1
0
Fork 0

GUI scripting done!

This commit is contained in:
mr.exodia 2014-02-09 13:34:48 +01:00
parent cfa83ca68e
commit f6bc8ea1b9
16 changed files with 296 additions and 62 deletions

View File

@ -28,3 +28,4 @@ DBGGETBPLIST _dbg_getbplist;
DBGDBGCMDEXECDIRECT _dbg_dbgcmddirectexec;
DBGGETBRANCHDESTINATION _dbg_getbranchdestination;
DBGFUNCTIONOVERLAPS _dbg_functionoverlaps;
DBGSENDMESSAGE _dbg_sendmessage;

View File

@ -10,7 +10,7 @@ extern HINSTANCE hInstDbg;
//GUI typedefs
typedef int (*GUIGUIINIT)(int, char**);
typedef void* (*GUISENDMESSAGE)(MSGTYPE type, void* param1, void* param2);
typedef void* (*GUISENDMESSAGE)(GUIMSG type, void* param1, void* param2);
//GUI functions
extern GUIGUIINIT _gui_guiinit;
@ -36,6 +36,7 @@ typedef int (*DBGGETBPLIST)(BPXTYPE type, BPMAP* bplist);
typedef bool (*DBGDBGCMDEXECDIRECT)(const char* cmd);
typedef duint (*DBGGETBRANCHDESTINATION)(duint addr);
typedef bool (*DBGFUNCTIONOVERLAPS)(duint start, duint end);
typedef duint (*DBGSENDMESSAGE)(DBGMSG type, void* param1, void* param2);
//DBG functions
extern DBGDBGINIT _dbg_dbginit;
@ -57,5 +58,6 @@ extern DBGGETBPLIST _dbg_getbplist;
extern DBGDBGCMDEXECDIRECT _dbg_dbgcmddirectexec;
extern DBGGETBRANCHDESTINATION _dbg_getbranchdestination;
extern DBGFUNCTIONOVERLAPS _dbg_functionoverlaps;
extern DBGSENDMESSAGE _dbg_sendmessage;
#endif // _GLOBAL_H

View File

