1
0
Fork 0

DBG: removed benchmark code

DBG: fixed a bug in the definition of disasm_fast.h
DBG: added command 'ref' (to search for references to addresses/values/constants)
DBG: added simple (but useful) reference API (reference.cpp)
DBG: fixed a bug in valfromstring
GUI: added Follow address context menus to ReferenceView
GUI: added Follow in Dump to symbol view context menu
GUI: added '*' to settings that require a restart of the debuggee
This commit is contained in:
Mr. eXoDia 2014-04-04 16:48:09 +02:00
parent 258ed71d48
commit e5ab01f63f
17 changed files with 235 additions and 71 deletions

View File

@ -1757,58 +1757,6 @@ CMDRESULT cbDebugMemset(int argc, char* argv[])
CMDRESULT cbBenchmark(int argc, char* argv[])
{
if(argc<2)
{
dputs("not enough arguments");
return STATUS_ERROR;
}
uint addr=0;
if(!valfromstring(argv[1], &addr, false))
return STATUS_ERROR;
uint ticks=GetTickCount();
int count=0;
uint size=0;
uint base=memfindbaseaddr(fdProcessInfo->hProcess, addr, &size);
if(!base or !size)
{
dputs("invalid memory page");
return STATUS_ERROR;
}
unsigned char* data=(unsigned char*)emalloc(size);
if(!memread(fdProcessInfo->hProcess, (const void*)base, data, size, 0))
{
dputs("error reading memory");
efree(data);
return STATUS_ERROR;
}
dprintf("memread:%"fext"X:%ums\n", size, GetTickCount()-ticks);
ticks=GetTickCount();
DISASM disasm;
memset(&disasm, 0, sizeof(disasm));
#ifdef _WIN64
disasm.Archi=64;
#endif // _WIN64
disasm.EIP=(UIntPtr)data;
disasm.VirtualAddr=(UInt64)data;
uint i=0;
BASIC_INSTRUCTION_INFO basicinfo;
while(i<size)
{
int len=Disasm(&disasm);
if(len!=UNKNOWN_OPCODE)
{
//fillbasicinfo(&disasm, &basicinfo);
count++;
}
else
len=1;
disasm.EIP+=len;
disasm.VirtualAddr+=len;
i+=len;
}
efree(data);
dprintf("disasmget:%u:%ums\n", count, GetTickCount()-ticks);
return STATUS_CONTINUE;
}

View File

@ -1,4 +1,5 @@
#ifndef _DISASM_FAST_H
#define _DISASM_FAST_H
#include "_global.h"
#include "BeaEngine\BeaEngine.h"

View File

