1
0
Fork 0

DBG: fixed a bug in addrinfoget (live comments)

DBG: check if process architecture matches the current debugger architecture
DBG: fixed a bug with non-silent valfromstring (last fix regarding silent stuff)
DBG: added memory operation brackets: '[', ']' and 'n:[' (see help)
GUI: removed useless info lines
PROJECT: updated help
This commit is contained in:
mr.exodia 2013-12-22 20:44:21 +01:00
parent d1b3f36cac
commit 1a8fcdcd65
13 changed files with 196 additions and 76 deletions

View File

@ -26,12 +26,12 @@ resolved first, there is no need for a terminating bracket, unless you want to
use one.</P>
<P><U>2:not</U>: '~' The not operator can be used before a
number of a variable, like in C.</P>
<P><U>3:addition/substraction</U>
: '+' and '-'</P>
<P><U>4:muliplication/devision</U>: '*'
= regular multiplication (signed/unsigned), '#' = get the higher part of the
<P><U>3:muliplication/devision</U>: '*' = regular
multiplication (signed/unsigned), '#' = get the higher part of the
multiplication, '/' = regular devision (signed/unsigned, devide by zero=error)
and '%' = get the modulo (remainder) of the devision.</P>
<P><U>4:addition/substraction</U>
: '+' and '-'</P>
<P><U>5:shift</U>: '&lt;' = shift left (shl for unsigned,
sal for signed), '&gt;' = shift right (shr for unsigned, sar for signed).</P>
<P><U>6:and</U>: '&amp;' Just the regular AND operation like
@ -47,4 +47,4 @@ syntax:</P>
can be any register, flag, variable or memory location. 'b' can be anything that is recognized as a mathmatical
input.</P>
<P><U>a++/a--</U>: 'a' can be any register, flag, variable or memory
location.</P></body>
location.</P></head>

View File

@ -30,6 +30,6 @@ given).</SPAN><SPAN class=rvts9><BR></P></SPAN>
class=rvts9>Description of the command result.</SPAN><SPAN
class=rvts9><BR></SPAN></P>
<P class=rvps3><SPAN class=rvts12><U><STRONG>REMARK</STRONG></U></SPAN><SPAN
class=rvts9>: Commands cannot contain any of the following characters: "," (comma),
" " (space) and "\" (backslash). These characters need to be
prefixed.</SPAN></P></BODY></HTML>
class=rvts9>: Commands cannot contain any of the following characters: "," (comma), " " (space) and
"\" (backslash). These characters need to be prefixed using a backslash
('\,').</SPAN></P></body></HTML>

View File

@ -30,12 +30,32 @@ class=rvts9>: All debug registers (all sizes) can be used as
variables.</SPAN><SPAN class=rvts9><BR></SPAN></P>
<P class=rvps3><SPAN class=rvts11><U>memory locations</U></SPAN><SPAN
class=rvts9>: You can read from a memory location by using one of the
following expressions:<BR>@addr<BR>
@n:addr (where n is the amount of bytes to read,
this can be anything smaller then 4 on x32 and smaller then
8 on x64, when specified otherwise, there will be an error). addr is directly interpreted
following expressions:<BR>[addr]&nbsp;&nbsp;&nbsp; - read a
DWORD/QWORD, depending on the architecture.<BR>
</SPAN><SPAN
class=rvts9>@addr&nbsp;&nbsp;&nbsp;&nbsp; - same as
above.<BR><EM>n</EM>:[addr]&nbsp;&nbsp;- read <EM>n</EM>
bytes.</SPAN><SPAN
class=rvts9><BR>
@<EM>n</EM>:addr&nbsp;&nbsp; - same as
above.<BR><STRONG>REMARKS</STRONG>:<BR>- <EM>n</EM> is the amount of bytes to
read, this can be anything smaller then 4 on x32 and smaller then 8 on x64 when
specified, otherwise there will be an error.<BR>- addr is directly interpreted
as a value, when you want to read [addr+1] you should use
brackets: @(addr+1), @addr+1 will read: [addr]+1.</SPAN></P>
brackets:<BR>
@(addr+1), @addr+1 will read: [addr]+1.</SPAN></P>
<P class=rvps3><SPAN
class=rvts9>
@ -59,9 +79,14 @@ automatically be resolved to the
actual address of the
function.</SPAN></P>
<P class=rvps3><SPAN class=rvts9><U>labels/symbols</U>
: user-defined labels
and symbols&nbsp;are a valid
expressions.</SPAN></P>
<P class=rvps3><SPAN class=rvts9>
Input
for arguments can always be done in any of the above forms, except if stated
otherwise.</SPAN></P></body>
otherwise.</SPAN></P></BODY></HTML>

