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{
86 if (validate_param_str(args.modules_ignored)) {
87 pesieve::util::string_to_list(args.modules_ignored.buffer, PARAM_LIST_SEPARATOR, ignoredModules);
88 }
89 const bool lazy_sym = args.threads ? false : true;
90 this->symbols.InitSymbols(this->processHandle, args.download_symbols, lazy_sym);
91 if (!this->symbols.IsInitialized()) {
92 if (!args.quiet) {
93 std::cerr << "[-] Failed to initialize symbols!\n";
94 }
95 }
96}
97
99{
100 BOOL isWow64 = FALSE;
101#ifdef _WIN64
103#endif
104 HeadersScanner scanner(processHandle, modData, remoteModData);
105 HeadersScanReport *scan_report = scanner.scanRemote();
106 if (!scan_report) {
107 return SCAN_ERROR;
108 }
109
110 if (scan_report->archMismatch && isWow64) {
111#ifdef _DEBUG
112 std::cout << "Arch mismatch, reloading..." << std::endl;
113#endif
114 if (modData.reloadWow64()) {
115 delete scan_report; // delete previous report
116 scan_report = scanner.scanRemote();
117 }
118 }
119 scan_report->moduleFile = modData.szModName;
120 scan_report->isInPEB = modData.isModuleInPEBList();
121
122 t_scan_status is_replaced = ModuleScanReport::get_scan_status(scan_report);
123 if (is_replaced && !scan_report->isHdrReplaced()) {
124 is_replaced = SCAN_NOT_SUSPICIOUS;
125 }
126 process_report.appendReport(scan_report);
127 return is_replaced;
128}
129
131{
132 const peconv::ExportsMapper *expMap = process_report.exportsMap;
133 if (!expMap) {
134 return SCAN_ERROR;
135 }
136
137 if (process_report.isModuleReplaced(modData.moduleHandle)) {
138#ifdef _DEBUG
139 std::cout << "Cannot scan replaced module for IAT hooks!\n";
140#endif
141 return SCAN_ERROR;
142 }
143 IATScanner scanner(processHandle, modData, remoteModData, *expMap, process_report.modulesInfo, filter);
144 IATScanReport *scan_report = scanner.scanRemote();
145 if (!scan_report) {
146 return SCAN_ERROR;
147 }
148 t_scan_status scan_res = ModuleScanReport::get_scan_status(scan_report);
149 scan_report->moduleFile = modData.szModName;
150 process_report.appendReport(scan_report);
151 return scan_res;
152}
153
154t_scan_status pesieve::ProcessScanner::scanForHooks(HANDLE processHandle, ModuleData& modData, RemoteModuleData &remoteModData, ProcessScanReport& process_report, bool scan_data, bool scan_inaccessible)
155{
156 CodeScanner scanner(processHandle, modData, remoteModData);
157 scanner.setScanData(scan_data);
158 scanner.setScanInaccessible(scan_inaccessible);
159 CodeScanReport *scan_report = scanner.scanRemote();
160 if (!scan_report) {
161 return SCAN_ERROR;
162 }
163 t_scan_status is_hooked = ModuleScanReport::get_scan_status(scan_report);
164
165 scan_report->moduleFile = modData.szModName;
166 process_report.appendReport(scan_report);
167 return is_hooked;
168}
169
171{
172 HookTargetResolver hookResolver(process_report);
173 std::set<ModuleScanReport*> &code_reports = process_report.reportsByType[ProcessScanReport::REPORT_CODE_SCAN];
174 size_t resolved_count = hookResolver.resolveAllHooks(code_reports);
175 return (resolved_count > 0);
176}
177
178inline bool set_non_suspicious(const std::set<ModuleScanReport*> &scan_reports, bool dnet_modules_only)
179{
180 bool is_set = false;
181 std::set<ModuleScanReport*>::iterator itr;
182 for (itr = scan_reports.begin(); itr != scan_reports.end(); ++itr) {
183 ModuleScanReport* report = *itr;
184 if (!report) {
185 //this should never happen
186 continue;
187 }
188 if (dnet_modules_only && !report->isDotNetModule) {
189 continue;
190 }
191 if (report->status == SCAN_SUSPICIOUS) {
192 report->status = SCAN_NOT_SUSPICIOUS;
193 is_set = true;
194 }
195 }
196 return is_set;
197}
198
200{
201 if (!process_report.isManaged // Not a .NET process
202 || this->args.dotnet_policy == pesieve::PE_DNET_NONE) // .NET policy not set
203 {
204 return false; // no filtering needed
205 }
206 bool is_set = false;
207 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_MAPPING
208 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
209 {
210 // set hook modules as not suspicious
211 const std::set<ModuleScanReport*> &reports = process_report.reportsByType[ProcessScanReport::REPORT_MAPPING_SCAN];
212 is_set = set_non_suspicious(reports, true);
213 }
214 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_HOOKS
215 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
216 {
217 // set hook modules as not suspicious
218 const std::set<ModuleScanReport*> &reports = process_report.reportsByType[ProcessScanReport::REPORT_CODE_SCAN];
219 is_set = set_non_suspicious(reports, false);
220 }
221 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_SHC
222 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
223 {
224 // set shellcodes detected by mempage scan as not suspicious
225 const std::set<ModuleScanReport*> &reports = process_report.reportsByType[ProcessScanReport::REPORT_MEMPAGE_SCAN];
226 const bool is_set1 = set_non_suspicious(reports, false);
227
228 // set shellcodes detected by thread scan as not-suspicious
229 const std::set<ModuleScanReport*>& reports2 = process_report.reportsByType[ProcessScanReport::REPORT_THREADS_SCAN];
230 const bool is_set2 = set_non_suspicious(reports2, false);
231 is_set = is_set1 || is_set2;
232 }
233 return is_set;
234}
235
237{
238 this->isDEP = is_DEP_enabled(this->processHandle);
239
240 const bool is_64bit = pesieve::util::is_process_64bit(this->processHandle);
241
242 ProcessScanReport *pReport = new ProcessScanReport(this->args.pid, is_64bit, this->isReflection, &this->args);
243
244 char image_buf[MAX_PATH] = { 0 };
245 GetProcessImageFileNameA(this->processHandle, image_buf, MAX_PATH);
246 pReport->mainImagePath = device_path_to_win32_path(image_buf);
247
248 std::stringstream errorsStr;
249
250 // scan modules
251 size_t modulesScanned = 0;
252 try {
253 modulesScanned = scanModules(*pReport);
254 } catch (std::exception &e) {
255 modulesScanned = 0;
256 errorsStr << e.what();
257 }
258
259 // scan working set
260 size_t regionsScanned = 0;
261 try {
262 regionsScanned = scanWorkingSet(*pReport);
263 } catch (std::exception &e) {
264 regionsScanned = 0;
265 errorsStr << e.what();
266 }
267
268 // scan IATs
269 size_t iatsScanned = 0;
270 if (args.iat) {
271 try {
272 iatsScanned = scanModulesIATs(*pReport);
273 }
274 catch (std::exception& e) {
275 iatsScanned = 0;
276 errorsStr << e.what();
277 }
278 }
279
280 // scan threads
281 size_t threadsScanned = 0;
282 if (args.threads) {
283 try {
284 threadsScanned = scanThreads(*pReport);
285 }
286 catch (std::exception& e) {
287 threadsScanned = 0;
288 errorsStr << e.what();
289 }
290 }
291
292 // throw error only if none of the scans was successful
293 if (!modulesScanned && !iatsScanned && !regionsScanned && !threadsScanned) {
294 throw std::runtime_error(errorsStr.str());
295 }
296 //post-process hooks
297 resolveHooksTargets(*pReport);
298
299 //post-process detection reports according to the .NET policy
300 filterDotNetReport(*pReport);
301 return pReport;
302}
303
305{
307 throw std::runtime_error("Could not query the working set. ");
308 return 0;
309 }
310 process_details proc_details(this->isReflection, this->isDEP);
311
312 DWORD start_tick = GetTickCount();
313 std::set<mem_region_info> region_bases;
314 size_t pages_count = util::enum_workingset(processHandle, region_bases);
315 if (!args.quiet) {
316 std::cout << "Scanning workingset: " << std::dec << pages_count << " memory regions." << std::endl;
317 }
318 size_t counter = 0;
319 //now scan all the nodes:
320
321 for (auto set_itr = region_bases.begin(); set_itr != region_bases.end() && is_running(this->processHandle); ++set_itr, ++counter) {
322 const mem_region_info region = *set_itr;
323
324 WorkingSetScanner scanner(this->processHandle, proc_details, region, this->args, pReport);
325 WorkingSetScanReport *my_report = scanner.scanRemote();
326 if (!my_report) {
327 continue;
328 }
329 my_report->is_listed_module = pReport.hasModule((ULONGLONG) my_report->module);
330 // this is a code section inside a PE file that was already detected
331 if (!my_report->has_pe
332 && (pReport.hasModuleContaining((ULONGLONG)my_report->module, my_report->moduleSize))
333 )
334 {
335 my_report->status = SCAN_NOT_SUSPICIOUS;
336 }
337
338 pReport.appendReport(my_report);
339 }
340 if (!args.quiet) {
341 const DWORD total_time = GetTickCount() - start_tick;
342 print_scan_time("Workingset", total_time);
343 }
344 return counter;
345}
346
348{
349 MappingScanner scanner(processHandle, modData);
350 MappingScanReport *scan_report = scanner.scanRemote();
351
352 process_report.appendReport(scan_report);
353 return scan_report;
354}
355
356size_t pesieve::ProcessScanner::scanModules(ProcessScanReport &pReport) //throws exceptions
357{
358 std::vector<HMODULE> hMods;
359 if (!enum_modules(this->processHandle, hMods, LIST_MODULES_ALL)) {
360 return 0;
361 }
362 const size_t modules_count = hMods.size();
363 if (args.imprec_mode != PE_IMPREC_NONE || args.iat != pesieve::PE_IATS_NONE || args.threads) {
364 pReport.exportsMap = new peconv::ExportsMapper();
365 }
366
367 size_t counter = 0;
368 for (counter = 0; counter < modules_count && is_running(this->processHandle); counter++) {
369 if (processHandle == nullptr) break;
370 const HMODULE module_base = hMods[counter];
371 //load module from file:
372 ModuleData modData(processHandle, module_base, true, args.use_cache);
373 ModuleScanReport *mappingScanReport = this->scanForMappingMismatch(modData, pReport);
374
375 //load the original file to make the comparisons:
376 if (!modData.loadOriginal()) {
377 if (!args.quiet) {
378 std::cout << "[!][" << args.pid << "] Suspicious: could not read the module file!" << std::endl;
379 }
380 //make a report that finding original module was not possible
381 pReport.appendReport(new UnreachableModuleReport(module_base, 0, modData.szModName));
382 continue;
383 }
384 if (modData.isDotNet()) {
385 // the process contains at least one .NET module. Treat it as managed process:
386 pReport.isManaged = true;
387 }
388 // Don't scan modules that are in the ignore list
389 const std::string plainName = peconv::get_file_name(modData.szModName);
390 if (is_in_list(plainName, this->ignoredModules)) {
391 // ...but add such modules to the exports lookup:
392 if (pReport.exportsMap) {
393 pReport.exportsMap->add_to_lookup(modData.szModName, (HMODULE)modData.original_module, (ULONGLONG)modData.moduleHandle);
394 }
395 if (!args.quiet) {
396 std::cout << "[*] Skipping ignored: " << std::hex << (ULONGLONG)modData.moduleHandle << " : " << modData.szModName << std::endl;
397 }
398 pReport.appendReport(new SkippedModuleReport(modData.moduleHandle, modData.original_size, modData.szModName));
399 continue;
400 }
401
402 if (!args.quiet) {
403 std::cout << "[*] Scanning: " << modData.szModName;
404 if (modData.isDotNet()) {
405 std::cout << " (.NET) ";
406 }
407 std::cout << std::endl;
408 }
409 //load data about the remote module
410 RemoteModuleData remoteModData(processHandle, this->isReflection, module_base);
411 if (!remoteModData.isInitialized()) {
412 if (!is_running(processHandle)) break;
413 pReport.appendReport(new MalformedHeaderReport(module_base, 0, modData.szModName));
414 continue;
415 }
416 t_scan_status is_hollowed = scanForHollows(processHandle, modData, remoteModData, pReport);
417 if (is_hollowed == SCAN_ERROR) {
418 continue;
419 }
420 if (is_hollowed == SCAN_NOT_SUSPICIOUS) {
421 //if the content does not differ, ignore the different name of the mapped file
422 mappingScanReport->status = SCAN_NOT_SUSPICIOUS;
423 }
424
425 // the module is not hollowed, so we can add it to the exports lookup:
426 if (pReport.exportsMap) {
427 pReport.exportsMap->add_to_lookup(modData.szModName, (HMODULE) modData.original_module, (ULONGLONG) modData.moduleHandle);
428 }
429
430 if (!args.no_hooks //if hooks not disabled
431 && (is_hollowed == SCAN_NOT_SUSPICIOUS) // and process is not hollowed
432 )
433 {
434 const bool scan_data = ((this->args.data >= pesieve::PE_DATA_SCAN_ALWAYS) && (this->args.data != pesieve::PE_DATA_SCAN_INACCESSIBLE_ONLY))
435 || (!this->isDEP && (this->args.data == pesieve::PE_DATA_SCAN_NO_DEP));
436
437 const bool scan_inaccessible = (this->isReflection && (this->args.data >= PE_DATA_SCAN_INACCESSIBLE));
438 scanForHooks(processHandle, modData, remoteModData, pReport, scan_data, scan_inaccessible);
439 }
440 }
441 return counter;
442}
443
445{
446 if (!pReport.exportsMap) {
447 return 0; // this feature cannot work without Exports Map
448 }
449 std::vector<HMODULE> hMods;
450 if (!enum_modules(this->processHandle, hMods, LIST_MODULES_ALL)) {
451 return 0;
452 }
453 const size_t modules_count = hMods.size();
454 if (!args.quiet) {
455 std::cout << "Scanning for IAT hooks: " << std::dec << modules_count << " modules." << std::endl;
456 }
457
458 DWORD start_tick = GetTickCount();
459 size_t counter = 0;
460 for (counter = 0; counter < modules_count && is_running(this->processHandle); counter++) {
461 if (!processHandle) break; // this should never happen
462
463 const HMODULE module_base = hMods[counter];
464 //load module from file:
465 ModuleData modData(processHandle, module_base, true, args.use_cache);
466
467 // Don't scan modules that are in the ignore list
468 std::string plainName = peconv::get_file_name(modData.szModName);
469 if (is_in_list(plainName, this->ignoredModules)) {
470 continue;
471 }
472
473 //load data about the remote module
474 RemoteModuleData remoteModData(processHandle, this->isReflection, module_base);
475 if (remoteModData.isInitialized() == false) {
476 //make a report that initializing remote module was not possible
477 pReport.appendReport(new MalformedHeaderReport(module_base, 0, modData.szModName));
478 continue;
479 }
480
481 // do the IAT scan:
482 scanForIATHooks(processHandle, modData, remoteModData, pReport, this->args.iat);
483 }
484 if (!args.quiet) {
485 const DWORD total_time = GetTickCount() - start_tick;
486 print_scan_time("IATs", total_time);
487 }
488 return counter;
489}
490
491bool fill_threads_info(IN const DWORD pid, OUT std::map<DWORD, thread_info>& threads_info)
492{
493 if (!pesieve::util::fetch_threads_info(pid, threads_info)) { //extended info, but doesn't work on old Windows...
494
495 if (!pesieve::util::fetch_threads_by_snapshot(pid, threads_info)) { // works on old Windows, but gives less data..
496 return false;
497 }
498 }
499 return true;
500}
501
502size_t pesieve::ProcessScanner::scanThreads(ProcessScanReport& pReport) //throws exceptions
503{
504 const DWORD pid = pReport.pid; //original PID, not a reflection!
505 const bool is_64bit = pesieve::util::is_process_64bit(this->processHandle);
506#ifndef _WIN64
507 if (is_64bit) return 0;
508#endif
509
510 if (!args.quiet) {
511 std::cout << "Scanning threads." << std::endl;
512 }
513
514 const DWORD start_tick = GetTickCount();
515
516 std::map<DWORD, thread_info> threads_info;
517 if (!fill_threads_info(pid, threads_info)) {
518 if (!args.quiet) {
519 std::cerr << "[-] Failed enumerating threads or no live threads found." << std::endl;
520 }
521 return 0;
522 }
523 const size_t queried_count = pesieve::util::query_threads_details(threads_info);
524 if (queried_count == 0) {
525 if (!args.quiet) {
526 std::cout << "[-] Failed quering thread details." << std::endl;
527 }
528 }
529 size_t scanned_count = 0;
530 for (auto itr = threads_info.begin();
531 itr != threads_info.end() && is_running(this->processHandle);
532 ++itr)
533 {
534 const thread_info &info = itr->second;
535 if (!info.is_filled) continue;
536
537 ThreadScanner scanner(this->processHandle, this->isReflection, pReport.isManaged, info, pReport.modulesInfo, pReport.exportsMap, &symbols);
539 if (report) {
540 pReport.appendReport(report);
541 scanned_count++;
542 }
543 }
544 if (!args.quiet) {
545 const DWORD total_time = GetTickCount() - start_tick;
546 print_scan_time("Threads", total_time);
547 }
548 return scanned_count;
549}
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()
static t_scan_status get_scan_status(const ElementScanReport *report)
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.
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:304
size_t scanModules(ProcessScanReport &pReport)
Definition scanner.cpp:356
const bool isReflection
Definition scanner.h:53
size_t scanThreads(ProcessScanReport &pReport)
Definition scanner.cpp:502
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:154
size_t scanModulesIATs(ProcessScanReport &pReport)
Definition scanner.cpp:444
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:98
bool resolveHooksTargets(ProcessScanReport &process_report)
Definition scanner.cpp:170
bool filterDotNetReport(ProcessScanReport &process_report)
Definition scanner.cpp:199
ModuleScanReport * scanForMappingMismatch(ModuleData &modData, ProcessScanReport &process_report)
Definition scanner.cpp:347
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:130
ProcessScanReport * scanRemote()
The main function of ProcessScanner, deploying the scan. Throws exceptions in case of a failure.
Definition scanner.cpp:236
std::set< std::string > ignoredModules
Definition scanner.h:57
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)
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)
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)
size_t query_threads_details(IN OUT std::map< DWORD, thread_info > &threads_info)
bool is_in_list(std::string searched_string, std::set< std::string > &string_list, bool to_lower=true)
BOOL(CALLBACK *_MiniDumpWriteDump)(HANDLE hProcess
size_t enum_modules(IN HANDLE hProcess, OUT std::vector< HMODULE > &hMods, IN DWORD filters)
DWORD(__stdcall *_PssCaptureSnapshot)(HANDLE ProcessHandle
struct pesieve::util::_thread_info thread_info
bool fetch_threads_info(IN DWORD pid, OUT std::map< DWORD, thread_info > &threads_info)
struct pesieve::util::_mem_region_info mem_region_info
struct pesieve::_process_details process_details
bool validate_param_str(PARAM_STRING &strparam)
Definition scanner.cpp:31
int MAX_PATH
Definition pesieve.py:11
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:276
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 fill_threads_info(IN const DWORD pid, OUT std::map< DWORD, thread_info > &threads_info)
Definition scanner.cpp:491
bool set_non_suspicious(const std::set< ModuleScanReport * > &scan_reports, bool dnet_modules_only)
Definition scanner.cpp:178
Final summary about the scanned process.