Skip to content

Commit

Permalink
[FEATURE] Unified process filtering between standalone and ETW
Browse files Browse the repository at this point in the history
  • Loading branch information
hasherezade committed Sep 7, 2024
1 parent 4902460 commit 9e8ff93
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 70 deletions.
53 changes: 12 additions & 41 deletions etw_listener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct ProceesStat
};

ProceesStat procStats[MAX_PROCESSES] = { 0 };
time_t g_initTime = 0;

// ETW Handler
// To filter our events, we want to compare against the
Expand Down Expand Up @@ -159,7 +160,7 @@ bool isAllocationExecutable(std::uint32_t pid, LPVOID baseAddress)
}


inline std::wstring getProcessName(DWORD pid)
inline std::wstring getProcessName(const DWORD pid)
{
WCHAR processName[MAX_PATH] = { 0 };
if (!process_util::get_process_path(pid, processName, MAX_PATH * 2)) {
Expand All @@ -175,55 +176,24 @@ inline std::wstring getProcessName(DWORD pid)
}


bool isWatchedPid(DWORD pid)
bool isWatchedPid(const DWORD pid)
{
if (!g_hh_args.names_list.size() && !g_hh_args.pids_list.size()
&& !g_hh_args.ignored_names_list.size())
{
// no filter applied, watch everything
return true;
}
if (g_hh_args.pids_list.find(pid) != g_hh_args.pids_list.end()) {
// the PID is on the watch list
return true;
}

// get process name:
std::wstring wImgFileName = getProcessName(pid);
if (g_hh_args.names_list.find(wImgFileName) != g_hh_args.names_list.end()) {
// the name is on the watch list
const std::wstring wImgFileName = getProcessName(pid);
const t_single_scan_status res = HHScanner::shouldScanProcess(g_hh_args, g_initTime, pid, wImgFileName.c_str());
if (res == SSCAN_READY) {
return true;
}
if (g_hh_args.ignored_names_list.size() &&
g_hh_args.ignored_names_list.find(wImgFileName) == g_hh_args.ignored_names_list.end())
{
// the name is NOT on the ignore list
return true;
}
// the PID is not on the watch list
return false;
}

bool isWatchedName(std::string& imgFileName)
bool isWatchedName(const std::string& imgFileName)
{
if (!g_hh_args.names_list.size() && !g_hh_args.pids_list.size()
&& !g_hh_args.ignored_names_list.size())
{
// no filter applied, watch everything
return true;
}
std::wstring wImgFileName(imgFileName.begin(), imgFileName.end());
if (g_hh_args.names_list.find(wImgFileName) != g_hh_args.names_list.end()) {
// the name is on the watch list
return true;
}
if (g_hh_args.ignored_names_list.size() &&
g_hh_args.ignored_names_list.find(wImgFileName) == g_hh_args.ignored_names_list.end())
{
// the name is NOT on the ignore list
const std::wstring wImgFileName(imgFileName.begin(), imgFileName.end());
const t_single_scan_status res = HHScanner::shouldScanProcess(g_hh_args, g_initTime, 0, wImgFileName.c_str());
if (res == SSCAN_READY) {
return true;
}
// the name is not on the watch list
return false;
}

Expand All @@ -234,7 +204,7 @@ void runHHinNewThread(t_hh_params args)
return;
}
long pid = *(args.pids_list.begin());
HHScanner hhunter(args);
HHScanner hhunter(args, g_initTime);
HHScanReport* report = hhunter.scan();
if (report)
{
Expand Down Expand Up @@ -315,6 +285,7 @@ std::string ipv4FromDword(DWORD ip_dword)
bool ETWstart()
{
krabs::kernel_trace trace(L"HollowsHunter");
g_initTime = time(NULL);

krabs::kernel::process_provider processProvider;
krabs::kernel::image_load_provider imageLoadProvider;
Expand Down
2 changes: 0 additions & 2 deletions hh_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,3 @@ typedef struct hh_params

} t_hh_params;



57 changes: 36 additions & 21 deletions hh_scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,9 @@ namespace files_util {

namespace util {

bool is_searched_name(const WCHAR* processName, std::set<std::wstring> &names_list)
bool is_searched_name(const WCHAR* processName, const std::set<std::wstring> &names_list)
{
std::set<std::wstring>::iterator itr;
for (itr = names_list.begin(); itr != names_list.end(); ++itr) {
for (auto itr = names_list.begin(); itr != names_list.end(); ++itr) {
const WCHAR* searchedName = itr->c_str();
if (_wcsicmp(processName, searchedName) == 0) {
return true;
Expand All @@ -92,7 +91,7 @@ namespace util {
return false;
}

bool is_searched_pid(long pid, std::set<long> &pids_list)
bool is_searched_pid(long pid, const std::set<long> &pids_list)
{
std::set<long>::iterator found = pids_list.find(pid);
if (found != pids_list.end()) {
Expand All @@ -102,7 +101,7 @@ namespace util {
}

template <typename TYPE_T>
std::string list_to_str(std::set<TYPE_T> &list)
std::string list_to_str(const std::set<TYPE_T> &list)
{
std::wstringstream stream;

Expand All @@ -121,10 +120,12 @@ namespace util {

//----

HHScanner::HHScanner(t_hh_params &_args)
: hh_args(_args)
HHScanner::HHScanner(t_hh_params& _args, time_t _initTime)
: hh_args(_args), initTime(_initTime)
{
initTime = time(NULL);
if (!initTime) {
initTime = time(NULL);
}
isScannerWow64 = process_util::is_wow_64(GetCurrentProcess());
}

Expand All @@ -151,18 +152,26 @@ void HHScanner::initOutDir(time_t scan_time, pesieve::t_params &pesieve_args)
}
}

void HHScanner::printScanRoundStats(size_t found, size_t ignored_count)
void HHScanner::printScanRoundStats(size_t found, size_t ignored_count, size_t not_matched_count)
{
#ifdef _DEBUG
if (!found && not_matched_count) {
if (!hh_args.quiet) {
const std::lock_guard<std::mutex> stdOutLock(g_stdOutMutex);
std::cout << "[WARNING] Some processes were filtered out basing on the defined criteria: " << not_matched_count << " skipped" << std::endl;
}
}
#endif
if (!found && hh_args.names_list.size() > 0) {
if (!hh_args.quiet) {
const std::lock_guard<std::mutex> stdOutLock(g_stdOutMutex);
std::cout << "[WARNING] No process from the list: {" << util::list_to_str(hh_args.names_list) << "} was found!" << std::endl;
std::cout << "[WARNING] No process from the list: {" << util::list_to_str(hh_args.names_list) << "} was scanned!" << std::endl;
}
}
if (!found && hh_args.pids_list.size() > 0) {
if (!hh_args.quiet) {
const std::lock_guard<std::mutex> stdOutLock(g_stdOutMutex);
std::cout << "[WARNING] No process from the list: {" << util::list_to_str(hh_args.pids_list) << "} was found!" << std::endl;
std::cout << "[WARNING] No process from the list: {" << util::list_to_str(hh_args.pids_list) << "} was scanned!" << std::endl;
}
}
if (ignored_count > 0) {
Expand All @@ -180,6 +189,7 @@ size_t HHScanner::scanProcesses(HHScanReport &my_report)
size_t count = 0;
size_t scanned_count = 0;
size_t ignored_count = 0;
size_t filtered_count = 0;

HANDLE hProcessSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnapShot == INVALID_HANDLE_VALUE) {
Expand All @@ -203,6 +213,7 @@ size_t HHScanner::scanProcesses(HHScanReport &my_report)
// scan callback
const t_single_scan_status stat = scanNextProcess(pe32.th32ProcessID, pe32.szExeFile, my_report);
if (stat == SSCAN_IGNORED) ignored_count++;
if (stat == SSCAN_NOT_MATCH) filtered_count++;
if (stat == SSCAN_SUCCESS) scanned_count++;
count++;

Expand All @@ -211,7 +222,7 @@ size_t HHScanner::scanProcesses(HHScanReport &my_report)
//close the handles
CloseHandle(hProcessSnapShot);

printScanRoundStats(scanned_count, ignored_count);
printScanRoundStats(scanned_count, ignored_count, filtered_count);
return count;
}

Expand Down Expand Up @@ -257,12 +268,9 @@ void HHScanner::printSingleReport(pesieve::t_report& report)
}
}

t_single_scan_status HHScanner::scanNextProcess(DWORD pid, WCHAR* exe_file, HHScanReport &my_report)
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 is_process_wow64 = process_util::is_wow_64_by_pid(pid);

const bool check_time = (hh_args.ptimes != TIME_UNDEFINED) ? true : false;
#ifdef _DEBUG
if (check_time) {
Expand All @@ -277,8 +285,8 @@ t_single_scan_status HHScanner::scanNextProcess(DWORD pid, WCHAR* exe_file, HHSc
if (process_time == INVALID_TIME) return SSCAN_ERROR0; //skip process if cannot retrieve the time

// if HH was started after the process
if (this->initTime > process_time) {
time_diff = this->initTime - process_time;
if (hh_initTime > process_time) {
time_diff = hh_initTime - process_time;
if (time_diff > hh_args.ptimes) return SSCAN_NOT_MATCH; // skip process created before the supplied time
}
}
Expand All @@ -295,6 +303,16 @@ t_single_scan_status HHScanner::scanNextProcess(DWORD pid, WCHAR* exe_file, HHSc
return SSCAN_IGNORED;
}
}
return SSCAN_READY;
}

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);
t_single_scan_status res = HHScanner::shouldScanProcess(hh_args, this->initTime, pid, exe_file);
if (res != SSCAN_READY) {
return res;
}
if (!hh_args.quiet) {
const std::lock_guard<std::mutex> stdOutLock(g_stdOutMutex);
std::cout << ">> Scanning PID: " << std::setw(PID_FIELD_SIZE) << std::dec << pid;
Expand All @@ -303,9 +321,6 @@ t_single_scan_status HHScanner::scanNextProcess(DWORD pid, WCHAR* exe_file, HHSc
if (is_process_wow64) {
std::cout << " : 32b";
}
if (check_time) {
std::cout << " : " << time_diff << "s";
}
std::cout << std::endl;
}
//perform the scan:
Expand Down
8 changes: 5 additions & 3 deletions hh_scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,24 @@ typedef enum single_status {
SSCAN_ERROR0 = (-1),
SSCAN_NOT_MATCH = 0,
SSCAN_IGNORED = 1,
SSCAN_SUCCESS = 2
SSCAN_SUCCESS = 2,
SSCAN_READY = 3
} t_single_scan_status;

class HHScanner {
public:
// is the scanner best suited for the OS bitness
static bool isScannerCompatibile();
static t_single_scan_status shouldScanProcess(const hh_params& hh_args, const time_t hh_initTime, const DWORD pid, const WCHAR* exe_file);

HHScanner(t_hh_params &_args);
HHScanner(t_hh_params& _args, time_t _initTime = 0);

HHScanReport* scan();
bool writeToLog(HHScanReport* hh_report);
void summarizeScan(HHScanReport *hh_report, bool suspiciousOnly = true);

protected:
void printScanRoundStats(size_t found, size_t ignored_count);
void printScanRoundStats(size_t found, size_t ignored_count, size_t not_matched_count);
size_t scanProcesses(HHScanReport &my_report);
void printSingleReport(pesieve::t_report& report);

Expand Down
4 changes: 2 additions & 2 deletions hh_ver_short.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
#define HH_MAJOR_VERSION 0
#define HH_MINOR_VERSION 3
#define HH_MICRO_VERSION 9
#define HH_PATCH_VERSION 5
#define HH_PATCH_VERSION 7

#define HH_VERSION_STR "0.3.9.5"
#define HH_VERSION_STR "0.3.9.7"
2 changes: 1 addition & 1 deletion pe-sieve

0 comments on commit 9e8ff93

Please sign in to comment.