View File

@ -15,20 +15,19 @@ html,body {
</head>
<body>
<P><STRONG>Introduction<BR></STRONG>This is a x64/x32 debugger that is currently
<P><STRONG>Introduction</STRONG><BR>This is a x64/x32 debugger that is currently
in active development.</P>
<P>The debugger has (currently) three parts:<BR>- DBG<BR>-
GUI<BR>
GUI<BR>
- Bridge</P>
<P><EM>DBG</EM> is the debugging part of the debugger. It
handles debugging (using<BR>TitanEngine) and will provide data
<P>DBG is the debugging part of the debugger. It handles
debugging (using<BR> TitanEngine) and will provide data
for the GUI.</P>
<P><EM>GUI</EM> is the graphical part of the debugger. It
is built on top of Qt and it<BR>provides the user interaction, the dump window
(not yet implemented), the<BR>disassembly, the register window, the memory map
view, the
<P>GUI is the graphical part of the debugger. It is built
on top of Qt and it<BR>provides the user interaction, the dump window (not yet
implemented), the<BR>disassembly, the register window, the memory map view, the
log view etc.</P>
<P><EM>Bridge</EM> is the communication library for the DBG
and GUI part (and maybe in<BR>the future more parts). The bridge can be used to
work on new features,<BR>without having to update the code of
the other parts.</P></body>
<P>Bridge is the communication library for the DBG and GUI
part (and maybe in<BR>the future more parts). The bridge can be used to work on
new features,<BR> without having to update the code of
the other parts.</P></body>

View File

@ -105,7 +105,7 @@ TitleList.Status.0=0
TitleList.Keywords.0=
TitleList.ContextNumber.0=1000
TitleList.ApplyTemp.0=0
TitleList.Expanded.0=0
TitleList.Expanded.0=1
TitleList.Kind.0=0
TitleList.Title.1=Input
TitleList.Level.1=1

View File

@ -27,7 +27,6 @@
- analysis
- getlasterror
- display open handles
- build howto
- step to user code
- tracing(?)
- [OPTIONAL] child processes (TitanEngine)
@ -46,7 +45,7 @@
- functions
- TEB/TBI
- PEB/PBI
- cpu filename+thread id
- cpu thread id
- shift+f7f8f9
- log breakpoints
- fix memory breakpoints
@ -65,14 +64,12 @@
- tabbed GUI (workspace+dragable windows)
- LUA/Python support
- ep break options
- live comments
- [] brackets for memory operations
- custom colours
- show export table
- find all intermodular calls
- highlight register changes (only when CIP changed also)
- PAGE UP + PAGE DOWN keys in disasm
- function lines (+database) for analysis
- function lines database for analysis
- 'dead' bytes custom analysis
- loops lines (+database) for analysis
- loops lines database for analysis
- enable/disable hw+mem breakpoint

View File

@ -167,7 +167,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
sprintf(temp_string, "%s:\"%s\"", instr.arg[i].mnemonic, ascii);
break;
case str_unicode:
sprintf(temp_string, "%s:L\"UNICODE!\"", instr.arg[i].mnemonic);
sprintf(temp_string, "%s:L\"UNICODE\"");
break;
}
}
@ -175,8 +175,10 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
{
sprintf(temp_string, "[%s]:%s", instr.arg[i].mnemonic, newinfo.label);
}
else if(instr.arg[i].value and ((instr.type==instr_normal and disasmgetstringat(instr.arg[i].value, &strtype, ascii, unicode)) or _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo)))
else if(instr.arg[i].value and (disasmgetstringat(instr.arg[i].value, &strtype, ascii, unicode) or _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo)))
{
if(instr.type==instr_branch)
strtype=str_none;
switch(strtype)
{
case str_none:
@ -186,7 +188,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
sprintf(temp_string, "%s:\"%s\"", instr.arg[i].mnemonic, ascii);
break;
case str_unicode:
sprintf(temp_string, "%s:L\"UNICODE!\"", instr.arg[i].mnemonic);
sprintf(temp_string, "%s:L\"UNICODE\"");
break;
}
}

View File

@ -542,20 +542,37 @@ static DWORD WINAPI threadDebugLoop(void* lpParameter)
INIT_STRUCT* init=(INIT_STRUCT*)lpParameter;
bFileIsDll=IsFileDLL(init->exe, 0);
pDebuggedEntry=GetPE32Data(init->exe, 0, UE_OEP);
strcpy(szFileName, init->exe);
if(bFileIsDll)
fdProcessInfo=(PROCESS_INFORMATION*)InitDLLDebug(init->exe, false, init->commandline, init->currentfolder, 0);
else
fdProcessInfo=(PROCESS_INFORMATION*)InitDebug(init->exe, init->commandline, init->currentfolder);
efree(init, "threadDebugLoop:init"); //free init struct
if(!fdProcessInfo)
{
fdProcessInfo=&g_pi;
dputs("error starting process (invalid pe?)!");
return 0;
}
BOOL wow64=false, mewow64=false;
if(!IsWow64Process(fdProcessInfo->hProcess, &wow64) or !IsWow64Process(GetCurrentProcess(), &mewow64))
{
dputs("IsWow64Process failed!");
StopDebug();
return 0;
}
if((mewow64 and !wow64) or (!mewow64 and wow64))
{
#ifdef _WIN64
dputs("Use x32_dbg to debug this process!");
return 0;
#else
dputs("Use x64_dbg to debug this process!");
#endif // _WIN64
return 0;
}
lock(WAITID_STOP);
strcpy(szFileName, init->exe);
BridgeSettingSet("Recent Files", "path", szFileName);
efree(init, "threadDebugLoop:init"); //free init struct
varset("$hp", (uint)fdProcessInfo->hProcess, true);
varset("$pid", fdProcessInfo->dwProcessId, true);
ecount=0;
@ -1534,6 +1551,23 @@ CMDRESULT cbDebugAttach(int argc, char* argv[])
CloseHandle(hProcess);
return STATUS_ERROR;
}
BOOL wow64=false, mewow64=false;
if(!IsWow64Process(hProcess, &wow64) or !IsWow64Process(GetCurrentProcess(), &mewow64))
{
dputs("IsWow64Process failed!");
CloseHandle(hProcess);
return STATUS_ERROR;
}
if((mewow64 and !wow64) or (!mewow64 and wow64))
{
#ifdef _WIN64
dputs("Use x32_dbg to debug this process!");
#else
dputs("Use x64_dbg to debug this process!");
#endif // _WIN64
CloseHandle(hProcess);
return STATUS_ERROR;
}
CloseHandle(hProcess);
CreateThread(0, 0, threadAttachLoop, (void*)pid, 0, 0);
return STATUS_CONTINUE;

View File

