1
0
Fork 0

Merge branch 'master' into doxygen

Conflicts:
	x64_dbg_bridge/bridgemain.cpp
This commit is contained in:
Mr. eXoDia 2014-12-30 02:33:02 +01:00
commit 8fb7527d41
34 changed files with 373 additions and 161 deletions

View File

@ -49,21 +49,36 @@ numbers are interpreted as hex by default. If you want to be sure, you can use
the "x" prefix or the "0x" prefix. Decimal numbers can be used by prefixing the
number with a "." (.123=7B).</P>
<P class=rvps3><U>basic calculations</U>: See "Calculations" for more information.</P>
<P class=rvps3><U>DLL exports</U>: Type
'GetProcAddress' and it will automatically be resolved to the actual address of
the function. To explicitly define from which module
to load the API, use: "[module].dll:[api]" or "[module]:[api]". In a similar
way you can resolve ordinals, try "[module]:[ordinal]". Another macro allows you to get the
loaded base of a module. Try "[module]:0",
"[module]:base", "[module]:imagebase" or "[module]:header". When "[module]" is an empty string (":0" for example), the
<P class=rvps3><U>Module Data</U>:</P>
<OL>
<LI>
<DIV class=rvps3><U>DLL exports</U>:
Type 'GetProcAddress' and it will automatically be
resolved to the actual address of the function.
To explicitly define from which module to load the API, use:
"[module].dll:[api]" or "[module]:[api]". In a similar way you can resolve ordinals, try "[module]:[ordinal]". Another
macro allows you to get the loaded
base of a module. When "[module]" is an empty string (":GetProcAddress" for example), the
module that is currently selected in the CPU will be
used.</P>
<P class=rvps3><U>RVA/File Offset</U>:
If you want to access a module RVA you can either write "[module]:0+[rva]" or
you can write "[module]:$[rva]". If you want
to convert a file offset to a VA you can use "[module]:#[offset]". When "[module]" is
an empty string (":0" for example), the module that is currently selected in the CPU will
be used.</P>
used.</DIV><U> </U>
<LI><U>Loaded Module&nbsp;Bases</U>:
If you want to access the loaded module base, you can write: "[module]:0",
"[module]:base", "[module]:imagebase" or "[module]:header".
<LI><U>RVA/File Offset</U>: If you
want to access a module RVA you can either write "[module]:0+[rva]" or you can
write "[module]:$[rva]". If you want to convert a file offset to a VA you can
use "[module]:#[offset]". When "[module]" is an empty string (":0" for
example), the module that is currently selected in the CPU will be used.
<LI><U>Module Entry Points</U>: To
access a module entry point you can write "[module]:entry", "[module]:oep" or
"[module]:ep". Notice that when there are exports with the names "entry",
"oep" or "ep" the address of these will be returned
instead.<BR><BR><STRONG>Notice</STRONG>: Instead of the ':' delimiter you can
also use a '.' If you need to query module information such as
"[module]:imagebase" or "[module]":entry" you are adviced to
use a '?' as delimiter instead ("[module]?entry"). The '?'&nbsp;does
checking for named exports later, so it will still work when there is an
export called "entry" in the module.</LI></OL>
<P class=rvps3><U>labels/symbols</U>:
user-defined labels and symbols&nbsp;are a valid expressions.</P>
<P class=rvps3><STRONG>Input for arguments can always be done in any of

View File

@ -910,6 +910,10 @@ BRIDGE_IMPEXP void GuiReferenceDeleteAllColumns()
_gui_sendmessage(GUI_REF_DELETEALLCOLUMNS, 0, 0);
}
BRIDGE_IMPEXP void GuiReferenceInitialize(const char* name)
{
_gui_sendmessage(GUI_REF_INITIALIZE, (void*)name, 0);
}
BRIDGE_IMPEXP void GuiReferenceSetCellContent(int row, int col, const char* str)
{

View File

@ -724,16 +724,16 @@ typedef enum
GUI_GETLINE_WINDOW, // param1=const char* title, param2=char* text
GUI_AUTOCOMPLETE_ADDCMD, // param1=const char* cmd, param2=ununsed
GUI_AUTOCOMPLETE_DELCMD, // param1=const char* cmd, param2=ununsed
GUI_AUTOCOMPLETE_CLEARALL, // param1=ununsed, param2=unused
GUI_AUTOCOMPLETE_CLEARALL, // param1=unused, param2=unused
GUI_SCRIPT_ENABLEHIGHLIGHTING, // param1=bool enable, param2=unused
GUI_ADD_MSG_TO_STATUSBAR, // param1=const char* msg, param2=unused
GUI_UPDATE_SIDEBAR, // param1=unused, param2=unused
GUI_REPAINT_TABLE_VIEW, // param1=unused, param2=unused
GUI_UPDATE_PATCHES, // param1=unused, param2=unused
GUI_UPDATE_CALLSTACK, // param1=unused, param2=unused
GUI_SYMBOL_REFRESH_CURRENT, // param1=unused, param2=unused
GUI_UPDATE_MEMORY_VIEW // param1=unused, param2=unused
GUI_SYMBOL_REFRESH_CURRENT, // param1=unused, param2=unused
GUI_UPDATE_MEMORY_VIEW, // param1=unused, param2=unused
GUI_REF_INITIALIZE // param1=const char* name param2=unused
} GUIMSG;
//GUI structures
@ -780,6 +780,7 @@ BRIDGE_IMPEXP void GuiReferenceAddColumn(int width, const char* title);
BRIDGE_IMPEXP void GuiReferenceSetRowCount(int count);
BRIDGE_IMPEXP int GuiReferenceGetRowCount();
BRIDGE_IMPEXP void GuiReferenceDeleteAllColumns();
BRIDGE_IMPEXP void GuiReferenceInitialize(const char* name);
BRIDGE_IMPEXP void GuiReferenceSetCellContent(int row, int col, const char* str);
BRIDGE_IMPEXP const char* GuiReferenceGetCellContent(int row, int col);
BRIDGE_IMPEXP void GuiReferenceReloadData();

View File

