#include "RegistersView.h" #include "Configuration.h" RegistersView::RegistersView(QWidget * parent) : QAbstractScrollArea(parent), mVScrollOffset(0) { // precreate ContextMenu Actions wCM_Increment = new QAction(tr("Increment"),this); wCM_Increment->setShortcut(Qt::Key_Plus); wCM_Decrement = new QAction(tr("Decrement"),this); wCM_Decrement->setShortcut(Qt::Key_Minus); wCM_Zero = new QAction(tr("Zero"),this); wCM_Zero->setShortcut(Qt::Key_0); wCM_SetToOne = new QAction(tr("Set to 1"),this); wCM_SetToOne->setShortcut(Qt::Key_1); wCM_Modify = new QAction(tr("Modify Value"),this); wCM_Modify->setShortcut(Qt::Key_Return); wCM_ToggleValue = new QAction(tr("Toggle"),this); wCM_ToggleValue->setShortcut(Qt::Key_Space); wCM_CopyToClipboard = new QAction(tr("Copy Value to Clipboard"),this); wCM_CopyToClipboard->setShortcut(QKeySequence::Copy); wCM_FollowInDisassembly = new QAction(tr("Follow in Disassembler"),this); wCM_FollowInDump = new QAction(tr("Follow in Dump"),this); wCM_FollowInStack = new QAction("Follow in Stack", this); // general purposes register (we allow the user to modify the value) mGPR.insert(CAX); mGPR.insert(CBX); mGPR.insert(CCX); mGPR.insert(CDX); mGPR.insert(CBP); mGPR.insert(CSP); mGPR.insert(CSI); mGPR.insert(CDI); mGPR.insert(R8); mGPR.insert(R9); mGPR.insert(R10); mGPR.insert(R11); mGPR.insert(R12); mGPR.insert(R13); mGPR.insert(R14); mGPR.insert(R15); mGPR.insert(EFLAGS); // flags (we allow the user to toggle them) mFlags.insert(CF); mFlags.insert(PF); mFlags.insert(AF); mFlags.insert(ZF); mFlags.insert(SF); mFlags.insert(TF); mFlags.insert(IF); mFlags.insert(DF); mFlags.insert(OF); //registers that should not be changed mNoChange.insert(GS); mNoChange.insert(FS); mNoChange.insert(ES); mNoChange.insert(DS); mNoChange.insert(CS); mNoChange.insert(SS); mNoChange.insert(DR0); mNoChange.insert(DR1); mNoChange.insert(DR2); mNoChange.insert(DR3); mNoChange.insert(DR6); mNoChange.insert(DR7); mNoChange.insert(CIP); // create mapping from internal id to name mRegisterMapping.clear(); mRegisterPlaces.clear(); int offset = 0; /* Register_Position is a struct definition the position * * (line , start, labelwidth, valuesize ) */ #ifdef _WIN64 mRegisterMapping.insert(CAX,"RAX"); mRegisterPlaces.insert(CAX,Register_Position(0,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CBX,"RBX"); mRegisterPlaces.insert(CBX,Register_Position(1,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CCX,"RCX"); mRegisterPlaces.insert(CCX,Register_Position(2,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CDX,"RDX"); mRegisterPlaces.insert(CDX,Register_Position(3,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CSI,"RSI"); mRegisterPlaces.insert(CSI,Register_Position(6,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CDI,"RDI"); mRegisterPlaces.insert(CDI,Register_Position(7,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CBP,"RBP"); mRegisterPlaces.insert(CBP,Register_Position(4,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CSP,"RSP"); mRegisterPlaces.insert(CSP,Register_Position(5,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(R8,"R8"); mRegisterPlaces.insert(R8 ,Register_Position(9,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(R9,"R9"); mRegisterPlaces.insert(R9 ,Register_Position(10,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(R10,"R10"); mRegisterPlaces.insert(R10,Register_Position(11,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(R11,"R11"); mRegisterPlaces.insert(R11,Register_Position(12,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(R12,"R12"); mRegisterPlaces.insert(R12,Register_Position(13,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(R13,"R13"); mRegisterPlaces.insert(R13,Register_Position(14,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(R14,"R14"); mRegisterPlaces.insert(R14,Register_Position(15,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(R15,"R15"); mRegisterPlaces.insert(R15,Register_Position(16,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CIP,"RIP"); mRegisterPlaces.insert(CIP,Register_Position(18,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(EFLAGS,"RFLAGS"); mRegisterPlaces.insert(EFLAGS,Register_Position(20,0, 9, sizeof(uint_t) * 2)); offset = 21; #else mRegisterMapping.insert(CAX,"EAX"); mRegisterPlaces.insert(CAX,Register_Position(0,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CBX,"EBX"); mRegisterPlaces.insert(CBX,Register_Position(1,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CCX,"ECX"); mRegisterPlaces.insert(CCX,Register_Position(2,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CDX,"EDX"); mRegisterPlaces.insert(CDX,Register_Position(3,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CSI,"ESI"); mRegisterPlaces.insert(CSI,Register_Position(6,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CDI,"EDI"); mRegisterPlaces.insert(CDI,Register_Position(7,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CBP,"EBP"); mRegisterPlaces.insert(CBP,Register_Position(4,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CSP,"ESP"); mRegisterPlaces.insert(CSP,Register_Position(5,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CIP,"EIP"); mRegisterPlaces.insert(CIP,Register_Position(9,0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(EFLAGS,"EFLAGS"); mRegisterPlaces.insert(EFLAGS,Register_Position(11,0, 9, sizeof(uint_t) * 2)); offset = 12; #endif mRegisterMapping.insert(CF,"CF"); mRegisterPlaces.insert(CF,Register_Position(offset+0,0, 3, 1)); mRegisterMapping.insert(PF,"PF"); mRegisterPlaces.insert(PF,Register_Position(offset+1,0, 3, 1)); mRegisterMapping.insert(AF,"AF"); mRegisterPlaces.insert(AF,Register_Position(offset+2,0, 3, 1)); mRegisterMapping.insert(ZF,"ZF"); mRegisterPlaces.insert(ZF,Register_Position(offset+3,0, 3, 1)); mRegisterMapping.insert(SF,"SF"); mRegisterPlaces.insert(SF,Register_Position(offset+4,0, 3, 1)); mRegisterMapping.insert(TF,"TF"); mRegisterPlaces.insert(TF,Register_Position(offset+0, 10, 3,1)); mRegisterMapping.insert(IF,"IF"); mRegisterPlaces.insert(IF,Register_Position(offset+1, 10, 3,1)); mRegisterMapping.insert(DF,"DF"); mRegisterPlaces.insert(DF,Register_Position(offset+2, 10, 3,1)); mRegisterMapping.insert(OF,"OF"); mRegisterPlaces.insert(OF,Register_Position(offset+3, 10, 3,1)); offset++; mRegisterMapping.insert(GS,"GS"); mRegisterPlaces.insert(GS,Register_Position(offset+5,0, 3, 4)); mRegisterMapping.insert(FS,"FS"); mRegisterPlaces.insert(FS,Register_Position(offset+6,0, 3, 4)); mRegisterMapping.insert(ES,"ES"); mRegisterPlaces.insert(ES,Register_Position(offset+7,0, 3, 4)); mRegisterMapping.insert(DS,"DS"); mRegisterPlaces.insert(DS,Register_Position(offset+8,0, 3, 4)); mRegisterMapping.insert(CS,"CS"); mRegisterPlaces.insert(CS,Register_Position(offset+9,0, 3, 4)); mRegisterMapping.insert(SS,"SS"); mRegisterPlaces.insert(SS,Register_Position(offset+10,0, 3, 4)); offset++; mRegisterMapping.insert(DR0,"DR0"); mRegisterPlaces.insert(DR0,Register_Position(offset+11,0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR1,"DR1"); mRegisterPlaces.insert(DR1,Register_Position(offset+12,0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR2,"DR2"); mRegisterPlaces.insert(DR2,Register_Position(offset+13,0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR3,"DR3"); mRegisterPlaces.insert(DR3,Register_Position(offset+14,0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR6,"DR6"); mRegisterPlaces.insert(DR6,Register_Position(offset+15,0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR7,"DR7"); mRegisterPlaces.insert(DR7,Register_Position(offset+16,0, 4, sizeof(uint_t) * 2)); fontsUpdatedSlot(); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); memset(&wRegDumpStruct, 0, sizeof(REGDUMP)); memset(&wCipRegDumpStruct, 0, sizeof(REGDUMP)); mCip=0; mRegisterUpdates.clear(); mRowsNeeded=offset+16; mRowsNeeded++; yTopSpacing=3; //set top spacing (in pixels) // Context Menu this->setContextMenuPolicy(Qt::CustomContextMenu); // foreign messages connect(Bridge::getBridge(), SIGNAL(updateRegisters()), this, SLOT(updateRegistersSlot())); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomContextMenuSlot(QPoint))); connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE))); // self communication for repainting (maybe some other widgets needs this information, too) connect(this,SIGNAL(refresh()),this,SLOT(repaint())); // context menu actions connect(wCM_Increment,SIGNAL(triggered()),this,SLOT(onIncrementAction())); connect(wCM_Decrement,SIGNAL(triggered()),this,SLOT(onDecrementAction())); connect(wCM_Zero,SIGNAL(triggered()),this,SLOT(onZeroAction())); connect(wCM_SetToOne,SIGNAL(triggered()),this,SLOT(onSetToOneAction())); connect(wCM_Modify,SIGNAL(triggered()),this,SLOT(onModifyAction())); connect(wCM_ToggleValue,SIGNAL(triggered()),this,SLOT(onToggleValueAction())); connect(wCM_CopyToClipboard,SIGNAL(triggered()),this,SLOT(onCopyToClipboardAction())); connect(wCM_FollowInDisassembly,SIGNAL(triggered()),this,SLOT(onFollowInDisassembly())); connect(wCM_FollowInDump,SIGNAL(triggered()),this,SLOT(onFollowInDump())); connect(wCM_FollowInStack,SIGNAL(triggered()),this,SLOT(onFollowInStack())); } RegistersView::~RegistersView() { } void RegistersView::fontsUpdatedSlot() { setFont(ConfigFont("Registers")); int wRowsHeight = QFontMetrics(this->font()).height(); wRowsHeight = (wRowsHeight * 105) / 100; wRowsHeight = (wRowsHeight % 2) == 0 ? wRowsHeight : wRowsHeight + 1; mRowHeight = wRowsHeight; mCharWidth = QFontMetrics(this->font()).averageCharWidth(); repaint(); } /** * @brief retrieves the register id from given corrdinates of the viewport * @param line * @param offset (x-coord) * @param resulting register-id * @return true if register found */ bool RegistersView::identifyRegister(const int line, const int offset, REGISTER_NAME *clickedReg) { // we start by an unknown register id if(clickedReg) *clickedReg = UNKNOWN; bool found_flag = false; QMap::const_iterator it = mRegisterPlaces.begin(); // iterate all registers that being displayed while (it != mRegisterPlaces.end()) { if( (it.value().line == (line - mVScrollOffset)) /* same line ? */ && ( (1 + it.value().start) <= offset) /* between start ... ? */ && ( offset<= (1+it.value().start+it.value().labelwidth+it.value().valuesize)) /* ... and end ? */ ) { // we found a matching register in the viewport if(clickedReg) *clickedReg = (REGISTER_NAME)it.key(); found_flag = true; break; } ++it; } return found_flag; } void RegistersView::mousePressEvent(QMouseEvent* event) { if(!DbgIsDebugging()) return; // get mouse position const int y = (event->y()-3)/(double)mRowHeight; const int x = event->x()/(double)mCharWidth; REGISTER_NAME r; // do we find a corresponding register? if(identifyRegister(y,x,&r)) { mSelected = r; emit refresh(); } } void RegistersView::mouseDoubleClickEvent(QMouseEvent* event) { Q_UNUSED(event); if(!DbgIsDebugging()) return; // get mouse position const int y = (event->y()-3)/(double)mRowHeight; const int x = event->x()/(double)mCharWidth; // do we find a corresponding register? if(!identifyRegister(y,x,0)) return; // is current register general purposes register ? if(mGPR.contains(mSelected)) { wCM_Modify->trigger(); } else if(mFlags.contains(mSelected)) // is flag ? wCM_ToggleValue->trigger(); else if(mSelected == CIP) //double clicked on CIP register DbgCmdExec("disasm cip"); } void RegistersView::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter wPainter(this->viewport()); wPainter.fillRect(wPainter.viewport(), QBrush(ConfigColor("RegistersBackgroundColor"))); QMap::const_iterator it = mRegisterMapping.begin(); // iterate all registers while (it != mRegisterMapping.end()) { // paint register at given position drawRegister(&wPainter,it.key(),registerValue(&wRegDumpStruct,it.key())); it++; } } void RegistersView::keyPressEvent(QKeyEvent *event) { if(!DbgIsDebugging()) return; if(event->matches(QKeySequence::Copy)) { wCM_CopyToClipboard->trigger(); return; } switch(event->key()) { case Qt::Key_0: wCM_Zero->trigger(); break; case Qt::Key_1: wCM_SetToOne->trigger(); break; case Qt::Key_Plus: wCM_Increment->trigger(); break; case Qt::Key_Minus: wCM_Decrement->trigger(); break; case Qt::Key_Space: wCM_ToggleValue->trigger(); break; case Qt::Key_Return: wCM_Modify->trigger(); break; default: break; } } void RegistersView::wheelEvent(QWheelEvent *event) { int numDegrees = event->delta() / 8; // one wheel click ==> 2 lines int numSteps = numDegrees / 15 * 1 ; int rowsDisplayed=this->viewport()->height()/mRowHeight; int vScrollEndOffset=0; if(rowsDisplayedorientation() == Qt::Vertical) { if(numSteps > 0 && mVScrollOffset + numSteps > 0) //before the first register mVScrollOffset=0; else if(numSteps < 0 && mVScrollOffset + numSteps < vScrollEndOffset) //after the last register mVScrollOffset = mVScrollOffset; //do nothing else mVScrollOffset += numSteps; } emit refresh(); event->accept(); } QSize RegistersView::sizeHint() const { // 32 character width return QSize(32*mCharWidth ,this->viewport()->height()); } void RegistersView::drawRegister(QPainter *p,REGISTER_NAME reg, uint_t value) { // is the register-id known? if(mRegisterMapping.contains(reg)) { // padding to the left is at least one character (looks better) int x = mCharWidth*(1 + mRegisterPlaces[reg].start); int ySpace=yTopSpacing; if(mVScrollOffset!=0) ySpace=0; int y = mRowHeight*(mRegisterPlaces[reg].line + mVScrollOffset) + ySpace; //draw raster /* p->save(); p->setPen(QColor("#FF0000")); p->drawLine(0, y, this->viewport()->width(), y); p->restore(); */ // draw name of value int width=mCharWidth*mRegisterMapping[reg].length(); p->setPen(ConfigColor("RegistersLabelColor")); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, mRegisterMapping[reg]); x += (mRegisterPlaces[reg].labelwidth) * mCharWidth; //p->drawText(offset,mRowHeight*(mRegisterPlaces[reg].line+1),mRegisterMapping[reg]); //set highlighting if(DbgIsDebugging() && mRegisterUpdates.contains(reg)) p->setPen(ConfigColor("RegistersModifiedColor")); else p->setPen(ConfigColor("RegistersColor")); //selection if(mSelected == reg) { p->fillRect(x, y, mRegisterPlaces[reg].valuesize*mCharWidth, mRowHeight, QBrush(ConfigColor("RegistersSelectionColor"))); //p->fillRect(QRect(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line)+2, mRegisterPlaces[reg].valuesize*mCharWidth, mRowHeight), QBrush(ConfigColor("RegistersSelectionColor"))); } // draw value QString valueText = QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); width = mCharWidth * valueText.length(); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, valueText); //p->drawText(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line+1),QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper()); // do we have a label ? char label_text[MAX_LABEL_SIZE]=""; char module_text[MAX_MODULE_SIZE]=""; char string_text[MAX_STRING_SIZE]=""; bool hasString=DbgGetStringAt(value, string_text); bool hasLabel=DbgGetLabelAt(value, SEG_DEFAULT, label_text); bool hasModule=DbgGetModuleAt(value, module_text); bool isCharacter=false; x += valueText.length() * mCharWidth; x += 5 * mCharWidth; //5 spaces QString newText = ""; if(hasString) { newText=string_text; } else if(hasLabel && hasModule) { newText="<"+QString(module_text)+"."+QString(label_text)+">"; } else if(hasModule) { newText=QString(module_text)+"."+valueText; } else if(hasLabel) { newText="<"+QString(label_text)+">"; } else { // can we interpret the character as ASCII ?? if(mGPR.contains(reg)) { if(value == (value & 0xFF)) { QChar c = QChar((char)value); if(c.isPrint()) { newText=QString("'%1'").arg((char)value); isCharacter=IsCharacterRegister(reg); } } else if(value == (value & 0xFFF)) //UNICODE? { QChar c = QChar((wchar_t)value); if(c.isPrint()) { newText="L'"+QString(c)+"'"; isCharacter=IsCharacterRegister(reg); } } } } // are there additional informations? if(hasString || hasLabel || hasModule || isCharacter) { width = newText.length() * mCharWidth; p->setPen(ConfigColor("RegistersExtraInfoColor")); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); //p->drawText(x,mRowHeight*(mRegisterPlaces[reg].line+1),newText); } } } void RegistersView::updateRegistersSlot() { // read registers REGDUMP z; memset(&z, 0, sizeof(REGDUMP)); DbgGetRegDump(&z); // update gui setRegisters(&z); } void RegistersView::displayEditDialog() { WordEditDialog wEditDial(this); wEditDial.setup(QString("Edit"),registerValue(&wRegDumpStruct,mSelected), sizeof(int_t)); if(wEditDial.exec() == QDialog::Accepted) //OK button clicked setRegister(mSelected, wEditDial.getVal()); } void RegistersView::onIncrementAction() { if(mGPR.contains(mSelected)) setRegister(mSelected, registerValue(&wRegDumpStruct,mSelected) + 1); } void RegistersView::onDecrementAction() { if(mGPR.contains(mSelected)) setRegister(mSelected, registerValue(&wRegDumpStruct,mSelected) - 1); } void RegistersView::onZeroAction() { if(!mNoChange.contains(mSelected)) setRegister(mSelected, 0); } void RegistersView::onSetToOneAction() { if(!mNoChange.contains(mSelected)) setRegister(mSelected, 1); } void RegistersView::onModifyAction() { if(mGPR.contains(mSelected)) displayEditDialog(); } void RegistersView::onToggleValueAction() { if(mFlags.contains(mSelected)) setRegister(mSelected, ((int)registerValue(&wRegDumpStruct,mSelected))^1); else { int_t val = registerValue(&wRegDumpStruct,mSelected); val++; val *= -1; setRegister(mSelected,val); } } void RegistersView::onCopyToClipboardAction() { QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(QString("%1").arg(registerValue(&wRegDumpStruct,mSelected), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper()); } void RegistersView::onFollowInDisassembly() { if(mGPR.contains(mSelected)) { QString addr = QString("%1").arg(registerValue(&wRegDumpStruct,mSelected), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); if(DbgMemIsValidReadPtr(registerValue(&wRegDumpStruct,mSelected))) DbgCmdExec(QString().sprintf("disasm \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); } } void RegistersView::onFollowInDump() { if(mGPR.contains(mSelected)) { QString addr = QString("%1").arg(registerValue(&wRegDumpStruct,mSelected), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); if(DbgMemIsValidReadPtr(registerValue(&wRegDumpStruct,mSelected))) DbgCmdExec(QString().sprintf("dump \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); } } void RegistersView::onFollowInStack() { if(mGPR.contains(mSelected)) { QString addr = QString("%1").arg(registerValue(&wRegDumpStruct,mSelected), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); if(DbgMemIsValidReadPtr(registerValue(&wRegDumpStruct,mSelected))) DbgCmdExec(QString().sprintf("sdump \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); } } void RegistersView::displayCustomContextMenuSlot(QPoint pos) { if(!DbgIsDebugging()) return; QMenu wMenu(this); if(mSelected != UNKNOWN) { if(!mNoChange.contains(mSelected)) { if(registerValue(&wRegDumpStruct,mSelected) >= 1) wMenu.addAction(wCM_Zero); if(registerValue(&wRegDumpStruct,mSelected) == 0) wMenu.addAction(wCM_SetToOne); wMenu.addAction(wCM_ToggleValue); } if(mGPR.contains(mSelected)) { wMenu.addAction(wCM_Modify); wMenu.addAction(wCM_Increment); wMenu.addAction(wCM_Decrement); uint_t addr = registerValue(&wRegDumpStruct,mSelected); if(DbgMemIsValidReadPtr(addr)) { wMenu.addAction(wCM_FollowInDump); wMenu.addAction(wCM_FollowInDisassembly); duint size=0; duint base=DbgMemFindBaseAddr(DbgValFromString("csp"), &size); if(addr>=base && addrmapToGlobal(pos)); } else { wMenu.addSeparator(); #ifdef _WIN64 QAction* wHwbpCsp = wMenu.addAction("HW Break on [RSP]"); #else QAction* wHwbpCsp = wMenu.addAction("HW Break on [ESP]"); #endif QAction* wAction = wMenu.exec(this->mapToGlobal(pos)); if(wAction == wHwbpCsp) DbgCmdExec("bphws csp,rw"); } } void RegistersView::setRegister(REGISTER_NAME reg, uint_t value) { // is register-id known? if(mRegisterMapping.contains(reg)) { // map "cax" to "eax" or "rax" QString wRegName = mRegisterMapping.constFind(reg).value(); // flags need to '!' infront if(mFlags.contains(reg)) wRegName = "!"+wRegName; // we change the value (so highlight it) mRegisterUpdates.insert(reg); // tell everything the compiler DbgValToString(wRegName.toUtf8().constData(), value); // force repaint emit refresh(); } } void RegistersView::debugStateChangedSlot(DBGSTATE state) { if(state==stopped) { updateRegistersSlot(); } } void RegistersView::repaint() { this->viewport()->repaint(); } int_t RegistersView::registerValue(const REGDUMP* regd,const REGISTER_NAME reg) { // this is probably the most efficient general method to access the values of the struct if(reg==CAX) return regd->cax; if(reg==CBX) return regd->cbx; if(reg==CCX) return regd->ccx; if(reg==CDX) return regd->cdx; if(reg==CSI) return regd->csi; if(reg==CDI) return regd->cdi; if(reg==CBP) return regd->cbp; if(reg==CSP) return regd->csp; if(reg==CIP) return regd->cip; if(reg==EFLAGS) return regd->eflags; #ifdef _WIN64 if(reg==R8) return regd->r8; if(reg==R9) return regd->r9; if(reg==R10) return regd->r10; if(reg==R11) return regd->r11; if(reg==R12) return regd->r12; if(reg==R13) return regd->r13; if(reg==R14) return regd->r14; if(reg==R15) return regd->r15; #endif // CF,PF,AF,ZF,SF,TF,IF,DF,OF if(reg==CF) return regd->flags.c; if(reg==PF) return regd->flags.p; if(reg==AF) return regd->flags.a; if(reg==ZF) return regd->flags.z; if(reg==SF) return regd->flags.s; if(reg==TF) return regd->flags.t; if(reg==IF) return regd->flags.i; if(reg==DF) return regd->flags.d; if(reg==OF) return regd->flags.o; // GS,FS,ES,DS,CS,SS if(reg==GS) return regd->gs; if(reg==FS) return regd->fs; if(reg==ES) return regd->es; if(reg==DS) return regd->ds; if(reg==CS) return regd->cs; if(reg==SS) return regd->ss; if(reg==DR0) return regd->dr0; if(reg==DR1) return regd->dr1; if(reg==DR2) return regd->dr2; if(reg==DR3) return regd->dr3; if(reg==DR6) return regd->dr6; if(reg==DR7) return regd->dr7; return 0; } void RegistersView::setRegisters(REGDUMP* reg) { // tests if new-register-value == old-register-value holds if(mCip!=reg->cip) //CIP changed { wCipRegDumpStruct=wRegDumpStruct; mRegisterUpdates.clear(); mCip=reg->cip; } QMap::const_iterator it = mRegisterMapping.begin(); // iterate all ids (CAX, CBX, ...) while (it != mRegisterMapping.end()) { // does a register-value change happens? if(registerValue(reg,it.key()) != registerValue(&wCipRegDumpStruct,it.key())) mRegisterUpdates.insert(it.key()); else if(mRegisterUpdates.contains(it.key())) //registers are equal mRegisterUpdates.remove(it.key()); it++; } // now we can save the values wRegDumpStruct = (*reg); if(mCip!=reg->cip) wCipRegDumpStruct=wRegDumpStruct; // force repaint emit refresh(); }