@ -1,6 +1,8 @@
#include "disasm_helper.h"
#include "BeaEngine\BeaEngine.h"
#include "value.h"
#include <cwctype>
#include <cwchar>
const char* disasmtext(uint addr)
{
@ -127,7 +129,7 @@ void disasmget(uint addr, DISASM_INSTR* instr)
}
if(disasm.Instruction.BranchType)
instr->type=instr_branch;
else if(strstr(disasm.CompleteInstr, "esp") or strstr(disasm.CompleteInstr, "ebp"))
else if(strstr(disasm.CompleteInstr, "sp") or strstr(disasm.CompleteInstr, "bp"))
instr->type=instr_stack;
else
instr->type=instr_normal;
@ -148,14 +150,13 @@ void disasmprint(uint addr)
printf(" %d:%d:%"fext"X:%"fext"X:%"fext"X\n", i, instr.arg[i].type, instr.arg[i].constant, instr.arg[i].value, instr.arg[i].memvalue);
}
//TODO: shitty function
static bool isasciistring(const unsigned char* data)
{
int len=strlen((const char*)data);
if(len<2)
return false;
for(int i=0; i<len; i++)
if(data[i]<' ' or data[i]>'~')
if(!isprint(data[i]) and !isspace(data[i]))
return false;
return true;
}
@ -165,29 +166,45 @@ bool disasmgetstringat(uint addr, STRING_TYPE* type, char* ascii, wchar_t* unico
if(type)
*type=str_none;
unsigned char data[512]="";
DbgMemRead(addr, data, 511);
memset(data, 0, 512);
DbgMemRead(addr, data, 510);
if(isasciistring(data))
{
if(type)
*type=str_ascii;
data[250]=0;
strcpy(ascii, (const char*)data);
return true;
}
else
{
return false;
//TODO: unicode stuff
int unitype=IS_TEXT_UNICODE_ASCII16;
if(IsTextUnicode(data, 511, &unitype))
int len=strlen((const char*)data);
for(int i=0,j=0; i<len; i++)
{
if(type)
*type=str_unicode;
data[500]=0;
data[501]=0;
lstrcmpW(unicode, (const wchar_t*)data);
return true;
switch(data[i])
{
case '\t':
j+=sprintf(ascii+j, "\\t");
break;
case '\f':
j+=sprintf(ascii+j, "\\f");
break;
case '\v':
j+=sprintf(ascii+j, "\\v");
break;
case '\n':
j+=sprintf(ascii+j, "\\n");
break;
case '\r':
j+=sprintf(ascii+j, "\\r");
break;
case '\\':
j+=sprintf(ascii+j, "\\\\");
break;
case '\"':
j+=sprintf(ascii+j, "\\\"");
break;
default:
j+=sprintf(ascii+j, "%c", data[i]);
break;
}
}
return true;
}
return false;
}

View File

