完善Macho文件的处理

细节调整
This commit is contained in:
Perfare 2019-04-12 06:24:38 +08:00
parent 7526e1fc21
commit 195eef8d7c
12 changed files with 130 additions and 184 deletions

View file

@ -104,7 +104,6 @@ namespace Il2CppDumper
public const int DT_SYMTAB = 6;
public const int DT_RELA = 7;
public const int DT_RELASZ = 8;
public const int DT_STRSZ = 10;
public const int DT_REL = 17;
public const int DT_RELSZ = 18;
public const int DT_INIT_ARRAY = 25;

View file

@ -296,7 +296,6 @@ namespace Il2CppDumper
uint dynsymOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_SYMTAB).d_un);
uint dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
var dynsymSize = dynstrOffset - dynsymOffset;
//var dynstrSize = dynamic_table.First(x => x.d_tag == DT_STRSZ).d_un;
uint reldynOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_REL).d_un);
var reldynSize = dynamic_table.First(x => x.d_tag == DT_RELSZ).d_un;
dynamic_symbol_table = ReadClassArray<Elf32_Sym>(dynsymOffset, dynsymSize / 16);
@ -379,14 +378,7 @@ namespace Il2CppDumper
}
var metadataRegistration = plusSearch.FindMetadataRegistration();
if (codeRegistration != 0 && metadataRegistration != 0)
{
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
Init(codeRegistration, metadataRegistration);
return true;
}
return false;
return AutoInit(codeRegistration, metadataRegistration);
}
public override bool SymbolSearch()

View file

@ -112,14 +112,7 @@ namespace Il2CppDumper
var codeRegistration = plusSearch.FindCodeRegistration64Bit();
plusSearch.SetPointerRangeSecond(data);
var metadataRegistration = plusSearch.FindMetadataRegistration64Bit();
if (codeRegistration != 0 && metadataRegistration != 0)
{
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
Init(codeRegistration, metadataRegistration);
return true;
}
return false;
return AutoInit(codeRegistration, metadataRegistration);
}
public override bool SymbolSearch()

View file

