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>
7
8namespace pesieve
9{
10 struct CachedModule {
11 public:
13 : moduleData(nullptr), moduleSize(0), lastUsage(0)
14 {
15 }
16
17 CachedModule(BYTE* _moduleData, size_t _moduleSize)
18 : moduleData(nullptr), moduleSize(0), lastUsage(0)
19 {
20 moduleData = peconv::alloc_unaligned(_moduleSize);
21 if (!moduleData) return;
22
23 memcpy(moduleData, _moduleData, _moduleSize);
24 moduleSize = _moduleSize;
25 lastUsage = GetTickCount();
26 }
27
28 BYTE* mapFromCached(size_t &mappedSize) const
29 {
30 if (!this->moduleData || !this->moduleSize) return nullptr;
31
32 BYTE* my_pe = peconv::load_pe_module(moduleData, moduleSize, mappedSize, false, false);
33 return my_pe;
34 }
35
37 {
38#ifdef _DEBUG
39 std::cout << "Deleting cached module...\n";
40#endif
41 peconv::free_unaligned(moduleData);
42 moduleData = nullptr;
43 moduleSize = 0;
44 }
45
47 size_t moduleSize;
48 DWORD lastUsage;
49 };
50
51
53
54 public:
55
56 static const size_t MinUsageCntr = 2;
57
59 {
60#ifdef _DEBUG
61 std::cout << "Cache initialized\n";
62#endif
63 }
64
66 {
68 }
69
70 BYTE* loadCached(LPSTR szModName, size_t& original_size);
71
72 protected:
73 BYTE* getMappedCached(const std::string &modName, size_t& mappedSize)
74 {
76
77 std::map<std::string, CachedModule*>::iterator itr = cachedModules.find(modName);
78 if (itr != cachedModules.end()) {
79 CachedModule* cached = itr->second;
80 if (!cached) return nullptr;
81
82 cached->lastUsage = GetTickCount();
83 return cached->mapFromCached(mappedSize);
84 }
85 return nullptr;
86 }
87
88 bool isCacheAvailable(const size_t neededSize);
89
90 bool prepareCacheSpace(const size_t neededSize, bool force_free)
91 {
93 if (force_free) {
95 }
96 while (!isCacheAvailable(neededSize)) {
97 if (!_deleteLeastRecent()) {
98 return false; // cannot make free space
99 }
100 }
101 return true;
102 }
103
105 {
106 DWORD lTimestamp = 0;
107 DWORD gTimestamp = 0;
108 std::map<std::string, CachedModule*>::iterator foundItr = cachedModules.end();
109
110 std::map<std::string, CachedModule*>::iterator itr;
111 for (itr = cachedModules.begin(); itr != cachedModules.end(); ++itr) {
112 CachedModule* mod = itr->second;
113 if (!mod) continue;
114
115 if ((lTimestamp == 0) || (mod->lastUsage < lTimestamp)) {
116 lTimestamp = mod->lastUsage;
117 foundItr = itr;
118 }
119
120 if ((gTimestamp == 0) || (mod->lastUsage > gTimestamp)) {
121 gTimestamp = mod->lastUsage;
122 }
123 }
124
125 if ((gTimestamp == lTimestamp) || (foundItr == cachedModules.end())) {
126 return false; // nothing to remove
127 }
128#ifdef _DEBUG
129 std::cout << "Deleting the least recent module: " << foundItr->first << " timestamp: " << lTimestamp << "\n";
130#endif
131 // remove the module that was used the least recently:
132 usageBeforeCounter[foundItr->first] = 0;
133 CachedModule* mod1 = foundItr->second;
134 delete mod1;
135 cachedModules.erase(foundItr);
136 return true;
137 }
138
140 {
142
143 std::map<std::string, CachedModule*>::iterator itr;
144#ifdef _DEBUG
145 size_t i = 0;
146#endif
147 for (itr = cachedModules.begin(); itr != cachedModules.end(); ++itr) {
148#ifdef _DEBUG
149 std::cout << "[" << i++ << "] Deleting cached module: " << itr->first << "\n";
150#endif
151 CachedModule* cached = itr->second;
152 delete cached;
153 }
154 cachedModules.clear();
155 usageBeforeCounter.clear();
156#ifdef _DEBUG
157 std::cout << "Cache deleted. Total: " << i << " modules.\n";
158#endif
159 }
160
161 std::map<std::string, size_t> usageBeforeCounter;
162
163 std::map<std::string, CachedModule*> cachedModules;
164
166 };
167
168};
BYTE * getMappedCached(const std::string &modName, size_t &mappedSize)
bool isCacheAvailable(const size_t neededSize)
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 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
bool prepareCacheSpace(const size_t neededSize, bool force_free)
CachedModule(BYTE *_moduleData, size_t _moduleSize)
BYTE * mapFromCached(size_t &mappedSize) const