RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
peexe.h
1#ifndef PEEXE_H
2#define PEEXE_H
3
4#include <array>
5#include "../common.h"
6#include "../dumper/dumper.h"
7#include "../linker/options.h"
8#include "../linker/segment_manager.h"
9#include "coff.h"
10#include "mzexe.h"
11#include "neexe.h"
12
13namespace Microsoft
14{
19 {
20 public:
21 std::array<char, 4> pe_signature;
22
25 {
26 uint16_t major, minor;
27 };
28
31 {
32 public:
34 static constexpr uint16_t ROM32 = 0x0107;
36 static constexpr uint16_t EXE32 = 0x010B;
38 static constexpr uint16_t EXE64 = 0x020B;
39
41 static constexpr offset_t Win32Base = 0x00400000;
43 static constexpr offset_t Dll32Base = 0x10000000;
45 static constexpr offset_t WinCEBase = 0x00010000;
47 static constexpr offset_t Win64Base = 0x140000000;
49 static constexpr offset_t Dll64Base = 0x180000000;
50
54 offset_t image_base = 0;
58 uint32_t section_align = 0;
62 uint32_t file_align = 0;
78 uint32_t win32_version = 0;
82 uint32_t total_image_size = 0;
86 uint32_t total_headers_size = 0;
90 uint32_t checksum = 0;
92 enum SubsystemType : uint16_t
93 {
94 Unknown = 0,
95 Native = 1,
96 WindowsGUI = 2,
97 WindowsCUI = 3,
98 OS2CUI = 5,
99 POSIXCUI = 7,
100 NativeWin95 = 8,
101 WinCEGUI = 9,
102 EFIApplication = 10,
103 EFIBootServiceDriver = 11,
104 EFIRuntimeDriver = 12,
105 EFIROM = 13,
106 Xbox = 14,
107 WindowsBootApplication = 16,
108 };
116 uint16_t flags = 0;
128 offset_t reserved_heap_size = 0;
136 uint32_t loader_flags = 0;
137
140 {
141 uint32_t address = 0, size = 0;
142 };
143
144 enum
145 {
146 DirExportTable,
147 DirImportTable,
148 DirResourceTable,
149 DirExceptionTable,
150 DirCertificateTable,
151 DirBaseRelocationTable,
152 DirDebug,
153 DirArchitecture, // reserved
154 DirGlobalPointer,
155 DirTLSTable,
156 DirLoadConfigTable,
157 DirBoundImport,
158 DirIAT,
159 DirDelayImportDescriptor,
160 DirCLRRuntimeHeader,
161 DirReserved,
162 DirTotalCount,
163 };
164
168 std::vector<DataDirectory> data_directories;
169
171 bool Is64Bit() const;
172
174 : AOutHeader()
175 {
176 }
177
178 uint32_t GetSize() const override;
179
180 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
181
182 void WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
183
184 offset_t CalculateValues(COFFFormat& coff) override;
185
187 uint32_t AddressToRVA(offset_t address) const;
189 offset_t RVAToAddress(uint32_t rva, bool suppress_on_zero = false) const;
190
191 std::string GetHeaderFormatName(const COFFFormat& coff) const override;
192
193 protected:
194 void DumpFields(const COFFFormat& coff, Dumper::Dumper& dump, Dumper::Region& header_region) const override;
195 };
196
198 PEOptionalHeader& GetOptionalHeader();
200 const PEOptionalHeader& GetOptionalHeader() const;
201
203 bool Is64Bit() const;
204
206 uint32_t AddressToRVA(offset_t address) const;
208 offset_t RVAToAddress(uint32_t rva, bool suppress_on_zero = false) const;
210 offset_t RVAToFileOffset(uint32_t rva) const;
211
214 {
215 public:
216 // TODO: other flags
218 static constexpr uint32_t DISCARDABLE = 0x02000000;
220 static constexpr uint32_t EXECUTE = 0x20000000;
222 static constexpr uint32_t READ = 0x40000000;
224 static constexpr uint32_t WRITE = 0x80000000;
225
226 Section(uint32_t flags = 0, std::shared_ptr<Linker::Contents> image = nullptr)
227 : COFFFormat::Section(flags, image)
228 {
229 }
230
232 constexpr offset_t& virtual_size() { return physical_address; }
234 constexpr const offset_t& virtual_size() const { return physical_address; }
235
236 void ReadSectionData(const std::shared_ptr<Linker::Reader>& rd, const COFFFormat& coff_format) override;
237 void WriteSectionData(const std::shared_ptr<Linker::Writer>& wr, const COFFFormat& coff_format) const override;
238 uint32_t ImageSize(const COFFFormat& coff_format) const override;
239 void Dump(Dumper::Dumper& dump, const COFFFormat& format, unsigned section_index) const override;
240
242 virtual void ReadSectionData(const std::shared_ptr<Linker::Reader>& rd, const PEFormat& fmt);
244 virtual void WriteSectionData(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt) const;
246 virtual uint32_t ImageSize(const PEFormat& fmt) const;
248 virtual uint32_t MemorySize(const PEFormat& fmt) const;
249
250 size_t ReadData(size_t bytes, size_t offset, void * buffer) const;
251 };
252
255 {
256 const PEFormat * pe;
257 struct iterator
258 {
259 std::vector<std::shared_ptr<COFFFormat::Section>>::iterator coff_iterator;
260 bool operator !=(const iterator& other) const;
261 iterator& operator++();
262 std::shared_ptr<PEFormat::Section> operator*() const;
263 };
265 {
266 std::vector<std::shared_ptr<COFFFormat::Section>>::const_iterator coff_iterator;
267 bool operator !=(const const_iterator& other) const;
268 const_iterator& operator++();
269 std::shared_ptr<const PEFormat::Section> operator*() const;
270 };
272 {
273 std::vector<std::shared_ptr<COFFFormat::Section>>::const_reference coff_reference;
274 PEFormat::Section * get() const;
275 PEFormat::Section * operator->() const;
276 };
277 iterator begin();
278 const_iterator begin() const;
279 iterator end();
280 const_iterator end() const;
281 size_t size() const;
282 const_reference back() const;
283 };
284
286 const PESections Sections() const;
289
302 size_t MapRVAToSectionData(uint32_t rva, size_t bytes, std::shared_ptr<Section>& found_section, size_t& section_offset) const;
303
305 size_t ReadData(size_t bytes, uint32_t rva, void * buffer) const;
307 uint64_t ReadUnsigned(size_t bytes, uint32_t rva, ::EndianType endiantype) const;
309 int64_t ReadSigned(size_t bytes, uint32_t rva, ::EndianType endiantype) const;
311 std::string ReadASCII(uint32_t rva, char terminator, size_t maximum = size_t(-1)) const;
313 std::string ReadData(uint32_t rva, size_t count) const;
314
316 template <typename Clock = POSIX_clock>
317 Timestamp<Clock> ReadTimestamp(uint32_t rva, EndianType endiantype) const
318 {
319 if constexpr(std::is_signed_v<typename Clock::rep>)
320 return Clock::to_time_point(ReadSigned(sizeof(typename Clock::rep), rva, endiantype));
321 else
322 return Clock::to_time_point(ReadUnsigned(sizeof(typename Clock::rep), rva, endiantype));
323 }
324
325 class MemoryPortionImage : public virtual Linker::Image
326 {
327 public:
328 const PEFormat& fmt;
329 uint32_t rva;
330 uint32_t size;
331
332 MemoryPortionImage(const PEFormat& fmt, uint32_t rva, uint32_t size)
333 : fmt(fmt), rva(rva), size(size)
334 {
335 }
336
337 offset_t ImageSize() const override;
338 size_t ReadData(size_t bytes, offset_t offset, void * buffer) const override;
339 };
340
343 {
344 public:
346 typedef std::variant<std::string, uint32_t> Identifier;
347
349 static constexpr size_t Level_Type = 0;
351 static constexpr size_t Level_Name = 1;
353 static constexpr size_t Level_Language = 2;
355 static constexpr size_t Level_Count = 3;
356
358 static void DumpIdentifier(std::vector<Identifier> full_identifier, Dumper::Container& container);
359
361 std::vector<Identifier> full_identifier;
363 uint32_t data_rva = 0;
365 uint32_t size = 0;
367 uint32_t codepage = 0;
369 uint32_t reserved = 0;
370
372 std::shared_ptr<Linker::Section> section = nullptr;
373
374 Resource(const std::vector<Resource::Identifier>& full_identifier)
376 {
377 }
378
380 size_t ParseResourceData(const PEFormat& fmt, uint32_t rva);
382 void DumpResource(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t rva) const;
384 uint32_t AssignAddress(PEFormat& fmt, uint32_t rva);
386 void WriteDirectories(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt, uint32_t section_pointer) const;
388 offset_t WriteResource(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt, uint32_t rva_to_offset) const;
389 };
390
391 class ResourcesSection;
392
394 {
395 public:
396 class Name
397 {
398 public:
399 std::string name;
400 uint32_t offset = 0;
401
402 Name(std::string name = "")
403 : name(name)
404 {
405 }
406 };
407
409 template <typename Key>
410 class Entry
411 {
412 public:
416 std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourceDirectory>> content;
418 uint32_t content_offset = 0;
419
420 bool IsSubdirectory() const { return std::get_if<std::shared_ptr<ResourceDirectory>>(&content); }
421 };
422
424 uint32_t flags = 0;
425 ::Timestamp<POSIX_clock> timestamp = { };
426 version_type version = { };
428 std::vector<Entry<Name>> name_entries;
430 std::vector<Entry<uint32_t>> id_entries;
431
437 void AddResource(std::shared_ptr<Resource>& resource, size_t level = 0);
438
440 size_t ParseResourceDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t rva, const std::vector<Resource::Identifier>& partial_identifier);
442 void DumpResourceDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t rva, const std::vector<Resource::Identifier>& partial_identifier, size_t dump_level) const;
444 uint32_t CalculateDirectoryOffsets(PEFormat& fmt, uint32_t offset, size_t level_deeper);
446 void CollectSubdirectoryStrings(PEFormat& fmt, ResourcesSection& rsrc, size_t level_deeper);
448 uint32_t CollectResourceData(PEFormat& fmt, uint32_t rva, size_t level_deeper);
450 void WriteDirectories(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt, uint32_t section_pointer) const;
452 offset_t WriteResources(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt, uint32_t rva_to_offset) const;
453 };
454
457 {
458 public:
460 : Section(DATA | READ)
461 {
462 name = ".rsrc";
463 }
464
465 size_t max_depth = 0;
466 protected:
467 std::vector<std::string> string_table;
468 std::map<std::string, uint32_t> string_table_map;
469 uint32_t string_table_offset = 0;
470 uint32_t string_table_end_offset = 0;
471 public:
472 uint32_t FetchString(std::string s);
473
474 using Section::ReadSectionData;
475 using Section::WriteSectionData;
476 using Section::ImageSize;
477
478 bool IsPresent() const;
479 void Generate(PEFormat& fmt);
480 void ReadSectionData(const std::shared_ptr<Linker::Reader>& rd, const PEFormat& fmt) override;
481 void WriteSectionData(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt) const override;
482 uint32_t ImageSize(const PEFormat& fmt) const override;
483 uint32_t MemorySize(const PEFormat& fmt) const override;
484
486 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
488 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
489 };
490
492 std::shared_ptr<ResourcesSection> resources = std::make_shared<ResourcesSection>();
493
496 {
497 public:
498 typedef uint16_t Ordinal;
499
501 class Name
502 {
503 public:
505 uint16_t hint;
507 std::string name = "";
509 uint32_t rva = 0;
510
511 Name(std::string name, uint16_t hint = 0)
512 : hint(hint), name(name)
513 {
514 }
515 };
516
518 typedef std::variant<Ordinal, Name> ImportTableEntry;
519
521 uint32_t lookup_table_rva = 0;
523 uint32_t address_table_rva = 0;
524 ::Timestamp<POSIX_clock> timestamp = { };
525 uint32_t forwarder_chain = 0;
527 std::string name;
529 uint32_t name_rva = 0;
530
532 std::vector<ImportTableEntry> import_table;
534 std::map<std::string, size_t> imports_by_name;
536 std::map<Ordinal, size_t> imports_by_ordinal;
537
539 void AddImportByName(std::string entry_name, uint16_t hint);
541 void AddImportByOrdinal(uint16_t ordinal);
542
544 offset_t GetImportByNameAddress(const PEFormat& fmt, std::string name);
546 offset_t GetImportByOrdinalAddress(const PEFormat& fmt, uint16_t ordinal);
547
548 ImportedLibrary(std::string name)
549 : name(name)
550 {
551 }
552 };
553
555 class ImportsSection : public Section
556 {
557 public:
559 std::vector<ImportedLibrary> libraries;
561 std::map<std::string, size_t> library_indexes;
562
567
569 : Section(DATA | READ | WRITE)
570 {
571 name = ".idata";
572 }
573
574 using Section::ReadSectionData;
575 using Section::WriteSectionData;
576 using Section::ImageSize;
577
578 bool IsPresent() const;
579 void Generate(PEFormat& fmt);
580 void ReadSectionData(const std::shared_ptr<Linker::Reader>& rd, const PEFormat& fmt) override;
581 void WriteSectionData(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt) const override;
582 uint32_t ImageSize(const PEFormat& fmt) const override;
583 uint32_t MemorySize(const PEFormat& fmt) const override;
584
586 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
588 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
589 };
590
592 std::shared_ptr<ImportsSection> imports = std::make_shared<ImportsSection>();
593
596 {
597 public:
604 {
605 public:
607 std::string dll_name;
609 std::variant<std::string, uint32_t> reference;
611 std::string reference_name;
613 uint32_t rva;
614 };
615
617 class Name
618 {
619 public:
621 std::string name;
623 uint32_t rva = 0;
624
625 Name(std::string name)
626 : name(name)
627 {
628 }
629 };
630
632 std::variant<uint32_t, Forwarder> value;
634 std::optional<Name> name;
635
636 ExportedEntry(uint32_t rva)
637 : value(rva), name()
638 {
639 }
640
641 ExportedEntry(uint32_t rva, std::string name)
642 : value(rva), name(name)
643 {
644 }
645
646 ExportedEntry(Forwarder fwd)
647 : value(fwd), name()
648 {
649 }
650 };
651
653 class ExportsSection : public Section
654 {
655 public:
656 uint32_t flags = 0;
657 ::Timestamp<POSIX_clock> timestamp = { };
658 version_type version = { };
660 std::string dll_name;
662 uint32_t dll_name_rva = 0;
664 uint32_t ordinal_base = 1;
668 uint32_t address_table_rva = 0;
670 uint32_t name_table_rva = 0;
672 uint32_t ordinal_table_rva = 0;
674 std::map<uint32_t, std::shared_ptr<ExportedEntry>> entries;
676 std::map<std::string, uint32_t> named_exports;
677
679 void SetEntry(PEFormat& fmt, uint32_t ordinal, std::shared_ptr<ExportedEntry> entry);
681 void AddEntry(PEFormat& fmt, std::shared_ptr<ExportedEntry> entry);
682
684 : Section(DATA | READ)
685 {
686 name = ".edata";
687 // TODO: flags and other fields
688 }
689
690 using Section::ReadSectionData;
691 using Section::WriteSectionData;
692 using Section::ImageSize;
693
694 bool IsPresent() const;
695 void Generate(PEFormat& fmt);
696 void ReadSectionData(const std::shared_ptr<Linker::Reader>& rd, const PEFormat& fmt) override;
697 void WriteSectionData(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt) const override;
698 uint32_t ImageSize(const PEFormat& fmt) const override;
699 uint32_t MemorySize(const PEFormat& fmt) const override;
700
702 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
704 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
705 };
706
708 std::shared_ptr<ExportsSection> exports = std::make_shared<ExportsSection>();
709
760
763 {
764 public:
766 static constexpr uint32_t PAGE_SIZE = 0x1000;
768 uint32_t page_rva;
770 uint32_t block_size;
772 std::vector<BaseRelocation> relocations_list;
774 std::map<uint16_t, BaseRelocation> relocations_map;
775
776 BaseRelocationBlock(uint32_t page_rva = 0)
777 : page_rva(page_rva & ~(PAGE_SIZE - 1))
778 {
779 }
780 };
781
784 {
785 public:
787 std::vector<std::shared_ptr<BaseRelocationBlock>> blocks_list;
789 std::map<uint32_t, std::shared_ptr<BaseRelocationBlock>> blocks_map;
790
793 {
794 name = ".reloc";
795 }
796
797 using Section::ReadSectionData;
798 using Section::WriteSectionData;
799 using Section::ImageSize;
800
801 bool IsPresent() const;
802 void Generate(PEFormat& fmt);
803 void ReadSectionData(const std::shared_ptr<Linker::Reader>& rd, const PEFormat& fmt) override;
804 void WriteSectionData(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt) const override;
805 uint32_t ImageSize(const PEFormat& fmt) const override;
806 uint32_t MemorySize(const PEFormat& fmt) const override;
807
809 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
811 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
812 };
813
815 std::shared_ptr<BaseRelocationsSection> base_relocations = std::make_shared<BaseRelocationsSection>();
816
823 void AddBaseRelocation(uint32_t rva, BaseRelocation::relocation_type type, uint16_t low_ref = 0);
824
825 // TODO: document
826 // TODO: should this be an actual section?
828 {
829 public:
831 : Section(TEXT | EXECUTE) // TODO: are these the correct flags?
832 {
833 name = ".cormeta"; // TODO: is this the correct name?
834 }
835
836 using Section::ReadSectionData;
837 using Section::WriteSectionData;
838 using Section::ImageSize;
839
840 void ReadSectionData(const std::shared_ptr<Linker::Reader>& rd, const PEFormat& fmt) override;
841 void WriteSectionData(const std::shared_ptr<Linker::Writer>& wr, const PEFormat& fmt) const override;
842 uint32_t ImageSize(const PEFormat& fmt) const override;
843 uint32_t MemorySize(const PEFormat& fmt) const override;
844
846 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
848 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
849 };
850
851 // TODO: document
852 std::shared_ptr<CLRHeaderSection> clr_header = std::make_shared<CLRHeaderSection>();
853
854 mutable MZStubWriter stub;
855
856 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
857
858 ::EndianType GetMachineEndianType() const;
859 void CalculateValues() override;
860
862 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
863 void Dump(Dumper::Dumper& dump) const override;
864
878
879 compatibility_type compatibility = CompatibleNone;
880
883 {
891 TargetMacintosh, // TODO: not supported
895 TargetTNT, // TODO: not supported
897 TargetEFI, // TODO: not supported
899 TargetDotNET, // TODO: not supported
901 TargetXbox, // TODO: not supported
902 //TargetBeOS, // TODO: possible target
903 //TargetSkyOS, // TODO: possible target
904 //TargetHXDOS, // TODO: possible target
905 };
908
919 /*** @brief Whether to generate an executable, library or system file */
920 output_type output = OUTPUT_EXE;
921
922 PEFormat(target_type target = TargetWinNT, PEOptionalHeader::SubsystemType subsystem = PEOptionalHeader::WindowsGUI, output_type output = OUTPUT_EXE)
923 : COFFFormat(WINDOWS, PECOFF, ::LittleEndian), target(target), output(output)
924 {
925 optional_header = std::make_unique<PEOptionalHeader>();
926 GetOptionalHeader().subsystem = subsystem;
927 }
928
929 public:
930 /* * * Writer members * * */
931
934
937
940
943
945 bool option_debug_info = false;
946
949
951 std::shared_ptr<Linker::Segment> import_thunk_segment = nullptr;
952
953 std::map<std::pair<std::string, std::string>, uint32_t> import_thunks_by_name;
954 std::map<std::pair<std::string, uint16_t>, uint32_t> import_thunks_by_ordinal;
955
957 {
958 public:
959 class TargetEnumeration : public Linker::Enumeration<target_type>
960 {
961 public:
963 : Enumeration(
964 "WIN9X", TargetWin9x,
965 "WINNT", TargetWinNT,
966 "WINCE", TargetWinCE,
967 "MACINTOSH", TargetMacintosh,
968 "WIN32S", TargetWin32s,
969 "TNT", TargetTNT,
970 "EFI", TargetEFI,
971 "DOTNET", TargetDotNET,
972 "XBOX", TargetXbox)
973 {
974 descriptions = {
975 { TargetWin9x, "targets Windows 95/98/ME" },
976 { TargetWinNT, "targets Windows NT" },
977 { TargetWinCE, "targets Windows CE/Windows Phone/Windows Mobile (pre-8)" },
978 { TargetMacintosh, "targets the Windows Portability Library on Macintosh (not implemented)" },
979 { TargetWin32s, "targets the Win32s layer for Windows 3.11" },
980 { TargetTNT, "targets the Phar Lap TNT DOS Extender (not implemented)" },
981 { TargetEFI, "targets EFI/UEFI (not implemented)" },
982 { TargetDotNET, "targets the .NET environment (not implemented)" },
983 { TargetXbox, "targets Xbox (not implemented)" },
984 //{ TargetBeOS, "targets BeOS x86 up to Release 3.2" },
985 //{ TargetSkyOS, "targets SkyOS" },
986 //{ TargetHXDOS, "targets the HX-DOS DOS extender" },
987 };
988 }
989 };
990
991 enum subsystem_determination
992 {
993 Subsystem_Windows = 1,
994 Subsystem_Console,
995 Subsystem_Native,
996 Subsystem_OS2,
997 Subsystem_POSIX,
998 Subsystem_EFIApplication,
999 Subsystem_EFIBootServiceDriver,
1000 Subsystem_EFIRuntimeDriver,
1001 Subsystem_EFI_ROM,
1002 Subsystem_BootApplication,
1003 };
1004
1005 class SubsystemEnumeration : public Linker::Enumeration<subsystem_determination>
1006 {
1007 public:
1009 : Enumeration(
1010 "WINDOWS", Subsystem_Windows,
1011 "CONSOLE", Subsystem_Console,
1012 "NATIVE", Subsystem_Native,
1013 "OS2", Subsystem_OS2,
1014 "POSIX", Subsystem_POSIX,
1015 "EFI_APPLICATION", Subsystem_EFIApplication,
1016 "EFI_BOOT_SERVICE_DRIVER", Subsystem_EFIBootServiceDriver,
1017 "EFI_RUNTIME_DRIVER", Subsystem_EFIRuntimeDriver,
1018 "EFI_ROM", Subsystem_EFI_ROM,
1019 "BOOT_APPLICATION", Subsystem_BootApplication)
1020 {
1021 descriptions = {
1022 { Subsystem_Windows, "creates a graphical program" },
1023 { Subsystem_Console, "creates a console (text mode) program" },
1024 { Subsystem_Native, "creates a native Windows NT kernel program" },
1025 { Subsystem_OS2, "creates a program that uses the OS/2 personality" },
1026 { Subsystem_POSIX, "creates a program that uses the POSIX personality" },
1027 { Subsystem_EFIApplication, "creates an EFI application" },
1028 { Subsystem_EFIBootServiceDriver, "creates an EFI boot service driver" },
1029 { Subsystem_EFIRuntimeDriver, "creates an EFI run-time driver" },
1030 { Subsystem_EFI_ROM, "creates an EFI ROM image" },
1031 { Subsystem_BootApplication, "creates a Windows boot application" },
1032 };
1033 }
1034 };
1035
1036 class OutputTypeEnumeration : public Linker::Enumeration<output_type>
1037 {
1038 public:
1040 : Enumeration(
1041 "EXE", OUTPUT_EXE,
1042 "DLL", OUTPUT_DLL,
1043 "SYS", OUTPUT_SYS)
1044 {
1045 descriptions = {
1046 { OUTPUT_EXE, "creates an executable" },
1047 { OUTPUT_DLL, "creates a dynamic linking library (DLL)" },
1048 { OUTPUT_SYS, "creates a system program" }
1049 };
1050 }
1051 };
1052
1053 class CompatibilityEnumeration : public Linker::Enumeration<compatibility_type>
1054 {
1055 public:
1057 : Enumeration(
1058 "NONE", CompatibleNone,
1059 "WATCOM", CompatibleWatcom,
1060 "MS", CompatibleMicrosoft,
1061 "BORLAND", CompatibleBorland,
1062 "GNU", CompatibleGNU)
1063 {
1064 descriptions = {
1065 { CompatibleNone, "default operation" },
1066 { CompatibleWatcom, "mimics the Watcom linker (not implemented)" },
1067 { CompatibleMicrosoft, "mimics the Microsoft linker (not implemented)" },
1068 { CompatibleBorland, "mimics the Borland linker (not implemented)" },
1069 { CompatibleGNU, "mimics the GNU (MinGW) linker (not implemented)" },
1070 };
1071 }
1072 };
1073
1074 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
1075 Linker::Option<Linker::ItemOf<TargetEnumeration>> target{"target", "Windows target type"};
1076 Linker::Option<Linker::ItemOf<SubsystemEnumeration>> subsystem{"subsystem", "Windows subsystem to target"};
1077 Linker::Option<Linker::ItemOf<OutputTypeEnumeration>> output{"output", "Output types"};
1078 Linker::Option<Linker::ItemOf<CompatibilityEnumeration>> compat{"compat", "Mimics the behavior of another linker"};
1079 Linker::Option<offset_t> image_base{"base", "Base address of image, used for calculating relative virtual addresses"};
1080 Linker::Option<offset_t> section_align{"section_align", "Section alignment"};
1081 Linker::Option<bool> import_thunks{"import_thunks", "Create thunk procedures for imported names"};
1082 // TODO: make stack size a parameter
1083
1084 PEOptionCollector()
1085 {
1086 InitializeFields(stub, target, subsystem, output, compat, image_base, section_align, import_thunks);
1087 }
1088 };
1089
1090 static std::shared_ptr<PEFormat> CreateConsoleApplication(target_type target = TargetWinNT, PEOptionalHeader::SubsystemType subsystem = PEOptionalHeader::WindowsCUI);
1091
1092 static std::shared_ptr<PEFormat> CreateGUIApplication(target_type target = TargetWinNT, PEOptionalHeader::SubsystemType subsystem = PEOptionalHeader::WindowsGUI);
1093
1094 static std::shared_ptr<PEFormat> CreateLibraryModule(target_type target = TargetWinNT);
1095
1096 static std::shared_ptr<PEFormat> CreateDeviceDriver(target_type target = TargetWinNT);
1097
1098 std::shared_ptr<PEFormat> SimulateLinker(compatibility_type compatibility);
1099
1100 bool FormatSupportsLibraries() const override;
1101
1102 bool FormatSupportsResources() const override;
1103
1104 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
1105
1106 std::shared_ptr<Resource>& AddResource(std::shared_ptr<Resource>& resource);
1107
1108 ImportedLibrary& FetchImportLibrary(std::string library_name, bool create_if_not_present = false);
1109 void AddImportByName(std::string library_name, std::string entry_name, uint16_t hint);
1110 void AddImportByOrdinal(std::string library_name, uint16_t ordinal);
1111
1112 static std::vector<Linker::OptionDescription<void> *> ParameterNames;
1113 std::vector<Linker::OptionDescription<void> *> GetLinkerScriptParameterNames() override;
1114 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
1115
1117 enum
1118 {
1120 FLAG_NO_RELOCATIONS = 0x0001, // already defined in COFF
1122 FLAG_EXECUTABLE = 0x0002, // already defined in COFF
1124 FLAG_NO_LINE_NUMBERS = 0x0004, // already defined in COFF
1126 FLAG_NO_SYMBOLS = 0x0008, // already defined in COFF
1134 FLAG_32BIT = 0x0100,
1142 FLAG_SYSTEM = 0x1000,
1149 };
1150
1151 void SetOptions(std::map<std::string, std::string>& options) override;
1152 void AllocateSymbols(Linker::Module& module) const override;
1153 void OnCallDirective(Linker::Module& module, std::string identifier) override;
1154 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
1155 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
1156 void Link(Linker::Module& module);
1157
1165 offset_t GenerateResourceSection(Linker::Module& module, offset_t image_end);
1166
1174 offset_t GenerateImportSection(Linker::Module& module, offset_t image_end);
1175
1183 offset_t GenerateExportSection(Linker::Module& module, offset_t image_end);
1184
1192 offset_t GenerateBaseRelocationSection(Linker::Module& module, offset_t image_end);
1193
1197 void ProcessRelocations(Linker::Module& module);
1198
1202 void FixupImportThunk(Linker::Module& module, offset_t offset, offset_t address);
1203
1204 offset_t GetMemoryImageEnd() const;
1205 void ProcessModule(Linker::Module& module) override;
1206 void GenerateFile(std::string filename, Linker::Module& module) override;
1208 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
1209
1213 class RVADisplay : public Dumper::Display<offset_t>
1214 {
1215 public:
1216 const PEFormat * pe;
1217 unsigned width;
1218 RVADisplay(const PEFormat * pe, unsigned width)
1219 : pe(pe), width(width)
1220 {
1221 }
1222
1223 void DisplayValue(Dumper::Dumper& dump, std::tuple<offset_t> values) override;
1224 };
1225
1226 std::shared_ptr<RVADisplay> MakeRVADisplay(unsigned width = 8) const;
1227 };
1228
1229 class NTResourceFile : public virtual Linker::Format
1230 {
1231 public:
1232 typedef ResourceFile::Identifier Identifier;
1233
1234 static void ReadIdentifier(const std::shared_ptr<Linker::Reader>& rd, Identifier& id);
1235 static void WriteIdentifier(const std::shared_ptr<Linker::Writer>& wr, const Identifier& id);
1236 static offset_t GetIdentifierSize(const Identifier& id);
1237
1239 {
1240 public:
1241 uint32_t header_size;
1242 uint32_t data_version;
1243 uint16_t language_id;
1244 uint32_t version;
1245 uint32_t characteristics;
1246 };
1247
1248 offset_t file_offset;
1249 std::vector<Resource> resources;
1250
1251 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
1252 void ReadFile(const std::shared_ptr<Linker::Reader>& rd, offset_t size);
1253 void CalculateValues();
1255 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
1256 void Dump(Dumper::Dumper& dump) const override;
1257
1259 };
1260}
1261
1262#endif /* PEEXE_H */
A standard 28 byte a.out optional header, used by AT&T UNIX and DJGPP.
Definition coff.h:1392
A COFF section.
Definition coff.h:940
std::string name
The name of the section (COFF name: s_name)
Definition coff.h:945
static constexpr uint32_t DATA
COFF section flag: Section contains initialized data (COFF name: STYP_DATA)
Definition coff.h:1003
offset_t physical_address
The physical address of the section (expected to be identical to the virtual address) (COFF name: s_p...
Definition coff.h:951
static constexpr uint32_t TEXT
COFF section flag: Section contains executable instructions (COFF name: STYP_TEXT)
Definition coff.h:1001
uint32_t flags
COFF section flags, determines the type of the section (text, data, bss, etc.) (COFF name: s_flags)
Definition coff.h:983
std::shared_ptr< Linker::Contents > image
The stored image data.
Definition coff.h:992
The UNIX COFF file format.
Definition coff.h:30
@ PECOFF
Microsoft PE/COFF variant.
Definition coff.h:255
@ WINDOWS
Windows Portable Executable (used only by PE)
Definition coff.h:2029
format_type type
A representation of the format to generate.
Definition coff.h:2034
::EndianType endiantype
The byte order.
Definition coff.h:1840
offset_t ImageSize() const override
Retrieves size of stored data.
Definition coff.cc:2354
std::unique_ptr< OptionalHeader > optional_header
The optional header instance used for reading/writing the COFF file.
Definition coff.h:1346
A record whose values should be displayed together, as a collection.
Definition dumper.h:797
This class represents an entry that can be displayed in a file dump.
Definition dumper.h:198
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:1009
A record that represents a region within the file.
Definition dumper.h:902
A representation of an enumeration with associated string representations for each value.
Definition options.h:15
std::map< value_type, std::string > descriptions
An empty dictionary that explains the value types in detail.
Definition options.h:20
A class to encode a general file format.
Definition format.h:29
offset_t WriteFile(const std::shared_ptr< Writer > &wr) const override=0
Stores data in memory to file.
Definition image.h:39
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
Helper class that contains the options interpreted by the format.
Definition options.h:499
Documents and handles command line options.
Definition options.h:306
virtual std::string GetDefaultExtension(Module &module, std::string filename) const
Appends a default extension to the filename.
Definition mzexe.h:387
Definition peexe.h:1230
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr) const override
Stores data in memory to file.
Definition peexe.cc:4217
void ReadFile(const std::shared_ptr< Linker::Reader > &rd) override
Loads file into memory.
Definition peexe.cc:4199
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition peexe.cc:4245
A block of base relocations, corresponding to a single page in the image.
Definition peexe.h:763
std::vector< BaseRelocation > relocations_list
Sequence of relocations in this block, filled in by the linker once all the relocations have been col...
Definition peexe.h:772
static constexpr uint32_t PAGE_SIZE
Pages are 4 KiB long.
Definition peexe.h:766
std::map< uint16_t, BaseRelocation > relocations_map
Collection of relocations, accessed via their page offset.
Definition peexe.h:774
uint32_t page_rva
The relative virtual address of the page this block corresponds to, with the least significant 12 bit...
Definition peexe.h:768
uint32_t block_size
Number of bytes in this block, including the initial 8 bytes for the relative virtual address of the ...
Definition peexe.h:770
Represents a base relocation, as stored in the image.
Definition peexe.h:712
size_t GetRelocationSize(const PEFormat *format) const
The number of bytes impacted by this relocation (typically 2 or 4 or 8)
Definition peexe.cc:1775
relocation_type type
The type of the relocation, stored as the 4 most significant bits of a 16-bit base relocation entry.
Definition peexe.h:749
uint16_t parameter
For relocation type HighAdj, the 16-bit value stored in the following base relocation entry.
Definition peexe.h:753
size_t GetEntryCount(const PEFormat *format) const
The number of base relocation entries required to store this base relocation, typically 1.
Definition peexe.cc:1764
relocation_type
The type of the relocation, partly dependent on the current CPU.
Definition peexe.h:716
@ RelRISCVHigh20
RISC-V specific.
Definition peexe.h:732
@ RelLow
The least significant 16 bits of the address.
Definition peexe.h:722
@ RelAbsolute
No relocation.
Definition peexe.h:718
@ RelLoongArch64MarkLA
LoongArch specific.
Definition peexe.h:742
@ RelThumbMov32
Thumb (ARM) specific.
Definition peexe.h:734
@ RelDir64
A full 64-bit address.
Definition peexe.h:746
@ RelLoongArch32MarkLA
LoongArch specific.
Definition peexe.h:740
@ RelRISCVLow12I
RISC-V specific.
Definition peexe.h:736
@ RelHigh
The most significant 16 bits of the address.
Definition peexe.h:720
@ RelMIPSJmpAddr16
MIPS specific.
Definition peexe.h:744
@ RelHighAdj
The most significant 16 bits of the address, with the currently assumed least significant 16 bits sto...
Definition peexe.h:726
@ RelMIPSJmpAddr
MIPS specific.
Definition peexe.h:728
@ RelRISCVLow12S
RISC-V specific.
Definition peexe.h:738
@ RelHighLow
A full 32-bit address.
Definition peexe.h:724
@ RelARMMov32
ARM specific.
Definition peexe.h:730
uint16_t offset
The offset of the relocation within the page corresponding to this base relocation block,...
Definition peexe.h:751
Represents a .reloc section for the base relocations for the binary.
Definition peexe.h:784
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:1924
void ReadSectionData(const std::shared_ptr< Linker::Reader > &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:1886
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:1961
void WriteSectionData(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:1891
std::map< uint32_t, std::shared_ptr< BaseRelocationBlock > > blocks_map
Collection of relocation blocks, accessed via the relative virtual address of the page.
Definition peexe.h:789
std::vector< std::shared_ptr< BaseRelocationBlock > > blocks_list
Sequence of relocation blocks, filled in by the linker once all the relocations have been collected.
Definition peexe.h:787
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:1929
void ReadSectionData(const std::shared_ptr< Linker::Reader > &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:2001
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:2023
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:2017
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:2028
void WriteSectionData(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:2006
Encompasses the information necessary to encode a forwarder exported reference.
Definition peexe.h:604
std::variant< std::string, uint32_t > reference
The name or ordinal to the entry that is being reexported, this field will not appear directly in the...
Definition peexe.h:609
std::string reference_name
A string representation of the forwarder, to appear in the image.
Definition peexe.h:611
uint32_t rva
The relative virtual address of the reference name.
Definition peexe.h:613
std::string dll_name
The name of the library whose entry is being reexported, this field will not appear directly in the i...
Definition peexe.h:607
Represents a name by which an exported entry is identified.
Definition peexe.h:618
uint32_t rva
The relative virtual address of the name string.
Definition peexe.h:623
std::string name
The name, as a string.
Definition peexe.h:621
Represents a single exported entry in the file.
Definition peexe.h:596
std::optional< Name > name
An optional name by which the exported entry is identified, otherwise its position in the export tabl...
Definition peexe.h:634
std::variant< uint32_t, Forwarder > value
Represents the associated value of the entry: either the relative virtual address of the object being...
Definition peexe.h:632
Represents an .edata section for the exported entries in the binary.
Definition peexe.h:654
void ReadSectionData(const std::shared_ptr< Linker::Reader > &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:1518
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:1701
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:1628
void AddEntry(PEFormat &fmt, std::shared_ptr< ExportedEntry > entry)
Adds an entry to an unused ordinal (for speed, we access the highest taken ordinal and assign this en...
Definition peexe.cc:1409
std::string dll_name
The name of this library.
Definition peexe.h:660
std::map< uint32_t, std::shared_ptr< ExportedEntry > > entries
Sequence of entries, the first entry corresponds to ordinal_base.
Definition peexe.h:674
uint32_t ordinal_base
The starting ordinal for the export table.
Definition peexe.h:664
uint32_t address_table_rva
Relative virtual address of the export address table, containing the exported entries for each succes...
Definition peexe.h:668
uint32_t name_table_rva
Relative virtual address of the name pointer table, containing the relative virtual addresses of the ...
Definition peexe.h:670
std::map< std::string, uint32_t > named_exports
A collection of exports by name, with each string being associated with its ordinal.
Definition peexe.h:676
uint32_t dll_name_rva
The relative virtual address of the library name string.
Definition peexe.h:662
void SetEntry(PEFormat &fmt, uint32_t ordinal, std::shared_ptr< ExportedEntry > entry)
Sets a specific entry, corresponding to some ordinal.
Definition peexe.cc:1390
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:1633
uint32_t ordinal_table_rva
Relative virtual address of the ordinal table, containing the ordinals for each entry exported by nam...
Definition peexe.h:672
uint32_t first_allowed_ordinal
A hint for AddEntry to start looking for free ordinals.
Definition peexe.h:666
void WriteSectionData(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:1523
Represents an entry in the hint-name table, corresponding to imports by name.
Definition peexe.h:502
uint32_t rva
The relative virtual address of the name of the entry.
Definition peexe.h:509
std::string name
The name by which the entry is identified.
Definition peexe.h:507
uint16_t hint
The hint (ordinal) corresponding to this entry.
Definition peexe.h:505
A collection of the imported names for a specific dynamic linking library.
Definition peexe.h:496
std::map< Ordinal, size_t > imports_by_ordinal
A convenience field to quickly access the imported entry index via its ordinal (only for import by or...
Definition peexe.h:536
std::variant< Ordinal, Name > ImportTableEntry
Represents a single entry in the import directory, either an ordinal or a name.
Definition peexe.h:518
offset_t GetImportByNameAddress(const PEFormat &fmt, std::string name)
Retrieves the virtual address of an already registered entry that is imported by name.
Definition peexe.cc:2732
void AddImportByOrdinal(uint16_t ordinal)
Adds a new imported entry by ordinal, unless an entry by the same ordinal already exists,...
Definition peexe.cc:2721
uint32_t name_rva
Relative virtual address of the name.
Definition peexe.h:529
std::vector< ImportTableEntry > import_table
List of imported entries.
Definition peexe.h:532
void AddImportByName(std::string entry_name, uint16_t hint)
Adds a new imported entry by name and hint, unless an entry by the same name already exists,...
Definition peexe.cc:2711
offset_t GetImportByOrdinalAddress(const PEFormat &fmt, uint16_t ordinal)
Retrieves the virtual address of an already registered entry that is imported by ordinal.
Definition peexe.cc:2743
std::map< std::string, size_t > imports_by_name
A convenience field to quickly access the imported entry index via its name, must be kept synchronize...
Definition peexe.h:534
uint32_t lookup_table_rva
Relative virtual address for the lookup table, preserved during execution time.
Definition peexe.h:521
uint32_t address_table_rva
Relative virtual address for the address table, used to access the imported functions,...
Definition peexe.h:523
std::string name
Name of the dynamic linking library included.
Definition peexe.h:527
Represents an .idata section for imported DLLs in the binary.
Definition peexe.h:556
std::map< std::string, size_t > library_indexes
A convenience field to access the DLL index by its name.
Definition peexe.h:561
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:1282
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:1277
std::vector< ImportedLibrary > libraries
The sequence of all import directories, one for each DLL.
Definition peexe.h:559
void WriteSectionData(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:1151
uint32_t address_table_size
Size of the import address table, to be stored in the optional header.
Definition peexe.h:566
void ReadSectionData(const std::shared_ptr< Linker::Reader > &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:1146
uint32_t address_table_rva
Relative virtual address of the import address table, to be stored in the optional header.
Definition peexe.h:564
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:1339
size_t ReadData(size_t bytes, offset_t offset, void *buffer) const override
Attempts to fill a buffer with data.
Definition peexe.cc:412
offset_t ImageSize() const override
Retrieves size of stored data.
Definition peexe.cc:407
The PE optional header as specified by Microsoft.
Definition peexe.h:31
version_type image_version
Binary image version.
Definition peexe.h:70
uint16_t flags
DLL flags (in PE terminology, characteristics)
Definition peexe.h:116
version_type os_version
Required operating system version.
Definition peexe.h:66
uint32_t win32_version
Reserved value.
Definition peexe.h:78
uint32_t loader_flags
Reserved.
Definition peexe.h:136
static constexpr offset_t Win32Base
Conventional image base for 32-bit Windows executables.
Definition peexe.h:41
uint32_t section_align
Section alignment.
Definition peexe.h:58
uint32_t file_align
File alignment.
Definition peexe.h:62
uint32_t checksum
Checksum.
Definition peexe.h:90
offset_t RVAToAddress(uint32_t rva, bool suppress_on_zero=false) const
Converts an image base relative virtual address into a virtual address.
Definition peexe.cc:33
static constexpr offset_t Dll32Base
Conventional image base for 32-bit Windows dynamic linking libraries.
Definition peexe.h:43
std::vector< DataDirectory > data_directories
PE specific areas in the file, each one has a specific purpose.
Definition peexe.h:168
static constexpr uint16_t EXE64
Magic number for 64-bit binaries, also signifies 8-byte entries in the file (PE32+)
Definition peexe.h:38
static constexpr offset_t WinCEBase
Conventional image base for Windows CE executables.
Definition peexe.h:45
static constexpr offset_t Win64Base
Conventional image base for 64-bit Windows executables.
Definition peexe.h:47
bool Is64Bit() const
Whether the file is in the PE32+ (64-bit) format.
Definition peexe.cc:9
offset_t reserved_stack_size
How much of stack should be reserved at launch.
Definition peexe.h:120
uint32_t total_headers_size
Cumulative size of all the headers, including the MZ stub.
Definition peexe.h:86
offset_t committed_stack_size
How many pages of stack are actually available at launch.
Definition peexe.h:124
static constexpr uint16_t EXE32
Magic number for 32-bit binaries, also signifies 4-byte entries in the file (PE32)
Definition peexe.h:36
offset_t image_base
Preferred base address of image, all relative virtual addresses are calculate relative to this value.
Definition peexe.h:54
SubsystemType subsystem
The Windows subsystem this program runs on.
Definition peexe.h:112
offset_t reserved_heap_size
How much of heap should be reserved at launch.
Definition peexe.h:128
uint32_t total_image_size
Size of the entire image, including headers.
Definition peexe.h:82
static constexpr offset_t Dll64Base
Conventional image base for 64-bit Windows dynamic linking libraries.
Definition peexe.h:49
offset_t committed_heap_size
How many pages of heap are actually available at launch.
Definition peexe.h:132
uint32_t AddressToRVA(offset_t address) const
Converts a virtual address into an image base relative virtual address.
Definition peexe.cc:19
uint32_t GetSize() const override
Returns size of optional header.
Definition peexe.cc:14
static constexpr uint16_t ROM32
Magic number for ROM images, according to Microsoft.
Definition peexe.h:34
version_type subsystem_version
Version of the subsystem.
Definition peexe.h:74
Represents a field that displays a relative virtual address and file offset pair.
Definition peexe.h:1214
Represents a single entry in the resource directory.
Definition peexe.h:411
Key identifier
The value that identifiers the resource at the current level.
Definition peexe.h:414
std::variant< std::shared_ptr< Resource >, std::shared_ptr< ResourceDirectory > > content
The contents at this level, either the resource itself, or another level of resource directory.
Definition peexe.h:416
uint32_t content_offset
The offset of the contents within the section.
Definition peexe.h:418
size_t ParseResourceDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t rva, const std::vector< Resource::Identifier > &partial_identifier)
Parses the contents of the directory at the current level, after all the section data for the file is...
Definition peexe.cc:622
offset_t WriteResources(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt, uint32_t rva_to_offset) const
Recursively writes all the resources, returns the file offset after the last written byte.
Definition peexe.cc:933
std::vector< Entry< Name > > name_entries
Entries that are identified via a string.
Definition peexe.h:428
void CollectSubdirectoryStrings(PEFormat &fmt, ResourcesSection &rsrc, size_t level_deeper)
Registers all strings occuring in the directory and its subdirectories at the specified relative leve...
Definition peexe.cc:808
void AddResource(std::shared_ptr< Resource > &resource, size_t level=0)
Inserts a resource into the directory.
Definition peexe.cc:546
uint32_t CollectResourceData(PEFormat &fmt, uint32_t rva, size_t level_deeper)
Calculates the relative virtual addresses of each individual resource at the specified relative level...
Definition peexe.cc:839
void WriteDirectories(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt, uint32_t section_pointer) const
Recursively writes the directory table and all those of all of its subdirectories and leaves.
Definition peexe.cc:885
uint32_t CalculateDirectoryOffsets(PEFormat &fmt, uint32_t offset, size_t level_deeper)
Fills in the offsets for all subdirectories at the specified relative level.
Definition peexe.cc:774
void DumpResourceDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t rva, const std::vector< Resource::Identifier > &partial_identifier, size_t dump_level) const
Displays the directory contents.
Definition peexe.cc:692
std::vector< Entry< uint32_t > > id_entries
Entries that are identified via a number.
Definition peexe.h:430
uint32_t flags
Resource directory characteristics.
Definition peexe.h:424
Represents a resource inside the image.
Definition peexe.h:343
offset_t WriteResource(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt, uint32_t rva_to_offset) const
Writes the actual resource, returns the file offset after the last written byte.
Definition peexe.cc:535
uint32_t codepage
Codepage of the resource.
Definition peexe.h:367
uint32_t reserved
Reserved entry in the resource table.
Definition peexe.h:369
uint32_t data_rva
The relative virtual address of the resource data.
Definition peexe.h:363
void WriteDirectories(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt, uint32_t section_pointer) const
Writes the directory entry for this resource.
Definition peexe.cc:527
std::vector< Identifier > full_identifier
The sequence of IDs that identifies this resource, conventionally corresponding to the resource type,...
Definition peexe.h:361
static constexpr size_t Level_Name
The second level of the resource tree corresponds to the resource name.
Definition peexe.h:351
static constexpr size_t Level_Type
The first level of the resource tree corresponds to the resource type.
Definition peexe.h:349
std::variant< std::string, uint32_t > Identifier
Represents a resource identifier, either a string or a 32-bit value.
Definition peexe.h:346
uint32_t AssignAddress(PEFormat &fmt, uint32_t rva)
Assigns the relative virtual addresses and returns the relative virtual address of the end of the res...
Definition peexe.cc:517
size_t ParseResourceData(const PEFormat &fmt, uint32_t rva)
Parses the contents of the resource, after all the section data for the file is loaded,...
Definition peexe.cc:419
uint32_t size
The size of the resource data.
Definition peexe.h:365
static constexpr size_t Level_Count
Total number of levels used.
Definition peexe.h:355
static constexpr size_t Level_Language
The third level of the resource tree corresponds to the language (locale) for the resource.
Definition peexe.h:353
void DumpResource(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t rva) const
Displays the resource contents.
Definition peexe.cc:467
std::shared_ptr< Linker::Section > section
The section containing the resource, only used for generating images.
Definition peexe.h:372
static void DumpIdentifier(std::vector< Identifier > full_identifier, Dumper::Container &container)
Adds fields to the container that describe the identifier.
Definition peexe.cc:428
Represents an .rsrc resource section in the binary.
Definition peexe.h:457
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:1050
void WriteSectionData(const std::shared_ptr< Linker::Writer > &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:1011
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:1044
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:1039
void ReadSectionData(const std::shared_ptr< Linker::Reader > &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:1006
A section, with the PE extensions.
Definition peexe.h:214
static constexpr uint32_t WRITE
The section contents are writable to the program.
Definition peexe.h:224
static constexpr uint32_t READ
The section contents are readable to the program.
Definition peexe.h:222
static constexpr uint32_t DISCARDABLE
The section is discardable.
Definition peexe.h:218
virtual uint32_t MemorySize(const PEFormat &fmt) const
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:397
constexpr const offset_t & virtual_size() const
The COFF s_paddr field is redefined to contain the size of the section as loaded into memory.
Definition peexe.h:234
static constexpr uint32_t EXECUTE
The section contains executable code.
Definition peexe.h:220
constexpr offset_t & virtual_size()
The COFF s_paddr field is redefined to contain the size of the section as loaded into memory.
Definition peexe.h:232
Microsoft PE .EXE portable executable file format.
Definition peexe.h:19
target_type target
The expected target system, only used for setting up default values.
Definition peexe.h:907
offset_t GenerateImportSection(Linker::Module &module, offset_t image_end)
Creates an import section and attaches it to the end of the file.
Definition peexe.cc:3494
compatibility_type
Definition peexe.h:866
@ CompatibleMicrosoft
Attempts to mimic the output of the Microsoft linker (TODO: unimplemented)
Definition peexe.h:872
@ CompatibleGNU
Attempts to mimic the output of the GNU (MinGW) linker, this is undefined for the LE output.
Definition peexe.h:876
@ CompatibleWatcom
Attempts to mimic the output of the Watcom linker.
Definition peexe.h:870
@ CompatibleNone
No emulation is attempted.
Definition peexe.h:868
@ CompatibleBorland
Attempts to mimic the output of the Borland linker (TODO: unimplemented)
Definition peexe.h:874
bool option_coff_local_symbols
Include COFF local symbols (TODO: not implemented)
Definition peexe.h:942
uint32_t AddressToRVA(offset_t address) const
Converts a virtual address into an image base relative virtual address.
Definition peexe.cc:2055
void OnNewSegment(std::shared_ptr< Linker::Segment > segment) override
Callback function when allocating a new segment When the linker script runs, it creates segments cons...
Definition peexe.cc:3070
offset_t GenerateResourceSection(Linker::Module &module, offset_t image_end)
Creates a resource section and attaches it to the end of the file.
Definition peexe.cc:3482
output_type
Represents the target image type.
Definition peexe.h:911
@ OUTPUT_EXE
An executable image, conventionally taking the suffix .exe
Definition peexe.h:913
@ OUTPUT_SYS
A system file or driver, conventionally taking the suffix .sys
Definition peexe.h:917
@ OUTPUT_DLL
A dynamically linked library, conventionally taking the suffix .dll
Definition peexe.h:915
size_t ReadData(size_t bytes, uint32_t rva, void *buffer) const
Loads a sequence of bytes from the filled section data.
Definition peexe.cc:2171
std::shared_ptr< Linker::Segment > import_thunk_segment
Holds the segment that contains the import thinks.
Definition peexe.h:951
std::shared_ptr< BaseRelocationsSection > base_relocations
The collection of base relocations.
Definition peexe.h:815
bool option_debug_info
Include debug information (TODO: not implemented)
Definition peexe.h:945
std::shared_ptr< ImportsSection > imports
The collection of imports in the file.
Definition peexe.h:592
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition peexe.cc:3937
std::string ReadASCII(uint32_t rva, char terminator, size_t maximum=size_t(-1)) const
Loads a sequence of bytes terminated by a specific character from the filled section data.
Definition peexe.cc:2209
std::shared_ptr< ExportsSection > exports
The collection of exported symbols.
Definition peexe.h:708
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr) const override
Stores data in memory to file.
Definition peexe.cc:2411
void AddBaseRelocation(uint32_t rva, BaseRelocation::relocation_type type, uint16_t low_ref=0)
Adds a base relocation at the specified relative virtual address.
Definition peexe.cc:2227
Timestamp< Clock > ReadTimestamp(uint32_t rva, EndianType endiantype) const
Reads a date-time value according to some epoch.
Definition peexe.h:317
void AllocateSymbols(Linker::Module &module) const override
Instructs the module to allocate any unallocated local symbols.
Definition peexe.cc:3065
void OnCallDirective(Linker::Module &module, std::string identifier) override
Callback function for the CALL directive.
Definition peexe.cc:3135
size_t MapRVAToSectionData(uint32_t rva, size_t bytes, std::shared_ptr< Section > &found_section, size_t &section_offset) const
Attempts to find the section:offset pair that encompasses this memory range.
Definition peexe.cc:2075
void ReadFile(const std::shared_ptr< Linker::Reader > &rd) override
Loads file into memory.
Definition peexe.cc:2248
int64_t ReadSigned(size_t bytes, uint32_t rva, ::EndianType endiantype) const
Loads a signed word from the filled section data.
Definition peexe.cc:2201
void ProcessRelocations(Linker::Module &module)
Processes relocations present in the module and stores them as base relocations and imports.
Definition peexe.cc:3535
bool option_include_deprecated_flags
Certain header flags are deprecated and should be zero, this option sets them if applicable (TODO: ex...
Definition peexe.h:936
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition peexe.cc:4081
PEOptionalHeader & GetOptionalHeader()
Retrieves the optional header.
Definition peexe.cc:2040
std::shared_ptr< ResourcesSection > resources
The resources in this file.
Definition peexe.h:492
bool Is64Bit() const
Whether the file is in the PE32+ (64-bit) format.
Definition peexe.cc:2050
bool option_coff_line_numbers
Include COFF line numbers (TODO: not implemented)
Definition peexe.h:939
bool option_relocatable
Make generated image relocatable (TODO: expose as command line option)
Definition peexe.h:933
offset_t GenerateExportSection(Linker::Module &module, offset_t image_end)
Creates an export section and attaches it to the end of the file.
Definition peexe.cc:3511
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition peexe.cc:2779
offset_t GenerateBaseRelocationSection(Linker::Module &module, offset_t image_end)
Creates a base relocation section and attaches it to the end of the file.
Definition peexe.cc:3523
uint64_t ReadUnsigned(size_t bytes, uint32_t rva, ::EndianType endiantype) const
Loads an unsigned word from the filled section data.
Definition peexe.cc:2193
std::vector< Linker::OptionDescription< void > * > GetLinkerScriptParameterNames() override
Returns a list of the parameters used in the linker scripts, used for documentation.
Definition peexe.cc:2769
target_type
Represents settings and assumptions about the target.
Definition peexe.h:883
@ TargetWin32s
Win32s compatibility library for Windows 3.1.
Definition peexe.h:893
@ TargetEFI
EFI and UEFI firmware.
Definition peexe.h:897
@ TargetWin9x
Windows 95/98/ME.
Definition peexe.h:885
@ TargetTNT
Phar Lap TNT DOS Extender.
Definition peexe.h:895
@ TargetXbox
Xbox.
Definition peexe.h:901
@ TargetWinNT
Windows NT kernel.
Definition peexe.h:887
@ TargetMacintosh
Windows Portability Library.
Definition peexe.h:891
@ TargetDotNET
.NET environment
Definition peexe.h:899
@ TargetWinCE
Windows CE kernel.
Definition peexe.h:889
@ FLAG_ON_REMOVABLE
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP.
Definition peexe.h:1138
@ FLAG_NO_LINE_NUMBERS
(deprecated) IMAGE_FILE_LINE_NUMS_STRIPPED (F_LNNO)
Definition peexe.h:1124
@ FLAG_32BIT
IMAGE_FILE_32BIT_MACHINE (redefined from COFF F_AR32WR)
Definition peexe.h:1134
@ FLAG_LIBRARY
IMAGE_FILE_DLL.
Definition peexe.h:1144
@ FLAG_LITTLE_ENDIAN
(deprecated) IMAGE_FILE_BYTES_REVERSED_LO (redefined from COFF F_AR16WR)
Definition peexe.h:1132
@ FLAG_NO_DEBUG
IMAGE_FILE_DEBUG_STRIPPED (redefined from COFF F_AR32W)
Definition peexe.h:1136
@ FLAG_SYSTEM
IMAGE_FILE_SYSTEM.
Definition peexe.h:1142
@ FLAG_BIG_ENDIAN
(deprecated) IMAGE_FILE_BYTES_REVERSED_HI
Definition peexe.h:1148
@ FLAG_ON_NETWORK
IMAGE_FILE_NET_RUN_FROM_SWAP.
Definition peexe.h:1140
@ FLAG_EXECUTABLE
IMAGE_FILE_EXECUTABLE_IMAGE (F_EXEC)
Definition peexe.h:1122
@ FLAG_NO_SYMBOLS
(deprecated) IMAGE_FILE_LOCAL_SYMS_STRIPPED (F_LSYMS)
Definition peexe.h:1126
@ FLAG_TRIM_WORKING_SET
(deprecated) IMAGE_FILE_AGGRESSIVE_WS_TRIM (no COFF meaning)
Definition peexe.h:1128
@ FLAG_NO_RELOCATIONS
IMAGE_FILE_RELOCS_STRIPPED (F_RELFLG)
Definition peexe.h:1120
@ FLAG_UNIPROCESSOR_ONLY
IMAGE_FILE_UP_SYSTEM_ONLY.
Definition peexe.h:1146
@ FLAG_LARGE_ADDRESS
IMAGE_FILE_LARGE_ADDRESS_AWARE (no COFF meaning)
Definition peexe.h:1130
const PESections Sections() const
Access the sections as PEFormat::Section.
Definition peexe.cc:2161
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition peexe.cc:2774
void FixupImportThunk(Linker::Module &module, offset_t offset, offset_t address)
Adjust addresses in the text section where the indirect jumps appear.
Definition peexe.cc:3711
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition peexe.cc:3760
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition peexe.cc:2325
bool FormatSupportsResources() const override
Whether the format supports resources.
Definition peexe.cc:2674
bool option_import_thunks
By default, imported labels address the import address table directly.
Definition peexe.h:948
offset_t RVAToFileOffset(uint32_t rva) const
Converts an image base relative virtual address into a file offset.
Definition peexe.cc:2065
bool FormatSupportsLibraries() const override
Whether the format supports libraries.
Definition peexe.cc:2669
offset_t RVAToAddress(uint32_t rva, bool suppress_on_zero=false) const
Converts an image base relative virtual address into a virtual address.
Definition peexe.cc:2060
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition peexe.cc:2421
Definition neexe.h:875
A data directory entry.
Definition peexe.h:140
Wrapper around COFFFormat::sections to return PEFormat::Section pointers instead of COFFFormat::Secti...
Definition peexe.h:255
Represents a version entry with major and minor versions.
Definition peexe.h:25