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() void BugFixes::init()
{ {
#ifndef NDEBUG #ifndef NDEBUG
LoadGameHook::OnBeforeGameClose() += PrintAddrList;
if (isDebug && (GetPrivateProfileIntA("Debugging", "BugFixes", 1, ::sfall::ddrawIni) == 0)) return; if (isDebug && (GetPrivateProfileIntA("Debugging", "BugFixes", 1, ::sfall::ddrawIni) == 0)) return;
#endif #endif
+54 -28
View File
@@ -1,7 +1,3 @@
#ifndef NDEBUG
#include <list>
#endif
#include "main.h" #include "main.h"
#pragma warning(disable:4996) #pragma warning(disable:4996)
@@ -16,21 +12,45 @@ enum CodeType : BYTE {
}; };
#ifndef NDEBUG #ifndef NDEBUG
std::list<long> writeAddress; std::multimap<long, long> writeAddress;
void CheckConflict(DWORD addr) { /* Checking for conflicts requires all options in ddraw.ini to be enabled */
bool exist = false; void PrintAddrList() {
unsigned long prev = 0, plen = 0;
for (const auto &wa : writeAddress) { for (const auto &wa : writeAddress) {
if (addr == wa) { unsigned long diff = (prev) ? (wa.first - prev) : -1; // length between two addresses
exist = true; if (diff == 0 || diff < plen) {
char buf[256]; dlog_f("0x%x L:%d [Conflict]\n", DL_MAIN, wa.first, wa.second);
dlog_f("Memory writing conflict at address: 0x%x\n", DL_MAIN, addr); } else if (diff == plen) {
sprintf_s(buf, "Memory writing conflict at address 0x%x. The address has already been overwritten by other code.", addr); dlog_f("0x%x L:%d [Warning] PL:%d\n", DL_MAIN, wa.first, wa.second, plen);
MessageBoxA(0, buf, "Conflict Detected", MB_TASKMODAL); } 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 #endif
static void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func) { 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; *((DWORD*)(addr + 1)) = data;
VirtualProtect((void *)addr, 5, oldProtect, &oldProtect); VirtualProtect((void *)addr, 5, oldProtect, &oldProtect);
#ifndef NDEBUG _CheckConflict(addr, 5);
CheckConflict(addr);
#endif
} }
static __declspec(noinline) void _stdcall SafeWriteFunc(BYTE code, DWORD addr, void* func, DWORD len) { 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); VirtualProtect((void *)addr, protectLen, oldProtect, &oldProtect);
#ifndef NDEBUG _CheckConflict(addr, protectLen);
CheckConflict(addr);
#endif
} }
void SafeWriteBytes(DWORD addr, BYTE* data, int count) { 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); VirtualProtect((void *)addr, count, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy((void*)addr, data, count); memcpy((void*)addr, data, count);
VirtualProtect((void *)addr, count, oldProtect, &oldProtect); VirtualProtect((void *)addr, count, oldProtect, &oldProtect);
_AddrAddToList(addr, count)
} }
void _stdcall SafeWrite8(DWORD addr, BYTE data) { 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); VirtualProtect((void *)addr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*((BYTE*)addr) = data; *((BYTE*)addr) = data;
VirtualProtect((void *)addr, 1, oldProtect, &oldProtect); VirtualProtect((void *)addr, 1, oldProtect, &oldProtect);
_AddrAddToList(addr, 1)
} }
void _stdcall SafeWrite16(DWORD addr, WORD data) { 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); VirtualProtect((void *)addr, 2, PAGE_EXECUTE_READWRITE, &oldProtect);
*((WORD*)addr) = data; *((WORD*)addr) = data;
VirtualProtect((void *)addr, 2, oldProtect, &oldProtect); VirtualProtect((void *)addr, 2, oldProtect, &oldProtect);
_AddrAddToList(addr, 2)
} }
void _stdcall SafeWrite32(DWORD addr, DWORD data) { 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); VirtualProtect((void *)addr, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
*((DWORD*)addr) = data; *((DWORD*)addr) = data;
VirtualProtect((void *)addr, 4, oldProtect, &oldProtect); VirtualProtect((void *)addr, 4, oldProtect, &oldProtect);
_AddrAddToList(addr, 4)
} }
void _stdcall SafeWriteStr(DWORD addr, const char* data) { void _stdcall SafeWriteStr(DWORD addr, const char* data) {
DWORD oldProtect; 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); 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) { void HookCall(DWORD addr, void* func) {
SafeWrite32(addr + 1, (DWORD)func - (addr + 5)); SafeWrite32(addr + 1, (DWORD)func - (addr + 5));
#ifndef NDEBUG
CheckConflict(addr); _CheckConflict(addr, 1)
#endif
} }
void MakeCall(DWORD addr, void* func) { 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); VirtualProtect((void *)addr, len, PAGE_EXECUTE_READWRITE, &oldProtect);
memset((void*)addr, val, len); memset((void*)addr, val, len);
VirtualProtect((void *)addr, len, oldProtect, &oldProtect); VirtualProtect((void *)addr, len, oldProtect, &oldProtect);
_AddrAddToList(addr, len)
} }
void BlockCall(DWORD addr) { void BlockCall(DWORD addr) {
@@ -157,9 +185,7 @@ void BlockCall(DWORD addr) {
*((BYTE*)(addr + 4)) = 0x00; *((BYTE*)(addr + 4)) = 0x00;
VirtualProtect((void *)addr, 5, oldProtect, &oldProtect); VirtualProtect((void *)addr, 5, oldProtect, &oldProtect);
#ifndef NDEBUG _CheckConflict(addr, 5)
CheckConflict(addr);
#endif
} }
} }
+4 -2
View File
@@ -5,8 +5,10 @@
namespace sfall namespace sfall
{ {
#ifndef NDEBUG #ifndef NDEBUG
void CheckConflict(DWORD addr); void AddrAddToList(DWORD addr, long len);
void PrintAddrList();
#endif #endif
template<typename T> void _stdcall SafeWrite(DWORD addr, T data) { 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); VirtualProtect((void*)addr, sizeof(T), oldProtect, &oldProtect);
#ifndef NDEBUG #ifndef NDEBUG
if (GetPrivateProfileIntA("Debugging", "Enable", 0, ::sfall::ddrawIni) == 2) CheckConflict(addr); AddrAddToList(addr, sizeof(T));
#endif #endif
} }