DBG: added assembleat function
DBG: added XEDParse (does not support all instructions yet) BRIDGE: added function DbgAssembleAt GUI: added assemble window
This commit is contained in:
parent
a3ec27853c
commit
53111a169d
|
@ -532,6 +532,13 @@ BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* us
|
|||
_dbg_sendmessage(DBG_SYMBOL_ENUM, &cbInfo, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction)
|
||||
{
|
||||
if(_dbg_sendmessage(DBG_ASSEMBLE_AT, (void*)addr, (void*)instruction))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//GUI
|
||||
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
|
||||
{
|
||||
|
|
|
@ -111,7 +111,8 @@ enum DBGMSG
|
|||
DBG_SCRIPT_ABORT, // param1=unused, param2=unused
|
||||
DBG_SCRIPT_GETLINETYPE, // param1=int line, param2=unused
|
||||
DBG_SCRIPT_SETIP, // param1=int line, param2=unused
|
||||
DBG_SYMBOL_ENUM // param1=SYMBOLCBINFO* cbInfo, param2=unused
|
||||
DBG_SYMBOL_ENUM, // param1=SYMBOLCBINFO* cbInfo, param2=unused
|
||||
DBG_ASSEMBLE_AT // param1=duint addr, param2=const char* instruction
|
||||
};
|
||||
|
||||
enum SCRIPTLINETYPE
|
||||
|
@ -287,6 +288,7 @@ BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line);
|
|||
BRIDGE_IMPEXP void DbgScriptSetIp(int line);
|
||||
|
||||
BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user);
|
||||
BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction);
|
||||
|
||||
//Gui enums
|
||||
enum GUIMSG
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef _XEDPARSE_H
|
||||
#define _XEDPARSE_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
//XEDParse defines
|
||||
#ifdef XEDPARSE_BUILD
|
||||
#define XEDPARSE_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define XEDPARSE_EXPORT __declspec(dllimport)
|
||||
#endif //XEDPARSE_BUILD
|
||||
|
||||
#define XEDPARSE_CALL //calling convention
|
||||
|
||||
#define XEDPARSE_MAXBUFSIZE 256
|
||||
#define XEDPARSE_MAXASMSIZE 16
|
||||
|
||||
//typedefs
|
||||
typedef bool (XEDPARSE_CALL *CBXEDPARSE_UNKNOWN)(const char* text, ULONG_PTR* value);
|
||||
|
||||
//XEDParse enums
|
||||
enum XEDPARSE_STATUS
|
||||
{
|
||||
XEDPARSE_ERROR=0,
|
||||
XEDPARSE_OK=1
|
||||
};
|
||||
|
||||
//XEDParse structs
|
||||
#pragma pack(push,8)
|
||||
struct XEDPARSE
|
||||
{
|
||||
ULONG_PTR cip; //instruction pointer (for relative addressing)
|
||||
unsigned int dest_size; //destination size (returned by XEDParse)
|
||||
CBXEDPARSE_UNKNOWN cbUnknown; //unknown operand callback
|
||||
unsigned char dest[XEDPARSE_MAXASMSIZE]; //destination buffer
|
||||
char instr[XEDPARSE_MAXBUFSIZE]; //instruction text
|
||||
char error[XEDPARSE_MAXBUFSIZE]; //error text (in case of an error)
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
XEDPARSE_EXPORT XEDPARSE_STATUS XEDPARSE_CALL XEDParseAssemble(XEDPARSE* XEDParse);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _XEDPARSE_H
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -9,6 +9,7 @@
|
|||
#include "disasm_helper.h"
|
||||
#include "simplescript.h"
|
||||
#include "symbolinfo.h"
|
||||
#include "assemble.h"
|
||||
|
||||
extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size)
|
||||
{
|
||||
|
@ -563,6 +564,12 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
symbolenum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_ASSEMBLE_AT:
|
||||
{
|
||||
return assembleat((duint)param1, (const char*)param2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,193 +1,18 @@
|
|||
#include "assemble.h"
|
||||
#include "memory.h"
|
||||
#include "debugger.h"
|
||||
#include "XEDParse\XEDParse.h"
|
||||
|
||||
char nasmpath[deflen]="";
|
||||
|
||||
static bool issegment(const char* str)
|
||||
bool assembleat(uint addr, const char* instruction)
|
||||
{
|
||||
if(!_strnicmp(str, "gs", 2))
|
||||
return true;
|
||||
if(!_strnicmp(str, "fs", 2))
|
||||
return true;
|
||||
if(!_strnicmp(str, "es", 2))
|
||||
return true;
|
||||
if(!_strnicmp(str, "ds", 2))
|
||||
return true;
|
||||
if(!_strnicmp(str, "cs", 2))
|
||||
return true;
|
||||
if(!_strnicmp(str, "ss", 2))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void intel2nasm(const char* intel, char* nasm)
|
||||
{
|
||||
char temp[256]="";
|
||||
memset(temp, 0, sizeof(temp));
|
||||
int len=strlen(intel);
|
||||
for(int i=0,j=0; i<len; i++) //fix basic differences and problems
|
||||
{
|
||||
if(!_strnicmp(intel+i, "ptr", 3)) //remove "ptr"
|
||||
{
|
||||
i+=2;
|
||||
if(intel[i+1]==' ')
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if(!_strnicmp(intel+i, " ", 2)) //remove double spaces
|
||||
continue;
|
||||
else if(intel[i]=='\t') //tab=space
|
||||
{
|
||||
j+=sprintf(temp+j, " ");
|
||||
continue;
|
||||
}
|
||||
j+=sprintf(temp+j, "%c", intel[i]);
|
||||
}
|
||||
len=strlen(temp);
|
||||
for(int i=0,j=0; i<len; i++)
|
||||
{
|
||||
if(temp[i]==' ' and temp[i+1]==',')
|
||||
continue;
|
||||
else if(temp[i]==',' and temp[i+1]==' ')
|
||||
{
|
||||
j+=sprintf(nasm+j, ",");
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if(issegment(temp+i) and temp[i+2]==' ')
|
||||
{
|
||||
j+=sprintf(nasm+j, "%c%c", temp[i], temp[i+1]);
|
||||
i+=2;
|
||||
continue;
|
||||
}
|
||||
else if(temp[i]==':' and temp[i+1]==' ')
|
||||
{
|
||||
j+=sprintf(nasm+j, ":");
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
j+=sprintf(nasm+j, "%c", temp[i]);
|
||||
}
|
||||
len=strlen(nasm);
|
||||
for(int i=0,j=0; i<len; i++)
|
||||
{
|
||||
if(issegment(nasm+i) and nasm[i+2]==':' and nasm[i+3]=='[')
|
||||
{
|
||||
j+=sprintf(temp+j, "[%c%c:", nasm[i], nasm[i+1]);
|
||||
i+=3;
|
||||
continue;
|
||||
}
|
||||
j+=sprintf(temp+j, "%c", nasm[i]);
|
||||
}
|
||||
strcpy(nasm, temp);
|
||||
}
|
||||
|
||||
bool assemble(const char* instruction, unsigned char** outdata, int* outsize, char* error, bool x64)
|
||||
{
|
||||
if(!instruction or !outsize)
|
||||
return false;
|
||||
char tmppath[MAX_PATH]="";
|
||||
char tmpfile[MAX_PATH]="";
|
||||
char outfile[MAX_PATH]="";
|
||||
if(!GetTempPathA(MAX_PATH, tmppath) or !GetTempFileNameA(tmppath, "dbg", 0, tmpfile) or !GetTempFileNameA(tmppath, "dbg", 0, outfile))
|
||||
{
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return false;
|
||||
}
|
||||
char* asmfile=(char*)emalloc(strlen(instruction)+9);
|
||||
if(x64)
|
||||
strcpy(asmfile, "BITS 64d\n");
|
||||
else
|
||||
strcpy(asmfile, "BITS 32d\n");
|
||||
strcat(asmfile, instruction);
|
||||
HANDLE hFile=CreateFileA(tmpfile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if(hFile==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "Failed to create asmfile!");
|
||||
efree(asmfile);
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return false;
|
||||
}
|
||||
DWORD written=0;
|
||||
if(!WriteFile(hFile, asmfile, strlen(asmfile), &written, 0))
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "Failed to write asmfile!");
|
||||
efree(asmfile);
|
||||
CloseHandle(hFile);
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return false;
|
||||
}
|
||||
efree(asmfile);
|
||||
CloseHandle(hFile);
|
||||
char cmdline[MAX_PATH*4]="";
|
||||
sprintf(cmdline, "\"%s\" \"%s\" -o \"%s\"", nasmpath, tmpfile, outfile);
|
||||
STARTUPINFO si;
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.cb=sizeof(si);
|
||||
PROCESS_INFORMATION pi;
|
||||
if(!CreateProcessA(0, cmdline, 0, 0, false, CREATE_NO_WINDOW, 0, 0, &si, &pi))
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "Failed to start NASM!");
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return false;
|
||||
}
|
||||
DWORD exitCode=STILL_ACTIVE;
|
||||
do
|
||||
GetExitCodeProcess(pi.hProcess, &exitCode);
|
||||
while(exitCode==STILL_ACTIVE);
|
||||
CloseHandle(pi.hThread);
|
||||
if(exitCode) //nasm failed
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "NASM reported a failure!");
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return false;
|
||||
}
|
||||
hFile=CreateFileA(outfile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
if(hFile==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "Failed to open outfile!");
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return false;
|
||||
}
|
||||
int filesize=GetFileSize(hFile, 0);
|
||||
if(!filesize)
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "No result in outfile!");
|
||||
CloseHandle(hFile);
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return false;
|
||||
}
|
||||
*outsize=filesize;
|
||||
unsigned char* out=(unsigned char*)emalloc(filesize);
|
||||
DWORD read=0;
|
||||
if(!ReadFile(hFile, out, filesize, &read, 0))
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "Failed to read outfile!");
|
||||
efree(out);
|
||||
CloseHandle(hFile);
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return false;
|
||||
}
|
||||
if(outdata)
|
||||
*outdata=out;
|
||||
else
|
||||
efree(out);
|
||||
CloseHandle(hFile);
|
||||
DeleteFileA(outfile);
|
||||
DeleteFileA(tmpfile);
|
||||
return true;
|
||||
if(strlen(instruction)>=XEDPARSE_MAXBUFSIZE)
|
||||
return false;
|
||||
XEDPARSE parse;
|
||||
memset(&parse, 0, sizeof(parse));
|
||||
strcpy(parse.instr, instruction);
|
||||
if(XEDParseAssemble(&parse)==XEDPARSE_ERROR)
|
||||
return false;
|
||||
bool ret=memwrite(fdProcessInfo->hProcess, (void*)addr, parse.dest, parse.dest_size, 0);
|
||||
GuiUpdateAllViews();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
|
||||
#include "_global.h"
|
||||
|
||||
//superglobal variables
|
||||
extern char nasmpath[deflen];
|
||||
|
||||
bool assemble(const char* instruction, unsigned char** outdata, int* outsize, char* error, bool x64);
|
||||
void intel2nasm(const char* intel, char* nasm);
|
||||
bool assembleat(uint addr, const char* instruction);
|
||||
|
||||
#endif // _ASSEMBLE_H
|
||||
|
|
|
@ -375,45 +375,11 @@ CMDRESULT cbAssemble(int argc, char* argv[])
|
|||
dprintf("invalid address: "fhex"!\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
char instruction[256]="";
|
||||
intel2nasm(argv[2], instruction);
|
||||
unsigned char* outdata=0;
|
||||
int outsize=0;
|
||||
char error[1024]="";
|
||||
#ifdef _WIN64
|
||||
bool ret=assemble(instruction, &outdata, &outsize, error, true);
|
||||
#else
|
||||
bool ret=assemble(instruction, &outdata, &outsize, error, false);
|
||||
#endif // _WIN64
|
||||
if(!ret)
|
||||
if(!assembleat(addr, argv[2]))
|
||||
{
|
||||
dprintf("assemble error: %s\n", error);
|
||||
dprintf("failed to assemble \"%s\"\n", argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
bool fillnop=false;
|
||||
if(argc>=4) //fill with NOPs
|
||||
fillnop=true;
|
||||
|
||||
if(!fillnop)
|
||||
{
|
||||
if(!memwrite(fdProcessInfo->hProcess, (void*)addr, outdata, outsize, 0))
|
||||
{
|
||||
efree(outdata);
|
||||
dputs("failed to write memory!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
efree(outdata);
|
||||
dputs("not yet implemented!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
varset("$result", outsize, false);
|
||||
efree(outdata);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,8 +190,6 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
char plugindir[deflen]="";
|
||||
strcpy(plugindir, dir);
|
||||
PathAppendA(plugindir, "plugins");
|
||||
strcpy(nasmpath, dir);
|
||||
PathAppendA(nasmpath, "nasm.exe");
|
||||
pluginload(plugindir);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<Add library=".\dbghelp\dbghelp_x86.a" />
|
||||
<Add library=".\sqlite\libsqlite32.a" />
|
||||
<Add library=".\BeaEngine\libBeaEngine.a" />
|
||||
<Add library=".\XEDParse\XEDParse_x86.a" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="x64">
|
||||
|
@ -49,6 +50,7 @@
|
|||
<Add library=".\dbghelp\dbghelp_x64.a" />
|
||||
<Add library=".\sqlite\libsqlite64.a" />
|
||||
<Add library=".\BeaEngine\libBeaEngine_64.a" />
|
||||
<Add library=".\XEDParse\XEDParse_x64.a" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
|
@ -68,6 +70,7 @@
|
|||
<Unit filename="BeaEngine/export.h" />
|
||||
<Unit filename="BeaEngine/macros.h" />
|
||||
<Unit filename="TitanEngine/TitanEngine.h" />
|
||||
<Unit filename="XEDParse/XEDParse.h" />
|
||||
<Unit filename="_exports.cpp" />
|
||||
<Unit filename="_exports.h" />
|
||||
<Unit filename="_global.cpp" />
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>$(SolutionDir)bin\x32\x32_bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;sqlite\sqlite32.lib;BeaEngine\BeaEngine.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32_bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;sqlite\sqlite32.lib;BeaEngine\BeaEngine.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -125,7 +125,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>$(SolutionDir)bin\x64\x64_bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;sqlite\sqlite64.lib;BeaEngine\BeaEngine_64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64_bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;sqlite\sqlite64.lib;BeaEngine\BeaEngine_64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
@ -477,9 +477,12 @@ void CPUDisassembly::assembleAt()
|
|||
if(mLineEdit.exec()!=QDialog::Accepted)
|
||||
return;
|
||||
|
||||
QMessageBox msg(QMessageBox::Critical, "Error!", "Function not (yet) supported...");
|
||||
msg.setWindowIcon(QIcon(":/icons/images/compile-error.png"));
|
||||
msg.setParent(this, Qt::Dialog);
|
||||
msg.setWindowFlags(msg.windowFlags()&(~Qt::WindowContextHelpButtonHint));
|
||||
msg.exec();
|
||||
if(!DbgAssembleAt(wVA, mLineEdit.editText.toUtf8().constData()))
|
||||
{
|
||||
QMessageBox msg(QMessageBox::Critical, "Error!", "Failed to assemble instruction \"" + mLineEdit.editText + QString("\""));
|
||||
msg.setWindowIcon(QIcon(":/icons/images/compile-error.png"));
|
||||
msg.setParent(this, Qt::Dialog);
|
||||
msg.setWindowFlags(msg.windowFlags()&(~Qt::WindowContextHelpButtonHint));
|
||||
msg.exec();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue