private static readonly byte[] FeatureBytes2 = { 0x78, 0x44, 0x79, 0x44 }; //ADD R0, PC and ADD R1, PC public Macho(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages) { Is32Bit = true; Position += 16; //skip magic, cputype, cpusubtype, filetype var ncmds = ReadUInt32(); Position += 8; //skip sizeofcmds, flags for (var i = 0; i < ncmds; i++) { var pos = Position; var cmd = ReadUInt32(); var cmdsize = ReadUInt32(); if (cmd == 1) //LC_SEGMENT { Position += 40; //skip segname, vmaddr, vmsize, fileoff, filesize, maxprot, initprot var nsects = ReadUInt32(); Position += 4; //skip flags for (var j = 0; j < nsects; j++) { 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 = pos + cmdsize;//next } }
public Macho(Stream stream, Action <string> reportProgressAction) : base(stream, reportProgressAction) { Is32Bit = true; Position += 16; //skip magic, cputype, cpusubtype, filetype var ncmds = ReadUInt32(); Position += 8; //skip sizeofcmds, flags for (var i = 0; i < ncmds; i++) { var pos = Position; var cmd = ReadUInt32(); var cmdsize = ReadUInt32(); switch (cmd) { case 1: //LC_SEGMENT var segname = Encoding.UTF8.GetString(ReadBytes(16)).TrimEnd('\0'); if (segname == "__TEXT") //__PAGEZERO { vmaddr = ReadUInt32(); } else { Position += 4; } Position += 20; //skip vmsize, fileoff, filesize, maxprot, initprot var nsects = ReadUInt32(); Position += 4; //skip flags for (var j = 0; j < nsects; j++) { 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 } break; case 0x21: //LC_ENCRYPTION_INFO Position += 8; var cryptID = ReadUInt32(); if (cryptID != 0) { reportProgressAction("ERROR: This Mach-O executable is encrypted and cannot be processed."); } break; } Position = pos + cmdsize;//next } }
private uint FindReference(uint pointer, MachoSection search) { var searchend = search.offset + search.size; Position = search.offset; while (Position < searchend) { if (ReadUInt32() == pointer) { return((uint)Position - search.offset + search.address);//MapRATV } } return(0); }
private uint FindCodeRegistration(int count, MachoSection search, MachoSection search2, MachoSection range) { var searchend = search.offset + search.size; var rangeend = range.address + range.size; var search2end = search2 == null ? 0 : search2.offset + search2.size; Position = search.offset; while (Position < searchend) { var add = Position; if (ReadUInt32() == count) { try { uint pointers = MapVATR(ReadUInt32()); if (pointers >= search.offset && pointers <= searchend) { var np = Position; var temp = ReadClassArray <uint>(pointers, count); var r = Array.FindIndex(temp, x => x <range.address || x> rangeend); if (r == -1) { return((uint)add - search.offset + search.address);//MapRATV } Position = np; } else if (search2 != null && pointers >= search2.offset && pointers <= search2end) { var np = Position; var temp = ReadClassArray <uint>(pointers, count); var r = Array.FindIndex(temp, x => x <range.address || x> rangeend); if (r == -1) { return((uint)add - search.offset + search.address);//MapRATV } Position = np; } } catch { // ignored } } } return(0); }
private uint FindMetadataRegistration(int typeDefinitionsCount, MachoSection search, MachoSection search2, MachoSection range) { var searchend = search.offset + search.size; var rangeend = range.address + range.size; var search2end = search2 == null ? 0 : search2.offset + search2.size; Position = search.offset; while (Position < searchend) { var add = Position; if (ReadUInt32() == typeDefinitionsCount) { try { var np = Position; Position += 8; uint pointers = MapVATR(ReadUInt32()); if (pointers >= search.offset && pointers <= searchend) { var temp = ReadClassArray <uint>(pointers, maxMetadataUsages); var r = Array.FindIndex(temp, x => x <range.address || x> rangeend); if (r == -1) { return((uint)add - 48u - search.offset + search.address); //VirtualAddress } } else if (search2 != null && pointers >= search2.offset && pointers <= search2end) { var temp = ReadClassArray <uint>(pointers, maxMetadataUsages); var r = Array.FindIndex(temp, x => x <range.address || x> rangeend); if (r == -1) { return((uint)add - 48u - search.offset + search.address); //VirtualAddress } } Position = np; } catch { // ignored } } } return(0); }
private uint FindPointersDesc(long readCount, MachoSection search, MachoSection range) { var add = 0; var searchend = search.offset + search.size; var rangeend = range.address + 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); if (r != -1) { add -= (int)((readCount - r) * 4); } else { return((uint)(search.address + search.size + add - 4 * readCount));//MapRATV } } return(0); }
private uint FindPointersAsc(long readCount, MachoSection search, MachoSection range) { var add = 0; var searchend = search.offset + search.size; var rangeend = range.address + 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); if (r != -1) { add += ++r * 4; } else { return(search.address + (uint)add);//MapRATV } } return(0); }