714 lines
17 KiB
C++
714 lines
17 KiB
C++
#include "Bridge.h"
|
|
|
|
/************************************************************************************
|
|
Global Variables
|
|
************************************************************************************/
|
|
static Bridge* mBridge;
|
|
|
|
/************************************************************************************
|
|
Class Members
|
|
************************************************************************************/
|
|
Bridge::Bridge(QObject *parent) : QObject(parent)
|
|
{
|
|
|
|
}
|
|
|
|
void Bridge::CopyToClipboard(const char* text)
|
|
{
|
|
HGLOBAL hText;
|
|
char *pText;
|
|
int len=strlen(text);
|
|
if(!len)
|
|
return;
|
|
|
|
hText=GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, len+1);
|
|
pText=(char*)GlobalLock(hText);
|
|
strcpy(pText, text);
|
|
|
|
OpenClipboard(0);
|
|
EmptyClipboard();
|
|
if(!SetClipboardData(CF_OEMTEXT, hText))
|
|
MessageBeep(MB_ICONERROR);
|
|
else
|
|
MessageBeep(MB_ICONINFORMATION);
|
|
CloseClipboard();
|
|
}
|
|
|
|
void Bridge::BridgeSetResult(int_t result)
|
|
{
|
|
bridgeResult=result;
|
|
hasBridgeResult=true;
|
|
}
|
|
|
|
/************************************************************************************
|
|
Exports Binding
|
|
************************************************************************************/
|
|
void Bridge::emitDisassembleAtSignal(int_t va, int_t eip)
|
|
{
|
|
emit disassembleAt(va, eip);
|
|
}
|
|
|
|
void Bridge::emitUpdateDisassembly()
|
|
{
|
|
emit repaintGui();
|
|
}
|
|
|
|
void Bridge::emitDbgStateChanged(DBGSTATE state)
|
|
{
|
|
emit dbgStateChanged(state);
|
|
}
|
|
|
|
void Bridge::emitAddMsgToLog(QString msg)
|
|
{
|
|
emit addMsgToLog(msg);
|
|
}
|
|
|
|
void Bridge::emitClearLog()
|
|
{
|
|
emit clearLog();
|
|
}
|
|
|
|
void Bridge::emitUpdateRegisters()
|
|
{
|
|
emit updateRegisters();
|
|
}
|
|
|
|
void Bridge::emitUpdateBreakpoints()
|
|
{
|
|
emit updateBreakpoints();
|
|
}
|
|
|
|
void Bridge::emitUpdateWindowTitle(QString filename)
|
|
{
|
|
emit updateWindowTitle(filename);
|
|
}
|
|
|
|
void Bridge::emitDumpAt(int_t va)
|
|
{
|
|
emit dumpAt(va);
|
|
}
|
|
|
|
void Bridge::emitScriptAdd(int count, const char** lines)
|
|
{
|
|
mBridgeMutex.lock();
|
|
hasBridgeResult=false;
|
|
emit scriptAdd(count, lines);
|
|
while(!hasBridgeResult) //wait for thread completion
|
|
Sleep(100);
|
|
mBridgeMutex.unlock();
|
|
}
|
|
|
|
void Bridge::emitScriptClear()
|
|
{
|
|
emit scriptClear();
|
|
}
|
|
|
|
void Bridge::emitScriptSetIp(int line)
|
|
{
|
|
emit scriptSetIp(line);
|
|
}
|
|
|
|
void Bridge::emitScriptError(int line, QString message)
|
|
{
|
|
emit scriptError(line, message);
|
|
}
|
|
|
|
void Bridge::emitScriptSetTitle(QString title)
|
|
{
|
|
emit scriptSetTitle(title);
|
|
}
|
|
|
|
void Bridge::emitScriptSetInfoLine(int line, QString info)
|
|
{
|
|
emit scriptSetInfoLine(line, info);
|
|
}
|
|
|
|
void Bridge::emitScriptMessage(QString message)
|
|
{
|
|
emit scriptMessage(message);
|
|
}
|
|
|
|
int Bridge::emitScriptQuestion(QString message)
|
|
{
|
|
mBridgeMutex.lock();
|
|
hasBridgeResult=false;
|
|
emit scriptQuestion(message);
|
|
while(!hasBridgeResult) //wait for thread completion
|
|
Sleep(100);
|
|
mBridgeMutex.unlock();
|
|
return bridgeResult;
|
|
}
|
|
|
|
void Bridge::emitScriptEnableHighlighting(bool enable)
|
|
{
|
|
emit scriptEnableHighlighting(enable);
|
|
}
|
|
|
|
void Bridge::emitUpdateSymbolList(int module_count, SYMBOLMODULEINFO* modules)
|
|
{
|
|
emit updateSymbolList(module_count, modules);
|
|
}
|
|
|
|
void Bridge::emitAddMsgToSymbolLog(QString msg)
|
|
{
|
|
emit addMsgToSymbolLog(msg);
|
|
}
|
|
|
|
void Bridge::emitClearSymbolLog()
|
|
{
|
|
emit clearSymbolLog();
|
|
}
|
|
|
|
void Bridge::emitSetSymbolProgress(int progress)
|
|
{
|
|
emit setSymbolProgress(progress);
|
|
}
|
|
|
|
void Bridge::emitReferenceAddColumnAt(int width, QString title)
|
|
{
|
|
emit referenceAddColumnAt(width, title);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void Bridge::emitReferenceReloadData()
|
|
{
|
|
emit referenceReloadData();
|
|
}
|
|
|
|
void Bridge::emitReferenceSetSingleSelection(int index, bool scroll)
|
|
{
|
|
emit referenceSetSingleSelection(index, scroll);
|
|
}
|
|
|
|
void Bridge::emitReferenceSetProgress(int progress)
|
|
{
|
|
emit referenceSetProgress(progress);
|
|
}
|
|
|
|
void Bridge::emitReferenceSetSearchStartCol(int col)
|
|
{
|
|
emit referenceSetSearchStartCol(col);
|
|
}
|
|
|
|
void Bridge::emitStackDumpAt(uint_t va, uint_t csp)
|
|
{
|
|
emit stackDumpAt(va, csp);
|
|
}
|
|
|
|
void Bridge::emitUpdateDump()
|
|
{
|
|
emit updateDump();
|
|
}
|
|
|
|
void Bridge::emitUpdateThreads()
|
|
{
|
|
emit updateThreads();
|
|
}
|
|
|
|
void Bridge::emitAddRecentFile(QString file)
|
|
{
|
|
emit addRecentFile(file);
|
|
}
|
|
|
|
void Bridge::emitSetLastException(unsigned int exceptionCode)
|
|
{
|
|
emit setLastException(exceptionCode);
|
|
}
|
|
|
|
int Bridge::emitMenuAddMenu(int hMenu, QString title)
|
|
{
|
|
mBridgeMutex.lock();
|
|
hasBridgeResult=false;
|
|
emit menuAddMenu(hMenu, title);
|
|
while(!hasBridgeResult) //wait for thread completion
|
|
Sleep(100);
|
|
mBridgeMutex.unlock();
|
|
return bridgeResult;
|
|
}
|
|
|
|
int Bridge::emitMenuAddMenuEntry(int hMenu, QString title)
|
|
{
|
|
mBridgeMutex.lock();
|
|
hasBridgeResult=false;
|
|
emit menuAddMenuEntry(hMenu, title);
|
|
while(!hasBridgeResult) //wait for thread completion
|
|
Sleep(100);
|
|
mBridgeMutex.unlock();
|
|
return bridgeResult;
|
|
}
|
|
|
|
void Bridge::emitMenuAddSeparator(int hMenu)
|
|
{
|
|
emit menuAddSeparator(hMenu);
|
|
}
|
|
|
|
void Bridge::emitMenuClearMenu(int hMenu)
|
|
{
|
|
emit menuClearMenu(hMenu);
|
|
}
|
|
|
|
void Bridge::emitAddMsgToStatusBar(QString msg)
|
|
{
|
|
emit addMsgToStatusBar(msg);
|
|
}
|
|
|
|
bool Bridge::emitSelectionGet(int hWindow, SELECTIONDATA* selection)
|
|
{
|
|
if(!DbgIsDebugging())
|
|
return false;
|
|
mBridgeMutex.lock();
|
|
hasBridgeResult=false;
|
|
switch(hWindow)
|
|
{
|
|
case GUI_DISASSEMBLY:
|
|
emit selectionDisasmGet(selection);
|
|
break;
|
|
case GUI_DUMP:
|
|
emit selectionDumpGet(selection);
|
|
break;
|
|
case GUI_STACK:
|
|
emit selectionStackGet(selection);
|
|
break;
|
|
default:
|
|
mBridgeMutex.unlock();
|
|
return false;
|
|
}
|
|
while(!hasBridgeResult) //wait for thread completion
|
|
Sleep(100);
|
|
mBridgeMutex.unlock();
|
|
if(selection->start > selection->end) //swap start and end
|
|
{
|
|
int_t temp=selection->end;
|
|
selection->end=selection->start;
|
|
selection->start=temp;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool Bridge::emitSelectionSet(int hWindow, const SELECTIONDATA* selection)
|
|
{
|
|
if(!DbgIsDebugging())
|
|
return false;
|
|
mBridgeMutex.lock();
|
|
hasBridgeResult=false;
|
|
switch(hWindow)
|
|
{
|
|
case GUI_DISASSEMBLY:
|
|
emit selectionDisasmSet(selection);
|
|
break;
|
|
case GUI_DUMP:
|
|
emit selectionDumpSet(selection);
|
|
break;
|
|
case GUI_STACK:
|
|
emit selectionStackSet(selection);
|
|
break;
|
|
default:
|
|
mBridgeMutex.unlock();
|
|
return false;
|
|
}
|
|
while(!hasBridgeResult) //wait for thread completion
|
|
Sleep(100);
|
|
mBridgeMutex.unlock();
|
|
return bridgeResult;
|
|
}
|
|
|
|
bool Bridge::emitGetStrWindow(const QString title, QString* text)
|
|
{
|
|
mBridgeMutex.lock();
|
|
hasBridgeResult=false;
|
|
emit getStrWindow(title, text);
|
|
while(!hasBridgeResult) //wait for thread completion
|
|
Sleep(100);
|
|
mBridgeMutex.unlock();
|
|
return bridgeResult;
|
|
}
|
|
|
|
void Bridge::emitAutoCompleteAddCmd(const QString cmd)
|
|
{
|
|
emit autoCompleteAddCmd(cmd);
|
|
}
|
|
|
|
void Bridge::emitAutoCompleteDelCmd(const QString cmd)
|
|
{
|
|
emit autoCompleteDelCmd(cmd);
|
|
}
|
|
|
|
void Bridge::emitAutoCompleteClearAll()
|
|
{
|
|
emit autoCompleteClearAll();
|
|
}
|
|
|
|
/************************************************************************************
|
|
Static Functions
|
|
************************************************************************************/
|
|
Bridge* Bridge::getBridge()
|
|
{
|
|
return mBridge;
|
|
}
|
|
|
|
void Bridge::initBridge()
|
|
{
|
|
mBridge = new Bridge();
|
|
}
|
|
|
|
/************************************************************************************
|
|
Exported Functions
|
|
************************************************************************************/
|
|
__declspec(dllexport) int _gui_guiinit(int argc, char *argv[])
|
|
{
|
|
return main(argc, argv);
|
|
}
|
|
|
|
__declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* param2)
|
|
{
|
|
switch(type)
|
|
{
|
|
case GUI_DISASSEMBLE_AT:
|
|
{
|
|
Bridge::getBridge()->emitDisassembleAtSignal((int_t)param1, (int_t)param2);
|
|
}
|
|
break;
|
|
|
|
case GUI_SET_DEBUG_STATE:
|
|
{
|
|
Bridge::getBridge()->emitDbgStateChanged(reinterpret_cast<DBGSTATE&>(param1));
|
|
}
|
|
break;
|
|
|
|
case GUI_ADD_MSG_TO_LOG:
|
|
{
|
|
Bridge::getBridge()->emitAddMsgToLog(QString(reinterpret_cast<const char*>(param1)));
|
|
}
|
|
break;
|
|
|
|
case GUI_CLEAR_LOG:
|
|
{
|
|
Bridge::getBridge()->emitClearLog();
|
|
}
|
|
break;
|
|
|
|
case GUI_UPDATE_REGISTER_VIEW:
|
|
{
|
|
Bridge::getBridge()->emitUpdateRegisters();
|
|
}
|
|
break;
|
|
|
|
case GUI_UPDATE_DISASSEMBLY_VIEW:
|
|
{
|
|
Bridge::getBridge()->emitUpdateDisassembly();
|
|
}
|
|
break;
|
|
|
|
case GUI_UPDATE_BREAKPOINTS_VIEW:
|
|
{
|
|
Bridge::getBridge()->emitUpdateBreakpoints();
|
|
}
|
|
break;
|
|
|
|
case GUI_UPDATE_WINDOW_TITLE:
|
|
{
|
|
Bridge::getBridge()->emitUpdateWindowTitle(QString(reinterpret_cast<const char*>(param1)));
|
|
}
|
|
break;
|
|
|
|
case GUI_GET_WINDOW_HANDLE:
|
|
{
|
|
return Bridge::getBridge()->winId;
|
|
}
|
|
break;
|
|
|
|
case GUI_DUMP_AT:
|
|
{
|
|
Bridge::getBridge()->emitDumpAt((int_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_ADD:
|
|
{
|
|
Bridge::getBridge()->emitScriptAdd((int)(int_t)param1, reinterpret_cast<const char**>(param2));
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_CLEAR:
|
|
{
|
|
Bridge::getBridge()->emitScriptClear();
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_SETIP:
|
|
{
|
|
Bridge::getBridge()->emitScriptSetIp((int)(int_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_ERROR:
|
|
{
|
|
Bridge::getBridge()->emitScriptError((int)(int_t)param1, QString(reinterpret_cast<const char*>(param2)));
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_SETTITLE:
|
|
{
|
|
Bridge::getBridge()->emitScriptSetTitle(QString(reinterpret_cast<const char*>(param1)));
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_SETINFOLINE:
|
|
{
|
|
Bridge::getBridge()->emitScriptSetInfoLine((int)(int_t)param1, QString(reinterpret_cast<const char*>(param2)));
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_MESSAGE:
|
|
{
|
|
Bridge::getBridge()->emitScriptMessage(QString(reinterpret_cast<const char*>(param1)));
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_MSGYN:
|
|
{
|
|
return (void*)Bridge::getBridge()->emitScriptQuestion(QString(reinterpret_cast<const char*>(param1)));
|
|
}
|
|
break;
|
|
|
|
case GUI_SCRIPT_ENABLEHIGHLIGHTING:
|
|
{
|
|
Bridge::getBridge()->emitScriptEnableHighlighting((bool)(int_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_SYMBOL_UPDATE_MODULE_LIST:
|
|
{
|
|
Bridge::getBridge()->emitUpdateSymbolList((int)(int_t)param1, (SYMBOLMODULEINFO*)param2);
|
|
}
|
|
break;
|
|
|
|
case GUI_SYMBOL_LOG_ADD:
|
|
{
|
|
Bridge::getBridge()->emitAddMsgToSymbolLog(QString(reinterpret_cast<const char*>(param1)));
|
|
}
|
|
break;
|
|
|
|
case GUI_SYMBOL_LOG_CLEAR:
|
|
{
|
|
Bridge::getBridge()->emitClearSymbolLog();
|
|
}
|
|
break;
|
|
|
|
case GUI_SYMBOL_SET_PROGRESS:
|
|
{
|
|
Bridge::getBridge()->emitSetSymbolProgress((int)(int_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_ADDCOLUMN:
|
|
{
|
|
Bridge::getBridge()->emitReferenceAddColumnAt((int)(int_t)param1, QString(reinterpret_cast<const char*>(param2)));
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_SETROWCOUNT:
|
|
{
|
|
Bridge::getBridge()->emitReferenceSetRowCount((int)(int_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_GETROWCOUNT:
|
|
{
|
|
return (void*)Bridge::getBridge()->referenceView->mList->getRowCount();
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_DELETEALLCOLUMNS:
|
|
{
|
|
Bridge::getBridge()->emitReferenceDeleteAllColumns();
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_SETCELLCONTENT:
|
|
{
|
|
CELLINFO* info=(CELLINFO*)param1;
|
|
Bridge::getBridge()->emitReferenceSetCellContent(info->row, info->col, QString(info->str));
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_GETCELLCONTENT:
|
|
{
|
|
return (void*)Bridge::getBridge()->referenceView->mList->getCellContent((int)(int_t)param1, (int)(int_t)param2).toUtf8().constData();
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_RELOADDATA:
|
|
{
|
|
Bridge::getBridge()->emitReferenceReloadData();
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_SETSINGLESELECTION:
|
|
{
|
|
Bridge::getBridge()->emitReferenceSetSingleSelection((int)(int_t)param1, (bool)(int_t)param2);
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_SETPROGRESS:
|
|
{
|
|
Bridge::getBridge()->emitReferenceSetProgress((int)(int_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_REF_SETSEARCHSTARTCOL:
|
|
{
|
|
Bridge::getBridge()->emitReferenceSetSearchStartCol((int)(int_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_STACK_DUMP_AT:
|
|
{
|
|
Bridge::getBridge()->emitStackDumpAt((uint_t)param1, (uint_t)param2);
|
|
}
|
|
break;
|
|
|
|
case GUI_UPDATE_DUMP_VIEW:
|
|
{
|
|
Bridge::getBridge()->emitUpdateDump();
|
|
}
|
|
break;
|
|
|
|
case GUI_UPDATE_THREAD_VIEW:
|
|
{
|
|
Bridge::getBridge()->emitUpdateThreads();
|
|
}
|
|
break;
|
|
|
|
case GUI_ADD_RECENT_FILE:
|
|
{
|
|
Bridge::getBridge()->emitAddRecentFile(QString(reinterpret_cast<const char*>(param1)));
|
|
}
|
|
break;
|
|
|
|
case GUI_SET_LAST_EXCEPTION:
|
|
{
|
|
Bridge::getBridge()->emitSetLastException((unsigned int)(uint_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_GET_DISASSEMBLY:
|
|
{
|
|
uint_t parVA=(uint_t)param1;
|
|
char* text=(char*)param2;
|
|
if(!text || !parVA || !DbgIsDebugging())
|
|
return 0;
|
|
byte_t wBuffer[16];
|
|
if(!DbgMemRead(parVA, wBuffer, 16))
|
|
return 0;
|
|
QBeaEngine* disasm = new QBeaEngine();
|
|
Instruction_t instr=disasm->DisassembleAt(wBuffer, 16, 0, 0, parVA);
|
|
QList<CustomRichText_t> richText;
|
|
BeaHighlight::PrintRtfInstruction(&richText, &instr.disasm);
|
|
QString finalInstruction="";
|
|
for(int i=0; i<richText.size(); i++)
|
|
finalInstruction+=richText.at(i).text;
|
|
strcpy(text, finalInstruction.toUtf8().constData());
|
|
return (void*)1;
|
|
}
|
|
break;
|
|
|
|
case GUI_MENU_ADD:
|
|
{
|
|
return (void*)(uint_t)Bridge::getBridge()->emitMenuAddMenu((int)(uint_t)param1, QString(reinterpret_cast<const char*>(param2)));
|
|
}
|
|
break;
|
|
|
|
case GUI_MENU_ADD_ENTRY:
|
|
{
|
|
return (void*)(uint_t)Bridge::getBridge()->emitMenuAddMenuEntry((int)(uint_t)param1, QString(reinterpret_cast<const char*>(param2)));
|
|
}
|
|
break;
|
|
|
|
case GUI_MENU_ADD_SEPARATOR:
|
|
{
|
|
Bridge::getBridge()->emitMenuAddSeparator((int)(uint_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_MENU_CLEAR:
|
|
{
|
|
Bridge::getBridge()->emitMenuClearMenu((int)(uint_t)param1);
|
|
}
|
|
break;
|
|
|
|
case GUI_SELECTION_GET:
|
|
{
|
|
return (void*)(int_t)Bridge::getBridge()->emitSelectionGet((int)(uint_t)param1, (SELECTIONDATA*)param2);
|
|
}
|
|
break;
|
|
|
|
case GUI_SELECTION_SET:
|
|
{
|
|
return (void*)(int_t)Bridge::getBridge()->emitSelectionSet((int)(uint_t)param1, (const SELECTIONDATA*)param2);
|
|
}
|
|
break;
|
|
|
|
case GUI_GETLINE_WINDOW:
|
|
{
|
|
QString text = "";
|
|
if(Bridge::getBridge()->emitGetStrWindow(QString(reinterpret_cast<const char*>(param1)), &text))
|
|
{
|
|
if(text.length()>=GUI_MAX_LINE_SIZE)
|
|
text.chop(text.length()-GUI_MAX_LINE_SIZE);
|
|
strcpy((char*)param2, text.toUtf8().constData());
|
|
return (void*)(uint_t)true;
|
|
}
|
|
return (void*)(uint_t)false; //cancel/escape
|
|
}
|
|
break;
|
|
|
|
case GUI_AUTOCOMPLETE_ADDCMD:
|
|
{
|
|
Bridge::getBridge()->emitAutoCompleteAddCmd(QString((const char*)param1));
|
|
}
|
|
break;
|
|
|
|
case GUI_AUTOCOMPLETE_DELCMD:
|
|
{
|
|
Bridge::getBridge()->emitAutoCompleteDelCmd(QString((const char*)param1));
|
|
}
|
|
break;
|
|
|
|
case GUI_AUTOCOMPLETE_CLEARALL:
|
|
{
|
|
Bridge::getBridge()->emitAutoCompleteClearAll();
|
|
}
|
|
break;
|
|
|
|
case GUI_ADD_MSG_TO_STATUSBAR:
|
|
{
|
|
Bridge::getBridge()->emitAddMsgToStatusBar(QString((const char*)param1));
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|