DBG: implement DLL breakpoints directly in x64dbg
This commit is contained in:
parent
a514176750
commit
0762182973
|
@ -898,7 +898,7 @@ static bool cbDeleteAllDllBreakpoints(const BREAKPOINT* bp)
|
|||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not delete DLL breakpoint %s (BpDelete)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(bp->mod, bp->titantype))
|
||||
if(!dbgdeletedllbreakpoint(bp->mod, bp->titantype))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not delete DLL breakpoint %s (LibrarianRemoveBreakPoint)\n"), bp->mod);
|
||||
return false;
|
||||
|
@ -916,7 +916,7 @@ static bool cbEnableAllDllBreakpoints(const BREAKPOINT* bp)
|
|||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianSetBreakPoint(bp->mod, bp->titantype, bp->singleshoot, (void*)cbLibrarianBreakpoint))
|
||||
if(!dbgsetdllbreakpoint(bp->mod, bp->titantype, bp->singleshoot))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), bp->mod);
|
||||
return false;
|
||||
|
@ -934,7 +934,7 @@ static bool cbDisableAllDllBreakpoints(const BREAKPOINT* bp)
|
|||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (BpEnable)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(bp->mod, bp->titantype))
|
||||
if(!dbgdeletedllbreakpoint(bp->mod, bp->titantype))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (LibrarianRemoveBreakPoint)\n"), bp->mod);
|
||||
return false;
|
||||
|
@ -946,6 +946,7 @@ bool cbDebugBpDll(int argc, char* argv[])
|
|||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return false;
|
||||
_strlwr_s(argv[1], strlen(argv[1]) + 1); //NOTE: does not really work on unicode strings
|
||||
DWORD type = UE_ON_LIB_ALL;
|
||||
if(argc > 2)
|
||||
{
|
||||
|
@ -967,7 +968,7 @@ bool cbDebugBpDll(int argc, char* argv[])
|
|||
dputs(QT_TRANSLATE_NOOP("DBG", "Error creating Dll breakpoint! (BpNewDll)"));
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianSetBreakPoint(argv[1], type, singleshoot, (void*)cbLibrarianBreakpoint))
|
||||
if(!dbgsetdllbreakpoint(argv[1], type, singleshoot))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error creating Dll breakpoint! (LibrarianSetBreakPoint)"));
|
||||
return false;
|
||||
|
@ -993,6 +994,7 @@ bool cbDebugBcDll(int argc, char* argv[])
|
|||
DebugUpdateBreakpointsViewAsync();
|
||||
return true;
|
||||
}
|
||||
_strlwr_s(argv[1], strlen(argv[1]) + 1); //NOTE: does not really work on unicode strings
|
||||
BREAKPOINT bp;
|
||||
if(!BpGetAny(BPDLL, argv[1], &bp))
|
||||
return false;
|
||||
|
@ -1001,7 +1003,7 @@ bool cbDebugBcDll(int argc, char* argv[])
|
|||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to remove DLL breakpoint..."));
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(bp.mod, bp.titantype))
|
||||
if(!dbgdeletedllbreakpoint(bp.mod, bp.titantype))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to remove DLL breakpoint..."));
|
||||
return false;
|
||||
|
@ -1026,6 +1028,7 @@ bool cbDebugBpDllEnable(int argc, char* argv[])
|
|||
GuiUpdateAllViews();
|
||||
return true;
|
||||
}
|
||||
_strlwr_s(argv[1], strlen(argv[1]) + 1); //NOTE: does not really work on unicode strings
|
||||
BREAKPOINT found;
|
||||
duint addr = 0;
|
||||
if(!BpGetAny(BPDLL, argv[1], &found)) //invalid DLL breakpoint
|
||||
|
@ -1043,7 +1046,7 @@ bool cbDebugBpDllEnable(int argc, char* argv[])
|
|||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), found.mod);
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianSetBreakPoint(found.mod, found.titantype, found.singleshoot, (void*)cbLibrarianBreakpoint))
|
||||
if(!dbgsetdllbreakpoint(found.mod, found.titantype, found.singleshoot))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), found.mod);
|
||||
}
|
||||
|
@ -1067,6 +1070,7 @@ bool cbDebugBpDllDisable(int argc, char* argv[])
|
|||
GuiUpdateAllViews();
|
||||
return true;
|
||||
}
|
||||
_strlwr_s(argv[1], strlen(argv[1]) + 1); //NOTE: does not really work on unicode strings
|
||||
BREAKPOINT found;
|
||||
duint addr = 0;
|
||||
if(!BpGetAny(BPDLL, argv[1], &found)) //invalid DLL breakpoint
|
||||
|
@ -1084,7 +1088,7 @@ bool cbDebugBpDllDisable(int argc, char* argv[])
|
|||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (BpEnable)\n"), found.mod);
|
||||
return false;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(found.mod, found.titantype))
|
||||
if(!dbgdeletedllbreakpoint(found.mod, found.titantype))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (LibrarianRemoveBreakPoint)\n"), found.mod);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ static bool isDetachedByUser = false;
|
|||
static bool bIsAttached = false;
|
||||
static bool bSkipExceptions = false;
|
||||
static duint skipExceptionCount = 0;
|
||||
static bool bBreakOnNextDll = false;
|
||||
static bool bFreezeStack = false;
|
||||
static std::vector<ExceptionRange> ignoredExceptionRange;
|
||||
static HANDLE hEvent = 0;
|
||||
|
@ -386,6 +385,39 @@ void dbgtracebrowserneedsupdate()
|
|||
bTraceBrowserNeedsUpdate = true;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, std::pair<DWORD, bool>> dllBreakpoints;
|
||||
|
||||
bool dbgsetdllbreakpoint(const char* mod, DWORD type, bool singleshoot)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockDllBreakpoints);
|
||||
return dllBreakpoints.insert({ mod, { type, singleshoot } }).second;
|
||||
}
|
||||
|
||||
bool dbgdeletedllbreakpoint(const char* mod, DWORD type)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockDllBreakpoints);
|
||||
auto found = dllBreakpoints.find(mod);
|
||||
if(found == dllBreakpoints.end())
|
||||
return false;
|
||||
dllBreakpoints.erase(found);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dbghandledllbreakpoint(const char* mod, bool loadDll)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockDllBreakpoints);
|
||||
auto shouldBreak = false;
|
||||
auto found = dllBreakpoints.find(mod);
|
||||
if(found != dllBreakpoints.end())
|
||||
{
|
||||
if(found->second.first == UE_ON_LIB_ALL || found->second.first == (loadDll ? UE_ON_LIB_LOAD : UE_ON_LIB_UNLOAD))
|
||||
shouldBreak = true;
|
||||
if(found->second.second)
|
||||
dllBreakpoints.erase(found);
|
||||
}
|
||||
return shouldBreak;
|
||||
}
|
||||
|
||||
static DWORD WINAPI updateCallStackThread(duint ptr)
|
||||
{
|
||||
stackupdatecallstack(ptr);
|
||||
|
@ -920,11 +952,6 @@ void cbRunToUserCodeBreakpoint(void* ExceptionAddress)
|
|||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
void cbLibrarianBreakpoint(void* lpData)
|
||||
{
|
||||
bBreakOnNextDll = true;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK SymRegisterCallbackProc64(HANDLE, ULONG ActionCode, ULONG64 CallbackData, ULONG64)
|
||||
{
|
||||
PIMAGEHLP_CBA_EVENT evt;
|
||||
|
@ -1060,8 +1087,7 @@ bool cbSetDLLBreakpoints(const BREAKPOINT* bp)
|
|||
return true;
|
||||
if(bp->type != BPDLL)
|
||||
return true;
|
||||
dputs("debug:dll breakpoint in database\n");
|
||||
LibrarianSetBreakPoint(bp->mod, bp->titantype, bp->singleshoot, (void*)cbLibrarianBreakpoint);
|
||||
dbgsetdllbreakpoint(bp->mod, bp->titantype, bp->singleshoot);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1674,7 +1700,9 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
}
|
||||
}
|
||||
|
||||
if((bBreakOnNextDll || settingboolget("Events", "DllEntry")) && !bAlreadySetEntry)
|
||||
auto breakOnDll = dbghandledllbreakpoint(modname, true);
|
||||
|
||||
if((breakOnDll || settingboolget("Events", "DllEntry")) && !bAlreadySetEntry)
|
||||
{
|
||||
auto entry = ModEntryFromAddr(duint(base));
|
||||
if(entry)
|
||||
|
@ -1722,9 +1750,8 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
callbackInfo.modname = modname;
|
||||
plugincbcall(CB_LOADDLL, &callbackInfo);
|
||||
|
||||
if(bBreakOnNextDll)
|
||||
if(breakOnDll)
|
||||
{
|
||||
bBreakOnNextDll = false;
|
||||
cbGenericBreakpoint(BPDLL, DLLDebugFileName);
|
||||
}
|
||||
else if(settingboolget("Events", "DllLoad"))
|
||||
|
@ -1756,9 +1783,8 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
|||
SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Unloaded: %p %s\n"), base, modname);
|
||||
|
||||
if(bBreakOnNextDll)
|
||||
if(dbghandledllbreakpoint(modname, false))
|
||||
{
|
||||
bBreakOnNextDll = false;
|
||||
cbGenericBreakpoint(BPDLL, modname);
|
||||
}
|
||||
else if(settingboolget("Events", "DllUnload"))
|
||||
|
@ -2534,7 +2560,6 @@ static void debugLoopFunction(void* lpParameter, bool attach)
|
|||
//initialize variables
|
||||
bIsAttached = attach;
|
||||
dbgsetskipexceptions(false);
|
||||
bBreakOnNextDll = false;
|
||||
bFreezeStack = false;
|
||||
|
||||
//prepare attach/createprocess
|
||||
|
@ -2711,12 +2736,10 @@ static void debugLoopFunction(void* lpParameter, bool attach)
|
|||
|
||||
//message the user/do final stuff
|
||||
RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints
|
||||
BpEnumAll([](const BREAKPOINT * bp) //RemoveAllBreakPoints doesn't remove librarian breakpoints
|
||||
{
|
||||
if(bp->type == BPDLL)
|
||||
LibrarianRemoveBreakPoint(bp->mod, bp->titantype);
|
||||
return true;
|
||||
});
|
||||
EXCLUSIVE_ACQUIRE(LockDllBreakpoints);
|
||||
dllBreakpoints.clear(); //RemoveAllBreakPoints doesn't remove librarian breakpoints
|
||||
}
|
||||
|
||||
//cleanup
|
||||
dbgcleartracestate();
|
||||
|
|
|
@ -79,6 +79,8 @@ const char* dbggetdebuggeeinitscript();
|
|||
void dbgsetforeground();
|
||||
bool dbggetwintext(std::vector<std::string>* winTextList, const DWORD dwProcessId);
|
||||
void dbgtracebrowserneedsupdate();
|
||||
bool dbgsetdllbreakpoint(const char* mod, DWORD type, bool singleshoot);
|
||||
bool dbgdeletedllbreakpoint(const char* mod, DWORD type);
|
||||
|
||||
void cbStep();
|
||||
void cbRtrStep();
|
||||
|
@ -88,7 +90,6 @@ void cbMemoryBreakpoint(void* ExceptionAddress);
|
|||
void cbHardwareBreakpoint(void* ExceptionAddress);
|
||||
void cbUserBreakpoint();
|
||||
void cbDebugLoadLibBPX();
|
||||
void cbLibrarianBreakpoint(void* lpData);
|
||||
DWORD WINAPI threadDebugLoop(void* lpParameter);
|
||||
void cbTraceOverConditionalStep();
|
||||
void cbTraceIntoConditionalStep();
|
||||
|
|
|
@ -73,6 +73,7 @@ enum SectionLock
|
|||
LockTypeManager,
|
||||
LockModuleHashes,
|
||||
LockFormatFunctions,
|
||||
LockDllBreakpoints,
|
||||
|
||||
// Number of elements in this enumeration. Must always be the last index.
|
||||
LockLast
|
||||
|
|
Loading…
Reference in New Issue