MCPcopy Create free account
hub / github.com/D7EAD/mkPIVM / parse_pe

Function parse_pe

src/pe_embed.cpp:103–160  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

101 };
102
103 PeView parse_pe(std::vector<std::uint8_t> raw) {
104 PeView v;
105 v.bytes = std::move(raw);
106 if (v.bytes.size() < sizeof(IMAGE_DOS_HEADER)) throw Error("target PE too small for DOS header");
107
108 auto* dos = reinterpret_cast<IMAGE_DOS_HEADER*>(v.bytes.data());
109 if (dos->e_magic != kDosMagic) throw Error("target PE: bad DOS magic");
110
111 v.nt_off = static_cast<std::size_t>(dos->e_lfanew);
112 if (v.nt_off + sizeof(std::uint32_t) + sizeof(IMAGE_FILE_HEADER) > v.bytes.size()) throw Error("target PE: NT headers out of range");
113
114 const std::uint32_t sig = *reinterpret_cast<std::uint32_t*>(v.bytes.data() + v.nt_off);
115 if (sig != kPeMagic) throw Error("target PE: bad NT signature");
116
117 v.file_hdr_off = v.nt_off + 4;
118 auto* fh = reinterpret_cast<IMAGE_FILE_HEADER*>(v.bytes.data() + v.file_hdr_off);
119
120 v.num_sections = fh->NumberOfSections;
121 v.opt_hdr_off = v.file_hdr_off + sizeof(IMAGE_FILE_HEADER);
122
123 const std::uint16_t opt_magic = *reinterpret_cast<std::uint16_t*>(v.bytes.data() + v.opt_hdr_off);
124 if (opt_magic == kOpt64) {
125 v.is64 = true;
126 if (v.opt_hdr_off + sizeof(IMAGE_OPTIONAL_HEADER64) > v.bytes.size()) throw Error("target PE: PE32+ optional header out of range");
127 auto* o = reinterpret_cast<IMAGE_OPTIONAL_HEADER64*>(v.bytes.data() + v.opt_hdr_off);
128
129 v.file_alignment = o->FileAlignment;
130 v.section_alignment = o->SectionAlignment;
131 v.size_of_headers = o->SizeOfHeaders;
132 v.size_of_image = o->SizeOfImage;
133 v.dll_characteristics = o->DllCharacteristics;
134 v.image_base = o->ImageBase;
135 v.old_reloc_rva = o->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
136 v.old_reloc_size = o->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
137 }
138 else if (opt_magic == kOpt32) {
139 if (v.opt_hdr_off + sizeof(IMAGE_OPTIONAL_HEADER32) > v.bytes.size()) throw Error("target PE: PE32 optional header out of range");
140 auto* o = reinterpret_cast<IMAGE_OPTIONAL_HEADER32*>( v.bytes.data() + v.opt_hdr_off);
141
142 v.file_alignment = o->FileAlignment;
143 v.section_alignment = o->SectionAlignment;
144 v.size_of_headers = o->SizeOfHeaders;
145 v.size_of_image = o->SizeOfImage;
146 v.dll_characteristics = o->DllCharacteristics;
147 v.image_base = o->ImageBase;
148 v.old_reloc_rva = o->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
149 v.old_reloc_size = o->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
150 }
151 else {
152 throw Error(fmt::format("target PE: unknown OptionalHeader magic 0x{:04x}", opt_magic));
153 }
154
155 v.section_tbl_off = v.opt_hdr_off + fh->SizeOfOptionalHeader;
156 if (v.section_tbl_off + v.num_sections * sizeof(IMAGE_SECTION_HEADER) > v.bytes.size()) throw Error("target PE: section table out of range");
157 if (v.file_alignment == 0 || v.section_alignment == 0) throw Error("target PE: zero alignment values");
158
159 return v;
160 }

Callers 1

embed_vm_blobFunction · 0.85

Calls 2

ErrorClass · 0.85
sizeMethod · 0.45

Tested by

no test coverage detected