@ -9,6 +9,8 @@
#include "debugger.h"
#include "memory.h"
#include "x64_dbg.h"
#include "disasm_fast.h"
#include "reference.h"
static bool bRefinit=false;
@ -733,6 +735,63 @@ CMDRESULT cbInstrRefadd(int argc, char* argv[])
return STATUS_CONTINUE;
}
//reffind value[,page]
static bool cbRefFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
{
if(!refinfo) //initialize
{
GuiReferenceAddColumn(2*sizeof(uint), "Address");
GuiReferenceAddColumn(0, "Disassembly");
return true;
}
bool found=false;
uint value=(uint)refinfo->userinfo;
if((basicinfo->type&TYPE_VALUE)==TYPE_VALUE)
{
if(basicinfo->value.value==value)
found=true;
}
if((basicinfo->type&TYPE_MEMORY)==TYPE_MEMORY)
{
if(basicinfo->memory.value==value)
found=true;
}
if((basicinfo->type&TYPE_ADDR)==TYPE_ADDR)
{
if(basicinfo->addr==value)
found=true;
}
if(found)
{
char addrText[20]="";
sprintf(addrText, "%p", disasm->VirtualAddr);
GuiReferenceSetRowCount(refinfo->refcount+1);
GuiReferenceSetCellContent(refinfo->refcount, 0, addrText);
GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->CompleteInstr);
}
return found;
}
CMDRESULT cbInstrRefFind(int argc, char* argv[])
{
if(argc<2)
{
puts("not enough arguments!");
return STATUS_ERROR;
}
uint value=0;
if(!valfromstring(argv[1], &value, false))
return STATUS_ERROR;
uint addr=0;
if(argc<3 or !valfromstring(argv[2], &addr, true))
addr=GetContextData(UE_CIP);
int found=reffind(addr, cbRefFind, (void*)value, false);
char cmd[256]="";
sprintf(cmd, "$result=%u", found);
DbgCmdExec(cmd);
return STATUS_CONTINUE;
}
CMDRESULT cbInstrSetstr(int argc, char* argv[])
{
if(argc<3)

View File

@ -44,6 +44,7 @@ CMDRESULT cbInstrXor(int argc, char* argv[]);
CMDRESULT cbInstrRefinit(int argc, char* argv[]);
CMDRESULT cbInstrRefadd(int argc, char* argv[]);
CMDRESULT cbInstrRefFind(int argc, char* argv[]);
CMDRESULT cbInstrSetstr(int argc, char* argv[]);
CMDRESULT cbInstrGetstr(int argc, char* argv[]);

61
x64_dbg_dbg/reference.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "reference.h"
#include "debugger.h"
#include "memory.h"
#include "console.h"
int reffind(uint addr, CBREF cbRef, void* userinfo, bool silent)
{
uint size=0;
uint base=memfindbaseaddr(fdProcessInfo->hProcess, addr, &size);
if(!base or !size)
{
if(!silent)
dputs("invalid memory page");
return 0;
}
unsigned char* data=(unsigned char*)emalloc(size);
if(!memread(fdProcessInfo->hProcess, (const void*)base, data, size, 0))
{
if(!silent)
dputs("error reading memory");
efree(data);
return 0;
}
DISASM disasm;
memset(&disasm, 0, sizeof(disasm));
#ifdef _WIN64
disasm.Archi=64;
#endif // _WIN64
disasm.EIP=(UIntPtr)data;
disasm.VirtualAddr=(UInt64)base;
uint i=0;
BASIC_INSTRUCTION_INFO basicinfo;
cbRef(&disasm, &basicinfo, 0); //allow initializing
REFINFO refinfo;
memset(&refinfo, 0, sizeof(REFINFO));
refinfo.userinfo=userinfo;
while(i<size)
{
if(!(i%0x1000))
{
double percent=(double)i/(double)size;
GuiReferenceSetProgress((int)(percent*100));
}
int len=Disasm(&disasm);
if(len!=UNKNOWN_OPCODE)
{
fillbasicinfo(&disasm, &basicinfo);
if(cbRef(&disasm, &basicinfo, &refinfo))
refinfo.refcount++;
}
else
len=1;
disasm.EIP+=len;
disasm.VirtualAddr+=len;
i+=len;
}
GuiReferenceSetProgress(100);
GuiReferenceReloadData();
efree(data);
return refinfo.refcount;
}

20
x64_dbg_dbg/reference.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef _REFERENCE_H
#define _REFERENCE_H
#include "_global.h"
#include "disasm_fast.h"
//structs
struct REFINFO
{
int refcount;
void* userinfo;
};
//typedefs
typedef bool (*CBREF)(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo);
//functions
int reffind(uint page, CBREF cbRef, void* userinfo, bool silent);
#endif //_REFERENCE_H

View File

@ -1141,7 +1141,7 @@ static bool ishexnumber(const char* string)
bool valfromstring(const char* string, uint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly)
{
if(!value)
if(!value or !string)
return false;
else if(*string=='.' and string[1]=='-' and string[2]) //negative decimal number
{

View File

@ -147,6 +147,7 @@ static void registercommands()
cmdnew(cmd, "refinit", cbInstrRefinit, false);
cmdnew(cmd, "refadd", cbInstrRefadd, false);
cmdnew(cmd, "reffind\1findref\1ref", cbInstrRefFind, true);
cmdnew(cmd, "setstr\1strset", cbInstrSetstr, false); //set a string variable
cmdnew(cmd, "getstr\1strget", cbInstrGetstr, false); //get a string variable

View File

@ -110,6 +110,8 @@
<Unit filename="msgqueue.h" />
<Unit filename="plugin_loader.cpp" />
<Unit filename="plugin_loader.h" />
<Unit filename="reference.cpp" />
<Unit filename="reference.h" />
<Unit filename="simplescript.cpp" />
<Unit filename="simplescript.h" />
<Unit filename="sqlhelper.cpp" />

View File

@ -26,6 +26,7 @@
<ClCompile Include="memory.cpp" />
<ClCompile Include="msgqueue.cpp" />
<ClCompile Include="plugin_loader.cpp" />
<ClCompile Include="reference.cpp" />
<ClCompile Include="simplescript.cpp" />
<ClCompile Include="sqlhelper.cpp" />
<ClCompile Include="stackinfo.cpp" />
@ -56,6 +57,7 @@
<ClInclude Include="memory.h" />
<ClInclude Include="msgqueue.h" />
<ClInclude Include="plugin_loader.h" />
<ClInclude Include="reference.h" />
<ClInclude Include="simplescript.h" />
<ClInclude Include="sqlhelper.h" />
<ClInclude Include="stackinfo.h" />

View File

@ -96,6 +96,9 @@
<ClCompile Include="disasm_fast.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="reference.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="_exports.h">
@ -188,5 +191,8 @@
<ClInclude Include="disasm_fast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="reference.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -22,6 +22,18 @@ ReferenceView::ReferenceView()
connect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData()));
connect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int,bool)), this, SLOT(setSingleSelection(int,bool)));
connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchProgress, SLOT(setValue(int)));
connect(this, SIGNAL(listContextMenuSignal(QPoint)), this, SLOT(referenceContextMenu(QPoint)));
setupContextMenu();
}
void ReferenceView::setupContextMenu()
{
mFollowAddress = new QAction("&Follow in Disassembler", this);
connect(mFollowAddress, SIGNAL(triggered()), this, SLOT(followAddress()));
mFollowDumpAddress = new QAction("Follow in &Dump", this);
connect(mFollowDumpAddress, SIGNAL(triggered()), this, SLOT(followDumpAddress()));
}
void ReferenceView::addColumnAt(int width, QString title)
@ -69,3 +81,31 @@ void ReferenceView::setSingleSelection(int index, bool scroll)
if(scroll) //TODO: better scrolling
mList->setTableOffset(index);
}
void ReferenceView::referenceContextMenu(const QPoint &pos)
{
if(!this->mCurList->getRowCount())
return;
const char* addrText = this->mCurList->getCellContent(this->mCurList->getInitialSelection(), 0).toUtf8().constData();
if(!DbgIsValidExpression(addrText))
return;
uint_t addr = DbgValFromString(addrText);
if(!DbgMemIsValidReadPtr(addr))
return;
QMenu* wMenu = new QMenu(this);
wMenu->addAction(mFollowAddress);
wMenu->addAction(mFollowDumpAddress);
wMenu->exec(pos);
}
void ReferenceView::followAddress()
{
DbgCmdExecDirect(QString("disasm " + this->mCurList->getCellContent(this->mCurList->getInitialSelection(), 0)).toUtf8().constData());
emit showCpu();
}
void ReferenceView::followDumpAddress()
{
DbgCmdExecDirect(QString("dump " + this->mCurList->getCellContent(this->mCurList->getInitialSelection(), 0)).toUtf8().constData());
emit showCpu();
}

