mirror of
https://github.com/x64dbg/x64dbg.git
synced 2025-02-20 04:51:31 +00:00
Remove some performance bottlenecks from the memory map update
Thanks to @AnthonyPrintup for bringing this to my attention
This commit is contained in:
parent
f56fa5ce23
commit
3eb2070c3a
@ -33,9 +33,9 @@ MemoryMapView::MemoryMapView(StdTable* parent)
|
||||
loadColumnFromConfig("MemoryMap");
|
||||
setIconColumn(ColParty);
|
||||
|
||||
connect(Bridge::getBridge(), SIGNAL(updateMemory()), this, SLOT(refreshMap()));
|
||||
connect(Bridge::getBridge(), SIGNAL(updateMemory()), this, SLOT(refreshMapSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(stateChangedSlot(DBGSTATE)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectInMemoryMap(duint)), this, SLOT(selectAddress(duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectInMemoryMap(duint)), this, SLOT(selectAddressSlot(duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionMemmapGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionMemmapSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
|
||||
@ -63,12 +63,12 @@ void MemoryMapView::setupContextMenu()
|
||||
|
||||
//Set PageMemory Rights
|
||||
mPageMemoryRights = new QAction(DIcon("memmap_set_page_memory_rights"), tr("Set Page Memory Rights"), this);
|
||||
connect(mPageMemoryRights, SIGNAL(triggered()), this, SLOT(pageMemoryRights()));
|
||||
connect(mPageMemoryRights, SIGNAL(triggered()), this, SLOT(pageMemoryRightsSlot()));
|
||||
|
||||
//Switch View
|
||||
mSwitchView = new QAction(DIcon("change-view"), "", this);
|
||||
setSwitchViewName();
|
||||
connect(mSwitchView, SIGNAL(triggered()), this, SLOT(switchView()));
|
||||
connect(mSwitchView, SIGNAL(triggered()), this, SLOT(switchViewSlot()));
|
||||
|
||||
//Breakpoint menu
|
||||
mBreakpointMenu = new QMenu(tr("Memory &Breakpoint"), this);
|
||||
@ -169,11 +169,11 @@ void MemoryMapView::setupContextMenu()
|
||||
//Dump
|
||||
//TODO: These two actions should also appear in CPUDump
|
||||
mDumpMemory = new QAction(DIcon("binary_save"), tr("&Dump Memory to File"), this);
|
||||
connect(mDumpMemory, SIGNAL(triggered()), this, SLOT(dumpMemory()));
|
||||
connect(mDumpMemory, SIGNAL(triggered()), this, SLOT(dumpMemorySlot()));
|
||||
|
||||
//Load
|
||||
mLoadMemory = new QAction(DIcon(""), tr("&Overwrite with Data from File"), this);
|
||||
connect(mLoadMemory, SIGNAL(triggered()), this, SLOT(loadMemory()));
|
||||
connect(mLoadMemory, SIGNAL(triggered()), this, SLOT(loadMemorySlot()));
|
||||
|
||||
//Add virtual module
|
||||
mAddVirtualMod = new QAction(DIcon("virtual"), tr("Add virtual module"), this);
|
||||
@ -272,17 +272,6 @@ void MemoryMapView::contextMenuSlot(const QPoint & pos)
|
||||
menu.exec(mapToGlobal(pos)); //execute context menu
|
||||
}
|
||||
|
||||
static QString getProtectionString(DWORD Protect)
|
||||
{
|
||||
#define RIGHTS_STRING (sizeof("ERWCG"))
|
||||
char rights[RIGHTS_STRING];
|
||||
|
||||
if(!DbgFunctions()->PageRightsToString(Protect, rights))
|
||||
return "bad";
|
||||
|
||||
return QString(rights);
|
||||
}
|
||||
|
||||
QString MemoryMapView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||
{
|
||||
if(col == 0) //address
|
||||
@ -377,14 +366,14 @@ void MemoryMapView::setSwitchViewName()
|
||||
QAction* MemoryMapView::makeCommandAction(QAction* action, const QString & command)
|
||||
{
|
||||
action->setData(QVariant(command));
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(ExecCommand()));
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(execCommandSlot()));
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MemoryMapView::ExecCommand execute command slot for menus.
|
||||
* @brief MemoryMapView::execCommandSlot execute command slot for menus.
|
||||
*/
|
||||
void MemoryMapView::ExecCommand()
|
||||
void MemoryMapView::execCommandSlot()
|
||||
{
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if(action)
|
||||
@ -404,16 +393,52 @@ void MemoryMapView::ExecCommand()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::refreshMap()
|
||||
static QString getProtectionString(DWORD protect)
|
||||
{
|
||||
//reserved pages don't have a protection (https://goo.gl/Izkk0c)
|
||||
if(protect == 0)
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
#define meme(prot, str) (prot & PAGE_GUARD) ? QStringLiteral(str QT_UNICODE_LITERAL("G")) : QStringLiteral(str QT_UNICODE_LITERAL("-"))
|
||||
|
||||
switch(protect & 0xFF)
|
||||
{
|
||||
case PAGE_NOACCESS:
|
||||
return meme(protect, "----");
|
||||
case PAGE_READONLY:
|
||||
return meme(protect, "-R--");
|
||||
case PAGE_READWRITE:
|
||||
return meme(protect, "-RW-");
|
||||
case PAGE_WRITECOPY:
|
||||
return meme(protect, "-RWC");
|
||||
case PAGE_EXECUTE:
|
||||
return meme(protect, "E---");
|
||||
case PAGE_EXECUTE_READ:
|
||||
return meme(protect, "ER--");
|
||||
case PAGE_EXECUTE_READWRITE:
|
||||
return meme(protect, "ERW-");
|
||||
case PAGE_EXECUTE_WRITECOPY:
|
||||
return meme(protect, "ERWC");
|
||||
default:
|
||||
return meme(protect, "????");
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::refreshMapSlot()
|
||||
{
|
||||
MEMMAP memoryMap = {};
|
||||
DbgMemMap(&memoryMap);
|
||||
|
||||
setRowCount(memoryMap.count);
|
||||
|
||||
auto strUser = tr("User");
|
||||
auto strSystem = tr("System");
|
||||
|
||||
for(int i = 0; i < memoryMap.count; i++)
|
||||
{
|
||||
const auto & mbi = (memoryMap.page)[i].mbi;
|
||||
const auto & mbi = memoryMap.page[i].mbi;
|
||||
|
||||
// Base address
|
||||
setCellContent(i, ColAddress, ToPtrString((duint)mbi.BaseAddress));
|
||||
@ -428,11 +453,11 @@ void MemoryMapView::refreshMap()
|
||||
switch(party)
|
||||
{
|
||||
case mod_user:
|
||||
setCellContent(i, ColParty, tr("User"));
|
||||
setCellContent(i, ColParty, strUser);
|
||||
setRowIcon(i, DIcon("markasuser"));
|
||||
break;
|
||||
case mod_system:
|
||||
setCellContent(i, ColParty, tr("System"));
|
||||
setCellContent(i, ColParty, strSystem);
|
||||
setRowIcon(i, DIcon("markassystem"));
|
||||
break;
|
||||
default:
|
||||
@ -442,64 +467,62 @@ void MemoryMapView::refreshMap()
|
||||
}
|
||||
|
||||
// Information
|
||||
auto content = QString((memoryMap.page)[i].info);
|
||||
setCellContent(i, ColPageInfo, content);
|
||||
auto info = memoryMap.page[i].info;
|
||||
setCellContent(i, ColPageInfo, info);
|
||||
|
||||
// Content, TODO: proper section content analysis in dbg/memory.cpp:MemUpdateMap
|
||||
QString content;
|
||||
char comment_text[MAX_COMMENT_SIZE];
|
||||
if(DbgFunctions()->GetUserComment((duint)mbi.BaseAddress, comment_text)) // user comment present
|
||||
content = comment_text;
|
||||
else if(content.contains(".bss"))
|
||||
else if(strncmp(info, ".bss", 4) == 0)
|
||||
content = tr("Uninitialized data");
|
||||
else if(content.contains(".data"))
|
||||
else if(strncmp(info, ".data", 5) == 0)
|
||||
content = tr("Initialized data");
|
||||
else if(content.contains(".edata"))
|
||||
else if(strncmp(info, ".edata", 6) == 0)
|
||||
content = tr("Export tables");
|
||||
else if(content.contains(".idata"))
|
||||
else if(strncmp(info, ".idata", 6) == 0)
|
||||
content = tr("Import tables");
|
||||
else if(content.contains(".pdata"))
|
||||
else if(strncmp(info, ".pdata", 6) == 0)
|
||||
content = tr("Exception information");
|
||||
else if(content.contains(".rdata"))
|
||||
else if(strncmp(info, ".rdata", 6) == 0)
|
||||
content = tr("Read-only initialized data");
|
||||
else if(content.contains(".reloc"))
|
||||
else if(strncmp(info, ".reloc", 6) == 0)
|
||||
content = tr("Base relocations");
|
||||
else if(content.contains(".rsrc"))
|
||||
else if(strncmp(info, ".rsrc", 5) == 0)
|
||||
content = tr("Resources");
|
||||
else if(content.contains(".text"))
|
||||
else if(strncmp(info, ".text", 5) == 0)
|
||||
content = tr("Executable code");
|
||||
else if(content.contains(".tls"))
|
||||
else if(strncmp(info, ".tls", 4) == 0)
|
||||
content = tr("Thread-local storage");
|
||||
else if(content.contains(".xdata"))
|
||||
else if(strncmp(info, ".xdata", 6) == 0)
|
||||
content = tr("Exception information");
|
||||
else
|
||||
content = QString("");
|
||||
setCellContent(i, ColContent, std::move(content));
|
||||
|
||||
// Type
|
||||
const char* type = "";
|
||||
QString type;
|
||||
switch(mbi.Type)
|
||||
{
|
||||
case MEM_IMAGE:
|
||||
type = "IMG";
|
||||
type = QStringLiteral("IMG");
|
||||
break;
|
||||
case MEM_MAPPED:
|
||||
type = "MAP";
|
||||
type = QStringLiteral("MAP");
|
||||
break;
|
||||
case MEM_PRIVATE:
|
||||
type = "PRV";
|
||||
type = QStringLiteral("PRV");
|
||||
break;
|
||||
default:
|
||||
type = "N/A";
|
||||
type = QStringLiteral("N/A");
|
||||
break;
|
||||
}
|
||||
setCellContent(i, ColAllocation, type);
|
||||
setCellContent(i, ColAllocation, std::move(type));
|
||||
|
||||
// current access protection
|
||||
setCellContent(i, ColCurProtect, getProtectionString(mbi.Protect));
|
||||
|
||||
// allocation protection
|
||||
setCellContent(i, ColAllocProtect, getProtectionString(mbi.AllocationProtect));
|
||||
|
||||
}
|
||||
if(memoryMap.page != 0)
|
||||
BridgeFree(memoryMap.page);
|
||||
@ -509,7 +532,7 @@ void MemoryMapView::refreshMap()
|
||||
void MemoryMapView::stateChangedSlot(DBGSTATE state)
|
||||
{
|
||||
if(state == paused)
|
||||
refreshMap();
|
||||
refreshMapSlot();
|
||||
}
|
||||
|
||||
void MemoryMapView::followDumpSlot()
|
||||
@ -554,16 +577,16 @@ void MemoryMapView::memoryExecuteSingleshootToggleSlot()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::pageMemoryRights()
|
||||
void MemoryMapView::pageMemoryRightsSlot()
|
||||
{
|
||||
PageMemoryRights PageMemoryRightsDialog(this);
|
||||
connect(&PageMemoryRightsDialog, SIGNAL(refreshMemoryMap()), this, SLOT(refreshMap()));
|
||||
connect(&PageMemoryRightsDialog, SIGNAL(refreshMemoryMap()), this, SLOT(refreshMapSlot()));
|
||||
duint addr = getSelectionAddr();
|
||||
duint size = getCellUserdata(getInitialSelection(), ColSize);
|
||||
PageMemoryRightsDialog.RunAddrSize(addr, size, getCellContent(getInitialSelection(), ColCurProtect));
|
||||
}
|
||||
|
||||
void MemoryMapView::switchView()
|
||||
void MemoryMapView::switchViewSlot()
|
||||
{
|
||||
Config()->setBool("Engine", "ListAllPages", !ConfigBool("Engine", "ListAllPages"));
|
||||
Config()->writeBools();
|
||||
@ -632,7 +655,7 @@ void MemoryMapView::findPatternSlot()
|
||||
emit showReferences();
|
||||
}
|
||||
|
||||
void MemoryMapView::dumpMemory()
|
||||
void MemoryMapView::dumpMemorySlot()
|
||||
{
|
||||
duint start = 0;
|
||||
duint end = 0;
|
||||
@ -665,7 +688,7 @@ void MemoryMapView::dumpMemory()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::loadMemory()
|
||||
void MemoryMapView::loadMemorySlot()
|
||||
{
|
||||
auto modname = mainModuleName();
|
||||
if(!modname.isEmpty())
|
||||
@ -682,7 +705,7 @@ void MemoryMapView::loadMemory()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::selectAddress(duint va)
|
||||
void MemoryMapView::selectAddressSlot(duint va)
|
||||
{
|
||||
auto base = DbgMemFindBaseAddr(va, nullptr);
|
||||
if(base)
|
||||
@ -703,7 +726,7 @@ void MemoryMapView::selectAddress(duint va)
|
||||
|
||||
void MemoryMapView::gotoOriginSlot()
|
||||
{
|
||||
selectAddress(mCipBase);
|
||||
selectAddressSlot(mCipBase);
|
||||
}
|
||||
|
||||
void MemoryMapView::gotoExpressionSlot()
|
||||
@ -714,7 +737,7 @@ void MemoryMapView::gotoExpressionSlot()
|
||||
mGoto->setInitialExpression(ToPtrString(getSelectionAddr()));
|
||||
if(mGoto->exec() == QDialog::Accepted)
|
||||
{
|
||||
selectAddress(DbgValFromString(mGoto->expressionText.toUtf8().constData()));
|
||||
selectAddressSlot(DbgValFromString(mGoto->expressionText.toUtf8().constData()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,16 +24,16 @@ public slots:
|
||||
void doubleClickedSlot();
|
||||
void memoryExecuteSingleshootToggleSlot();
|
||||
void memoryAllocateSlot();
|
||||
void ExecCommand();
|
||||
void execCommandSlot();
|
||||
void contextMenuSlot(const QPoint & pos);
|
||||
void switchView();
|
||||
void pageMemoryRights();
|
||||
void refreshMap();
|
||||
void switchViewSlot();
|
||||
void pageMemoryRightsSlot();
|
||||
void refreshMapSlot();
|
||||
void findPatternSlot();
|
||||
void dumpMemory();
|
||||
void loadMemory();
|
||||
void dumpMemorySlot();
|
||||
void loadMemorySlot();
|
||||
void commentSlot();
|
||||
void selectAddress(duint va);
|
||||
void selectAddressSlot(duint va);
|
||||
void gotoOriginSlot();
|
||||
void gotoExpressionSlot();
|
||||
void addVirtualModSlot();
|
||||
|
@ -19,11 +19,11 @@ inline QString ToPtrString(duint Address)
|
||||
|
||||
char temp[32];
|
||||
#ifdef _WIN64
|
||||
sprintf_s(temp, "%016llX", Address);
|
||||
auto size = sprintf_s(temp, "%016llX", Address);
|
||||
#else
|
||||
sprintf_s(temp, "%08X", Address);
|
||||
auto size = sprintf_s(temp, "%08X", Address);
|
||||
#endif // _WIN64
|
||||
return QString(temp);
|
||||
return QString::fromLatin1(temp, size);
|
||||
}
|
||||
|
||||
inline QString ToLongLongHexString(unsigned long long Value)
|
||||
|
Loading…
x
Reference in New Issue
Block a user