BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
PECore.cpp
Go to the documentation of this file.
1#include "pe/PECore.h"
2
3#define DEFAULT_IMGBASE 0x10000
4
6{
7 dos = NULL;
8 fHdr = NULL;
9 opt32 = NULL;
10 opt64 = NULL;
11}
12
14{
15 buf = v_buf;
16 const bool allowExceptionsFromBuffer = false;
17
18 // reset all:
19 reset();
20
21 offset_t offset = 0;
22 this->dos = (IMAGE_DOS_HEADER*) buf->getContentAt(offset, sizeof(IMAGE_DOS_HEADER), allowExceptionsFromBuffer);
23 if (!dos) throw ExeException("Could not wrap PECore: invalid DOS Header!");
24
25 offset = dos->e_lfanew + sizeof(DWORD); //skip 'PE' signature
26 this->fHdr = (IMAGE_FILE_HEADER*) buf->getContentAt(offset, sizeof(IMAGE_FILE_HEADER), allowExceptionsFromBuffer);
27 if (!fHdr) throw ExeException("Could not wrap PECore!");
28
29 offset = offset + sizeof(IMAGE_FILE_HEADER);
30 WORD *magic = (WORD*) buf->getContentAt(offset, sizeof(WORD), allowExceptionsFromBuffer);
31 if (!magic) throw ExeException("Could not wrap PECore: invalid FileHeader");
32
33 const Executable::exe_bits mode = ((*magic) == pe::OH_NT64) ? Executable::BITS_64 : Executable::BITS_32;
34 const size_t ntHdrSize = (mode == Executable::BITS_32) ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64);
35 BYTE *ntHdrPtr = buf->getContentAt(offset, ntHdrSize, allowExceptionsFromBuffer);
36
37 if (ntHdrPtr) {
38 if (mode == Executable::BITS_32) {
39 this->opt32 = (IMAGE_OPTIONAL_HEADER32*)ntHdrPtr;
40 }
41 else if (mode == Executable::BITS_64) {
42 this->opt64 = (IMAGE_OPTIONAL_HEADER64*)ntHdrPtr;
43 }
44 }
45 if (!this->opt32 && !this->opt64) {
46 throw ExeException("Could not wrap PECore: invalid OptionalHeader");
47 }
48 return true;
49}
50
52{
53 if (opt32) return Executable::BITS_32;
54 if (opt64) return Executable::BITS_64;
55
56 return Executable::BITS_32; // DEFAULT
57}
58
60{
61 if (!this->fHdr) {
63 }
64 if (this->fHdr->Machine == M_I386 || this->fHdr->Machine == M_AMD64) {
66 }
67 if (this->fHdr->Machine == M_ARM || this->fHdr->Machine == M_ARM64LE) {
69 }
71}
72
74{
75 if (!dos) return INVALID_ADDR;
76 return static_cast<offset_t> (dos->e_lfanew);
77}
78
80{
81 const offset_t offset = peSignatureOffset();
82 if (offset == INVALID_ADDR) {
83 return INVALID_ADDR;
84 }
85 const offset_t signSize = sizeof(DWORD);
86 return offset + signSize;
87}
88
90{
91 const offset_t offset = peFileHdrOffset();
92 if (offset == INVALID_ADDR) {
93 return INVALID_ADDR;
94 }
95 return offset + sizeof(IMAGE_FILE_HEADER);
96}
97
99{
100 if (this->getHdrBitMode() == Executable::BITS_64)
101 return sizeof(IMAGE_NT_HEADERS64);
102
103 return sizeof(IMAGE_NT_HEADERS32);
104}
105
107{
108 const offset_t offset = peOptHdrOffset();
109 if (offset == INVALID_ADDR) {
110 return INVALID_ADDR;
111 }
112 if (!fHdr) {
113 return INVALID_ADDR;
114 }
115 const offset_t size = static_cast<offset_t>(this->fHdr->SizeOfOptionalHeader);
116 return offset + size;
117}
118
120{
121 if (this->opt32) {
122 if (aType == Executable::RAW) return opt32->FileAlignment;
123 return opt32->SectionAlignment;
124 }
125 if (this->opt64) {
126 if (aType == Executable::RAW) return opt64->FileAlignment;
127 return opt64->SectionAlignment;
128 }
129 return 0;
130}
131
133{
134 bufsize_t imgSize = 0;
135 if (this->opt32) {
136 imgSize = opt32->SizeOfImage;
137 }
138 if (this->opt64) {
139 imgSize = opt64->SizeOfImage;
140 }
141 return imgSize;
142}
143
145{
147 if (this->opt32) {
148 hdrsSize = opt32->SizeOfHeaders;
149 }
150 if (this->opt64) {
151 hdrsSize = opt64->SizeOfHeaders;
152 }
153 return hdrsSize;
154}
155
157{
158 offset_t imgBase = 0;
159 if (this->opt32) {
160 imgBase = opt32->ImageBase;
161 }
162 if (this->opt64) {
163 imgBase = opt64->ImageBase;
164 }
165 //can be null, under XP. In this case, the binary will be relocated to 10000h
166 //(quote: http://code.google.com/p/corkami/wiki/PE)
167 if (imgBase == 0 && recalculate) {
168 imgBase = DEFAULT_IMGBASE;
169 }
170 //in 32 bit PEs: it can be any value as long as ImageBase + 'SizeOfImage' < 80000000h
171 //if the ImageBase is bigger than that, the binary will be relocated to 10000h
172 if (this->opt32) {
173 offset_t maxOffset = this->getImageSize() + imgBase;
174 if (maxOffset >= 0x80000000 && recalculate) {
175 imgBase = DEFAULT_IMGBASE;
176 }
177 }
178 return imgBase;
179}
180
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_t
#define DEFAULT_IMGBASE
Definition PECore.cpp:3
virtual BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Executable::exe_arch getHdrArch() const
Definition PECore.cpp:59
virtual bufsize_t getAlignment(Executable::addr_type aType) const
Definition PECore.cpp:119
bufsize_t hdrsSize() const
Definition PECore.cpp:144
offset_t peOptHdrOffset() const
Definition PECore.cpp:89
IMAGE_OPTIONAL_HEADER32 * opt32
Definition PECore.h:57
bool wrap(AbstractByteBuffer *v_buf)
Definition PECore.cpp:13
virtual offset_t getImageBase(bool recalculate=false)
Definition PECore.cpp:156
offset_t peFileHdrOffset() const
Definition PECore.cpp:79
AbstractByteBuffer * buf
Definition PECore.h:53
void reset()
Definition PECore.cpp:5
virtual bufsize_t getImageSize()
Definition PECore.cpp:132
offset_t peSignatureOffset() const
Definition PECore.cpp:73
IMAGE_FILE_HEADER * fHdr
Definition PECore.h:56
bufsize_t peNtHeadersSize() const
Definition PECore.cpp:98
offset_t secHdrsOffset() const
Definition PECore.cpp:106
IMAGE_OPTIONAL_HEADER64 * opt64
Definition PECore.h:58
Executable::exe_bits getHdrBitMode() const
Definition PECore.cpp:51
IMAGE_DOS_HEADER * dos
Definition PECore.h:55