Add rich and less rich log macro
This commit is contained in:
@@ -10,13 +10,23 @@
|
||||
#include <iomanip>
|
||||
#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;
|
||||
std::unordered_map<void*, Memory::PatchInfo> Memory::patches;
|
||||
|
||||
uint8_t* Memory::GetOffsetFromOpcode(uint8_t* opcode, int extraOffset)
|
||||
{
|
||||
if (!opcode)
|
||||
return nullptr;
|
||||
uint8_t* Memory::GetOffsetFromOpcode(uint8_t* opcode, int extraOffset) {
|
||||
if (!opcode) return nullptr;
|
||||
|
||||
int32_t disp = 0;
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
std::memcpy(&disp, opcode + dispOffset, sizeof(disp)); // lit le disp32 de manière safe
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (it == patches.end())
|
||||
{
|
||||
if (it == patches.end()) {
|
||||
// If a patch doesn't exist, create a new one.
|
||||
PatchInfo info;
|
||||
info.address = address;
|
||||
@@ -68,11 +75,9 @@ void Memory::PatchBytes(void* address, const char* bytes, size_t len)
|
||||
VirtualProtect(address, len, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
void Memory::RestoreBytes(void *address)
|
||||
{
|
||||
void Memory::RestoreBytes(void *address) {
|
||||
auto it = patches.find(address);
|
||||
if (it != patches.end())
|
||||
{
|
||||
if (it != patches.end()) {
|
||||
// Restore the original bytes.
|
||||
const auto& info = it->second;
|
||||
DWORD oldProtect;
|
||||
@@ -90,15 +95,12 @@ MODULEINFO Memory::WaitForModule(const std::string& module_name, int timeoutMs,
|
||||
const HANDLE hProc = GetCurrentProcess();
|
||||
MODULEINFO modInfo{};
|
||||
|
||||
for (int waited = 0; waited < timeoutMs; waited += intervalMs)
|
||||
{
|
||||
for (int waited = 0; waited < timeoutMs; waited += intervalMs) {
|
||||
HMODULE hMods[1024];
|
||||
DWORD cbNeeded;
|
||||
|
||||
if (EnumProcessModules(hProc, hMods, sizeof(hMods), &cbNeeded))
|
||||
{
|
||||
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i)
|
||||
{
|
||||
if (EnumProcessModules(hProc, hMods, sizeof(hMods), &cbNeeded)) {
|
||||
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i) {
|
||||
char modName[MAX_PATH];
|
||||
if (GetModuleBaseNameA(hProc, hMods[i], modName, sizeof(modName))) {
|
||||
if (_stricmp(modName, module_name.c_str()) == 0) {
|
||||
@@ -164,8 +166,7 @@ uint8_t* Memory::AOBScan(
|
||||
std::vector<int> pattern_bytes;
|
||||
std::istringstream stream(signature);
|
||||
std::string byte_str;
|
||||
while (stream >> byte_str)
|
||||
{
|
||||
while (stream >> byte_str) {
|
||||
if (byte_str == "??" || byte_str == "?")
|
||||
pattern_bytes.push_back(-1);
|
||||
else
|
||||
@@ -184,8 +185,7 @@ uint8_t* Memory::AOBScan(
|
||||
|
||||
// Memory scan
|
||||
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)))
|
||||
break;
|
||||
|
||||
@@ -198,11 +198,9 @@ uint8_t* Memory::AOBScan(
|
||||
uint8_t* regionBase = reinterpret_cast<uint8_t*>(mbi.BaseAddress);
|
||||
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;
|
||||
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])) {
|
||||
match = false;
|
||||
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;
|
||||
*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;
|
||||
// Calculate offset according type
|
||||
switch (scanEntry.calcType)
|
||||
{
|
||||
switch (scanEntry.calcType) {
|
||||
case OffsetCalcType::GetOffsetFromOpcode: {
|
||||
calculatedOffset = static_cast<UT::uint32>(Memory::GetOffsetFromOpcode(*scanEntry.outAddress + scanEntry.opcodeOffset) - baseModule);
|
||||
break;
|
||||
@@ -290,14 +287,10 @@ PVOID Memory::SetupOrClearHardwareBreakPointForAllThreads(uintptr_t targetAddres
|
||||
|
||||
// Add VectoredExceptionHandler
|
||||
if (enable && !vehHandle && pVEH)
|
||||
{
|
||||
vehHandle = AddVectoredExceptionHandler(1, pVEH);
|
||||
}
|
||||
|
||||
if (Thread32First(snapshot, &te))
|
||||
{
|
||||
do
|
||||
{
|
||||
if (Thread32First(snapshot, &te)) {
|
||||
do {
|
||||
if (te.th32OwnerProcessID != pid) continue;
|
||||
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
|
||||
@@ -306,21 +299,18 @@ PVOID Memory::SetupOrClearHardwareBreakPointForAllThreads(uintptr_t targetAddres
|
||||
CONTEXT ctx = {};
|
||||
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
||||
|
||||
if (GetThreadContext(hThread, &ctx))
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
if (GetThreadContext(hThread, &ctx)) {
|
||||
if (enable) {
|
||||
switch (hwIndex) {
|
||||
case 0: ctx.Dr0 = targetAddress; break; // Set Hardware breakpoint #1
|
||||
case 1: ctx.Dr1 = targetAddress; break; // Set Hardware breakpoint #2
|
||||
case 2: ctx.Dr2 = targetAddress; break; // Set Hardware breakpoint #3
|
||||
case 3: ctx.Dr3 = targetAddress; break; // Set Hardware breakpoint #4
|
||||
default: break;
|
||||
case 0: ctx.Dr0 = targetAddress; break; // Set Hardware breakpoint #1
|
||||
case 1: ctx.Dr1 = targetAddress; break; // Set Hardware breakpoint #2
|
||||
case 2: ctx.Dr2 = targetAddress; break; // Set Hardware breakpoint #3
|
||||
case 3: ctx.Dr3 = targetAddress; break; // Set Hardware breakpoint #4
|
||||
default: break;
|
||||
}
|
||||
ctx.Dr7 |= (1ULL << (hwIndex * 2)); // activate hardware breakpoint
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
switch (hwIndex) {
|
||||
case 0: ctx.Dr0 = 0; break; // Unset Hardware breakpoint #1
|
||||
case 1: ctx.Dr1 = 0; break; // Unset Hardware breakpoint #2
|
||||
@@ -342,12 +332,10 @@ PVOID Memory::SetupOrClearHardwareBreakPointForAllThreads(uintptr_t targetAddres
|
||||
CloseHandle(snapshot);
|
||||
|
||||
// Remove VectoredExceptionHandler
|
||||
if (!enable && vehHandle)
|
||||
{
|
||||
if (!enable && vehHandle) {
|
||||
RemoveVectoredExceptionHandler(vehHandle);
|
||||
vehHandle = nullptr;
|
||||
}
|
||||
|
||||
return vehHandle;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user