@ -120,6 +120,10 @@ BRIDGE_IMPEXP const char* BridgeInit()
_dbg_functionoverlaps=(DBGFUNCTIONOVERLAPS)GetProcAddress(hInstDbg, "_dbg_functionoverlaps");
if(!_dbg_functionoverlaps)
return "Export \"_dbg_functionoverlaps\" could not be found!";
//_dbg_sendmessage
_dbg_sendmessage=(DBGSENDMESSAGE)GetProcAddress(hInstDbg, "_dbg_sendmessage");
if(!_dbg_sendmessage)
return "Export \"_dbg_sendmessage\" could not be found!";
return 0;
}
@ -134,7 +138,7 @@ BRIDGE_IMPEXP const char* BridgeStart()
BRIDGE_IMPEXP void* BridgeAlloc(size_t size)
{
unsigned char* a= new (std::nothrow)unsigned char[size+0x1000];
unsigned char* a=new (std::nothrow)unsigned char[size+0x1000];
if(!a)
{
MessageBoxA(0, "Could not allocate memory", "Error", MB_ICONERROR);
@ -461,6 +465,49 @@ BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end)
return true;
}
BRIDGE_IMPEXP bool DbgScriptLoad(const char* filename)
{
if(_dbg_sendmessage(DBG_SCRIPT_LOAD, (void*)filename, 0))
return true;
return false;
}
BRIDGE_IMPEXP void DbgScriptUnload()
{
_dbg_sendmessage(DBG_SCRIPT_UNLOAD, 0, 0);
}
BRIDGE_IMPEXP void DbgScriptRun()
{
_dbg_sendmessage(DBG_SCRIPT_RUN, 0, 0);
}
BRIDGE_IMPEXP void DbgScriptStep()
{
_dbg_sendmessage(DBG_SCRIPT_STEP, 0, 0);
}
BRIDGE_IMPEXP bool DbgScriptBpSet(int line, bool set)
{
if(_dbg_sendmessage(DBG_SCRIPT_BPSET, (void*)(duint)line, (void*)(duint)set))
return true;
return false;
}
BRIDGE_IMPEXP bool DbgScriptBpGet(int line)
{
if(_dbg_sendmessage(DBG_SCRIPT_BPGET, (void*)(duint)line, 0))
return true;
return false;
}
BRIDGE_IMPEXP bool DbgScriptCmdExec(const char* command)
{
if(_dbg_sendmessage(DBG_SCRIPT_CMDEXEC, (void*)command, 0))
return true;
return false;
}
//GUI
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
{
@ -524,6 +571,36 @@ BRIDGE_IMPEXP void GuiDumpAt(duint va)
_gui_sendmessage(GUI_DUMP_AT, (void*)va, 0);
}
BRIDGE_IMPEXP void GuiScriptAddLine(const char* text)
{
_gui_sendmessage(GUI_SCRIPT_ADDLINE, (void*)text, 0);
}
BRIDGE_IMPEXP void GuiScriptClear()
{
_gui_sendmessage(GUI_SCRIPT_CLEAR, 0, 0);
}
BRIDGE_IMPEXP void GuiScriptSetIp(int line)
{
_gui_sendmessage(GUI_SCRIPT_SETIP, (void*)(duint)line, 0);
}
BRIDGE_IMPEXP void GuiScriptError(int line, const char* message)
{
_gui_sendmessage(GUI_SCRIPT_ERROR, (void*)(duint)line, (void*)message);
}
BRIDGE_IMPEXP void GuiScriptSetTitle(const char* title)
{
_gui_sendmessage(GUI_SCRIPT_SETTITLE, (void*)title, 0);
}
BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info)
{
_gui_sendmessage(GUI_SCRIPT_SETINFOLINE, (void*)(duint)line, (void*)info);
}
//Main
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{

View File

@ -44,7 +44,7 @@ BRIDGE_IMPEXP bool BridgeSettingSetUint(const char* section, const char* key, du
#define MAX_BREAKPOINT_SIZE 256
//Gui enums
enum MSGTYPE
enum GUIMSG
{
GUI_DISASSEMBLE_AT, // param1=(duint)va, param2=(duint)cip
GUI_SET_DEBUG_STATE, // param1=(DBGSTATE)state, param2=unused
@ -57,7 +57,14 @@ enum MSGTYPE
GUI_UPDATE_CPU_TITLE, // param1=(const char*)mod, param2=unused
GUI_SET_INFO_LINE, // param1=(int)line, param2=(const char*)text
GUI_GET_WINDOW_HANDLE, // param1=unused, param2=unused
GUI_DUMP_AT // param1=(duint)va param2=unused
GUI_DUMP_AT, // param1=(duint)va param2=unused
GUI_SCRIPT_ADDLINE, // param1=const char* text, param2=unused
GUI_SCRIPT_CLEAR, // param1=unused, param2=unused
GUI_SCRIPT_SETIP, // param1=int line, param2=unused
GUI_SCRIPT_ERROR, // param1=int line, param2=const char* message
GUI_SCRIPT_SETTITLE, // param1=const char* title, param2=unused
GUI_SCRIPT_SETINFOLINE // param1=int line, param2=const char* info
};
//Debugger enums
@ -115,6 +122,18 @@ enum LOOPTYPE
LOOP_END
};
//Debugger enums
enum DBGMSG
{
DBG_SCRIPT_LOAD, // param1=const char* filename, param2=unused
DBG_SCRIPT_UNLOAD, // param1=unused, param2=unused
DBG_SCRIPT_RUN, // param1=unused, param2=unused
DBG_SCRIPT_STEP, // param1=unused, param2=unused
DBG_SCRIPT_BPSET, // param1=int line, param2=bool set
DBG_SCRIPT_BPGET, // param1=int line, param2=unused
DBG_SCRIPT_CMDEXEC // param1=const char* command, param2=unused
};
//Debugger structs
struct MEMPAGE
{
@ -242,6 +261,14 @@ BRIDGE_IMPEXP duint DbgGetBranchDestination(duint addr);
BRIDGE_IMPEXP bool DbgFunctionOverlaps(duint start, duint end);
BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end);
BRIDGE_IMPEXP bool DbgScriptLoad(const char* filename);
BRIDGE_IMPEXP void DbgScriptUnload();
BRIDGE_IMPEXP void DbgScriptRun();
BRIDGE_IMPEXP void DbgScriptStep();
BRIDGE_IMPEXP bool DbgScriptBpSet(int line, bool set);
BRIDGE_IMPEXP bool DbgScriptBpGet(int line);
BRIDGE_IMPEXP bool DbgScriptCmdExec(const char* command);
//GUI functions
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip);
BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state);
@ -256,6 +283,13 @@ BRIDGE_IMPEXP void GuiUpdateCPUTitle(const char* modname);
BRIDGE_IMPEXP HWND GuiGetWindowHandle();
BRIDGE_IMPEXP void GuiDumpAt(duint va);
BRIDGE_IMPEXP void GuiScriptAddLine(const char* text);
BRIDGE_IMPEXP void GuiScriptClear();
BRIDGE_IMPEXP void GuiScriptSetIp(int line);
BRIDGE_IMPEXP void GuiScriptError(int line, const char* message);
BRIDGE_IMPEXP void GuiScriptSetTitle(const char* title);
BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info);
#ifdef __cplusplus
}
#endif

