BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
ClrDirWrapper.cpp
Go to the documentation of this file.
1#include "pe/ClrDirWrapper.h"
2
3/*
4typedef struct IMAGE_COR20_HEADER
5{
6 // Header versioning
7 DWORD cb;
8 WORD MajorRuntimeVersion;
9 WORD MinorRuntimeVersion;
10
11 // Symbol table and startup information
12 IMAGE_DATA_DIRECTORY MetaData;
13 DWORD Flags;
14
15 // The main program if it is an EXE (not used if a DLL?)
16 // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint.
17 // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint
18 // (depricated for DLLs, use modules constructors intead).
19 union {
20 DWORD EntryPointToken;
21 DWORD EntryPointRVA;
22 };
23
24 // This is the blob of managed resources. Fetched using code:AssemblyNative.GetResource and
25 // code:PEFile.GetResource and accessible from managed code from
26 // System.Assembly.GetManifestResourceStream. The meta data has a table that maps names to offsets into
27 // this blob, so logically the blob is a set of resources.
28 IMAGE_DATA_DIRECTORY Resources;
29 // IL assemblies can be signed with a public-private key to validate who created it. The signature goes
30 // here if this feature is used.
31 IMAGE_DATA_DIRECTORY StrongNameSignature;
32
33 IMAGE_DATA_DIRECTORY CodeManagerTable; // Depricated, not used
34 // Used for manged codee that has unmaanaged code inside it (or exports methods as unmanaged entry points)
35 IMAGE_DATA_DIRECTORY VTableFixups;
36 IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
37
38 // null for ordinary IL images. NGEN images it points at a code:CORCOMPILE_HEADER structure
39 IMAGE_DATA_DIRECTORY ManagedNativeHeader;
40
41} IMAGE_COR20_HEADER, *PIMAGE_COR20_HEADER;
42*/
43
44pe::IMAGE_COR20_HEADER* ClrDirWrapper::clrDir()
45{
47
48 BYTE *ptr = m_Exe->getContentAt(rva, Executable::RVA, sizeof(pe::IMAGE_COR20_HEADER));
49 if (ptr == NULL) return NULL;
50
51 return (pe::IMAGE_COR20_HEADER*) ptr;
52}
53
55{
56 return true;
57}
58
60{
61 return clrDir();
62}
63
65{
66 if (!getPtr()) return 0;
67 return sizeof(pe::IMAGE_COR20_HEADER);
68}
69
71{
72 if (!getPtr()) return 0;
73 return FIELD_COUNTER;
74}
75
77{
78 return "CLR Directory";
79}
80
81void* ClrDirWrapper::getFieldPtr(size_t fId, size_t subField)
82{
83 pe::IMAGE_COR20_HEADER* d = clrDir();
84 if (!d) return NULL;
85
86 switch (fId) {
87 case CB: return &d->cb;
88 case MAJOR_RUNTIME_VER: return &d->MajorRuntimeVersion;
89 case MINOR_RUNTIME_VER: return &d->MinorRuntimeVersion;
90 case META_DATA_VA: return &d->MetaData.VirtualAddress;
91 case META_DATA_SIZE: return &d->MetaData.Size;
92 case FLAGS: return &d->Flags;
93 case ENTRY_POINT:
94 {
95 return &d->EntryPointRVA;
96 }
97 case RESOURCES_VA: return &d->Resources.VirtualAddress;
98 case RESOURCES_SIZE: return &d->Resources.Size;
99 case STRONG_NAME_SIGNATURE_VA: return &d->StrongNameSignature.VirtualAddress;
100 case STRONG_NAME_SIGNATURE_SIZE: return &d->StrongNameSignature.Size;
101 case CODE_MANAGER_TABLE_VA: return &d->CodeManagerTable.VirtualAddress;
102 case CODE_MANAGER_TABLE_SIZE: return &d->CodeManagerTable.Size;
103 case VTABLE_FIXUPS_VA: return &d->VTableFixups.VirtualAddress;
104 case VTABLE_FIXUPS_SIZE: return &d->VTableFixups.Size;
105 case EXPORT_ADDR_TABLE_JMPS_VA: return &d->ExportAddressTableJumps.VirtualAddress;
106 case EXPORT_ADDR_TABLE_JMPS_SIZE: return &d->ExportAddressTableJumps.Size;
107 case MANAGED_NATIVE_HDR_VA: return &d->ManagedNativeHeader.VirtualAddress;
108 case MANAGED_NATIVE_HDR_SIZE: return &d->ManagedNativeHeader.Size;
109 }
110 return this->getPtr();
111}
112
113QString ClrDirWrapper::getFieldName(size_t fieldId)
114{
115 switch (fieldId) {
116 case CB: return "Cb";
117 case MAJOR_RUNTIME_VER: return "MajorRuntimeVersion";
118 case MINOR_RUNTIME_VER: return "MinorRuntimeVersion";
119 case META_DATA_VA: return "MetaData.VA";
120 case META_DATA_SIZE: return "MetaData.Size";
121 case FLAGS: return "Flags";
122 case ENTRY_POINT: {
123 const pe::IMAGE_COR20_HEADER* d = clrDir();
124 if (!d) return "EntryPoint";
125
126 if (d->Flags & pe::COMIMAGE_FLAGS_NATIVE_ENTRYPOINT) {
127 return "EntryPointRVA";
128 } else {
129 return "EntryPointToken";
130 }
131 }
132 case RESOURCES_VA: return "Resources.VA";
133 case RESOURCES_SIZE: return "Resources.Size";
134 case STRONG_NAME_SIGNATURE_VA: return "StrongNameSignature.VA";
135 case STRONG_NAME_SIGNATURE_SIZE: return "StrongNameSignature.Size";
136 case CODE_MANAGER_TABLE_VA: return "CodeManagerTable.VA";
137 case CODE_MANAGER_TABLE_SIZE: return "CodeManagerTable.Size";
138 case VTABLE_FIXUPS_VA: return "VTableFixups.VA";
139 case VTABLE_FIXUPS_SIZE: return "VTableFixups.Size";
140 case EXPORT_ADDR_TABLE_JMPS_VA: return "ExportAddressTableJumps.VA";
141 case EXPORT_ADDR_TABLE_JMPS_SIZE: return "ExportAddressTableJumps.Size";
142 case MANAGED_NATIVE_HDR_VA: return "ManagedNativeHeader.VA";
143 case MANAGED_NATIVE_HDR_SIZE: return "ManagedNativeHeader.Size";
144 }
145 return getName();
146}
147
149{
150 switch (fieldId) {
151 case ENTRY_POINT: {
152 const pe::IMAGE_COR20_HEADER* d = clrDir();
153 if (!d) return Executable::NOT_ADDR;
154 if (d->Flags & pe::COMIMAGE_FLAGS_NATIVE_ENTRYPOINT) {
155 return Executable::RVA;
156 } else {
158 }
159 }
160 case RESOURCES_VA:
161 case META_DATA_VA:
164 case VTABLE_FIXUPS_VA:
167 return Executable::RVA;
168 }
170}
171
172std::set<DWORD> ClrDirWrapper::getFlagsSet(DWORD flags)
173{
174 const size_t clrFlagsCount = 6;
175 const DWORD clrFlags[clrFlagsCount] = {
176 pe::COMIMAGE_FLAGS_ILONLY,
177 pe::COMIMAGE_FLAGS_32BITREQUIRED,
178 pe::COMIMAGE_FLAGS_IL_LIBRARY,
179 pe::COMIMAGE_FLAGS_STRONGNAMESIGNED,
180 pe::COMIMAGE_FLAGS_NATIVE_ENTRYPOINT,
181 pe::COMIMAGE_FLAGS_TRACKDEBUGDATA
182 };
183 std::set<DWORD> allFlags;
184 for (size_t i = 0; i < clrFlagsCount; ++i) {
185 const DWORD nextFlag = clrFlags[i];
186 if (flags & nextFlag) {
187 allFlags.insert(nextFlag);
188 }
189 }
190 return allFlags;
191}
192
194{
195 if (flags & pe::COMIMAGE_FLAGS_ILONLY) {
196 return ("IL Only");
197 }
198 if (flags & pe::COMIMAGE_FLAGS_32BITREQUIRED) {
199 return("32-bit required");
200 }
201 if (flags & pe::COMIMAGE_FLAGS_IL_LIBRARY) {
202 return ("IL Library");
203 }
204 if (flags & pe::COMIMAGE_FLAGS_STRONGNAMESIGNED) {
205 return("Strong Name Signed");
206 }
207 if (flags & pe::COMIMAGE_FLAGS_NATIVE_ENTRYPOINT) {
208 return("Native EntryPoint");
209 }
210 if (flags & pe::COMIMAGE_FLAGS_TRACKDEBUGDATA) {
211 return("Track Debug Data");
212 }
213 return "";
214}
215
217{
218 const pe::IMAGE_COR20_HEADER* d = clrDir();
219 if (!d) return "";
220
221 if (fieldId != FLAGS) return "";
222
223 std::set<DWORD> flagsSet = ClrDirWrapper::getFlagsSet(d->Flags);
224 std::set<DWORD>::iterator itr;
225 QStringList list;
226 for (itr = flagsSet.begin() ; itr != flagsSet.end(); ++itr) {
227 const DWORD nextFlag = *itr;
228 const QString flagInfo = ClrDirWrapper::translateFlag(nextFlag);
229 if (flagInfo.length() == 0) continue;
230 list.append(flagInfo);
231 }
232 return list.join(";");
233}
234
uint32_t bufsize_t
uint64_t offset_t
static std::set< DWORD > getFlagsSet(DWORD flags)
virtual size_t getFieldsCount()
virtual QString getName()
virtual QString getFieldName(size_t fieldId)
QString translateFieldContent(size_t fieldId)
static QString translateFlag(DWORD value)
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
virtual bufsize_t getSize()
@ EXPORT_ADDR_TABLE_JMPS_SIZE
virtual void * getPtr()
virtual void * getFieldPtr(size_t fieldId, size_t subField)
offset_t getDirEntryAddress()
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:65