[FEATURE] Allow to filter the scanned processes by architecture

This commit is contained in:
hasherezade
2026-06-01 10:31:09 -08:00
parent 6378c8e170
commit d10eee18c7
4 changed files with 65 additions and 4 deletions
+2
View File
@@ -21,6 +21,7 @@ void hh_params::init()
quiet = false;
log = false;
json_output = false;
process_arch = PROCESS_ALL;
ptimes = TIME_UNDEFINED;
}
@@ -48,5 +49,6 @@ hh_params& hh_params::operator=(const hh_params& other)
this->names_list = other.names_list;
this->pids_list = other.pids_list;
this->ignored_names_list = other.ignored_names_list;
this->process_arch = other.process_arch;
return *this;
}
+8
View File
@@ -15,6 +15,13 @@ typedef enum {
CACHE_MODES_COUNT
} t_cache_mode;
typedef enum {
PROCESS_ALL = 0,
PROCESS_32BIT = 1,
PROCESS_64BIT = 2,
PROCESS_TYPES_COUNT
} t_process_type;
//HollowsHunter's parameters:
typedef struct hh_params
{
@@ -33,6 +40,7 @@ public:
std::set<std::wstring> names_list;
std::set<long> pids_list;
std::set<std::wstring> ignored_names_list;
t_process_type process_arch;
pesieve::t_params pesieve_args; //PE-sieve parameters
void init();
+38 -2
View File
@@ -178,7 +178,7 @@ void HHScanner::printScanRoundStats(size_t found, size_t ignored_count, size_t n
std::string info1 = (ignored_count > 1) ? "processes" : "process";
std::string info2 = (ignored_count > 1) ? "were" : "was";
const std::lock_guard<std::mutex> stdOutLock(g_stdOutMutex);
std::cout << "[INFO] " << std::dec << ignored_count << " " << info1 << " from the list : {" << util::list_to_str(hh_args.ignored_names_list) << "} " << info2 << " ignored!" << std::endl;
std::cout << "[INFO] " << std::dec << ignored_count << " " << info1 << " " << info2 << " ignored!" << std::endl;
}
}
}
@@ -201,7 +201,6 @@ size_t HHScanner::scanProcesses(HHScanReport &my_report)
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof(PROCESSENTRY32);
//check all modules in the process, including the main module:
if (!Process32First(hProcessSnapShot, &pe32)) {
CloseHandle(hProcessSnapShot);
const std::lock_guard<std::mutex> stdOutLock(g_stdOutMutex);
@@ -210,6 +209,10 @@ size_t HHScanner::scanProcesses(HHScanReport &my_report)
}
do {
if (pe32.th32ProcessID == 0) continue;
USHORT processMachine;
USHORT nativeMachine;
// scan callback
const t_single_scan_status stat = scanNextProcess(pe32.th32ProcessID, pe32.szExeFile, my_report);
if (stat == SSCAN_IGNORED) ignored_count++;
@@ -268,9 +271,39 @@ void HHScanner::printSingleReport(pesieve::t_report& report)
}
}
bool is_arch_ok(const t_process_type& process_arch, const bool is_process_wow64)
{
if (process_arch == PROCESS_ALL) {
return true;
}
#ifdef _WIN64
static const int is_curr_wow = false;
static const int is_curr_32 = false;
if (process_arch == PROCESS_32BIT && is_process_wow64) {
return true;
}
if (process_arch == PROCESS_64BIT && !is_process_wow64) {
return true;
}
#else
static const int is_curr_wow = process_util::is_wow_64(GetCurrentProcess());
static const int is_curr_32 = true;
if (is_curr_wow) {
if (is_process_wow64 == is_curr_wow) {
if (process_arch == PROCESS_32BIT) return true;
}
else {
if (process_arch == PROCESS_64BIT) return true;
}
}
#endif
return false;
}
t_single_scan_status HHScanner::shouldScanProcess(const hh_params &hh_args, const time_t hh_initTime, const DWORD pid, const WCHAR* exe_file)
{
bool found = false;
const bool check_time = (hh_args.ptimes != TIME_UNDEFINED) ? true : false;
// filter by the time
@@ -303,6 +336,9 @@ t_single_scan_status HHScanner::shouldScanProcess(const hh_params &hh_args, cons
t_single_scan_status HHScanner::scanNextProcess(DWORD pid, WCHAR* exe_file, HHScanReport &my_report)
{
const bool is_process_wow64 = process_util::is_wow_64_by_pid(pid);
if (!is_arch_ok(hh_args.process_arch, is_process_wow64)) {
return SSCAN_IGNORED;
}
t_single_scan_status res = HHScanner::shouldScanProcess(hh_args, this->initTime, pid, exe_file);
if (res != SSCAN_READY) {
return res;
+17 -2
View File
@@ -32,6 +32,7 @@ using namespace pesieve;
#define PARAM_DOTNET_POLICY "dnet"
#define PARAM_SYMBOLS "sym"
#define PARAM_PTIMES "ptimes"
#define PARAM_ARCH "arch"
//dump options:
#define PARAM_IMP_REC "imp"
@@ -154,7 +155,19 @@ public:
}
this->addParam(new IntParam(PARAM_PTIMES, false, IntParam::INT_BASE_DEC));
this->setInfo(PARAM_PTIMES, "Scan only processes created N seconds before HH, or later.");
this->setInfo(PARAM_PTIMES, "Skip processes created N or more seconds before the scanner start");
#ifdef _WIN64
#endif
EnumParam* enumParam = new EnumParam(PARAM_ARCH, "process_arch", false);
if (enumParam) {
this->addParam(enumParam);
this->setInfo(PARAM_ARCH, "Scan only processes with given architecture");
enumParam->addEnumValue(t_process_type::PROCESS_ALL, "All available");
enumParam->addEnumValue(t_process_type::PROCESS_32BIT, "Only 32-bit");
enumParam->addEnumValue(t_process_type::PROCESS_64BIT, "Only 64-bit");
}
this->addParam(new BoolParam(PARAM_SUSPEND, false));
this->setInfo(PARAM_SUSPEND, "Suspend processes detected as suspicious.");
@@ -179,7 +192,7 @@ public:
this->setInfo(PARAM_ETW, "Use ETW (disabled).");
#endif //USE_ETW
}
EnumParam *enumParam = new EnumParam(PARAM_IMP_REC, "imprec_mode", false);
enumParam = new EnumParam(PARAM_IMP_REC, "imprec_mode", false);
if (enumParam) {
this->addParam(enumParam);
this->setInfo(PARAM_IMP_REC, "Set in which mode the ImportTable should be recovered");
@@ -386,6 +399,7 @@ public:
this->addParamToGroup(PARAM_PID, str_group);
this->addParamToGroup(PARAM_PNAME, str_group);
this->addParamToGroup(PARAM_PTIMES, str_group);
this->addParamToGroup(PARAM_ARCH, str_group);
str_group = "6. post-scan actions";
this->addGroup(new ParamGroup(str_group));
@@ -436,6 +450,7 @@ public:
copyVal<BoolParam>(PARAM_UNIQUE_DIR, ps.unique_dir);
copyVal<BoolParam>(PARAM_SUSPEND, ps.suspend_suspicious);
copyVal<BoolParam>(PARAM_KILL, ps.kill_suspicious);
copyVal<EnumParam>(PARAM_ARCH, ps.process_arch);
#ifdef USE_ETW
copyVal<BoolParam>(PARAM_ETW, ps.etw_scan);
#endif // USE_ETW