@ -169,7 +169,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
len--;
if(len)
len++;
sprintf(addrinfo->comment, "%s:%u", filename + len, line.LineNumber);
sprintf_s(addrinfo->comment, "\1%s:%u", filename + len, line.LineNumber);
retval = true;
}
else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number
@ -279,8 +279,10 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
retval = true;
}
}
comment.resize(MAX_COMMENT_SIZE - 1);
strcpy_s(addrinfo->comment, comment.c_str());
comment.resize(MAX_COMMENT_SIZE - 2);
String fullComment = "\1";
fullComment += comment;
strcpy_s(addrinfo->comment, fullComment.c_str());
}
}
}

View File

@ -387,7 +387,7 @@ bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum)
bool commentset(uint addr, const char* text, bool manual)
{
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text) >= MAX_COMMENT_SIZE - 1)
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or text[0] == '\1' or strlen(text) >= MAX_COMMENT_SIZE - 1)
return false;
if(!*text) //NOTE: delete when there is no text
{

View File

@ -766,7 +766,7 @@ CMDRESULT cbInstrXor(int argc, char* argv[])
CMDRESULT cbInstrRefinit(int argc, char* argv[])
{
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize("Script");
GuiReferenceAddColumn(sizeof(uint) * 2, "Address");
GuiReferenceAddColumn(0, "Data");
GuiReferenceSetRowCount(0);
@ -805,9 +805,9 @@ struct VALUERANGE
static bool cbRefFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
{
if(!refinfo) //initialize
if(!disasm && !basicinfo) //initialize
{
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize(refinfo->name);
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
GuiReferenceAddColumn(0, "Disassembly");
GuiReferenceReloadData();
@ -885,7 +885,7 @@ CMDRESULT cbInstrRefFindRange(int argc, char* argv[])
if(!valfromstring(argv[4], &size))
size = 0;
uint ticks = GetTickCount();
int found = reffind(addr, size, cbRefFind, &range, false);
int found = reffind(addr, size, cbRefFind, &range, false, "Constant");
dprintf("%u reference(s) in %ums\n", found, GetTickCount() - ticks);
varset("$result", found, false);
return STATUS_CONTINUE;
@ -893,9 +893,9 @@ CMDRESULT cbInstrRefFindRange(int argc, char* argv[])
bool cbRefStr(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
{
if(!refinfo) //initialize
if(!disasm && !basicinfo) //initialize
{
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize(refinfo->name);
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
GuiReferenceAddColumn(64, "Disassembly");
GuiReferenceAddColumn(500, "String");
@ -949,7 +949,7 @@ CMDRESULT cbInstrRefStr(int argc, char* argv[])
if(!valfromstring(argv[2], &size, true))
size = 0;
uint ticks = GetTickCount();
int found = reffind(addr, size, cbRefStr, 0, false);
int found = reffind(addr, size, cbRefStr, 0, false, "Strings");
dprintf("%u string(s) in %ums\n", found, GetTickCount() - ticks);
varset("$result", found, false);
return STATUS_CONTINUE;
@ -1164,7 +1164,7 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
else
find_size = size - start;
//setup reference view
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize("Occurrences");
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
if(findData)
GuiReferenceAddColumn(0, "&Data&");
@ -1212,9 +1212,9 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
static bool cbModCallFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
{
if(!refinfo) //initialize
if(!disasm && !basicinfo) //initialize
{
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize(refinfo->name);
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
GuiReferenceAddColumn(0, "Disassembly");
GuiReferenceReloadData();
@ -1252,7 +1252,7 @@ CMDRESULT cbInstrModCallFind(int argc, char* argv[])
if(!valfromstring(argv[2], &size, true))
size = 0;
uint ticks = GetTickCount();
int found = reffind(addr, size, cbModCallFind, 0, false);
int found = reffind(addr, size, cbModCallFind, 0, false, "Calls");
dprintf("%u call(s) in %ums\n", found, GetTickCount() - ticks);
varset("$result", found, false);
return STATUS_CONTINUE;
@ -1261,7 +1261,7 @@ CMDRESULT cbInstrModCallFind(int argc, char* argv[])
CMDRESULT cbInstrCommentList(int argc, char* argv[])
{
//setup reference view
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize("Comments");
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
GuiReferenceAddColumn(64, "Disassembly");
GuiReferenceAddColumn(0, "Comment");
@ -1296,7 +1296,7 @@ CMDRESULT cbInstrCommentList(int argc, char* argv[])
CMDRESULT cbInstrLabelList(int argc, char* argv[])
{
//setup reference view
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize("Labels");
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
GuiReferenceAddColumn(64, "Disassembly");
GuiReferenceAddColumn(0, "Label");
@ -1331,7 +1331,7 @@ CMDRESULT cbInstrLabelList(int argc, char* argv[])
CMDRESULT cbInstrBookmarkList(int argc, char* argv[])
{
//setup reference view
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize("Bookmarks");
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
GuiReferenceAddColumn(0, "Disassembly");
GuiReferenceReloadData();
@ -1364,7 +1364,7 @@ CMDRESULT cbInstrBookmarkList(int argc, char* argv[])
CMDRESULT cbInstrFunctionList(int argc, char* argv[])
{
//setup reference view
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize("Functions");
GuiReferenceAddColumn(2 * sizeof(uint), "Start");
GuiReferenceAddColumn(2 * sizeof(uint), "End");
GuiReferenceAddColumn(64, "Disassembly (Start)");
@ -1410,7 +1410,7 @@ CMDRESULT cbInstrFunctionList(int argc, char* argv[])
CMDRESULT cbInstrLoopList(int argc, char* argv[])
{
//setup reference view
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize("Loops");
GuiReferenceAddColumn(2 * sizeof(uint), "Start");
GuiReferenceAddColumn(2 * sizeof(uint), "End");
GuiReferenceAddColumn(64, "Disassembly (Start)");
@ -1467,9 +1467,9 @@ CMDRESULT cbInstrSleep(int argc, char* argv[])
static bool cbFindAsm(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
{
if(!refinfo) //initialize
if(!disasm && !basicinfo) //initialize
{
GuiReferenceDeleteAllColumns();
GuiReferenceInitialize(refinfo->name);
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
GuiReferenceAddColumn(0, "Disassembly");
GuiReferenceReloadData();
@ -1521,7 +1521,7 @@ CMDRESULT cbInstrFindAsm(int argc, char* argv[])
disasmfast(dest, addr + size / 2, &basicinfo);
uint ticks = GetTickCount();
int found = reffind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false);
int found = reffind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false, "Command");
dprintf("%u result(s) in %ums\n", found, GetTickCount() - ticks);
varset("$result", found, false);
return STATUS_CONTINUE;

View File

@ -9,7 +9,7 @@
#include "memory.h"
#include "console.h"
int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent)
int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent, const char* name)
{
uint start_addr;
uint start_size;
@ -53,10 +53,17 @@ int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent)
disasm.VirtualAddr = (UInt64)start_addr;
uint i = 0;
BASIC_INSTRUCTION_INFO basicinfo;
cbRef(&disasm, &basicinfo, 0); //allow initializing
REFINFO refinfo;
memset(&refinfo, 0, sizeof(REFINFO));
refinfo.userinfo = userinfo;
char fullName[deflen] = "";
char modname[MAX_MODULE_SIZE] = "";
if(modnamefromaddr(start_addr, modname, true))
sprintf_s(fullName, "%s (%s)", name, modname);
else
sprintf_s(fullName, "%s (%p)", name, start_addr);
refinfo.name = fullName;
cbRef(0, 0, &refinfo); //allow initializing
while(i < start_size)
{
if(!(i % 0x1000))

View File

@ -9,12 +9,13 @@ struct REFINFO
{
int refcount;
void* userinfo;
const char* name;
};
//typedefs
typedef bool (*CBREF)(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo);
//functions
int reffind(uint page, uint size, CBREF cbRef, void* userinfo, bool silent);
int reffind(uint page, uint size, CBREF cbRef, void* userinfo, bool silent, const char* name);
#endif //_REFERENCE_H

View File

@ -1275,7 +1275,17 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
if(!value or !DbgIsDebugging())
return false;
//explicit API handling
const char* apiname = strstr(name, ":");
const char* apiname = strchr(name, ':'); //the ':' character cannot be in a path: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#naming_conventions
bool noexports = false;
if(!apiname) //not found
{
apiname = strrchr(name, '.'); //kernel32.GetProcAddress support
if(!apiname) //not found
{
apiname = strchr(name, '?'); //the '?' character cannot be in a path either
noexports = true;
}
}
if(apiname)
{
char modname[MAX_MODULE_SIZE] = "";
@ -1304,34 +1314,42 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
}
else
{
wchar_t* szBaseName = wcschr(szModName, L'\\');
if(szBaseName)
HMODULE mod = LoadLibraryExW(szModName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
if(!mod)
{
szBaseName++;
HMODULE mod = LoadLibraryExW(szModName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
if(!mod)
if(!silent)
dprintf("unable to load library %s\n", szModName);
}
else
{
uint addr = noexports ? 0 : (uint)GetProcAddress(mod, apiname);
if(addr) //found exported function
addr = modbase + (addr - (uint)mod); //correct for loaded base
else //not found
{
if(!silent)
dprintf("unable to load library %s\n", szBaseName);
}
else
{
uint addr = (uint)GetProcAddress(mod, apiname);
if(!addr) //not found
if(scmp(apiname, "base") or scmp(apiname, "imagebase") or scmp(apiname, "header")) //get loaded base
addr = modbase;
else if(scmp(apiname, "entry") or scmp(apiname, "oep") or scmp(apiname, "ep")) //get entry point
addr = modbase + GetPE32DataW(szModName, 0, UE_OEP);
else if(*apiname == '$') //RVA
{
if(!_stricmp(apiname, "base") or !_stricmp(apiname, "imagebase") or !_stricmp(apiname, "header"))
addr = modbase;
else if(*apiname == '$') //RVA
uint rva;
if(valfromstring(apiname + 1, &rva))
addr = modbase + rva;
}
else if(*apiname == '#') //File Offset
{
uint offset;
if(valfromstring(apiname + 1, &offset))
addr = valfileoffsettova(modname, offset);
}
else
{
if(noexports) //get the exported functions with the '?' delimiter
{
uint rva;
if(valfromstring(apiname + 1, &rva))
addr = modbase + rva;
}
else if(*apiname == '#') //File Offset
{
uint offset;
if(valfromstring(apiname + 1, &offset))
addr = valfileoffsettova(modname, offset);
addr = (uint)GetProcAddress(mod, apiname);
if(addr) //found exported function
addr = modbase + (addr - (uint)mod); //correct for loaded base
}
else
{
@ -1339,35 +1357,30 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
if(valfromstring(apiname, &ordinal))
{
addr = (uint)GetProcAddress(mod, (LPCSTR)(ordinal & 0xFFFF));
if(!addr and !ordinal)
if(addr) //found exported function
addr = modbase + (addr - (uint)mod); //correct for loaded base
else if(!ordinal) //support for getting the image base using <modname>:0
addr = modbase;
}
}
}
FreeLibrary(mod);
if(addr) //found!
{
if(value_size)
*value_size = sizeof(uint);
if(hexonly)
*hexonly = true;
uint rva;
if(addr == modbase)
rva = 0;
else
rva = addr - (uint)mod;
*value = modbase + rva;
return true;
}
}
FreeLibrary(mod);
if(addr) //found!
{
if(value_size)
*value_size = sizeof(uint);
if(hexonly)
*hexonly = true;
*value = addr;
return true;
}
}
else if(!silent)
dputs("unknown error");
}
return false;
}
int found = 0;
int kernelbase = -1;
int kernel32 = -1;
DWORD cbNeeded = 0;
Memory<uint*> addrfound;
if(EnumProcessModules(fdProcessInfo->hProcess, 0, 0, &cbNeeded))
@ -1381,7 +1394,7 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
wchar_t szModuleName[MAX_PATH] = L"";
if(GetModuleFileNameExW(fdProcessInfo->hProcess, hMods[i], szModuleName, MAX_PATH))
{
wchar_t* szBaseName = wcschr(szModuleName, L'\\');
wchar_t* szBaseName = wcsrchr(szModuleName, L'\\');
if(szBaseName)
{
szBaseName++;
@ -1391,8 +1404,8 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
ULONG_PTR funcAddress = (ULONG_PTR)GetProcAddress(hModule, name);
if(funcAddress)
{
if(!_wcsicmp(szBaseName, L"kernelbase.dll"))
kernelbase = found;
if(!_wcsicmp(szBaseName, L"kernel32.dll"))
kernel32 = found;
uint rva = funcAddress - (uint)hModule;
addrfound[found] = (uint)hMods[i] + rva;
found++;
@ -1410,13 +1423,13 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
*value_size = sizeof(uint);
if(hexonly)
*hexonly = true;
if(kernelbase != -1)
if(kernel32 != -1) //prioritize kernel32 exports
{
*value = addrfound[kernelbase];
*value = addrfound[kernel32];
if(!printall or silent)
return true;
for(int i = 0; i < found; i++)
if(i != kernelbase)
if(i != kernel32)
dprintf(fhex"\n", addrfound[i]);
}
else

View File

@ -380,13 +380,28 @@ QString Disassembly::paintContent(QPainter* painter, int_t rowBase, int rowOffse
char comment[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt(rvaToVa(mInstBuffer.at(rowOffset).rva), comment))
{
painter->setPen(ConfigColor("DisassemblyCommentColor"));
int width = getCharWidth() * QString(comment).length() + 4;
QString commentText;
QColor penColor;
QColor backgroundColor;
if(comment[0] == '\1') //automatic comment
{
penColor = ConfigColor("DisassemblyAutoCommentColor");
backgroundColor = ConfigColor("DisassemblyAutoCommentBackgroundColor");
commentText = QString(comment + 1);
}
else //user comment
{
penColor = ConfigColor("DisassemblyCommentColor");
backgroundColor = ConfigColor("DisassemblyCommentBackgroundColor");
commentText = comment;
}
painter->setPen(penColor);
int width = getCharWidth() * commentText.length() + 4;
if(width > w)
width = w;
if(width)
painter->fillRect(QRect(x + 2, y, width, h), QBrush(ConfigColor("DisassemblyCommentBackgroundColor"))); //fill bookmark color
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, QString(comment));
painter->fillRect(QRect(x + 2, y, width, h), QBrush(backgroundColor)); //fill comment color
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, commentText);
}
}
break;
@ -1160,13 +1175,11 @@ void Disassembly::prepareDataRange(int_t startRva, int_t endRva, QList<Instructi
{
int wCount = 0;
int_t addr = startRva;
while(addr < endRva)
while(addr <= endRva)
{
addr = getNextInstructionRVA(addr, 1);
wCount++;
}
if(addr - 1 != endRva)
wCount--;
prepareDataCount(startRva, wCount, instBuffer);
}
}

View File

@ -20,7 +20,6 @@ ReferenceView::ReferenceView()
// Setup signals
connect(Bridge::getBridge(), SIGNAL(referenceAddColumnAt(int, QString)), this, SLOT(addColumnAt(int, QString)));
connect(Bridge::getBridge(), SIGNAL(referenceSetRowCount(int_t)), this, SLOT(setRowCount(int_t)));
connect(Bridge::getBridge(), SIGNAL(referenceDeleteAllColumns()), this, SLOT(deleteAllColumns()));
connect(Bridge::getBridge(), SIGNAL(referenceSetCellContent(int, int, QString)), this, SLOT(setCellContent(int, int, QString)));
connect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData()));
connect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int, bool)), this, SLOT(setSingleSelection(int, bool)));
@ -58,6 +57,17 @@ void ReferenceView::setupContextMenu()
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot()));
}
void ReferenceView::disconnectBridge()
{
disconnect(Bridge::getBridge(), SIGNAL(referenceAddColumnAt(int, QString)), this, SLOT(addColumnAt(int, QString)));
disconnect(Bridge::getBridge(), SIGNAL(referenceSetRowCount(int_t)), this, SLOT(setRowCount(int_t)));
disconnect(Bridge::getBridge(), SIGNAL(referenceSetCellContent(int, int, QString)), this, SLOT(setCellContent(int, int, QString)));
disconnect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData()));
disconnect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int, bool)), this, SLOT(setSingleSelection(int, bool)));
disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchProgress, SLOT(setValue(int)));
disconnect(Bridge::getBridge(), SIGNAL(referenceSetSearchStartCol(int)), this, SLOT(setSearchStartCol(int)));
}
void ReferenceView::refreshShortcutsSlot()
{
mToggleBreakpoint->setShortcut(ConfigShortcut("ActionToggleBreakpoint"));
@ -87,21 +97,6 @@ void ReferenceView::setRowCount(int_t count)
mList->setRowCount(count);
}
void ReferenceView::deleteAllColumns()
{
mSearchBox->setText("");
mList->setTableOffset(0);
mList->setSingleSelection(0);
mList->deleteAllColumns();
mList->reloadData();
mSearchList->setTableOffset(0);
mSearchList->setSingleSelection(0);
mSearchList->deleteAllColumns();
mSearchList->reloadData();
mSearchStartCol = 1;
mFollowDumpDefault = false;
}
void ReferenceView::setCellContent(int r, int c, QString s)
{
mSearchBox->setText("");

View File

@ -11,11 +11,11 @@ class ReferenceView : public SearchListView
public:
ReferenceView();
void setupContextMenu();
void disconnectBridge();
private slots:
void addColumnAt(int width, QString title);
void setRowCount(int_t count);
void deleteAllColumns();
void setCellContent(int r, int c, QString s);
void reloadData();
void setSingleSelection(int index, bool scroll);

View File

@ -17,7 +17,7 @@ Bridge::Bridge(QObject* parent) : QObject(parent)
mBridgeMutex = new QMutex();
winId = 0;
scriptView = 0;
referenceView = 0;
referenceManager = 0;
bridgeResult = 0;
hasBridgeResult = false;
}
@ -173,11 +173,6 @@ void Bridge::emitReferenceSetRowCount(int_t count)
emit referenceSetRowCount(count);
}
void Bridge::emitReferenceDeleteAllColumns()
{
emit referenceDeleteAllColumns();
}
void Bridge::emitReferenceSetCellContent(int r, int c, QString s)
{
emit referenceSetCellContent(r, c, s);
@ -203,6 +198,16 @@ void Bridge::emitReferenceSetSearchStartCol(int col)
emit referenceSetSearchStartCol(col);
}
void Bridge::emitReferenceInitialize(QString name)
{
mBridgeMutex->lock();
hasBridgeResult = false;
emit referenceInitialize(name);
while(!hasBridgeResult) //wait for thread completion
Sleep(100);
mBridgeMutex->unlock();
}
void Bridge::emitStackDumpAt(uint_t va, uint_t csp)
{
emit stackDumpAt(va, csp);
@ -558,13 +563,13 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
case GUI_REF_GETROWCOUNT:
{
return (void*)Bridge::getBridge()->referenceView->mList->getRowCount();
return (void*)(void*)Bridge::getBridge()->referenceManager->currentReferenceView()->mList->getRowCount();
}
break;
case GUI_REF_DELETEALLCOLUMNS:
{
Bridge::getBridge()->emitReferenceDeleteAllColumns();
GuiReferenceInitialize("References");
}
break;
@ -577,7 +582,7 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
case GUI_REF_GETCELLCONTENT:
{
return (void*)Bridge::getBridge()->referenceView->mList->getCellContent((int)(int_t)param1, (int)(int_t)param2).toUtf8().constData();
return (void*)Bridge::getBridge()->referenceManager->currentReferenceView()->mList->getCellContent((int)(int_t)param1, (int)(int_t)param2).toUtf8().constData();
}
break;
@ -605,6 +610,12 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
}
break;
case GUI_REF_INITIALIZE:
{
Bridge::getBridge()->emitReferenceInitialize(QString(reinterpret_cast<const char*>(param1)));
}
break;
case GUI_STACK_DUMP_AT:
{
Bridge::getBridge()->emitStackDumpAt((uint_t)param1, (uint_t)param2);

View File

@ -5,7 +5,7 @@
#include <QMutex>
#include "Imports.h"
#include "NewTypes.h"
#include "SearchListView.h"
#include "ReferenceManager.h"
class Bridge : public QObject
{
@ -48,12 +48,12 @@ public:
void emitSetSymbolProgress(int progress);
void emitReferenceAddColumnAt(int width, QString title);
void emitReferenceSetRowCount(int_t count);
void emitReferenceDeleteAllColumns();
void emitReferenceSetCellContent(int r, int c, QString s);
void emitReferenceReloadData();
void emitReferenceSetSingleSelection(int index, bool scroll);
void emitReferenceSetProgress(int progress);
void emitReferenceSetSearchStartCol(int col);
void emitReferenceInitialize(QString name);
void emitStackDumpAt(uint_t va, uint_t csp);
void emitUpdateDump();
void emitUpdateThreads();
@ -80,7 +80,7 @@ public:
//Public variables
void* winId;
QWidget* scriptView;
SearchListView* referenceView;
ReferenceManager* referenceManager;
signals:
void disassembleAt(int_t va, int_t eip);
@ -107,12 +107,12 @@ signals:
void setSymbolProgress(int progress);
void referenceAddColumnAt(int width, QString title);
void referenceSetRowCount(int_t count);
void referenceDeleteAllColumns();
void referenceSetCellContent(int r, int c, QString s);
void referenceReloadData();
void referenceSetSingleSelection(int index, bool scroll);
void referenceSetProgress(int progress);
void referenceSetSearchStartCol(int col);
void referenceInitialize(QString name);
void stackDumpAt(uint_t va, uint_t csp);
void updateDump();
void updateThreads();

View File

@ -136,6 +136,8 @@ void BeaTokenizer::Mnemonic(BeaInstructionToken* instr, const DISASM* disasm)
type = TokenMnemonicPushPop;
else if(IsNopInstruction(mnemonic, disasm)) //nop instructions
type = TokenMnemonicNop;
else if(mnemonic == "int3" || mnemonic == "int 3") //int3 instruction on request
type = TokenMnemonicInt3;
else if(completeInstr.contains("movs") || completeInstr.contains("cmps") || completeInstr.contains("scas") || completeInstr.contains("lods") || completeInstr.contains("stos") || completeInstr.contains("outs"))
{
completeInstr = completeInstr.replace("rep ", "").replace("repne ", "");
@ -470,6 +472,7 @@ void BeaTokenizer::Init()
AddColorName(TokenMnemonicUncondJump, "InstructionUnconditionalJumpColor", "InstructionUnconditionalJumpBackgroundColor");
AddColorName(TokenMnemonicNop, "InstructionNopColor", "InstructionNopBackgroundColor");
AddColorName(TokenMnemonicFar, "InstructionFarColor", "InstructionFarBackgroundColor");
AddColorName(TokenMnemonicInt3, "InstructionInt3Color", "InstructionInt3BackgroundColor");
//memory
AddColorName(TokenMemorySize, "InstructionMemorySizeColor", "InstructionMemorySizeBackgroundColor");
AddColorName(TokenMemorySegment, "InstructionMemorySegmentColor", "InstructionMemorySegmentBackgroundColor");

View File

@ -33,6 +33,7 @@ public:
TokenMnemonicUncondJump,
TokenMnemonicNop,
TokenMnemonicFar,
TokenMnemonicInt3,
//memory
TokenMemorySize,
TokenMemorySegment,

View File

@ -428,6 +428,7 @@ void AppearanceDialog::colorInfoListInit()
colorInfoListAppend("Hardware Breakpoints", "DisassemblyHardwareBreakpointColor", "DisassemblyHardwareBreakpointBackgroundColor");
colorInfoListAppend("Bookmarks", "DisassemblyBookmarkColor", "DisassemblyBookmarkBackgroundColor");
colorInfoListAppend("Comments", "DisassemblyCommentColor", "DisassemblyCommentBackgroundColor");
colorInfoListAppend("Automatic Comments", "DisassemblyAutoCommentColor", "DisassemblyAutoCommentBackgroundColor");
colorInfoListAppend("Labels", "DisassemblyLabelColor", "DisassemblyLabelBackgroundColor");
colorInfoListAppend("Addresses", "DisassemblyAddressColor", "DisassemblyAddressBackgroundColor");
colorInfoListAppend("Selected Addresses", "DisassemblySelectedAddressColor", "DisassemblySelectedAddressBackgroundColor");
@ -475,6 +476,7 @@ void AppearanceDialog::colorInfoListInit()
colorInfoListAppend("Unconditional Jumps", "InstructionUnconditionalJumpColor", "InstructionUnconditionalJumpBackgroundColor");
colorInfoListAppend("NOPs", "InstructionNopColor", "InstructionNopBackgroundColor");
colorInfoListAppend("FAR", "InstructionFarColor", "InstructionFarBackgroundColor");
colorInfoListAppend("INT3s", "InstructionInt3Color", "InstructionInt3BackgroundColor");
colorInfoListAppend("General Registers", "InstructionGeneralRegisterColor", "InstructionGeneralRegisterBackgroundColor");
colorInfoListAppend("FPU Registers", "InstructionFpuRegisterColor", "InstructionFpuRegisterBackgroundColor");
colorInfoListAppend("SSE Registers", "InstructionSseRegisterColor", "InstructionSseRegisterBackgroundColor");

View File

@ -97,7 +97,12 @@ void BreakpointsView::reloadData()
char comment[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt(wBPList.bp[wI].addr, comment))
mHardBPTable->setCellContent(wI, 4, comment);
{
if(comment[0] == '\1') //automatic comment
mHardBPTable->setCellContent(wI, 4, QString(comment + 1));
else
mHardBPTable->setCellContent(wI, 4, comment);
}
}
mHardBPTable->reloadData();
if(wBPList.count)
@ -129,7 +134,12 @@ void BreakpointsView::reloadData()
char comment[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt(wBPList.bp[wI].addr, comment))
mSoftBPTable->setCellContent(wI, 4, comment);
{
if(comment[0] == '\1') //automatic comment
mSoftBPTable->setCellContent(wI, 4, QString(comment + 1));
else
mSoftBPTable->setCellContent(wI, 4, comment);
}
}
mSoftBPTable->reloadData();
if(wBPList.count)
@ -161,7 +171,12 @@ void BreakpointsView::reloadData()
char comment[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt(wBPList.bp[wI].addr, comment))
mMemBPTable->setCellContent(wI, 4, comment);
{
if(comment[0] == '\1') //automatic comment
mMemBPTable->setCellContent(wI, 4, QString(comment + 1));
else
mMemBPTable->setCellContent(wI, 4, comment);
}
}
mMemBPTable->reloadData();
if(wBPList.count)

View File

@ -708,7 +708,12 @@ void CPUDisassembly::setComment()
QString addr_text = QString("%1").arg(wVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
char comment_text[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt((duint)wVA, comment_text))
mLineEdit.setText(QString(comment_text));
{
if(comment_text[0] == '\1') //automatic comment
mLineEdit.setText(QString(comment_text + 1));
else
mLineEdit.setText(QString(comment_text));
}
mLineEdit.setWindowTitle("Add comment at " + addr_text);
if(mLineEdit.exec() != QDialog::Accepted)
return;
@ -1160,7 +1165,12 @@ void CPUDisassembly::copySelection(bool copyBytes)
char comment[MAX_COMMENT_SIZE] = "";
QString fullComment;
if(DbgGetCommentAt(cur_addr, comment))
fullComment = " ;" + QString(comment);
{
if(comment[0] == '\1') //automatic comment
fullComment = " ;" + QString(comment + 1);
else
fullComment = " ;" + QString(comment);
}
clipboard += address.leftJustified(addressLen, QChar(' '), true);
if(copyBytes)
clipboard += " | " + bytes.leftJustified(bytesLen, QChar(' '), true);

View File

@ -427,9 +427,11 @@ QString CPUDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, i
uint_t data = 0;
int_t wRva = (rowBase + rowOffset) * getBytePerRowCount() - mByteOffset;
mMemPage->read((byte_t*)&data, wRva, sizeof(uint_t));
char modname[MAX_MODULE_SIZE] = "";
DbgGetModuleAt(data, modname);
char label_text[MAX_LABEL_SIZE] = "";
if(DbgGetLabelAt(data, SEG_DEFAULT, label_text))
wStr = QString(label_text);
wStr = QString(modname) + "." + QString(label_text);
}
else //data
{
@ -521,7 +523,10 @@ void CPUDump::mouseDoubleClickEvent(QMouseEvent* event)
break;
default:
break;
{
binaryEditSlot();
}
break;
}
}

