Workaround for a bug in the kernel with x64 emulation on ARM

This commit is contained in:
Duncan Ogilvie 2022-08-10 18:49:36 +02:00
parent fb1babcbb3
commit 160d66919e
5 changed files with 31 additions and 9 deletions

View File

@ -42,6 +42,27 @@ bool DebugStepFinal = false;
LPVOID StepOutCallBack = NULL; LPVOID StepOutCallBack = NULL;
CRITICAL_SECTION engineStepActiveCr; CRITICAL_SECTION engineStepActiveCr;
// Workaround for a bug in the kernel with x64 emulation on ARM
DWORD ContextControlFlags = []
{
DWORD flags = CONTEXT_CONTROL;
typedef BOOL(WINAPI *type_IsWow64Process2)(HANDLE, USHORT*, USHORT*);
auto p_IsWow64Process2 = (type_IsWow64Process2)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process2");
if (p_IsWow64Process2)
{
USHORT processMachine = 0;
USHORT nativeMachine = 0;
if (p_IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine))
{
if (nativeMachine == IMAGE_FILE_MACHINE_ARM || nativeMachine == IMAGE_FILE_MACHINE_ARM64)
{
flags = CONTEXT_ALL;
}
}
}
return flags;
}();
// Global.Debugger.functions: // Global.Debugger.functions:
long DebugLoopInSecondThread(LPVOID InputParameter) long DebugLoopInSecondThread(LPVOID InputParameter)
{ {

View File

@ -41,6 +41,7 @@ extern wchar_t szDebuggerName[512];
extern bool DebugStepFinal; extern bool DebugStepFinal;
extern LPVOID StepOutCallBack; extern LPVOID StepOutCallBack;
extern CRITICAL_SECTION engineStepActiveCr; extern CRITICAL_SECTION engineStepActiveCr;
extern DWORD ContextControlFlags;
long DebugLoopInSecondThread(LPVOID InputParameter); long DebugLoopInSecondThread(LPVOID InputParameter);
void DebuggerReset(); void DebuggerReset();

View File

@ -55,7 +55,7 @@ __declspec(dllexport) void TITCALL StepInto(LPVOID StepCallBack)
{ {
CONTEXT myDBGContext; CONTEXT myDBGContext;
HANDLE hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId); HANDLE hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_CONTROL; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
myDBGContext.EFlags |= UE_TRAP_FLAG; myDBGContext.EFlags |= UE_TRAP_FLAG;
SetThreadContext(hActiveThread, &myDBGContext); SetThreadContext(hActiveThread, &myDBGContext);

View File

@ -552,7 +552,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
FlushInstructionCache(dbgProcessInformation.hProcess, NULL, 0); FlushInstructionCache(dbgProcessInformation.hProcess, NULL, 0);
DBGCode = DBG_CONTINUE; DBGCode = DBG_CONTINUE;
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId); hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_CONTROL; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
if(FoundBreakPoint.BreakPointType != UE_SINGLESHOOT) if(FoundBreakPoint.BreakPointType != UE_SINGLESHOOT)
myDBGContext.EFlags |= UE_TRAP_FLAG; myDBGContext.EFlags |= UE_TRAP_FLAG;
@ -674,7 +674,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
else else
{ {
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId); hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_CONTROL; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
myDBGContext.EFlags |= UE_TRAP_FLAG; myDBGContext.EFlags |= UE_TRAP_FLAG;
SetThreadContext(hActiveThread, &myDBGContext); SetThreadContext(hActiveThread, &myDBGContext);
@ -727,7 +727,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
{ {
//handle hardware breakpoints //handle hardware breakpoints
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId); hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_DEBUG_REGISTERS | CONTEXT_CONTROL; myDBGContext.ContextFlags = CONTEXT_DEBUG_REGISTERS | ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
if((ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == myDBGContext.Dr0 || (myDBGContext.Dr6 & 0x1)) if((ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == myDBGContext.Dr0 || (myDBGContext.Dr6 & 0x1))
{ {
@ -893,7 +893,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
if(bFoundBreakPoint) //found memory breakpoint if(bFoundBreakPoint) //found memory breakpoint
{ {
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId); hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_CONTROL; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
DBGCode = DBG_CONTINUE; //debugger handled the exception DBGCode = DBG_CONTINUE; //debugger handled the exception
MemoryBpxCallBack = FoundBreakPoint.ExecuteCallBack; MemoryBpxCallBack = FoundBreakPoint.ExecuteCallBack;
@ -1062,7 +1062,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
if(bFoundBreakPoint && engineMembpAlt) //found memory breakpoint if(bFoundBreakPoint && engineMembpAlt) //found memory breakpoint
{ {
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId); hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_CONTROL; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
DBGCode = DBG_CONTINUE; //debugger handled the exception DBGCode = DBG_CONTINUE; //debugger handled the exception
MemoryBpxCallBack = FoundBreakPoint.ExecuteCallBack; MemoryBpxCallBack = FoundBreakPoint.ExecuteCallBack;
@ -1239,7 +1239,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
FlushInstructionCache(dbgProcessInformation.hProcess, NULL, 0); FlushInstructionCache(dbgProcessInformation.hProcess, NULL, 0);
DBGCode = DBG_CONTINUE; DBGCode = DBG_CONTINUE;
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId); hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_CONTROL; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
if(FoundBreakPoint.BreakPointType != UE_SINGLESHOOT) if(FoundBreakPoint.BreakPointType != UE_SINGLESHOOT)
myDBGContext.EFlags |= UE_TRAP_FLAG; myDBGContext.EFlags |= UE_TRAP_FLAG;
@ -1400,7 +1400,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
{ {
CONTEXT DbgCtx; CONTEXT DbgCtx;
DbgCtx.ContextFlags = CONTEXT_CONTROL; DbgCtx.ContextFlags = ContextControlFlags;
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId); hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);

View File

@ -620,7 +620,7 @@ __declspec(dllexport) bool TITCALL DetachDebuggerEx(DWORD ProcessId)
{ {
HANDLE hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, hListThread.at(i).dwThreadId); HANDLE hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, hListThread.at(i).dwThreadId);
CONTEXT myDBGContext; CONTEXT myDBGContext;
myDBGContext.ContextFlags = CONTEXT_CONTROL; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
myDBGContext.EFlags &= ~UE_TRAP_FLAG; myDBGContext.EFlags &= ~UE_TRAP_FLAG;
myDBGContext.EFlags &= ~UE_RESUME_FLAG; myDBGContext.EFlags &= ~UE_RESUME_FLAG;