Add rich and less rich log macro

This commit is contained in:
2026-01-16 10:55:22 +01:00
parent fcc1a932ef
commit 9f893ca4e6

View File

@@ -10,13 +10,23 @@
#include <iomanip> #include <iomanip>
#include <tlhelp32.h> #include <tlhelp32.h>
// Rich verbose for internal release only
#ifdef MY_VERBOSE_LOGS
#define LOG_SIGNATURE_FOUND(name, addr) \
logger->info( \
"{} signature found at address: 0x{:X}.", \
name, addr \
)
#else
#define LOG_SIGNATURE_FOUND(name, addr) \
logger->info("{} signature found", name)
#endif
static std::shared_ptr<spdlog::logger> _log; static std::shared_ptr<spdlog::logger> _log;
std::unordered_map<void*, Memory::PatchInfo> Memory::patches; std::unordered_map<void*, Memory::PatchInfo> Memory::patches;
uint8_t* Memory::GetOffsetFromOpcode(uint8_t* opcode, int extraOffset) uint8_t* Memory::GetOffsetFromOpcode(uint8_t* opcode, int extraOffset) {
{ if (!opcode) return nullptr;
if (!opcode)
return nullptr;
int32_t disp = 0; int32_t disp = 0;
std::memcpy(&disp, opcode, sizeof(int32_t)); std::memcpy(&disp, opcode, sizeof(int32_t));
@@ -28,8 +38,7 @@ uint8_t* Memory::GetOffsetFromOpcode(uint8_t* opcode, int extraOffset)
return opcode + 4 + disp + extraOffset; // +4 car disp32 fait 4 octets return opcode + 4 + disp + extraOffset; // +4 car disp32 fait 4 octets
} }
uint8_t* Memory::GetAddressFromOpcode(uint8_t* opcode, uint32_t dispOffset, uint32_t instructionLen) uint8_t* Memory::GetAddressFromOpcode(uint8_t* opcode, uint32_t dispOffset, uint32_t instructionLen) {
{
int32_t disp = 0; int32_t disp = 0;
std::memcpy(&disp, opcode + dispOffset, sizeof(disp)); // lit le disp32 de manière safe std::memcpy(&disp, opcode + dispOffset, sizeof(disp)); // lit le disp32 de manière safe
return opcode + instructionLen + disp; // gère automatiquement disp négatif return opcode + instructionLen + disp; // gère automatiquement disp négatif
@@ -47,11 +56,9 @@ std::vector<std::uint8_t> Memory::ReadBytes(const void* addr, std::size_t size)
return buffer; return buffer;
} }
void Memory::PatchBytes(void* address, const char* bytes, size_t len) void Memory::PatchBytes(void* address, const char* bytes, size_t len) {
{
auto it = patches.find(address); auto it = patches.find(address);
if (it == patches.end()) if (it == patches.end()) {
{
// If a patch doesn't exist, create a new one. // If a patch doesn't exist, create a new one.
PatchInfo info; PatchInfo info;
info.address = address; info.address = address;
@@ -68,11 +75,9 @@ void Memory::PatchBytes(void* address, const char* bytes, size_t len)
VirtualProtect(address, len, oldProtect, &oldProtect); VirtualProtect(address, len, oldProtect, &oldProtect);
} }
void Memory::RestoreBytes(void *address) void Memory::RestoreBytes(void *address) {
{
auto it = patches.find(address); auto it = patches.find(address);
if (it != patches.end()) if (it != patches.end()) {
{
// Restore the original bytes. // Restore the original bytes.
const auto& info = it->second; const auto& info = it->second;
DWORD oldProtect; DWORD oldProtect;
@@ -90,15 +95,12 @@ MODULEINFO Memory::WaitForModule(const std::string& module_name, int timeoutMs,
const HANDLE hProc = GetCurrentProcess(); const HANDLE hProc = GetCurrentProcess();
MODULEINFO modInfo{}; MODULEINFO modInfo{};
for (int waited = 0; waited < timeoutMs; waited += intervalMs) for (int waited = 0; waited < timeoutMs; waited += intervalMs) {
{
HMODULE hMods[1024]; HMODULE hMods[1024];
DWORD cbNeeded; DWORD cbNeeded;
if (EnumProcessModules(hProc, hMods, sizeof(hMods), &cbNeeded)) if (EnumProcessModules(hProc, hMods, sizeof(hMods), &cbNeeded)) {
{ for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i) {
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i)
{
char modName[MAX_PATH]; char modName[MAX_PATH];
if (GetModuleBaseNameA(hProc, hMods[i], modName, sizeof(modName))) { if (GetModuleBaseNameA(hProc, hMods[i], modName, sizeof(modName))) {
if (_stricmp(modName, module_name.c_str()) == 0) { if (_stricmp(modName, module_name.c_str()) == 0) {
@@ -164,8 +166,7 @@ uint8_t* Memory::AOBScan(
std::vector<int> pattern_bytes; std::vector<int> pattern_bytes;
std::istringstream stream(signature); std::istringstream stream(signature);
std::string byte_str; std::string byte_str;
while (stream >> byte_str) while (stream >> byte_str) {
{
if (byte_str == "??" || byte_str == "?") if (byte_str == "??" || byte_str == "?")
pattern_bytes.push_back(-1); pattern_bytes.push_back(-1);
else else
@@ -184,8 +185,7 @@ uint8_t* Memory::AOBScan(
// Memory scan // Memory scan
MEMORY_BASIC_INFORMATION mbi{}; MEMORY_BASIC_INFORMATION mbi{};
for (uint8_t* current = base; current < base + size;) for (uint8_t* current = base; current < base + size;) {
{
if (!VirtualQuery(current, &mbi, sizeof(mbi))) if (!VirtualQuery(current, &mbi, sizeof(mbi)))
break; break;
@@ -198,11 +198,9 @@ uint8_t* Memory::AOBScan(
uint8_t* regionBase = reinterpret_cast<uint8_t*>(mbi.BaseAddress); uint8_t* regionBase = reinterpret_cast<uint8_t*>(mbi.BaseAddress);
size_t regionSize = mbi.RegionSize; size_t regionSize = mbi.RegionSize;
for (size_t i = 0; i <= regionSize - pattern_bytes.size(); ++i) for (size_t i = 0; i <= regionSize - pattern_bytes.size(); ++i) {
{
bool match = true; bool match = true;
for (size_t j = 0; j < pattern_bytes.size(); ++j) for (size_t j = 0; j < pattern_bytes.size(); ++j) {
{
if (pattern_bytes[j] != -1 && regionBase[i + j] != static_cast<uint8_t>(pattern_bytes[j])) { if (pattern_bytes[j] != -1 && regionBase[i + j] != static_cast<uint8_t>(pattern_bytes[j])) {
match = false; match = false;
break; break;
@@ -241,7 +239,7 @@ void Memory::AOBScanBatch(const std::vector<AOBScanEntry>& entries, std::shared_
uintptr_t finalAddress = reinterpret_cast<uintptr_t>(result) + scanEntry->offset; uintptr_t finalAddress = reinterpret_cast<uintptr_t>(result) + scanEntry->offset;
*scanEntry->address = reinterpret_cast<uint8_t*>(finalAddress); *scanEntry->address = reinterpret_cast<uint8_t*>(finalAddress);
logger->info("{} signature found at address: 0x{:X}.", scanEntry->featureName, finalAddress); LOG_SIGNATURE_FOUND(scanEntry->featureName, finalAddress);
} }
} }
@@ -259,8 +257,7 @@ void Memory::OffsetScanBatch(const std::vector<OffsetScanEntry>& entries, uint8_
UT::uint32 calculatedOffset = 0; UT::uint32 calculatedOffset = 0;
// Calculate offset according type // Calculate offset according type
switch (scanEntry.calcType) switch (scanEntry.calcType) {
{
case OffsetCalcType::GetOffsetFromOpcode: { case OffsetCalcType::GetOffsetFromOpcode: {
calculatedOffset = static_cast<UT::uint32>(Memory::GetOffsetFromOpcode(*scanEntry.outAddress + scanEntry.opcodeOffset) - baseModule); calculatedOffset = static_cast<UT::uint32>(Memory::GetOffsetFromOpcode(*scanEntry.outAddress + scanEntry.opcodeOffset) - baseModule);
break; break;
@@ -290,14 +287,10 @@ PVOID Memory::SetupOrClearHardwareBreakPointForAllThreads(uintptr_t targetAddres
// Add VectoredExceptionHandler // Add VectoredExceptionHandler
if (enable && !vehHandle && pVEH) if (enable && !vehHandle && pVEH)
{
vehHandle = AddVectoredExceptionHandler(1, pVEH); vehHandle = AddVectoredExceptionHandler(1, pVEH);
}
if (Thread32First(snapshot, &te)) if (Thread32First(snapshot, &te)) {
{ do {
do
{
if (te.th32OwnerProcessID != pid) continue; if (te.th32OwnerProcessID != pid) continue;
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID); HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
@@ -306,21 +299,18 @@ PVOID Memory::SetupOrClearHardwareBreakPointForAllThreads(uintptr_t targetAddres
CONTEXT ctx = {}; CONTEXT ctx = {};
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
if (GetThreadContext(hThread, &ctx)) if (GetThreadContext(hThread, &ctx)) {
{ if (enable) {
if (enable)
{
switch (hwIndex) { switch (hwIndex) {
case 0: ctx.Dr0 = targetAddress; break; // Set Hardware breakpoint #1 case 0: ctx.Dr0 = targetAddress; break; // Set Hardware breakpoint #1
case 1: ctx.Dr1 = targetAddress; break; // Set Hardware breakpoint #2 case 1: ctx.Dr1 = targetAddress; break; // Set Hardware breakpoint #2
case 2: ctx.Dr2 = targetAddress; break; // Set Hardware breakpoint #3 case 2: ctx.Dr2 = targetAddress; break; // Set Hardware breakpoint #3
case 3: ctx.Dr3 = targetAddress; break; // Set Hardware breakpoint #4 case 3: ctx.Dr3 = targetAddress; break; // Set Hardware breakpoint #4
default: break; default: break;
} }
ctx.Dr7 |= (1ULL << (hwIndex * 2)); // activate hardware breakpoint ctx.Dr7 |= (1ULL << (hwIndex * 2)); // activate hardware breakpoint
} }
else else {
{
switch (hwIndex) { switch (hwIndex) {
case 0: ctx.Dr0 = 0; break; // Unset Hardware breakpoint #1 case 0: ctx.Dr0 = 0; break; // Unset Hardware breakpoint #1
case 1: ctx.Dr1 = 0; break; // Unset Hardware breakpoint #2 case 1: ctx.Dr1 = 0; break; // Unset Hardware breakpoint #2
@@ -342,12 +332,10 @@ PVOID Memory::SetupOrClearHardwareBreakPointForAllThreads(uintptr_t targetAddres
CloseHandle(snapshot); CloseHandle(snapshot);
// Remove VectoredExceptionHandler // Remove VectoredExceptionHandler
if (!enable && vehHandle) if (!enable && vehHandle) {
{
RemoveVectoredExceptionHandler(vehHandle); RemoveVectoredExceptionHandler(vehHandle);
vehHandle = nullptr; vehHandle = nullptr;
} }
return vehHandle; return vehHandle;
} }