添加数组类型读取

This commit is contained in:
Perfare 2020-02-08 17:39:32 +08:00
parent 2c982f71f6
commit 79f60bd73a
10 changed files with 94 additions and 88 deletions

View file

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Il2CppDumper
{
[AttributeUsage(AttributeTargets.Field)]
class ArrayLengthAttribute : Attribute
{
public int Length { get; set; }
}
}

View file

@ -27,29 +27,7 @@ namespace Il2CppDumper
public Elf(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages) public Elf(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
{ {
is32Bit = true; is32Bit = true;
elfHeader = new Elf32_Ehdr(); elfHeader = ReadClass<Elf32_Ehdr>();
elfHeader.ei_mag = ReadUInt32();
elfHeader.ei_class = ReadByte();
elfHeader.ei_data = ReadByte();
elfHeader.ei_version = ReadByte();
elfHeader.ei_osabi = ReadByte();
elfHeader.ei_abiversion = ReadByte();
elfHeader.ei_pad = ReadBytes(7);
elfHeader.e_type = ReadUInt16();
elfHeader.e_machine = ReadUInt16();
if (elfHeader.e_machine != EM_ARM && elfHeader.e_machine != EM_386)
throw new Exception("ERROR: Unsupported machines.");
elfHeader.e_version = ReadUInt32();
elfHeader.e_entry = ReadUInt32();
elfHeader.e_phoff = ReadUInt32();
elfHeader.e_shoff = ReadUInt32();
elfHeader.e_flags = ReadUInt32();
elfHeader.e_ehsize = ReadUInt16();
elfHeader.e_phentsize = ReadUInt16();
elfHeader.e_phnum = ReadUInt16();
elfHeader.e_shentsize = ReadUInt16();
elfHeader.e_shnum = ReadUInt16();
elfHeader.e_shtrndx = ReadUInt16();
programSegment = ReadClassArray<Elf32_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum); programSegment = ReadClassArray<Elf32_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
try try
{ {

View file

@ -18,27 +18,7 @@ namespace Il2CppDumper
public Elf64(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages) public Elf64(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
{ {
elfHeader = new Elf64_Ehdr(); elfHeader = ReadClass<Elf64_Ehdr>();
elfHeader.ei_mag = ReadUInt32();
elfHeader.ei_class = ReadByte();
elfHeader.ei_data = ReadByte();
elfHeader.ei_version = ReadByte();
elfHeader.ei_osabi = ReadByte();
elfHeader.ei_abiversion = ReadByte();
elfHeader.ei_pad = ReadBytes(7);
elfHeader.e_type = ReadUInt16();
elfHeader.e_machine = ReadUInt16();
elfHeader.e_version = ReadUInt32();
elfHeader.e_entry = ReadUInt64();
elfHeader.e_phoff = ReadUInt64();
elfHeader.e_shoff = ReadUInt64();
elfHeader.e_flags = ReadUInt32();
elfHeader.e_ehsize = ReadUInt16();
elfHeader.e_phentsize = ReadUInt16();
elfHeader.e_phnum = ReadUInt16();
elfHeader.e_shentsize = ReadUInt16();
elfHeader.e_shnum = ReadUInt16();
elfHeader.e_shtrndx = ReadUInt16();
programSegment = ReadClassArray<Elf64_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum); programSegment = ReadClassArray<Elf64_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
try try
{ {

View file

@ -13,6 +13,7 @@ namespace Il2CppDumper
public byte ei_version; public byte ei_version;
public byte ei_osabi; public byte ei_osabi;
public byte ei_abiversion; public byte ei_abiversion;
[ArrayLength(Length = 7)]
public byte[] ei_pad; public byte[] ei_pad;
public ushort e_type; public ushort e_type;
public ushort e_machine; public ushort e_machine;

View file

@ -14,6 +14,7 @@ namespace Il2CppDumper
public byte ei_version; public byte ei_version;
public byte ei_osabi; public byte ei_osabi;
public byte ei_abiversion; public byte ei_abiversion;
[ArrayLength(Length = 7)]
public byte[] ei_pad; public byte[] ei_pad;
public ushort e_type; public ushort e_type;
public ushort e_machine; public ushort e_machine;

View file

@ -13,52 +13,40 @@ namespace Il2CppDumper
public PE(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages) public PE(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
{ {
if (ReadUInt16() != 0x5A4D)//e_magic var dosHeader = ReadClass<DosHeader>();
throw new Exception("ERROR: Invalid PE file"); if (dosHeader.Magic != 0x5A4D)
Position = 0x3C;//e_lfanew {
Position = ReadUInt32(); throw new InvalidDataException("ERROR: Invalid PE file");
if (ReadUInt32() != 0x00004550)//Signature }
throw new Exception("ERROR: Invalid PE file"); Position = dosHeader.Lfanew;
if (ReadUInt32() != 0x4550u) //Signature
{
throw new InvalidDataException("ERROR: Invalid PE file");
}
var fileHeader = ReadClass<FileHeader>(); var fileHeader = ReadClass<FileHeader>();
if (fileHeader.Machine == 0x014c)//Intel 386 var pos = Position;
if (fileHeader.Machine == 0x14c) //Intel 386
{ {
is32Bit = true; is32Bit = true;
var optionalHeader = ReadClass<OptionalHeader>(); var optionalHeader = ReadClass<OptionalHeader>();
optionalHeader.DataDirectory = ReadClassArray<DataDirectory>(optionalHeader.NumberOfRvaAndSizes);
imageBase = optionalHeader.ImageBase; imageBase = optionalHeader.ImageBase;
} }
else if (fileHeader.Machine == 0x8664) //AMD64 else if (fileHeader.Machine == 0x8664) //AMD64
{ {
var optionalHeader = ReadClass<OptionalHeader64>(); var optionalHeader = ReadClass<OptionalHeader64>();
optionalHeader.DataDirectory = ReadClassArray<DataDirectory>(optionalHeader.NumberOfRvaAndSizes);
imageBase = optionalHeader.ImageBase; imageBase = optionalHeader.ImageBase;
} }
else else
{ {
throw new Exception("ERROR: Unsupported machine."); throw new NotSupportedException("ERROR: Unsupported machine.");
}
sections = new SectionHeader[fileHeader.NumberOfSections];
for (int i = 0; i < fileHeader.NumberOfSections; i++)
{
sections[i] = new SectionHeader
{
Name = Encoding.UTF8.GetString(ReadBytes(8)).Trim('\0'),
VirtualSize = ReadUInt32(),
VirtualAddress = ReadUInt32(),
SizeOfRawData = ReadUInt32(),
PointerToRawData = ReadUInt32(),
PointerToRelocations = ReadUInt32(),
PointerToLinenumbers = ReadUInt32(),
NumberOfRelocations = ReadUInt16(),
NumberOfLinenumbers = ReadUInt16(),
Characteristics = ReadUInt32()
};
} }
Position = pos + fileHeader.SizeOfOptionalHeader;
sections = ReadClassArray<SectionHeader>(fileHeader.NumberOfSections);
} }
public override ulong MapVATR(ulong uiAddr) public override ulong MapVATR(ulong absAddr)
{ {
var addr = uiAddr - imageBase; var addr = absAddr - imageBase;
var section = sections.First(x => addr >= x.VirtualAddress && addr <= x.VirtualAddress + x.VirtualSize); var section = sections.First(x => addr >= x.VirtualAddress && addr <= x.VirtualAddress + x.VirtualSize);
return addr - (section.VirtualAddress - section.PointerToRawData); return addr - (section.VirtualAddress - section.PointerToRawData);
} }

View file

@ -5,6 +5,31 @@ using System.Text;
namespace Il2CppDumper namespace Il2CppDumper
{ {
public class DosHeader
{
public ushort Magic;
public ushort Cblp;
public ushort Cp;
public ushort Crlc;
public ushort Cparhdr;
public ushort Minalloc;
public ushort Maxalloc;
public ushort Ss;
public ushort Sp;
public ushort Csum;
public ushort Ip;
public ushort Cs;
public ushort Lfarlc;
public ushort Ovno;
[ArrayLength(Length = 4)]
public ushort[] Res;
public ushort Oemid;
public ushort Oeminfo;
[ArrayLength(Length = 10)]
public ushort[] Res2;
public uint Lfanew;
}
public class FileHeader public class FileHeader
{ {
public ushort Machine; public ushort Machine;
@ -48,7 +73,7 @@ namespace Il2CppDumper
public uint SizeOfHeapCommit; public uint SizeOfHeapCommit;
public uint LoaderFlags; public uint LoaderFlags;
public uint NumberOfRvaAndSizes; public uint NumberOfRvaAndSizes;
public DataDirectory[] DataDirectory { get; set; } //public DataDirectory[] DataDirectory;
} }
public class OptionalHeader64 public class OptionalHeader64
@ -82,18 +107,19 @@ namespace Il2CppDumper
public ulong SizeOfHeapCommit; public ulong SizeOfHeapCommit;
public uint LoaderFlags; public uint LoaderFlags;
public uint NumberOfRvaAndSizes; public uint NumberOfRvaAndSizes;
public DataDirectory[] DataDirectory { get; set; } //public DataDirectory[] DataDirectory;
} }
public class DataDirectory /*public class DataDirectory
{ {
public uint VirtualAddress; public uint VirtualAddress;
public uint Size; public uint Size;
} }*/
public class SectionHeader public class SectionHeader
{ {
public string Name; [ArrayLength(Length = 8)]
public byte[] Name;
public uint VirtualSize; public uint VirtualSize;
public uint VirtualAddress; public uint VirtualAddress;
public uint SizeOfRawData; public uint SizeOfRawData;
@ -104,4 +130,12 @@ namespace Il2CppDumper
public ushort NumberOfLinenumbers; public ushort NumberOfLinenumbers;
public uint Characteristics; public uint Characteristics;
} }
[Flags]
public enum SectionCharacteristics : uint
{
IMAGE_SCN_MEM_EXECUTE = 0x20000000,
IMAGE_SCN_MEM_READ = 0x40000000,
IMAGE_SCN_MEM_WRITE = 0x80000000
}
} }

View file

@ -14,7 +14,8 @@ namespace Il2CppDumper
private BinaryReader reader; private BinaryReader reader;
private BinaryWriter writer; private BinaryWriter writer;
private MethodInfo readClass; private MethodInfo readClass;
private Dictionary<Type, MethodInfo> readClassCache = new Dictionary<Type, MethodInfo>(); private MethodInfo readClassArray;
private Dictionary<Type, MethodInfo> genericMethodCache = new Dictionary<Type, MethodInfo>();
private Dictionary<FieldInfo, VersionAttribute> attributeCache = new Dictionary<FieldInfo, VersionAttribute>(); private Dictionary<FieldInfo, VersionAttribute> attributeCache = new Dictionary<FieldInfo, VersionAttribute>();
public BinaryStream(Stream input) public BinaryStream(Stream input)
@ -23,6 +24,7 @@ namespace Il2CppDumper
reader = new BinaryReader(stream, Encoding.UTF8, true); reader = new BinaryReader(stream, Encoding.UTF8, true);
writer = new BinaryWriter(stream, Encoding.UTF8, true); writer = new BinaryWriter(stream, Encoding.UTF8, true);
readClass = GetType().GetMethod("ReadClass", Type.EmptyTypes); readClass = GetType().GetMethod("ReadClass", Type.EmptyTypes);
readClassArray = GetType().GetMethod("ReadClassArray", new[] { typeof(long) });
} }
public bool ReadBoolean() => reader.ReadBoolean(); public bool ReadBoolean() => reader.ReadBoolean();
@ -101,7 +103,7 @@ namespace Il2CppDumper
case "UInt64": case "UInt64":
return ReadUInt64(); return ReadUInt64();
default: default:
return null; throw new NotSupportedException();
} }
} }
@ -127,7 +129,7 @@ namespace Il2CppDumper
{ {
if (Attribute.IsDefined(i, typeof(VersionAttribute))) if (Attribute.IsDefined(i, typeof(VersionAttribute)))
{ {
versionAttribute = (VersionAttribute)Attribute.GetCustomAttribute(i, typeof(VersionAttribute)); versionAttribute = i.GetCustomAttribute<VersionAttribute>();
attributeCache.Add(i, versionAttribute); attributeCache.Add(i, versionAttribute);
} }
} }
@ -140,16 +142,24 @@ namespace Il2CppDumper
{ {
i.SetValue(t, ReadPrimitive(i.FieldType)); i.SetValue(t, ReadPrimitive(i.FieldType));
} }
else if (i.FieldType.IsArray)
{
var arrayLengthAttribute = i.GetCustomAttribute<ArrayLengthAttribute>();
if (!genericMethodCache.TryGetValue(i.FieldType, out var methodInfo))
{
methodInfo = readClassArray.MakeGenericMethod(i.FieldType.GetElementType());
genericMethodCache.Add(i.FieldType, methodInfo);
}
i.SetValue(t, methodInfo.Invoke(this, new object[] { arrayLengthAttribute.Length }));
}
else else
{ {
if (!readClassCache.TryGetValue(i.FieldType, out var methodInfo)) if (!genericMethodCache.TryGetValue(i.FieldType, out var methodInfo))
{ {
methodInfo = readClass.MakeGenericMethod(i.FieldType); methodInfo = readClass.MakeGenericMethod(i.FieldType);
readClassCache.Add(i.FieldType, methodInfo); genericMethodCache.Add(i.FieldType, methodInfo);
} }
var value = methodInfo.Invoke(this, null); i.SetValue(t, methodInfo.Invoke(this, null));
i.SetValue(t, value);
break;
} }
} }
return t; return t;

View file

@ -51,6 +51,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Attributes\ArrayLengthAttribute.cs" />
<Compile Include="Extensions\BoyerMooreHorspool.cs" /> <Compile Include="Extensions\BoyerMooreHorspool.cs" />
<Compile Include="ExecutableFormats\ElfConstants.cs" /> <Compile Include="ExecutableFormats\ElfConstants.cs" />
<Compile Include="Extensions\HexExtensions.cs" /> <Compile Include="Extensions\HexExtensions.cs" />

View file

@ -514,7 +514,6 @@ namespace Il2CppDumper
var pointer = metadata.GetDefaultValueFromIndex(dataIndex); var pointer = metadata.GetDefaultValueFromIndex(dataIndex);
var defaultValueType = il2Cpp.types[typeIndex]; var defaultValueType = il2Cpp.types[typeIndex];
metadata.Position = pointer; metadata.Position = pointer;
value = null;
switch (defaultValueType.type) switch (defaultValueType.type)
{ {
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN: case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN: