1
0
Fork 0

PROJECT: updated todo list

DBG: added 'asm' command (there are bugs with original breakpoint bytes with this->MemWrite in TitanEngine)
DBG: fixed a bug inside bpenumall
DBG: added memwrite function
This commit is contained in:
mr.exodia 2013-12-07 20:25:58 +01:00
parent 31eb12b8a0
commit 06d86c3c20
16 changed files with 327 additions and 6 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@ x64_dbg_*/x64/*
!bin/*/sqlite.dll
!bin/*/BeaEngine.dll
!bin/*/Scylla.dll
!bin/*/nasm.exe
#files to ignore
todo_bridge.txt

BIN
bin/x32/nasm.exe Normal file

Binary file not shown.

BIN
bin/x64/nasm.exe Normal file

Binary file not shown.

View File

@ -75,4 +75,4 @@
- function lines (+database) for analysis
- 'dead' bytes custom analysis
- loops lines (+database) for analysis
- signal for GUI in bridge (msgsend)
- enable/disable hw+mem breakpoint

192
x64_dbg_dbg/assemble.cpp Normal file
View File

@ -0,0 +1,192 @@
#include "assemble.h"
char nasmpath[deflen]="";
static bool issegment(const char* str)
{
if(!strncasecmp(str, "gs", 2))
return true;
if(!strncasecmp(str, "fs", 2))
return true;
if(!strncasecmp(str, "es", 2))
return true;
if(!strncasecmp(str, "ds", 2))
return true;
if(!strncasecmp(str, "cs", 2))
return true;
if(!strncasecmp(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(!strncasecmp(intel+i, "ptr", 3)) //remove "ptr"
{
i+=2;
if(intel[i+1]==' ')
i++;
continue;
}
else if(!strncasecmp(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);
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;
}

12
x64_dbg_dbg/assemble.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _ASSEMBLE_H
#define _ASSEMBLE_H
#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);
#endif // _ASSEMBLE_H

View File

@ -244,6 +244,10 @@ bool bpenumall(BPENUMCALLBACK cbEnum, const char* module)
curbp.type=(BP_TYPE)sqlite3_column_int(stmt, 4); //type
curbp.titantype=sqlite3_column_int(stmt, 5); //titantype
const char* modname=(const char*)sqlite3_column_text(stmt, 6); //mod
if(modname)
strcpy(curbp.mod, modname);
else
*curbp.mod=0;
const char* bpname=(const char*)sqlite3_column_text(stmt, 7); //name
if(bpname)
strcpy(curbp.name, bpname);

View File

@ -825,7 +825,6 @@ static bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
{
puts("cbDebugEnableBPX");
char arg1[deflen]="";
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
{

View File

@ -5,6 +5,9 @@
#include "value.h"
#include "command.h"
#include "addrinfo.h"
#include "assemble.h"
#include "debugger.h"
#include "memory.h"
CMDRESULT cbBadCmd(int argc, char* argv[])
{
@ -338,7 +341,7 @@ CMDRESULT cbLoaddb(int argc, char* argv[])
{
if(!dbload())
{
puts("failed to load database from disk!");
dputs("failed to load database from disk!");
return STATUS_ERROR;
}
GuiUpdateAllViews();
@ -349,8 +352,68 @@ CMDRESULT cbSavedb(int argc, char* argv[])
{
if(!dbsave())
{
puts("failed to save database to disk!");
dputs("failed to save database to disk!");
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
CMDRESULT cbAssemble(int argc, char* argv[])
{
if(argc<3)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
uint addr=0;
if(!valfromstring(argv[1], &addr, 0, 0, true, 0))
{
dprintf("invalid expression: \"%s\"!\n", argv[1]);
return STATUS_ERROR;
}
if(!DbgMemIsValidReadPtr(addr))
{
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)
{
dprintf("assemble error: %s\n", error);
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;
}

View File

@ -19,5 +19,6 @@ CMDRESULT cbInstrBookmarkSet(int argc, char* argv[]);
CMDRESULT cbInstrBookmarkDel(int argc, char* argv[]);
CMDRESULT cbLoaddb(int argc, char* argv[]);
CMDRESULT cbSavedb(int argc, char* argv[]);
CMDRESULT cbAssemble(int argc, char* argv[]);
#endif // _INSTRUCTIONS_H

View File

@ -28,7 +28,6 @@ bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T
{
if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize) //generic failures
return false;
SIZE_T read=0;
DWORD oldprotect=0;
bool ret=ReadProcessMemory(hProcess, (void*)lpBaseAddress, lpBuffer, nSize, &read); //try 'normal' RPM
@ -44,7 +43,6 @@ bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T
*lpNumberOfBytesRead=read;
return true;
}
for(uint i=0; i<nSize; i++) //read byte-per-byte
{
unsigned char* curaddr=(unsigned char*)lpBaseAddress+i;
@ -62,6 +60,42 @@ bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T
return true;
}
bool memwrite(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten)
{
if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize) //generic failures
return false;
SIZE_T written=0;
DWORD oldprotect=0;
bool ret=WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, &written);
if(!ret or written!=nSize) //failed
{
VirtualProtectEx(hProcess, (void*)lpBaseAddress, nSize, PAGE_EXECUTE_READWRITE, &oldprotect); //change page protection
ret=WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, &written); //try 'normal' WPM again
VirtualProtectEx(hProcess, (void*)lpBaseAddress, nSize, oldprotect, &oldprotect); //restore page protection
}
if(ret and written==nSize) //'normal' WPM worked!
{
if(lpNumberOfBytesWritten)
*lpNumberOfBytesWritten=written;
return true;
}
for(uint i=0; i<nSize; i++) //read byte-per-byte
{
unsigned char* curaddr=(unsigned char*)lpBaseAddress+i;
unsigned char* curbuf=(unsigned char*)lpBuffer+i;
ret=WriteProcessMemory(hProcess, curaddr, curbuf, 1, 0); //try 'normal' WPM
if(!ret) //we failed
{
VirtualProtectEx(hProcess, curaddr, 1, PAGE_EXECUTE_READWRITE, &oldprotect); //change page protection
ret=WriteProcessMemory(hProcess, curaddr, curbuf, PAGE_SIZE, 0); //try 'normal' WPM again
VirtualProtectEx(hProcess, curaddr, 1, oldprotect, &oldprotect); //restore page protection
if(!ret) //complete failure
return false;
}
}
return true;
}
bool memisvalidreadptr(HANDLE hProcess, uint addr)
{
unsigned char a=0;

View File

@ -7,6 +7,7 @@
uint memfindbaseaddr(HANDLE hProcess, uint addr, uint* size);
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
bool memwrite(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);
bool memisvalidreadptr(HANDLE hProcess, uint addr);
void* memalloc(HANDLE hProcess, uint addr, DWORD size, DWORD fdProtect);

View File

@ -13,6 +13,7 @@
#include "addrinfo.h"
#include "threading.h"
#include "plugin_loader.h"
#include "assemble.h"
static MESSAGE_STACK* gMsgStack=0;
static COMMAND* command_list=0;
@ -76,6 +77,7 @@ static void registercommands()
cmdnew(cmd, "loaddb\1dbload", cbLoaddb, true); //load program database
cmdnew(cmd, "DeleteHardwareBreakpoint\1bphc\1bphwc", cbDebugDeleteHardwareBreakpoint, true); //delete hardware breakpoint
cmdnew(cmd, "DeleteMemoryBPX\1membpc\1bpmc", cbDebugDeleteMemoryBreakpoint, true); //delete memory breakpoint
cmdnew(cmd, "asm", cbAssemble, true); //assemble instruction
}
static bool cbCommandProvider(char* cmd, int maxlen)
@ -126,6 +128,8 @@ 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;
}

View File

@ -73,6 +73,8 @@
<Unit filename="addrinfo.h" />
<Unit filename="argument.cpp" />
<Unit filename="argument.h" />
<Unit filename="assemble.cpp" />
<Unit filename="assemble.h" />
<Unit filename="breakpoint.cpp" />
<Unit filename="breakpoint.h" />
<Unit filename="command.cpp" />

View File

@ -13,6 +13,7 @@
<ItemGroup>
<ClCompile Include="addrinfo.cpp" />
<ClCompile Include="argument.cpp" />
<ClCompile Include="assemble.cpp" />
<ClCompile Include="breakpoint.cpp" />
<ClCompile Include="command.cpp" />
<ClCompile Include="console.cpp" />
@ -36,6 +37,7 @@
<ItemGroup>
<ClInclude Include="addrinfo.h" />
<ClInclude Include="argument.h" />
<ClInclude Include="assemble.h" />
<ClInclude Include="breakpoint.h" />
<ClInclude Include="command.h" />
<ClInclude Include="console.h" />

View File

@ -78,6 +78,9 @@
<ClCompile Include="_plugins.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="assemble.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="_exports.h">
@ -149,5 +152,8 @@
<ClInclude Include="_plugin_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="assemble.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>