View File

@ -358,7 +358,10 @@ void CPUStack::mouseDoubleClickEvent(QMouseEvent* event)
break;
default:
break;
{
modifySlot();
}
break;
}
}

View File

@ -82,11 +82,11 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
mCpuWidget->setWindowTitle("CPU");
mCpuWidget->setWindowIcon(QIcon(":/icons/images/processor-cpu.png"));
// Reference View
mReferenceView = new ReferenceView();
Bridge::getBridge()->referenceView = mReferenceView;
mReferenceView->setWindowTitle("References");
mReferenceView->setWindowIcon(QIcon(":/icons/images/search.png"));
// Reference Manager
mReferenceManager = new ReferenceManager();
Bridge::getBridge()->referenceManager = mReferenceManager;
mReferenceManager->setWindowTitle("References");
mReferenceManager->setWindowIcon(QIcon(":/icons/images/search.png"));
// Thread View
mThreadView = new ThreadView();
@ -105,7 +105,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
mTabWidget->addTab(mCallStackView, mCallStackView->windowIcon(), mCallStackView->windowTitle());
mTabWidget->addTab(mScriptView, mScriptView->windowIcon(), mScriptView->windowTitle());
mTabWidget->addTab(mSymbolView, mSymbolView->windowIcon(), mSymbolView->windowTitle());
mTabWidget->addTab(mReferenceView, mReferenceView->windowIcon(), mReferenceView->windowTitle());
mTabWidget->addTab(mReferenceManager, mReferenceManager->windowIcon(), mReferenceManager->windowTitle());
mTabWidget->addTab(mThreadView, mThreadView->windowIcon(), mThreadView->windowTitle());
setCentralWidget(mTabWidget);
@ -152,7 +152,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(mReferenceManager, 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()));
@ -644,9 +644,9 @@ void MainWindow::displaySymbolWidget()
void MainWindow::displayReferencesWidget()
{
mReferenceView->show();
mReferenceView->setFocus();
setTab(mReferenceView);
mReferenceManager->show();
mReferenceManager->setFocus();
setTab(mReferenceManager);
}
void MainWindow::displayThreadsWidget()

View File

@ -13,7 +13,7 @@
#include "SymbolView.h"
#include "BreakpointsView.h"
#include "ScriptView.h"
#include "ReferenceView.h"
#include "ReferenceManager.h"
#include "ThreadView.h"
#include "PatchDialog.h"
#include "CalculatorDialog.h"
@ -104,7 +104,7 @@ private:
SymbolView* mSymbolView;
BreakpointsView* mBreakpointsView;
ScriptView* mScriptView;
ReferenceView* mReferenceView;
ReferenceManager* mReferenceManager;
ThreadView* mThreadView;
PatchDialog* mPatchDialog;
CalculatorDialog* mCalculatorDialog;

View File

@ -0,0 +1,25 @@
#include "ReferenceManager.h"
#include "Bridge.h"
ReferenceManager::ReferenceManager(QWidget* parent) : MHTabWidget(parent, false, true)
{
this->setMovable(true);
mCurrentReferenceView = 0;
connect(Bridge::getBridge(), SIGNAL(referenceInitialize(QString)), this, SLOT(newReferenceView(QString)));
}
ReferenceView* ReferenceManager::currentReferenceView()
{
return mCurrentReferenceView;
}
void ReferenceManager::newReferenceView(QString name)
{
if(mCurrentReferenceView) //disconnect previous reference view
mCurrentReferenceView->disconnectBridge();
mCurrentReferenceView = new ReferenceView();
connect(mCurrentReferenceView, SIGNAL(showCpu()), this, SIGNAL(showCpu()));
insertTab(0, mCurrentReferenceView, name);
setCurrentIndex(0);
Bridge::getBridge()->BridgeSetResult(1);
}

