PE-sieve
Scans all running processes. Recognizes and dumps a variety of potentially malicious implants (replaced/implanted PEs, shellcodes, hooks, in-memory patches).
Toggle main menu visibility
Loading...
Searching...
No Matches
utils
workingset_enum.cpp
Go to the documentation of this file.
1
#include "
workingset_enum.h
"
2
3
#include <iostream>
4
5
#include <psapi.h>
6
#pragma comment(lib,"psapi.lib")
7
8
#ifdef _WIN64
9
const
ULONGLONG
mask
= ULONGLONG(-1);
10
#else
11
const
ULONGLONG
mask
= DWORD(-1);
12
#endif
13
14
namespace
pesieve
{
15
namespace
util {
16
17
bool
get_next_commited_region
(HANDLE processHandle, ULONGLONG start_va, MEMORY_BASIC_INFORMATION &page_info)
18
{
19
const
SIZE_T page_info_size =
sizeof
(MEMORY_BASIC_INFORMATION);
20
21
while
(start_va <
mask
) {
22
//std::cout << "Checking: " << std::hex << start_va << std::endl;
23
memset(&page_info, 0, page_info_size);
24
const
SIZE_T out = VirtualQueryEx(processHandle, (LPCVOID)start_va, &page_info, page_info_size);
25
const
bool
is_read = (out == page_info_size) ?
true
:
false
;
26
const
DWORD
error = is_read ? ERROR_SUCCESS : GetLastError();
27
if
(error == ERROR_INVALID_PARAMETER) {
28
//nothing more to read
29
#ifdef _DEBUG
30
std::cout <<
"Nothing more to read: "
<< std::hex << start_va << std::endl;
31
#endif
32
break
;
33
}
34
if
(error == ERROR_ACCESS_DENIED) {
35
std::cerr <<
"[ERROR] Cannot query the memory region. "
<< std::hex << start_va <<
" Error: "
<< std::dec << error << std::endl;
36
break
;
37
}
38
if
(!is_read) {
39
// on any other error:
40
std::cerr <<
"[WARNING] Cannot query the memory region. "
<< std::hex<< start_va <<
" Error: "
<< std::dec << error <<
", skipping the page..."
<< std::endl;
41
start_va +=
PAGE_SIZE
;
42
continue
;
43
}
44
if
((page_info.State & MEM_FREE) || (page_info.State & MEM_COMMIT) == 0) {
45
if
(page_info.RegionSize != 0) {
46
//std::cout << "Free: " << std::hex << start_va << " RegionSize:" << page_info.RegionSize << std::endl;
47
start_va += page_info.RegionSize;
48
continue
;
49
}
50
}
51
if
(page_info.RegionSize == 0) {
52
start_va +=
PAGE_SIZE
;
53
continue
;
54
}
55
//std::cout << "Commited: " << std::hex << start_va << " RegionSize: " << page_info.RegionSize << " Err: " << std::dec << error << std::endl;
56
return
true
;
57
}
58
return
false
;
59
}
60
61
};
62
};
63
64
size_t
pesieve::util::enum_workingset
(HANDLE processHandle, std::set<mem_region_info> ®ion_bases)
65
{
66
region_bases.clear();
67
68
MEMORY_BASIC_INFORMATION page_info = { 0 };
69
ULONGLONG next_va = 0;
70
while
(
get_next_commited_region
(processHandle, next_va, page_info))
71
{
72
ULONGLONG base = (ULONGLONG)page_info.BaseAddress;
73
next_va = base + page_info.RegionSize;
//end of the region
74
mem_region_info
curr_info((ULONGLONG)page_info.AllocationBase, base, page_info.RegionSize);
75
76
if
(region_bases.find(curr_info) != region_bases.end()) {
77
// don't let it stuck on adding the same region over and over again
78
break
;
79
}
80
region_bases.insert(curr_info);
81
}
82
return
region_bases.size();
83
}
84
85
DWORD
pesieve::util::count_workingset_entries
(HANDLE processHandle)
86
{
87
DWORD
number_of_entries = 1;
88
DWORD
buffer_size =
sizeof
(PSAPI_WORKING_SET_INFORMATION) + (number_of_entries *
sizeof
(PSAPI_WORKING_SET_BLOCK));
89
PSAPI_WORKING_SET_INFORMATION* buffer =
reinterpret_cast<
PSAPI_WORKING_SET_INFORMATION*
>
(calloc(1, buffer_size));
90
if
(!buffer) {
91
return
0;
//this should not happen
92
}
93
DWORD
res = QueryWorkingSet(processHandle, buffer, buffer_size);
94
if
(res == FALSE && GetLastError() == ERROR_BAD_LENGTH) {
95
// ERROR_BAD_LENGTH is normal: we didn't provide the buffer that could fit all the entries
96
res = TRUE;
97
}
98
number_of_entries =
static_cast<
DWORD
>
(buffer->NumberOfEntries);
99
free(buffer); buffer = NULL;
100
101
if
(!res) {
102
return
0;
103
}
104
#ifdef _DEBUG
105
std::cout <<
"Number of entries: "
<< std::dec << number_of_entries << std::endl;
106
#endif
107
return
number_of_entries;
108
}
pesieve::util::count_workingset_entries
DWORD count_workingset_entries(HANDLE processHandle)
Definition
workingset_enum.cpp:85
pesieve::util::get_next_commited_region
bool get_next_commited_region(HANDLE processHandle, ULONGLONG start_va, MEMORY_BASIC_INFORMATION &page_info)
Definition
workingset_enum.cpp:17
pesieve::util::enum_workingset
size_t enum_workingset(HANDLE processHandle, std::set< mem_region_info > ®ions)
Definition
workingset_enum.cpp:64
pesieve::util::DWORD
DWORD(__stdcall *_PssCaptureSnapshot)(HANDLE ProcessHandle
pesieve::util::mem_region_info
struct pesieve::util::_mem_region_info mem_region_info
pesieve
Definition
pesieve.py:1
mask
const ULONGLONG mask
Definition
workingset_enum.cpp:11
workingset_enum.h
PAGE_SIZE
#define PAGE_SIZE
Definition
workingset_enum.h:11
Generated by
1.17.0