PE-sieve
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
artefacts_util.cpp
Go to the documentation of this file.
1#include "artefacts_util.h"
2#include <peconv.h>
3#include "code_patterns.h"
4#ifdef _DEBUG
5 #include <iostream>
6#endif
7
8using namespace sig_finder;
9
10BYTE* pesieve::util::find_pattern(BYTE* buffer, size_t buf_size, BYTE* pattern_buf, size_t pattern_size, size_t max_iter)
11{
12 for (size_t i = 0; (i + pattern_size) < buf_size; i++) {
13 if (max_iter != 0 && i > max_iter) break;
14 if (memcmp(buffer + i, pattern_buf, pattern_size) == 0) {
15 return (buffer + i);
16 }
17 }
18 return nullptr;
19}
20
21namespace pesieve {
22
23 std::set<DWORD> HardcodedPatterns;
24
26 {
27 if (!rootN) return 0;
28
29 size_t added = 0;
30 for (size_t i = 0; i < _countof(patterns32); i++)
31 {
32 const t_pattern& pattern = patterns32[i];
33 std::string name = "prolog32_" + std::to_string((ULONGLONG)i);
34 Signature sign(name, pattern.ptr, pattern.size);
35 if (rootN->addPattern(sign)) {
36 HardcodedPatterns.insert(sign.checksum());
37 added++;
38 }
39 }
40 return added;
41 }
42
44 {
45 if (!rootN) return 0;
46
47 size_t added = 0;
48 for (size_t i = 0; i < _countof(patterns64); i++)
49 {
50 const t_pattern &pattern = patterns64[i];
51 std::string name = "prolog64_" + std::to_string((ULONGLONG)i);
52 Signature sign(name, pattern.ptr, pattern.size);
53 if (rootN->addPattern(sign)) {
54 HardcodedPatterns.insert(sign.checksum());
55 added++;
56 }
57 }
58 return added;
59 }
60
61 inline size_t search_till_pattern(sig_finder::Node& rootN, const BYTE* loadedData, size_t loadedSize)
62 {
63 Match m = sig_finder::find_first_match(rootN, loadedData, loadedSize);
64 if (!m.sign) {
65 return PATTERN_NOT_FOUND;
66 }
67 return m.offset;
68 }
69
70}; //namespace pesieve
71
72size_t pesieve::util::is_32bit_code(BYTE *loadedData, size_t loadedSize)
73{
74 static sig_finder::Node rootN;
75 if(rootN.isEnd()) {
76 init_32_patterns(&rootN);
77 }
78 return search_till_pattern(rootN, loadedData, loadedSize);
79}
80
81size_t pesieve::util::is_64bit_code(BYTE* loadedData, size_t loadedSize)
82{
83 static sig_finder::Node rootN;
84 if (rootN.isEnd()) {
85 init_64_patterns(&rootN);
86 }
87 return search_till_pattern(rootN, loadedData, loadedSize);
88}
89
90bool pesieve::util::is_code(BYTE* loadedData, size_t loadedSize)
91{
92 static sig_finder::Node rootN;
93 if (peconv::is_padding(loadedData, loadedSize, 0)) {
94 return false;
95 }
96 if (rootN.isEnd()) {
97 init_32_patterns(&rootN);
98 init_64_patterns(&rootN);
99 }
100 if ((search_till_pattern(rootN, loadedData, loadedSize)) != PATTERN_NOT_FOUND) {
101 return true;
102 }
103 return false;
104}
105
106bool pesieve::util::is_executable(DWORD mapping_type, DWORD protection)
107{
108 const bool is_any_exec = (protection & PAGE_EXECUTE_READWRITE)
109 || (protection & PAGE_EXECUTE_READ)
110 || (protection & PAGE_EXECUTE)
111 || (protection & PAGE_EXECUTE_WRITECOPY);
112 return is_any_exec;
113}
114
115bool pesieve::util::is_readable(DWORD mapping_type, DWORD protection)
116{
117 const bool is_read = (protection & PAGE_READWRITE)
118 || (protection & PAGE_READONLY);
119 return is_read;
120}
121
122bool pesieve::util::is_normal_inaccessible(DWORD state, DWORD mapping_type, DWORD protection)
123{
124 if ((state & MEM_COMMIT) == 0) {
125 //not committed
126 return false;
127 }
128 if (mapping_type != MEM_IMAGE && (mapping_type != MEM_MAPPED) && mapping_type != MEM_PRIVATE) {
129 // invalid mapping type
130 return false;
131 }
132 if (protection & PAGE_NOACCESS) {
133 // inaccessible found
134 return true;
135 }
136 return false;
137}
138
139// matcher:
140
141sig_finder::Node mainMatcher;
142
144{
145 return (mainMatcher.isEnd()) ? false : true;
146}
147
148size_t pesieve::matcher::load_pattern_file(const char* filename)
149{
150 static bool isLoaded = false;
151 if (isLoaded) return 0; // allow to load file only once
152
153 isLoaded = true;
154 std::vector<Signature*> signatures;
155 Signature::loadFromFile(filename, signatures);
156 const size_t added = mainMatcher.addPatterns(signatures);
157 // delete the loaded signatures:
158 for (auto itr = signatures.begin(); itr != signatures.end(); ++itr) {
159 Signature* sign = *itr;
160 delete sign;
161 }
162 return added;
163}
164
166{
167 static bool isLoaded = false;
168 if (isLoaded) return false; // allow to load only once
169
170 isLoaded = true;
173 return true;
174}
175
176size_t pesieve::matcher::find_all_patterns(BYTE* loadedData, size_t loadedSize, std::vector<sig_finder::Match>& allMatches)
177{
178 if (!is_matcher_ready()) {
179 return false;
180 }
181 if (peconv::is_padding(loadedData, loadedSize, 0)) {
182 return false;
183 }
184 const size_t matches = sig_finder::find_all_matches(mainMatcher, loadedData, loadedSize, allMatches);
185 return matches;
186}
187
188size_t pesieve::matcher::filter_custom(std::vector<sig_finder::Match>& allMatches, std::vector<sig_finder::Match>& customPatternMatches)
189{
190 size_t customCount = 0;
191 for (auto itr = allMatches.begin(); itr != allMatches.end(); ++itr) {
192 sig_finder::Match m = *itr;
193 if (m.sign) {
194 const DWORD checks = m.sign->checksum();
195 if (HardcodedPatterns.find(checks) != HardcodedPatterns.end()) {
196 continue;
197 }
198 customPatternMatches.push_back(m);
199 customCount++;
200 }
201 }
202 return customCount;
203}
sig_finder::Node mainMatcher
#define PATTERN_NOT_FOUND
size_t load_pattern_file(const char *filename)
size_t find_all_patterns(BYTE *loadedData, size_t loadedSize, std::vector< sig_finder::Match > &allMatches)
size_t filter_custom(std::vector< sig_finder::Match > &allMatches, std::vector< sig_finder::Match > &customPatternMatches)
size_t is_32bit_code(BYTE *loadedData, size_t loadedSize)
bool is_readable(DWORD mapping_type, DWORD protection)
BYTE * find_pattern(BYTE *buffer, size_t buf_size, BYTE *pattern_buf, size_t pattern_size, size_t max_iter=0)
bool is_normal_inaccessible(DWORD state, DWORD mapping_type, DWORD protection)
bool is_code(BYTE *loadedData, size_t loadedSize)
bool is_executable(DWORD mapping_type, DWORD protection)
size_t is_64bit_code(BYTE *loadedData, size_t loadedSize)
size_t init_32_patterns(Node *rootN)
t_pattern patterns32[]
size_t search_till_pattern(sig_finder::Node &rootN, const BYTE *loadedData, size_t loadedSize)
size_t fill_iat(BYTE *vBuf, size_t vBufSize, IN const peconv::ExportsMapper *exportsMap, IN OUT IATBlock &iat, IN ThunkFoundCallback *callback)
Definition iat_finder.h:31
t_pattern patterns64[]
size_t init_64_patterns(Node *rootN)
std::set< DWORD > HardcodedPatterns