@ -295,7 +295,7 @@ static void adjustpairs(EXPRESSION* exps, int cur_open, int cur_close, int cur_l
}
}
static bool printlayer(char* exp, EXPRESSION* exps, int layer)
static bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent)
{
for(int i=0; i<exps->total_pairs; i++)
{
@ -312,7 +312,7 @@ static bool printlayer(char* exp, EXPRESSION* exps, int layer)
strcpy(backup, exp+open+len+1);
uint value;
if(!mathfromstring(temp, &value, 0, 0))
if(!mathfromstring(temp, &value, 0, 0, silent))
return false;
adjustpairs(exps, open, close, len+1, sprintf(exp+open, "%X", value));
@ -325,7 +325,7 @@ static bool printlayer(char* exp, EXPRESSION* exps, int layer)
return true;
}
bool mathhandlebrackets(char* expression)
bool mathhandlebrackets(char* expression, bool silent)
{
EXPRESSION expstruct;
expstruct.expression=expression;
@ -345,7 +345,7 @@ bool mathhandlebrackets(char* expression)
deepest=expstruct.pairs[i].layer;
for(int i=deepest; i>0; i--)
if(!printlayer(expression, &expstruct, i))
if(!printlayer(expression, &expstruct, i, silent))
{
efree(expstruct.pairs, "mathhandlebrackets:expstruct.pairs");
return false;
@ -358,7 +358,7 @@ bool mathhandlebrackets(char* expression)
/*
- handle math
*/
bool mathfromstring(const char* string, uint* value, int* value_size, bool* isvar)
bool mathfromstring(const char* string, uint* value, int* value_size, bool* isvar, bool silent)
{
int highestop=0;
int highestop_pos=0;
@ -410,7 +410,7 @@ bool mathfromstring(const char* string, uint* value, int* value_size, bool* isva
}
}
uint left=0;
if(!valfromstring(strleft, &left, 0, 0, false, 0))
if(!valfromstring(strleft, &left, 0, 0, silent, 0))
{
efree(strleft, "mathfromstring:strleft");
efree(strright, "mathfromstring:strright");

View File

@ -6,8 +6,8 @@
int mathisoperator(char ch);
void mathformat(char* text);
bool mathcontains(const char* text);
bool mathhandlebrackets(char* expression);
bool mathfromstring(const char* string, uint* value, int* value_size, bool* isvar);
bool mathhandlebrackets(char* expression, bool silent);
bool mathfromstring(const char* string, uint* value, int* value_size, bool* isvar, bool silent);
bool mathdounsignedoperation(char op, uint left, uint right, uint* result);
bool mathdosignedoperation(char op, sint left, sint right, sint* result);

View File

@ -1104,21 +1104,42 @@ bool valfromstring(const char* string, uint* value, int* value_size, bool* isvar
else if(mathcontains(string)) //handle math
{
int len=strlen(string);
char* newstring=(char*)emalloc(len*2, "valfromstring:newstring");
if(strstr(string, "[")) //memory brackets: []
{
for(int i=0,j=0; i<len; i++)
{
if(string[i]==']')
j+=sprintf(newstring+j, ")");
else if(isdigit(string[i]) and string[i+1]==':' and string[i+2]=='[') //n:[
{
j+=sprintf(newstring+j, "@%c:(", string[i]);
i+=2;
}
else if(string[i]=='[')
j+=sprintf(newstring+j, "@(");
else
j+=sprintf(newstring+j, "%c", string[i]);
}
}
else
strcpy(newstring, string);
char* string_=(char*)emalloc(len+256, "valfromstring:string_");
strcpy(string_, string);
strcpy(string_, newstring);
efree(newstring, "valfromstring::newstring");
int add=0;
while(mathisoperator(string_[add])>2)
add++;
if(!mathhandlebrackets(string_+add))
if(!mathhandlebrackets(string_+add, silent))
{
efree(string_, "valfromstring:string_");
return false;
}
bool ret=mathfromstring(string_+add, value, value_size, isvar);
bool ret=mathfromstring(string_+add, value, value_size, isvar, silent);
efree(string_, "valfromstring:string_");
return ret;
}
else if(*string=='@') //memory location
else if(*string=='@' or strstr(string, "[")) //memory location
{
if(!IsFileBeingDebugged())
{
@ -1131,17 +1152,42 @@ bool valfromstring(const char* string, uint* value, int* value_size, bool* isvar
*isvar=true;
return true;
}
int len=strlen(string);
char* newstring=(char*)emalloc(len*2, "valfromstring:newstring");
if(strstr(string, "["))
{
for(int i=0,j=0; i<len; i++)
{
if(string[i]==']')
j+=sprintf(newstring+j, ")");
else if(isdigit(string[i]) and string[i+1]==':' and string[i+2]=='[') //n:[
{
j+=sprintf(newstring+j, "@%c:(", string[i]);
i+=2;
}
else if(string[i]=='[')
j+=sprintf(newstring+j, "@(");
else
j+=sprintf(newstring+j, "%c", string[i]);
}
}
else
strcpy(newstring, string);
int read_size=sizeof(uint);
int add=1;
if(string[2]==':' and isdigit((string[1]))) //@n: (number of bytes to read)
if(newstring[2]==':' and isdigit((newstring[1]))) //@n: (number of bytes to read)
{
add+=2;
int new_size=string[1]-0x30;
int new_size=newstring[1]-0x30;
if(new_size<read_size)
read_size=new_size;
}
if(!valfromstring(string+add, value, 0, 0, false, 0))
if(!valfromstring(newstring+add, value, 0, 0, silent, 0))
{
efree(newstring, "valfromstring::newstring");
return false;
}
efree(newstring, "valfromstring::newstring");
uint addr=*value;
*value=0;
if(!memread(fdProcessInfo->hProcess, (void*)addr, value, read_size, 0))
@ -1260,7 +1306,7 @@ bool valtostring(const char* string, uint* value, bool silent)
read_size=new_size;
}
uint temp;
if(!valfromstring(string+add, &temp, 0, 0, false, 0))
if(!valfromstring(string+add, &temp, 0, 0, silent, 0))
return false;
bool wpm=WriteProcessMemory(fdProcessInfo->hProcess, (void*)temp, value, read_size, 0);
bpfixmemory(temp, (unsigned char*)value, read_size);

View File

@ -6,9 +6,9 @@ InfoBox::InfoBox(StdTable *parent) : StdTable(parent)
setShowHeader(false);
addColumnAt(0, "", true);
setRowCount(3);
setCellContent(0, 0, "Info Line 1");
setCellContent(1, 0, "Info Line 2");
setCellContent(2, 0, "Info Line 3");
setCellContent(0, 0, "");
setCellContent(1, 0, "");
setCellContent(2, 0, "");
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
int height = getHeight();
setMaximumHeight(height);