29 #ifndef COFFI_WIN_HEADER_HPP
30 #define COFFI_WIN_HEADER_HPP
37 #if defined(__has_include) && __has_include(<gsl/narrow>)
39 using gsl::narrow_cast;
42 #define narrow_cast static_cast
56 std::fill_n(
reinterpret_cast<char*
>(&header),
sizeof(header),
'\0');
57 static const uint8_t default_stub[] = {
58 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01,
59 0x4C, 0xCD, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F,
60 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, 0x74,
61 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69, 0x6E, 0x20,
62 0x44, 0x4F, 0x53, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D,
63 0x0A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 std::fill_n(
reinterpret_cast<char*
>(&header),
sizeof(header),
'\0');
68 set_stub(
reinterpret_cast<const char*
>(default_stub),
69 sizeof(default_stub));
70 set_signature(
'M' + (
'Z' << 8));
71 set_bytes_in_last_block(144);
72 set_blocks_in_file(3);
73 set_header_paragraphs(4);
74 set_max_extra_paragraphs(65535);
76 set_reloc_table_offset(64);
77 set_pe_sign_location(
sizeof(
msdos_header) + get_stub_size());
83 COFFI_GET_SET_ACCESS(uint16_t, signature);
84 COFFI_GET_SET_ACCESS(uint16_t, bytes_in_last_block);
85 COFFI_GET_SET_ACCESS(uint16_t, blocks_in_file);
86 COFFI_GET_SET_ACCESS(uint16_t, num_relocs);
87 COFFI_GET_SET_ACCESS(uint16_t, header_paragraphs);
88 COFFI_GET_SET_ACCESS(uint16_t, min_extra_paragraphs);
89 COFFI_GET_SET_ACCESS(uint16_t, max_extra_paragraphs);
90 COFFI_GET_SET_ACCESS(uint16_t, ss);
91 COFFI_GET_SET_ACCESS(uint16_t, sp);
92 COFFI_GET_SET_ACCESS(uint16_t, checksum);
93 COFFI_GET_SET_ACCESS(uint16_t, ip);
94 COFFI_GET_SET_ACCESS(uint16_t, cs);
95 COFFI_GET_SET_ACCESS(uint16_t, reloc_table_offset);
96 COFFI_GET_SET_ACCESS(uint16_t, overlay_number);
97 COFFI_GET_SET_ACCESS(uint16_t, oem_id);
98 COFFI_GET_SET_ACCESS(uint16_t, oem_info);
99 COFFI_GET_SET_ACCESS(int32_t, pe_sign_location);
105 bool load(std::istream& stream)
110 char e_ident0[CI_NIDENT0];
111 stream.read(
reinterpret_cast<char*
>(&e_ident0),
sizeof(e_ident0));
112 if (stream.gcount() !=
sizeof(e_ident0)) {
117 if (e_ident0[CI_MAG0] != PEMAG0 || e_ident0[CI_MAG1] != PEMAG1) {
122 stream.read(
reinterpret_cast<char*
>(&header),
sizeof(header));
123 if (stream.gcount() !=
sizeof(header)) {
127 if (get_pe_sign_location() >
static_cast<int32_t
>(
sizeof(header))) {
128 stub_size_ = get_pe_sign_location() -
sizeof(header);
129 char* read_stub =
new char[stub_size_];
133 stream.read(read_stub, stub_size_);
135 if (stream.gcount() != stub_size_) {
140 stream.seekg(get_pe_sign_location());
143 char e_ident1[CI_NIDENT1];
144 stream.read(e_ident1, CI_NIDENT1);
145 if (stream.gcount() != CI_NIDENT1 || e_ident1[CI_MAG2] != PEMAG2 ||
146 e_ident1[CI_MAG3] != PEMAG3 || e_ident1[CI_MAG4] != PEMAG4 ||
147 e_ident1[CI_MAG5] != PEMAG5) {
155 void save(std::ostream& stream)
157 stream.write(
reinterpret_cast<char*
>(&header),
sizeof(header));
158 stream.write(stub_, stub_size_);
166 virtual const char* get_stub()
const {
return stub_; }
169 virtual uint32_t get_stub_size()
const {
return stub_size_; }
172 void set_stub(
const char* data, uint32_t size)
178 char* new_stub =
new char[stub_size_];
183 std::copy(data, data + size, new_stub);
189 void set_stub(
const std::string& data)
191 set_stub(data.c_str(), narrow_cast<uint32_t>(data.size()));
220 COFFI_GET_SET_ACCESS_DECL(uint16_t, version);
221 COFFI_GET_SET_ACCESS_DECL(uint16_t, machine);
222 COFFI_GET_SET_ACCESS_DECL(uint16_t, sections_count);
223 COFFI_GET_SET_ACCESS_DECL(uint32_t, time_data_stamp);
224 COFFI_GET_SET_ACCESS_DECL(uint32_t, symbol_table_offset);
225 COFFI_GET_SET_ACCESS_DECL(uint32_t, symbols_count);
226 COFFI_GET_SET_ACCESS_DECL(uint16_t, optional_header_size);
227 COFFI_GET_SET_ACCESS_DECL(uint16_t, flags);
228 COFFI_GET_SET_ACCESS_DECL(uint16_t, target_id);
230 COFFI_GET_SIZEOF_DECL();
233 virtual bool load(std::istream& stream) = 0;
234 virtual void save(std::ostream& stream) = 0;
249 std::fill_n(
reinterpret_cast<char*
>(&header),
sizeof(header),
'\0');
254 COFFI_GET_SET_ACCESS(uint16_t, sections_count);
255 COFFI_GET_SET_ACCESS(uint32_t, time_data_stamp);
256 COFFI_GET_SET_ACCESS(uint32_t, symbol_table_offset);
257 COFFI_GET_SET_ACCESS(uint32_t, symbols_count);
258 COFFI_GET_SET_ACCESS(uint16_t, optional_header_size);
259 COFFI_GET_SET_ACCESS(uint16_t, flags);
265 bool load(std::istream& stream)
267 stream.read(
reinterpret_cast<char*
>(&header),
sizeof(header));
268 if (stream.gcount() !=
sizeof(header)) {
276 void save(std::ostream& stream)
278 stream.write(
reinterpret_cast<char*
>(&header),
sizeof(header));
292 COFFI_GET_SET_ACCESS(uint16_t, machine);
293 COFFI_GET_SET_ACCESS_NONE(uint16_t, version);
294 COFFI_GET_SET_ACCESS_NONE(uint16_t, target_id);
304 COFFI_GET_SET_ACCESS(uint16_t, version);
305 COFFI_GET_SET_ACCESS(uint16_t, target_id);
306 COFFI_GET_SET_ACCESS_NONE(uint16_t, machine);
318 COFFI_GET_SET_ACCESS_DECL(uint16_t, magic);
319 COFFI_GET_SET_ACCESS_DECL(uint8_t, major_linker_version);
320 COFFI_GET_SET_ACCESS_DECL(uint8_t, minor_linker_version);
321 COFFI_GET_SET_ACCESS_DECL(uint16_t, linker_version);
322 COFFI_GET_SET_ACCESS_DECL(uint32_t, code_size);
323 COFFI_GET_SET_ACCESS_DECL(uint32_t, initialized_data_size);
324 COFFI_GET_SET_ACCESS_DECL(uint32_t, uninitialized_data_size);
325 COFFI_GET_SET_ACCESS_DECL(uint32_t, entry_point_address);
326 COFFI_GET_SET_ACCESS_DECL(uint32_t, code_base);
327 COFFI_GET_SET_ACCESS_DECL(uint32_t, data_base);
329 COFFI_GET_SIZEOF_DECL();
332 virtual bool load(std::istream& stream) = 0;
333 virtual void save(std::ostream& stream) = 0;
349 std::fill_n(
reinterpret_cast<char*
>(&header),
sizeof(header),
'\0');
355 COFFI_GET_SET_ACCESS(uint16_t, magic);
356 COFFI_GET_SET_ACCESS(uint32_t, code_size);
357 COFFI_GET_SET_ACCESS(uint32_t, initialized_data_size);
358 COFFI_GET_SET_ACCESS(uint32_t, uninitialized_data_size);
359 COFFI_GET_SET_ACCESS(uint32_t, entry_point_address);
360 COFFI_GET_SET_ACCESS(uint32_t, code_base);
366 bool load(std::istream& stream)
368 std::fill_n(
reinterpret_cast<char*
>(&header),
sizeof(header),
'\0');
369 stream.read(
reinterpret_cast<char*
>(&header),
sizeof(header));
370 if (stream.gcount() !=
sizeof(header)) {
377 void save(std::ostream& stream)
379 stream.write(
reinterpret_cast<char*
>(&header),
sizeof(header));
393 COFFI_GET_SET_ACCESS(uint8_t, major_linker_version);
394 COFFI_GET_SET_ACCESS(uint8_t, minor_linker_version);
395 COFFI_GET_SET_ACCESS_NONE(uint16_t, linker_version);
396 COFFI_GET_SET_ACCESS(uint32_t, data_base);
407 COFFI_GET_SET_ACCESS(uint8_t, major_linker_version);
408 COFFI_GET_SET_ACCESS(uint8_t, minor_linker_version);
409 COFFI_GET_SET_ACCESS_NONE(uint16_t, linker_version);
410 COFFI_GET_SET_ACCESS_NONE(uint32_t, data_base);
421 COFFI_GET_SET_ACCESS(uint16_t, linker_version);
422 COFFI_GET_SET_ACCESS_NONE(uint8_t, major_linker_version);
423 COFFI_GET_SET_ACCESS_NONE(uint8_t, minor_linker_version);
424 COFFI_GET_SET_ACCESS(uint32_t, data_base);
436 COFFI_GET_SET_ACCESS_DECL(uint64_t, image_base);
437 COFFI_GET_SET_ACCESS_DECL(uint32_t, section_alignment);
438 COFFI_GET_SET_ACCESS_DECL(uint32_t, file_alignment);
439 COFFI_GET_SET_ACCESS_DECL(uint16_t, major_os_version);
440 COFFI_GET_SET_ACCESS_DECL(uint16_t, minor_os_version);
441 COFFI_GET_SET_ACCESS_DECL(uint16_t, major_image_version);
442 COFFI_GET_SET_ACCESS_DECL(uint16_t, minor_image_version);
443 COFFI_GET_SET_ACCESS_DECL(uint16_t, major_subsystem_version);
444 COFFI_GET_SET_ACCESS_DECL(uint16_t, minor_subsystem_version);
445 COFFI_GET_SET_ACCESS_DECL(uint32_t, win32_version_value);
446 COFFI_GET_SET_ACCESS_DECL(uint32_t, image_size);
447 COFFI_GET_SET_ACCESS_DECL(uint32_t, headers_size);
448 COFFI_GET_SET_ACCESS_DECL(uint32_t, checksum);
449 COFFI_GET_SET_ACCESS_DECL(uint16_t, subsystem);
450 COFFI_GET_SET_ACCESS_DECL(uint16_t, dll_flags);
451 COFFI_GET_SET_ACCESS_DECL(uint64_t, stack_reserve_size);
452 COFFI_GET_SET_ACCESS_DECL(uint64_t, stack_commit_size);
453 COFFI_GET_SET_ACCESS_DECL(uint64_t, heap_reserve_size);
454 COFFI_GET_SET_ACCESS_DECL(uint64_t, heap_commit_size);
455 COFFI_GET_SET_ACCESS_DECL(uint32_t, loader_flags);
456 COFFI_GET_SET_ACCESS_DECL(uint32_t, number_of_rva_and_sizes);
458 COFFI_GET_SIZEOF_DECL();
461 virtual bool load(std::istream& f) = 0;
462 virtual void save(std::ostream& f) = 0;
478 std::fill_n(
reinterpret_cast<char*
>(&header),
sizeof(header),
'\0');
479 set_image_base(0x00400000);
480 set_file_alignment(512);
485 COFFI_GET_SET_ACCESS(uint64_t, image_base);
486 COFFI_GET_SET_ACCESS(uint32_t, section_alignment);
487 COFFI_GET_SET_ACCESS(uint32_t, file_alignment);
488 COFFI_GET_SET_ACCESS(uint16_t, major_os_version);
489 COFFI_GET_SET_ACCESS(uint16_t, minor_os_version);
490 COFFI_GET_SET_ACCESS(uint16_t, major_image_version);
491 COFFI_GET_SET_ACCESS(uint16_t, minor_image_version);
492 COFFI_GET_SET_ACCESS(uint16_t, major_subsystem_version);
493 COFFI_GET_SET_ACCESS(uint16_t, minor_subsystem_version);
494 COFFI_GET_SET_ACCESS(uint32_t, win32_version_value);
495 COFFI_GET_SET_ACCESS(uint32_t, image_size);
496 COFFI_GET_SET_ACCESS(uint32_t, headers_size);
497 COFFI_GET_SET_ACCESS(uint32_t, checksum);
498 COFFI_GET_SET_ACCESS(uint16_t, subsystem);
499 COFFI_GET_SET_ACCESS(uint16_t, dll_flags);
500 COFFI_GET_SET_ACCESS(uint64_t, stack_reserve_size);
501 COFFI_GET_SET_ACCESS(uint64_t, stack_commit_size);
502 COFFI_GET_SET_ACCESS(uint64_t, heap_reserve_size);
503 COFFI_GET_SET_ACCESS(uint64_t, heap_commit_size);
504 COFFI_GET_SET_ACCESS(uint32_t, loader_flags);
505 COFFI_GET_SET_ACCESS(uint32_t, number_of_rva_and_sizes);
511 bool load(std::istream& stream)
override
513 int read_size =
sizeof(header);
514 std::fill_n(
reinterpret_cast<char*
>(&header), read_size,
'\0');
515 stream.read(
reinterpret_cast<char*
>(&header), read_size);
516 if (stream.gcount() != read_size) {
524 void save(std::ostream& stream)
526 stream.write(
reinterpret_cast<char*
>(&header),
sizeof(header));