View File

@ -478,3 +478,8 @@ extern "C" DLL_EXPORT bool _dbg_functionoverlaps(uint start, uint end)
{
return functionoverlaps(start, end);
}
extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* param2)
{
return 0;
}

View File

@ -23,6 +23,7 @@ DLL_EXPORT bool _dbg_valtostring(const char* string, duint* value);
DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* list);
DLL_EXPORT uint _dbg_getbranchdestination(uint addr);
DLL_EXPORT bool _dbg_functionoverlaps(uint start, uint end);
DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* param2);
#ifdef __cplusplus
}

View File

@ -4,51 +4,19 @@
#include "instruction.h"
#include "x64_dbg.h"
static int total=0;
static char found[1024][1024];
static COMMAND* command_list=0;
static CMDRESULT cbRet(int argc, char* argv[])
CMDRESULT cbScriptAddLine(int argc, char* argv[])
{
return STATUS_EXIT;
}
static bool cbCommandProvider(char* cmd, int maxlen)
{
fgets(cmd, maxlen, stdin);
cmd[strlen(cmd)-1]=0;
return true;
}
static CMDRESULT cbCollect(int argc, char* argv[])
{
strcpy(found[total], *argv);
total++;
if(total>=1024)
return STATUS_EXIT;
if(argc<2)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
GuiScriptAddLine(argv[1]);
return STATUS_CONTINUE;
}
static int i=0;
static bool provider(char* cmd, int size)
CMDRESULT cbScriptClear(int argc, char* argv[])
{
strcpy(cmd, found[i]);
i++;
if(i>total)
return false;
return true;
}
CMDRESULT cbScript(int argc, char* argv[])
{
command_list=dbggetcommandlist();
total=0;
i=0;
COMMAND* cmd_list=cmdinit();
cmdnew(cmd_list, "ret", cbRet, false);
cmdloop(cmd_list, cbCollect, cbCommandProvider, 0, false);
cmdfree(cmd_list);
cmdloop(command_list, cbBadCmd, provider, cmdfindmain, true);
GuiScriptClear();
return STATUS_CONTINUE;
}

View File

@ -3,6 +3,7 @@
#include "command.h"
CMDRESULT cbScript(int argc, char* argv[]);
CMDRESULT cbScriptAddLine(int argc, char* argv[]);
CMDRESULT cbScriptClear(int argc, char* argv[]);
#endif // _SIMPLESCRIPT_H

View File

