1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-15 06:04:49 +01:00

add testing code for privileged instructions

This commit is contained in:
FunkyFr3sh 2024-09-24 20:17:53 +02:00
parent 7febf01343
commit e0e59cd9fa
4 changed files with 135 additions and 46 deletions

View File

@ -64,6 +64,7 @@ typedef struct CNCDDRAWCONFIG
BOOL fix_alt_key_stuck;
BOOL fix_not_responding;
BOOL no_compat_warning;
BOOL ignore_exceptions;
BOOL wine_allow_resize;
int guard_lines;
int max_resolutions;

View File

@ -77,6 +77,7 @@ void cfg_load()
GET_BOOL(GameHandlesClose, "game_handles_close", FALSE);
GET_BOOL(g_config.fix_not_responding, "fix_not_responding", FALSE);
GET_BOOL(g_config.no_compat_warning, "no_compat_warning", FALSE);
GET_BOOL(g_config.ignore_exceptions, "ignore_exceptions", FALSE);
GET_BOOL(g_config.wine_allow_resize, "wine_allow_resize", FALSE);
GET_INT(g_config.guard_lines, "guard_lines", 200);
GET_INT(g_config.max_resolutions, "max_resolutions", 0);
@ -309,6 +310,7 @@ static void cfg_create_ini()
"game_handles_close=false\n"
"fix_not_responding=false\n"
"no_compat_warning=false\n"
"ignore_exceptions=false\n"
"wine_allow_resize=false\n"
"guard_lines=200\n"
"max_resolutions=0\n"

View File

@ -14,6 +14,8 @@
#include "versionhelpers.h"
#include "utils.h"
#include "dllmain.h"
#include "config.h"
#include "patch.h"
double g_dbg_frame_time = 0;
@ -35,59 +37,98 @@ static int g_dbg_crash_count = 0;
LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception)
{
g_dbg_crash_count++;
HANDLE dmp =
CreateFile(
g_dbg_crash_count == 1 ? g_dbg_dmp_path1 : g_dbg_dmp_path2,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
0,
CREATE_ALWAYS,
0,
0);
if (dmp != INVALID_HANDLE_VALUE)
if (!exception || !exception->ExceptionRecord)
{
MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = GetCurrentThreadId();
info.ExceptionPointers = exception;
info.ClientPointers = TRUE;
if (g_dbg_exception_filter)
return g_dbg_exception_filter(exception);
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
dmp,
0,
&info,
NULL,
NULL);
CloseHandle(dmp);
return EXCEPTION_EXECUTE_HANDLER;
}
if (exception && exception->ExceptionRecord)
if (exception->ExceptionRecord->ExceptionCode != STATUS_PRIVILEGED_INSTRUCTION || !g_config.ignore_exceptions)
{
HMODULE mod = NULL;
char filename[MAX_PATH] = { 0 };
g_dbg_crash_count++;
HANDLE dmp =
CreateFile(
g_dbg_crash_count == 1 ? g_dbg_dmp_path1 : g_dbg_dmp_path2,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
0,
CREATE_ALWAYS,
0,
0);
if (dmp != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = GetCurrentThreadId();
info.ExceptionPointers = exception;
info.ClientPointers = TRUE;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
dmp,
0,
&info,
NULL,
NULL);
CloseHandle(dmp);
}
}
HMODULE mod = NULL;
char filename[MAX_PATH] = { 0 };
#if defined(_MSC_VER) /* comment this out just to keep the mingw build win2000 compatible */
if (GetModuleHandleExA(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
exception->ExceptionRecord->ExceptionAddress,
&mod))
{
GetModuleFileNameA(mod, filename, sizeof(filename) - 1);
}
if (GetModuleHandleExA(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
exception->ExceptionRecord->ExceptionAddress,
&mod))
{
GetModuleFileNameA(mod, filename, sizeof(filename) - 1);
}
#endif
TRACE(
"Exception at %p (%p+%p), Code=%08X - %s\n",
exception->ExceptionRecord->ExceptionAddress,
mod,
(int)exception->ExceptionRecord->ExceptionAddress - (int)mod,
exception->ExceptionRecord->ExceptionCode,
filename);
TRACE(
"Exception at %p (%p+%p), Code=%08X - %s\n",
exception->ExceptionRecord->ExceptionAddress,
mod,
(int)exception->ExceptionRecord->ExceptionAddress - (int)mod,
exception->ExceptionRecord->ExceptionCode,
filename);
if (g_config.ignore_exceptions &&
exception->ContextRecord &&
exception->ExceptionRecord->ExceptionAddress &&
exception->ExceptionRecord->ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION)
{
size_t size = 0;
BYTE* addr = exception->ExceptionRecord->ExceptionAddress;
switch (*addr)
{
case 0xE4: // IN ib
case 0xE5: // IN id
case 0xE6: // OUT ib
case 0xE7: // OUT ib
size = 2;
break;
case 0xEC: // IN ib
case 0xED: // IN id
case 0xEE: // OUT
case 0xEF: // OUT
size = 1;
break;
}
if (size)
{
exception->ContextRecord->Eip += size;
patch_clear((void*)addr, 0x90, (char*)addr + size);
return EXCEPTION_CONTINUE_EXECUTION;
}
}
if (g_dbg_exception_filter)
@ -111,6 +152,46 @@ void __cdecl dbg_invoke_watson(
TerminateProcess(GetCurrentProcess(), STATUS_INVALID_CRUNTIME_PARAMETER);
}
#else
LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception)
{
if (exception &&
exception->ContextRecord &&
exception->ExceptionRecord &&
exception->ExceptionRecord->ExceptionAddress &&
exception->ExceptionRecord->ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION)
{
size_t size = 0;
BYTE* addr = exception->ExceptionRecord->ExceptionAddress;
switch (*addr)
{
case 0xE4: // IN ib
case 0xE5: // IN id
case 0xE6: // OUT ib
case 0xE7: // OUT ib
size = 2;
break;
case 0xEC: // IN ib
case 0xED: // IN id
case 0xEE: // OUT
case 0xEF: // OUT
size = 1;
break;
}
if (size)
{
exception->ContextRecord->Eip += size;
patch_clear((void*)addr, 0x90, (char*)addr + size);
return EXCEPTION_CONTINUE_EXECUTION;
}
}
if (g_dbg_exception_filter)
return g_dbg_exception_filter(exception);
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
void dbg_init()

View File

@ -43,9 +43,14 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
#ifdef _DEBUG
dbg_init();
g_dbg_exception_filter = real_SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)dbg_exception_handler);
#endif
cfg_load();
#else
cfg_load();
if (g_config.ignore_exceptions)
{
g_dbg_exception_filter = real_SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)dbg_exception_handler);
}
#endif
char buf[1024];