push and pop actions
This commit is contained in:
parent
ba08bc2786
commit
fe77076bc0
|
@ -1220,6 +1220,7 @@ extern "C" DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* pa
|
|||
BridgeList<WATCHINFO>::CopyData((ListInfo*)param1, WatchGetList());
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -187,6 +187,33 @@ static DWORD WINAPI dumpRefreshThread(void* ptr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Called when the debugger pauses.
|
||||
*/
|
||||
void cbDebuggerPaused()
|
||||
{
|
||||
// Clear tracing conditions
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
// Trace record is not handled by this function currently.
|
||||
// Signal thread switch warning
|
||||
static DWORD PrevThreadId = 0;
|
||||
if(PrevThreadId == 0)
|
||||
PrevThreadId = fdProcessInfo->dwThreadId; // Initialize to Main Thread
|
||||
DWORD currentThreadId = ThreadGetId(hActiveThread);
|
||||
if(currentThreadId != PrevThreadId)
|
||||
{
|
||||
dprintf("Thread switched from %X to %X !\n", PrevThreadId, currentThreadId);
|
||||
PrevThreadId = currentThreadId;
|
||||
}
|
||||
// Watchdog
|
||||
cbWatchdog(0, nullptr);
|
||||
// Plugin callback
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = nullptr;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
}
|
||||
|
||||
void dbginit()
|
||||
{
|
||||
hTimeWastedCounterThread = CreateThread(nullptr, 0, timeWastedCounterThread, nullptr, 0, nullptr);
|
||||
|
@ -375,6 +402,9 @@ void DebugUpdateGuiSetState(duint disasm_addr, bool stack, DBGSTATE state = paus
|
|||
}
|
||||
void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state)
|
||||
{
|
||||
// call paused routine to clean up various tracing states.
|
||||
if(state == DBGSTATE::paused)
|
||||
cbDebuggerPaused();
|
||||
//correctly orders the GuiSetDebugState DebugUpdateGui to prevent drawing inconsistencies
|
||||
static TaskThread_<decltype(&DebugUpdateGuiSetState), duint, bool, DBGSTATE> DebugUpdateGuiSetStateTask(&DebugUpdateGuiSetState);
|
||||
DebugUpdateGuiSetStateTask.WakeUp(disasm_addr, stack, state);
|
||||
|
@ -543,19 +573,11 @@ void cbPauseBreakpoint()
|
|||
auto CIP = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
DeleteBPX(CIP);
|
||||
DebugUpdateGuiSetStateAsync(CIP, true);
|
||||
// Clear tracing conditions
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
// Trace record
|
||||
_dbg_dbgtraceexecute(CIP);
|
||||
// Watchdog
|
||||
cbWatchdog(0, nullptr);
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = nullptr;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
|
@ -583,9 +605,6 @@ static void handleBreakCondition(const BREAKPOINT & bp, const void* ExceptionAdd
|
|||
}
|
||||
}
|
||||
DebugUpdateGuiSetStateAsync(CIP, true);
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = nullptr;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -617,9 +636,6 @@ static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr
|
|||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = nullptr;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
return;
|
||||
}
|
||||
|
@ -695,9 +711,6 @@ static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr
|
|||
}
|
||||
if(breakCondition) //break the debugger
|
||||
{
|
||||
// Clear tracing conditions
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
}
|
||||
|
@ -729,16 +742,6 @@ void cbRunToUserCodeBreakpoint(void* ExceptionAddress)
|
|||
auto CIP = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
auto symbolicname = SymGetSymbolicName(CIP);
|
||||
dprintf("User code reached at %s (" fhex ")!", symbolicname.c_str(), CIP);
|
||||
// Clear tracing conditions
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
lock(WAITID_RUN);
|
||||
// Watchdog
|
||||
cbWatchdog(0, nullptr);
|
||||
// Plugin callback
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = nullptr;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
// Trace record
|
||||
_dbg_dbgtraceexecute(CIP);
|
||||
// Update GUI
|
||||
|
@ -921,8 +924,6 @@ void cbStep()
|
|||
DebugUpdateGuiSetStateAsync(CIP, true);
|
||||
// Trace record
|
||||
_dbg_dbgtraceexecute(CIP);
|
||||
// Watchdog
|
||||
cbWatchdog(0, nullptr);
|
||||
// Plugin interaction
|
||||
PLUG_CB_STEPPED stepInfo;
|
||||
stepInfo.reserved = 0;
|
||||
|
@ -930,9 +931,6 @@ void cbStep()
|
|||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
plugincbcall(CB_STEPPED, &stepInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
@ -945,15 +943,10 @@ static void cbRtrFinalStep()
|
|||
// Trace record
|
||||
_dbg_dbgtraceexecute(CIP);
|
||||
DebugUpdateGuiSetStateAsync(CIP, true);
|
||||
// Watchdog
|
||||
cbWatchdog(0, nullptr);
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
|
@ -1293,9 +1286,6 @@ static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
|||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
}
|
||||
|
@ -1330,9 +1320,6 @@ static void cbExitThread(EXIT_THREAD_DEBUG_INFO* ExitThread)
|
|||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
}
|
||||
|
@ -1364,9 +1351,6 @@ static void cbSystemBreakpoint(void* ExceptionData) // TODO: System breakpoint e
|
|||
GuiSetDebugStateAsync(paused);
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
}
|
||||
|
@ -1495,15 +1479,9 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
bBreakOnNextDll = false;
|
||||
//update GUI
|
||||
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
// Clear tracing conditions
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
}
|
||||
|
@ -1528,15 +1506,9 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
|||
bBreakOnNextDll = false;
|
||||
//update GUI
|
||||
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
// Clear tracing conditions
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
|
@ -1575,15 +1547,9 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
|||
{
|
||||
//update GUI
|
||||
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
// Clear tracing conditions
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
}
|
||||
|
@ -1627,9 +1593,6 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
plugincbcall(CB_EXCEPTION, &callbackInfo);
|
||||
wait(WAITID_RUN);
|
||||
return;
|
||||
|
@ -1676,16 +1639,10 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
}
|
||||
|
||||
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
// Clear tracing conditions
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
SetForegroundWindow(GuiGetWindowHandle());
|
||||
bSkipExceptions = false;
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo;
|
||||
pauseInfo.reserved = 0;
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
plugincbcall(CB_EXCEPTION, &callbackInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
@ -2327,6 +2284,8 @@ static void debugLoopFunction(void* lpParameter, bool attach)
|
|||
RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints
|
||||
|
||||
//cleanup
|
||||
dbgcleartracecondition();
|
||||
dbgClearRtuBreakpoints();
|
||||
DbClose();
|
||||
ModClear();
|
||||
ThreadClear();
|
||||
|
|
|
@ -87,13 +87,6 @@ int ThreadGetCount()
|
|||
|
||||
void ThreadGetList(THREADLIST* List)
|
||||
{
|
||||
// Initialize function pointer
|
||||
if(QueryThreadCycleTime == nullptr)
|
||||
{
|
||||
QueryThreadCycleTime = (BOOL(WINAPI*)(HANDLE, PULONG64))GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "QueryThreadCycleTime");
|
||||
if(QueryThreadCycleTime == nullptr)
|
||||
QueryThreadCycleTime = QueryThreadCycleTimeUnsupported;
|
||||
}
|
||||
ASSERT_NONNULL(List);
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
|
||||
|
@ -132,7 +125,7 @@ void ThreadGetList(THREADLIST* List)
|
|||
List->list[index].WaitReason = ThreadGetWaitReason(threadHandle);
|
||||
List->list[index].LastError = ThreadGetLastErrorTEB(itr.second.ThreadLocalBase);
|
||||
GetThreadTimes(threadHandle, &List->list[index].CreationTime, &threadExitTime, &List->list[index].KernelTime, &List->list[index].UserTime);
|
||||
QueryThreadCycleTime(threadHandle, &List->list[index].Cycles);
|
||||
List->list[index].Cycles = ThreadQueryCycleTime(threadHandle);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
@ -297,4 +290,21 @@ ULONG_PTR ThreadGetLocalBase(DWORD ThreadId)
|
|||
SHARED_ACQUIRE(LockThreads);
|
||||
auto found = threadList.find(ThreadId);
|
||||
return found != threadList.end() ? found->second.ThreadLocalBase : 0;
|
||||
}
|
||||
|
||||
ULONG64 ThreadQueryCycleTime(HANDLE hThread)
|
||||
{
|
||||
ULONG64 CycleTime;
|
||||
|
||||
// Initialize function pointer
|
||||
if(QueryThreadCycleTime == nullptr)
|
||||
{
|
||||
QueryThreadCycleTime = (BOOL(WINAPI*)(HANDLE, PULONG64))GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "QueryThreadCycleTime");
|
||||
if(QueryThreadCycleTime == nullptr)
|
||||
QueryThreadCycleTime = QueryThreadCycleTimeUnsupported;
|
||||
}
|
||||
|
||||
if(!QueryThreadCycleTime(hThread, &CycleTime))
|
||||
CycleTime = 0;
|
||||
return CycleTime;
|
||||
}
|
|
@ -25,5 +25,6 @@ DWORD ThreadGetId(HANDLE Thread);
|
|||
int ThreadSuspendAll();
|
||||
int ThreadResumeAll();
|
||||
ULONG_PTR ThreadGetLocalBase(DWORD ThreadId);
|
||||
ULONG64 ThreadQueryCycleTime(HANDLE hThread);
|
||||
|
||||
#endif // _THREAD_H
|
|
@ -69,6 +69,14 @@ void CPUStack::updateFonts()
|
|||
|
||||
void CPUStack::setupContextMenu()
|
||||
{
|
||||
//Push
|
||||
mPushAction = new QAction(ArchValue(tr("P&ush DWORD..."), tr("P&ush QWORD...")), this);
|
||||
connect(mPushAction, SIGNAL(triggered()), this, SLOT(pushSlot()));
|
||||
|
||||
//Pop
|
||||
mPopAction = new QAction(ArchValue(tr("P&op DWORD"), tr("P&op QWORD")), this);
|
||||
connect(mPopAction, SIGNAL(triggered()), this, SLOT(popSlot()));
|
||||
|
||||
//Binary menu
|
||||
mBinaryMenu = new QMenu(tr("B&inary"), this);
|
||||
mBinaryMenu->setIcon(DIcon("binary.png"));
|
||||
|
@ -238,8 +246,8 @@ void CPUStack::setupContextMenu()
|
|||
this->addAction(mGotoNext);
|
||||
connect(mGotoNext, SIGNAL(triggered(bool)), this, SLOT(gotoNextSlot()));
|
||||
|
||||
//Go to Base of Frame
|
||||
mGotoFrameBase = new QAction(cspIcon, tr("Go to Base of Frame"), this);
|
||||
//Go to Base of Stack Frame
|
||||
mGotoFrameBase = new QAction(cspIcon, tr("Go to Base of Stack Frame"), this);
|
||||
connect(mGotoFrameBase, SIGNAL(triggered()), this, SLOT(gotoFrameBaseSlot()));
|
||||
|
||||
//Go to Next Frame
|
||||
|
@ -264,7 +272,7 @@ void CPUStack::setupContextMenu()
|
|||
mFollowDump = new QAction(DIcon("dump.png"), followDumpName, this);
|
||||
connect(mFollowDump, SIGNAL(triggered()), this, SLOT(followDumpSlot()));
|
||||
|
||||
auto followDumpMenuName = ArchValue(tr("&Follow DWORD in Dump"), tr("&Follow QWORD in Dump"));
|
||||
auto followDumpMenuName = ArchValue(tr("Follow DWORD in Dump"), tr("Follow QWORD in Dump"));
|
||||
mFollowInDumpMenu = new QMenu(followDumpMenuName, this);
|
||||
|
||||
int maxDumps = mMultiDump->getMaxCPUTabs();
|
||||
|
@ -281,7 +289,7 @@ void CPUStack::setupContextMenu()
|
|||
connect(mFollowStack, SIGNAL(triggered()), this, SLOT(followStackSlot()));
|
||||
|
||||
//Watch data
|
||||
auto watchDataName = ArchValue(tr("Watch DWORD"), tr("Watch QWORD"));
|
||||
auto watchDataName = ArchValue(tr("&Watch DWORD"), tr("&Watch QWORD"));
|
||||
mWatchData = new QAction(DIcon("animal-dog.png"), watchDataName, this);
|
||||
connect(mWatchData, SIGNAL(triggered()), this, SLOT(watchDataSlot()));
|
||||
|
||||
|
@ -488,6 +496,8 @@ void CPUStack::contextMenuEvent(QContextMenuEvent* event)
|
|||
return;
|
||||
|
||||
QMenu wMenu(this); //create context menu
|
||||
wMenu.addAction(mPushAction);
|
||||
wMenu.addAction(mPopAction);
|
||||
wMenu.addAction(mModifyAction);
|
||||
wMenu.addMenu(mBinaryMenu);
|
||||
QMenu wCopyMenu(tr("&Copy"), this);
|
||||
|
@ -612,8 +622,8 @@ void CPUStack::stackDumpAt(duint addr, duint csp)
|
|||
// callstack data highest >> lowest
|
||||
std::qsort(callstack.entries, callstack.total, sizeof(DBGCALLSTACKENTRY), [](const void* a, const void* b)
|
||||
{
|
||||
auto p = (DBGCALLSTACKENTRY*)a;
|
||||
auto q = (DBGCALLSTACKENTRY*)b;
|
||||
auto p = (const DBGCALLSTACKENTRY*)a;
|
||||
auto q = (const DBGCALLSTACKENTRY*)b;
|
||||
if(p->addr < q->addr)
|
||||
return -1;
|
||||
else
|
||||
|
@ -1013,6 +1023,27 @@ void CPUStack::modifySlot()
|
|||
GuiUpdateAllViews();
|
||||
}
|
||||
|
||||
void CPUStack::pushSlot()
|
||||
{
|
||||
WordEditDialog wEditDialog(this);
|
||||
dsint value = 0;
|
||||
wEditDialog.setup(ArchValue(tr("Push DWORD"), tr("Push QWORD")), value, sizeof(dsint));
|
||||
if(wEditDialog.exec() != QDialog::Accepted)
|
||||
return;
|
||||
value = wEditDialog.getVal();
|
||||
mCsp -= sizeof(dsint);
|
||||
DbgValToString("csp", mCsp);
|
||||
DbgMemWrite(mCsp, (const unsigned char*)&value, sizeof(dsint));
|
||||
GuiUpdateAllViews();
|
||||
}
|
||||
|
||||
void CPUStack::popSlot()
|
||||
{
|
||||
mCsp += sizeof(dsint);
|
||||
DbgValToString("csp", mCsp);
|
||||
GuiUpdateAllViews();
|
||||
}
|
||||
|
||||
void CPUStack::freezeStackSlot()
|
||||
{
|
||||
if(bStackFrozen)
|
||||
|
|
|
@ -28,6 +28,8 @@ signals:
|
|||
void displayReferencesWidget();
|
||||
|
||||
public slots:
|
||||
void pushSlot();
|
||||
void popSlot();
|
||||
void refreshShortcutsSlot();
|
||||
void stackDumpAt(duint addr, duint csp);
|
||||
void gotoSpSlot();
|
||||
|
@ -122,6 +124,8 @@ private:
|
|||
QAction* mWatchData;
|
||||
QMenu* mPluginMenu;
|
||||
QMenu* mFollowInDumpMenu;
|
||||
QAction* mPushAction;
|
||||
QAction* mPopAction;
|
||||
QList<QAction*> mFollowInDumpActions;
|
||||
|
||||
GotoDialog* mGoto;
|
||||
|
|
|
@ -449,6 +449,10 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff
|
|||
wCM_Incrementx87Stack = new QAction(DIcon("arrow-small-down.png"), tr("Increment x87 Stack"), this);
|
||||
wCM_Decrementx87Stack = new QAction(DIcon("arrow-small-up.png"), tr("Decrement x87 Stack"), this);
|
||||
wCM_ChangeFPUView = new QAction(DIcon("change-view.png"), tr("Change view"), this);
|
||||
wCM_IncrementPtrSize = new QAction(ArchValue(tr("Increase 4"), tr("Increase 8")), this);
|
||||
wCM_DecrementPtrSize = new QAction(ArchValue(tr("Decrease 4"), tr("Decrease 8")), this);
|
||||
wCM_Push = new QAction(tr("Push"), this);
|
||||
wCM_Pop = new QAction(tr("Pop"), this);
|
||||
|
||||
// general purposes register (we allow the user to modify the value)
|
||||
mGPR.insert(CAX);
|
||||
|
@ -514,7 +518,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff
|
|||
mUINTDISPLAY.insert(CDI);
|
||||
mLABELDISPLAY.insert(CDI);
|
||||
mMODIFYDISPLAY.insert(CDI);
|
||||
|
||||
#ifdef _WIN64
|
||||
mSETONEZEROTOGGLE.insert(R8);
|
||||
mINCREMENTDECREMET.insert(R8);
|
||||
mCANSTOREADDRESS.insert(R8);
|
||||
|
@ -578,9 +582,9 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff
|
|||
mMODIFYDISPLAY.insert(R15);
|
||||
mUINTDISPLAY.insert(R15);
|
||||
mLABELDISPLAY.insert(R15);
|
||||
#endif //_WIN64
|
||||
|
||||
mSETONEZEROTOGGLE.insert(EFLAGS);
|
||||
mINCREMENTDECREMET.insert(EFLAGS);
|
||||
mGPR.insert(EFLAGS);
|
||||
mMODIFYDISPLAY.insert(EFLAGS);
|
||||
mUINTDISPLAY.insert(EFLAGS);
|
||||
|
@ -1045,21 +1049,27 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff
|
|||
|
||||
mNoChange.insert(GS);
|
||||
mUSHORTDISPLAY.insert(GS);
|
||||
mSEGMENTREGISTER.insert(GS);
|
||||
|
||||
mNoChange.insert(FS);
|
||||
mUSHORTDISPLAY.insert(FS);
|
||||
mSEGMENTREGISTER.insert(FS);
|
||||
|
||||
mNoChange.insert(ES);
|
||||
mUSHORTDISPLAY.insert(ES);
|
||||
mSEGMENTREGISTER.insert(ES);
|
||||
|
||||
mNoChange.insert(DS);
|
||||
mUSHORTDISPLAY.insert(DS);
|
||||
mSEGMENTREGISTER.insert(DS);
|
||||
|
||||
mNoChange.insert(CS);
|
||||
mUSHORTDISPLAY.insert(CS);
|
||||
mSEGMENTREGISTER.insert(CS);
|
||||
|
||||
mNoChange.insert(SS);
|
||||
mUSHORTDISPLAY.insert(SS);
|
||||
mSEGMENTREGISTER.insert(SS);
|
||||
|
||||
mNoChange.insert(DR0);
|
||||
mUINTDISPLAY.insert(DR0);
|
||||
|
@ -1139,6 +1149,10 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff
|
|||
connect(wCM_FollowInDisassembly, SIGNAL(triggered()), this, SLOT(onFollowInDisassembly()));
|
||||
connect(wCM_FollowInDump, SIGNAL(triggered()), this, SLOT(onFollowInDump()));
|
||||
connect(wCM_FollowInStack, SIGNAL(triggered()), this, SLOT(onFollowInStack()));
|
||||
connect(wCM_IncrementPtrSize, SIGNAL(triggered()), this, SLOT(onIncrementPtrSize()));
|
||||
connect(wCM_DecrementPtrSize, SIGNAL(triggered()), this, SLOT(onDecrementPtrSize()));
|
||||
connect(wCM_Push, SIGNAL(triggered()), this, SLOT(onPushAction()));
|
||||
connect(wCM_Pop, SIGNAL(triggered()), this, SLOT(onPopAction()));
|
||||
|
||||
refreshShortcutsSlot();
|
||||
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot()));
|
||||
|
@ -2015,6 +2029,41 @@ void RegistersView::onDecrementAction()
|
|||
setRegister(mSelected, (* ((duint*) registerValue(&wRegDumpStruct, mSelected))) - 1);
|
||||
}
|
||||
|
||||
void RegistersView::onIncrementPtrSize()
|
||||
{
|
||||
if(mINCREMENTDECREMET.contains(mSelected))
|
||||
setRegister(mSelected, (* ((duint*) registerValue(&wRegDumpStruct, mSelected))) + sizeof(void*));
|
||||
}
|
||||
|
||||
void RegistersView::onDecrementPtrSize()
|
||||
{
|
||||
if(mINCREMENTDECREMET.contains(mSelected))
|
||||
setRegister(mSelected, (* ((duint*) registerValue(&wRegDumpStruct, mSelected))) - sizeof(void*));
|
||||
}
|
||||
|
||||
void RegistersView::onPushAction()
|
||||
{
|
||||
duint csp = (* ((duint*) registerValue(&wRegDumpStruct, CSP))) - sizeof(void*);
|
||||
duint regVal = 0;
|
||||
if(mSEGMENTREGISTER.contains(mSelected))
|
||||
regVal = * ((unsigned short*) registerValue(&wRegDumpStruct, mSelected));
|
||||
else
|
||||
regVal = * ((duint*) registerValue(&wRegDumpStruct, mSelected));
|
||||
setRegister(CSP, csp);
|
||||
DbgMemWrite(csp, (const unsigned char*)®Val , sizeof(void*));
|
||||
}
|
||||
|
||||
void RegistersView::onPopAction()
|
||||
{
|
||||
duint csp = (* ((duint*) registerValue(&wRegDumpStruct, CSP)));
|
||||
duint newVal;
|
||||
DbgMemRead(csp, (unsigned char*)&newVal, sizeof(void*));
|
||||
setRegister(CSP, csp + sizeof(void*));
|
||||
if(mSEGMENTREGISTER.contains(mSelected))
|
||||
newVal &= 0xFFFF;
|
||||
setRegister(mSelected, newVal);
|
||||
}
|
||||
|
||||
void RegistersView::onZeroAction()
|
||||
{
|
||||
if(mSETONEZEROTOGGLE.contains(mSelected))
|
||||
|
@ -2311,6 +2360,14 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos)
|
|||
{
|
||||
wMenu.addAction(wCM_Increment);
|
||||
wMenu.addAction(wCM_Decrement);
|
||||
wMenu.addAction(wCM_IncrementPtrSize);
|
||||
wMenu.addAction(wCM_DecrementPtrSize);
|
||||
}
|
||||
|
||||
if(mGPR.contains(mSelected) || mSEGMENTREGISTER.contains(mSelected))
|
||||
{
|
||||
wMenu.addAction(wCM_Push);
|
||||
wMenu.addAction(wCM_Pop);
|
||||
}
|
||||
|
||||
if(mMODIFYDISPLAY.contains(mSelected))
|
||||
|
|
|
@ -142,6 +142,10 @@ protected slots:
|
|||
void onFollowInDisassembly();
|
||||
void onFollowInDump();
|
||||
void onFollowInStack();
|
||||
void onIncrementPtrSize();
|
||||
void onDecrementPtrSize();
|
||||
void onPushAction();
|
||||
void onPopAction();
|
||||
void InitMappings();
|
||||
QString getRegisterLabel(REGISTER_NAME);
|
||||
int CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2);
|
||||
|
@ -177,6 +181,7 @@ private:
|
|||
QSet<REGISTER_NAME> mFIELDVALUE;
|
||||
QSet<REGISTER_NAME> mTAGWORD;
|
||||
QSet<REGISTER_NAME> mCANSTOREADDRESS;
|
||||
QSet<REGISTER_NAME> mSEGMENTREGISTER;
|
||||
QSet<REGISTER_NAME> mINCREMENTDECREMET;
|
||||
QSet<REGISTER_NAME> mFPUx87_80BITSDISPLAY;
|
||||
QSet<REGISTER_NAME> mFPU;
|
||||
|
@ -207,6 +212,10 @@ private:
|
|||
// context menu actions
|
||||
QAction* wCM_Increment;
|
||||
QAction* wCM_Decrement;
|
||||
QAction* wCM_IncrementPtrSize;
|
||||
QAction* wCM_DecrementPtrSize;
|
||||
QAction* wCM_Push;
|
||||
QAction* wCM_Pop;
|
||||
QAction* wCM_Zero;
|
||||
QAction* wCM_SetToOne;
|
||||
QAction* wCM_Modify;
|
||||
|
|
Loading…
Reference in New Issue