1
0
Fork 0

misc improvments

This commit is contained in:
torusrxxx 2016-07-25 18:36:06 +08:00
parent c6bf7b6570
commit 886511fdcd
11 changed files with 153 additions and 55 deletions

View File

@ -1403,7 +1403,7 @@ bool valapifromstring(const char* name, duint* value, int* value_size, bool prin
if(szBaseName)
{
szBaseName++;
HMODULE hModule = LoadLibraryExW(szModuleName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
HMODULE hModule = LoadLibraryExW(szModuleName, 0, DONT_RESOLVE_DLL_REFERENCES);
if(hModule)
{
ULONG_PTR funcAddress = (ULONG_PTR)GetProcAddress(hModule, name);
@ -1448,6 +1448,21 @@ bool valapifromstring(const char* name, duint* value, int* value_size, bool prin
return true;
}
bool valenvfromstring(const char* string, duint* Address)
{
if(scmp(string, "peb"))
{
*Address = (duint)GetPEBLocation(fdProcessInfo->hProcess);
return true;
}
else if(scmp(string, "teb"))
{
*Address = (duint)GetTEBLocation(hActiveThread);
return true;
}
return false;
}
/**
\brief Check if a string is a valid decimal number. This function also accepts "-" or "." as prefix.
\param string The string to check.
@ -1515,6 +1530,11 @@ bool convertLongLongNumber(const char* str, unsigned long long & result, int rad
return true;
}
/**
\brief Check if a character is a valid hexadecimal digit that is smaller than the size of a pointer.
\param digit The character to check.
\return true if the character is a valid hexadecimal digit.
*/
static bool isdigitduint(char digit)
{
#ifdef _WIN64
@ -1609,7 +1629,8 @@ bool valfromstring_noexpr(const char* string, duint* value, bool silent, bool ba
if(!valfromstring(ptrstring.c_str(), value, silent, baseonly))
{
dprintf("noexpr failed on %s\n", ptrstring.c_str());
if(!silent)
dprintf("noexpr failed on %s\n", ptrstring.c_str());
return false;
}
duint addr = *value;
@ -1702,6 +1723,8 @@ bool valfromstring_noexpr(const char* string, duint* value, bool silent, bool ba
*isvar = true;
return true;
}
else if(valenvfromstring(string, value)) //environment block
return true;
else if(strstr(string, "sub_") == string) //then come sub_ functions
{
auto result = sscanf(string, "sub_%" fext "X", value) == 1;

View File

@ -444,6 +444,37 @@ void StdTable::setupCopyMenu(QMenu* copyMenu)
}
}
void StdTable::setupCopyMenu(MenuBuilder *copyMenu)
{
if(!getColumnCount())
return;
//Copy->Whole Line
copyMenu->addAction(makeAction(tr("&Line"), SLOT(copyLineSlot())));
//Copy->Cropped Table
copyMenu->addAction(makeAction(tr("Cropped &Table"), SLOT(copyTableSlot())));
//Copy->Full Table
copyMenu->addAction(makeAction(tr("&Full Table"), SLOT(copyTableResizeSlot())));
//Copy->Separator
copyMenu->addSeparator();
//Copy->ColName
copyMenu->addBuilder(new MenuBuilder(this, [this](QMenu* menu)
{
for(int i = 0; i < getColumnCount(); i++)
{
if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells
continue;
QString title = mCopyTitles.at(i);
if(!title.length()) //skip empty copy titles
continue;
QAction* action = new QAction(title, menu);
action->setObjectName(QString::number(i));
connect(action, SIGNAL(triggered()), this, SLOT(copyEntrySlot()));
menu->addAction(action);
}
return true;
}));
}
void StdTable::setCopyMenuOnly(bool bSet, bool bDebugOnly)
{
mCopyMenuOnly = bSet;

View File

@ -39,6 +39,7 @@ public:
//context menu helpers
void setupCopyMenu(QMenu* copyMenu);
void setupCopyMenu(MenuBuilder* copyMenu);
void setCopyMenuOnly(bool bSet, bool bDebugOnly = true);
signals:

View File

@ -1311,7 +1311,7 @@ void CPUDisassembly::yaraSlot()
YaraRuleSelectionDialog yaraDialog(this);
if(yaraDialog.exec() == QDialog::Accepted)
{
QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper();
QString addrText = ToPtrString(rvaToVa(getInitialSelection()));
DbgCmdExec(QString("yara \"%0\",%1").arg(yaraDialog.getSelectedFile()).arg(addrText).toUtf8().constData());
emit displayReferencesWidget();
}

View File

@ -193,6 +193,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
#endif //_WIN64
std::vector<JumpLine> jumpLines;
std::vector<LabelArrow> labelArrows;
for(int line = 0; line < viewableRows; line++)
{
@ -270,7 +271,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
if(regLabelText.size())
{
regLabelText.chop(1);
drawLabel(&painter, line, regLabelText);
labelArrows.push_back(drawLabel(&painter, line, regLabelText));
}
//debug
@ -291,10 +292,16 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
}
if(jumpLines.size())
{
AllocateJumpOffsets(jumpLines);
AllocateJumpOffsets(jumpLines, labelArrows);
for(auto i : jumpLines)
drawJump(&painter, i.line, i.destLine, i.jumpOffset, i.isConditional, i.isJumpGoingToExecute, i.isSelected);
}
else
{
for(auto i = labelArrows.begin(); i != labelArrows.end(); i++)
i->endX = viewport()->width() - 1 - 11 - (isFoldingGraphicsPresent(i->line) != 0 ? mBulletRadius + fontHeight : 0);
}
drawLabelArrows(&painter, labelArrows);
}
void CPUSideBar::mouseReleaseEvent(QMouseEvent* e)
@ -599,7 +606,7 @@ void CPUSideBar::drawBullets(QPainter* painter, int line, bool isbp, bool isbpdi
painter->restore();
}
void CPUSideBar::drawLabel(QPainter* painter, int Line, const QString & Text)
CPUSideBar::LabelArrow CPUSideBar::drawLabel(QPainter* painter, int Line, const QString & Text)
{
painter->save();
const int LineCoordinate = fontHeight * (1 + Line);
@ -630,7 +637,29 @@ void CPUSideBar::drawLabel(QPainter* painter, int Line, const QString & Text)
painter->setBrush(QBrush(IPLabelBG));
drawStraightArrow(painter, rect.right() + 2, y, this->viewport()->width() - x - 11 - (isFoldingGraphicsPresent(Line) != 0 ? mBulletRadius + fontHeight : 0), y);*/
LabelArrow labelArrow;
labelArrow.line = Line;
labelArrow.startX = rect.right() + 2;
labelArrow.endX = 0;
painter->restore();
return labelArrow;
}
void CPUSideBar::drawLabelArrows(QPainter* painter, const std::vector<LabelArrow> & labelArrows)
{
if(!labelArrows.empty())
{
painter->save();
painter->setPen(QPen(mCipLabelBackgroundColor, 2.0));
for(auto i : labelArrows)
{
int y = fontHeight * (1 + i.line) - 0.5 * fontHeight;
drawStraightArrow(painter, i.startX, y, i.endX, y);
}
painter->restore();
}
}
void CPUSideBar::drawFoldingCheckbox(QPainter* painter, int y, bool state)
@ -660,10 +689,10 @@ void CPUSideBar::drawStraightArrow(QPainter* painter, int x1, int y1, int x2, in
painter->drawLine(x2 - 1, y2, x2 - ArrowSizeX, y2 + ArrowSizeY - 1);// Arrow bottom
}
void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines)
void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vector<LabelArrow> & labelArrows)
{
unsigned int* numLines = new unsigned int[viewableRows];
memset(numLines, 0, sizeof(unsigned int) * viewableRows);
unsigned int* numLines = new unsigned int[viewableRows * 2]; // Low:jump offsets of the vertical jumping line, High:jump offsets of the horizontal jumping line.
memset(numLines, 0, sizeof(unsigned int) * viewableRows * 2);
// preprocessing
for(size_t i = 0; i < jumpLines.size(); i++)
{
@ -707,6 +736,20 @@ void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines)
for(int j = jmp.line; j >= jmp.destLine && j >= 0; j--)
numLines[j] = jmp.jumpOffset;
}
if(jmp.line >= 0 && jmp.line < viewableRows)
numLines[jmp.line + viewableRows] = jmp.jumpOffset;
if(jmp.destLine >= 0 && jmp.destLine < viewableRows)
numLines[jmp.destLine + viewableRows] = jmp.jumpOffset;
}
// set label arrows according to jump offsets
auto viewportWidth = viewport()->width();
const int JumpPadding = 11;
for(auto i = labelArrows.begin(); i != labelArrows.end(); i++)
{
if(numLines[i->line + viewableRows] != 0)
i->endX = viewportWidth - numLines[i->line + viewableRows] * JumpPadding - 15 - fontHeight; // This expression should be consistent with drawJump
else
i->endX = viewportWidth - 1- 11 - (isFoldingGraphicsPresent(i->line) != 0 ? mBulletRadius + fontHeight : 0);
}
delete[] numLines;
}

View File

@ -43,7 +43,6 @@ protected:
void mouseReleaseEvent(QMouseEvent* e);
void mouseMoveEvent(QMouseEvent* event);
void drawLabel(QPainter* painter, int Line, const QString & Text);
void drawBullets(QPainter* painter, int line, bool ispb, bool isbpdisabled, bool isbookmark);
bool isJump(int i) const;
void drawJump(QPainter* painter, int startLine, int endLine, int jumpoffset, bool conditional, bool isexecute, bool isactive);
@ -68,12 +67,21 @@ private:
{
int line;
int destLine;
int jumpOffset;
unsigned int jumpOffset;
bool isSelected;
bool isConditional;
bool isJumpGoingToExecute;
};
void AllocateJumpOffsets(std::vector<JumpLine> & jumpLines);
struct LabelArrow
{
int line;
int startX;
int endX;
};
void AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vector<LabelArrow> & labelArrows);
LabelArrow drawLabel(QPainter* painter, int Line, const QString & Text);
void drawLabelArrows(QPainter* painter, const std::vector<LabelArrow> & labelArrows);
// Configuration
QColor mBackgroundColor;