@ -67,7 +67,6 @@ static void registercommands()
cmdnew(cmd, "alloc", cbDebugAlloc, true); //allocate memory
cmdnew(cmd, "free", cbDebugFree, true); //free memory
cmdnew(cmd, "Fill\1memset", cbDebugMemset, true); //memset
cmdnew(cmd, "scr\1script", cbScript, false); //script testing
cmdnew(cmd, "bench", cbBenchmark, true); //benchmark test (readmem etc)
cmdnew(cmd, "pause", cbDebugPause, true); //pause debugger
cmdnew(cmd, "memwrite", cbMemWrite, true); //memwrite test
@ -88,6 +87,9 @@ static void registercommands()
cmdnew(cmd, "functionadd\1func", cbFunctionAdd, true); //function
cmdnew(cmd, "functiondel\1funcc", cbFunctionDel, true); //function
cmdnew(cmd, "dump", cbDebugDump, true); //dump at address
cmdnew(cmd, "scriptaddline", cbScriptAddLine, false);
cmdnew(cmd, "scriptclear", cbScriptClear, false);
}
static bool cbCommandProvider(char* cmd, int maxlen)

View File

@ -10,14 +10,14 @@ ScriptView::ScriptView(StdTable *parent) : StdTable(parent)
addColumnAt(8+charwidth*60, "Text", false);
addColumnAt(8+charwidth*40, "Info", false);
const char* sample_script[6]={"var test,123", "mov test,$pid", "mov eax,pid", "estep", "mov test,eax", "ret"};
setIp(0); //no IP
setRowCount(6);
for(int i=0; i<6; i++)
{
setCellContent(i, 1, sample_script[i]);
}
connect(Bridge::getBridge(), SIGNAL(scriptAddLine(QString)), this, SLOT(addLine(QString)));
connect(Bridge::getBridge(), SIGNAL(scriptClear()), this, SLOT(clear()));
connect(Bridge::getBridge(), SIGNAL(scriptSetIp(int)), this, SLOT(setIp(int)));
connect(Bridge::getBridge(), SIGNAL(scriptError(int,QString)), this, SLOT(error(int,QString)));
connect(Bridge::getBridge(), SIGNAL(scriptSetTitle(QString)), this, SLOT(setTitle(QString)));
connect(Bridge::getBridge(), SIGNAL(scriptSetInfoLine(int,QString)), this, SLOT(setInfoLine(int,QString)));
}
QString ScriptView::paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)
@ -31,15 +31,18 @@ QString ScriptView::paintContent(QPainter* painter, int_t rowBase, int rowOffset
{
case 0: //line number
{
int line=rowOffset+1;
int line=rowBase+rowOffset+1;
returnString=returnString.sprintf("%.4d", line);
painter->save();
if(line==2)
if(line==mIpLine) //IP
{
painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#000000")));
painter->setPen(QPen(QColor("#FFFFFF"))); //black address
if(DbgScriptBpGet(line)) //breakpoint
painter->setPen(QPen(QColor("#FF0000"))); //red address
else
painter->setPen(QPen(QColor("#FFFFFF"))); //black address
}
else if(line==5)
else if(DbgScriptBpGet(line)) //breakpoint
{
painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#ff0000")));
painter->setPen(QPen(QColor("#000000"))); //black address
@ -59,15 +62,61 @@ QString ScriptView::paintContent(QPainter* painter, int_t rowBase, int rowOffset
case 1: //command
{
returnString=getCellContent(rowOffset, col);
returnString=getCellContent(rowBase+rowOffset, col);
}
break;
case 2: //info
{
returnString=getCellContent(rowOffset, col);
returnString=getCellContent(rowBase+rowOffset, col);
}
break;
}
return returnString;
}
void ScriptView::addLine(QString text)
{
int rows=getRowCount();
setRowCount(rows+1);
setCellContent(rows, 1, text);
reloadData(); //repaint
}
void ScriptView::clear()
{
setRowCount(0);
mIpLine=0;
reloadData(); //repaint
}
void ScriptView::setIp(int line)
{
if(!isValidIndex(line-1, 0))
return;
mIpLine=line;
reloadData(); //repaint
}
void ScriptView::error(int line, QString message)
{
QString title;
if(isValidIndex(line-1, 0))
title=title.sprintf("Error on line %.4d!", line);
else
title="Script Error!";
QMessageBox msg(QMessageBox::Critical, title, message);
msg.setWindowIcon(QIcon(":/icons/images/script-error.png"));
msg.exec();
}
void ScriptView::setTitle(QString title)
{
setWindowTitle(title);
}
void ScriptView::setInfoLine(int line, QString info)
{
setCellContent(line-1, 2, info);
reloadData(); //repaint
}

View File

@ -12,6 +12,17 @@ public:
explicit ScriptView(StdTable *parent = 0);
// Reimplemented Functions
QString paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h);
public slots:
void addLine(QString text);
void clear();
void setIp(int line);
void error(int line, QString message);
void setTitle(QString title);
void setInfoLine(int line, QString info);
private:
int mIpLine;
};
#endif // SCRIPTVIEW_H

View File

@ -79,6 +79,36 @@ void Bridge::emitDumpAt(int_t va)
emit dumpAt(va);
}
void Bridge::emitScriptAddLine(QString text)
{
emit scriptAddLine(text);
}
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);
}
/************************************************************************************
Static Functions
@ -102,7 +132,7 @@ __declspec(dllexport) int _gui_guiinit(int argc, char *argv[])
return main(argc, argv);
}
__declspec(dllexport) void* _gui_sendmessage(MSGTYPE type, void* param1, void* param2)
__declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* param2)
{
switch(type)
{
@ -178,6 +208,45 @@ __declspec(dllexport) void* _gui_sendmessage(MSGTYPE type, void* param1, void* p
}
break;
case GUI_SCRIPT_ADDLINE:
{
Bridge::getBridge()->emitScriptAddLine(QString(reinterpret_cast<const char*>(param1)));
}
break;
case GUI_SCRIPT_CLEAR:
{
Bridge::getBridge()->emitScriptClear();
}
break;
case GUI_SCRIPT_SETIP:
{
int_t arg=(int_t)param1;
Bridge::getBridge()->emitScriptSetIp((int)arg);
}
break;
case GUI_SCRIPT_ERROR:
{
int_t arg=(int_t)param1;
Bridge::getBridge()->emitScriptError((int)arg, 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:
{
int_t arg=(int_t)param1;
Bridge::getBridge()->emitScriptSetInfoLine((int)arg, QString(reinterpret_cast<const char*>(param2)));
}
break;
default:
{
}

View File

@ -34,6 +34,12 @@ public:
void emitSetInfoLine(int line, QString text);
void emitClearInfoBox();
void emitDumpAt(int_t va);
void emitScriptAddLine(QString text);
void emitScriptClear();
void emitScriptSetIp(int line);
void emitScriptError(int line, QString message);
void emitScriptSetTitle(QString title);
void emitScriptSetInfoLine(int line, QString info);
void* winId;
@ -49,6 +55,13 @@ signals:
void updateCPUTitle(QString modname);
void setInfoLine(int line, QString text);
void dumpAt(int_t va);
void scriptAddLine(QString text);
void scriptClear();
void scriptSetIp(int line);
void scriptError(int line, QString message);
void scriptSetTitle(QString title);
void scriptSetInfoLine(int line, QString info);
public slots:

View File

@ -9,7 +9,7 @@
#ifdef BUILD_LIB
extern "C" __declspec(dllexport) int _gui_guiinit(int argc, char *argv[]);
extern "C" __declspec(dllexport) void* _gui_sendmessage(MSGTYPE type, void* param1, void* param2);
extern "C" __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* param2);
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

View File

@ -22,5 +22,6 @@
<file>images/compile-warning.png</file>
<file>images/compile.png</file>
<file>images/script-code.png</file>
<file>images/script-error.png</file>
</qresource>
</RCC>