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
params.h
Go to the documentation of this file.
1#pragma once
2#include <sstream>
3
4#include "pe_sieve.h"
6
7#include <paramkit.h>
8
9using namespace paramkit;
10using namespace pesieve;
11
12//scan options:
13#define PARAM_PID "pid"
14#define PARAM_SHELLCODE "shellc"
15#define PARAM_OBFUSCATED "obfusc"
16#define PARAM_THREADS "threads"
17#define PARAM_DATA "data"
18#define PARAM_IAT "iat"
19#define PARAM_MODULES_IGNORE "mignore"
20#define PARAM_REFLECTION "refl"
21#define PARAM_DOTNET_POLICY "dnet"
22#define PARAM_SYMBOLS "sym"
23
24//dump options:
25#define PARAM_IMP_REC "imp"
26#define PARAM_DUMP_MODE "dmode"
27#define PARAM_REBASE "rebase"
28//output options:
29#define PARAM_OUT_FILTER "ofilter"
30#define PARAM_RESULTS_FILTER "report"
31#define PARAM_QUIET "quiet"
32#define PARAM_JSON "json"
33#define PARAM_JSON_LVL "jlvl"
34#define PARAM_DIR "dir"
35#define PARAM_MINIDUMP "minidmp"
36#define PARAM_PATTERN "pattern"
37
38
39bool alloc_strparam(PARAM_STRING& strparam, ULONG len)
40{
41 if (strparam.buffer != nullptr) { // already allocated
42 return false;
43 }
44 strparam.buffer = (char*)calloc(len + 1, sizeof(char));
45 if (strparam.buffer) {
46 strparam.length = len;
47 return true;
48 }
49 return false;
50}
51
53{
54 free(strparam.buffer);
55 strparam.buffer = nullptr;
56 strparam.length = 0;
57}
58
59class PEsieveParams : public Params
60{
61public:
62 PEsieveParams(const std::string &version)
63 : Params(version)
64 {
65 this->addParam(new IntParam(PARAM_PID, true));
66 this->setInfo(PARAM_PID, "Set the PID of the target process.");
67
68 EnumParam *enumParam = new EnumParam(PARAM_IMP_REC, "imprec_mode", false);
69 if (enumParam) {
70 this->addParam(enumParam);
71 this->setInfo(PARAM_IMP_REC, "Set in which mode the ImportTable should be recovered");
72 for (size_t i = 0; i < PE_IMPREC_MODES_COUNT; i++) {
73 t_imprec_mode mode = (t_imprec_mode)(i);
74 enumParam->addEnumValue(mode, imprec_mode_to_id(mode), translate_imprec_mode(mode));
75 }
76 }
77
78 enumParam = new EnumParam(PARAM_OUT_FILTER, "ofilter_id", false);
79 if (enumParam) {
80 this->addParam(enumParam);
81 this->setInfo(PARAM_OUT_FILTER, "Filter the dumped output.");
82 for (size_t i = 0; i < OUT_FILTERS_COUNT; i++) {
84 enumParam->addEnumValue(mode, translate_out_filter(mode));
85 }
86 }
87
88 enumParam = new EnumParam(PARAM_RESULTS_FILTER, "result_type", false);
89 if (enumParam) {
90 this->addParam(enumParam);
91 this->setInfo(PARAM_RESULTS_FILTER, "Define what type of results are reported.");
92 for (size_t i = SHOW_SUSPICIOUS; i <= SHOW_ALL; i++) {
94 std::string info = translate_results_filter(mode);
95 if (info.empty()) continue;
96 enumParam->addEnumValue(mode, results_filter_to_id(i), info);
97 }
98 }
99
100 this->addParam(new StringListParam(PARAM_MODULES_IGNORE, false, PARAM_LIST_SEPARATOR));
101 {
102 std::stringstream ss1;
103 ss1 << "Do not scan module/s with given name/s.";
104 std::stringstream ss2;
105 ss2 << INFO_SPACER << "Example: kernel32.dll" << PARAM_LIST_SEPARATOR << "user32.dll";
106 this->setInfo(PARAM_MODULES_IGNORE, ss1.str(), ss2.str());
107 }
108
109 this->addParam(new BoolParam(PARAM_REBASE, false));
110 this->setInfo(PARAM_REBASE, "Rebase the module to its original base (if known).");
111
112 this->addParam(new BoolParam(PARAM_QUIET, false));
113 this->setInfo(PARAM_QUIET, "Print only the summary. Do not log on stdout during the scan.");
114
115 this->addParam(new BoolParam(PARAM_JSON, false));
116 this->setInfo(PARAM_JSON, "Print the JSON report as the summary.");
117 //
118 //PARAM_JSON_LVL
119 enumParam = new EnumParam(PARAM_JSON_LVL, "json_lvl", false);
120 if (enumParam) {
121 this->addParam(enumParam);
122 this->setInfo(PARAM_JSON_LVL, "Level of details of the JSON report.");
123 for (size_t i = 0; i < JSON_LVL_COUNT; i++) {
124 t_json_level mode = (t_json_level)(i);
125 enumParam->addEnumValue(mode, translate_json_level(mode));
126 }
127 }
128
129 this->addParam(new BoolParam(PARAM_MINIDUMP, false));
130 this->setInfo(PARAM_MINIDUMP, "Create a minidump of the full suspicious process.");
131
132 //PARAM_SHELLCODE
133 enumParam = new EnumParam(PARAM_SHELLCODE, "shellc_mode", false);
134 if (enumParam) {
135 this->addParam(enumParam);
136 this->setInfo(PARAM_SHELLCODE, "Detect shellcode implants (by patterns or statistics). ");
137 for (size_t i = 0; i < SHELLC_COUNT; i++) {
138 t_shellc_mode mode = (t_shellc_mode)(i);
139 enumParam->addEnumValue(mode, shellc_mode_mode_to_id(mode), translate_shellc_mode(mode));
140 }
141 }
142
143 this->addParam(new StringParam(PARAM_PATTERN, false));
144 this->setInfo(PARAM_PATTERN, "Set additional shellcode patterns (file in the SIG format).");
145
146 //PARAM_OBFUSCATED
147 enumParam = new EnumParam(PARAM_OBFUSCATED, "obfusc_mode", false);
148 if (enumParam) {
149 this->addParam(enumParam);
150 this->setInfo(PARAM_OBFUSCATED, "Detect encrypted content, and possible obfuscated shellcodes.");
151 for (size_t i = 0; i < OBFUSC_COUNT; i++) {
152 t_obfusc_mode mode = (t_obfusc_mode)(i);
153 enumParam->addEnumValue(mode, obfusc_mode_mode_to_id(mode), translate_obfusc_mode(mode));
154 }
155 }
156
157 //PARAM_THREADS
158 this->addParam(new BoolParam(PARAM_THREADS, false));
159 this->setInfo(PARAM_THREADS, "Scan threads' callstack. Detect shellcodes, incl. 'sleeping beacons'.");
160
161 //PARAM_REFLECTION
162 this->addParam(new BoolParam(PARAM_REFLECTION, false));
163 this->setInfo(PARAM_REFLECTION,
164 "Make a process reflection before scan.",
165 std::string(INFO_SPACER) + "This allows i.e. to force-read inaccessible pages."
166 );
167
168 //PARAM_SYMBOLS
169 this->addParam(new BoolParam(PARAM_SYMBOLS, false));
170 this->setInfo(PARAM_SYMBOLS,
171 "Autodownload symbols for scanned modules."
172 );
173 //PARAM_IAT
174 enumParam = new EnumParam(PARAM_IAT, "iat_scan_mode", false);
175 if (enumParam) {
176 this->addParam(enumParam);
177 this->setInfo(PARAM_IAT, "Scan for IAT hooks.");
178 for (size_t i = 0; i < PE_IATS_MODES_COUNT; i++) {
180 enumParam->addEnumValue(mode, translate_iat_scan_mode(mode));
181 }
182 }
183
184 //PARAM_DOTNET_POLICY
185 enumParam = new EnumParam(PARAM_DOTNET_POLICY, "dotnet_policy", false);
186 if (enumParam) {
187 this->addParam(enumParam);
188 this->setInfo(PARAM_DOTNET_POLICY, "Set the policy for scanning managed processes (.NET).");
189 for (size_t i = 0; i < PE_DNET_COUNT; i++) {
191 enumParam->addEnumValue(mode, translate_dotnet_policy(mode));
192 }
193 }
194
195 //PARAM_DATA
196 enumParam = new EnumParam(PARAM_DATA, "data_scan_mode", false);
197 if (enumParam) {
198 this->addParam(enumParam);
199 this->setInfo(PARAM_DATA, "Set if non-executable pages should be scanned.");
200 for (size_t i = 0; i < PE_DATA_COUNT; i++) {
202 enumParam->addEnumValue(mode, translate_data_mode(mode));
203 }
204 }
205
206 //PARAM_DUMP_MODE
207 enumParam = new EnumParam(PARAM_DUMP_MODE, "dump_mode", false);
208 if (enumParam) {
209 this->addParam(enumParam);
210 this->setInfo(PARAM_DUMP_MODE, "Set in which mode the detected PE files should be dumped.");
211 for (size_t i = 0; i < PE_DUMP_MODES_COUNT; i++) {
212 peconv::t_pe_dump_mode mode = (peconv::t_pe_dump_mode)(i);
213 enumParam->addEnumValue(mode, dump_mode_to_id(mode), translate_dump_mode(mode));
214 }
215 }
216
217 //PARAM_DIR
218 this->addParam(new StringParam(PARAM_DIR, false));
219 this->setInfo(PARAM_DIR, "Set a root directory for the output (default: current directory).");
220
221 //optional: group parameters
222 std::string str_group = "5. output options";
223 this->addGroup(new ParamGroup(str_group));
224 this->addParamToGroup(PARAM_DIR, str_group);
225 this->addParamToGroup(PARAM_JSON, str_group);
226 this->addParamToGroup(PARAM_JSON_LVL, str_group);
227 this->addParamToGroup(PARAM_OUT_FILTER, str_group);
228 this->addParamToGroup(PARAM_RESULTS_FILTER, str_group);
229
230 str_group = "1. scanner settings";
231 this->addGroup(new ParamGroup(str_group));
232 this->addParamToGroup(PARAM_QUIET, str_group);
233 this->addParamToGroup(PARAM_REFLECTION, str_group);
234 this->addParamToGroup(PARAM_SYMBOLS, str_group);
235
236 str_group = "3. scan options";
237 this->addGroup(new ParamGroup(str_group));
238 this->addParamToGroup(PARAM_DATA, str_group);
239 this->addParamToGroup(PARAM_IAT, str_group);
240 this->addParamToGroup(PARAM_SHELLCODE, str_group);
241 this->addParamToGroup(PARAM_OBFUSCATED, str_group);
242 this->addParamToGroup(PARAM_THREADS, str_group);
243 this->addParamToGroup(PARAM_PATTERN, str_group);
244
245 str_group = "4. dump options";
246 this->addGroup(new ParamGroup(str_group));
247 this->addParamToGroup(PARAM_MINIDUMP, str_group);
248 this->addParamToGroup(PARAM_IMP_REC, str_group);
249 this->addParamToGroup(PARAM_DUMP_MODE, str_group);
250 this->addParamToGroup(PARAM_REBASE, str_group);
251
252 str_group = "2. scan exclusions";
253 this->addGroup(new ParamGroup(str_group));
254 this->addParamToGroup(PARAM_DOTNET_POLICY, str_group);
255 this->addParamToGroup(PARAM_MODULES_IGNORE, str_group);
256 }
257
258 bool fillStringParam(const std::string &paramId, PARAM_STRING &strparam)
259 {
260 StringParam* myStr = dynamic_cast<StringParam*>(this->getParam(paramId));
261 if (!myStr || !myStr->isSet()) {
262 return false;
263 }
264 std::string val = myStr->valToString();
265 const size_t len = val.length();
266 if (!len) {
267 return false;
268 }
269 alloc_strparam(strparam, len);
270 bool is_copied = false;
271 if (strparam.buffer) {
272 is_copied = copyCStr<StringParam>(paramId, strparam.buffer, strparam.length);
273 }
274 return is_copied;
275 }
276
278 {
279 copyVal<IntParam>(PARAM_PID, ps.pid);
280 copyVal<EnumParam>(PARAM_IMP_REC, ps.imprec_mode);
281 copyVal<EnumParam>(PARAM_OUT_FILTER, ps.out_filter);
282 copyVal<EnumParam>(PARAM_RESULTS_FILTER, ps.results_filter);
283
284 fillStringParam(PARAM_MODULES_IGNORE, ps.modules_ignored);
285 copyVal<BoolParam>(PARAM_REBASE, ps.rebase);
286 copyVal<BoolParam>(PARAM_QUIET, ps.quiet);
287 copyVal<BoolParam>(PARAM_JSON, ps.json_output);
288
289 copyVal<EnumParam>(PARAM_JSON_LVL, ps.json_lvl);
290
291 copyVal<BoolParam>(PARAM_MINIDUMP, ps.minidump);
292 copyVal<EnumParam>(PARAM_SHELLCODE, ps.shellcode);
293 copyVal<EnumParam>(PARAM_OBFUSCATED, ps.obfuscated);
294 copyVal<BoolParam>(PARAM_THREADS, ps.threads);
295 copyVal<BoolParam>(PARAM_REFLECTION, ps.make_reflection);
296
297 copyVal<EnumParam>(PARAM_IAT, ps.iat);
298 copyVal<EnumParam>(PARAM_DOTNET_POLICY, ps.dotnet_policy);
299 copyVal<EnumParam>(PARAM_DATA, ps.data);
300 copyVal<EnumParam>(PARAM_DUMP_MODE, ps.dump_mode);
301
302 copyCStr<StringParam>(PARAM_DIR, ps.output_dir, _countof(ps.output_dir));
303 fillStringParam(PARAM_PATTERN, ps.pattern_file);
304
305 copyVal<BoolParam>(PARAM_SYMBOLS, ps.download_symbols);
306 }
307
309 {
310 char logo[] = "\
311.______ _______ _______. __ ___________ ____ _______ \n\
312| _ \\ | ____| / || | | ____\\ \\ / / | ____|\n\
313| |_) | | |__ ______ | (----`| | | |__ \\ \\/ / | |__ \n\
314| ___/ | __| |______| \\ \\ | | | __| \\ / | __| \n\
315| | | |____ .----) | | | | |____ \\ / | |____ \n\
316| _| |_______| |_______/ |__| |_______| \\__/ |_______|\n";
317
318 char logo2[] = "\
319 _ _______ _______ __ _______ __ _______ \n";
320 char logo3[] = "\
321________________________________________________________________________\n";
322 paramkit::print_in_color(DARK_GREEN, logo);
323 paramkit::print_in_color(DARK_RED, logo2);
324 paramkit::print_in_color(DARK_RED, logo3);
325 std::cout << "\n";
326 std::cout << pesieve::info();
327 }
328
329};
void printBanner()
Definition params.h:308
PEsieveParams(const std::string &version)
Definition params.h:62
void fillStruct(t_params &ps)
Definition params.h:277
bool fillStringParam(const std::string &paramId, PARAM_STRING &strparam)
Definition params.h:258
std::string shellc_mode_mode_to_id(const pesieve::t_shellc_mode &mode)
std::string translate_iat_scan_mode(const pesieve::t_iat_scan_mode mode)
std::string translate_data_mode(const pesieve::t_data_scan_mode &mode)
std::string imprec_mode_to_id(const pesieve::t_imprec_mode imprec_mode)
std::string translate_obfusc_mode(const pesieve::t_obfusc_mode &mode)
std::string translate_dump_mode(const DWORD dump_mode)
std::string obfusc_mode_mode_to_id(const pesieve::t_obfusc_mode &mode)
std::string dump_mode_to_id(const DWORD dump_mode)
std::string translate_json_level(const pesieve::t_json_level &mode)
std::string results_filter_to_id(const DWORD r_filter)
std::string translate_out_filter(const pesieve::t_output_filter o_filter)
std::string info()
The string with the basic information about the scanner.
Definition pe_sieve.cpp:276
std::string translate_imprec_mode(const pesieve::t_imprec_mode imprec_mode)
std::string translate_results_filter(const pesieve::t_results_filter r_filter)
std::string translate_dotnet_policy(const pesieve::t_dotnet_policy &mode)
std::string translate_shellc_mode(const pesieve::t_shellc_mode &mode)
#define PARAM_IAT
Definition params.h:18
#define PARAM_RESULTS_FILTER
Definition params.h:30
#define PARAM_PATTERN
Definition params.h:36
#define PARAM_SYMBOLS
Definition params.h:22
#define PARAM_MINIDUMP
Definition params.h:35
#define PARAM_IMP_REC
Definition params.h:25
#define PARAM_OUT_FILTER
Definition params.h:29
#define PARAM_OBFUSCATED
Definition params.h:15
#define PARAM_JSON
Definition params.h:32
#define PARAM_PID
Definition params.h:13
#define PARAM_REBASE
Definition params.h:27
#define PARAM_DOTNET_POLICY
Definition params.h:21
#define PARAM_DATA
Definition params.h:17
#define PARAM_MODULES_IGNORE
Definition params.h:19
#define PARAM_QUIET
Definition params.h:31
bool alloc_strparam(PARAM_STRING &strparam, ULONG len)
Definition params.h:39
#define PARAM_THREADS
Definition params.h:16
#define PARAM_SHELLCODE
Definition params.h:14
#define PARAM_JSON_LVL
Definition params.h:33
#define PARAM_DIR
Definition params.h:34
void free_strparam(PARAM_STRING &strparam)
Definition params.h:52
#define PARAM_DUMP_MODE
Definition params.h:26
#define PARAM_REFLECTION
Definition params.h:20
The root of the PE-sieve scanner.
#define PARAM_LIST_SEPARATOR
@ SHOW_SUSPICIOUS
report only suspicious
@ SHOW_ALL
@ SHELLC_COUNT
@ PE_DATA_COUNT
@ PE_DUMP_MODES_COUNT
@ PE_IATS_MODES_COUNT
@ OUT_FILTERS_COUNT
@ PE_DNET_COUNT
@ OBFUSC_COUNT
@ PE_IMPREC_MODES_COUNT
@ JSON_LVL_COUNT