mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-09 19:27:17 -03:00
添加数组类型读取
This commit is contained in:
parent
2c982f71f6
commit
79f60bd73a
10 changed files with 94 additions and 88 deletions
14
Il2CppDumper/Attributes/ArrayLengthAttribute.cs
Normal file
14
Il2CppDumper/Attributes/ArrayLengthAttribute.cs
Normal 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; }
|
||||
}
|
||||
}
|
|
@ -27,29 +27,7 @@ namespace Il2CppDumper
|
|||
public Elf(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
{
|
||||
is32Bit = true;
|
||||
elfHeader = new 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();
|
||||
elfHeader = ReadClass<Elf32_Ehdr>();
|
||||
programSegment = ReadClassArray<Elf32_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
|
||||
try
|
||||
{
|
||||
|
|
|
@ -18,27 +18,7 @@ namespace Il2CppDumper
|
|||
|
||||
public Elf64(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
{
|
||||
elfHeader = new 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();
|
||||
elfHeader = ReadClass<Elf64_Ehdr>();
|
||||
programSegment = ReadClassArray<Elf64_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
|
||||
try
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Il2CppDumper
|
|||
public byte ei_version;
|
||||
public byte ei_osabi;
|
||||
public byte ei_abiversion;
|
||||
[ArrayLength(Length = 7)]
|
||||
public byte[] ei_pad;
|
||||
public ushort e_type;
|
||||
public ushort e_machine;
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Il2CppDumper
|
|||
public byte ei_version;
|
||||
public byte ei_osabi;
|
||||
public byte ei_abiversion;
|
||||
[ArrayLength(Length = 7)]
|
||||
public byte[] ei_pad;
|
||||
public ushort e_type;
|
||||
public ushort e_machine;
|
||||
|
|
|
@ -13,52 +13,40 @@ namespace Il2CppDumper
|
|||
|
||||
public PE(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
{
|
||||
if (ReadUInt16() != 0x5A4D)//e_magic
|
||||
throw new Exception("ERROR: Invalid PE file");
|
||||
Position = 0x3C;//e_lfanew
|
||||
Position = ReadUInt32();
|
||||
if (ReadUInt32() != 0x00004550)//Signature
|
||||
throw new Exception("ERROR: Invalid PE file");
|
||||
var dosHeader = ReadClass<DosHeader>();
|
||||
if (dosHeader.Magic != 0x5A4D)
|
||||
{
|
||||
throw new InvalidDataException("ERROR: Invalid PE file");
|
||||
}
|
||||
Position = dosHeader.Lfanew;
|
||||
if (ReadUInt32() != 0x4550u) //Signature
|
||||
{
|
||||
throw new InvalidDataException("ERROR: Invalid PE file");
|
||||
}
|
||||
var fileHeader = ReadClass<FileHeader>();
|
||||
if (fileHeader.Machine == 0x014c)//Intel 386
|
||||
var pos = Position;
|
||||
if (fileHeader.Machine == 0x14c) //Intel 386
|
||||
{
|
||||
is32Bit = true;
|
||||
var optionalHeader = ReadClass<OptionalHeader>();
|
||||
optionalHeader.DataDirectory = ReadClassArray<DataDirectory>(optionalHeader.NumberOfRvaAndSizes);
|
||||
imageBase = optionalHeader.ImageBase;
|
||||
}
|
||||
else if (fileHeader.Machine == 0x8664)//AMD64
|
||||
else if (fileHeader.Machine == 0x8664) //AMD64
|
||||
{
|
||||
var optionalHeader = ReadClass<OptionalHeader64>();
|
||||
optionalHeader.DataDirectory = ReadClassArray<DataDirectory>(optionalHeader.NumberOfRvaAndSizes);
|
||||
imageBase = optionalHeader.ImageBase;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("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()
|
||||
};
|
||||
throw new NotSupportedException("ERROR: Unsupported machine.");
|
||||
}
|
||||
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);
|
||||
return addr - (section.VirtualAddress - section.PointerToRawData);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,31 @@ using System.Text;
|
|||
|
||||
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 ushort Machine;
|
||||
|
@ -48,7 +73,7 @@ namespace Il2CppDumper
|
|||
public uint SizeOfHeapCommit;
|
||||
public uint LoaderFlags;
|
||||
public uint NumberOfRvaAndSizes;
|
||||
public DataDirectory[] DataDirectory { get; set; }
|
||||
//public DataDirectory[] DataDirectory;
|
||||
}
|
||||
|
||||
public class OptionalHeader64
|
||||
|
@ -82,18 +107,19 @@ namespace Il2CppDumper
|
|||
public ulong SizeOfHeapCommit;
|
||||
public uint LoaderFlags;
|
||||
public uint NumberOfRvaAndSizes;
|
||||
public DataDirectory[] DataDirectory { get; set; }
|
||||
//public DataDirectory[] DataDirectory;
|
||||
}
|
||||
|
||||
public class DataDirectory
|
||||
/*public class DataDirectory
|
||||
{
|
||||
public uint VirtualAddress;
|
||||
public uint Size;
|
||||
}
|
||||
}*/
|
||||
|
||||
public class SectionHeader
|
||||
{
|
||||
public string Name;
|
||||
[ArrayLength(Length = 8)]
|
||||
public byte[] Name;
|
||||
public uint VirtualSize;
|
||||
public uint VirtualAddress;
|
||||
public uint SizeOfRawData;
|
||||
|
@ -104,4 +130,12 @@ namespace Il2CppDumper
|
|||
public ushort NumberOfLinenumbers;
|
||||
public uint Characteristics;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SectionCharacteristics : uint
|
||||
{
|
||||
IMAGE_SCN_MEM_EXECUTE = 0x20000000,
|
||||
IMAGE_SCN_MEM_READ = 0x40000000,
|
||||
IMAGE_SCN_MEM_WRITE = 0x80000000
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace Il2CppDumper
|
|||
private BinaryReader reader;
|
||||
private BinaryWriter writer;
|
||||
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>();
|
||||
|
||||
public BinaryStream(Stream input)
|
||||
|
@ -23,6 +24,7 @@ namespace Il2CppDumper
|
|||
reader = new BinaryReader(stream, Encoding.UTF8, true);
|
||||
writer = new BinaryWriter(stream, Encoding.UTF8, true);
|
||||
readClass = GetType().GetMethod("ReadClass", Type.EmptyTypes);
|
||||
readClassArray = GetType().GetMethod("ReadClassArray", new[] { typeof(long) });
|
||||
}
|
||||
|
||||
public bool ReadBoolean() => reader.ReadBoolean();
|
||||
|
@ -101,7 +103,7 @@ namespace Il2CppDumper
|
|||
case "UInt64":
|
||||
return ReadUInt64();
|
||||
default:
|
||||
return null;
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +129,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
if (Attribute.IsDefined(i, typeof(VersionAttribute)))
|
||||
{
|
||||
versionAttribute = (VersionAttribute)Attribute.GetCustomAttribute(i, typeof(VersionAttribute));
|
||||
versionAttribute = i.GetCustomAttribute<VersionAttribute>();
|
||||
attributeCache.Add(i, versionAttribute);
|
||||
}
|
||||
}
|
||||
|
@ -140,16 +142,24 @@ namespace Il2CppDumper
|
|||
{
|
||||
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
|
||||
{
|
||||
if (!readClassCache.TryGetValue(i.FieldType, out var methodInfo))
|
||||
if (!genericMethodCache.TryGetValue(i.FieldType, out var methodInfo))
|
||||
{
|
||||
methodInfo = readClass.MakeGenericMethod(i.FieldType);
|
||||
readClassCache.Add(i.FieldType, methodInfo);
|
||||
genericMethodCache.Add(i.FieldType, methodInfo);
|
||||
}
|
||||
var value = methodInfo.Invoke(this, null);
|
||||
i.SetValue(t, value);
|
||||
break;
|
||||
i.SetValue(t, methodInfo.Invoke(this, null));
|
||||
}
|
||||
}
|
||||
return t;
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Attributes\ArrayLengthAttribute.cs" />
|
||||
<Compile Include="Extensions\BoyerMooreHorspool.cs" />
|
||||
<Compile Include="ExecutableFormats\ElfConstants.cs" />
|
||||
<Compile Include="Extensions\HexExtensions.cs" />
|
||||
|
|
|
@ -514,7 +514,6 @@ namespace Il2CppDumper
|
|||
var pointer = metadata.GetDefaultValueFromIndex(dataIndex);
|
||||
var defaultValueType = il2Cpp.types[typeIndex];
|
||||
metadata.Position = pointer;
|
||||
value = null;
|
||||
switch (defaultValueType.type)
|
||||
{
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
|
||||
|
|
Loading…
Reference in a new issue