HollowsHunter
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
hh_report.cpp
Go to the documentation of this file.
1#include "hh_report.h"
2
3#include <string>
4#include <sstream>
5#include <codecvt>
6#include <locale>
7#include <iostream>
8#include <iomanip>
9#include <cmath>
10
11#include "util/time_util.h"
12
13#define OUT_PADDED(stream, field_size, str) \
14std::cout.fill(' '); \
15if (field_size) stream << std::setw(field_size) << ' '; \
16stream << str;
17
18
19bool HHScanReport::appendReport(pesieve::t_report &scan_report, const std::wstring &img_name)
20{
21 pidToReport[scan_report.pid] = scan_report;
22 pidToName[scan_report.pid] = img_name;
23 if (scan_report.suspicious) {
24 this->suspicious.push_back(scan_report.pid);
25 }
26 if (scan_report.errors == pesieve::ERROR_SCAN_FAILURE) {
27 this->failed.push_back(scan_report.pid);
28 }
29 return true;
30}
31
32size_t HHScanReport::reportsToString(std::wstringstream& stream, const pesieve::t_results_filter rfilter)
33{
34 if (rfilter == pesieve::SHOW_NONE) {
35 return 0;
36 }
37 size_t printed = 0;
38 size_t counter = 0;
39 size_t scannedCount = countReports(rfilter);
40
41 if (!scannedCount) {
42 return printed;
43 }
44
45 const size_t max_len = size_t(std::floor(std::log10(double(scannedCount))) + 1) % 100;
46 for (auto itr = this->pidToReport.begin(); itr != pidToReport.end(); ++itr) {
47 bool isFailed = false;
48 DWORD pid = itr->first;
49 pesieve::t_report rep = itr->second;
50 if ((rfilter & pesieve::SHOW_SUSPICIOUS) == 0) {
51 if (rep.suspicious) continue;
52 }
53 if ((rfilter & pesieve::SHOW_NOT_SUSPICIOUS) == 0) {
54 if (!rep.suspicious) continue;
55 }
56 if (rep.errors == pesieve::ERROR_SCAN_FAILURE) {
57 isFailed = true;
58 }
59
60 if (isFailed && ((rfilter & pesieve::SHOW_ERRORS) == 0)) {
61 continue; // do not display failed
62 }
63 stream << L"[" << std::setw(max_len) << counter++ << L"]: PID: " << std::dec << pid << L", ";
64 stream << L"Name: " << this->pidToName[pid];
65 if (isFailed) {
66 stream << L" : FAILED";
67 }
68 stream << L"\n";
69 printed++;
70 }
71 return printed;
72}
73
74size_t HHScanReport::reportsToJSON(std::wstringstream &stream, size_t level, const t_hh_params &params)
75{
76 std::vector<DWORD>::const_iterator itr;
77 OUT_PADDED(stream, level, L"\"suspicious\" : [\n");
78 level++;
79 size_t printed = 0;
80 for (itr = this->suspicious.begin(); itr != suspicious.end(); ++itr) {
81 DWORD pid = *itr;
82 OUT_PADDED(stream, level, L"{\n");
83 level++;
84
85 OUT_PADDED(stream, level, L"\"pid\" : ");
86 stream << std::dec << pid << L",\n";
87 OUT_PADDED(stream, level, L"\"is_managed\" : ");
88 stream << std::dec << pidToReport[pid].is_managed << L",\n";
89 OUT_PADDED(stream, level, L"\"name\" : ");
90 stream << L"\"" << this->pidToName[pid] << L"\",\n";
91 OUT_PADDED(stream, level, L"\"replaced\" : ");
92 stream << std::dec << pidToReport[pid].replaced << L",\n";
93 OUT_PADDED(stream, level, L"\"hdr_modified\" : ");
94 stream << std::dec << pidToReport[pid].hdr_mod << L",\n";
95 if (!params.pesieve_args.no_hooks) {
96 OUT_PADDED(stream, level, L"\"patched\" : ");
97 stream << std::dec << pidToReport[pid].patched << L",\n";
98 }
99 if (params.pesieve_args.iat != pesieve::PE_IATS_NONE) {
100 OUT_PADDED(stream, level, L"\"iat_hooked\" : ");
101 stream << std::dec << pidToReport[pid].iat_hooked << L",\n";
102 }
103 OUT_PADDED(stream, level, L"\"implanted_pe\" : ");
104 stream << std::dec << pidToReport[pid].implanted_pe << L",\n";
105 OUT_PADDED(stream, level, L"\"implanted_shc\" : ");
106 stream << std::dec << pidToReport[pid].implanted_shc << L",\n";
107 OUT_PADDED(stream, level, L"\"unreachable_file\" : ");
108 stream << std::dec << pidToReport[pid].unreachable_file << L",\n";
109 OUT_PADDED(stream, level, L"\"other\" : ");
110 stream << std::dec << pidToReport[pid].other << L"\n";
111 level--;
112 OUT_PADDED(stream, level, L"}");
113 printed++;
114 if (printed < suspicious.size()) {
115 stream << L",";
116 }
117 stream << L"\n";
118 }
119 level--;
120 OUT_PADDED(stream, level, L"]\n");
121 return printed;
122}
123
124size_t HHScanReport::toJSON(std::wstringstream &stream, const t_hh_params &params)
125{
126 size_t level = 0;
127 OUT_PADDED(stream, level, L"{\n");
128 level++;
129 //summary:
130 const size_t suspicious_count = countReports(pesieve::SHOW_SUSPICIOUS);
131 size_t all_count = 0;
132 OUT_PADDED(stream, level, L"\"scan_date_time\" : ");
133 stream << std::dec << L"\"" << util::strtime(this->startTime) << L"\"" << L",\n";
134 OUT_PADDED(stream, level, L"\"scan_timestamp\" : ");
135 stream << std::dec << startTime << L",\n";
136 OUT_PADDED(stream, level, L"\"scan_time_ms\" : ");
137 stream << std::dec << getScanTime() << L",\n";
138 OUT_PADDED(stream, level, L"\"scanned_count\" : ");
139 stream << std::dec << countTotal(true) << L",\n";
140 OUT_PADDED(stream, level, L"\"failed_count\" : ");
141 stream << std::dec << countReports(pesieve::SHOW_ERRORS) << L",\n";
142 OUT_PADDED(stream, level, L"\"suspicious_count\" : ");
143 stream << std::dec << suspicious_count;
144 if (suspicious_count > 0) {
145 stream << L",\n";
146 all_count = reportsToJSON(stream, level, params);
147 }
148 else {
149 stream << L"\n";
150 }
151 level--;
152 OUT_PADDED(stream, level, L"}\n");
153 return all_count;
154}
155
156template<class STR_STREAM>
157void print_scantime(STR_STREAM& stream, size_t timeInMs)
158{
159 float seconds = ((float)timeInMs / 1000);
160 float minutes = ((float)timeInMs / 60000);
161 stream << std::dec << timeInMs << L" ms.";
162 if (seconds > 0.5) {
163 stream << L" = " << seconds << L" sec.";
164 }
165 if (minutes > 0.5) {
166 stream << L" = " << minutes << L" min.";
167 }
168}
169
170void HHScanReport::toString(std::wstringstream &stream, const pesieve::t_results_filter rfilter)
171{
172 //summary:
173 stream << L"--------" << std::endl;
174 stream << L"SUMMARY:\n";
175 stream << L"Scan at: " << util::strtime(this->startTime) << L" (" << std::dec << startTime << L")\n";
176 stream << L"Finished scan in: ";
177 print_scantime(stream, getScanTime());
178 stream << L"\n";
179 const size_t scannedCount = countReports(pesieve::SHOW_SUCCESSFUL_ONLY);
180 stream << L"[*] Total scanned: " << std::dec << scannedCount << L"\n";
181 if ((rfilter & pesieve::SHOW_NOT_SUSPICIOUS) && scannedCount > 0) {
182 stream << L"[+] List of scanned: \n";
183 reportsToString(stream, pesieve::SHOW_SUCCESSFUL_ONLY);
184 }
185 if (rfilter & pesieve::SHOW_SUSPICIOUS) {
186 const size_t count = countReports(pesieve::SHOW_SUSPICIOUS);
187 stream << L"[*] Total suspicious: " << std::dec << count << L"\n";
188 if (count > 0) {
189 stream << L"[+] List of suspicious: \n";
190 reportsToString(stream, pesieve::SHOW_SUSPICIOUS);
191 }
192 }
193 if (rfilter & pesieve::SHOW_ERRORS) {
194 const size_t count = countReports(pesieve::SHOW_ERRORS);
195 stream << L"[*] Total failed: " << std::dec << count << L"\n";
196 }
197}
bool appendReport(pesieve::t_report &scan_report, const std::wstring &img_name)
Definition hh_report.cpp:19
std::map< DWORD, std::wstring > pidToName
Definition hh_report.h:84
void toString(std::wstringstream &stream, const pesieve::t_results_filter rfilter)
std::map< DWORD, pesieve::t_report > pidToReport
Definition hh_report.h:83
size_t reportsToJSON(std::wstringstream &stream, size_t level, const t_hh_params &params)
Definition hh_report.cpp:74
std::vector< DWORD > suspicious
Definition hh_report.h:85
size_t countReports(const pesieve::t_results_filter rfilter) const
Definition hh_report.h:39
size_t countTotal(bool successfulOnly=true) const
Definition hh_report.h:60
time_t startTime
Definition hh_report.h:77
DWORD getScanTime() const
Definition hh_report.h:31
size_t reportsToString(std::wstringstream &stream, const pesieve::t_results_filter rfilter)
Definition hh_report.cpp:32
size_t toJSON(std::wstringstream &stream, const t_hh_params &params)
std::vector< DWORD > failed
Definition hh_report.h:86
void print_scantime(STR_STREAM &stream, size_t timeInMs)
#define OUT_PADDED(stream, field_size, str)
Definition hh_report.cpp:13
std::wstring strtime(const time_t t)
Definition time_util.cpp:12
pesieve::t_params pesieve_args
Definition hh_params.h:36