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
scanners
pe_section.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <windows.h>
4
5
#include <peconv.h>
6
#include "
module_data.h
"
7
8
namespace
pesieve
{
9
11
class
PeSection
12
{
13
public
:
14
PeSection
(
RemoteModuleData
& remoteModData,
size_t
section_number)
15
:
loadedSection
(nullptr),
loadedSize
(0),
rva
(0),
rawSize
(0)
16
{
17
loadRemote
(remoteModData, section_number);
18
}
19
20
PeSection
(
ModuleData
& modData,
size_t
section_number)
21
:
loadedSection
(nullptr),
loadedSize
(0),
rva
(0),
rawSize
(0)
22
{
23
loadOriginal
(modData, section_number);
24
}
25
26
~PeSection
()
27
{
28
unload
();
29
}
30
31
bool
isInitialized
()
32
{
33
return
(
loadedSection
&&
loadedSize
> 0) ? true :
false
;
34
}
35
36
bool
isContained
(ULONGLONG field_start,
size_t
field_size)
37
{
38
ULONGLONG field_end = field_start + field_size;
39
40
bool
isInside = (field_start >= this->
rva
&& (field_start < (this->
rva
+ this->
loadedSize
)))
41
|| (field_end >= this->
rva
&& (field_end < (this->
rva
+ this->
loadedSize
)));
42
43
return
isInside;
44
}
45
46
size_t
rawSize
;
47
size_t
loadedSize
;
48
PBYTE
loadedSection
;
49
DWORD
rva
;
50
51
protected
:
52
53
bool
loadRemote
(
RemoteModuleData
& remoteModData,
size_t
section_number)
54
{
55
unload
();
//ensure that buffers are empty
56
57
//corner case: if no sections in PE
58
const
size_t
hdr_sec_num = peconv::get_sections_count(remoteModData.
headerBuffer
, remoteModData.
getHeaderSize
());
59
if
(hdr_sec_num == 0 && section_number == 0) {
60
return
loadRemoteImageAsSection(remoteModData);
61
}
62
//normal case: if PE has sections
63
PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(remoteModData.
headerBuffer
, peconv::MAX_HEADER_SIZE, section_number);
64
if
((!section_hdr) || section_hdr->Misc.VirtualSize == 0) {
65
return
false
;
66
}
67
this->rawSize = section_hdr->SizeOfRawData;
68
this->rva = section_hdr->VirtualAddress;
69
//get the code section from the module:
70
this->loadedSize = 0;
71
this->loadedSection = peconv::get_remote_pe_section(remoteModData.
processHandle
, (PBYTE)remoteModData.
modBaseAddr
, section_number,
loadedSize
,
true
, remoteModData.
isReflection
);
72
if
(
loadedSection
==
nullptr
) {
73
return
false
;
74
}
75
return
true
;
76
}
77
78
bool
loadOriginal
(
ModuleData
& modData,
size_t
section_number)
79
{
80
unload
();
//ensure that buffers are empty
81
82
//corner case: if no sections in PE
83
const
size_t
hdr_sec_num = peconv::get_sections_count(modData.
original_module
, modData.
original_size
);
84
if
(hdr_sec_num == 0 && section_number == 0) {
85
return
loadOriginalImageAsSection(modData);
86
}
87
PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modData.
original_module
, modData.
original_size
, section_number);
88
if
(section_hdr ==
nullptr
) {
89
return
false
;
90
}
91
this->rawSize = section_hdr->SizeOfRawData;
92
const
size_t
raw_code_size = section_hdr->SizeOfRawData;
93
const
size_t
orig_code_size = section_hdr->Misc.VirtualSize > raw_code_size ? section_hdr->Misc.VirtualSize : raw_code_size;
94
95
loadedSection
= peconv::alloc_unaligned(orig_code_size);
96
if
(
loadedSection
==
nullptr
) {
97
return
false
;
98
}
99
this->rva = section_hdr->VirtualAddress;
100
//make a copy of the section:
101
BYTE *orig_code = modData.
original_module
+ section_hdr->VirtualAddress;
102
memcpy(
loadedSection
, orig_code, raw_code_size);
103
loadedSize
= orig_code_size;
104
return
true
;
105
}
106
107
void
unload
()
108
{
109
if
(!
loadedSection
) {
110
return
;
111
}
112
peconv::free_unaligned(
loadedSection
);
113
loadedSection
=
nullptr
;
114
loadedSize
= 0;
115
}
116
117
private
:
118
bool
loadOriginalImageAsSection(
ModuleData
& modData)
119
{
120
#ifdef _DEBUG
121
std::cout <<
"PE with no sections! Loading original image as section\n"
;
122
#endif
123
if
(!modData.
isInitialized
()) {
124
return
false
;
125
}
126
peconv::UNALIGNED_BUF buf = peconv::alloc_unaligned(modData.
original_size
);
127
if
(!buf) {
128
#ifdef _DEBUG
129
std::cout <<
"Could not alloc: "
<< std::hex << modData.
original_size
<<
"\n"
;
130
#endif
131
return
false
;
132
}
133
memcpy(buf, modData.
original_module
, modData.
original_size
);
134
loadedSection
= buf;
135
loadedSize
= modData.
original_size
;
136
rawSize
= modData.
original_size
;
137
rva
= 0;
138
#ifdef _DEBUG
139
std::cout <<
"Copied local: "
<< std::hex << modData.
original_size
<<
"\n"
;
140
#endif
141
return
true
;
142
}
143
144
bool
_loadRemoteImageAsSection(RemoteModuleData& remoteModData,
size_t
image_size)
145
{
146
peconv::UNALIGNED_BUF buf = peconv::alloc_unaligned(image_size);
147
if
(!buf) {
148
return
false
;
149
}
150
size_t
read_size = peconv::read_remote_pe(remoteModData.processHandle, (PBYTE)remoteModData.modBaseAddr, image_size, buf, image_size);
151
if
(read_size != image_size) {
152
//std::cout << "Read size: " << std::hex << read_size << " vs " << image_size << "\n";
153
peconv::free_unaligned(buf);
154
return
false
;
155
}
156
this->
loadedSection
= buf;
157
this->
loadedSize
= read_size;
158
this->
rawSize
= 0;
// TODO: unknown?
159
this->
rva
= 0;
160
return
true
;
161
}
162
163
bool
loadRemoteImageAsSection(RemoteModuleData& remoteModData)
164
{
165
#ifdef _DEBUG
166
std::cout <<
"PE with no sections! Loading remote image as section\n"
;
167
#endif
168
if
(_loadRemoteImageAsSection(remoteModData, remoteModData.getModuleSize())) {
169
return
true
;
170
}
171
// if failed, try again with calculated size
172
return
_loadRemoteImageAsSection(remoteModData, remoteModData.calcImgSize());
173
}
174
};
175
176
};
//namespace pesieve
177
pesieve::ModuleData
Loads a module from the disk, corresponding to the module in the scanned process' memory.
Definition
module_data.h:15
pesieve::ModuleData::isInitialized
bool isInitialized()
Definition
module_data.h:78
pesieve::ModuleData::original_size
size_t original_size
Definition
module_data.h:104
pesieve::ModuleData::original_module
PBYTE original_module
Definition
module_data.h:103
pesieve::PeSection::loadRemote
bool loadRemote(RemoteModuleData &remoteModData, size_t section_number)
Definition
pe_section.h:53
pesieve::PeSection::PeSection
PeSection(RemoteModuleData &remoteModData, size_t section_number)
Definition
pe_section.h:14
pesieve::PeSection::loadedSize
size_t loadedSize
Definition
pe_section.h:47
pesieve::PeSection::isInitialized
bool isInitialized()
Definition
pe_section.h:31
pesieve::PeSection::unload
void unload()
Definition
pe_section.h:107
pesieve::PeSection::loadedSection
PBYTE loadedSection
Definition
pe_section.h:48
pesieve::PeSection::isContained
bool isContained(ULONGLONG field_start, size_t field_size)
Definition
pe_section.h:36
pesieve::PeSection::PeSection
PeSection(ModuleData &modData, size_t section_number)
Definition
pe_section.h:20
pesieve::PeSection::~PeSection
~PeSection()
Definition
pe_section.h:26
pesieve::PeSection::rva
DWORD rva
Definition
pe_section.h:49
pesieve::PeSection::rawSize
size_t rawSize
Definition
pe_section.h:46
pesieve::PeSection::loadOriginal
bool loadOriginal(ModuleData &modData, size_t section_number)
Definition
pe_section.h:78
pesieve::RemoteModuleData
Buffers the data from the module loaded in the scanned process into the local memory.
Definition
module_data.h:121
pesieve::RemoteModuleData::getHeaderSize
size_t getHeaderSize()
Definition
module_data.h:181
pesieve::RemoteModuleData::headerBuffer
BYTE headerBuffer[peconv::MAX_HEADER_SIZE]
Definition
module_data.h:196
pesieve::RemoteModuleData::modBaseAddr
HMODULE modBaseAddr
Definition
module_data.h:214
pesieve::RemoteModuleData::processHandle
HANDLE processHandle
Definition
module_data.h:212
pesieve::RemoteModuleData::isReflection
const bool isReflection
Definition
module_data.h:213
module_data.h
pesieve
Definition
pesieve.py:1
Generated by
1.17.0