View File

@ -310,13 +310,10 @@ void CPUStack::refreshShortcutsSlot()
void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & richText)
{
// Compute RVA
dsint wRva = rva;
duint wVa = rvaToVa(wRva);
// Compute VA
duint wVa = rvaToVa(rva);
bool wActiveStack = true;
if(wVa < mCsp) //inactive stack
wActiveStack = false;
bool wActiveStack = (wVa >= mCsp); //inactive stack
STACK_COMMENT comment;
RichTextPainter::CustomRichText_t curData;
@ -337,7 +334,7 @@ void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & ric
}
}
}
else if(col && DbgStackCommentGet(rvaToVa(wRva), &comment)) //paint stack comments
else if(col && DbgStackCommentGet(wVa, &comment)) //paint stack comments
{
if(wActiveStack)
{
@ -407,7 +404,7 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
if(background.alpha())
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background when defined
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(wVa));
return "";
return QString();
}
return HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);;
}

View File

@ -13,22 +13,31 @@ CallStackView::CallStackView(StdTable* parent) : StdTable(parent)
connect(Bridge::getBridge(), SIGNAL(updateCallStack()), this, SLOT(updateCallStack()));
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot()));
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(followTo()));
setupContextMenu();
}
void CallStackView::setupContextMenu()
{
mFollowAddress = new QAction(tr("Follow &Address"), this);
connect(mFollowAddress, SIGNAL(triggered()), this, SLOT(followAddress()));
mFollowTo = new QAction(tr("Follow &To"), this);
mMenuBuilder = new MenuBuilder(this, [](QMenu*)
{
return DbgIsDebugging();
});
mMenuBuilder->addAction(makeAction(tr("Follow &Address"), SLOT(followAddress())));
QAction* mFollowTo = mMenuBuilder->addAction(makeAction(tr("Follow &To"), SLOT(followTo())));
mFollowTo->setShortcutContext(Qt::WidgetShortcut);
mFollowTo->setShortcut(QKeySequence("enter"));
connect(mFollowTo, SIGNAL(triggered()), this, SLOT(followTo()));
connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followTo()));
mFollowFrom = new QAction(tr("Follow &From"), this);
connect(mFollowFrom, SIGNAL(triggered()), this, SLOT(followFrom()));
mMenuBuilder->addAction(makeAction(tr("Follow &From"), SLOT(followFrom())), [this](QMenu*)
{
return !getCellContent(getInitialSelection(), 2).isEmpty();
});
MenuBuilder* mCopyMenu = new MenuBuilder(this);
setupCopyMenu(mCopyMenu);
// Column count cannot be zero
mMenuBuilder->addSeparator();
mMenuBuilder->addMenu(makeMenu(DIcon("copy.png"), tr("&Copy")), mCopyMenu);
}
void CallStackView::updateCallStack()
@ -41,13 +50,13 @@ void CallStackView::updateCallStack()
setRowCount(callstack.total);
for(int i = 0; i < callstack.total; i++)
{
QString addrText = QString("%1").arg((duint)callstack.entries[i].addr, sizeof(duint) * 2, 16, QChar('0')).toUpper();
QString addrText = ToPtrString(callstack.entries[i].addr);
setCellContent(i, 0, addrText);
addrText = QString("%1").arg((duint)callstack.entries[i].to, sizeof(duint) * 2, 16, QChar('0')).toUpper();
addrText = ToPtrString(callstack.entries[i].to);
setCellContent(i, 1, addrText);
if(callstack.entries[i].from)
{
addrText = QString("%1").arg((duint)callstack.entries[i].from, sizeof(duint) * 2, 16, QChar('0')).toUpper();
addrText = ToPtrString(callstack.entries[i].from);
setCellContent(i, 2, addrText);
}
setCellContent(i, 3, callstack.entries[i].comment);
@ -59,29 +68,11 @@ void CallStackView::updateCallStack()
void CallStackView::contextMenuSlot(const QPoint pos)
{
if(!DbgIsDebugging())
return;
QMenu wMenu(this); //create context menu
wMenu.addAction(mFollowAddress);
wMenu.addAction(mFollowTo);
QString wStr = getCellContent(getInitialSelection(), 2);
if(wStr.length())
wMenu.addAction(mFollowFrom);
QMenu wCopyMenu(tr("&Copy"), this);
setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
{
wMenu.addSeparator();
wMenu.addMenu(&wCopyMenu);
}
mMenuBuilder->build(&wMenu);
wMenu.exec(mapToGlobal(pos)); //execute context menu
}
void CallStackView::doubleClickedSlot()
{
followTo();
}
void CallStackView::followAddress()
{
QString addrText = getCellContent(getInitialSelection(), 0);

View File

@ -16,15 +16,12 @@ signals:
protected slots:
void updateCallStack();
void contextMenuSlot(const QPoint pos);
void doubleClickedSlot();
void followAddress();
void followTo();
void followFrom();
private:
QAction* mFollowAddress;
QAction* mFollowTo;
QAction* mFollowFrom;
MenuBuilder* mMenuBuilder;
};
#endif // CALLSTACKVIEW_H

View File

@ -1407,7 +1407,8 @@ void MainWindow::changeCommandLine()
void MainWindow::displayManual()
{
// Open the Windows CHM in the upper directory
QDesktopServices::openUrl(QUrl(QUrl::fromLocalFile(QString("%1/../x64dbg.chm").arg(QCoreApplication::applicationDirPath()))));
if(!QDesktopServices::openUrl(QUrl(QUrl::fromLocalFile(QString("%1/../x64dbg.chm").arg(QCoreApplication::applicationDirPath())))))
SimpleErrorBox(this, tr("Error"), tr("Manual cannot be opened. Please check if x64dbg.chm exists and ensure there is no other problems with your system."));
}
void MainWindow::decompileAt(dsint start, dsint end)

View File

@ -97,6 +97,11 @@ public:
return true;
}
inline bool empty() const
{
return _containers.empty();
}
private:
struct Container
{
@ -109,7 +114,8 @@ private:
};
inline Container()
: type(Separator)
: type(Separator),
action(nullptr)
{
}