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
module_cache.h
Go to the documentation of this file.
1#pragma once
2
3#include <peconv.h>
4#include <string>
5#include <map>
6
7namespace pesieve
8{
9 namespace util {
10 struct Mutex {
11 public:
13 {
15 }
16
17 void Lock()
18 {
20 }
21
22 void Unlock()
23 {
25 }
26
28 {
30 }
31
32 private:
34 };
35
37 {
38 public:
40 : mutex(_mutex)
41 {
42 mutex.Lock();
43 }
44
46 {
47 mutex.Unlock();
48 }
49
50 private:
51 Mutex& mutex;
52 };
53 };
54
55 struct CachedModule {
56 public:
61
64 {
65 moduleData = peconv::alloc_unaligned(_moduleSize);
66 if (!moduleData) return;
67
71 }
72
74 {
75 if (!this->moduleData || !this->moduleSize) return nullptr;
76
77 BYTE* my_pe = peconv::load_pe_module(moduleData, moduleSize, mappedSize, false, false);
78 return my_pe;
79 }
80
82 {
83#ifdef _DEBUG
84 std::cout << "Deleting cached module...\n";
85#endif
86 peconv::free_unaligned(moduleData);
87 moduleData = nullptr;
88 moduleSize = 0;
89 }
90
92 size_t moduleSize;
93 DWORD lastUsage;
94 };
95
96
98
99 public:
100
101 static const size_t MinUsageCntr = 2;
102 static const size_t MaxCachedModules = 255;
103
105 {
106#ifdef _DEBUG
107 std::cout << "Cache initialized\n";
108#endif
109 }
110
112 {
113 deleteCache();
114 }
115
116 BYTE* loadCached(LPSTR szModName, size_t& original_size);
117
118 protected:
119 BYTE* getMappedCached(const std::string &modName, size_t& mappedSize)
120 {
122
123 std::map<std::string, CachedModule*>::iterator itr = cachedModules.find(modName);
124 if (itr != cachedModules.end()) {
125 CachedModule* cached = itr->second;
126 if (!cached) return nullptr;
127
129 return cached->mapFromCached(mappedSize);
130 }
131 return nullptr;
132 }
133
134 bool prepareCacheSpace(bool force_free = false)
135 {
139 return true;
140 }
141 return _deleteLeastRecent();
142 }
143
145 {
146 DWORD lTimestamp = 0;
147 DWORD gTimestamp = 0;
148 std::map<std::string, CachedModule*>::iterator foundItr = cachedModules.end();
149
150 std::map<std::string, CachedModule*>::iterator itr;
151 for (itr = cachedModules.begin(); itr != cachedModules.end(); ++itr) {
152 CachedModule* mod = itr->second;
153 if (!mod) continue;
154
155 if ((lTimestamp == 0) || (mod->lastUsage < lTimestamp)) {
157 foundItr = itr;
158 }
159
160 if ((gTimestamp == 0) || (mod->lastUsage > gTimestamp)) {
161 gTimestamp = mod->lastUsage;
162 }
163 }
164
165 if ((gTimestamp == lTimestamp) || (foundItr == cachedModules.end())) {
166 return false; // nothing to remove
167 }
168#ifdef _DEBUG
169 std::cout << "Deleting the least recent module: " << foundItr->first << " timestamp: " << lTimestamp << "\n";
170#endif
171 // remove the module that was used the least recently:
172 usageBeforeCounter[foundItr->first] = 0;
173 CachedModule* mod1 = foundItr->second;
174 delete mod1;
175 cachedModules.erase(foundItr);
176 return true;
177 }
178
180 {
182
183 std::map<std::string, CachedModule*>::iterator itr;
184#ifdef _DEBUG
185 size_t i = 0;
186#endif
187 for (itr = cachedModules.begin(); itr != cachedModules.end(); ++itr) {
188#ifdef _DEBUG
189 std::cout << "[" << i++ << "] Deleting cached module: " << itr->first << "\n";
190#endif
191 CachedModule* cached = itr->second;
192 delete cached;
193 }
194 cachedModules.clear();
195 usageBeforeCounter.clear();
196#ifdef _DEBUG
197 std::cout << "Cache deleted. Total: " << i << " modules.\n";
198#endif
199 }
200
201 std::map<std::string, size_t> usageBeforeCounter;
202
203 std::map<std::string, CachedModule*> cachedModules;
204
206 };
207
208};
BYTE * getMappedCached(const std::string &modName, size_t &mappedSize)
bool prepareCacheSpace(bool force_free=false)
BYTE * loadCached(LPSTR szModName, size_t &original_size)
std::map< std::string, CachedModule * > cachedModules
the list of all the cached modules
static const size_t MaxCachedModules
how many modules can be stored in the cache at the time
static const size_t MinUsageCntr
how many times loading of the module must be requested before the module is added to cache
std::map< std::string, size_t > usageBeforeCounter
how many times loading of the same module was requested before it was cached
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
CachedModule(BYTE *_moduleData, size_t _moduleSize)
BYTE * mapFromCached(size_t &mappedSize) const