PE-sieve
Scans all running processes. Recognizes and dumps a variety of potentially malicious implants (replaced/implanted PEs, shellcodes, hooks, in-memory patches).
Loading...
Searching...
No Matches
pe_buffer.cpp
Go to the documentation of this file.
1#include "pe_buffer.h"
2
3#include <iostream>
6
7size_t pesieve::PeBuffer::calcRemoteImgSize(ULONGLONG modBaseAddr) const
8{
9 const size_t hdr_buffer_size = PAGE_SIZE;
11 size_t pe_vsize = 0;
12
14 if (peconv::read_remote_pe_header(this->processHndl, (BYTE*)modBaseAddr, hdr_buffer, hdr_buffer_size)) {
15 hdr_ptr = peconv::get_section_hdr(hdr_buffer, hdr_buffer_size, 0);
16 }
17 if (!hdr_ptr) {
18 pe_vsize = peconv::fetch_region_size(this->processHndl, (PBYTE)modBaseAddr);
19 //std::cout << "[!] Image size at: " << std::hex << modBaseAddr << " undetermined, using region size instead: " << pe_vsize << std::endl;
20 return pe_vsize;
21 }
23 //std::cout << "[!] Image size at: " << std::hex << modBaseAddr << " undetermined, using calculated img size: " << pe_vsize << std::endl;
24 return pe_vsize;
25}
26
28{
29 if (pe_vsize == 0) {
30 // if not size supplied, try with the size fetched from the header
31 pe_vsize = peconv::get_remote_image_size(processHndl, (BYTE*)module_base);
32 }
33 if (_readRemote(module_base, pe_vsize)) {
34 return true; //success
35 }
36 // try with the calculated size
37 pe_vsize = calcRemoteImgSize(module_base);
38 std::cout << "[!] Image size at: " << std::hex << module_base << " undetermined, using calculated size: " << pe_vsize << std::endl;
39 return _readRemote(module_base, pe_vsize);
40}
41
43{
44 size_t cached_size = data_cache.getDataSize();
45 if (!cached_size) {
46 return false;
47 }
48 if (!allocBuffer(cached_size)) {
49 return false;
50 }
51 this->moduleBase = module_base;
52 this->relocBase = module_base; //by default set the same as module base
53
54 ::memcpy(this->vBuf, data_cache.getData(), cached_size);
55 return true;
56}
57
59{
60 if (pe_vsize == 0) {
61 return false;
62 }
63 if (!allocBuffer(pe_vsize)) {
64 return false;
65 }
66
67 // store the base no matter if reading succeeded or failed
68 this->moduleBase = module_base;
69 this->relocBase = module_base; //by default set the same as module base
70
71 const bool can_force_access = this->isRefl ? true : false;
72 size_t read_size = peconv::read_remote_area(processHndl, (BYTE*)this->moduleBase, vBuf, pe_vsize, can_force_access);
73 if (read_size != pe_vsize) {
74 std::cout << "[!] Failed reading Image at: " << std::hex << this->moduleBase << " img size: " << pe_vsize << std::endl;
75 freeBuffer();
76 return false;
77 }
78 return true;
79}
80
82{
83 if (!vBuf) return false;
84
85 BYTE *new_buf = peconv::alloc_aligned(new_size, PAGE_READWRITE);
86 if (!new_buf) {
87 return false;
88 }
89
90 size_t smaller_size = (vBufSize < new_size) ? vBufSize : new_size;
91 memcpy(new_buf, this->vBuf, smaller_size);
92 freeBuffer();
93
94 this->vBuf = new_buf;
95 this->vBufSize = new_size;
96 return true;
97}
98
100{
101 if (!vBuf) return false;
102
103 PIMAGE_SECTION_HEADER last_sec = peconv::get_last_section(vBuf, vBufSize, false);
104 if (!last_sec) {
105 return false;
106 }
107
109 return false;
110 }
111
112 const size_t new_sec_vsize = new_img_size - last_sec->VirtualAddress;
113 const size_t new_sec_rsize = new_sec_vsize;
114
115 if (last_sec->VirtualAddress + new_sec_vsize > this->vBufSize) {
116 //buffer too small
117 return false;
118 }
119
120 if (!peconv::update_image_size(vBuf, MASK_TO_DWORD(new_img_size))) {
121 return false;
122 }
123
124 last_sec->Misc.VirtualSize = MASK_TO_DWORD(new_sec_vsize);
125 last_sec->SizeOfRawData = MASK_TO_DWORD(new_sec_rsize);
126 return true;
127}
128
130 IN std::string dumpFileName,
131 IN OUT peconv::t_pe_dump_mode &dumpMode,
132 IN OPTIONAL const peconv::ExportsMapper* exportsMap,
133 OUT OPTIONAL peconv::ImpsNotCovered *notCovered
134)
135{
136 if (!vBuf || !isValidPe()) return false;
137#ifdef _DEBUG
138 std::cout << "Dumping using relocBase: " << std::hex << relocBase << "\n";
139#endif
140 if (exportsMap != nullptr) {
141 const bool fixed = peconv::fix_imports(this->vBuf, this->vBufSize, *exportsMap, notCovered);
142#ifdef _DEBUG
143 if (!fixed) {
144 std::cerr << "[-] Unable to fix imports!" << std::endl;
145 }
146#endif
147 }
148 if (dumpMode == peconv::PE_DUMP_AUTO) {
149 bool is_raw_alignment_valid = peconv::is_valid_sectons_alignment(vBuf, vBufSize, true);
150 bool is_virtual_alignment_valid = peconv::is_valid_sectons_alignment(vBuf, vBufSize, false);
151#ifdef _DEBUG
152 std::cout << "Is raw alignment valid: " << is_raw_alignment_valid << std::endl;
153 std::cout << "Is virtual alignment valid: " << is_virtual_alignment_valid << std::endl;
154#endif
156 //in case if raw alignment is invalid and virtual valid, try to dump using Virtual Alignment first
157 dumpMode = peconv::PE_DUMP_REALIGN;
158 bool is_dumped = peconv::dump_pe(dumpFileName.c_str(), this->vBuf, this->vBufSize, this->relocBase, dumpMode);
159 if (is_dumped) {
160 return is_dumped;
161 }
162 dumpMode = peconv::PE_DUMP_AUTO; //revert and try again
163 }
164 }
165 // dump PE in a given dump mode:
166 return peconv::dump_pe(dumpFileName.c_str(), this->vBuf, this->vBufSize, this->relocBase, dumpMode);
167}
168
169bool pesieve::PeBuffer::dumpToFile(IN std::string dumpFileName)
170{
171 if (!vBuf) return false;
172 return peconv::dump_to_file(dumpFileName.c_str(), vBuf, vBufSize);
173}
174
176{
177 if (!vBuf) return false;
178 return pesieve::util::is_code(vBuf, vBufSize);
179}
static size_t calcImgSize(HANDLE processHandle, HMODULE modBaseAddr, BYTE *headerBuffer, size_t headerBufferSize, IMAGE_SECTION_HEADER *hdr_ptr=NULL)
bool fillFromBuffer(ULONGLONG module_base, util::ByteBuffer &data_cache)
Definition pe_buffer.cpp:42
size_t calcRemoteImgSize(ULONGLONG module_base) const
Definition pe_buffer.cpp:7
bool _readRemote(ULONGLONG module_base, size_t pe_vsize)
Definition pe_buffer.cpp:58
bool readRemote(ULONGLONG module_base, size_t pe_vsize)
Definition pe_buffer.cpp:27
bool dumpPeToFile(IN std::string dumpFileName, IN OUT peconv::t_pe_dump_mode &dumpMode, IN OPTIONAL const peconv::ExportsMapper *exportsMap=NULL, OUT OPTIONAL peconv::ImpsNotCovered *notCovered=NULL)
bool resizeLastSection(size_t new_img_size)
Definition pe_buffer.cpp:99
bool resizeBuffer(size_t new_size)
Definition pe_buffer.cpp:81
bool dumpToFile(IN std::string dumpFileName)
#define MASK_TO_DWORD(val)
Definition iat_finder.h:9
bool is_code(BYTE *loadedData, size_t loadedSize)
size_t fill_iat(BYTE *vBuf, size_t vBufSize, IN const peconv::ExportsMapper *exportsMap, IN OUT IATBlock &iat, IN ThunkFoundCallback *callback)
Definition iat_finder.h:31
size_t getDataSize(bool trimmed=false) const
Definition byte_buffer.h:55
const BYTE * getData(bool trimmed=false) const
Definition byte_buffer.h:65
#define PAGE_SIZE