mirror of https://github.com/x64dbg/TitanEngine
Remove a redundant GetThreadContext for synchronized breakpoints
This commit is contained in:
parent
8d833fb2e3
commit
d0b7e5addd
|
|
@ -8,6 +8,7 @@
|
|||
#include "Global.Threader.h"
|
||||
#include "Global.Librarian.h"
|
||||
#include "Global.TLS.h"
|
||||
#include <unordered_map>
|
||||
|
||||
#define UE_MODULEx86 0x2000;
|
||||
#define UE_MODULEx64 0x2000;
|
||||
|
|
@ -67,7 +68,6 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
ULONG_PTR NumberOfBytesReadWritten = 0;
|
||||
MEMORY_BASIC_INFORMATION MemInfo;
|
||||
HANDLE hActiveThread;
|
||||
CONTEXT myDBGContext;
|
||||
DWORD OldProtect;
|
||||
DWORD NewProtect;
|
||||
DWORD DebugRegisterXId = NULL;
|
||||
|
|
@ -80,7 +80,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
wchar_t* szTranslatedNativeName;
|
||||
|
||||
DWORD ThreadBeingProcessed = 0;
|
||||
std::vector<THREAD_ITEM_DATA> SuspendedThreads;
|
||||
std::unordered_map<DWORD, THREAD_ITEM_DATA> SuspendedThreads;
|
||||
bool IsDbgReplyLaterSupported = false;
|
||||
|
||||
// Check if DBG_REPLY_LATER is supported based on Windows version (Windows 10, version 1507 or above)
|
||||
|
|
@ -112,6 +112,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
|
||||
while(!BreakDBG) //actual debug loop
|
||||
{
|
||||
bool synchronizedStep = false;
|
||||
// Fix based on work by https://github.com/number201724
|
||||
if(!WaitForDebugEvent(&DBGEvent, 100))
|
||||
{
|
||||
|
|
@ -154,8 +155,8 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(ThreadBeingProcessed != 0 && DBGEvent.dwThreadId == ThreadBeingProcessed)
|
||||
{
|
||||
// Resume the other threads since the thread being processed is exiting
|
||||
for(auto & Thread : SuspendedThreads)
|
||||
ResumeThread(Thread.hThread);
|
||||
for(auto & itr : SuspendedThreads)
|
||||
ResumeThread(itr.second.hThread);
|
||||
|
||||
SuspendedThreads.clear();
|
||||
ThreadBeingProcessed = 0;
|
||||
|
|
@ -552,10 +553,14 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
FlushInstructionCache(dbgProcessInformation.hProcess, NULL, 0);
|
||||
DBGCode = DBG_CONTINUE;
|
||||
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||
CONTEXT myDBGContext;
|
||||
myDBGContext.ContextFlags = ContextControlFlags;
|
||||
GetThreadContext(hActiveThread, &myDBGContext);
|
||||
if (FoundBreakPoint.BreakPointType != UE_SINGLESHOOT)
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
}
|
||||
#if defined(_WIN64)
|
||||
myDBGContext.Rip = myDBGContext.Rip - FoundBreakPoint.BreakPointSize;
|
||||
#else
|
||||
|
|
@ -642,8 +647,8 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(IsDbgReplyLaterSupported)
|
||||
{
|
||||
// Resume the other threads since we are done processing the single step
|
||||
for(auto & Thread : SuspendedThreads)
|
||||
ResumeThread(Thread.hThread);
|
||||
for(auto & itr : SuspendedThreads)
|
||||
ResumeThread(itr.second.hThread);
|
||||
|
||||
SuspendedThreads.clear();
|
||||
ThreadBeingProcessed = 0;
|
||||
|
|
@ -672,15 +677,19 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
engineStep();
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||
CONTEXT myDBGContext;
|
||||
myDBGContext.ContextFlags = ContextControlFlags;
|
||||
GetThreadContext(hActiveThread, &myDBGContext);
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
EngineCloseHandle(hActiveThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ResetHwBPX) //restore hardware breakpoint
|
||||
{
|
||||
ResetHwBPX = false;
|
||||
|
|
@ -727,6 +736,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
{
|
||||
//handle hardware breakpoints
|
||||
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||
CONTEXT myDBGContext;
|
||||
myDBGContext.ContextFlags = CONTEXT_DEBUG_REGISTERS | ContextControlFlags;
|
||||
GetThreadContext(hActiveThread, &myDBGContext);
|
||||
if((ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress == myDBGContext.Dr0 || (myDBGContext.Dr6 & 0x1))
|
||||
|
|
@ -734,8 +744,11 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(DebugRegister[0].DrxEnabled)
|
||||
{
|
||||
DBGCode = DBG_CONTINUE;
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
myCustomHandler = (fCustomHandler)(DebugRegister[0].DrxCallBack);
|
||||
myCustomHandler((void*)myDBGContext.Dr0);
|
||||
if(DebugRegister[0].DrxEnabled)
|
||||
|
|
@ -762,8 +775,11 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(DebugRegister[1].DrxEnabled)
|
||||
{
|
||||
DBGCode = DBG_CONTINUE;
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
myCustomHandler = (fCustomHandler)(DebugRegister[1].DrxCallBack);
|
||||
myCustomHandler((void*)myDBGContext.Dr1);
|
||||
if(DebugRegister[1].DrxEnabled)
|
||||
|
|
@ -790,8 +806,11 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(DebugRegister[2].DrxEnabled)
|
||||
{
|
||||
DBGCode = DBG_CONTINUE;
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
myCustomHandler = (fCustomHandler)(DebugRegister[2].DrxCallBack);
|
||||
myCustomHandler((void*)myDBGContext.Dr2);
|
||||
if(DebugRegister[2].DrxEnabled)
|
||||
|
|
@ -818,8 +837,11 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(DebugRegister[3].DrxEnabled)
|
||||
{
|
||||
DBGCode = DBG_CONTINUE;
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
myCustomHandler = (fCustomHandler)(DebugRegister[3].DrxCallBack);
|
||||
myCustomHandler((void*)myDBGContext.Dr3);
|
||||
if(DebugRegister[3].DrxEnabled)
|
||||
|
|
@ -893,6 +915,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(bFoundBreakPoint) //found memory breakpoint
|
||||
{
|
||||
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||
CONTEXT myDBGContext;
|
||||
myDBGContext.ContextFlags = ContextControlFlags;
|
||||
GetThreadContext(hActiveThread, &myDBGContext);
|
||||
DBGCode = DBG_CONTINUE; //debugger handled the exception
|
||||
|
|
@ -904,9 +927,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -922,9 +948,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||
}
|
||||
else //restore the memory breakpoint
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -935,9 +964,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
myCustomHandler((void*)bpaddr);
|
||||
}
|
||||
else //no read operation, restore breakpoint
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -951,9 +983,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||
}
|
||||
else //restore breakpoint after trap flag
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -964,9 +999,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
myCustomHandler((void*)bpaddr);
|
||||
}
|
||||
else //no write operation, restore breakpoint
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -981,9 +1019,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -995,9 +1036,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
myCustomHandler((void*)bpaddr);
|
||||
}
|
||||
else //no execute operation, restore breakpoint
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -1062,6 +1106,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(bFoundBreakPoint && engineMembpAlt) //found memory breakpoint
|
||||
{
|
||||
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||
CONTEXT myDBGContext;
|
||||
myDBGContext.ContextFlags = ContextControlFlags;
|
||||
GetThreadContext(hActiveThread, &myDBGContext);
|
||||
DBGCode = DBG_CONTINUE; //debugger handled the exception
|
||||
|
|
@ -1074,9 +1119,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -1092,9 +1140,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||
}
|
||||
else //restore the memory breakpoint
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -1104,9 +1155,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
bCallCustomHandler = true;
|
||||
}
|
||||
else //no read operation, restore breakpoint
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -1120,9 +1174,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||
}
|
||||
else //restore breakpoint after trap flag
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -1132,9 +1189,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
bCallCustomHandler = true;
|
||||
}
|
||||
else //no write operation, restore breakpoint
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -1149,9 +1209,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
RemoveMemoryBPX(FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -1162,9 +1225,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
bCallCustomHandler = true;
|
||||
}
|
||||
else //no execute operation, restore breakpoint
|
||||
{
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
}
|
||||
ResetMemBPXAddress = FoundBreakPoint.BreakPointAddress;
|
||||
ResetMemBPXSize = FoundBreakPoint.BreakPointSize;
|
||||
ResetMemBPX = true;
|
||||
|
|
@ -1238,13 +1304,21 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
{
|
||||
FlushInstructionCache(dbgProcessInformation.hProcess, NULL, 0);
|
||||
DBGCode = DBG_CONTINUE;
|
||||
|
||||
{
|
||||
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||
CONTEXT myDBGContext;
|
||||
myDBGContext.ContextFlags = ContextControlFlags;
|
||||
GetThreadContext(hActiveThread, &myDBGContext);
|
||||
if (FoundBreakPoint.BreakPointType != UE_SINGLESHOOT)
|
||||
{
|
||||
myDBGContext.EFlags |= UE_TRAP_FLAG;
|
||||
synchronizedStep = true;
|
||||
}
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
EngineCloseHandle(hActiveThread);
|
||||
}
|
||||
|
||||
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)FoundBreakPoint.BreakPointAddress, FoundBreakPoint.BreakPointSize, OldProtect, &OldProtect);
|
||||
|
||||
if(FoundBreakPoint.BreakPointType == UE_SINGLESHOOT)
|
||||
|
|
@ -1398,31 +1472,26 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
|
||||
if(IsDbgReplyLaterSupported && DBGEvent.dwDebugEventCode != EXIT_THREAD_DEBUG_EVENT)
|
||||
{
|
||||
CONTEXT DbgCtx;
|
||||
|
||||
DbgCtx.ContextFlags = ContextControlFlags;
|
||||
|
||||
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||
|
||||
if(hActiveThread != NULL)
|
||||
{
|
||||
// If TF is set (single step), then suspend all the other threads
|
||||
if(GetThreadContext(hActiveThread, &DbgCtx) && (DbgCtx.EFlags & UE_TRAP_FLAG))
|
||||
if(synchronizedStep)
|
||||
{
|
||||
ThreadBeingProcessed = DBGEvent.dwThreadId;
|
||||
|
||||
for(auto & Thread : hListThread)
|
||||
{
|
||||
// Do not suspend the current thread
|
||||
if(ThreadBeingProcessed == Thread.dwThreadId)
|
||||
continue;
|
||||
|
||||
// Check if the thread is already suspended
|
||||
for(auto & SuspendedThread : SuspendedThreads)
|
||||
if(SuspendedThread.dwThreadId == Thread.dwThreadId)
|
||||
if (SuspendedThreads.count(Thread.dwThreadId) != 0)
|
||||
continue;
|
||||
|
||||
if (SuspendThread(Thread.hThread) != -1)
|
||||
SuspendedThreads.push_back(Thread);
|
||||
SuspendedThreads.emplace(Thread.dwThreadId, Thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue