fixed Detach and DetachAndBreak functions

This commit is contained in:
Mr. eXoDia 2016-03-11 21:43:00 +01:00
parent 2296d9ed5f
commit 0a2696b381
3 changed files with 29 additions and 30 deletions

View File

@ -25,20 +25,6 @@ namespace GleeBug
while (!mBreakDebugger) while (!mBreakDebugger)
{ {
//execute the delayed-detach
if (mDetach)
{
if (!UnsafeDetach())
cbInternalError("Debugger::Detach failed!");
break;
}
if (mDetachAndBreak)
{
if (!UnsafeDetachAndBreak())
cbInternalError("Debugger::DetachAndBreak failed!");
break;
}
//wait for a debug event //wait for a debug event
mIsRunning = true; mIsRunning = true;
if (!MyWaitForDebugEvent(&mDebugEvent, INFINITE)) if (!MyWaitForDebugEvent(&mDebugEvent, INFINITE))
@ -119,6 +105,21 @@ namespace GleeBug
//call the post debug event callback //call the post debug event callback
cbPostDebugEvent(mDebugEvent); cbPostDebugEvent(mDebugEvent);
//execute the delayed-detach
if (mDetachAndBreak)
{
if (!UnsafeDetachAndBreak())
cbInternalError("Debugger::DetachAndBreak failed!");
break;
}
//clear trap flag when set by GleeBug (to prevent an EXCEPTION_SINGLE_STEP after detach
if (mDetach && mThread)
{
if (mThread->isInternalStepping || mThread->isSingleStepping)
mThread->registers.TrapFlag = false;
}
//write the register context //write the register context
if (mThread) if (mThread)
{ {
@ -129,6 +130,13 @@ namespace GleeBug
//continue the debug event //continue the debug event
if (!ContinueDebugEvent(mDebugEvent.dwProcessId, mDebugEvent.dwThreadId, mContinueStatus)) if (!ContinueDebugEvent(mDebugEvent.dwProcessId, mDebugEvent.dwThreadId, mContinueStatus))
break; break;
if (mDetach || mDetachAndBreak)
{
if (!UnsafeDetach())
cbInternalError("Debugger::Detach failed!");
break;
}
} }
//cleanup //cleanup

View File

@ -57,6 +57,8 @@ namespace GleeBug
bool Debugger::UnsafeDetach() bool Debugger::UnsafeDetach()
{ {
mRegisters->TrapFlag = false;
mThread->RegWriteContext();
return !!DebugActiveProcessStop(mMainProcess.dwProcessId); return !!DebugActiveProcessStop(mMainProcess.dwProcessId);
} }
@ -66,22 +68,15 @@ namespace GleeBug
mDetachAndBreak = false; mDetachAndBreak = false;
} }
bool Debugger::UnsafeDetachAndBreak() //TODO check with child processes bool Debugger::UnsafeDetachAndBreak()
{ {
if (!mProcess || !mThread || !mRegisters) //fail when there is no process or thread currently specified if (!mProcess || !mThread || !mRegisters) //fail when there is no process or thread currently specified
return false; return false;
//set the trap flag to trigger an exception
auto gip = mRegisters->Gip();
auto codePtr = ptr(VirtualAllocEx(mProcess->hProcess, nullptr, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE));
unsigned char code[2] = { 0xCC, 0xC3 };
mProcess->MemWriteUnsafe(codePtr, code, sizeof(code));
mRegisters->Gsp -= sizeof(ptr); //trigger an EXCEPTION_SINGLE_STEP in the debuggee
mProcess->MemWriteUnsafe(mRegisters->Gsp(), &gip, sizeof(gip)); mRegisters->TrapFlag = true;
mRegisters->Gip = codePtr;
mThread->RegWriteContext(); mThread->RegWriteContext();
//detach from the process //detach from the process
return UnsafeDetach(); return UnsafeDetach();
} }
@ -90,9 +85,5 @@ namespace GleeBug
{ {
mDetachAndBreak = true; mDetachAndBreak = true;
mDetach = false; mDetach = false;
//unset the trap flag when set by GleeBug
if (mThread->isInternalStepping || mThread->isSingleStepping)
mRegisters->TrapFlag = false;
} }
}; };

@ -1 +1 @@
Subproject commit 5a37f7cfaf4a1b1050890c244348fa6f7cfd109b Subproject commit 28919b6b84f2e1b162365ae3699833097fc64864