mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added printing a list of all mem addrs in the log for debug version
* for checking hidden memory conflicts.
This commit is contained in:
@@ -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
@@ -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
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user