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
scanner.cpp
Go to the documentation of this file.
1#include "scanner.h"
2
3#include <sstream>
4#include <fstream>
5#include <string>
6#include <locale>
7#include <codecvt>
8
9#include <tlhelp32.h>
10
17
18#include "headers_scanner.h"
19#include "code_scanner.h"
20#include "iat_scanner.h"
21#include "workingset_scanner.h"
22#include "mapping_scanner.h"
24#include "thread_scanner.h"
25
26using namespace pesieve;
27using namespace pesieve::util;
28
29namespace pesieve {
30
32 {
33 if (!strparam.buffer || strparam.length == 0) {
34 return false;
35 }
36 if (IsBadReadPtr(strparam.buffer, strparam.length)) {
37 return false;
38 }
39 return true;
40 }
41
42 namespace util {
43
44 void print_scantime(std::stringstream& stream, size_t timeInMs)
45 {
46 float seconds = ((float)timeInMs / 1000);
47 float minutes = ((float)timeInMs / 60000);
48 stream << std::dec << timeInMs << " ms.";
49 if (seconds > 0.5) {
50 stream << " = " << seconds << " sec.";
51 }
52 if (minutes > 0.5) {
53 stream << " = " << minutes << " min.";
54 }
55 }
56
57 }; // namespace util
58
59 void print_scan_time(const char* scanned_element, size_t total_time)
60 {
61 std::stringstream ss;
62 ss << "[*] "<< scanned_element << " scanned in ";
63 util::print_scantime(ss, total_time);
64 std::cout << ss.str() << std::endl;
65 }
66
67 bool is_running(HANDLE processHandle)
68 {
69 DWORD exitCode = 0;
70 if (GetExitCodeProcess(processHandle, &exitCode)) {
71 if (exitCode != STILL_ACTIVE) {
72#ifdef _DEBUG
73 std::cerr << "Process terminated, exit = " << std::dec << exitCode << "\n";
74#endif
75 return false; //process terminated, discontinue the scan
76 }
77 }
78 return true;
79 }
80};
81
82pesieve::ProcessScanner::ProcessScanner(HANDLE procHndl, bool is_reflection, pesieve::t_params _args)
83 : processHandle(procHndl), isDEP(false), isReflection(is_reflection),
84 args(_args)
85{
87 if (validate_param_str(args.modules_ignored)) {
88 pesieve::util::string_to_list(args.modules_ignored.buffer, PARAM_LIST_SEPARATOR, ignoredModules);
89 }
90}
91
92t_scan_status pesieve::ProcessScanner::scanForHollows(HANDLE processHandle, ModuleData& modData, RemoteModuleData &remoteModData, ProcessScanReport& process_report)
93{
94 BOOL isWow64 = FALSE;
95#ifdef _WIN64
96 is_process_wow64(processHandle, &isWow64);
97#endif
98 HeadersScanner scanner(processHandle, modData, remoteModData);
99 HeadersScanReport *scan_report = scanner.scanRemote();
100 if (!scan_report) {
101 return SCAN_ERROR;
102 }
103
104 if (scan_report->archMismatch && isWow64) {
105#ifdef _DEBUG
106 std::cout << "Arch mismatch, reloading..." << std::endl;
107#endif
108 if (modData.reloadWow64()) {
109 delete scan_report; // delete previous report
110 scan_report = scanner.scanRemote();
111 }
112 }
113 scan_report->moduleFile = modData.szModName;
114 scan_report->isInPEB = modData.isModuleInPEBList();
115
116 t_scan_status is_replaced = ModuleScanReport::get_scan_status(scan_report);
117 if (is_replaced && !scan_report->isHdrReplaced()) {
118 is_replaced = SCAN_NOT_SUSPICIOUS;
119 }
120 process_report.appendReport(scan_report);
121 return is_replaced;
122}
123
124t_scan_status pesieve::ProcessScanner::scanForIATHooks(HANDLE processHandle, ModuleData& modData, RemoteModuleData &remoteModData, ProcessScanReport& process_report, t_iat_scan_mode filter)
125{
126 const peconv::ExportsMapper *expMap = process_report.exportsMap;
127 if (!expMap) {
128 return SCAN_ERROR;
129 }
130
131 if (process_report.isModuleReplaced(modData.moduleHandle)) {
132#ifdef _DEBUG
133 std::cout << "Cannot scan replaced module for IAT hooks!\n";
134#endif
135 return SCAN_ERROR;
136 }
137 IATScanner scanner(processHandle, modData, remoteModData, *expMap, process_report.modulesInfo, filter);
138 IATScanReport *scan_report = scanner.scanRemote();
139 if (!scan_report) {
140 return SCAN_ERROR;
141 }
142 t_scan_status scan_res = ModuleScanReport::get_scan_status(scan_report);
143 scan_report->moduleFile = modData.szModName;
144 process_report.appendReport(scan_report);
145 return scan_res;
146}
147
148t_scan_status pesieve::ProcessScanner::scanForHooks(HANDLE processHandle, ModuleData& modData, RemoteModuleData &remoteModData, ProcessScanReport& process_report, bool scan_data, bool scan_inaccessible)
149{
150 CodeScanner scanner(processHandle, modData, remoteModData);
151 scanner.setScanData(scan_data);
152 scanner.setScanInaccessible(scan_inaccessible);
153 CodeScanReport *scan_report = scanner.scanRemote();
154 if (!scan_report) {
155 return SCAN_ERROR;
156 }
157 t_scan_status is_hooked = ModuleScanReport::get_scan_status(scan_report);
158
159 scan_report->moduleFile = modData.szModName;
160 process_report.appendReport(scan_report);
161 return is_hooked;
162}
163
165{
166 HookTargetResolver hookResolver(process_report);
167 std::set<ModuleScanReport*> &code_reports = process_report.reportsByType[ProcessScanReport::REPORT_CODE_SCAN];
168 size_t resolved_count = hookResolver.resolveAllHooks(code_reports);
169 return (resolved_count > 0);
170}
171
172inline bool set_non_suspicious(const std::set<ModuleScanReport*> &scan_reports, bool dnet_modules_only)
173{
174 bool is_set = false;
175 std::set<ModuleScanReport*>::iterator itr;
176 for (itr = scan_reports.begin(); itr != scan_reports.end(); ++itr) {
177 ModuleScanReport* report = *itr;
178 if (!report) {
179 //this should never happen
180 continue;
181 }
182 if (dnet_modules_only && !report->isDotNetModule) {
183 continue;
184 }
185 if (report->status == SCAN_SUSPICIOUS) {
186 report->status = SCAN_NOT_SUSPICIOUS;
187 is_set = true;
188 }
189 }
190 return is_set;
191}
192
194{
195 if (!process_report.isManaged // Not a .NET process
196 || this->args.dotnet_policy == pesieve::PE_DNET_NONE) // .NET policy not set
197 {
198 return false; // no filtering needed
199 }
200 bool is_set = false;
201 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_MAPPING
202 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
203 {
204 // set hook modules as not suspicious
205 const std::set<ModuleScanReport*> &reports = process_report.reportsByType[ProcessScanReport::REPORT_MAPPING_SCAN];
206 is_set = set_non_suspicious(reports, true);
207 }
208 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_HOOKS
209 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
210 {
211 // set hook modules as not suspicious
212 const std::set<ModuleScanReport*> &reports = process_report.reportsByType[ProcessScanReport::REPORT_CODE_SCAN];
213 is_set = set_non_suspicious(reports, false);
214 }
215 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_SHC
216 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
217 {
218 // set shellcodes detected by mempage scan as not suspicious
219 const std::set<ModuleScanReport*> &reports = process_report.reportsByType[ProcessScanReport::REPORT_MEMPAGE_SCAN];
220 const bool is_set1 = set_non_suspicious(reports, false);
221
222 // set shellcodes detected by thread scan as not-suspicious
223 const std::set<ModuleScanReport*>& reports2 = process_report.reportsByType[ProcessScanReport::REPORT_THREADS_SCAN];
224 const bool is_set2 = set_non_suspicious(reports2, false);
225 is_set = is_set1 || is_set2;
226 }
227 return is_set;
228}
229
231{
232 this->isDEP = is_DEP_enabled(this->processHandle);
233
234 const bool is_64bit = pesieve::util::is_process_64bit(this->processHandle);
235
236 ProcessScanReport *pReport = new ProcessScanReport(this->args.pid, is_64bit, this->isReflection, &this->args);
237
238 char image_buf[MAX_PATH] = { 0 };
239 GetProcessImageFileNameA(this->processHandle, image_buf, MAX_PATH);
240 pReport->mainImagePath = device_path_to_win32_path(image_buf);
241
242 std::stringstream errorsStr;
243
244 // scan modules
245 size_t modulesScanned = 0;
246 try {
247 modulesScanned = scanModules(*pReport);
248 } catch (std::exception &e) {
249 modulesScanned = 0;
250 errorsStr << e.what();
251 }
252
253 // scan working set
254 size_t regionsScanned = 0;
255 try {
256 regionsScanned = scanWorkingSet(*pReport);
257 } catch (std::exception &e) {
258 regionsScanned = 0;
259 errorsStr << e.what();
260 }
261
262 // scan IATs
263 size_t iatsScanned = 0;
264 if (args.iat) {
265 try {
266 iatsScanned = scanModulesIATs(*pReport);
267 }
268 catch (std::exception& e) {
269 iatsScanned = 0;
270 errorsStr << e.what();
271 }
272 }
273
274 // scan threads
275 size_t threadsScanned = 0;
276 if (args.threads) {
277 try {
278 threadsScanned = scanThreads(*pReport);
279 }
280 catch (std::exception& e) {
281 threadsScanned = 0;
282 errorsStr << e.what();
283 }
284 }
285
286 // throw error only if none of the scans was successful
287 if (!modulesScanned && !iatsScanned && !regionsScanned && !threadsScanned) {
288 throw std::runtime_error(errorsStr.str());
289 }
290 //post-process hooks
291 resolveHooksTargets(*pReport);
292
293 //post-process detection reports according to the .NET policy
294 filterDotNetReport(*pReport);
295 return pReport;
296}
297
299{
300 if (!util::count_workingset_entries(this->processHandle)) {
301 throw std::runtime_error("Could not query the working set. ");
302 return 0;
303 }
304 process_details proc_details(this->isReflection, this->isDEP);
305
306 DWORD start_tick = GetTickCount();
307 std::set<mem_region_info> region_bases;
308 size_t pages_count = util::enum_workingset(processHandle, region_bases);
309 if (!args.quiet) {
310 std::cout << "Scanning workingset: " << std::dec << pages_count << " memory regions." << std::endl;
311 }
312 size_t counter = 0;
313 //now scan all the nodes:
314
315 for (auto set_itr = region_bases.begin(); set_itr != region_bases.end() && is_running(this->processHandle); ++set_itr, ++counter) {
316 const mem_region_info region = *set_itr;
317
318 WorkingSetScanner scanner(this->processHandle, proc_details, region, this->args, pReport);
319 WorkingSetScanReport *my_report = scanner.scanRemote();
320 if (!my_report) {
321 continue;
322 }
323 my_report->is_listed_module = pReport.hasModule((ULONGLONG) my_report->module);
324 // this is a code section inside a PE file that was already detected
325 if (!my_report->has_pe
326 && (pReport.hasModuleContaining((ULONGLONG)my_report->module, my_report->moduleSize))
327 )
328 {
329 my_report->status = SCAN_NOT_SUSPICIOUS;
330 }
331
332 pReport.appendReport(my_report);
333 }
334 if (!args.quiet) {
335 const DWORD total_time = GetTickCount() - start_tick;
336 print_scan_time("Workingset", total_time);
337 }
338 return counter;
339}
340
342{
343 MappingScanner scanner(processHandle, modData);
344 MappingScanReport *scan_report = scanner.scanRemote();
345
346 process_report.appendReport(scan_report);
347 return scan_report;
348}
349
350size_t pesieve::ProcessScanner::scanModules(ProcessScanReport &pReport) //throws exceptions
351{
352 HMODULE hMods[1024] = { 0 };
353 const size_t modules_count = enum_modules(this->processHandle, hMods, sizeof(hMods), LIST_MODULES_ALL);
354 if (modules_count == 0) {
355 return 0;
356 }
357 if (args.imprec_mode != PE_IMPREC_NONE || args.iat != pesieve::PE_IATS_NONE) {
358 pReport.exportsMap = new peconv::ExportsMapper();
359 }
360
361 size_t counter = 0;
362 for (counter = 0; counter < modules_count && is_running(this->processHandle); counter++) {
363 if (processHandle == nullptr) break;
364 const HMODULE module_base = hMods[counter];
365 //load module from file:
366 ModuleData modData(processHandle, module_base, true, args.use_cache);
367 ModuleScanReport *mappingScanReport = this->scanForMappingMismatch(modData, pReport);
368
369 //load the original file to make the comparisons:
370 if (!modData.loadOriginal()) {
371 if (!args.quiet) {
372 std::cout << "[!][" << args.pid << "] Suspicious: could not read the module file!" << std::endl;
373 }
374 //make a report that finding original module was not possible
375 pReport.appendReport(new UnreachableModuleReport(module_base, 0, modData.szModName));
376 continue;
377 }
378 if (modData.isDotNet()) {
379 // the process contains at least one .NET module. Treat it as managed process:
380 pReport.isManaged = true;
381 }
382 // Don't scan modules that are in the ignore list
383 const std::string plainName = peconv::get_file_name(modData.szModName);
384 if (is_in_list(plainName, this->ignoredModules)) {
385 // ...but add such modules to the exports lookup:
386 if (pReport.exportsMap) {
387 pReport.exportsMap->add_to_lookup(modData.szModName, (HMODULE)modData.original_module, (ULONGLONG)modData.moduleHandle);
388 }
389 if (!args.quiet) {
390 std::cout << "[*] Skipping ignored: " << std::hex << (ULONGLONG)modData.moduleHandle << " : " << modData.szModName << std::endl;
391 }
392 pReport.appendReport(new SkippedModuleReport(modData.moduleHandle, modData.original_size, modData.szModName));
393 continue;
394 }
395
396 if (!args.quiet) {
397 std::cout << "[*] Scanning: " << modData.szModName;
398 if (modData.isDotNet()) {
399 std::cout << " (.NET) ";
400 }
401 std::cout << std::endl;
402 }
403 //load data about the remote module
404 RemoteModuleData remoteModData(processHandle, this->isReflection, module_base);
405 if (!remoteModData.isInitialized()) {
406 if (!is_running(processHandle)) break;
407 pReport.appendReport(new MalformedHeaderReport(module_base, 0, modData.szModName));
408 continue;
409 }
410 t_scan_status is_hollowed = scanForHollows(processHandle, modData, remoteModData, pReport);
411 if (is_hollowed == SCAN_ERROR) {
412 continue;
413 }
414 if (is_hollowed == SCAN_NOT_SUSPICIOUS) {
415 //if the content does not differ, ignore the different name of the mapped file
416 mappingScanReport->status = SCAN_NOT_SUSPICIOUS;
417 }
418
419 // the module is not hollowed, so we can add it to the exports lookup:
420 if (pReport.exportsMap) {
421 pReport.exportsMap->add_to_lookup(modData.szModName, (HMODULE) modData.original_module, (ULONGLONG) modData.moduleHandle);
422 }
423
424 if (!args.no_hooks //if hooks not disabled
425 && (is_hollowed == SCAN_NOT_SUSPICIOUS) // and process is not hollowed
426 )
427 {
428 const bool scan_data = ((this->args.data >= pesieve::PE_DATA_SCAN_ALWAYS) && (this->args.data != pesieve::PE_DATA_SCAN_INACCESSIBLE_ONLY))
429 || (!this->isDEP && (this->args.data == pesieve::PE_DATA_SCAN_NO_DEP));
430
431 const bool scan_inaccessible = (this->isReflection && (this->args.data >= PE_DATA_SCAN_INACCESSIBLE));
432 scanForHooks(processHandle, modData, remoteModData, pReport, scan_data, scan_inaccessible);
433 }
434 }
435 return counter;
436}
437
439{
440 if (!pReport.exportsMap) {
441 return 0; // this feature cannot work without Exports Map
442 }
443 HMODULE hMods[1024];
444 const size_t modules_count = enum_modules(this->processHandle, hMods, sizeof(hMods), LIST_MODULES_ALL);
445 if (modules_count == 0) {
446 return 0;
447 }
448 if (!args.quiet) {
449 std::cout << "Scanning for IAT hooks: " << modules_count << " modules." << std::endl;
450 }
451 DWORD start_tick = GetTickCount();
452 size_t counter = 0;
453 for (counter = 0; counter < modules_count && is_running(this->processHandle); counter++) {
454 if (!processHandle) break; // this should never happen
455
456 const HMODULE module_base = hMods[counter];
457 //load module from file:
458 ModuleData modData(processHandle, module_base, true, args.use_cache);
459
460 // Don't scan modules that are in the ignore list
461 std::string plainName = peconv::get_file_name(modData.szModName);
462 if (is_in_list(plainName, this->ignoredModules)) {
463 continue;
464 }
465
466 //load data about the remote module
467 RemoteModuleData remoteModData(processHandle, this->isReflection, module_base);
468 if (remoteModData.isInitialized() == false) {
469 //make a report that initializing remote module was not possible
470 pReport.appendReport(new MalformedHeaderReport(module_base, 0, modData.szModName));
471 continue;
472 }
473
474 // do the IAT scan:
475 scanForIATHooks(processHandle, modData, remoteModData, pReport, this->args.iat);
476 }
477 if (!args.quiet) {
478 const DWORD total_time = GetTickCount() - start_tick;
479 print_scan_time("IATs", total_time);
480 }
481 return counter;
482}
483
484size_t pesieve::ProcessScanner::scanThreads(ProcessScanReport& pReport) //throws exceptions
485{
486 if (!this->symbols.IsInitialized()) {
487 if (!args.quiet) {
488 std::cerr << "[-] Failed to initialize symbols!\n";
489 }
490 return 0;
491 }
492
493 const DWORD pid = pReport.pid; //original PID, not a reflection!
494
495 const bool is_64bit = pesieve::util::is_process_64bit(this->processHandle);
496#ifndef _WIN64
497 if (is_64bit) return 0;
498#endif
499
500 if (!args.quiet) {
501 std::cout << "Scanning threads." << std::endl;
502 }
503 DWORD start_tick = GetTickCount();
504
505 std::map<DWORD, thread_info> threads_info;
506 if (!pesieve::util::fetch_threads_info(pid, threads_info)) { //extended info, but doesn't work on old Windows...
507
508 if (!pesieve::util::fetch_threads_by_snapshot(pid, threads_info)) { // works on old Windows, but gives less data..
509
510 if (!args.quiet) {
511 std::cerr << "[-] Failed enumerating threads." << std::endl;
512 }
513 return 0;
514 }
515 }
516 if (!pesieve::util::query_threads_details(threads_info)) {
517 if (!args.quiet) {
518 std::cout << "[-] Failed quering thread details." << std::endl;
519 }
520 }
521
522 for (auto itr = threads_info.begin(); itr != threads_info.end() && is_running(this->processHandle); ++itr) {
523 const thread_info &info = itr->second;
524
525 ThreadScanner scanner(this->processHandle, this->isReflection, info, pReport.modulesInfo, pReport.exportsMap, &symbols);
527 pReport.appendReport(report);
528 }
529 if (!args.quiet) {
530 const DWORD total_time = GetTickCount() - start_tick;
531 print_scan_time("Threads", total_time);
532 }
533 return 0;
534}
bool InitSymbols(HANDLE _hProcess)
A report from the code scan, generated by CodeScanner.
A scanner for detection of patches in the code.
void setScanInaccessible(bool enable)
void setScanData(bool enable)
virtual CodeScanReport * scanRemote()
A report from the headers scan, generated by HeadersScanner.
A scanner for detection of PE header's modifications.
virtual HeadersScanReport * scanRemote()
Processes the list of the collected patches (preprocessed by PatchAnalyzer), and for those of them th...
size_t resolveAllHooks(IN OUT std::set< ModuleScanReport * > &code_reports)
Resolves all the hooks collected within the given set of reports.
A report from an IAT scan, generated by IATScanner.
Definition iat_scanner.h:12
A scanner for detection of IAT hooking.
Definition iat_scanner.h:62
virtual IATScanReport * scanRemote()
A scanner for detection of inconsistencies in mapping. Checks if the mapped file name is different th...
virtual MappingScanReport * scanRemote()
Loads a module from the disk, corresponding to the module in the scanned process' memory.
Definition module_data.h:15
char szModName[MAX_PATH]
A base class of all the reports detailing on the output of the performed module's scan.
static t_scan_status get_scan_status(const ModuleScanReport *report)
The report aggregating the results of the performed scan.
Definition scan_report.h:19
void appendReport(ModuleScanReport *report)
Definition scan_report.h:48
bool isModuleReplaced(HMODULE module_base)
peconv::ExportsMapper * exportsMap
Definition scan_report.h:98
std::set< ModuleScanReport * > reportsByType[REPORT_TYPES_COUNT]
bool hasModule(ULONGLONG page_addr)
Definition scan_report.h:67
bool hasModuleContaining(ULONGLONG page_addr, size_t size)
Definition scan_report.h:75
size_t scanWorkingSet(ProcessScanReport &pReport)
Definition scanner.cpp:298
size_t scanModules(ProcessScanReport &pReport)
Definition scanner.cpp:350
size_t scanThreads(ProcessScanReport &pReport)
Definition scanner.cpp:484
ProcessScanner(HANDLE procHndl, bool is_reflection, pesieve::t_params _args)
Definition scanner.cpp:82
static t_scan_status scanForHooks(HANDLE hProcess, ModuleData &modData, RemoteModuleData &remoteModData, ProcessScanReport &process_report, bool scan_data, bool scan_inaccessible)
Definition scanner.cpp:148
size_t scanModulesIATs(ProcessScanReport &pReport)
Definition scanner.cpp:438
pesieve::t_params args
Definition scanner.h:55
static t_scan_status scanForHollows(HANDLE hProcess, ModuleData &modData, RemoteModuleData &remoteModData, ProcessScanReport &process_report)
Definition scanner.cpp:92
bool resolveHooksTargets(ProcessScanReport &process_report)
Definition scanner.cpp:164
bool filterDotNetReport(ProcessScanReport &process_report)
Definition scanner.cpp:193
ModuleScanReport * scanForMappingMismatch(ModuleData &modData, ProcessScanReport &process_report)
Definition scanner.cpp:341
ProcessSymbolsManager symbols
Definition scanner.h:54
static t_scan_status scanForIATHooks(HANDLE hProcess, ModuleData &modData, RemoteModuleData &remoteModData, ProcessScanReport &process_report, t_iat_scan_mode filter)
Definition scanner.cpp:124
ProcessScanReport * scanRemote()
The main function of ProcessScanner, deploying the scan. Throws exceptions in case of a failure.
Definition scanner.cpp:230
Buffers the data from the module loaded in the scanned process into the local memory.
A report from the thread scan, generated by ThreadScanner.
virtual ThreadScanReport * scanRemote()
A report from the working set scan, generated by WorkingSetScanner.
A scanner for detection of code implants in the process workingset.
virtual WorkingSetScanReport * scanRemote()
bool is_process_64bit(IN HANDLE process)
bool fetch_threads_by_snapshot(IN DWORD pid, OUT std::map< DWORD, thread_info > &threads_info)
size_t enum_modules(IN HANDLE hProcess, IN OUT HMODULE hMods[], IN const DWORD hModsMax, IN DWORD filters)
void print_scantime(std::stringstream &stream, size_t timeInMs)
Definition scanner.cpp:44
BOOL is_process_wow64(IN HANDLE processHandle, OUT BOOL *isProcWow64)
bool is_DEP_enabled(HANDLE hProcess)
bool query_threads_details(IN OUT std::map< DWORD, thread_info > &threads_info)
DWORD count_workingset_entries(HANDLE processHandle)
std::string device_path_to_win32_path(const std::string &full_path)
size_t enum_workingset(HANDLE processHandle, std::set< mem_region_info > &regions)
bool is_in_list(std::string searched_string, std::set< std::string > &string_list, bool to_lower=true)
BOOL(CALLBACK *_MiniDumpWriteDump)(HANDLE hProcess
DWORD(__stdcall *_PssCaptureSnapshot)(HANDLE ProcessHandle
bool fetch_threads_info(IN DWORD pid, OUT std::map< DWORD, thread_info > &threads_info)
bool validate_param_str(PARAM_STRING &strparam)
Definition scanner.cpp:31
int MAX_PATH
Definition pesieve.py:10
void print_scan_time(const char *scanned_element, size_t total_time)
Definition scanner.cpp:59
bool is_running(HANDLE processHandle)
Definition scanner.cpp:67
std::string info()
The string with the basic information about the scanner.
Definition pe_sieve.cpp:274
enum pesieve::module_scan_status t_scan_status
@ PE_DATA_SCAN_INACCESSIBLE
scan data unconditionally, and inaccessible pages (if running in reflection mode)
@ PE_IMPREC_NONE
do not try to recover imports
bool set_non_suspicious(const std::set< ModuleScanReport * > &scan_reports, bool dnet_modules_only)
Definition scanner.cpp:172
Final summary about the scanned process.