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:
parent
31eb12b8a0
commit
06d86c3c20
|
@ -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
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue