Skip to content

Commit

Permalink
Put a critical section around StepInto to make it thread-safe
Browse files Browse the repository at this point in the history
  • Loading branch information
mrexodia committed Dec 11, 2021
1 parent 1a76d61 commit fb1babc
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 79 deletions.
1 change: 1 addition & 0 deletions TitanEngine/Global.Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ LPVOID engineAttachedProcessDebugInfo = NULL;
wchar_t szDebuggerName[512];
bool DebugStepFinal = false;
LPVOID StepOutCallBack = NULL;
CRITICAL_SECTION engineStepActiveCr;

// Global.Debugger.functions:
long DebugLoopInSecondThread(LPVOID InputParameter)
Expand Down
2 changes: 2 additions & 0 deletions TitanEngine/Global.Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _GLOBAL_DEBUGGER_H

#include <vector>
#include <Windows.h>

extern HARDWARE_DATA DebugRegister[4];
extern PROCESS_INFORMATION dbgProcessInformation;
Expand Down Expand Up @@ -39,6 +40,7 @@ extern LPVOID engineAttachedProcessDebugInfo;
extern wchar_t szDebuggerName[512];
extern bool DebugStepFinal;
extern LPVOID StepOutCallBack;
extern CRITICAL_SECTION engineStepActiveCr;

long DebugLoopInSecondThread(LPVOID InputParameter);
void DebuggerReset();
Expand Down
49 changes: 27 additions & 22 deletions TitanEngine/TitanEngine.Debugger.Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,35 @@ __declspec(dllexport) void TITCALL ForceClose()

__declspec(dllexport) void TITCALL StepInto(LPVOID StepCallBack)
{
ULONG_PTR ueCurrentPosition = GetContextData(UE_CIP);
unsigned char instr[16];
MemoryReadSafe(dbgProcessInformation.hProcess, (void*)ueCurrentPosition, instr, sizeof(instr), 0);
char* DisassembledString = (char*)StaticDisassembleEx(ueCurrentPosition, (LPVOID)instr);
if(strstr(DisassembledString, "PUSHF"))
StepOver(StepCallBack);
else if(strstr(DisassembledString, "POP SS") || strstr(DisassembledString, "MOV SS")) //prevent the 'PUSH SS', 'POP SS' step trick
EnterCriticalSection(&engineStepActiveCr);
if (!engineStepActive)
{
ueCurrentPosition += StaticLengthDisassemble((void*)instr);
SetBPX(ueCurrentPosition, UE_BREAKPOINT_TYPE_INT3 + UE_SINGLESHOOT, StepCallBack);
}
else
{
CONTEXT myDBGContext;
HANDLE hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(hActiveThread, &myDBGContext);
myDBGContext.EFlags |= UE_TRAP_FLAG;
SetThreadContext(hActiveThread, &myDBGContext);
EngineCloseHandle(hActiveThread);
engineStepActive = true;
engineStepCallBack = StepCallBack;
engineStepCount = 0;
ULONG_PTR ueCurrentPosition = GetContextData(UE_CIP);
unsigned char instr[16];
MemoryReadSafe(dbgProcessInformation.hProcess, (void*)ueCurrentPosition, instr, sizeof(instr), 0);
char* DisassembledString = (char*)StaticDisassembleEx(ueCurrentPosition, (LPVOID)instr);
if (strstr(DisassembledString, "PUSHF"))
StepOver(StepCallBack);
else if (strstr(DisassembledString, "POP SS") || strstr(DisassembledString, "MOV SS")) //prevent the 'PUSH SS', 'POP SS' step trick
{
ueCurrentPosition += StaticLengthDisassemble((void*)instr);
SetBPX(ueCurrentPosition, UE_BREAKPOINT_TYPE_INT3 + UE_SINGLESHOOT, StepCallBack);
}
else
{
CONTEXT myDBGContext;
HANDLE hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
myDBGContext.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(hActiveThread, &myDBGContext);
myDBGContext.EFlags |= UE_TRAP_FLAG;
SetThreadContext(hActiveThread, &myDBGContext);
EngineCloseHandle(hActiveThread);
engineStepActive = true;
engineStepCallBack = StepCallBack;
engineStepCount = 0;
}
}
LeaveCriticalSection(&engineStepActiveCr);
}

