public SDKEnumFieldInfo(IntPtr address, RemoteProcess remoteProcess) { EnumFieldInfo typeInfo = remoteProcess.Read <EnumFieldInfo>(address); EnumFieldInfoData typeInfoData = remoteProcess.Read <EnumFieldInfoData>(typeInfo.m_InfoData); Name = $"{remoteProcess.ReadString(typeInfoData.m_Name, 255)}"; ThisTypeInfo = address; Type = typeInfoData.GetNewEntryType(); Flags = typeInfoData.m_Flags; Alignment = typeInfoData.m_Alignment; TotalSize = typeInfoData.m_TotalSize; FieldCount = typeInfoData.m_FieldCount; RuntimeId = typeInfo.m_RuntimeId; Next = typeInfo.m_Next; if (FieldCount > 0) { for (int i = 0; i < FieldCount; i++) { var fieldInfoData = remoteProcess.Read <FieldInfoData>((IntPtr)((Int64)typeInfoData.m_Fields + (i * 0x18))); SDKFieldEntry fieldEntry; fieldEntry.fieldName = remoteProcess.ReadString(fieldInfoData.m_Name, 255); fieldEntry.fieldType = ""; fieldEntry.fieldInternalType = ""; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Void; fieldEntry.fieldOffset = 0; fieldEntry.fieldSize = 0; fieldEntry.lastFieldOffset = 0; fieldEntry.lastFieldSize = 0; Fields.Add(fieldEntry); } } }
public SDKTypeInfo(IntPtr address, RemoteProcess remoteProcess) { TypeInfo typeInfo = remoteProcess.Read <TypeInfo>(address); TypeInfoData typeInfoData = remoteProcess.Read <TypeInfoData>(typeInfo.m_InfoData); Name = remoteProcess.ReadString(typeInfoData.m_Name, 255); ThisTypeInfo = address; //Type = typeInfoData.GetEntryType(); Type = typeInfoData.GetNewEntryType(); //switch (typeInfoData.GetNewEntryType()) //{ // case 0x0000: // Type = BasicTypesEnum.kTypeCode_Void; // break; // case 0x0020: // Type = BasicTypesEnum.kTypeCode_DbObject; // break; // case 0x0040: // Type = BasicTypesEnum.kTypeCode_ValueType; // break; // case 0x0060: // Type = BasicTypesEnum.kTypeCode_Class; // break; // case 0x0080: // Type = BasicTypesEnum.kTypeCode_Array; // break; // case 0x00A0: // Type = BasicTypesEnum.kTypeCode_FixedArray; // break; // case 0x00C0: // Type = BasicTypesEnum.kTypeCode_String; // break; // case 0x00E0: // Type = BasicTypesEnum.kTypeCode_CString; // break; // case 0x0100: // Type = BasicTypesEnum.kTypeCode_Enum; // break; // case 0x0120: // Type = BasicTypesEnum.kTypeCode_FileRef; // break; // case 0x0140: // Type = BasicTypesEnum.kTypeCode_Boolean; // break; // case 0x0160: // Type = BasicTypesEnum.kTypeCode_Int8; // break; // case 0x0180: // Type = BasicTypesEnum.kTypeCode_Uint8; // break; // case 0x01A0: // Type = BasicTypesEnum.kTypeCode_Int16; // break; // case 0x01C0: // Type = BasicTypesEnum.kTypeCode_Uint16; // break; // case 0x01E0: // Type = BasicTypesEnum.kTypeCode_Int32; // break; // case 0x0200: // Type = BasicTypesEnum.kTypeCode_Uint32; // break; // case 0x0220: // Type = BasicTypesEnum.kTypeCode_Int64; // break; // case 0x0240: // Type = BasicTypesEnum.kTypeCode_Uint64; // break; // case 0x0260: // Type = BasicTypesEnum.kTypeCode_Float32; // break; // case 0x0280: // Type = BasicTypesEnum.kTypeCode_Float64; // break; // case 0x02A0: // Type = BasicTypesEnum.kTypeCode_Guid; // break; // case 0x02C0: // Type = BasicTypesEnum.kTypeCode_SHA1; // break; // case 0x02E0: // Type = BasicTypesEnum.kTypeCode_ResourceRef; // break; // //case 0x0300: // // Type = BasicTypesEnum.kTypeCode_BasicTypeCount; // // break; // case 0x0320: // Type = BasicTypesEnum.kTypeCode_TypeRef; // break; // case 0x0340: // Type = BasicTypesEnum.kTypeCode_BoxedValueRef; // break; // default: // Console.WriteLine($"New type = {typeInfoData.GetNewEntryType().ToString("X4")}, {Name}"); // break; //} Flags = typeInfoData.m_Flags; Alignment = typeInfoData.m_Alignment; TotalSize = typeInfoData.m_TotalSize; FieldCount = typeInfoData.m_FieldCount; RuntimeId = typeInfo.m_RuntimeId; Next = typeInfo.m_Next; }
public SDKClassInfo(IntPtr address, RemoteProcess remoteProcess, PEImageBuffer peImageBuffer) { ClassInfo typeInfo = remoteProcess.Read <ClassInfo>(address); ClassInfoData typeInfoData = remoteProcess.Read <ClassInfoData>(typeInfo.m_InfoData); Name = $"{remoteProcess.ReadString(typeInfoData.m_Name, 255)}"; ThisTypeInfo = address; Type = typeInfoData.GetNewEntryType(); Flags = typeInfoData.m_Flags; Alignment = typeInfoData.m_Alignment; TotalSize = typeInfoData.m_TotalSize; FieldCount = typeInfoData.m_FieldCount; ParentClass = typeInfoData.m_SuperClass; var superClassInfo = new SDKTypeInfo(ParentClass, remoteProcess); ParentClassName = $"{superClassInfo.Name}"; // debug if (Name == "PoseTrackKeyframe") { Name = Name; } // end debug // fill fields list if (FieldCount == 0) { if ((ParentClass != IntPtr.Zero) && (TotalSize > superClassInfo.TotalSize)) { SDKFieldEntry fieldEntry; fieldEntry.fieldType = "char"; fieldEntry.fieldInternalType = "Uint8"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Uint8; fieldEntry.fieldName = $"_0x{superClassInfo.TotalSize.ToString("X4")}[{TotalSize - superClassInfo.TotalSize}]"; fieldEntry.fieldOffset = superClassInfo.TotalSize; fieldEntry.fieldSize = TotalSize - superClassInfo.TotalSize; fieldEntry.lastFieldOffset = 0; fieldEntry.lastFieldSize = 0; Fields.Add(fieldEntry); FieldCount++; } else if ((ParentClass == IntPtr.Zero) || (Name == ParentClassName)) { // reference oddity for (Name == ParentClassName) fb::IglooSubsystem : has itself as parent, 0 fields SDKFieldEntry fieldEntry; fieldEntry.fieldType = "char"; fieldEntry.fieldInternalType = "Uint8"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Uint8; fieldEntry.fieldName = $"_0x000[{TotalSize}]"; fieldEntry.fieldOffset = 0; fieldEntry.fieldSize = TotalSize; fieldEntry.lastFieldOffset = 0; fieldEntry.lastFieldSize = 0; Fields.Add(fieldEntry); FieldCount++; } } else //if (FieldCount > 0) { for (int i = 0; i < FieldCount; i++) { var fieldInfoData = remoteProcess.Read <FieldInfoData>((IntPtr)((Int64)typeInfoData.m_Fields + (i * 0x18))); SDKFieldEntry fieldEntry; var fieldTypeInfo = new SDKTypeInfo(fieldInfoData.m_FieldTypePtr, remoteProcess); // fix the odd field type with flags as 0x0000 or 0x2000 if ((fieldInfoData.m_Flags == 0) || (fieldInfoData.m_Flags == 0x2000)) { fieldEntry.fieldType = fieldTypeInfo.FixTypeName(fieldTypeInfo.Name); } else { fieldEntry.fieldType = fieldTypeInfo.GetCppType(); //fieldTypeInfo.Name; } fieldEntry.fieldInternalType = fieldTypeInfo.Name; fieldEntry.fieldBasicType = fieldTypeInfo.Type;//fieldInfoData.GetEntryType(); fieldEntry.fieldName = remoteProcess.ReadString(fieldInfoData.m_Name, 255); fieldEntry.fieldOffset = fieldInfoData.m_FieldOffset; fieldEntry.fieldSize = fieldTypeInfo.TotalSize; fieldEntry.lastFieldOffset = lastFieldOffset; fieldEntry.lastFieldSize = lastFieldSize; // fix error with some bools being flagged as int16_t if ((fieldEntry.fieldType == "int16_t") && (fieldEntry.fieldSize == 1)) { fieldEntry.fieldType = "bool"; fieldEntry.fieldInternalType = "Boolean"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Boolean; } Fields.Add(fieldEntry); lastFieldOffset = fieldEntry.fieldOffset; lastFieldSize = fieldTypeInfo.TotalSize; } // the field array isn't sorted in offset order so fix that Fields = Fields.OrderBy(x => x.fieldOffset).ToList(); // check if pads needed for (int i = 1; i < FieldCount; i++) { lastFieldOffset = Fields.ElementAt(i - 1).fieldOffset; lastFieldSize = Fields.ElementAt(i - 1).fieldSize; SDKFieldEntry fieldEntry; fieldEntry = Fields.ElementAt(i); fieldEntry.lastFieldOffset = lastFieldOffset; fieldEntry.lastFieldSize = lastFieldSize; Fields[i] = fieldEntry; } for (int i = 0; i < FieldCount; i++) { SDKFieldEntry fieldEntry; if (i == (FieldCount - 1)) { // last class member so check against total size if (TotalSize > (Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize)) { fieldEntry.fieldType = "char"; fieldEntry.fieldInternalType = "Uint8"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Uint8; fieldEntry.fieldName = $"_0x{(Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize).ToString("X4")}[{TotalSize - (Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize)}]"; fieldEntry.fieldOffset = Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize; fieldEntry.fieldSize = TotalSize - (Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize); fieldEntry.lastFieldOffset = Fields.ElementAt(i).fieldOffset; fieldEntry.lastFieldSize = Fields.ElementAt(i).fieldSize; Fields.Add(fieldEntry); FieldCount++; } } if ((i == 0) && (ParentClass != IntPtr.Zero)) { // first class member so check against parent size if (superClassInfo.TotalSize < Fields.ElementAt(i).fieldOffset) { var debug = Fields.ElementAt(i).fieldOffset; fieldEntry.fieldType = "char"; fieldEntry.fieldInternalType = "Uint8"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Uint8; fieldEntry.fieldName = $"_0x{superClassInfo.TotalSize.ToString("X4")}[{Fields.ElementAt(i).fieldOffset - superClassInfo.TotalSize}]"; fieldEntry.fieldOffset = superClassInfo.TotalSize; fieldEntry.fieldSize = Fields.ElementAt(i).fieldOffset - superClassInfo.TotalSize; fieldEntry.lastFieldOffset = 0; // superClassInfo.TotalSize; fieldEntry.lastFieldSize = superClassInfo.TotalSize; Fields.Insert(0, fieldEntry); i++; FieldCount++; } } else { // inter-field pads. seems to be correct now :) if (Fields.ElementAt(i).fieldOffset > (Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize)) { fieldEntry.fieldType = "char"; fieldEntry.fieldInternalType = "Uint8"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Uint8; fieldEntry.fieldName = $"_0x{(Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize).ToString("X4")}[{Fields.ElementAt(i).fieldOffset - (Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize)}]"; fieldEntry.fieldOffset = Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize; fieldEntry.fieldSize = Fields.ElementAt(i).fieldOffset - (Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize); fieldEntry.lastFieldOffset = Fields.ElementAt(i).fieldOffset; fieldEntry.lastFieldSize = Fields.ElementAt(i).fieldSize; Fields.Insert(i, fieldEntry); i++; FieldCount++; } } } } RuntimeId = typeInfo.m_RuntimeId; Next = typeInfo.m_Next; DefaultInstance = typeInfo.m_DefaultInstance; ClassId = typeInfo.m_ClassId; GetVtable(remoteProcess, peImageBuffer); }
public SDKValueTypeInfo(IntPtr address, RemoteProcess remoteProcess) { ValueTypeInfo typeInfo = remoteProcess.Read <ValueTypeInfo>(address); ValueTypeInfoData typeInfoData = remoteProcess.Read <ValueTypeInfoData>(typeInfo.m_InfoData); Name = $"{remoteProcess.ReadString(typeInfoData.m_Name, 255)}"; ThisTypeInfo = address; Type = typeInfoData.GetNewEntryType(); Flags = typeInfoData.m_Flags; Alignment = typeInfoData.m_Alignment; TotalSize = typeInfoData.m_TotalSize; FieldCount = typeInfoData.m_FieldCount; RuntimeId = typeInfo.m_RuntimeId; Next = typeInfo.m_Next; // fill fields list if (FieldCount == 0) { SDKFieldEntry fieldEntry; fieldEntry.fieldType = "char"; fieldEntry.fieldInternalType = "Uint8"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Uint8; fieldEntry.fieldName = $"_0x000[{TotalSize}]"; fieldEntry.fieldOffset = 0; fieldEntry.fieldSize = TotalSize; fieldEntry.lastFieldOffset = 0; fieldEntry.lastFieldSize = 0; Fields.Add(fieldEntry); FieldCount++; } else { for (int i = 0; i < FieldCount; i++) { var fieldInfoData = remoteProcess.Read <FieldInfoData>((IntPtr)((Int64)typeInfoData.m_Fields + (i * 0x18))); SDKFieldEntry fieldEntry; var fieldTypeInfo = new SDKTypeInfo(fieldInfoData.m_FieldTypePtr, remoteProcess); // fix the odd field type with flags as 0x0000 or 0x2000 if ((fieldInfoData.m_Flags == 0) || (fieldInfoData.m_Flags == 0x2000)) { fieldEntry.fieldType = fieldTypeInfo.FixTypeName(fieldTypeInfo.Name); } else { fieldEntry.fieldType = fieldTypeInfo.GetCppType(); //fieldTypeInfo.Name; } fieldEntry.fieldInternalType = fieldTypeInfo.Name; fieldEntry.fieldBasicType = fieldTypeInfo.Type;//fieldInfoData.GetEntryType(); fieldEntry.fieldName = remoteProcess.ReadString(fieldInfoData.m_Name, 255); fieldEntry.fieldOffset = fieldInfoData.m_FieldOffset; fieldEntry.fieldSize = fieldTypeInfo.TotalSize; fieldEntry.lastFieldOffset = lastFieldOffset; fieldEntry.lastFieldSize = lastFieldSize; // fix error with some bools being flagged as int16_t if ((fieldEntry.fieldType == "int16_t") && (fieldEntry.fieldSize == 1)) { fieldEntry.fieldType = "bool"; } Fields.Add(fieldEntry); lastFieldOffset = fieldEntry.fieldOffset; lastFieldSize = fieldTypeInfo.TotalSize; } // the field array isn't always sorted in offset order so fix that Fields = Fields.OrderBy(x => x.fieldOffset).ToList(); // check if pads needed for (int i = 1; i < FieldCount; i++) { lastFieldOffset = Fields.ElementAt(i - 1).fieldOffset; lastFieldSize = Fields.ElementAt(i - 1).fieldSize; SDKFieldEntry fieldEntry; fieldEntry = Fields.ElementAt(i); fieldEntry.lastFieldOffset = lastFieldOffset; fieldEntry.lastFieldSize = lastFieldSize; Fields[i] = fieldEntry; } for (int i = 0; i < FieldCount; i++) { SDKFieldEntry fieldEntry; if (i == (FieldCount - 1)) { // last class member so check against total size if (TotalSize > (Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize)) { fieldEntry.fieldType = "char"; fieldEntry.fieldInternalType = "Uint8"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Uint8; fieldEntry.fieldName = $"_0x{(Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize).ToString("X4")}[{TotalSize - (Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize)}]"; fieldEntry.fieldOffset = Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize; fieldEntry.fieldSize = TotalSize - (Fields.ElementAt(i).fieldOffset + Fields.ElementAt(i).fieldSize); fieldEntry.lastFieldOffset = Fields.ElementAt(i).fieldOffset; fieldEntry.lastFieldSize = Fields.ElementAt(i).fieldSize; Fields.Add(fieldEntry); FieldCount++; } } else { // inter-field pads. seems to be correct now :) if (Fields.ElementAt(i).fieldOffset > (Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize)) { fieldEntry.fieldType = "char"; fieldEntry.fieldInternalType = "Uint8"; fieldEntry.fieldBasicType = BasicTypesEnum.kTypeCode_Uint8; fieldEntry.fieldName = $"_0x{(Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize).ToString("X4")}[{Fields.ElementAt(i).fieldOffset - (Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize)}]"; fieldEntry.fieldOffset = Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize; fieldEntry.fieldSize = Fields.ElementAt(i).fieldOffset - (Fields.ElementAt(i).lastFieldOffset + Fields.ElementAt(i).lastFieldSize); fieldEntry.lastFieldOffset = Fields.ElementAt(i).fieldOffset; fieldEntry.lastFieldSize = Fields.ElementAt(i).fieldSize; Fields.Insert(i, fieldEntry); i++; FieldCount++; } } } } }