View File

@ -0,0 +1,24 @@
#ifndef REFERENCEMANAGER_H
#define REFERENCEMANAGER_H
#include "TabWidget.h"
#include "ReferenceView.h"
class ReferenceManager : public MHTabWidget
{
Q_OBJECT
public:
explicit ReferenceManager(QWidget* parent = 0);
ReferenceView* currentReferenceView();
public slots:
void newReferenceView(QString name);
signals:
void showCpu();
private:
ReferenceView* mCurrentReferenceView;
};
#endif // REFERENCEMANAGER_H

View File

@ -465,7 +465,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff
mUINTDISPLAY.insert(CDX);
mLABELDISPLAY.insert(CDX);
mMODIFYDISPLAY.insert(CDX);
mCANSTOREADDRESS.insert(CCX);
mCANSTOREADDRESS.insert(CDX);
mSETONEZEROTOGGLE.insert(CBP);
mINCREMENTDECREMET.insert(CBP);

View File

@ -111,12 +111,18 @@ void SymbolView::setupContextMenu()
mFollowModuleAction->setShortcut(QKeySequence("enter"));
connect(mFollowModuleAction, SIGNAL(triggered()), this, SLOT(moduleFollow()));
mFollowModuleEntryAction = new QAction("Follow &Entry Point in Disassembler", this);
connect(mFollowModuleEntryAction, SIGNAL(triggered()), this, SLOT(moduleEntryFollow()));
mDownloadSymbolsAction = new QAction("&Download Symbols for This Module", this);
connect(mDownloadSymbolsAction, SIGNAL(triggered()), this, SLOT(moduleDownloadSymbols()));
mDownloadAllSymbolsAction = new QAction("Download Symbols for &All Modules", this);
connect(mDownloadAllSymbolsAction, SIGNAL(triggered()), this, SLOT(moduleDownloadAllSymbols()));
mCopyPathAction = new QAction("Copy File &Path", this);
connect(mCopyPathAction, SIGNAL(triggered()), this, SLOT(moduleCopyPath()));
//Shortcuts
refreshShortcutsSlot();
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot()));
@ -231,8 +237,13 @@ void SymbolView::moduleContextMenu(const QPoint & pos)
return;
QMenu* wMenu = new QMenu(this); //create context menu
wMenu->addAction(mFollowModuleAction);
wMenu->addAction(mFollowModuleEntryAction);
wMenu->addAction(mDownloadSymbolsAction);
wMenu->addAction(mDownloadAllSymbolsAction);
int_t modbase = DbgValFromString(mModuleList->getCellContent(mModuleList->getInitialSelection(), 0).toUtf8().constData());
char szModPath[MAX_PATH] = "";
if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath)))
wMenu->addAction(mCopyPathAction);
QMenu wCopyMenu("&Copy", this);
mModuleList->setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
@ -249,6 +260,20 @@ void SymbolView::moduleFollow()
emit showCpu();
}
void SymbolView::moduleEntryFollow()
{
DbgCmdExecDirect(QString("disasm " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 1) + "?entry").toUtf8().constData());
emit showCpu();
}
void SymbolView::moduleCopyPath()
{
int_t modbase = DbgValFromString(mModuleList->getCellContent(mModuleList->getInitialSelection(), 0).toUtf8().constData());
char szModPath[MAX_PATH] = "";
if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath)))
Bridge::CopyToClipboard(szModPath);
}
void SymbolView::moduleDownloadSymbols()
{
DbgCmdExec(QString("symdownload " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 1)).toUtf8().constData());

