Skip to content

Commit

Permalink
So apparently field offsets are in the metadata registration. Who kne…
Browse files Browse the repository at this point in the history
…w? not me.
  • Loading branch information
Sam Byass committed Jan 22, 2021
1 parent d290cea commit 75f9cd4
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 32 deletions.
23 changes: 6 additions & 17 deletions Cpp2IL/AssemblyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ private static List<CppMethodData> ProcessTypeContents(Il2CppMetadata metadata,
}

//Handle base fields
var fieldOffset = baseFields.Aggregate((ulong) (ilTypeDefinition.MetadataType == MetadataType.Class ? 0x10 : 0x0), (currentOffset, baseField) => HandleField(baseField.FieldType, currentOffset, baseField.Name, baseField, ref fields, typeMetaText));
// var fieldOffset = baseFields.Aggregate((ulong) (ilTypeDefinition.MetadataType == MetadataType.Class ? 0x10 : 0x0), (currentOffset, baseField) => HandleField(baseField.FieldType, currentOffset, baseField.Name, baseField, ref fields, typeMetaText));

var lastFieldIdx = cppTypeDefinition.firstFieldIdx + cppTypeDefinition.field_count;
for (var fieldIdx = cppTypeDefinition.firstFieldIdx; fieldIdx < lastFieldIdx; ++fieldIdx)
Expand All @@ -299,8 +299,10 @@ private static List<CppMethodData> ProcessTypeContents(Il2CppMetadata metadata,

if (!fieldDefinition.IsStatic)
{
fieldOffset = HandleField(fieldTypeRef, fieldOffset, fieldName, fieldDefinition, ref fields, typeMetaText);
var thisFieldOffset = cppAssembly.GetFieldOffsetFromIndex(cppTypeDefinition.TypeIndex, fieldIdx - cppTypeDefinition.firstFieldIdx, fieldIdx, ilTypeDefinition.IsValueType, fieldDefinition.IsStatic);

HandleField(fieldTypeRef, thisFieldOffset, fieldName, fieldDefinition, ref fields, typeMetaText);

//Add [FieldOffset(Offset = "0xDEADBEEF")]
var fieldOffsetAttributeInst = new CustomAttribute(ilTypeDefinition.Module.ImportReference(fieldOffsetAttribute));
fieldOffsetAttributeInst.Fields.Add(new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{fields.Last().Offset:X}")));
Expand Down Expand Up @@ -565,18 +567,8 @@ private static List<CppMethodData> ProcessTypeContents(Il2CppMetadata metadata,
return typeMethods;
}

private static ulong HandleField(TypeReference fieldTypeRef, ulong fieldOffset, string fieldName, FieldDefinition fieldDefinition, ref List<FieldInType> fields, StringBuilder typeMetaText)
private static void HandleField(TypeReference fieldTypeRef, int fieldOffset, string fieldName, FieldDefinition fieldDefinition, ref List<FieldInType> fields, StringBuilder typeMetaText)
{
var length = Utils.GetSizeOfObject(fieldTypeRef);

var boundarySize = LibCpp2IlMain.ThePe!.is32Bit ? (decimal) 4 : 8;
var fieldEnd = fieldOffset + length - 1;
if (Math.Floor(fieldOffset / boundarySize) != Math.Floor(fieldEnd / boundarySize))
{
//Would cross an alignment boundary, so move to the next alignment.
fieldOffset = (ulong) ((Math.Floor(fieldOffset / boundarySize) + 1) * boundarySize);
}

//ONE correction. String#start_char is remapped to a char[] not a char because the block allocated for all chars is directly sequential to the length of the string, because that's how c++ works.
if (fieldDefinition.DeclaringType.FullName == "System.String" && fieldTypeRef.FullName == "System.Char")
fieldTypeRef = fieldTypeRef.MakeArrayType();
Expand All @@ -585,13 +577,11 @@ private static ulong HandleField(TypeReference fieldTypeRef, ulong fieldOffset,
{
Name = fieldName,
Type = fieldTypeRef,
Offset = fieldOffset,
Offset = (ulong) fieldOffset,
Static = fieldDefinition.IsStatic,
Constant = fieldDefinition.Constant
};

fieldOffset += length;

fields.Add(field);

typeMetaText.Append($"\n\t{(field.Static ? "Static Field" : "Field")}: {field.Name}\n")
Expand All @@ -600,7 +590,6 @@ private static ulong HandleField(TypeReference fieldTypeRef, ulong fieldOffset,

if (field.Constant != null)
typeMetaText.Append($"\t\tDefault Value: {field.Constant}\n");
return fieldOffset;
}


Expand Down
2 changes: 0 additions & 2 deletions Cpp2IL/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ public static int Main(string[] args)
Console.WriteLine("Initialization with LibCpp2IL failed.");
return 1;
}

Console.WriteLine(LibCpp2IlReflection.GetType("String", "System").DeclaringAssembly.Name);

//Dump DLLs

Expand Down
44 changes: 31 additions & 13 deletions LibCpp2IL/PE/PE.cs
Original file line number Diff line number Diff line change
Expand Up @@ -637,26 +637,44 @@ public ulong[] GetPointers(ulong pointer, long count)
return ReadClassArrayAtVirtualAddress<ulong>(pointer, count);
}

public long GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType, int fieldIndex)
public int GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType, int fieldIndex, bool isValueType, bool isStatic)
{
var ptr = fieldOffsets[typeIndex];
if (ptr >= 0)
try
{
long pos;
if (is32Bit)
pos = MapVirtualAddressToRaw((uint) ptr) + 4 * fieldIndexInType;
var offset = -1;
if (LibCpp2IlMain.MetadataVersion > 21)
{
var ptr = (ulong) fieldOffsets[typeIndex];
if (ptr > 0)
{
Position = (long) ((ulong) MapVirtualAddressToRaw(ptr) + 4ul * (ulong)fieldIndexInType);
offset = ReadInt32();
}
}
else
pos = MapVirtualAddressToRaw((ulong) ptr) + 4 * fieldIndexInType;
if (pos <= BaseStream.Length - 4)
{
Position = pos;
return ReadInt32();
offset = (int)fieldOffsets[fieldIndex];
}

if (offset > 0)
{
if (isValueType && !isStatic)
{
if (is32Bit)
{
offset -= 8;
}
else
{
offset -= 16;
}
}
}
return offset;
}
catch
{
return -1;
}

return 0;
}

public ulong GetMethodPointer(int methodIndex, int methodDefinitionIndex, int imageIndex, uint methodToken)
Expand Down

0 comments on commit 75f9cd4

Please sign in to comment.