33 if (!strparam.buffer || strparam.length == 0) {
36 if (IsBadReadPtr(strparam.buffer, strparam.length)) {
46 float seconds = ((float)timeInMs / 1000);
47 float minutes = ((float)timeInMs / 60000);
48 stream << std::dec << timeInMs <<
" ms.";
50 stream <<
" = " << seconds <<
" sec.";
53 stream <<
" = " << minutes <<
" min.";
62 ss <<
"[*] "<< scanned_element <<
" scanned in ";
64 std::cout << ss.str() << std::endl;
70 if (GetExitCodeProcess(processHandle, &exitCode)) {
71 if (exitCode != STILL_ACTIVE) {
73 std::cerr <<
"Process terminated, exit = " << std::dec << exitCode <<
"\n";
83 : processHandle(procHndl), isDEP(false), isReflection(is_reflection),
88 pesieve::util::string_to_list(args.modules_ignored.buffer, PARAM_LIST_SEPARATOR, ignoredModules);
106 std::cout <<
"Arch mismatch, reloading..." << std::endl;
126 const peconv::ExportsMapper *expMap = process_report.
exportsMap;
133 std::cout <<
"Cannot scan replaced module for IAT hooks!\n";
137 IATScanner scanner(processHandle, modData, remoteModData, *expMap, process_report.
modulesInfo, filter);
150 CodeScanner scanner(processHandle, modData, remoteModData);
169 return (resolved_count > 0);
172inline bool set_non_suspicious(
const std::set<ModuleScanReport*> &scan_reports,
bool dnet_modules_only)
175 std::set<ModuleScanReport*>::iterator itr;
176 for (itr = scan_reports.begin(); itr != scan_reports.end(); ++itr) {
182 if (dnet_modules_only && !
report->isDotNetModule) {
196 || this->args.dotnet_policy == pesieve::PE_DNET_NONE)
201 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_MAPPING
202 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
208 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_HOOKS
209 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
215 if (this->args.dotnet_policy == pesieve::PE_DNET_SKIP_SHC
216 || this->args.dotnet_policy == pesieve::PE_DNET_SKIP_ALL)
225 is_set = is_set1 || is_set2;
239 GetProcessImageFileNameA(this->processHandle, image_buf,
MAX_PATH);
242 std::stringstream errorsStr;
245 size_t modulesScanned = 0;
247 modulesScanned = scanModules(*pReport);
248 }
catch (std::exception &e) {
250 errorsStr << e.what();
254 size_t regionsScanned = 0;
256 regionsScanned = scanWorkingSet(*pReport);
257 }
catch (std::exception &e) {
259 errorsStr << e.what();
263 size_t iatsScanned = 0;
266 iatsScanned = scanModulesIATs(*pReport);
268 catch (std::exception& e) {
270 errorsStr << e.what();
275 size_t threadsScanned = 0;
278 threadsScanned = scanThreads(*pReport);
280 catch (std::exception& e) {
282 errorsStr << e.what();
287 if (!modulesScanned && !iatsScanned && !regionsScanned && !threadsScanned) {
288 throw std::runtime_error(errorsStr.str());
291 resolveHooksTargets(*pReport);
294 filterDotNetReport(*pReport);
301 throw std::runtime_error(
"Could not query the working set. ");
306 DWORD start_tick = GetTickCount();
307 std::set<mem_region_info> region_bases;
310 std::cout <<
"Scanning workingset: " << std::dec << pages_count <<
" memory regions." << std::endl;
315 for (
auto set_itr = region_bases.begin(); set_itr != region_bases.end() &&
is_running(this->processHandle); ++set_itr, ++counter) {
318 WorkingSetScanner scanner(this->processHandle, proc_details, region, this->args, pReport);
335 const DWORD total_time = GetTickCount() - start_tick;
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) {
357 if (args.imprec_mode !=
PE_IMPREC_NONE || args.iat != pesieve::PE_IATS_NONE) {
358 pReport.
exportsMap =
new peconv::ExportsMapper();
362 for (counter = 0; counter < modules_count &&
is_running(this->processHandle); counter++) {
363 if (processHandle ==
nullptr)
break;
364 const HMODULE module_base = hMods[counter];
366 ModuleData modData(processHandle, module_base,
true, args.use_cache);
367 ModuleScanReport *mappingScanReport = this->scanForMappingMismatch(modData, pReport);
372 std::cout <<
"[!][" << args.pid <<
"] Suspicious: could not read the module file!" << std::endl;
383 const std::string plainName = peconv::get_file_name(modData.
szModName);
384 if (
is_in_list(plainName, this->ignoredModules)) {
390 std::cout <<
"[*] Skipping ignored: " << std::hex << (ULONGLONG)modData.
moduleHandle <<
" : " << modData.
szModName << std::endl;
397 std::cout <<
"[*] Scanning: " << modData.
szModName;
399 std::cout <<
" (.NET) ";
401 std::cout << std::endl;
404 RemoteModuleData remoteModData(processHandle, this->isReflection, module_base);
410 t_scan_status is_hollowed = scanForHollows(processHandle, modData, remoteModData, pReport);
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));
432 scanForHooks(processHandle, modData, remoteModData, pReport, scan_data, scan_inaccessible);
444 const size_t modules_count =
enum_modules(this->processHandle, hMods,
sizeof(hMods), LIST_MODULES_ALL);
445 if (modules_count == 0) {
449 std::cout <<
"Scanning for IAT hooks: " << modules_count <<
" modules." << std::endl;
451 DWORD start_tick = GetTickCount();
453 for (counter = 0; counter < modules_count &&
is_running(this->processHandle); counter++) {
454 if (!processHandle)
break;
456 const HMODULE module_base = hMods[counter];
458 ModuleData modData(processHandle, module_base,
true, args.use_cache);
461 std::string plainName = peconv::get_file_name(modData.
szModName);
462 if (
is_in_list(plainName, this->ignoredModules)) {
467 RemoteModuleData remoteModData(processHandle, this->isReflection, module_base);
475 scanForIATHooks(processHandle, modData, remoteModData, pReport, this->args.iat);
478 const DWORD total_time = GetTickCount() - start_tick;
486 if (!this->symbols.IsInitialized()) {
488 std::cerr <<
"[-] Failed to initialize symbols!\n";
497 if (is_64bit)
return 0;
501 std::cout <<
"Scanning threads." << std::endl;
503 DWORD start_tick = GetTickCount();
505 std::map<DWORD, thread_info> threads_info;
511 std::cerr <<
"[-] Failed enumerating threads." << std::endl;
518 std::cout <<
"[-] Failed quering thread details." << std::endl;
522 for (
auto itr = threads_info.begin(); itr != threads_info.end() &&
is_running(this->processHandle); ++itr) {
530 const DWORD total_time = GetTickCount() - start_tick;
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()
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.
A scanner for detection of IAT hooking.
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.
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.
std::string mainImagePath
void appendReport(ModuleScanReport *report)
bool isModuleReplaced(HMODULE module_base)
peconv::ExportsMapper * exportsMap
std::set< ModuleScanReport * > reportsByType[REPORT_TYPES_COUNT]
bool hasModule(ULONGLONG page_addr)
bool hasModuleContaining(ULONGLONG page_addr, size_t size)
size_t scanWorkingSet(ProcessScanReport &pReport)
size_t scanModules(ProcessScanReport &pReport)
size_t scanThreads(ProcessScanReport &pReport)
ProcessScanner(HANDLE procHndl, bool is_reflection, pesieve::t_params _args)
static t_scan_status scanForHooks(HANDLE hProcess, ModuleData &modData, RemoteModuleData &remoteModData, ProcessScanReport &process_report, bool scan_data, bool scan_inaccessible)
size_t scanModulesIATs(ProcessScanReport &pReport)
static t_scan_status scanForHollows(HANDLE hProcess, ModuleData &modData, RemoteModuleData &remoteModData, ProcessScanReport &process_report)
bool resolveHooksTargets(ProcessScanReport &process_report)
bool filterDotNetReport(ProcessScanReport &process_report)
ModuleScanReport * scanForMappingMismatch(ModuleData &modData, ProcessScanReport &process_report)
ProcessSymbolsManager symbols
static t_scan_status scanForIATHooks(HANDLE hProcess, ModuleData &modData, RemoteModuleData &remoteModData, ProcessScanReport &process_report, t_iat_scan_mode filter)
ProcessScanReport * scanRemote()
The main function of ProcessScanner, deploying the scan. Throws exceptions in case of a failure.
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)
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 > ®ions)
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)
void print_scan_time(const char *scanned_element, size_t total_time)
bool is_running(HANDLE processHandle)
std::string info()
The string with the basic information about the scanner.
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)
Final summary about the scanned process.