added 'DetachAndBreak' function

This commit is contained in:
Mr. eXoDia 2016-02-11 16:49:45 +01:00
parent 8652a6aa66
commit 4b7be626fa
4 changed files with 81 additions and 4 deletions

View File

@ -7,6 +7,8 @@ namespace GleeBug
//initialize loop variables //initialize loop variables
mBreakDebugger = false; mBreakDebugger = false;
mIsDebugging = true; mIsDebugging = true;
mDetach = false;
mDetachAndBreak = false;
//use correct WaitForDebugEvent function //use correct WaitForDebugEvent function
typedef BOOL(WINAPI *MYWAITFORDEBUGEVENT)( typedef BOOL(WINAPI *MYWAITFORDEBUGEVENT)(
@ -23,6 +25,20 @@ 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))
@ -63,7 +79,7 @@ namespace GleeBug
} }
//call the pre debug event callback //call the pre debug event callback
cbPostDebugEvent(mDebugEvent); cbPreDebugEvent(mDebugEvent);
//dispatch the debug event (documented here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms679302(v=vs.85).aspx) //dispatch the debug event (documented here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms679302(v=vs.85).aspx)
switch (mDebugEvent.dwDebugEventCode) switch (mDebugEvent.dwDebugEventCode)

View File

@ -57,8 +57,50 @@ namespace GleeBug
return !!TerminateProcess(mMainProcess.hProcess, 0); return !!TerminateProcess(mMainProcess.hProcess, 0);
} }
bool Debugger::Detach() const bool Debugger::UnsafeDetach()
{ {
return !!DebugActiveProcessStop(mMainProcess.dwProcessId); return !!DebugActiveProcessStop(mMainProcess.dwProcessId);
} }
void Debugger::Detach()
{
mDetach = true;
mDetachAndBreak = false;
}
bool Debugger::UnsafeDetachAndBreak() //TODO check with child processes
{
if (!mProcess || !mThread || !mRegisters) //fail when there is no process or thread currently specified
return false;
//write the code that breaks the process
auto codePtr = ptr(VirtualAllocEx(mProcess->hProcess, nullptr, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE));
if (!codePtr)
{
cbInternalError("Debugger::UnsafeDetachAndBreak, VirtualAllocEx failed!");
return false;
}
uint8 code[] = { 0xCC, 0xC3 };
mProcess->MemWriteUnsafe(codePtr, code, sizeof(code));
//push the return address (current GIP) on the stack
mRegisters->Gsp -= sizeof(ptr);
auto gip = mRegisters->Gip();
mProcess->MemWriteUnsafe(mRegisters->Gsp(), &gip, sizeof(gip));
//change the GIP to the code
mRegisters->Gip = codePtr;
//flush the register cache (needed here explicitly because control will be out of the debugger after this).
mThread->RegWriteContext();
//detach from the process
return UnsafeDetach();
}
void Debugger::DetachAndBreak()
{
mDetachAndBreak = true;
mDetach = false;
}
}; };

View File

@ -45,7 +45,23 @@ namespace GleeBug
\brief Detaches the debuggee. \brief Detaches the debuggee.
\return true if the debuggee was detached correctly, false otherwise. \return true if the debuggee was detached correctly, false otherwise.
*/ */
bool Detach() const; bool UnsafeDetach();
/**
\brief Detaches the debuggee. The detach happens at the end of the debug loop.
*/
void Detach();
/**
\brief Detaches the debuggee and breaks with an INT3 (to invoke the JIT debugger).
\return true if the debuggee was detached correctly, false otherwise.
*/
bool UnsafeDetachAndBreak();
/**
\brief Detaches the debuggee and breaks with an INT3 (to invoke the JIT debugger). The detach happens at the end of the debug loop.
*/
void DetachAndBreak();
/** /**
\brief Run the debug loop (does not return until the debuggee is detached or terminated). This function should be run from the same thread as you ran Init. \brief Run the debug loop (does not return until the debuggee is detached or terminated). This function should be run from the same thread as you ran Init.
@ -251,6 +267,8 @@ namespace GleeBug
ProcessMap mProcesses; ProcessMap mProcesses;
bool mIsRunning = false; bool mIsRunning = false;
bool mIsDebugging = false; bool mIsDebugging = false;
bool mDetach = false;
bool mDetachAndBreak = false;
Capstone mCapstone; Capstone mCapstone;
/** /**

View File

@ -34,7 +34,8 @@ public:
bool DetachDebuggerEx(DWORD ProcessId) bool DetachDebuggerEx(DWORD ProcessId)
{ {
//TODO //TODO
return Detach(); Detach();
return true;
} }
void DebugLoop() void DebugLoop()