Skip to content

Commit

Permalink
[FEATURE] Added new parameter: report allowing to regulate what resul…
Browse files Browse the repository at this point in the history
…ts are included in the report (Issue #21)
  • Loading branch information
hasherezade committed Oct 31, 2024
1 parent 6cfd370 commit 915235a
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 67 deletions.
5 changes: 3 additions & 2 deletions etw_listener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ void runHHinNewThread(t_hh_params args)
HHScanReport* report = hhunter.scan();
if (report)
{
if (!g_hh_args.quiet || report->countSuspicious()) {
// in this mode only suspicious will be reported
if (!g_hh_args.quiet || report->countReports(pesieve::SHOW_SUSPICIOUS)) {
const std::lock_guard<std::mutex> lock(g_stdOutMutex);
hhunter.summarizeScan(report);
hhunter.summarizeScan(report, pesieve::SHOW_SUSPICIOUS);
}
else {
hhunter.writeToLog(report);
Expand Down
3 changes: 2 additions & 1 deletion hh_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ void hh_params::init()

pesieve_args.quiet = true;
pesieve_args.no_hooks = true;
pesieve_args.results_filter = pesieve::SHOW_SUSPICIOUS;

suspend_suspicious = false;
kill_suspicious = false;
Expand Down Expand Up @@ -48,4 +49,4 @@ hh_params& hh_params::operator=(const hh_params& other)
this->ignored_names_list = other.ignored_names_list;

return *this;
}
}
69 changes: 43 additions & 26 deletions hh_report.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,51 @@ std::cout.fill(' '); \
if (field_size) stream << std::setw(field_size) << ' '; \
stream << str;

bool is_suspicious_process(pesieve::t_report report)
{
if (report.suspicious) {
return true;
}
return false;
}

bool HHScanReport::appendReport(pesieve::t_report &scan_report, const std::wstring &img_name)
{
pidToReport[scan_report.pid] = scan_report;
pidToName[scan_report.pid] = img_name;
if (is_suspicious_process(scan_report)) {
if (scan_report.suspicious) {
this->suspicious.push_back(scan_report.pid);
}
if (scan_report.errors == pesieve::ERROR_SCAN_FAILURE) {
this->failed.push_back(scan_report.pid);
}
return true;
}

size_t HHScanReport::reportsToString(std::wstringstream& stream, bool suspiciousOnly)
size_t HHScanReport::reportsToString(std::wstringstream& stream, const pesieve::t_results_filter rfilter)
{
size_t printed = 0;
size_t counter = 0;
size_t scannedCount = pidToReport.size();
if (suspiciousOnly) {
scannedCount = suspicious.size();
}
size_t scannedCount = countReports(rfilter);

if (!scannedCount) {
return printed;
}

const size_t max_len = size_t(std::floor(std::log10(double(scannedCount))) + 1) % 100;
for (auto itr = this->pidToReport.begin(); itr != pidToReport.end(); ++itr) {
bool isFailed = false;
DWORD pid = itr->first;
if (suspiciousOnly) {
pesieve::t_report rep = itr->second;
pesieve::t_report rep = itr->second;
if ((rfilter & pesieve::SHOW_SUSPICIOUS) == 0) {
if (!rep.suspicious) continue;
}
if (rep.errors == pesieve::ERROR_SCAN_FAILURE) {
isFailed = true;
}

if (isFailed && (rfilter & pesieve::SHOW_ERRORS) == 0) {
continue; // do not display failed
}
stream << L"[" << std::setw(max_len) << counter++ << L"]: PID: " << std::dec << pid << L", ";
stream << L"Name: " << this->pidToName[pid] << L"\n";
stream << L"Name: " << this->pidToName[pid];
if (isFailed) {
stream << L" : FAILED";
}
stream << L"\n";
printed++;
}
return printed;
Expand Down Expand Up @@ -114,7 +121,7 @@ size_t HHScanReport::toJSON(std::wstringstream &stream, const t_hh_params &param
OUT_PADDED(stream, level, L"{\n");
level++;
//summary:
const size_t suspicious_count = countSuspicious();
const size_t suspicious_count = countReports(pesieve::SHOW_SUSPICIOUS);
size_t all_count = 0;
OUT_PADDED(stream, level, L"\"scan_date_time\" : ");
stream << std::dec << L"\"" << util::strtime(this->startTime) << L"\"" << L",\n";
Expand All @@ -123,7 +130,9 @@ size_t HHScanReport::toJSON(std::wstringstream &stream, const t_hh_params &param
OUT_PADDED(stream, level, L"\"scan_time_ms\" : ");
stream << std::dec << getScanTime() << L",\n";
OUT_PADDED(stream, level, L"\"scanned_count\" : ");
stream << std::dec << countTotal() << L",\n";
stream << std::dec << countTotal(true) << L",\n";
OUT_PADDED(stream, level, L"\"failed_count\" : ");
stream << std::dec << countReports(pesieve::SHOW_ERRORS) << L",\n";
OUT_PADDED(stream, level, L"\"suspicious_count\" : ");
stream << std::dec << suspicious_count;
if (suspicious_count > 0) {
Expand Down Expand Up @@ -152,7 +161,7 @@ void print_scantime(STR_STREAM& stream, size_t timeInMs)
}
}

void HHScanReport::toString(std::wstringstream &stream, bool suspiciousOnly)
void HHScanReport::toString(std::wstringstream &stream, const pesieve::t_results_filter rfilter)
{
//summary:
stream << L"--------" << std::endl;
Expand All @@ -161,14 +170,22 @@ void HHScanReport::toString(std::wstringstream &stream, bool suspiciousOnly)
stream << L"Finished scan in: ";
print_scantime(stream, getScanTime());
stream << L"\n";
stream << L"[*] Total scanned: " << std::dec << countTotal() << L"\n";
if (!suspiciousOnly && countTotal() > 0) {
const size_t scannedCount = countReports(pesieve::SHOW_SUCCESSFUL_ONLY);
stream << L"[*] Total scanned: " << std::dec << scannedCount << L"\n";
if ((rfilter & pesieve::SHOW_NOT_SUSPICIOUS) && scannedCount > 0) {
stream << L"[+] List of scanned: \n";
reportsToString(stream, false);
reportsToString(stream, pesieve::SHOW_SUCCESSFUL_ONLY);
}
if (rfilter & pesieve::SHOW_SUSPICIOUS) {
const size_t count = countReports(pesieve::SHOW_SUSPICIOUS);
stream << L"[*] Total suspicious: " << std::dec << count << L"\n";
if (count > 0) {
stream << L"[+] List of suspicious: \n";
reportsToString(stream, pesieve::SHOW_SUSPICIOUS);
}
}
stream << L"[*] Total suspicious: " << std::dec << countSuspicious() << L"\n";
if (countSuspicious() > 0) {
stream << L"[+] List of suspicious: \n";
reportsToString(stream, true);
if (rfilter & pesieve::SHOW_ERRORS) {
const size_t count = countReports(pesieve::SHOW_ERRORS);
stream << L"[*] Total failed: " << std::dec << count << L"\n";
}
}
34 changes: 27 additions & 7 deletions hh_report.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,40 @@ class HHScanReport

bool appendReport(pesieve::t_report &scan_report, const std::wstring &img_name);

size_t countSuspicious() const
size_t countReports(const pesieve::t_results_filter rfilter) const
{
return suspicious.size();
if (rfilter == pesieve::SHOW_NONE) {
return 0;
}
if (rfilter == pesieve::SHOW_ALL) {
return countTotal(false);
}
if (rfilter == pesieve::SHOW_SUCCESSFUL_ONLY) {
return countTotal(true);
}
size_t total = 0;
if (rfilter & pesieve::SHOW_ERRORS) {
total += failed.size();
}
if (rfilter & pesieve::SHOW_SUSPICIOUS) {
total += suspicious.size();
}
return total;
}

size_t countTotal() const
size_t countTotal(bool successfulOnly = true) const
{
return pidToReport.size();
size_t total = pidToReport.size();
if (successfulOnly) {
total -= failed.size();
}
return total;
}

void toString(std::wstringstream &stream, bool suspiciousOnly = true);
void toString(std::wstringstream &stream, const pesieve::t_results_filter rfilter);

protected:
size_t reportsToString(std::wstringstream &stream, bool suspiciousOnly = true);
size_t reportsToString(std::wstringstream &stream, const pesieve::t_results_filter rfilter);

size_t toJSON(std::wstringstream &stream, const t_hh_params &params);
size_t reportsToJSON(std::wstringstream &stream, size_t level, const t_hh_params &params);
Expand All @@ -63,6 +83,6 @@ class HHScanReport
std::map<DWORD, pesieve::t_report> pidToReport;
std::map<DWORD, std::wstring> pidToName;
std::vector<DWORD> suspicious;

std::vector<DWORD> failed;
friend class HHScanner;
};
16 changes: 8 additions & 8 deletions hh_scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include <paramkit.h>
#include <mutex>

#define PID_FIELD_SIZE 4
#define PID_FIELD_SIZE 8

using namespace pesieve;

Expand Down Expand Up @@ -309,8 +309,9 @@ t_single_scan_status HHScanner::scanNextProcess(DWORD pid, WCHAR* exe_file, HHSc
}
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;
std::wcout << " : " << exe_file;
std::wcout << ">> Scanning PID: "
<< std::setw(PID_FIELD_SIZE) << std::dec << pid
<< " : " << exe_file;

if (is_process_wow64) {
std::cout << " : 32b";
Expand Down Expand Up @@ -350,22 +351,21 @@ bool HHScanner::writeToLog(HHScanReport* hh_report)
return false;
}

const bool suspiciousOnly = false;
std::wstringstream stream;
hh_report->toString(stream, suspiciousOnly);
hh_report->toString(stream, pesieve::SHOW_ALL);

static std::mutex logMutx;
const std::lock_guard<std::mutex> lock(logMutx);
return files_util::write_to_file("hollows_hunter.log", stream.str(), true);
}

void HHScanner::summarizeScan(HHScanReport *hh_report, bool suspiciousOnly)
void HHScanner::summarizeScan(HHScanReport *hh_report, const pesieve::t_results_filter rfilter)
{
if (!hh_report) return;
std::wstringstream summary_str;

if (!this->hh_args.json_output) {
hh_report->toString(summary_str, suspiciousOnly);
hh_report->toString(summary_str, rfilter);
std::wcout << summary_str.rdbuf();
}
else {
Expand All @@ -375,7 +375,7 @@ void HHScanner::summarizeScan(HHScanReport *hh_report, bool suspiciousOnly)

if (hh_args.pesieve_args.out_filter != OUT_NO_DIR) {
//file the same report into the directory with dumps:
if (hh_report->suspicious.size()) {
if (hh_report->countReports(rfilter)) {
std::string report_path = files_util::join_path(this->outDir, "summary.json");

static std::mutex summaryMutx;
Expand Down
2 changes: 1 addition & 1 deletion hh_scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class HHScanner {

HHScanReport* scan();
bool writeToLog(HHScanReport* hh_report);
void summarizeScan(HHScanReport *hh_report, bool suspiciousOnly = true);
void summarizeScan(HHScanReport* hh_report, const pesieve::t_results_filter rfilter);

protected:
void printScanRoundStats(size_t found, size_t ignored_count, size_t not_matched_count);
Expand Down
22 changes: 11 additions & 11 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,18 @@ t_pesieve_res deploy_scan()
else
{
HHScanner hhunter(g_hh_args);
do {
HHScanReport *report = hhunter.scan();
if (report) {
hhunter.summarizeScan(report);
if (report->countSuspicious() > 0) {
scan_res = PESIEVE_DETECTED;
do {
HHScanReport *report = hhunter.scan();
if (report) {
hhunter.summarizeScan(report, g_hh_args.pesieve_args.results_filter);
if (report->countReports(pesieve::SHOW_SUSPICIOUS) > 0) {
scan_res = PESIEVE_DETECTED;
}
delete report;
}
if (!HHScanner::isScannerCompatibile()) {
compatibility_alert();
}
delete report;
}
if (!HHScanner::isScannerCompatibile()) {
compatibility_alert();
}
} while (g_hh_args.loop_scanning);
}
return scan_res;
Expand Down
15 changes: 15 additions & 0 deletions params_info/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ using namespace pesieve;
//output options:
#define PARAM_QUIET "quiet"
#define PARAM_OUT_FILTER "ofilter"
#define PARAM_RESULTS_FILTER "report"
#define PARAM_SUSPEND "suspend"
#define PARAM_KILL "kill"
#define PARAM_UNIQUE_DIR "uniqd"
Expand Down Expand Up @@ -169,6 +170,18 @@ class HHParams : public Params
}
}

enumParam = new EnumParam(PARAM_RESULTS_FILTER, "result_type", false);
if (enumParam) {
this->addParam(enumParam);
this->setInfo(PARAM_RESULTS_FILTER, "Define what type of results are reported.");
for (size_t i = SHOW_SUSPICIOUS; i < SHOW_FILTERS_COUNT; i++) {
t_results_filter mode = (t_results_filter)(i);
std::string info = translate_results_filter(mode);
if (info.empty()) continue;
enumParam->addEnumValue(mode, results_filter_to_id(i), info);
}
}

this->addParam(new StringListParam(PARAM_MODULES_IGNORE, false, PARAM_LIST_SEPARATOR));
{
std::stringstream ss1;
Expand Down Expand Up @@ -289,6 +302,7 @@ class HHParams : public Params
this->addParamToGroup(PARAM_JSON, str_group);
this->addParamToGroup(PARAM_JSON_LVL, str_group);
this->addParamToGroup(PARAM_OUT_FILTER, str_group);
this->addParamToGroup(PARAM_RESULTS_FILTER, str_group);
this->addParamToGroup(PARAM_LOG, str_group);
this->addParamToGroup(PARAM_UNIQUE_DIR, str_group);

Expand Down Expand Up @@ -464,6 +478,7 @@ class HHParams : public Params
{
copyVal<EnumParam>(PARAM_IMP_REC, ps.imprec_mode);
copyVal<EnumParam>(PARAM_OUT_FILTER, ps.out_filter);
copyVal<EnumParam>(PARAM_RESULTS_FILTER, ps.results_filter);

fillStringParam(PARAM_MODULES_IGNORE, ps.modules_ignored);

Expand Down
Loading

0 comments on commit 915235a

Please sign in to comment.