Skip to content
This repository has been archived by the owner on Aug 13, 2024. It is now read-only.

Commit

Permalink
Refactored signature scanner
Browse files Browse the repository at this point in the history
  • Loading branch information
Blaumaus committed Mar 2, 2021
1 parent 383f798 commit 4da3483
Showing 1 changed file with 55 additions and 35 deletions.
90 changes: 55 additions & 35 deletions Le_Chiffre/sig_scanner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,74 +3,94 @@
#define SIG_SCANNER
#pragma once
#include <Windows.h>
#include <cstddef>
#include <iostream>

class SigScanner {
private:
HANDLE process;

char* _scan(const char* pattern, const char* mask, char* begin, unsigned size) {
intptr_t _scan(const char* pattern, const char* mask, char* begin, unsigned size) {
unsigned patternLength = strlen(mask);

for (unsigned i = 0; i < size - patternLength; i++) {
bool found = true;

for (unsigned j = 0; j < patternLength; j++) {
if (mask[j] != '?' && pattern[j] != *(begin + i + j)) {
if (mask[j] != '?' && pattern[j] != *(char*)((intptr_t)begin + i + j)) {
found = false;
break;
}
}

if (found) return (begin + i);
if (found) return ((intptr_t)begin + i);
}

return nullptr;
return 0;
}

public:
SigScanner() {
process = nullptr;
}
BYTE* _find_signature(char* pattern, char* mask, BYTE* begin, intptr_t size) {
BYTE* match { nullptr };
SIZE_T bytesRead;
DWORD oldprotect;
char* buffer{ nullptr };
MEMORY_BASIC_INFORMATION mbi;
mbi.RegionSize = 0x1000;//

SigScanner(HANDLE process) {
this->process = process;
}
VirtualQueryEx(process, (LPCVOID)begin, &mbi, sizeof(mbi));

::std::ptrdiff_t find_signature(const char* pattern, const char* mask, DWORD begin, DWORD end) { // https://stackoverflow.com/a/55113370
DWORD current = begin;
::std::ptrdiff_t match = NULL;
SIZE_T bytes_read = 0;
for (BYTE* current = begin; current < begin + size; current += mbi.RegionSize) {
if (!VirtualQueryEx(process, (LPCVOID)current, &mbi, sizeof(mbi))) continue;
if (mbi.State != MEM_COMMIT || mbi.Protect == PAGE_NOACCESS) continue;

while (current < end) {
MEMORY_BASIC_INFORMATION mbi;
delete[] buffer;
buffer = new char[mbi.RegionSize];

if (!VirtualQueryEx(process, &current, &mbi, sizeof(mbi))) return NULL;
if (VirtualProtectEx(process, mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &oldprotect)) {
ReadProcessMemory(process, mbi.BaseAddress, buffer, mbi.RegionSize, &bytesRead);
VirtualProtectEx(process, mbi.BaseAddress, mbi.RegionSize, oldprotect, &oldprotect);

char* buffer = new char[mbi.RegionSize];
intptr_t internalAddr = _scan(pattern, mask, buffer, bytesRead);

if (mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS) {
DWORD protect;
if (internalAddr != 0) {
match = current + (internalAddr - (intptr_t)buffer);
break;
}
}
}

if (VirtualProtectEx(process, mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &protect)) {
ReadProcessMemory(process, mbi.BaseAddress, buffer, mbi.RegionSize, &bytes_read);
VirtualProtectEx(process, mbi.BaseAddress, mbi.RegionSize, protect, &protect);
delete[] buffer;
return match;
}

char* address = _scan(pattern, mask, buffer, bytes_read);
public:
SigScanner() {
process = nullptr;
}

if (address != nullptr) { // internal address to external
uintptr_t offsetFromBuffer = address - buffer;
match = current + offsetFromBuffer;
delete[] buffer;
break;
}
}
SigScanner(HANDLE process) {
this->process = process;
}

BYTE* find (const char* signature, BYTE* begin, intptr_t size) {
char pattern[50];
char mask[50];
char lastChar = ' ';
unsigned int j = 0;

for (unsigned int i = 0; i < strlen(signature); ++i, ++j) {
if ((signature[i] == '?' || signature[i] == '*') && (lastChar != '?' && lastChar != '*')) {
pattern[j] = mask[j] = '?';
} else if (isspace(lastChar)) {
pattern[j] = lastChar = (char)strtol(&signature[i], 0, 16);
mask[j] = 'x';
}

current += mbi.RegionSize;
delete[] buffer;
lastChar = signature[i];
}
pattern[j] = mask[j] = '\0';

return match;
return _find_signature(pattern, mask, begin, size);
}
};

Expand Down

0 comments on commit 4da3483

Please sign in to comment.