1 #pragma once
2 
3 #include <type_traits>
4 #include "../../plugins/plugins.h"
5 #include "pe_header.h"
6 #include "pe_resources.h"
7 #include "pe_imports.h"
8 #include "pe_utils.h"
9 #include "pe_utils.h"
10 #include "pe_classifier.h"
11 #include "dotnet/dotnet_header.h"
12 #include "dotnet/dotnet_reader.h"
13 
14 namespace REDasm {
15 
16 template<size_t b> class PELoader: public LoaderPluginT<ImageDosHeader>
17 {
18     DECLARE_LOADER_PLUGIN_TEST(ImageDosHeader)
19 
20     private:
21         typedef typename std::conditional<b == 64, u64, u32>::type pe_integer_t;
22         typedef typename std::conditional<b == 64, ImageOptionalHeader64, ImageOptionalHeader32>::type ImageOptionalHeader;
23         typedef typename std::conditional<b == 64, ImageThunkData64, ImageThunkData32>::type ImageThunkData;
24         typedef typename std::conditional<b == 64, ImageTlsDirectory64, ImageTlsDirectory32>::type ImageTlsDirectory;
25         typedef typename std::conditional<b == 64, ImageLoadConfigDirectory64, ImageLoadConfigDirectory32>::type ImageLoadConfigDirectory;
26 
27     public:
28         PELoader(AbstractBuffer* buffer);
29         std::string assembler() const override;
30         Analyzer* createAnalyzer(DisassemblerAPI *disassembler) const override;
31         void load() override;
32         const DotNetReader *dotNetReader() const;
33         address_t rvaToVa(address_t rva) const;
34         address_t vaToRva(address_t rva) const;
35 
36     private:
37         ImageCorHeader *checkDotNet();
38         void readDescriptor(const ImageImportDescriptor& importdescriptor, pe_integer_t ordinalflag);
39         void readTLSCallbacks(const ImageTlsDirectory* tlsdirectory);
40         void checkResources();
41         void checkDebugInfo();
42         void loadDotNet(ImageCor20Header* corheader);
43         void loadSymbolTable();
44         void loadDefault();
45         void loadSections();
46         void loadExports();
47         bool loadImports();
48         void loadExceptions();
49         void loadConfig();
50         void loadTLS();
51 
52     private:
rvaPointer(u64 rva)53         template<typename T> T* rvaPointer(u64 rva) const {
54             offset_location offset = PEUtils::rvaToOffset(m_ntheaders, rva);
55 
56             if(!offset.valid) return nullptr;
57             return this->pointer<T>(offset);
58         }
59 
60     private:
61         PEClassifier m_classifier;
62         std::unique_ptr<DotNetReader> m_dotnetreader;
63         ImageDosHeader* m_dosheader;
64         ImageNtHeaders* m_ntheaders;
65         ImageOptionalHeader* m_optionalheader;
66         ImageSectionHeader* m_sectiontable;
67         ImageDataDirectory* m_datadirectory;
68         pe_integer_t m_imagebase, m_sectionalignment, m_entrypoint;
69         std::unordered_set<std::string> m_validimportsections;
70 };
71 
72 LOADER_INHERIT(PE32Loader, (PELoader<32>), "Portable Executable (32 bits)")
73 LOADER_INHERIT(PE64Loader, (PELoader<64>), "Portable Executable (64 bits)")
74 
75 DECLARE_LOADER_PLUGIN(PE32Loader, pe32)
76 DECLARE_LOADER_PLUGIN(PE64Loader, pe64)
77 
78 } // namespace REDasm
79 
80 #include "pe.hpp"
81