__declspec(dllexport) void TITCALL StepOver(LPVOID StepCallBack)
Expand Down
88 changes: 31 additions & 57 deletions TitanEngine/TitanEngine.Debugger.DebugLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,33 @@
#define UE_MODULEx86 0x2000;
#define UE_MODULEx64 0x2000;

static void engineStep()
{
EnterCriticalSection(&engineStepActiveCr);
if (engineStepActive)
{
DBGCode = DBG_CONTINUE;
if (engineStepCount == 0)
{
typedef void(TITCALL* fCustomBreakPoint)(void);
auto cbStep = fCustomBreakPoint(engineStepCallBack);
engineStepActive = false;
engineStepCallBack = NULL;
LeaveCriticalSection(&engineStepActiveCr);
cbStep();
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
LeaveCriticalSection(&engineStepActiveCr);
}
}
else
{
LeaveCriticalSection(&engineStepActiveCr);
}
}

__declspec(dllexport) void TITCALL DebugLoop()
{
bool FirstBPX = true;
Expand Down Expand Up @@ -642,20 +669,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
EnableBPX(ResetBPXAddressTo);
ResetBPXAddressTo = NULL;
ResetBPX = false;
if(engineStepActive)
{
if(engineStepCount == 0)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineStepCallBack);
engineStepActive = false;
engineStepCallBack = NULL;
myCustomBreakPoint();
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
}
}
engineStep();
}
else
{
Expand All @@ -671,20 +685,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
{
ResetHwBPX = false;
SetHardwareBreakPoint(DebugRegisterX.DrxBreakAddress, DebugRegisterXId, DebugRegisterX.DrxBreakPointType, DebugRegisterX.DrxBreakPointSize, (LPVOID)DebugRegisterX.DrxCallBack);
if(engineStepActive)
{
if(engineStepCount == 0)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineStepCallBack);
engineStepActive = false;
engineStepCallBack = NULL;
myCustomBreakPoint();
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
}
}
engineStep();
}
if(ResetMemBPX) //restore memory breakpoint
{
Expand Down Expand Up @@ -719,20 +720,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)ResetMemBPXAddress, ResetMemBPXSize, NewProtect, &OldProtect);
}

if(engineStepActive)
{
if(engineStepCount == 0)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineStepCallBack);
engineStepActive = false;
engineStepCallBack = NULL;
myCustomBreakPoint();
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
}
}
engineStep();
}
}
else //no resetting needed (debugger reached hardware breakpoint or the user stepped)
Expand Down Expand Up @@ -867,21 +855,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
if(strstr(DisassembledString, "PUSHF"))
PushfBPX = true;
}
if(engineStepActive)
{
DBGCode = DBG_CONTINUE;
if(engineStepCount == 0)
{
myCustomBreakPoint = (fCustomBreakPoint)(engineStepCallBack);
engineStepActive = false;
engineStepCallBack = NULL;
myCustomBreakPoint();
}
else
{
SingleStep(engineStepCount, engineStepCallBack);
}
}
engineStep();
}
if(DBGCode == DBG_EXCEPTION_NOT_HANDLED) //NOTE: only call the chSingleStep callback when the debuggee generated the exception
{
Expand Down
2 changes: 2 additions & 0 deletions TitanEngine/TitanEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Global.Injector.h"
#include "Global.Engine.Extension.h"
#include "Global.Engine.Threading.h"
#include "Global.Debugger.h"

// Global.Engine.Entry:
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
Expand All @@ -13,6 +14,7 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
case DLL_PROCESS_ATTACH:
engineHandle = hinstDLL;
InitializeCriticalSection(&engineStepActiveCr);
EngineInit();
EmptyGarbage();
for(int i = 0; i < UE_MAX_RESERVED_MEMORY_LEFT; i++)
Expand Down

0 comments on commit fb1babc

Please sign in to comment.