| 32 | } |
| 33 | |
| 34 | std::optional<SharedCacheMachOHeader> SharedCacheMachOHeader::ParseHeaderForAddress( |
| 35 | std::shared_ptr<VirtualMemory> vm, uint64_t address, const std::string& imagePath) |
| 36 | { |
| 37 | // Sanity check to make sure that the header is mapped. |
| 38 | // This should really only fail if we didn't grab all the required entries. |
| 39 | if (!vm->IsAddressMapped(address)) |
| 40 | return std::nullopt; |
| 41 | |
| 42 | SharedCacheMachOHeader header; |
| 43 | |
| 44 | header.textBase = address; |
| 45 | header.installName = imagePath; |
| 46 | // The identifierPrefix is used for the display of the image name in the sections and segments. |
| 47 | header.identifierPrefix = BaseFileName(imagePath); |
| 48 | |
| 49 | std::string errorMsg; |
| 50 | VirtualMemoryReader reader(vm); |
| 51 | reader.Seek(address); |
| 52 | |
| 53 | header.ident.magic = reader.ReadUInt32(); |
| 54 | |
| 55 | BNEndianness endianness; |
| 56 | switch (header.ident.magic) |
| 57 | { |
| 58 | case MH_MAGIC: |
| 59 | case MH_MAGIC_64: |
| 60 | endianness = LittleEndian; |
| 61 | break; |
| 62 | case MH_CIGAM: |
| 63 | case MH_CIGAM_64: |
| 64 | endianness = BigEndian; |
| 65 | break; |
| 66 | default: |
| 67 | return {}; |
| 68 | } |
| 69 | |
| 70 | reader.SetEndianness(endianness); |
| 71 | header.ident.cputype = reader.ReadUInt32(); |
| 72 | header.ident.cpusubtype = reader.ReadUInt32(); |
| 73 | header.ident.filetype = reader.ReadUInt32(); |
| 74 | header.ident.ncmds = reader.ReadUInt32(); |
| 75 | header.ident.sizeofcmds = reader.ReadUInt32(); |
| 76 | header.ident.flags = reader.ReadUInt32(); |
| 77 | if ((header.ident.cputype & MachOABIMask) == MachOABI64) // address size == 8 |
| 78 | { |
| 79 | header.ident.reserved = reader.ReadUInt32(); |
| 80 | } |
| 81 | header.loadCommandOffset = reader.GetOffset(); |
| 82 | |
| 83 | bool first = true; |
| 84 | // Parse segment commands |
| 85 | try |
| 86 | { |
| 87 | for (size_t i = 0; i < header.ident.ncmds; i++) |
| 88 | { |
| 89 | // BNLogInfo("of 0x%llx", reader.GetOffset()); |
| 90 | load_command load; |
| 91 | segment_command_64 segment64; |
nothing calls this directly
no test coverage detected