@ -36,6 +36,18 @@ namespace Il2CppDumper
this.maxMetadataUsages = maxMetadataUsages;
}
protected bool AutoInit(ulong codeRegistration, ulong metadataRegistration)
{
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
if (codeRegistration != 0 && metadataRegistration != 0)
{
Init(codeRegistration, metadataRegistration);
return true;
}
return false;
}
public virtual void Init(ulong codeRegistration, ulong metadataRegistration)
{
if (is32Bit)
@ -111,9 +123,9 @@ namespace Il2CppDumper
if (isNew21)
{
var ptr = fieldOffsets[typeIndex];
dynamic pos;
if (ptr >= 0)
{
dynamic pos;
if (is32Bit)
pos = MapVATR((uint)ptr) + 4 * fieldIndexInType;
else

View file

@ -17,36 +17,35 @@ namespace Il2CppDumper
public Macho(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
{
is32Bit = true;
Position += 16;//skip
Position += 16; //skip magic, cputype, cpusubtype, filetype
var ncmds = ReadUInt32();
Position += 8;//skip
Position += 8; //skip sizeofcmds, flags
for (var i = 0; i < ncmds; i++)
{
var offset = Position;
var loadCommandType = ReadUInt32();
var command_size = ReadUInt32();
if (loadCommandType == 1) //SEGMENT
var pos = Position;
var cmd = ReadUInt32();
var cmdsize = ReadUInt32();
if (cmd == 1) //LC_SEGMENT
{
var segment_name = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
if (segment_name == "__TEXT" || segment_name == "__DATA")
Position += 40; //skip segname, vmaddr, vmsize, fileoff, filesize, maxprot, initprot
var nsects = ReadUInt32();
Position += 4; //skip flags
for (var j = 0; j < nsects; j++)
{
Position += 24;//skip
var number_of_sections = ReadUInt32();
Position += 4;//skip
for (var j = 0; j < number_of_sections; j++)
{
var section_name = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
Position += 16;
var address = ReadUInt32();
var size = ReadUInt32();
var offset2 = ReadUInt32();
var end = address + size;
sections.Add(new MachoSection { section_name = section_name, address = address, size = size, offset = offset2, end = end });
Position += 24;
}
var section = new MachoSection();
sections.Add(section);
section.sectname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
Position += 16; //skip segname
section.addr = ReadUInt32();
section.size = ReadUInt32();
section.offset = ReadUInt32();
Position += 12; //skip align, reloff, nreloc
section.flags = ReadUInt32();
section.end = section.addr + section.size;
Position += 8; //skip reserved1, reserved2
}
}
Position = offset + command_size;//skip
Position = pos + cmdsize;//next
}
}
@ -59,15 +58,15 @@ namespace Il2CppDumper
public override dynamic MapVATR(dynamic uiAddr)
{
var section = sections.First(x => uiAddr >= x.address && uiAddr <= x.end);
return uiAddr - (section.address - section.offset);
var section = sections.First(x => uiAddr >= x.addr && uiAddr <= x.end);
return uiAddr - (section.addr - section.offset);
}
public override bool Search()
{
if (version < 21)
{
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
var addrs = ReadClassArray<uint>(__mod_init_func.offset, __mod_init_func.size / 4u);
foreach (var a in addrs)
{
@ -107,7 +106,7 @@ namespace Il2CppDumper
}
else
{
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
var addrs = ReadClassArray<uint>(__mod_init_func.offset, __mod_init_func.size / 4u);
foreach (var a in addrs)
{
@ -149,10 +148,10 @@ namespace Il2CppDumper
public override bool AdvancedSearch(int methodCount)
{
var __const = sections.First(x => x.section_name == "__const");
var __const2 = sections.Last(x => x.section_name == "__const");
var __text = sections.First(x => x.section_name == "__text");
var __common = sections.First(x => x.section_name == "__common");
var __const = sections.First(x => x.sectname == "__const");
var __const2 = sections.Last(x => x.sectname == "__const");
var __text = sections.First(x => x.sectname == "__text");
var __common = sections.First(x => x.sectname == "__common");
uint codeRegistration = 0;
uint metadataRegistration = 0;
var pmethodPointers = FindPointersAsc(methodCount, __const, __text);
@ -220,18 +219,18 @@ namespace Il2CppDumper
{
var add = 0;
var searchend = search.offset + search.size;
var rangeend = range.address + range.size;
var rangeend = range.addr + range.size;
while (search.offset + add < searchend)
{
var temp = ReadClassArray<int>(search.offset + add, readCount);
var r = Array.FindLastIndex(temp, x => x < range.address || x > rangeend);
var r = Array.FindLastIndex(temp, x => x < range.addr || x > rangeend);
if (r != -1)
{
add += ++r * 4;
}
else
{
return search.address + (uint)add; //VirtualAddress
return search.addr + (uint)add; //VirtualAddress
}
}
return 0;
@ -241,18 +240,18 @@ namespace Il2CppDumper
{
var add = 0;
var searchend = search.offset + search.size;
var rangeend = range.address + range.size;
var rangeend = range.addr + range.size;
while (searchend + add > search.offset)
{
var temp = ReadClassArray<int>(searchend + add - 4 * readCount, readCount);
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
var r = Array.FindIndex(temp, x => x < range.addr || x > rangeend);
if (r != -1)
{
add -= (int)((readCount - r) * 4);
}
else
{
return (uint)(search.address + search.size + add - 4 * readCount); //VirtualAddress
return (uint)(search.addr + search.size + add - 4 * readCount); //VirtualAddress
}
}
return 0;
@ -266,7 +265,7 @@ namespace Il2CppDumper
{
if (ReadUInt32() == pointer)
{
return (uint)Position - search.offset + search.address; //VirtualAddress
return (uint)Position - search.offset + search.addr; //VirtualAddress
}
}
return 0;
@ -274,34 +273,18 @@ namespace Il2CppDumper
public override bool PlusSearch(int methodCount, int typeDefinitionsCount)
{
var __const = sections.First(x => x.section_name == "__const");
var __const2 = sections.Last(x => x.section_name == "__const");
var __text = sections.First(x => x.section_name == "__text");
var __common = sections.First(x => x.section_name == "__common");
var data = sections.Where(x => x.sectname == "__const").ToArray();
var code = sections.Where(x => x.flags == 0x80000400).ToArray();
var bss = sections.Where(x => x.flags == 1u).ToArray();
var plusSearch = new PlusSearch(this, methodCount, typeDefinitionsCount, maxMetadataUsages);
plusSearch.SetSearch(__const, __const2);
plusSearch.SetPointerRangeFirst(__const2, __const2);
plusSearch.SetPointerRangeSecond(__text);
plusSearch.SetSearch(data);
plusSearch.SetPointerRangeFirst(data);
plusSearch.SetPointerRangeSecond(code);
var codeRegistration = plusSearch.FindCodeRegistration();
if (version == 16)
{
Console.WriteLine("WARNING: Version 16 can only get CodeRegistration");
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
return false;
}
plusSearch.SetPointerRangeSecond(__common);
plusSearch.SetPointerRangeSecond(bss);
var metadataRegistration = plusSearch.FindMetadataRegistration();
if (codeRegistration != 0 && metadataRegistration != 0)
{
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
Init(codeRegistration, metadataRegistration);
return true;
}
return false;
return AutoInit(codeRegistration, metadataRegistration);
}
public override bool SymbolSearch()

View file

@ -16,50 +16,49 @@ namespace Il2CppDumper
public Macho64(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
{
Position += 16;//skip
Position += 16; //skip magic, cputype, cpusubtype, filetype
var ncmds = ReadUInt32();
Position += 12;//skip
Position += 12; //skip sizeofcmds, flags, reserved
for (var i = 0; i < ncmds; i++)
{
var offset = Position;
var loadCommandType = ReadUInt32();
var command_size = ReadUInt32();
if (loadCommandType == 0x19) //SEGMENT_64
var pos = Position;
var cmd = ReadUInt32();
var cmdsize = ReadUInt32();
if (cmd == 0x19) //LC_SEGMENT_64
{
var segment_name = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
if (segment_name == "__TEXT" || segment_name == "__DATA" || segment_name == "__RODATA")
Position += 56; //skip segname, vmaddr, vmsize, fileoff, filesize, maxprot, initprot
var nsects = ReadUInt32();
Position += 4; //skip flags
for (var j = 0; j < nsects; j++)
{
Position += 40;//skip
var number_of_sections = ReadUInt32();
Position += 4;//skip
for (var j = 0; j < number_of_sections; j++)
{
var section_name = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
Position += 16;//skip
var address = ReadUInt64();
var size = ReadUInt64();
var offset2 = (uint)ReadUInt64();
var end = address + size;
sections.Add(new MachoSection64Bit { section_name = section_name, address = address, size = size, offset = offset2, end = end });
Position += 24;
}
var section = new MachoSection64Bit();
sections.Add(section);
section.sectname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0');
Position += 16; //skip segname
section.addr = ReadUInt64();
section.size = ReadUInt64();
section.offset = ReadUInt32();
Position += 12; //skip align, reloff, nreloc
section.flags = ReadUInt32();
section.end = section.addr + section.size;
Position += 12; //skip reserved1, reserved2, reserved3
}
}
Position = offset + command_size;//skip
Position = pos + cmdsize;//skip
}
}
public override dynamic MapVATR(dynamic uiAddr)
{
var section = sections.First(x => uiAddr >= x.address && uiAddr <= x.end);
return uiAddr - (section.address - section.offset);
var section = sections.First(x => uiAddr >= x.addr && uiAddr <= x.end);
return uiAddr - (section.addr - section.offset);
}
public override bool Search()
{
if (version < 23)
{
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
var addrs = ReadClassArray<ulong>(__mod_init_func.offset, (long)__mod_init_func.size / 8);
foreach (var i in addrs)
{
@ -100,7 +99,7 @@ namespace Il2CppDumper
* MOV W3, #0
* B sub
*/
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
var addrs = ReadClassArray<ulong>(__mod_init_func.offset, (long)__mod_init_func.size / 8);
foreach (var i in addrs)
{
@ -141,7 +140,7 @@ namespace Il2CppDumper
* MOV X2, #0
* B sub
*/
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
var __mod_init_func = sections.First(x => x.sectname == "__mod_init_func");
var addrs = ReadClassArray<ulong>(__mod_init_func.offset, (long)__mod_init_func.size / 8);
foreach (var i in addrs)
{
@ -177,11 +176,11 @@ namespace Il2CppDumper
public override bool AdvancedSearch(int methodCount)
{
var __consts = sections.Where(x => x.section_name == "__const").ToArray();
var __consts = sections.Where(x => x.sectname == "__const").ToArray();
var __const = __consts[0];
var __const2 = __consts[1];
var __text = sections.First(x => x.section_name == "__text");
var __common = sections.First(x => x.section_name == "__common");
var __text = sections.First(x => x.sectname == "__text");
var __common = sections.First(x => x.sectname == "__common");
ulong codeRegistration = 0;
ulong metadataRegistration = 0;
var pmethodPointers = FindPointersAsc(methodCount, __const, __text);
@ -249,18 +248,18 @@ namespace Il2CppDumper
{
var add = 0ul;
var searchend = search.offset + search.size;
var rangeend = range.address + range.size;
var rangeend = range.addr + range.size;
while (search.offset + add < searchend)
{
var temp = ReadClassArray<ulong>(search.offset + add, readCount);
var r = Array.FindLastIndex(temp, x => x < range.address || x > rangeend);
var r = Array.FindLastIndex(temp, x => x < range.addr || x > rangeend);
if (r != -1)
{
add += (ulong)(++r * 8);
}
else
{
return search.address + add; //VirtualAddress
return search.addr + add; //VirtualAddress
}
}
return 0;
@ -270,18 +269,18 @@ namespace Il2CppDumper
{
var add = 0L;
var searchend = search.offset + search.size;
var rangeend = range.address + range.size;
var rangeend = range.addr + range.size;
while (searchend + (ulong)add > search.offset)
{
var temp = ReadClassArray<ulong>((long)searchend + add - 8 * readCount, readCount);
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
var r = Array.FindIndex(temp, x => x < range.addr || x > rangeend);
if (r != -1)
{
add -= (readCount - r) * 8;
}
else
{
return search.address + search.size + (ulong)add - 8ul * (ulong)readCount; //VirtualAddress
return search.addr + search.size + (ulong)add - 8ul * (ulong)readCount; //VirtualAddress
}
}
return 0;
@ -295,7 +294,7 @@ namespace Il2CppDumper
{
if (ReadUInt64() == pointer)
{
return (ulong)Position - search.offset + search.address; //VirtualAddress
return (ulong)Position - search.offset + search.addr; //VirtualAddress
}
}
return 0;
@ -303,38 +302,18 @@ namespace Il2CppDumper
public override bool PlusSearch(int methodCount, int typeDefinitionsCount)
{
//TODO 使用flags处理可执行段和数据段
var __consts = sections.Where(x => x.section_name == "__const").ToArray();
var __const = __consts[0];
var __const2 = __consts[1];
var __text = sections.First(x => x.section_name == "__text");
var __common = sections.First(x => x.section_name == "__common");
var __il2cpp = sections.FirstOrDefault(x => x.section_name == ".il2cpp");
var __bss = sections.FirstOrDefault(x => x.section_name == "__bss");
var data = sections.Where(x => x.sectname == "__const").ToArray();
var code = sections.Where(x => x.flags == 0x80000400).ToArray();
var bss = sections.Where(x => x.flags == 1u).ToArray();
var plusSearch = new PlusSearch(this, methodCount, typeDefinitionsCount, maxMetadataUsages);
plusSearch.SetSearch(__const, __const2);
plusSearch.SetPointerRangeFirst(__const2, __const2);
plusSearch.SetPointerRangeSecond(__text, __il2cpp);
plusSearch.SetSearch(data);
plusSearch.SetPointerRangeFirst(data);
plusSearch.SetPointerRangeSecond(code);
var codeRegistration = plusSearch.FindCodeRegistration64Bit();
if (version == 16)
{
Console.WriteLine("WARNING: Version 16 can only get CodeRegistration");
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
return false;
}
plusSearch.SetPointerRangeSecond(__bss, __common);
plusSearch.SetPointerRangeSecond(bss);
var metadataRegistration = plusSearch.FindMetadataRegistration64Bit();
if (codeRegistration != 0 && metadataRegistration != 0)
{
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
Init(codeRegistration, metadataRegistration);
return true;
}
return false;
return AutoInit(codeRegistration, metadataRegistration);
}
public override bool SymbolSearch()

View file

@ -7,25 +7,27 @@ namespace Il2CppDumper
{
public class MachoSection
{
public string section_name;
public uint address;
public string sectname;
public uint addr;
public uint size;
public uint offset;
public uint flags;
public uint end;
}
public class MachoSection64Bit
{
public string section_name;
public ulong address;
public string sectname;
public ulong addr;
public ulong size;
public ulong offset;
public uint flags;
public ulong end;
}
public class Fat
{
public uint file_offset;
public uint offset;
public uint size;
public uint magic;
}

View file

@ -20,20 +20,20 @@ namespace Il2CppDumper
{
Position += 8;
fats[i] = new Fat();
fats[i].file_offset = BitConverter.ToUInt32(ReadBytes(4).Reverse().ToArray(), 0);
fats[i].offset = BitConverter.ToUInt32(ReadBytes(4).Reverse().ToArray(), 0);
fats[i].size = BitConverter.ToUInt32(ReadBytes(4).Reverse().ToArray(), 0);
Position += 4;
}
for (var i = 0; i < size; i++)
{
Position = fats[i].file_offset;
Position = fats[i].offset;
fats[i].magic = ReadUInt32();
}
}
public byte[] GetMacho(int index)
{
Position = fats[index].file_offset;
Position = fats[index].offset;
return ReadBytes((int)fats[index].size);
}
}

View file

@ -69,7 +69,7 @@ namespace Il2CppDumper
metadataUsageLists = ReadMetadataClassArray<Il2CppMetadataUsageList>(metadataHeader.metadataUsageListsOffset, metadataHeader.metadataUsageListsCount);
metadataUsagePairs = ReadMetadataClassArray<Il2CppMetadataUsagePair>(metadataHeader.metadataUsagePairsOffset, metadataHeader.metadataUsagePairsCount);
CreateStringLiteralDic();
ProcessingMetadataUsage();
fieldRefs = ReadMetadataClassArray<Il2CppFieldRef>(metadataHeader.fieldRefsOffset, metadataHeader.fieldRefsCount);
}
@ -132,7 +132,7 @@ namespace Il2CppDumper
return Encoding.UTF8.GetString(ReadBytes((int)stringLiteral.length));
}
private void CreateStringLiteralDic()
private void ProcessingMetadataUsage()
{
metadataUsageDic = new Dictionary<uint, SortedDictionary<uint, uint>>();
for (uint i = 1; i <= 6u; i++)
@ -150,7 +150,7 @@ namespace Il2CppDumper
metadataUsageDic[usage][metadataUsagePair.destinationIndex] = decodedIndex;
}
}
maxMetadataUsages = metadataUsageDic[5].Last().Key + 1;
maxMetadataUsages = metadataUsageDic.Max(x => x.Value.Max(y => y.Key)) + 1;
}
private uint GetEncodedIndexType(uint index)

View file

@ -116,14 +116,7 @@ namespace Il2CppDumper
var codeRegistration = plusSearch.FindCodeRegistration64Bit();
plusSearch.SetPointerRangeSecond(header.BssSegment);
var metadataRegistration = plusSearch.FindMetadataRegistration64Bit();
if (codeRegistration != 0 && metadataRegistration != 0)
{
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
Init(codeRegistration, metadataRegistration);
return true;
}
return false;
return AutoInit(codeRegistration, metadataRegistration);
}
public override bool SymbolSearch()

View file

@ -110,14 +110,7 @@ namespace Il2CppDumper
plusSearch.SetPointerRangeSecond(imageBase, data);
metadataRegistration = plusSearch.FindMetadataRegistration64Bit();
}
if (codeRegistration != 0 && metadataRegistration != 0)
{
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
Init(codeRegistration, metadataRegistration);
return true;
}
return false;
return AutoInit(codeRegistration, metadataRegistration);
}
public override bool SymbolSearch()

View file

@ -38,7 +38,7 @@ namespace Il2CppDumper
{
start = section.offset,
end = section.offset + section.size,
address = section.address
address = section.addr
});
}
}
@ -54,7 +54,7 @@ namespace Il2CppDumper
{
start = section.offset,
end = section.offset + section.size,
address = section.address
address = section.addr
});
}
}
@ -166,7 +166,7 @@ namespace Il2CppDumper
{
start = section.offset,
end = section.offset + section.size,
address = section.address
address = section.addr
});
}
}
@ -182,7 +182,7 @@ namespace Il2CppDumper
{
start = section.offset,
end = section.offset + section.size,
address = section.address
address = section.addr
});
}
}
@ -293,9 +293,9 @@ namespace Il2CppDumper
{
pointerRange2.Add(new Section
{
start = section.address,
end = section.address + section.size,
address = section.address
start = section.addr,
end = section.addr + section.size,
address = section.addr
});
}
}
@ -310,9 +310,9 @@ namespace Il2CppDumper
{
pointerRange2.Add(new Section
{
start = section.address,
end = section.address + section.size,
address = section.address
start = section.addr,
end = section.addr + section.size,
address = section.addr
});
}
}