View File

@ -2,6 +2,7 @@
#define REFERENCEVIEW_H
#include <QProgressBar>
#include <QAction>
#include "SearchListView.h"
#include "Bridge.h"
@ -11,6 +12,7 @@ class ReferenceView : public SearchListView
public:
ReferenceView();
void setupContextMenu();
private slots:
void addColumnAt(int width, QString title);
@ -19,9 +21,17 @@ private slots:
void setCellContent(int r, int c, QString s);
void reloadData();
void setSingleSelection(int index, bool scroll);
void referenceContextMenu(const QPoint & pos);
void followAddress();
void followDumpAddress();
signals:
void showCpu();
private:
QProgressBar* mSearchProgress;
QAction* mFollowAddress;
QAction* mFollowDumpAddress;
};
#endif // REFERENCEVIEW_H

View File

@ -84,6 +84,9 @@ void SymbolView::setupContextMenu()
mFollowSymbolAction = new QAction("&Follow in Disassembler", this);
connect(mFollowSymbolAction, SIGNAL(triggered()), this, SLOT(symbolFollow()));
mFollowSymbolDumpAction = new QAction("Follow in &Dump", this);
connect(mFollowSymbolDumpAction, SIGNAL(triggered()), this, SLOT(symbolFollowDump()));
mCopySymbolAddress = new QAction("Copy &Address", this);
connect(mCopySymbolAddress, SIGNAL(triggered()), this, SLOT(symbolAddressCopy()));
@ -163,6 +166,7 @@ void SymbolView::symbolContextMenu(const QPoint & pos)
return;
QMenu* wMenu = new QMenu(this);
wMenu->addAction(mFollowSymbolAction);
wMenu->addAction(mFollowSymbolDumpAction);
wMenu->addSeparator();
wMenu->addAction(mCopySymbolAddress);
wMenu->addAction(mCopyDecoratedSymbolAction);
@ -177,6 +181,12 @@ void SymbolView::symbolFollow()
emit showCpu();
}
void SymbolView::symbolFollowDump()
{
DbgCmdExecDirect(QString("dump " + mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0)).toUtf8().constData());
emit showCpu();
}
void SymbolView::symbolAddressCopy()
{
Bridge::CopyToClipboard(mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0).toUtf8().constData());

