Added printing a list of all mem addrs in the log for debug version

* for checking hidden memory conflicts.
This commit is contained in:
NovaRain
2019-09-09 12:55:24 +08:00
parent fee142342c
commit 4975177c34
3 changed files with 62 additions and 33 deletions
+1
View File
@@ -2294,6 +2294,7 @@ static void __declspec(naked) map_check_state_hook() {
void BugFixes::init()
{
#ifndef NDEBUG
LoadGameHook::OnBeforeGameClose() += PrintAddrList;
if (isDebug && (GetPrivateProfileIntA("Debugging", "BugFixes", 1, ::sfall::ddrawIni) == 0)) return;
#endif
+54 -28
View File
@@ -1,7 +1,3 @@
#ifndef NDEBUG
#include <list>
#endif
#include "main.h"
#pragma warning(disable:4996)
@@ -16,21 +12,45 @@ enum CodeType : BYTE {
};
#ifndef NDEBUG
std::list<long> writeAddress;
std::multimap<long, long> writeAddress;
void CheckConflict(DWORD addr) {
bool exist = false;
/* Checking for conflicts requires all options in ddraw.ini to be enabled */
void PrintAddrList() {
unsigned long prev = 0, plen = 0;
for (const auto &wa : writeAddress) {
if (addr == wa) {
exist = true;
char buf[256];
dlog_f("Memory writing conflict at address: 0x%x\n", DL_MAIN, addr);
sprintf_s(buf, "Memory writing conflict at address 0x%x. The address has already been overwritten by other code.", addr);
MessageBoxA(0, buf, "Conflict Detected", MB_TASKMODAL);
unsigned long diff = (prev) ? (wa.first - prev) : -1; // length between two addresses
if (diff == 0 || diff < plen) {
dlog_f("0x%x L:%d [Conflict]\n", DL_MAIN, wa.first, wa.second);
} else if (diff == plen) {
dlog_f("0x%x L:%d [Warning] PL:%d\n", DL_MAIN, wa.first, wa.second, plen);
} else {
dlog_f("0x%x L:%d\n", DL_MAIN, wa.first, wa.second);
}
prev = wa.first;
plen = wa.second;
}
}
if (!exist) writeAddress.push_back(addr);
void CheckConflict(DWORD addr, long len) {
writeAddress.begin()->first;
if (writeAddress.find(addr) != writeAddress.cend()) {
char buf[64];
sprintf_s(buf, "Memory writing conflict at address 0x%x.", addr);
//dlogr(buf, DL_MAIN);
MessageBoxA(0, buf, "", MB_TASKMODAL);
}
writeAddress.emplace(addr, len);
}
void AddrAddToList(DWORD addr, long len) {
writeAddress.emplace(addr, len);
}
#define _CheckConflict(addr, len) CheckConflict(addr, len);
#define _AddrAddToList(addr, len) AddrAddToList(addr, len);
#else
#define _CheckConflict(a, b)
#define _AddrAddToList(a, b)
#endif
static void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func) {
@@ -41,9 +61,7 @@ static void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func) {
*((DWORD*)(addr + 1)) = data;
VirtualProtect((void *)addr, 5, oldProtect, &oldProtect);
#ifndef NDEBUG
CheckConflict(addr);
#endif
_CheckConflict(addr, 5);
}
static __declspec(noinline) void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func, DWORD len) {
@@ -61,9 +79,7 @@ static __declspec(noinline) void _stdcall SafeWriteFunc(BYTE code, DWORD addr, v
}
VirtualProtect((void *)addr, protectLen, oldProtect, &oldProtect);
#ifndef NDEBUG
CheckConflict(addr);
#endif
_CheckConflict(addr, protectLen);
}
void SafeWriteBytes(DWORD addr, BYTE* data, int count) {
@@ -72,6 +88,8 @@ void SafeWriteBytes(DWORD addr, BYTE* data, int count) {
VirtualProtect((void *)addr, count, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy((void*)addr, data, count);
VirtualProtect((void *)addr, count, oldProtect, &oldProtect);
_AddrAddToList(addr, count)
}
void _stdcall SafeWrite8(DWORD addr, BYTE data) {
@@ -80,6 +98,8 @@ void _stdcall SafeWrite8(DWORD addr, BYTE data) {
VirtualProtect((void *)addr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*((BYTE*)addr) = data;
VirtualProtect((void *)addr, 1, oldProtect, &oldProtect);
_AddrAddToList(addr, 1)
}
void _stdcall SafeWrite16(DWORD addr, WORD data) {
@@ -88,6 +108,8 @@ void _stdcall SafeWrite16(DWORD addr, WORD data) {
VirtualProtect((void *)addr, 2, PAGE_EXECUTE_READWRITE, &oldProtect);
*((WORD*)addr) = data;
VirtualProtect((void *)addr, 2, oldProtect, &oldProtect);
_AddrAddToList(addr, 2)
}
void _stdcall SafeWrite32(DWORD addr, DWORD data) {
@@ -96,21 +118,25 @@ void _stdcall SafeWrite32(DWORD addr, DWORD data) {
VirtualProtect((void *)addr, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
*((DWORD*)addr) = data;
VirtualProtect((void *)addr, 4, oldProtect, &oldProtect);
_AddrAddToList(addr, 4)
}
void _stdcall SafeWriteStr(DWORD addr, const char* data) {
DWORD oldProtect;
long len = strlen(data) + 1;
VirtualProtect((void *)addr, strlen(data) + 1, PAGE_EXECUTE_READWRITE, &oldProtect);
VirtualProtect((void *)addr, len, PAGE_EXECUTE_READWRITE, &oldProtect);
strcpy((char *)addr, data);
VirtualProtect((void *)addr, strlen(data) + 1, oldProtect, &oldProtect);
VirtualProtect((void *)addr, len, oldProtect, &oldProtect);
_AddrAddToList(addr, len)
}
void HookCall(DWORD addr, void* func) {
SafeWrite32(addr + 1, (DWORD)func - (addr + 5));
#ifndef NDEBUG
CheckConflict(addr);
#endif
_CheckConflict(addr, 1)
}
void MakeCall(DWORD addr, void* func) {
@@ -147,6 +173,8 @@ void SafeMemSet(DWORD addr, BYTE val, int len) {
VirtualProtect((void *)addr, len, PAGE_EXECUTE_READWRITE, &oldProtect);
memset((void*)addr, val, len);
VirtualProtect((void *)addr, len, oldProtect, &oldProtect);
_AddrAddToList(addr, len)
}
void BlockCall(DWORD addr) {
@@ -157,9 +185,7 @@ void BlockCall(DWORD addr) {
*((BYTE*)(addr + 4)) = 0x00;
VirtualProtect((void *)addr, 5, oldProtect, &oldProtect);
#ifndef NDEBUG
CheckConflict(addr);
#endif
_CheckConflict(addr, 5)
}
}
+4 -2
View File
@@ -5,8 +5,10 @@
namespace sfall
{
#ifndef NDEBUG
void CheckConflict(DWORD addr);
void AddrAddToList(DWORD addr, long len);
void PrintAddrList();
#endif
template<typename T> void _stdcall SafeWrite(DWORD addr, T data) {
@@ -16,7 +18,7 @@ template<typename T> void _stdcall SafeWrite(DWORD addr, T data) {
VirtualProtect((void*)addr, sizeof(T), oldProtect, &oldProtect);
#ifndef NDEBUG
if (GetPrivateProfileIntA("Debugging", "Enable", 0, ::sfall::ddrawIni) == 2) CheckConflict(addr);
AddrAddToList(addr, sizeof(T));
#endif
}