添加数组类型读取

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)
{
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
{

View file

@ -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
{

View file

@ -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;

View file

@ -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;

View file

@ -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
{
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);
}

View file

@ -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
}
}

View file

@ -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;

View file

@ -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" />

View file

@ -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: