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++; } } } } }