[ Обновленные темы · Новые сообщения · Участники · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Моддинг » Уроки моддинга Worms Ultimate Mayhem » Декодируем структуру Xom через IDA
Декодируем структуру Xom через IDA
AlexBond
Админы
Сообщений: 1042
Реп: 106 / Инв: 8
Как же происходит декодирование XOM?

Инструменты
Для работы нам нужен дизассемблер IDA желательно от 7.5 версии.

Теория
Все основные классы Xom создаются функцией XContainerClass::XContainerClass
Выглядит это примерно так:
Код
XContainerClass::XContainerClass(
      &XResourceDetails::c_class,
      &XResourceDetails::c_typeinfodata,
      &XContainer::c_class,
      XResourceDetails::CreateInstance_,
      2,
      XResourceDetails::InitClass);
Что нам дает эта функция? Она присутствует почти во всех играх Worms серии 3D начиная от Worms Blast и заканчивая WUM, а часть осталась и в WMD.

В эту функцию передаются параметры:
- создаваемый XClass
- структура XBase::TypeInfo::TypeInfoData
- XClass родитель
- функция CreateInstance
- тип класса 2
- функция InitClass

Тут нам нужна структура XBase::TypeInfo::TypeInfoData.
В структуре TypeInfoData содержится ссылка на название класса, ссылка на GUID, номер версии, и тип класса.

Код
XResourceDetails__c_typeinfodata
XBase::TypeInfo::TypeInfoData
<offset aXresourcedetai, \\ XName "XResourceDetails"
1C0000h,
offset XResourceDetails__GUID, \\ XGuid
offset g_XrmUnit, \\ Type
0,
0, \\ Xver
0>
Нам важно название XName, XGuid и версия XVer.
XGuid используется в начале всех Xom файлов для определения типа контейнеров.

Код
XResourceDetails__GUID XGuid <0E77556F2h, 491AA495h, 6C006385h, 447257E2h>
в xml он выглядит так:
Код
guid="{E77556F2-A495-491A-8563-006CE2577244}"

Версия Xver нужна для совместимости, некоторые поля игнорируются в зависимости от версии.

Дальше нам важна функция InitClass. Она есть не во всех классах, но в ней содержатся все поля для контейнера.
Внутри этой функции инициализируются поля
Код
XResourceDetails::InitClass(void *this) {
XSFStringDescriptor::Initialize(this, &XResourceDetails::FieldInfo_Name);
XSFUint32Descriptor::Initialize(this, &XResourceDetails::FieldInfo_Flags);
}
FieldInfo это описание полей, оно обычно динамической длины, но основа всегда общая

Код
XResourceDetails::FieldInfo_Name FieldInfo <
offset aName, \\ FieldName "Name"
14h, \\ FieldOffset
0, \\ FieldID
8, \\ FieldМask
offset XBase::StringTypeInfo::c_class, \\ FieldClass XString
0, \\ SubType
0 \\ Xcomment
>
Из этой структуры нам важно FieldName , FieldClass, FieldМask и Xcomment
FieldМask работает следующем образом:
- FieldМask = 8, поле присутствует всегда
- FieldМask = 9, поле присутствует с данной версией
- FieldМask > 9, поле отсутствует в данной версии или вообще

Кроме информации по полю важно еще функция Initialize.
Есть два вида функций:
- XSFTypeDescriptor::Initialize
- XMFTypeDescriptor::Initialize

Первая XSF для одного значения, вторая XMF для коллекции XCollection
Каждый XClass имеет в себе все поля своих родителей.
Прикрепления: XomClassFound.idc (2.0 Kb) · xomreadtypewum_xml.idc (15.4 Kb)


 
AlexBond
Админы
Сообщений: 1042
Реп: 106 / Инв: 8
Практика

Как же распознать названия всех этих функций и полей?
Тут нам пригодится встроенный скриптовой язык idc для автоматизации процесса.
И необходимо вручную назвать базовые типы XInt, XUInt, XInt8, XUInt8, XInt16, XUInt16, XString, XFloat, XBool, XEnum, XColor4ub, XVector2f, XVector3f, XVector4f, XMatrix34, XMatrix, XBoundBox. Это можно легко сделать ориентируясь по классу XResourceDetails.

Итак мы открыли WormsMayhem.exe в IDA  и прошли первое сканирование, переключаемся в окне IDA View-A на Text view.
Теперь нам нужно найти XContainerClass::XContainerClass и назвать ее для простоты XContainerClass
Вбиваем в поиск (Alt +T) "XResourceDetails"
и получаем вот такой вид:

Эта и есть функция которую мы рассматривали в теории, она создает класс XResourceDetails::c_class
Переименовываем sub_6C3C99 в XContainerClass.
Далее нам нужно создать упрощенные структуры. Переходим в окно Local Types (Shift+F1) и нажимаем "Insert..." .
Создаем XGuid

Код
struct XGuid
{
  int d1;
  int d2;
  int d3;
  int d4;
};
и XClass для структуры XBase::TypeInfo::TypeInfoData. Синхронизируем их кликая на каждую после создания

Код
struct XClass
{
  void *XName;
  int Xflag;
  void *PXGuid;
  void *XType;
  int unk;
  int Xver;
  void *Xcomm;
};

Все наша основа для работы скрипта готова!

Запускаем скрипт XomClassFound.idc (Alt+F7)
Итог работы скрипта:

Теперь выбрав XContainerClass и нажав X мы получим список всех функций для инициализации контейнеров
Прикрепления: 2778408.png (23.0 Kb) · 2047360.png (11.6 Kb) · 8427248.png (29.2 Kb)


 
AlexBond
Админы
Сообщений: 1042
Реп: 106 / Инв: 8
Далее нужно создать еще две структуры, для работы второго скрипта:
XComment

Код
struct XComment
{
  void *name;
  void *comment;
  void *used;
  void *version;
};

XValue он же ::FieldInfo
Код
struct XValue
{
char *FieldName;
__int16 FieldOffset;
char FieldID;
char FieldMask;
void *FieldClass;
void *SubType;
XComment *Xcomment;
};

Запускаем скрипт XomReadTypeWUM_XML.idc (Alt+F7)
Получаем в Output window следующее

Код
<XResourceDetails guid="{E77556F2-A495-491A-8563-006CE2577244}" Xver="0" id="XRef">
   <Name>dword_967698</Name>
   <Flags>dword_967650</Flags>
</XResourceDetails>
<XIntResourceDetails guid="{7D889B8D-2C14-445E-961F-5E0E5520416A}" Xver="0" id="XRef">
   <Value>dword_96765C</Value>
</XIntResourceDetails>
<XUintResourceDetails guid="{93E5117C-8ADA-4AFB-B17A-668D0BDD15E6}" Xver="0" id="XRef">
   <Value>dword_967650</Value>
</XUintResourceDetails>
<XStringResourceDetails guid="{7CDC5872-2CA3-4FCC-AE66-431071E5CE67}" Xver="0" id="XRef">
   <Value>dword_967698</Value>
</XStringResourceDetails>
<XFloatResourceDetails guid="{08889D5F-8039-4CEA-BA5B-9C059AC0570E}" Xver="0" id="XRef">
   <Value>dword_967680</Value>
</XFloatResourceDetails>
<XVectorResourceDetails guid="{071F4563-8CB3-4996-B79F-B0F5CAEC9D99}" Xver="0" id="XRef">
   <Value>unk_96EBE0</Value>
</XVectorResourceDetails>
<XContainerResourceDetails guid="{E0B6BF20-F80B-4329-B6EB-1998ED8AEC1F}" Xver="0" id="XRef">
   <Value>dword_970B94</Value>
</XContainerResourceDetails>
<XColorResourceDetails guid="{7804BA7B-C6FD-4E8E-AFFF-8E266B6A5544}" Xver="0" id="XRef">
   <Value>unk_96E988</Value>
</XColorResourceDetails>
<XDataBank guid="{93E661AC-D941-442A-A18E-E99B795879DC}" Xver="0" id="XRef">
   <Section>dword_967620</Section>
   <IntResources>dword_970B94</IntResources>
   <UintResources>dword_970B94</UintResources>
   <StringResources>dword_970B94</StringResources>
   <FloatResources>dword_970B94</FloatResources>
   <VectorResources>dword_970B94</VectorResources>
   <ContainerResources>dword_970B94</ContainerResources>
   <StringTableResources>dword_970B94</StringTableResources>
   <ColorResources>dword_970B94</ColorResources>
</XDataBank>

Как видно у нас много не известных типов dword_970B94, dword_967620 , unk_96E988 их нужно в ручном режиме назвать соответственно ресурсам.
У нас должен получится такой вывод:

Код
<XResourceDetails guid="{E77556F2-A495-491A-8563-006CE2577244}" Xver="0" id="XRef">
   <Name>XString</Name>
   <Flags>XUInt</Flags>
</XResourceDetails>
<XIntResourceDetails guid="{7D889B8D-2C14-445E-961F-5E0E5520416A}" Xver="0" id="XRef">
   <Value>XInt</Value>
</XIntResourceDetails>
<XUintResourceDetails guid="{93E5117C-8ADA-4AFB-B17A-668D0BDD15E6}" Xver="0" id="XRef">
   <Value>XUInt</Value>
</XUintResourceDetails>
<XStringResourceDetails guid="{7CDC5872-2CA3-4FCC-AE66-431071E5CE67}" Xver="0" id="XRef">
   <Value>XString</Value>
</XStringResourceDetails>
<XFloatResourceDetails guid="{08889D5F-8039-4CEA-BA5B-9C059AC0570E}" Xver="0" id="XRef">
   <Value>XFloat</Value>
</XFloatResourceDetails>

За вывод в формате XML отвечает функция скрипта XMLPrint. Она закомментирована для остальных типов, с помощью ее можно узнать структуру любого контейнера.

Структура этих общих функций EXE отличается в разных играх, поэтом скрипт не универсален и его необходимо переписывать, но суть работы не меняется.

При должном желании можете глубже разобраться.


 
Unaited
Админы
Сообщений: 1463
Реп: 92 / Инв: 13
Цитата AlexBond ()
- тип класса 2
это ComponentCategoryEnum

Код
enum ComponentCategoryEnum
{
  Generic = 0x0,
  Action = 0x1,
  Container = 0x2,
  RenderAttribute = 0x3,
  Type = 0x4,
  ActionMethods = 0x5,
  HttpCallback = 0x6,
  Singleton = 0x7,
  TypeConverter = 0x8,
  Entity = 0x9,
  Service = 0xA,
  LogicEntity = 0xB,
  ContainerBinding = 0xC,
};


 
Форум » Моддинг » Уроки моддинга Worms Ultimate Mayhem » Декодируем структуру Xom через IDA
  • Страница 1 из 1
  • 1
Поиск: