Как же происходит декодирование 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 имеет в себе все поля своих родителей.