mirror of https://github.com/x64dbg/GleeBug
Port the fixes from https://github.com/x64dbg/TitanEngine/pull/14
This commit is contained in:
parent
a9a339ad45
commit
37b6606d58
|
|
@ -31,12 +31,12 @@ namespace GleeBug
|
|||
|
||||
//restore the original breakpoint byte and do an internal step
|
||||
mProcess->MemWriteUnsafe(info.address, info.internal.software.oldbytes, info.internal.software.size);
|
||||
mThread->StepInternal(std::bind([this, info]()
|
||||
mProcess->StepInternal([this, info]()
|
||||
{
|
||||
//only restore the bytes if the breakpoint still exists
|
||||
if(mProcess->breakpoints.find({ BreakpointType::Software, info.address }) != mProcess->breakpoints.end())
|
||||
mProcess->MemWriteUnsafe(info.address, info.internal.software.newbytes, info.internal.software.size);
|
||||
}));
|
||||
});
|
||||
|
||||
//call the generic callback
|
||||
cbBreakpoint(info);
|
||||
|
|
@ -126,12 +126,12 @@ namespace GleeBug
|
|||
|
||||
//delete the hardware breakpoint from the thread (not the breakpoint buffer) and do an internal step (TODO: maybe delete from all threads?)
|
||||
mThread->DeleteHardwareBreakpoint(breakpointSlot);
|
||||
mThread->StepInternal(std::bind([this, info]()
|
||||
mProcess->StepInternal([this, info]()
|
||||
{
|
||||
//only restore if the breakpoint still exists
|
||||
if(mProcess->breakpoints.find({ BreakpointType::Hardware, info.address }) != mProcess->breakpoints.end())
|
||||
mThread->SetHardwareBreakpoint(info.address, info.internal.hardware.slot, info.internal.hardware.type, info.internal.hardware.size);
|
||||
}));
|
||||
});
|
||||
|
||||
//call the generic callback
|
||||
cbBreakpoint(info);
|
||||
|
|
@ -182,7 +182,7 @@ namespace GleeBug
|
|||
// -add more memory breakpoints
|
||||
//The solution: We just try to see if the page is mapped into memoryBreakpointPages. If the page is in deed being used by any memory breakpoint,
|
||||
// then we ought to restore the protection.
|
||||
mThread->StepInternal(std::bind([this, pBaseAddr]()
|
||||
mProcess->StepInternal([this, pBaseAddr]()
|
||||
{
|
||||
//seek out the page address
|
||||
auto found_page = mProcess->memoryBreakpointPages.find(pBaseAddr);
|
||||
|
|
@ -193,7 +193,7 @@ namespace GleeBug
|
|||
}
|
||||
mProcess->MemProtect(pBaseAddr, PAGE_SIZE, found_page->second.NewProtect);
|
||||
return;
|
||||
}));
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ namespace GleeBug
|
|||
cbInternalError(error);
|
||||
}
|
||||
|
||||
mThread->StepInternal(std::bind([this, pageAddr]()
|
||||
mProcess->StepInternal([this, pageAddr]()
|
||||
{
|
||||
//seek out the page address
|
||||
auto found_page = mProcess->memoryBreakpointPages.find(pageAddr);
|
||||
|
|
@ -254,7 +254,7 @@ namespace GleeBug
|
|||
}
|
||||
mProcess->MemProtect(pageAddr, PAGE_SIZE, found_page->second.NewProtect);
|
||||
return;
|
||||
}));
|
||||
});
|
||||
return;
|
||||
}
|
||||
else if(((pageProperties.Type & 0x1) != 0))
|
||||
|
|
@ -306,7 +306,7 @@ namespace GleeBug
|
|||
cbInternalError(error);
|
||||
}
|
||||
//Pass info as well
|
||||
mThread->StepInternal(std::bind([this, pageAddr]()
|
||||
mProcess->StepInternal([this, pageAddr]()
|
||||
{
|
||||
//With page check this should work better: So when we reach this part of the code we are sure that:
|
||||
//-The exception Address In deed corresponded to an existing (now possibly deleted) memory breakpoint range
|
||||
|
|
@ -327,7 +327,7 @@ namespace GleeBug
|
|||
mProcess->MemProtect(pageAddr, PAGE_SIZE, found_page->second.NewProtect);
|
||||
}
|
||||
return;
|
||||
}));
|
||||
});
|
||||
|
||||
if(info.singleshoot)
|
||||
{
|
||||
|
|
@ -373,7 +373,7 @@ namespace GleeBug
|
|||
// -add more memory breakpoints
|
||||
//The solution: We just try to see if the page is mapped into memoryBreakpointPages. If the page is in deed being used by any memory breakpoint,
|
||||
// then we ought to restore the protection.
|
||||
mThread->StepInternal(std::bind([this, pBaseAddr]()
|
||||
mProcess->StepInternal([this, pBaseAddr]()
|
||||
{
|
||||
//seek out the page address
|
||||
auto found_page = mProcess->memoryBreakpointPages.find(pBaseAddr);
|
||||
|
|
@ -384,7 +384,7 @@ namespace GleeBug
|
|||
}
|
||||
mProcess->MemProtect(pBaseAddr, PAGE_SIZE, found_page->second.NewProtect);
|
||||
return;
|
||||
}));
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -462,7 +462,7 @@ namespace GleeBug
|
|||
cbInternalError(error);
|
||||
}
|
||||
//Pass info as well
|
||||
mThread->StepInternal(std::bind([this, pageAddr]()
|
||||
mProcess->StepInternal([this, pageAddr]()
|
||||
{
|
||||
//With page check this should work better: So when we reach this part of the code we are sure that:
|
||||
//-The exception Address In deed corresponded to an existing (now possibly deleted) memory breakpoint range
|
||||
|
|
@ -483,7 +483,7 @@ namespace GleeBug
|
|||
mProcess->MemProtect(pageAddr, PAGE_SIZE, found_page->second.NewProtect);
|
||||
}
|
||||
return;
|
||||
}));
|
||||
});
|
||||
|
||||
if(info.singleshoot)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -101,14 +101,62 @@ namespace GleeBug
|
|||
}
|
||||
thread->StepInto(cbStep);
|
||||
}
|
||||
|
||||
void Process::StepInternal(const StepCallback & cbStep)
|
||||
{
|
||||
SetBreakpoint(gip + info.length, [cbStep](const BreakpointInfo & info)
|
||||
Registers registers(thread->hThread, CONTEXT_CONTROL);
|
||||
registers.TrapFlag.Set();
|
||||
thread->isInternalStepping = true;
|
||||
|
||||
// Check if we're currently stepping on a pushf instruction
|
||||
auto isPushf = false;
|
||||
{
|
||||
auto gip = registers.Gip();
|
||||
unsigned char data[16];
|
||||
if(MemReadSafe(gip, data, sizeof(data)))
|
||||
{
|
||||
ZydisDisassembledInstruction instruction;
|
||||
if(ZYAN_SUCCESS(ZydisDisassembleIntel(
|
||||
GleeArchValue(ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_MACHINE_MODE_LONG_COMPAT_32),
|
||||
gip,
|
||||
data,
|
||||
sizeof(data),
|
||||
&instruction
|
||||
)))
|
||||
{
|
||||
switch(instruction.info.mnemonic)
|
||||
{
|
||||
case ZYDIS_MNEMONIC_PUSHF:
|
||||
case ZYDIS_MNEMONIC_PUSHFD:
|
||||
case ZYDIS_MNEMONIC_PUSHFQ:
|
||||
isPushf = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isPushf)
|
||||
{
|
||||
thread->cbInternalStep = [this, cbStep]()
|
||||
{
|
||||
// Remove the trap flag from the stack
|
||||
auto gsp = Registers(this->thread->hThread).Gsp();
|
||||
GleeBug::ptr data;
|
||||
if(MemReadUnsafe(gsp, &data, sizeof(data)))
|
||||
{
|
||||
data &= ~(int)Registers::F::Trap;
|
||||
MemWriteUnsafe(gsp, &data, sizeof(data));
|
||||
}
|
||||
|
||||
cbStep();
|
||||
}, true, SoftwareType::ShortInt3);
|
||||
return;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
thread->cbInternalStep = cbStep;
|
||||
}
|
||||
thread->StepInto(cbStep);
|
||||
}
|
||||
};
|
||||
|
|
@ -396,6 +396,25 @@ namespace GleeBug
|
|||
static_cast<void>(static_cast<Debugger*>(debugger));
|
||||
StepOver(std::bind(callback, debugger));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Perform an internal step (not reported to the outside)
|
||||
\param cbStep Step callback. Can be written using BIND(this, MyDebugger::cb).
|
||||
*/
|
||||
void StepInternal(const StepCallback & cbStep);
|
||||
|
||||
/**
|
||||
\brief Perform an internal step (not reported to the outside)
|
||||
\tparam T Generic type parameter. Must be a subclass of Debugger.
|
||||
\param debugger This pointer to a subclass of Debugger.
|
||||
\param callback Pointer to the callback. Written like: &MyDebugger::cb
|
||||
*/
|
||||
template<typename T>
|
||||
void StepInternal(T* debugger, void(T::*callback)())
|
||||
{
|
||||
static_cast<void>(static_cast<Debugger*>(debugger));
|
||||
StepInternal(std::bind(callback, debugger));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,13 +36,6 @@ namespace GleeBug
|
|||
stepCallbacks.push_back(cbStep);
|
||||
}
|
||||
|
||||
void Thread::StepInternal(const StepCallback & cbStep)
|
||||
{
|
||||
Registers(hThread).TrapFlag.Set();
|
||||
isInternalStepping = true;
|
||||
cbInternalStep = cbStep;
|
||||
}
|
||||
|
||||
bool Thread::Suspend()
|
||||
{
|
||||
return SuspendThread(hThread) != -1;
|
||||
|
|
|
|||
|
|
@ -60,25 +60,6 @@ namespace GleeBug
|
|||
StepInto(std::bind(callback, debugger));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Perform an internal step (not reported to the outside)
|
||||
\param cbStep Step callback. Can be written using BIND(this, MyDebugger::cb).
|
||||
*/
|
||||
void StepInternal(const StepCallback & cbStep);
|
||||
|
||||
/**
|
||||
\brief Perform an internal step (not reported to the outside)
|
||||
\tparam T Generic type parameter. Must be a subclass of Debugger.
|
||||
\param debugger This pointer to a subclass of Debugger.
|
||||
\param callback Pointer to the callback. Written like: &MyDebugger::cb
|
||||
*/
|
||||
template<typename T>
|
||||
void StepInternal(T* debugger, void(T::*callback)())
|
||||
{
|
||||
static_cast<void>(static_cast<Debugger*>(debugger));
|
||||
StepInternal(std::bind(callback, debugger));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Sets a hardware breakpoint.
|
||||
\param address The address to set the hardware breakpoint on.
|
||||
|
|
|
|||
Loading…
Reference in New Issue