From 1a8fcdcd65978d2ecebe34fd90609273a00a62e2 Mon Sep 17 00:00:00 2001 From: "mr.exodia" Date: Sun, 22 Dec 2013 20:44:21 +0100 Subject: [PATCH] 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 --- help/Calculations.htm | 10 +-- help/Commands.htm | 6 +- help/Input.htm | 37 +++++++++-- help/Introduction.htm | 23 ++++--- help/x64_dbg.wcp | 2 +- todo_dbg.txt | 9 +-- x64_dbg_dbg/_exports.cpp | 8 ++- x64_dbg_dbg/debugger.cpp | 38 +++++++++++- x64_dbg_dbg/disasm_helper.cpp | 55 ++++++++++------ x64_dbg_dbg/math.cpp | 12 ++-- x64_dbg_dbg/math.h | 4 +- x64_dbg_dbg/value.cpp | 62 ++++++++++++++++--- x64_dbg_gui/Project/Src/BasicView/InfoBox.cpp | 6 +- 13 files changed, 196 insertions(+), 76 deletions(-) diff --git a/help/Calculations.htm b/help/Calculations.htm index 5e5e4973..383bd7bd 100644 --- a/help/Calculations.htm +++ b/help/Calculations.htm @@ -26,12 +26,12 @@ resolved first, there is no need for a terminating bracket, unless you want to use one.

2:not: '~' The not operator can be used before a number of a variable, like in C.

-

3:addition/substraction -: '+' and '-'

-

4:muliplication/devision: '*' -= regular multiplication (signed/unsigned), '#' = get the higher part of the +

3:muliplication/devision: '*' = 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.

+

4:addition/substraction +: '+' and '-'

5:shift: '<' = shift left (shl for unsigned, sal for signed), '>' = shift right (shr for unsigned, sar for signed).

6:and: '&' Just the regular AND operation like @@ -47,4 +47,4 @@ syntax:

can be any register, flag, variable or memory location. 'b' can be anything that is recognized as a mathmatical input.

a++/a--: 'a' can be any register, flag, variable or memory -location.

\ No newline at end of file +location.

\ No newline at end of file diff --git a/help/Commands.htm b/help/Commands.htm index 5f0b1b80..e370f4b8 100644 --- a/help/Commands.htm +++ b/help/Commands.htm @@ -30,6 +30,6 @@ given).

class=rvts9>Description of the command result.

REMARK: Commands cannot contain any of the following characters: "," (comma), -" " (space) and "\" (backslash). These characters need to be -prefixed.

\ No newline at end of file +class=rvts9>: Commands cannot contain any of the following characters: "," (comma), " " (space) and +"\" (backslash). These characters need to be prefixed using a backslash +('\,').

\ No newline at end of file diff --git a/help/Input.htm b/help/Input.htm index 57321b79..b05850e3 100644 --- a/help/Input.htm +++ b/help/Input.htm @@ -30,12 +30,32 @@ class=rvts9>: All debug registers (all sizes) can be used as variables.

memory locations: You can read from a memory location by using one of the -following expressions:
@addr
- @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:
[addr]    - read a +DWORD/QWORD, depending on the architecture.
+ + + + +
@addr     - same as +above.
n:[addr]  - read n + + + + + bytes.

+ @n:addr   - same as +above.
REMARKS:
- 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 as a value, when you want to read [addr+1] you should use -brackets: @(addr+1), @addr+1 will read: [addr]+1.

+brackets:
+ + + + + @(addr+1), @addr+1 will read: [addr]+1.

@@ -59,9 +79,14 @@ automatically be resolved to the actual address of the function.

+

labels/symbols + : user-defined labels + + and symbols are a valid +expressions.

Input for arguments can always be done in any of the above forms, except if stated -otherwise.

\ No newline at end of file +otherwise.

\ No newline at end of file diff --git a/help/Introduction.htm b/help/Introduction.htm index b9a65693..51934485 100644 --- a/help/Introduction.htm +++ b/help/Introduction.htm @@ -15,20 +15,19 @@ html,body { -

Introduction
This is a x64/x32 debugger that is currently +

Introduction
This is a x64/x32 debugger that is currently in active development.

The debugger has (currently) three parts:
- DBG
- -GUI
+GUI
- Bridge

-

DBG is the debugging part of the debugger. It -handles debugging (using
TitanEngine) and will provide data +

DBG is the debugging part of the debugger. It handles +debugging (using
TitanEngine) and will provide data for the GUI.

-

GUI is the graphical part of the debugger. It -is built on top of Qt and it
provides the user interaction, the dump window -(not yet implemented), the
disassembly, the register window, the memory map -view, the +

GUI is the graphical part of the debugger. It is built +on top of Qt and it
provides the user interaction, the dump window (not yet +implemented), the
disassembly, the register window, the memory map view, the log view etc.

-

Bridge is the communication library for the DBG -and GUI part (and maybe in
the future more parts). The bridge can be used to -work on new features,
without having to update the code of -the other parts.

+

Bridge is the communication library for the DBG and GUI +part (and maybe in
the future more parts). The bridge can be used to work on +new features,
without having to update the code of +the other parts.

\ No newline at end of file diff --git a/help/x64_dbg.wcp b/help/x64_dbg.wcp index f3ae81dc..b9a99ec1 100644 --- a/help/x64_dbg.wcp +++ b/help/x64_dbg.wcp @@ -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 diff --git a/todo_dbg.txt b/todo_dbg.txt index 092c167f..1b438d9a 100644 --- a/todo_dbg.txt +++ b/todo_dbg.txt @@ -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 \ No newline at end of file diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index 6bb4f6a9..5cde6282 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -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; } } diff --git a/x64_dbg_dbg/debugger.cpp b/x64_dbg_dbg/debugger.cpp index d18fdd85..6c7a40ae 100644 --- a/x64_dbg_dbg/debugger.cpp +++ b/x64_dbg_dbg/debugger.cpp @@ -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; diff --git a/x64_dbg_dbg/disasm_helper.cpp b/x64_dbg_dbg/disasm_helper.cpp index 4e415ead..e65ee694 100644 --- a/x64_dbg_dbg/disasm_helper.cpp +++ b/x64_dbg_dbg/disasm_helper.cpp @@ -1,6 +1,8 @@ #include "disasm_helper.h" #include "BeaEngine\BeaEngine.h" #include "value.h" +#include +#include 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'~') + 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; itotal_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"); diff --git a/x64_dbg_dbg/math.h b/x64_dbg_dbg/math.h index 65f7fac3..8ca255c1 100644 --- a/x64_dbg_dbg/math.h +++ b/x64_dbg_dbg/math.h @@ -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); diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index ca6150c0..bffa209c 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -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; i2) 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; ihProcess, (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); diff --git a/x64_dbg_gui/Project/Src/BasicView/InfoBox.cpp b/x64_dbg_gui/Project/Src/BasicView/InfoBox.cpp index bd2b6127..b3df6354 100644 --- a/x64_dbg_gui/Project/Src/BasicView/InfoBox.cpp +++ b/x64_dbg_gui/Project/Src/BasicView/InfoBox.cpp @@ -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);