View File

@ -30,8 +30,10 @@ private slots:
void symbolRefreshCurrent();
void moduleContextMenu(const QPoint & pos);
void moduleFollow();
void moduleEntryFollow();
void moduleDownloadSymbols();
void moduleDownloadAllSymbols();
void moduleCopyPath();
void toggleBreakpoint();
void toggleBookmark();
void refreshShortcutsSlot();
@ -52,8 +54,10 @@ private:
QAction* mToggleBreakpoint;
QAction* mToggleBookmark;
QAction* mFollowModuleAction;
QAction* mFollowModuleEntryAction;
QAction* mDownloadSymbolsAction;
QAction* mDownloadAllSymbolsAction;
QAction* mCopyPathAction;
static void cbSymbolEnum(SYMBOLINFO* symbol, void* user);
};

View File

@ -14,8 +14,10 @@
//////////////////////////////////////////////////////////////
// Default Constructor
//////////////////////////////////////////////////////////////
MHTabBar::MHTabBar(QWidget* parent) : QTabBar(parent)
MHTabBar::MHTabBar(QWidget* parent, bool allowDetach, bool allowDelete) : QTabBar(parent)
{
mAllowDetach = allowDetach;
mAllowDelete = allowDelete;
setAcceptDrops(true);
setElideMode(Qt::ElideRight);
setSelectionBehaviorOnRemove(QTabBar::SelectLeftTab);
@ -31,14 +33,25 @@ MHTabBar::~MHTabBar(void)
void MHTabBar::contextMenuEvent(QContextMenuEvent* event)
{
if(!mAllowDetach && !mAllowDelete)
return;
QMenu wMenu(this);
QAction wDetach("&Detach", this);
wMenu.addAction(&wDetach);
if(wMenu.exec(event->globalPos()) == &wDetach)
if(mAllowDetach)
wMenu.addAction(&wDetach);
QAction wDelete("&Delete", this);
if(mAllowDelete)
wMenu.addAction(&wDelete);
QAction* executed = wMenu.exec(event->globalPos());
if(executed == &wDetach)
{
QPoint p(0, 0);
OnDetachTab((int)tabAt(event->pos()), p);
}
else if(executed == &wDelete)
{
OnDeleteTab((int)tabAt(event->pos()));
}
}

View File

@ -18,7 +18,7 @@ class MHTabBar: public QTabBar
{
Q_OBJECT
public:
MHTabBar(QWidget* parent);
MHTabBar(QWidget* parent, bool allowDetach, bool allowDelete);
~MHTabBar(void);
protected:
@ -36,8 +36,12 @@ signals:
void OnDetachTab(int index, QPoint & dropPoint);
// Move Tab
void OnMoveTab(int fromIndex, int toIndex);
// Delete Tab
void OnDeleteTab(int index);
private:
bool mAllowDetach;
bool mAllowDelete;
/*
QPoint m_dragStartPos;
QPoint m_dragMovedPos;

View File

@ -5,11 +5,12 @@
//////////////////////////////////////////////////////////////
// Default Constructor
//////////////////////////////////////////////////////////////
MHTabWidget::MHTabWidget(QWidget* parent) : QTabWidget(parent)
MHTabWidget::MHTabWidget(QWidget* parent, bool allowDetach, bool allowDelete) : QTabWidget(parent)
{
m_tabBar = new MHTabBar(this);
m_tabBar = new MHTabBar(this, allowDetach, allowDelete);
connect(m_tabBar, SIGNAL(OnDetachTab(int, QPoint &)), this, SLOT(DetachTab(int, QPoint &)));
connect(m_tabBar, SIGNAL(OnMoveTab(int, int)), this, SLOT(MoveTab(int, int)));
connect(m_tabBar, SIGNAL(OnDeleteTab(int)), this, SLOT(DeleteTab(int)));
setTabBar(m_tabBar);
setMovable(true);
@ -29,6 +30,7 @@ MHTabWidget::~MHTabWidget(void)
{
disconnect(m_tabBar, SIGNAL(OnMoveTab(int, int)), this, SLOT(MoveTab(int, int)));
disconnect(m_tabBar, SIGNAL(OnDetachTab(int, QPoint &)), this, SLOT(DetachTab(int, QPoint &)));
disconnect(m_tabBar, SIGNAL(OnDeleteTab(int)), this, SLOT(DeleteTab(int)));
delete m_tabBar;
}
@ -120,6 +122,11 @@ void MHTabWidget::DetachTab(int index, QPoint & dropPoint)
detachedWidget->showNormal();
}
void MHTabWidget::DeleteTab(int index)
{
removeTab(index);
}
//////////////////////////////////////////////////////////////////////////////
void MHTabWidget::AttachTab(QWidget* parent)
{

View File

@ -22,7 +22,7 @@ class MHTabWidget: public QTabWidget
Q_OBJECT
public:
MHTabWidget(QWidget* parent);
MHTabWidget(QWidget* parent, bool allowDetach = true, bool allowDelete = false);
virtual ~MHTabWidget(void);
QTabBar* tabBar();
@ -39,6 +39,9 @@ public slots:
// Attach Tab
void AttachTab(QWidget* parent);
// Delete Tab
void DeleteTab(int index);
public Q_SLOTS:
void setCurrentIndex(int index);
void setCurrentWidget(QWidget* widget);

View File

@ -39,6 +39,8 @@ Configuration::Configuration() : QObject()
defaultColors.insert("DisassemblyModifiedBytesColor", QColor("#FF0000"));
defaultColors.insert("DisassemblyCommentColor", QColor("#000000"));
defaultColors.insert("DisassemblyCommentBackgroundColor", Qt::transparent);
defaultColors.insert("DisassemblyAutoCommentColor", QColor("#808080"));
defaultColors.insert("DisassemblyAutoCommentBackgroundColor", Qt::transparent);
defaultColors.insert("SideBarCipLabelColor", QColor("#FFFFFF"));
defaultColors.insert("SideBarCipLabelBackgroundColor", QColor("#4040FF"));
@ -86,6 +88,8 @@ Configuration::Configuration() : QObject()
defaultColors.insert("InstructionNopBackgroundColor", Qt::transparent);
defaultColors.insert("InstructionFarColor", QColor("#000000"));
defaultColors.insert("InstructionFarBackgroundColor", Qt::transparent);
defaultColors.insert("InstructionInt3Color", QColor("#000000"));
defaultColors.insert("InstructionInt3BackgroundColor", Qt::transparent);
defaultColors.insert("InstructionMemorySizeColor", QColor("#000080"));
defaultColors.insert("InstructionMemorySizeBackgroundColor", Qt::transparent);
defaultColors.insert("InstructionMemorySegmentColor", QColor("#FF00FF"));

View File

@ -84,7 +84,8 @@ SOURCES += \
Src/Gui/CalculatorDialog.cpp \
Src/Gui/AttachDialog.cpp \
Src/Gui/PageMemoryRights.cpp \
Src/Gui/SelectFields.cpp
Src/Gui/SelectFields.cpp \
Src/Gui/ReferenceManager.cpp
HEADERS += \
@ -147,7 +148,8 @@ HEADERS += \
Src/Gui/CalculatorDialog.h \
Src/Gui/AttachDialog.h \
Src/Gui/PageMemoryRights.h \
Src/Gui/SelectFields.h
Src/Gui/SelectFields.h \
Src/Gui/ReferenceManager.h
INCLUDEPATH += \