Simple FindSignature with LRU cache (max: 8192. If the value is above this limit, then the cache is flushed).
PHP Code:
#include <iostream>
#include <Windows.h>
#include <Tlhelp32.h>
#include <map>
#include <string>
struct LRU_Record {
std::string module_name;
std::string signature;
void* xAddr;
};
typedef unsigned long long int BigInt;
typedef std::map<size_t, LRU_Record> LRU;
LRU lru_cache;
BigInt FindSignatureCalls = 0;
template <typename T>
T __fastcall FindSignature(const char* module_name, const char* signature)
{
static_assert(std::is_pointer<T>::value, "Pointer only allowed!");
if (!module_name || !signature) {
return nullptr;
}
for (LRU::iterator it = lru_cache.begin(); it != lru_cache.end(); it++) {
if (it->second.module_name == std::string(module_name) && it->second.signature == std::string(signature)) {
return reinterpret_cast<T>(it->second.xAddr);
}
}
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
MODULEENTRY32 xModule = { 0 };
xModule.dwSize = sizeof(MODULEENTRY32);
size_t signature_length = strlen(signature);
unsigned char* xModuleBaseAddress = nullptr;
unsigned char* xModuleBuffer = nullptr;
unsigned char* xAddr = nullptr;
long xResult = -1;
unsigned char xStart = 0;
unsigned long xNextStart = 0;
unsigned char xSymbol = 0;
unsigned long i = 0;
unsigned long j = 0;
if (Module32First(hSnap, &xModule)) {
while (Module32Next(hSnap, &xModule)) {
if (!strcmp(xModule.szModule, module_name)) {
CloseHandle(hSnap);
xModuleBaseAddress = reinterpret_cast<unsigned char*>(xModule.modBaseAddr);
if (!xModuleBaseAddress) {
return nullptr;
}
xModuleBuffer = xModuleBaseAddress;
for (i = 0; i < (xModule.modBaseSize - signature_length); i++)
{
xResult = -1;
xNextStart = 0;
xStart = static_cast<unsigned char>(signature[0]);
for (j = 0; j < signature_length; j++)
{
if (static_cast<unsigned char>(signature[j]) == static_cast<unsigned char>(0x2A)) // if sig[j] == '?' { ... }
{
continue;
}
xSymbol = (xModuleBuffer + i)[j];
if (xSymbol == xStart)
{
xNextStart = j;
}
if (xSymbol != static_cast<unsigned char>(signature[j]))
{
xResult = xNextStart;
break;
}
}
if (xResult < 0)
{
xAddr = xModuleBaseAddress + i;
break;
}
else
{
i += xResult;
}
}
if (FindSignatureCalls >= 8192) {
lru_cache.clear();
}
FindSignatureCalls++;
size_t cnt = lru_cache.size() + 1;
lru_cache[cnt].module_name = (module_name);
lru_cache[cnt].signature = (signature);
lru_cache[cnt].xAddr = reinterpret_cast<void*>(xAddr);
return reinterpret_cast<T>(xAddr);
}
}
}
CloseHandle(hSnap);
return nullptr;
}
#pragma optimize("", off)
int main() {
void* addr = FindSignature<void*>("bla.dll", "\x55\x8B\xEC\x8B\x45\x08\x03\x45\x0C");
printf("addr = 0x%X\n", reinterpret_cast<unsigned long>(addr));
(void)(std::getchar());
return 0;
}
#pragma optimize("", on)