PE-sieve
Scans all running processes. Recognizes and dumps a variety of potentially malicious implants (replaced/implanted PEs, shellcodes, hooks, in-memory patches).
Toggle main menu visibility
Loading...
Searching...
No Matches
postprocessors
imp_rec
imp_reconstructor.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <windows.h>
4
#include <map>
5
6
#include <peconv.h>
7
#include "
pe_sieve_types.h
"
8
9
#include "
../pe_buffer.h
"
10
#include "
iat_block.h
"
11
#include "../utils/artefacts_util.h"
12
13
namespace
pesieve
{
14
15
class
ImportTableBuffer
16
{
17
public
:
18
19
ImportTableBuffer
(DWORD _descriptorsRVA)
20
:
descriptors
(nullptr), descriptosCount(0),
21
descriptorsRVA(_descriptorsRVA),
22
namesRVA(0), namesBuf(nullptr), namesBufSize(0),
23
dllsRVA(0), dllsBufSize(0), dllsBuf(nullptr)
24
{
25
}
26
27
~ImportTableBuffer
()
28
{
29
delete
[]
descriptors
;
30
delete
[]namesBuf;
31
delete
[]dllsBuf;
32
}
33
34
bool
allocDesciptors
(
size_t
descriptors_count)
35
{
36
descriptors
=
new
(std::nothrow) IMAGE_IMPORT_DESCRIPTOR[descriptors_count];
37
if
(!
descriptors
) {
38
return
false
;
39
}
40
memset(
descriptors
, 0, descriptors_count);
41
size_t
size_bytes =
sizeof
(IMAGE_IMPORT_DESCRIPTOR) * descriptors_count;
42
memset(
descriptors
, 0, size_bytes);
43
descriptosCount = descriptors_count;
44
return
true
;
45
}
46
47
bool
allocNamesSpace
(DWORD names_rva,
size_t
names_size)
48
{
49
delete
[]namesBuf;
50
this->namesBuf =
new
(std::nothrow) BYTE[names_size];
51
if
(!this->namesBuf) {
52
this->namesBufSize = 0;
53
return
false
;
54
}
55
memset(this->namesBuf, 0, names_size);
56
this->namesBufSize = names_size;
57
this->namesRVA = names_rva;
58
return
true
;
59
}
60
61
bool
allocDllsSpace
(DWORD dlls_rva,
size_t
dlls_area_size)
62
{
63
delete
[]dllsBuf;
64
this->dllsBuf =
new
(std::nothrow) BYTE[dlls_area_size];
65
if
(!this->dllsBuf) {
66
this->dllsBufSize = 0;
67
return
false
;
68
}
69
memset(this->dllsBuf, 0, dlls_area_size);
70
this->dllsBufSize = dlls_area_size;
71
this->dllsRVA = dlls_rva;
72
return
true
;
73
}
74
75
size_t
getDescriptosCount
()
76
{
77
return
descriptosCount;
78
}
79
80
size_t
getDescriptorsSize
()
81
{
82
if
(!
descriptors
)
return
0;
83
const
size_t
size_bytes =
sizeof
(IMAGE_IMPORT_DESCRIPTOR) * descriptosCount;
84
return
size_bytes;
85
}
86
87
size_t
getNamesSize
()
88
{
89
if
(!this->namesBuf)
return
0;
90
return
this->namesBufSize;
91
}
92
93
size_t
getDllNamesSize
()
94
{
95
return
dllsBufSize;
96
}
97
98
DWORD
getRVA
()
99
{
100
return
descriptorsRVA;
101
}
102
103
//copy table to the Virtual PE buffer
104
bool
setTableInPe
(BYTE *vBuf,
size_t
vBufSize)
105
{
106
if
(!
descriptors
|| !namesBuf || !dllsBuf) {
107
return
false
;
108
}
109
const
size_t
descriptors_size_b =
getDescriptorsSize
();
110
if
((descriptorsRVA + descriptors_size_b) > vBufSize || (namesRVA + namesBufSize) > vBufSize) {
111
// buffer too small
112
return
false
;
113
}
114
IMAGE_DATA_DIRECTORY* imp_dir = peconv::get_directory_entry(vBuf, IMAGE_DIRECTORY_ENTRY_IMPORT,
true
);
115
if
(!imp_dir) {
116
//cannot retrieve import directory
117
return
false
;
118
}
119
120
const
size_t
import_table_size =
getDescriptorsSize
() +
getNamesSize
();
121
122
//copy buffers into PE:
123
memcpy(vBuf + descriptorsRVA,
descriptors
, descriptors_size_b);
124
memcpy(vBuf + namesRVA, namesBuf, namesBufSize);
125
memcpy(vBuf + dllsRVA, dllsBuf, dllsBufSize);
126
127
//overwrite the Data Directory:
128
imp_dir->VirtualAddress = descriptorsRVA;
129
imp_dir->Size =
MASK_TO_DWORD
(import_table_size);
130
return
true
;
131
}
132
133
protected
:
134
135
BYTE *
getNamesSpaceAt
(
const
DWORD rva,
size_t
required_size);
136
137
BYTE*
getDllSpaceAt
(
const
DWORD rva,
size_t
required_size);
138
139
IMAGE_IMPORT_DESCRIPTOR*
descriptors
;
140
friend
class
ImpReconstructor
;
141
142
private
:
143
144
DWORD descriptorsRVA;
145
size_t
descriptosCount;
146
147
DWORD namesRVA;
148
BYTE* namesBuf;
149
size_t
namesBufSize;
150
151
DWORD dllsRVA;
152
BYTE* dllsBuf;
153
size_t
dllsBufSize;
154
};
155
156
class
ImpReconstructor
{
157
158
public
:
159
160
ImpReconstructor
(
PeBuffer
&_peBuffer)
161
: peBuffer(_peBuffer), is64bit(false)
162
{
163
if
(!peBuffer.vBuf)
return
;
164
if (peBuffer.isValidPe()) {
165
this->is64bit = peconv::is64bit(peBuffer.vBuf);
166
}
167
else
{
168
const size_t found_pattern = pesieve::util::is_64bit_code(peBuffer.vBuf, peBuffer.vBufSize);
169
this->is64bit = (found_pattern != PATTERN_NOT_FOUND);
170
}
171
collectMainIatData();
172
}
173
174
~ImpReconstructor
()
175
{
176
deleteFoundIATs();
177
}
178
179
typedef
enum
imprec_filter
{
180
IMP_REC0
,
181
IMP_REC1
,
182
IMP_REC2
,
183
IMP_REC_COUNT
184
}
t_imprec_filter
;
185
186
typedef
enum
imprec_res
{
187
IMP_NOT_FOUND
= -3,
188
IMP_RECOVERY_ERROR
= -2,
189
IMP_RECOVERY_NOT_APPLICABLE
= -1,
190
IMP_RECOVERY_SKIPPED
= 0,
191
IMP_ALREADY_OK
= 1,
192
IMP_DIR_FIXED
= 2,
193
IMP_FIXED
= 3,
194
IMP_RECREATED_FILTER0
= 4,
195
IMP_RECREATED_FILTER1
= 5,
196
IMP_RECREATED_FILTER2
= 6,
197
}
t_imprec_res
;
198
199
t_imprec_res
rebuildImportTable
(
const
IN peconv::ExportsMapper* exportsMap, IN
const
pesieve::t_imprec_mode
&imprec_mode);
200
201
bool
printFoundIATs
(
const
std::string &reportPath);
202
203
private
:
204
205
t_imprec_res
_recreateImportTableFiltered(
const
IN peconv::ExportsMapper* exportsMap, IN
const
pesieve::t_imprec_mode
& imprec_mode);
206
207
IATBlock
* findIATBlock(IN
const
peconv::ExportsMapper* exportsMap,
size_t
start_offset);
208
IATBlock
* findIAT(IN
const
peconv::ExportsMapper* exportsMap,
size_t
start_offset);
209
void
collectMainIatData();
210
212
bool
hasDynamicIAT()
const
;
213
214
size_t
getMainIATSize()
const
;
215
216
size_t
getMaxDynamicIATSize(IN
bool
isIatTerminated)
const
;
217
218
bool
findImportTable(IN
const
peconv::ExportsMapper* exportsMap);
219
size_t
collectIATs(IN
const
peconv::ExportsMapper* exportsMap);
220
221
bool
isDefaultImportValid(IN
const
peconv::ExportsMapper* exportsMap);
222
223
bool
findIATsCoverage(IN
const
peconv::ExportsMapper* exportsMap,
t_imprec_filter
filter);
224
ImportTableBuffer
* constructImportTable();
225
bool
appendImportTable(
ImportTableBuffer
&importTable);
226
227
bool
appendFoundIAT(DWORD iat_offset,
IATBlock
* found_block)
228
{
229
if
(foundIATs.find(iat_offset) != foundIATs.end()) {
230
return
false
;
//already exist
231
}
232
foundIATs[iat_offset] = found_block;
233
return
true
;
234
}
235
236
void
deleteFoundIATs()
237
{
238
std::map<DWORD, IATBlock*>::iterator itr;
239
for
(itr = foundIATs.begin(); itr != foundIATs.end(); ++itr) {
240
delete
itr->second;
241
}
242
foundIATs.clear();
243
}
244
245
PeBuffer &peBuffer;
246
bool
is64bit;
247
std::map<DWORD, IATBlock*> foundIATs;
248
249
std::set<DWORD> mainIatThunks;
//< RVAs of the Thunks of the main IAT
250
};
251
252
};
// namespace pesieve
pesieve::IATBlock
Definition
iat_block.h:88
pesieve::ImpReconstructor::rebuildImportTable
t_imprec_res rebuildImportTable(const IN peconv::ExportsMapper *exportsMap, IN const pesieve::t_imprec_mode &imprec_mode)
Definition
imp_reconstructor.cpp:152
pesieve::ImpReconstructor::ImpReconstructor
ImpReconstructor(PeBuffer &_peBuffer)
Definition
imp_reconstructor.h:160
pesieve::ImpReconstructor::t_imprec_res
enum pesieve::ImpReconstructor::imprec_res t_imprec_res
pesieve::ImpReconstructor::printFoundIATs
bool printFoundIATs(const std::string &reportPath)
Definition
imp_reconstructor.cpp:201
pesieve::ImpReconstructor::imprec_filter
imprec_filter
Definition
imp_reconstructor.h:179
pesieve::ImpReconstructor::IMP_REC0
@ IMP_REC0
Definition
imp_reconstructor.h:180
pesieve::ImpReconstructor::IMP_REC_COUNT
@ IMP_REC_COUNT
Definition
imp_reconstructor.h:183
pesieve::ImpReconstructor::IMP_REC2
@ IMP_REC2
Definition
imp_reconstructor.h:182
pesieve::ImpReconstructor::IMP_REC1
@ IMP_REC1
Definition
imp_reconstructor.h:181
pesieve::ImpReconstructor::~ImpReconstructor
~ImpReconstructor()
Definition
imp_reconstructor.h:174
pesieve::ImpReconstructor::t_imprec_filter
enum pesieve::ImpReconstructor::imprec_filter t_imprec_filter
pesieve::ImpReconstructor::imprec_res
imprec_res
Definition
imp_reconstructor.h:186
pesieve::ImpReconstructor::IMP_RECOVERY_SKIPPED
@ IMP_RECOVERY_SKIPPED
Definition
imp_reconstructor.h:190
pesieve::ImpReconstructor::IMP_RECREATED_FILTER0
@ IMP_RECREATED_FILTER0
Definition
imp_reconstructor.h:194
pesieve::ImpReconstructor::IMP_RECOVERY_ERROR
@ IMP_RECOVERY_ERROR
Definition
imp_reconstructor.h:188
pesieve::ImpReconstructor::IMP_RECREATED_FILTER1
@ IMP_RECREATED_FILTER1
Definition
imp_reconstructor.h:195
pesieve::ImpReconstructor::IMP_FIXED
@ IMP_FIXED
Definition
imp_reconstructor.h:193
pesieve::ImpReconstructor::IMP_NOT_FOUND
@ IMP_NOT_FOUND
Definition
imp_reconstructor.h:187
pesieve::ImpReconstructor::IMP_RECOVERY_NOT_APPLICABLE
@ IMP_RECOVERY_NOT_APPLICABLE
Definition
imp_reconstructor.h:189
pesieve::ImpReconstructor::IMP_RECREATED_FILTER2
@ IMP_RECREATED_FILTER2
Definition
imp_reconstructor.h:196
pesieve::ImpReconstructor::IMP_ALREADY_OK
@ IMP_ALREADY_OK
Definition
imp_reconstructor.h:191
pesieve::ImpReconstructor::IMP_DIR_FIXED
@ IMP_DIR_FIXED
Definition
imp_reconstructor.h:192
pesieve::ImportTableBuffer
Definition
imp_reconstructor.h:16
pesieve::ImportTableBuffer::ImpReconstructor
friend class ImpReconstructor
Definition
imp_reconstructor.h:140
pesieve::ImportTableBuffer::~ImportTableBuffer
~ImportTableBuffer()
Definition
imp_reconstructor.h:27
pesieve::ImportTableBuffer::allocDllsSpace
bool allocDllsSpace(DWORD dlls_rva, size_t dlls_area_size)
Definition
imp_reconstructor.h:61
pesieve::ImportTableBuffer::getDllNamesSize
size_t getDllNamesSize()
Definition
imp_reconstructor.h:93
pesieve::ImportTableBuffer::getRVA
DWORD getRVA()
Definition
imp_reconstructor.h:98
pesieve::ImportTableBuffer::allocNamesSpace
bool allocNamesSpace(DWORD names_rva, size_t names_size)
Definition
imp_reconstructor.h:47
pesieve::ImportTableBuffer::getDllSpaceAt
BYTE * getDllSpaceAt(const DWORD rva, size_t required_size)
Definition
imp_reconstructor.cpp:33
pesieve::ImportTableBuffer::getNamesSize
size_t getNamesSize()
Definition
imp_reconstructor.h:87
pesieve::ImportTableBuffer::ImportTableBuffer
ImportTableBuffer(DWORD _descriptorsRVA)
Definition
imp_reconstructor.h:19
pesieve::ImportTableBuffer::getNamesSpaceAt
BYTE * getNamesSpaceAt(const DWORD rva, size_t required_size)
Definition
imp_reconstructor.cpp:28
pesieve::ImportTableBuffer::setTableInPe
bool setTableInPe(BYTE *vBuf, size_t vBufSize)
Definition
imp_reconstructor.h:104
pesieve::ImportTableBuffer::getDescriptorsSize
size_t getDescriptorsSize()
Definition
imp_reconstructor.h:80
pesieve::ImportTableBuffer::allocDesciptors
bool allocDesciptors(size_t descriptors_count)
Definition
imp_reconstructor.h:34
pesieve::ImportTableBuffer::getDescriptosCount
size_t getDescriptosCount()
Definition
imp_reconstructor.h:75
pesieve::ImportTableBuffer::descriptors
IMAGE_IMPORT_DESCRIPTOR * descriptors
Definition
imp_reconstructor.h:139
pesieve::PeBuffer
Definition
pe_buffer.h:8
pesieve.t_imprec_mode
Definition
pesieve.py:43
iat_block.h
MASK_TO_DWORD
#define MASK_TO_DWORD(val)
Definition
iat_finder.h:9
pesieve
Definition
pesieve.py:1
pe_buffer.h
pe_sieve_types.h
The types used by PE-sieve API.
Generated by
1.17.0