View File

@ -28,6 +28,7 @@ private slots:
void moduleSelectionChanged(int index);
void updateSymbolList(int module_count, SYMBOLMODULEINFO* modules);
void symbolFollow();
void symbolFollowDump();
void symbolContextMenu(const QPoint & pos);
void symbolAddressCopy();
void symbolDecoratedCopy();
@ -45,6 +46,7 @@ private:
StdTable* mModuleList;
QList<uint_t> mModuleBaseList;
QAction* mFollowSymbolAction;
QAction* mFollowSymbolDumpAction;
QAction* mCopySymbolAddress;
QAction* mCopyDecoratedSymbolAction;
QAction* mCopyUndecoratedSymbolAction;

View File

@ -123,6 +123,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(ui->actionCpu,SIGNAL(triggered()),this,SLOT(displayCpuWidget()));
connect(ui->actionSymbolInfo,SIGNAL(triggered()),this,SLOT(displaySymbolWidget()));
connect(mSymbolView,SIGNAL(showCpu()),this,SLOT(displayCpuWidget()));
connect(mReferenceView,SIGNAL(showCpu()),this,SLOT(displayCpuWidget()));
connect(ui->actionReferences,SIGNAL(triggered()),this,SLOT(displayReferencesWidget()));
connect(ui->actionThreads,SIGNAL(triggered()),this,SLOT(displayThreadsWidget()));
connect(ui->actionSettings,SIGNAL(triggered()),this,SLOT(openSettings()));

View File

@ -63,12 +63,12 @@
<rect>
<x>20</x>
<y>30</y>
<width>111</width>
<width>121</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>System Breakpoint</string>
<string>System Breakpoint*</string>
</property>
<property name="checked">
<bool>false</bool>
@ -79,12 +79,12 @@
<rect>
<x>20</x>
<y>50</y>
<width>111</width>
<width>121</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>TLS Callbacks</string>
<string>TLS Callbacks*</string>
</property>
<property name="checked">
<bool>false</bool>
@ -95,12 +95,12 @@
<rect>
<x>20</x>
<y>70</y>
<width>111</width>
<width>121</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Entry Breakpoint</string>
<string>Entry Breakpoint*</string>
</property>
<property name="checked">
<bool>false</bool>
@ -109,9 +109,9 @@
<widget class="QCheckBox" name="chkDllLoad">
<property name="geometry">
<rect>
<x>140</x>
<x>150</x>
<y>30</y>
<width>111</width>
<width>101</width>
<height>17</height>
</rect>
</property>
@ -122,9 +122,9 @@
<widget class="QCheckBox" name="chkDllUnload">
<property name="geometry">
<rect>
<x>140</x>
<x>150</x>
<y>50</y>
<width>111</width>
<width>101</width>
<height>17</height>
</rect>
</property>
@ -135,9 +135,9 @@
<widget class="QCheckBox" name="chkThreadStart">
<property name="geometry">
<rect>
<x>140</x>
<x>150</x>
<y>70</y>
<width>111</width>
<width>101</width>
<height>17</height>
</rect>
</property>
@ -148,9 +148,9 @@
<widget class="QCheckBox" name="chkThreadEnd">
<property name="geometry">
<rect>
<x>140</x>
<x>150</x>
<y>90</y>
<width>111</width>
<width>101</width>
<height>17</height>
</rect>
</property>
@ -161,9 +161,9 @@
<widget class="QCheckBox" name="chkDebugStrings">
<property name="geometry">
<rect>
<x>140</x>
<x>150</x>
<y>110</y>
<width>111</width>
<width>101</width>
<height>17</height>
</rect>
</property>
@ -176,7 +176,7 @@
<rect>
<x>20</x>
<y>90</y>
<width>111</width>
<width>121</width>
<height>17</height>
</rect>
</property>
@ -189,7 +189,7 @@
<rect>
<x>20</x>
<y>110</y>
<width>111</width>
<width>121</width>
<height>17</height>
</rect>
</property>