mirror of
https://github.com/x64dbg/x64dbg.git
synced 2024-10-07 18:23:49 +00:00
script dummy working
This commit is contained in:
parent
d982bc2365
commit
e85b2a8a91
@ -465,11 +465,9 @@ BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end)
|
||||
return true;
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP bool DbgScriptLoad(const char* filename)
|
||||
BRIDGE_IMPEXP void DbgScriptLoad(const char* filename)
|
||||
{
|
||||
if(_dbg_sendmessage(DBG_SCRIPT_LOAD, (void*)filename, 0))
|
||||
return true;
|
||||
return false;
|
||||
_dbg_sendmessage(DBG_SCRIPT_LOAD, (void*)filename, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void DbgScriptUnload()
|
||||
@ -513,6 +511,11 @@ BRIDGE_IMPEXP void DbgScriptAbort()
|
||||
_dbg_sendmessage(DBG_SCRIPT_ABORT, 0, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line)
|
||||
{
|
||||
return (SCRIPTLINETYPE)_dbg_sendmessage(DBG_SCRIPT_GETLINETYPE, (void*)(duint)line, 0);
|
||||
}
|
||||
|
||||
//GUI
|
||||
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
|
||||
{
|
||||
@ -606,6 +609,11 @@ BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info)
|
||||
_gui_sendmessage(GUI_SCRIPT_SETINFOLINE, (void*)(duint)line, (void*)info);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptMessage(const char* message)
|
||||
{
|
||||
_gui_sendmessage(GUI_SCRIPT_MESSAGE, (void*)message, 0);
|
||||
}
|
||||
|
||||
//Main
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
|
@ -42,30 +42,7 @@ BRIDGE_IMPEXP bool BridgeSettingSetUint(const char* section, const char* key, du
|
||||
#define MAX_COMMENT_SIZE 512
|
||||
#define MAX_MODULE_SIZE 256
|
||||
#define MAX_BREAKPOINT_SIZE 256
|
||||
|
||||
//Gui enums
|
||||
enum GUIMSG
|
||||
{
|
||||
GUI_DISASSEMBLE_AT, // param1=(duint)va, param2=(duint)cip
|
||||
GUI_SET_DEBUG_STATE, // param1=(DBGSTATE)state, param2=unused
|
||||
GUI_ADD_MSG_TO_LOG, // param1=(const char*)msg, param2=unused
|
||||
GUI_CLEAR_LOG, // param1=unused, param2=unused
|
||||
GUI_UPDATE_REGISTER_VIEW, // param1=unused, param2=unused
|
||||
GUI_UPDATE_DISASSEMBLY_VIEW, // param1=unused, param2=unused
|
||||
GUI_UPDATE_BREAKPOINTS_VIEW, // param1=unused, param2=unused
|
||||
GUI_UPDATE_WINDOW_TITLE, // param1=(const char*)file, param2=unused
|
||||
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_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
|
||||
};
|
||||
#define MAX_SCRIPT_LINE_SIZE 2048
|
||||
|
||||
//Debugger enums
|
||||
enum DBGSTATE
|
||||
@ -122,7 +99,6 @@ enum LOOPTYPE
|
||||
LOOP_END
|
||||
};
|
||||
|
||||
//Debugger enums
|
||||
enum DBGMSG
|
||||
{
|
||||
DBG_SCRIPT_LOAD, // param1=const char* filename, param2=unused
|
||||
@ -133,6 +109,16 @@ enum DBGMSG
|
||||
DBG_SCRIPT_BPGET, // param1=int line, param2=unused
|
||||
DBG_SCRIPT_CMDEXEC, // param1=const char* command, param2=unused
|
||||
DBG_SCRIPT_ABORT, // param1=unused, param2=unused
|
||||
DBG_SCRIPT_GETLINETYPE // param1=int line, param2=unused
|
||||
};
|
||||
|
||||
enum SCRIPTLINETYPE
|
||||
{
|
||||
linecommand,
|
||||
linebranch,
|
||||
linelabel,
|
||||
linecomment,
|
||||
lineempty,
|
||||
};
|
||||
|
||||
//Debugger structs
|
||||
@ -262,7 +248,7 @@ 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 DbgScriptLoad(const char* filename);
|
||||
BRIDGE_IMPEXP void DbgScriptUnload();
|
||||
BRIDGE_IMPEXP void DbgScriptRun(int destline);
|
||||
BRIDGE_IMPEXP void DbgScriptStep();
|
||||
@ -270,6 +256,32 @@ BRIDGE_IMPEXP bool DbgScriptBpToggle(int line);
|
||||
BRIDGE_IMPEXP bool DbgScriptBpGet(int line);
|
||||
BRIDGE_IMPEXP bool DbgScriptCmdExec(const char* command);
|
||||
BRIDGE_IMPEXP void DbgScriptAbort();
|
||||
BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line);
|
||||
|
||||
//Gui enums
|
||||
enum GUIMSG
|
||||
{
|
||||
GUI_DISASSEMBLE_AT, // param1=(duint)va, param2=(duint)cip
|
||||
GUI_SET_DEBUG_STATE, // param1=(DBGSTATE)state, param2=unused
|
||||
GUI_ADD_MSG_TO_LOG, // param1=(const char*)msg, param2=unused
|
||||
GUI_CLEAR_LOG, // param1=unused, param2=unused
|
||||
GUI_UPDATE_REGISTER_VIEW, // param1=unused, param2=unused
|
||||
GUI_UPDATE_DISASSEMBLY_VIEW, // param1=unused, param2=unused
|
||||
GUI_UPDATE_BREAKPOINTS_VIEW, // param1=unused, param2=unused
|
||||
GUI_UPDATE_WINDOW_TITLE, // param1=(const char*)file, param2=unused
|
||||
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_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
|
||||
GUI_SCRIPT_MESSAGE // param1=const char* message, param2=unused
|
||||
};
|
||||
|
||||
//GUI functions
|
||||
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip);
|
||||
@ -291,6 +303,7 @@ 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);
|
||||
BRIDGE_IMPEXP void GuiScriptMessage(const char* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -486,7 +486,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
||||
{
|
||||
case DBG_SCRIPT_LOAD:
|
||||
{
|
||||
return scriptload((const char*)param1);
|
||||
scriptload((const char*)param1);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -531,6 +531,12 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
||||
scriptabort();
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_SCRIPT_GETLINETYPE:
|
||||
{
|
||||
return (duint)scriptgetlinetype((int)(duint)param1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,122 +1,387 @@
|
||||
#include "simplescript.h"
|
||||
#include "value.h"
|
||||
#include "console.h"
|
||||
#include "argument.h"
|
||||
|
||||
bool scriptload(const char* filename)
|
||||
static std::vector<LINEMAPENTRY> linemap;
|
||||
static std::vector<SCRIPTBP> scriptbplist;
|
||||
static int scriptIp=0;
|
||||
static bool bAbort=false;
|
||||
static bool bIsRunning=false;
|
||||
|
||||
static SCRIPTBRANCHTYPE getbranchtype(const char* text)
|
||||
{
|
||||
dprintf("scriptload(%s)\n", filename);
|
||||
if(!strncmp(text, "jmp", 3))
|
||||
return scriptjmp;
|
||||
else if(!strncmp(text, "jne", 3) or !strncmp(text, "jnz", 3))
|
||||
return scriptjnejnz;
|
||||
else if(!strncmp(text, "je", 2) or !strncmp(text, "jz", 2))
|
||||
return scriptjnejnz;
|
||||
else if(!strncmp(text, "jb", 2) or !strncmp(text, "jl", 2))
|
||||
return scriptjnejnz;
|
||||
else if(!strncmp(text, "ja", 2) or !strncmp(text, "jg", 2))
|
||||
return scriptjnejnz;
|
||||
else if(!strncmp(text, "jbe", 3) or !strncmp(text, "jle", 3))
|
||||
return scriptjnejnz;
|
||||
else if(!strncmp(text, "jae", 3) or !strncmp(text, "jge", 3))
|
||||
return scriptjnejnz;
|
||||
return scriptnobranch;
|
||||
}
|
||||
|
||||
static bool islabel(const char* text)
|
||||
{
|
||||
if(!strstr(text, " ") and !strstr(text, ",") and !strstr(text, "\\") and text[strlen(text)-1]==':')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool createlinemap(const char* filename)
|
||||
{
|
||||
HANDLE hFile=CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
if(hFile==INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
unsigned int filesize=GetFileSize(hFile, 0);
|
||||
char* filedata=(char*)emalloc(filesize+1, "createlinemap:filedata");
|
||||
memset(filedata, 0, filesize+1);
|
||||
DWORD read=0;
|
||||
if(!ReadFile(hFile, filedata, filesize, &read, 0))
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
GuiScriptError(0, "ReadFile failed...");
|
||||
efree(filedata, "createlinemap:filedata");
|
||||
return false;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
int len=strlen(filedata);
|
||||
char temp[256]="";
|
||||
LINEMAPENTRY entry;
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
linemap.clear();
|
||||
for(int i=0,j=0; i<len; i++) //make raw line map
|
||||
{
|
||||
if(filedata[i]=='\r' and filedata[i+1]=='\n') //windows file
|
||||
{
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
strcpy(entry.raw, temp);
|
||||
*temp=0;
|
||||
j=0;
|
||||
i++;
|
||||
linemap.push_back(entry);
|
||||
}
|
||||
else if(filedata[i]=='\n') //other file
|
||||
{
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
strcpy(entry.raw, temp);
|
||||
*temp=0;
|
||||
j=0;
|
||||
linemap.push_back(entry);
|
||||
}
|
||||
else if(j>=254)
|
||||
{
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
argformat(temp);
|
||||
strcpy(entry.raw, temp);
|
||||
*temp=0;
|
||||
j=0;
|
||||
linemap.push_back(entry);
|
||||
}
|
||||
else
|
||||
j+=sprintf(temp+j, "%c", filedata[i]);
|
||||
}
|
||||
if(*temp)
|
||||
{
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
strcpy(entry.raw, temp);
|
||||
linemap.push_back(entry);
|
||||
}
|
||||
efree(filedata, "createlinemap:filedata");
|
||||
unsigned int linemapsize=linemap.size();
|
||||
while(!*linemap.at(linemapsize-1).raw) //remove empty lines
|
||||
{
|
||||
linemapsize--;
|
||||
linemap.pop_back();
|
||||
}
|
||||
for(unsigned int i=0; i<linemapsize; i++)
|
||||
{
|
||||
LINEMAPENTRY cur=linemap.at(i);
|
||||
int rawlen=strlen(cur.raw);
|
||||
if(!strlen(cur.raw)) //empty
|
||||
{
|
||||
cur.type=lineempty;
|
||||
}
|
||||
else if(!strncmp(cur.raw, "//", 2)) //comment
|
||||
{
|
||||
cur.type=linecomment;
|
||||
strcpy(cur.u.comment, cur.raw);
|
||||
}
|
||||
else if(islabel(cur.raw)) //label
|
||||
{
|
||||
cur.type=linelabel;
|
||||
strncpy(cur.u.label, cur.raw, rawlen-1);
|
||||
}
|
||||
else if(getbranchtype(cur.raw)!=scriptnobranch) //branch
|
||||
{
|
||||
cur.type=linebranch;
|
||||
cur.u.branch.type=getbranchtype(cur.raw);
|
||||
int len=strlen(cur.raw);
|
||||
for(int i=0; i<len; i++)
|
||||
if(cur.raw[i]==' ')
|
||||
{
|
||||
strcpy(cur.u.branch.branchlabel, cur.raw+i+1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cur.type=linecommand;
|
||||
strcpy(cur.u.command, cur.raw);
|
||||
}
|
||||
linemap.at(i)=cur;
|
||||
}
|
||||
linemapsize=linemap.size();
|
||||
if(linemap.at(linemapsize-1).type==linecomment or linemap.at(linemapsize-1).type==linelabel) //label/comment on the end
|
||||
{
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
entry.type=linecommand;
|
||||
strcpy(entry.raw, "ret");
|
||||
strcpy(entry.u.command, "ret");
|
||||
linemap.push_back(entry);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int scriptinternalstep(int fromIp) //internal step routine
|
||||
{
|
||||
int maxIp=linemap.size(); //maximum ip
|
||||
if(fromIp==maxIp) //script end
|
||||
return fromIp;
|
||||
while((linemap.at(fromIp).type==lineempty or linemap.at(fromIp).type==linecomment or linemap.at(fromIp).type==linelabel) and fromIp<maxIp) //skip empty lines
|
||||
fromIp++;
|
||||
fromIp++;
|
||||
return fromIp;
|
||||
}
|
||||
|
||||
static bool scriptinternalbpget(int line) //internal bpget routine
|
||||
{
|
||||
int bpcount=scriptbplist.size();
|
||||
for(int i=0; i<bpcount; i++)
|
||||
if(scriptbplist.at(i).line==line)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool scriptinternalbptoggle(int line) //internal breakpoint
|
||||
{
|
||||
if(!line or line>(int)linemap.size()) //invalid line
|
||||
return false;
|
||||
line=scriptinternalstep(line-1); //no breakpoints on non-executable locations
|
||||
if(scriptinternalbpget(line)) //remove breakpoint
|
||||
{
|
||||
int bpcount=scriptbplist.size();
|
||||
for(int i=0; i<bpcount; i++)
|
||||
if(scriptbplist.at(i).line==line)
|
||||
{
|
||||
scriptbplist.erase(scriptbplist.begin()+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //add breakpoint
|
||||
{
|
||||
SCRIPTBP newbp;
|
||||
newbp.silent=true;
|
||||
newbp.line=line;
|
||||
scriptbplist.push_back(newbp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static CMDRESULT scriptinternalcmdexec(const char* command)
|
||||
{
|
||||
dprintf("scriptinternalcmdexec(%s)\n", command);
|
||||
if(!strcmp(command, "ret"))
|
||||
{
|
||||
GuiScriptMessage("Script finished!");
|
||||
return STATUS_EXIT;
|
||||
}
|
||||
else if(!strcmp(command, "invalid"))
|
||||
return STATUS_ERROR;
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static DWORD WINAPI runThread(void* arg)
|
||||
{
|
||||
int destline=(int)(duint)arg;
|
||||
if(!destline or destline>(int)linemap.size()) //invalid line
|
||||
destline=0;
|
||||
if(destline)
|
||||
{
|
||||
destline=scriptinternalstep(destline-1); //no breakpoints on non-executable locations
|
||||
if(!scriptinternalbpget(destline)) //no breakpoint set
|
||||
scriptinternalbptoggle(destline);
|
||||
}
|
||||
bAbort=false;
|
||||
if(scriptIp)
|
||||
scriptIp--;
|
||||
scriptIp=scriptinternalstep(scriptIp);
|
||||
bool bContinue=true;
|
||||
while(bContinue && !bAbort) //run loop
|
||||
{
|
||||
LINEMAPENTRY cur=linemap.at(scriptIp-1);
|
||||
if(cur.type==linecommand)
|
||||
{
|
||||
CMDRESULT cmdres=scriptinternalcmdexec(cur.u.command);
|
||||
switch(cmdres)
|
||||
{
|
||||
case STATUS_CONTINUE:
|
||||
break;
|
||||
case STATUS_ERROR:
|
||||
bContinue=false;
|
||||
GuiScriptError(scriptIp, "Error executing command!");
|
||||
break;
|
||||
case STATUS_EXIT:
|
||||
bContinue=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(cur.type==linebranch) //branch
|
||||
{
|
||||
bContinue=false;
|
||||
GuiScriptError(scriptIp, "Branches are not yet supported...");
|
||||
}
|
||||
if(scriptIp==scriptinternalstep(scriptIp)) //end of script
|
||||
{
|
||||
bContinue=false;
|
||||
scriptIp=scriptinternalstep(0);
|
||||
}
|
||||
if(bContinue)
|
||||
scriptIp=scriptinternalstep(scriptIp); //this is the next ip
|
||||
if(scriptinternalbpget(scriptIp)) //breakpoint=stop run loop
|
||||
bContinue=false;
|
||||
Sleep(1); //don't fry the processor
|
||||
}
|
||||
bIsRunning=false; //not running anymore
|
||||
GuiScriptSetIp(scriptIp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scriptload(const char* filename)
|
||||
{
|
||||
GuiScriptClear();
|
||||
scriptIp=0;
|
||||
scriptbplist.clear(); //clear breakpoints
|
||||
bAbort=false;
|
||||
if(!createlinemap(filename))
|
||||
return;
|
||||
for(unsigned int i=0; i<linemap.size(); i++) //add script lines
|
||||
GuiScriptAddLine(linemap.at(i).raw);
|
||||
scriptIp=scriptinternalstep(0);
|
||||
GuiScriptSetIp(scriptIp);
|
||||
}
|
||||
|
||||
void scriptunload()
|
||||
{
|
||||
dputs("scriptunload");
|
||||
GuiScriptClear();
|
||||
scriptIp=0;
|
||||
scriptbplist.clear(); //clear breakpoints
|
||||
bAbort=false;
|
||||
}
|
||||
|
||||
void scriptrun(int destline)
|
||||
{
|
||||
dprintf("scriptrun(%d)\n", destline);
|
||||
if(bIsRunning) //already running
|
||||
return;
|
||||
bIsRunning=true;
|
||||
CreateThread(0, 0, runThread, (void*)(duint)destline, 0, 0);
|
||||
}
|
||||
|
||||
void scriptstep()
|
||||
{
|
||||
dputs("scriptstep");
|
||||
if(bIsRunning) //already running
|
||||
return;
|
||||
scriptIp=scriptinternalstep(scriptIp-1); //probably useless
|
||||
bool bContinue=true;
|
||||
LINEMAPENTRY cur=linemap.at(scriptIp-1);
|
||||
if(cur.type==linecommand)
|
||||
{
|
||||
CMDRESULT cmdres=scriptinternalcmdexec(cur.u.command);
|
||||
switch(cmdres)
|
||||
{
|
||||
case STATUS_CONTINUE:
|
||||
break;
|
||||
case STATUS_ERROR:
|
||||
bContinue=false;
|
||||
GuiScriptError(scriptIp, "Error executing command!");
|
||||
break;
|
||||
case STATUS_EXIT:
|
||||
bContinue=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(cur.type==linebranch) //branch
|
||||
{
|
||||
bContinue=false;
|
||||
GuiScriptError(scriptIp, "Branches are not yet supported...");
|
||||
}
|
||||
|
||||
if(!bContinue)
|
||||
return;
|
||||
|
||||
if(scriptIp==scriptinternalstep(scriptIp)) //end of script
|
||||
scriptIp=0;
|
||||
scriptIp=scriptinternalstep(scriptIp);
|
||||
GuiScriptSetIp(scriptIp);
|
||||
}
|
||||
|
||||
bool scriptbptoggle(int line)
|
||||
{
|
||||
dprintf("scriptbptoggle(%d)\n", line);
|
||||
if(!line or line>(int)linemap.size()) //invalid line
|
||||
return false;
|
||||
line=scriptinternalstep(line-1); //no breakpoints on non-executable locations
|
||||
if(scriptbpget(line)) //remove breakpoint
|
||||
{
|
||||
int bpcount=scriptbplist.size();
|
||||
for(int i=0; i<bpcount; i++)
|
||||
if(scriptbplist.at(i).line==line && !scriptbplist.at(i).silent)
|
||||
{
|
||||
scriptbplist.erase(scriptbplist.begin()+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //add breakpoint
|
||||
{
|
||||
SCRIPTBP newbp;
|
||||
newbp.silent=false;
|
||||
newbp.line=line;
|
||||
scriptbplist.push_back(newbp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool scriptbpget(int line)
|
||||
{
|
||||
if(line==5)
|
||||
return true;
|
||||
int bpcount=scriptbplist.size();
|
||||
for(int i=0; i<bpcount; i++)
|
||||
if(scriptbplist.at(i).line==line && !scriptbplist.at(i).silent)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool scriptcmdexec(const char* command)
|
||||
{
|
||||
dprintf("scriptcmdexec(%s)\n", command);
|
||||
return true;
|
||||
if(scriptinternalcmdexec(command)!=STATUS_ERROR)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void scriptabort()
|
||||
{
|
||||
dputs("scriptabort");
|
||||
if(bIsRunning)
|
||||
bAbort=true;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptAddLine(int argc, char* argv[])
|
||||
SCRIPTLINETYPE scriptgetlinetype(int line)
|
||||
{
|
||||
if(argc<2)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiScriptAddLine(argv[1]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptClear(int argc, char* argv[])
|
||||
{
|
||||
GuiScriptClear();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptSetIp(int argc, char* argv[])
|
||||
{
|
||||
if(argc<2)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint line=0;
|
||||
if(!valfromstring(argv[1], &line, 0, 0, false, 0))
|
||||
return STATUS_ERROR;
|
||||
GuiScriptSetIp((int)line);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptError(int argc, char* argv[])
|
||||
{
|
||||
if(argc<2)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint line=0;
|
||||
if(argc>=3)
|
||||
if(!valfromstring(argv[2], &line, 0, 0, false, 0))
|
||||
return STATUS_ERROR;
|
||||
GuiScriptError((int)line, argv[1]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptSetTitle(int argc, char* argv[])
|
||||
{
|
||||
if(argc<2)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiScriptSetTitle(argv[1]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptSetInfoLine(int argc, char* argv[])
|
||||
{
|
||||
if(argc<2)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint line=0;
|
||||
if(!valfromstring(argv[1], &line, 0, 0, false, 0))
|
||||
return STATUS_ERROR;
|
||||
if(argc<3)
|
||||
GuiScriptSetInfoLine((int)line, "");
|
||||
else
|
||||
GuiScriptSetInfoLine((int)line, argv[2]);
|
||||
return STATUS_CONTINUE;
|
||||
if(line>(int)linemap.size())
|
||||
return lineempty;
|
||||
return linemap.at(line-1).type;
|
||||
}
|
||||
|
@ -3,7 +3,47 @@
|
||||
|
||||
#include "command.h"
|
||||
|
||||
bool scriptload(const char* filename);
|
||||
//enums
|
||||
enum SCRIPTBRANCHTYPE
|
||||
{
|
||||
scriptnobranch,
|
||||
scriptjmp,
|
||||
scriptjnejnz,
|
||||
scriptjejz,
|
||||
scriptjbjl,
|
||||
scriptjajg,
|
||||
scriptjbejle,
|
||||
scriptjaejge
|
||||
};
|
||||
|
||||
//structures
|
||||
struct SCRIPTBP
|
||||
{
|
||||
int line;
|
||||
bool silent; //do not show in GUI
|
||||
};
|
||||
|
||||
struct SCRIPTBRANCH
|
||||
{
|
||||
SCRIPTBRANCHTYPE type;
|
||||
char branchlabel[256];
|
||||
};
|
||||
|
||||
struct LINEMAPENTRY
|
||||
{
|
||||
SCRIPTLINETYPE type;
|
||||
char raw[256];
|
||||
union
|
||||
{
|
||||
char command[256];
|
||||
SCRIPTBRANCH branch;
|
||||
char label[256];
|
||||
char comment[256];
|
||||
} u;
|
||||
};
|
||||
|
||||
//functions
|
||||
void scriptload(const char* filename);
|
||||
void scriptunload();
|
||||
void scriptrun(int destline);
|
||||
void scriptstep();
|
||||
@ -11,12 +51,6 @@ bool scriptbptoggle(int line);
|
||||
bool scriptbpget(int line);
|
||||
bool scriptcmdexec(const char* command);
|
||||
void scriptabort();
|
||||
|
||||
CMDRESULT cbScriptAddLine(int argc, char* argv[]);
|
||||
CMDRESULT cbScriptClear(int argc, char* argv[]);
|
||||
CMDRESULT cbScriptSetIp(int argc, char* argv[]);
|
||||
CMDRESULT cbScriptError(int argc, char* argv[]);
|
||||
CMDRESULT cbScriptSetTitle(int argc, char* argv[]);
|
||||
CMDRESULT cbScriptSetInfoLine(int argc, char* argv[]);
|
||||
SCRIPTLINETYPE scriptgetlinetype(int line);
|
||||
|
||||
#endif // _SIMPLESCRIPT_H
|
||||
|
@ -87,15 +87,6 @@ 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);
|
||||
cmdnew(cmd, "scriptsetip", cbScriptSetIp, false);
|
||||
cmdnew(cmd, "scripterror", cbScriptError, false);
|
||||
cmdnew(cmd, "scriptsettitle", cbScriptSetTitle, false);
|
||||
cmdnew(cmd, "scriptsetinfoline", cbScriptSetInfoLine, false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static bool cbCommandProvider(char* cmd, int maxlen)
|
||||
|
@ -18,6 +18,7 @@ ScriptView::ScriptView(StdTable *parent) : StdTable(parent)
|
||||
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)));
|
||||
connect(Bridge::getBridge(), SIGNAL(scriptMessage(QString)), this, SLOT(message(QString)));
|
||||
|
||||
setupContextMenu();
|
||||
}
|
||||
@ -29,11 +30,12 @@ QString ScriptView::paintContent(QPainter* painter, int_t rowBase, int rowOffset
|
||||
if(wIsSelected)
|
||||
painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#C0C0C0")));
|
||||
QString returnString;
|
||||
int line=rowBase+rowOffset+1;
|
||||
SCRIPTLINETYPE linetype=DbgScriptGetLineType(line);
|
||||
switch(col)
|
||||
{
|
||||
case 0: //line number
|
||||
{
|
||||
int line=rowBase+rowOffset+1;
|
||||
returnString=returnString.sprintf("%.4d", line);
|
||||
painter->save();
|
||||
if(line==mIpLine) //IP
|
||||
@ -51,10 +53,10 @@ QString ScriptView::paintContent(QPainter* painter, int_t rowBase, int rowOffset
|
||||
}
|
||||
else
|
||||
{
|
||||
if(wIsSelected)
|
||||
if(linetype==linecommand || linetype==linebranch)
|
||||
painter->setPen(QPen(QColor("#000000"))); //black address
|
||||
else
|
||||
painter->setPen(QPen(QColor("#808080")));
|
||||
painter->setPen(QPen(QColor("#808080"))); //grey address
|
||||
}
|
||||
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, returnString);
|
||||
painter->restore();
|
||||
@ -64,7 +66,19 @@ QString ScriptView::paintContent(QPainter* painter, int_t rowBase, int rowOffset
|
||||
|
||||
case 1: //command
|
||||
{
|
||||
returnString=getCellContent(rowBase+rowOffset, col);
|
||||
painter->save();
|
||||
if(linetype==linecomment || linetype==linelabel)
|
||||
painter->setPen(QPen(QColor("#808080"))); //grey text
|
||||
if(linetype!=linelabel)
|
||||
returnString=QString(" ") + getCellContent(rowBase+rowOffset, col);
|
||||
else //label
|
||||
{
|
||||
returnString=getCellContent(rowBase+rowOffset, col);
|
||||
painter->drawLine(QPoint(x+2, y+h-2), QPoint(x+w-4, y+h-2));
|
||||
}
|
||||
painter->drawText(QRect(x+1, y , w , h), Qt::AlignVCenter | Qt::AlignLeft, returnString);
|
||||
painter->restore();
|
||||
returnString="";
|
||||
}
|
||||
break;
|
||||
|
||||
@ -205,8 +219,7 @@ void ScriptView::openFile()
|
||||
return;
|
||||
filename=QDir::toNativeSeparators(filename); //convert to native path format (with backlashes)
|
||||
DbgScriptUnload();
|
||||
if(!DbgScriptLoad(filename.toUtf8().constData()))
|
||||
error(0, "Failed to open script!");
|
||||
DbgScriptLoad(filename.toUtf8().constData());
|
||||
}
|
||||
|
||||
void ScriptView::unload()
|
||||
@ -216,29 +229,40 @@ void ScriptView::unload()
|
||||
|
||||
void ScriptView::run()
|
||||
{
|
||||
if(!getRowCount())
|
||||
return;
|
||||
DbgScriptRun(0);
|
||||
}
|
||||
|
||||
void ScriptView::bpToggle()
|
||||
{
|
||||
if(!getRowCount())
|
||||
return;
|
||||
int selected=getInitialSelection()+1;
|
||||
if(!DbgScriptBpToggle(selected))
|
||||
error(selected, "Error setting script breakpoint!");
|
||||
reloadData();
|
||||
}
|
||||
|
||||
void ScriptView::runCursor()
|
||||
{
|
||||
if(!getRowCount())
|
||||
return;
|
||||
int selected=getInitialSelection()+1;
|
||||
DbgScriptRun(selected);
|
||||
}
|
||||
|
||||
void ScriptView::step()
|
||||
{
|
||||
if(!getRowCount())
|
||||
return;
|
||||
DbgScriptStep();
|
||||
}
|
||||
|
||||
void ScriptView::abort()
|
||||
{
|
||||
if(!getRowCount())
|
||||
return;
|
||||
DbgScriptAbort();
|
||||
}
|
||||
|
||||
@ -251,3 +275,10 @@ void ScriptView::cmdExec()
|
||||
if(!DbgScriptCmdExec(mLineEdit.editText.toUtf8().constData()))
|
||||
error(0, "Error executing command!");
|
||||
}
|
||||
|
||||
void ScriptView::message(QString message)
|
||||
{
|
||||
QMessageBox msg(QMessageBox::Information, "Information", message);
|
||||
msg.setWindowIcon(QIcon(":/icons/images/information.png"));
|
||||
msg.exec();
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ public slots:
|
||||
void step();
|
||||
void abort();
|
||||
void cmdExec();
|
||||
void message(QString message);
|
||||
|
||||
private:
|
||||
//private functions
|
||||
|
@ -109,6 +109,11 @@ void Bridge::emitScriptSetInfoLine(int line, QString info)
|
||||
emit scriptSetInfoLine(line, info);
|
||||
}
|
||||
|
||||
void Bridge::emitScriptMessage(QString message)
|
||||
{
|
||||
emit scriptMessage(message);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
Static Functions
|
||||
@ -247,6 +252,12 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_SCRIPT_MESSAGE:
|
||||
{
|
||||
Bridge::getBridge()->emitScriptMessage(QString(reinterpret_cast<const char*>(param1)));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
void emitScriptError(int line, QString message);
|
||||
void emitScriptSetTitle(QString title);
|
||||
void emitScriptSetInfoLine(int line, QString info);
|
||||
void emitScriptMessage(QString message);
|
||||
|
||||
void* winId;
|
||||
|
||||
@ -62,6 +63,7 @@ signals:
|
||||
void scriptError(int line, QString message);
|
||||
void scriptSetTitle(QString title);
|
||||
void scriptSetInfoLine(int line, QString info);
|
||||
void scriptMessage(QString message);
|
||||
|
||||
public slots:
|
||||
|
||||
|
BIN
x64_dbg_gui/Project/images/information.png
Normal file
BIN
x64_dbg_gui/Project/images/information.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
@ -23,5 +23,6 @@
|
||||
<file>images/compile.png</file>
|
||||
<file>images/script-code.png</file>
|
||||
<file>images/script-error.png</file>
|
||||
<file>images/information.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
Reference in New Issue
Block a user