20#define PID_FIELD_SIZE 8
22using namespace pesieve;
26 std::string
join_path(
const std::string &baseDir,
const std::string &subpath)
28 std::stringstream stream;
29 if (baseDir.length() > 0) {
39 std::stringstream stream;
40 if (baseDir.length() > 0) {
51 const size_t new_len = new_dir.length();
52 if (!new_len)
return false;
54 const char* new_dir_cstr = new_dir.c_str();
55 size_t buffer_len =
sizeof(args.output_dir) - 1;
56 if (new_len > buffer_len)
return false;
58 memset(args.output_dir, 0, buffer_len);
59 memcpy(args.output_dir, new_dir_cstr, new_len);
63 bool write_to_file(
const std::string &report_path,
const std::wstring &summary_str,
const bool append)
65 std::wofstream final_report;
67 final_report.open(report_path, std::ios_base::app);
70 final_report.open(report_path);
72 if (final_report.is_open()) {
73 final_report << summary_str;
83 bool is_searched_name(
const WCHAR* processName,
const std::set<std::wstring> &names_list)
85 for (
auto itr = names_list.begin(); itr != names_list.end(); ++itr) {
86 const WCHAR* searchedName = itr->c_str();
87 if (_wcsicmp(processName, searchedName) == 0) {
96 std::set<long>::iterator found = pids_list.find(pid);
97 if (found != pids_list.end()) {
103 template <
typename TYPE_T>
106 std::wstringstream stream;
108 for (
auto itr = list.begin(); itr != list.end(); ) {
111 if (itr != list.end()) {
157 if (!found && not_matched_count) {
160 std::cout <<
"[WARNING] Some processes were filtered out basing on the defined criteria: " << not_matched_count <<
" skipped" << std::endl;
164 if (!found &&
hh_args.names_list.size() > 0) {
167 std::cout <<
"[WARNING] No process from the list: {" <<
util::list_to_str(
hh_args.names_list) <<
"} was scanned!" << std::endl;
170 if (!found &&
hh_args.pids_list.size() > 0) {
173 std::cout <<
"[WARNING] No process from the list: {" <<
util::list_to_str(
hh_args.pids_list) <<
"} was scanned!" << std::endl;
176 if (ignored_count > 0) {
178 std::string info1 = (ignored_count > 1) ?
"processes" :
"process";
179 std::string info2 = (ignored_count > 1) ?
"were" :
"was";
181 std::cout <<
"[INFO] " << std::dec << ignored_count <<
" " << info1 <<
" " << info2 <<
" ignored!" << std::endl;
189 size_t scanned_count = 0;
190 size_t ignored_count = 0;
191 size_t filtered_count = 0;
193 HANDLE hProcessSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
194 if (hProcessSnapShot == INVALID_HANDLE_VALUE) {
195 const DWORD err = GetLastError();
197 std::cerr <<
"[-] Could not create modules snapshot. Error: " << std::dec << err << std::endl;
201 PROCESSENTRY32 pe32 = { 0 };
202 pe32.dwSize =
sizeof(PROCESSENTRY32);
204 if (!Process32First(hProcessSnapShot, &pe32)) {
205 CloseHandle(hProcessSnapShot);
207 std::cerr <<
"[-] Could not enumerate processes. Error: " << GetLastError() << std::endl;
211 if (pe32.th32ProcessID == 0)
continue;
213 USHORT processMachine;
214 USHORT nativeMachine;
223 }
while (Process32Next(hProcessSnapShot, &pe32));
226 CloseHandle(hProcessSnapShot);
236 if (report.errors == pesieve::ERROR_SCAN_FAILURE) {
239 if (report.errors == pesieve::ERROR_SCAN_FAILURE) {
240 std::cout <<
"[!] Could not access: " << std::dec << report.pid;
243 std::cout << std::endl;
247 if (report.is_64bit) {
250 std::cout <<
"[!] Partial scan: " << std::dec << report.pid <<
" : " << (report.is_64bit ? 64 : 32) <<
"b";
252 std::cout << std::endl;
255 if (report.suspicious) {
257 if (report.replaced || report.implanted) {
260 if (report.is_managed) {
265 std::cout <<
">> Detected: " << std::dec << report.pid;
266 if (report.is_managed) {
267 std::cout <<
" [.NET]";
270 std::cout << std::endl;
280 static const int is_curr_wow =
false;
281 static const int is_curr_32 =
false;
290 static const int is_curr_32 =
true;
292 if (is_process_wow64 == is_curr_wow) {
315 if (hh_initTime > process_time) {
316 time_t time_diff = hh_initTime - process_time;
328 if (!found &&
hh_args.ignored_names_list.size()) {
348 std::wcout <<
">> Scanning PID: "
350 <<
" : " << exe_file;
352 if (is_process_wow64) {
353 std::cout <<
" : 32b";
355 std::cout << std::endl;
358 pesieve::t_params &pesieve_args = this->
hh_args.pesieve_args;
359 pesieve_args.pid = pid;
361 pesieve::t_report report = PESieve_scan(&pesieve_args);
365 if (report.scanned > 0) {
373 const time_t scan_start = time(NULL);
374 pesieve::t_params &pesieve_args = this->
hh_args.pesieve_args;
380 my_report->
setEndTick(GetTickCount(), time(NULL));
390 std::wstringstream stream;
391 hh_report->
toString(stream, pesieve::SHOW_ALL);
393 static std::mutex logMutx;
394 const std::lock_guard<std::mutex> lock(logMutx);
400 if (!hh_report)
return;
401 std::wstringstream summary_str;
403 if (!this->
hh_args.json_output) {
404 hh_report->
toString(summary_str, rfilter);
405 std::wcout << summary_str.rdbuf();
409 std::wcout << summary_str.rdbuf();
412 if (
hh_args.pesieve_args.out_filter != OUT_NO_DIR) {
417 static std::mutex summaryMutx;
418 const std::lock_guard<std::mutex> lock(summaryMutx);
420 std::wstringstream summary_str1;
428 if (
hh_args.suspend_suspicious) {
bool appendReport(pesieve::t_report &scan_report, const std::wstring &img_name)
bool setEndTick(DWORD end_tick, time_t end_time)
void toString(std::wstringstream &stream, const pesieve::t_results_filter rfilter)
std::vector< DWORD > suspicious
size_t countReports(const pesieve::t_results_filter rfilter) const
size_t toJSON(std::wstringstream &stream, const t_hh_params ¶ms)
void printScanRoundStats(size_t found, size_t ignored_count, size_t not_matched_count)
bool writeToLog(HHScanReport *hh_report)
void summarizeScan(HHScanReport *hh_report, const pesieve::t_results_filter rfilter)
t_single_scan_status scanNextProcess(DWORD pid, WCHAR *image_buf, HHScanReport &report)
static t_single_scan_status shouldScanProcess(const hh_params &hh_args, const time_t hh_initTime, const DWORD pid, const WCHAR *exe_file)
size_t scanProcesses(HHScanReport &my_report)
void initOutDir(time_t scan_time, pesieve::t_params &pesieve_args)
HHScanner(t_hh_params &_args, time_t _initTime=0)
static bool isScannerCompatibile()
void printSingleReport(pesieve::t_report &report)
struct hh_params t_hh_params
bool is_arch_ok(const t_process_type &process_arch, const bool is_process_wow64)
enum single_status t_single_scan_status
bool write_to_file(const std::string &report_path, const std::wstring &summary_str, const bool append)
std::string join_path(const std::string &baseDir, const std::string &subpath)
bool set_output_dir(t_params &args, const std::string &new_dir)
std::string make_dir_name(const std::string &baseDir, time_t timestamp)
WORD set_color(WORD color)
std::string wstring_to_utf8(const std::wstring &wstr)
bool is_wow_64(HANDLE process)
size_t suspend_suspicious(std::vector< DWORD > &suspicious_pids)
size_t kill_suspicious(std::vector< DWORD > &suspicious_pids)
bool is_wow_64_by_pid(DWORD processID)
LONGLONG process_start_time(IN DWORD processID)
bool is_searched_pid(long pid, const std::set< long > &pids_list)
bool is_searched_name(const WCHAR *processName, const std::set< std::wstring > &names_list)
std::string list_to_str(const std::set< TYPE_T > &list)
#define MAKE_COLOR(fg_color, bg_color)