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
bindings
python
pesieve.py
Go to the documentation of this file.
1
#!/usr/bin/env python3
2
# Requires Python 3.9+
3
4
import
ctypes
5
import
os
6
7
PESIEVE_MIN_VER = 0x040102
# minimal version of the PE-sieve DLL to work with this wrapper
8
PESIEVE_MAX_VER = 0x040102
# maximal version of the PE-sieve DLL to work with this wrapper
9
10
ERROR_SCAN_FAILURE = -1
11
MAX_PATH = 260
12
13
def
version_to_str
(version_val):
14
major = (version_val >> 24) & 0xFF
15
minor = (version_val >> 16) & 0xFF
16
patch = (version_val >> 8) & 0xFF
17
build = version_val & 0xFF
18
return
f
"{major}.{minor}.{patch}.{build}"
19
20
21
22
class
t_output_filter
(ctypes.c_int):
23
OUT_FULL = 0
24
OUT_NO_DUMPS = 1
25
OUT_NO_DIR = 2
26
OUT_FILTERS_COUNT = 3
27
28
class
t_shellc_mode
(ctypes.c_int):
29
SHELLC_NONE = 0
30
SHELLC_PATTERNS = 1
31
SHELLC_STATS = 2
32
SHELLC_PATTERNS_OR_STATS = 3
33
SHELLC_PATTERNS_AND_STATS = 4
34
SHELLC_COUNT = 5
35
36
class
t_obfusc_mode
(ctypes.c_int):
37
OBFUSC_NONE = 0
38
OBFUSC_STRONG_ENC = 1
39
OBFUSC_WEAK_ENC = 2
40
OBFUSC_ANY = 3
41
OBFUSC_COUNT = 4
42
43
class
t_imprec_mode
(ctypes.c_int):
44
PE_IMPREC_NONE = 0
45
PE_IMPREC_AUTO = 1
46
PE_IMPREC_UNERASE = 2
47
PE_IMPREC_REBUILD0 = 3
48
PE_IMPREC_REBUILD1 = 4
49
PE_IMPREC_REBUILD2 = 5
50
PE_IMPREC_MODES_COUNT = 6
51
52
class
t_dump_mode
(ctypes.c_int):
53
PE_DUMP_AUTO = 0
54
PE_DUMP_VIRTUAL = 1
55
PE_DUMP_UNMAP = 2
56
PE_DUMP_REALIGN = 3
57
PE_DUMP_MODES_COUNT = 4
58
59
class
t_iat_scan_mode
(ctypes.c_int):
60
PE_IATS_NONE = 0
61
PE_IATS_CLEAN_SYS_FILTERED = 1
62
PE_IATS_ALL_SYS_FILTERED = 2
63
PE_IATS_UNFILTERED = 3
64
PE_IATS_MODES_COUNT = 4
65
66
class
t_dotnet_policy
(ctypes.c_int):
67
PE_DNET_NONE = 0
68
PE_DNET_SKIP_MAPPING = 1
69
PE_DNET_SKIP_SHC = 2
70
PE_DNET_SKIP_HOOKS = 3
71
PE_DNET_SKIP_ALL = 4
72
PE_DNET_COUNT = 5
73
74
class
t_data_scan_mode
(ctypes.c_int):
75
PE_DATA_NO_SCAN = 0
76
PE_DATA_SCAN_DOTNET = 1
77
PE_DATA_SCAN_NO_DEP = 2
78
PE_DATA_SCAN_ALWAYS = 3
79
PE_DATA_SCAN_INACCESSIBLE = 4
80
PE_DATA_SCAN_INACCESSIBLE_ONLY = 5
81
PE_DATA_COUNT = 6
82
83
class
t_json_level
(ctypes.c_int):
84
JSON_BASIC = 0
85
JSON_DETAILS = 1
86
JSON_DETAILS2 = 2
87
JSON_LVL_COUNT = 3
88
89
class
t_results_filter
(ctypes.c_int):
90
SHOW_NONE = 0
91
SHOW_ERRORS = 1
92
SHOW_NOT_SUSPICIOUS = 2
93
SHOW_SUSPICIOUS = 4
94
SHOW_SUSPICIOUS_AND_ERRORS = 5
95
SHOW_SUCCESSFUL_ONLY = 6
96
SHOW_ALL = 7
97
98
class
t_report_type
(ctypes.c_int):
99
REPORT_NONE = 0
100
REPORT_SCANNED = 1
101
REPORT_DUMPED = 2
102
REPORT_ALL = 3
103
104
class
PARAM_STRING
(ctypes.Structure):
105
_fields_ = [
106
(
'length'
, ctypes.c_ulong),
107
(
'buffer'
, ctypes.c_char_p)
108
]
109
110
class
t_params
(ctypes.Structure):
111
_fields_ = [
112
(
'pid'
, ctypes.c_ulong),
113
(
'dotnet_policy'
, t_dotnet_policy),
114
(
'imprec_mode'
, t_imprec_mode),
115
(
'quiet'
, ctypes.c_bool),
116
(
'out_filter'
, t_output_filter),
117
(
'no_hooks'
, ctypes.c_bool),
118
(
'shellcode'
, t_shellc_mode),
119
(
'obfuscated'
, t_obfusc_mode),
120
(
'threads'
, ctypes.c_bool),
121
(
'iat'
, t_iat_scan_mode),
122
(
'data'
, t_data_scan_mode),
123
(
'minidump'
, ctypes.c_bool),
124
(
'rebase'
, ctypes.c_bool),
125
(
'dump_mode'
, t_dump_mode),
126
(
'json_output'
, ctypes.c_bool),
127
(
'make_reflection'
, ctypes.c_bool),
128
(
'use_cache'
, ctypes.c_bool),
129
(
'json_lvl'
, t_json_level),
130
(
'results_filter'
, t_results_filter),
131
(
'output_dir'
, ctypes.c_char * (MAX_PATH + 1)),
132
(
'modules_ignored'
, PARAM_STRING),
133
(
'pattern_file'
, PARAM_STRING)
134
]
135
136
class
t_report
(ctypes.Structure):
137
_fields_ = [
138
(
'pid'
, ctypes.c_ulong),
139
(
'is_managed'
, ctypes.c_bool),
140
(
'is_64bit'
, ctypes.c_bool),
141
(
'is_reflection'
, ctypes.c_bool),
142
(
'scanned'
, ctypes.c_ulong),
143
(
'suspicious'
, ctypes.c_ulong),
144
(
'replaced'
, ctypes.c_ulong),
145
(
'hdr_mod'
, ctypes.c_ulong),
146
(
'unreachable_file'
, ctypes.c_ulong),
147
(
'patched'
, ctypes.c_ulong),
148
(
'iat_hooked'
, ctypes.c_ulong),
149
(
'implanted'
, ctypes.c_ulong),
150
(
'implanted_pe'
, ctypes.c_ulong),
151
(
'implanted_shc'
, ctypes.c_ulong),
152
(
'other'
, ctypes.c_ulong),
153
(
'skipped'
, ctypes.c_ulong),
154
(
'errors'
, ctypes.c_ulong)
155
]
156
157
lib =
None
158
PESieve_version =
None
159
160
def
init
():
161
global
lib
162
global
PESieve_version
163
ptr_size = ctypes.sizeof(ctypes.c_voidp)
164
if
ptr_size == 4:
165
pesieve_dll =
"pe-sieve32.dll"
166
else
:
167
pesieve_dll =
"pe-sieve64.dll"
168
169
try
:
170
pesieve_path = os.path.abspath(os.getcwd()) + os.path.sep + pesieve_dll
171
lib = ctypes.cdll.LoadLibrary(pesieve_path)
172
except
FileNotFoundError:
173
if
'PESIEVE_DIR'
in
os.environ:
174
pesieve_path = os.environ.get(
'PESIEVE_DIR'
) + os.path.sep + pesieve_dll
175
lib = ctypes.cdll.LoadLibrary(pesieve_path)
176
else
:
177
raise
178
179
PESieve_version = ctypes.c_uint32.in_dll(lib,
"PESieve_version"
).value
180
if
(PESieve_version < PESIEVE_MIN_VER
or
PESieve_version > PESIEVE_MAX_VER):
181
dll_version_str =
version_to_str
(PESieve_version)
182
exception_msg = f
"Version mismatch: the PE-sieve.dll version ({dll_version_str}) doesn't match the bindings version"
183
raise
Exception(exception_msg)
184
185
lib.PESieve_scan.argtypes = [ctypes.POINTER(t_params)]
186
lib.PESieve_scan.restype = t_report
187
188
lib.PESieve_scan_ex.argtypes = [
189
ctypes.POINTER(t_params),
190
t_report_type,
191
ctypes.c_char_p,
192
ctypes.c_size_t,
193
ctypes.POINTER(ctypes.c_size_t),
194
]
195
lib.PESieve_scan_ex.restype = t_report
196
197
def
PESieve_help
():
198
if
not
lib:
199
init
()
200
lib.PESieve_help()
201
202
def
PESieve_scan
(params: t_params) -> t_report:
203
if
not
lib:
204
init
()
205
if
not
isinstance(params, t_params):
206
raise
TypeError(
"params must be t_params"
)
207
208
return
lib.PESieve_scan(ctypes.byref(params))
209
210
def
PESieve_scan_ex
(params: t_params, rtype: t_report_type, buf_size: int) -> tuple[t_report, str, int]:
211
if
not
lib:
212
init
()
213
if
not
isinstance(params, t_params):
214
raise
TypeError(
"params must be t_params"
)
215
if
buf_size < 0:
216
raise
ValueError(
"buf_size must be >= 0"
)
217
218
out_size = ctypes.c_size_t(0)
219
220
if
buf_size > 0:
221
json_buf = ctypes.create_string_buffer(buf_size)
222
report = lib.PESieve_scan_ex(
223
ctypes.byref(params),
224
rtype,
225
ctypes.cast(json_buf, ctypes.c_char_p),
226
ctypes.c_size_t(buf_size),
227
ctypes.byref(out_size)
228
)
229
json_str = json_buf.value.decode(
"utf-8"
, errors=
"replace"
)
230
else
:
231
report = lib.PESieve_scan_ex(
232
ctypes.byref(params),
233
rtype,
234
None
,
235
ctypes.c_size_t(0),
236
ctypes.byref(out_size)
237
)
238
json_str =
""
239
240
return
(report, json_str, out_size.value)
241
242
def
PESieve_scan_ex_auto
(params: t_params, rtype: t_report_type):
243
report, json_str, needed =
PESieve_scan_ex
(params, rtype, 0)
244
if
needed == 0:
245
return
report,
""
246
report, json_str, needed2 =
PESieve_scan_ex
(params, rtype, needed)
247
return
report, json_str
pesieve.PARAM_STRING
Definition
pesieve.py:104
pesieve.t_data_scan_mode
Definition
pesieve.py:74
pesieve.t_dotnet_policy
Definition
pesieve.py:66
pesieve.t_dump_mode
Definition
pesieve.py:52
pesieve.t_iat_scan_mode
Definition
pesieve.py:59
pesieve.t_imprec_mode
Definition
pesieve.py:43
pesieve.t_json_level
Definition
pesieve.py:83
pesieve.t_obfusc_mode
Definition
pesieve.py:36
pesieve.t_output_filter
Definition
pesieve.py:22
pesieve.t_params
Definition
pesieve.py:110
pesieve.t_report_type
Definition
pesieve.py:98
pesieve.t_report
Definition
pesieve.py:136
pesieve.t_results_filter
Definition
pesieve.py:89
pesieve.t_shellc_mode
Definition
pesieve.py:28
pesieve.PESieve_help
PESieve_help()
Definition
pesieve.py:197
pesieve.init
init()
Definition
pesieve.py:160
pesieve.version_to_str
version_to_str(version_val)
Definition
pesieve.py:13
pesieve.PESieve_scan_ex
tuple[t_report, str, int] PESieve_scan_ex(t_params params, t_report_type rtype, int buf_size)
Definition
pesieve.py:210
pesieve.PESieve_scan_ex_auto
PESieve_scan_ex_auto(t_params params, t_report_type rtype)
Definition
pesieve.py:242
pesieve.PESieve_scan
t_report PESieve_scan(t_params params)
Definition
pesieve.py:202
Generated by
1.17.0