1
0
Fork 0
Conflicts:
	x64_dbg_dbg/debugger.cpp
	x64_dbg_dbg/debugger_commands.cpp
	x64_dbg_dbg/symbolinfo.h
	x64_dbg_dbg/thread.h
This commit is contained in:
Nukem 2015-04-04 19:20:13 -04:00
commit c1115bb203
46 changed files with 946 additions and 538 deletions

View File

@ -1102,6 +1102,10 @@ BRIDGE_IMPEXP void GuiUpdateCallStack()
_gui_sendmessage(GUI_UPDATE_CALLSTACK, 0, 0);
}
BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line)
{
_gui_sendmessage(GUI_LOAD_SOURCE_FILE, (void*)path, (void*)line);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{

View File

@ -501,6 +501,12 @@ typedef struct
#endif
} REGISTERCONTEXT;
typedef struct
{
DWORD code;
const char* name;
} LASTERROR;
typedef struct
{
REGISTERCONTEXT regcontext;
@ -510,6 +516,7 @@ typedef struct
MXCSRFIELDS MxCsrFields;
X87STATUSWORDFIELDS x87StatusWordFields;
X87CONTROLWORDFIELDS x87ControlWordFields;
LASTERROR lastError;
} REGDUMP;
typedef struct
@ -749,7 +756,8 @@ typedef enum
GUI_UPDATE_CALLSTACK, // param1=unused, param2=unused
GUI_SYMBOL_REFRESH_CURRENT, // param1=unused, param2=unused
GUI_UPDATE_MEMORY_VIEW, // param1=unused, param2=unused
GUI_REF_INITIALIZE // param1=const char* name param2=unused
GUI_REF_INITIALIZE, // param1=const char* name, param2=unused
GUI_LOAD_SOURCE_FILE // param1=const char* path, param2=line
} GUIMSG;
//GUI structures
@ -826,6 +834,7 @@ BRIDGE_IMPEXP void GuiRepaintTableView();
BRIDGE_IMPEXP void GuiUpdatePatches();
BRIDGE_IMPEXP void GuiUpdateCallStack();
BRIDGE_IMPEXP void GuiUpdateMemoryView();
BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line);
#ifdef __cplusplus
}

View File

@ -27,6 +27,7 @@
#include "bookmark.h"
#include "function.h"
#include "loop.h"
#include "error.h"
static bool bOnlyCipAutoComments = false;
@ -496,6 +497,10 @@ extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump)
GetMxCsrFields(& (regdump->MxCsrFields), regdump->regcontext.MxCsr);
Getx87ControlWordFields(& (regdump->x87ControlWordFields), regdump->regcontext.x87fpu.ControlWord);
Getx87StatusWordFields(& (regdump->x87StatusWordFields), regdump->regcontext.x87fpu.StatusWord);
LASTERROR lastError;
lastError.code = ThreadGetLastError(ThreadGetId(hActiveThread));
lastError.name = ErrorCodeToName(lastError.code);
regdump->lastError = lastError;
return true;
}
@ -737,6 +742,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
bOnlyCipAutoComments = settingboolget("Disassembler", "OnlyCipAutoComments");
bListAllPages = settingboolget("Engine", "ListAllPages");
bUndecorateSymbolNames = settingboolget("Engine", "UndecorateSymbolNames");
bEnableSourceDebugging = settingboolget("Engine", "EnableSourceDebugging");
uint setting;
if(BridgeSettingGetUint("Engine", "BreakpointType", &setting))

View File

@ -1,296 +0,0 @@
/**
\file argument.cpp
\brief Implements the argument class.
*/
#include "argument.h"
#include "console.h"
/*
formatarg:
01) remove prepended spaces
02) get command (first space) and lowercase
03) get arguments
04) remove double quotes (from arguments)
05) temp. remove double backslash
06) remove prepended/appended non-escaped commas and spaces (from arguments)
a) prepended
b) appended
07) get quote count, ignore escaped (from arguments)
08) process quotes (from arguments):
a) zero quotes
b) restore double backslash
c) escape commas and spaces
09) temp. remove double backslash
10) remove unescaped double commas (from arguments)
11) remove unescaped spaces (from arguments)
12) restore double backslash
13) combine formatted arguments and command
*/
/**
\brief Formats a command string (see source code for more information).
\param [in,out] Command to format.
*/
void argformat(char* cmd)
{
if(strlen(cmd) >= deflen)
return;
char command_[deflen] = "";
char* command = command_;
strcpy_s(command, deflen, cmd);
while(*command == ' ')
command++;
int len = (int)strlen(command);
int start = 0;
for(int i = 0; i < len; i++)
if(command[i] == ' ')
{
command[i] = 0;
start = i + 1;
break;
}
if(!start)
start = len;
char arguments_[deflen] = "";
char* arguments = arguments_;
strcpy_s(arguments, deflen, command + start);
char temp[deflen] = "";
len = (int)strlen(arguments);
for(int i = 0, j = 0; i < len; i++)
{
if(arguments[i] == '"' and arguments[i + 1] == '"') //TODO: fix this
i += 2;
j += sprintf(temp + j, "%c", arguments[i]);
}
strcpy_s(arguments, deflen, temp);
len = (int)strlen(arguments);
for(int i = 0; i < len; i++)
if(arguments[i] == '\\' and arguments[i + 1] == '\\')
{
arguments[i] = 1;
arguments[i + 1] = 1;
}
while((*arguments == ',' or * arguments == ' ') and * (arguments - 1) != '\\')
arguments++;
len = (int)strlen(arguments);
while((arguments[len - 1] == ' ' or arguments[len - 1] == ',') and arguments[len - 2] != '\\')
len--;
arguments[len] = 0;
len = (int)strlen(arguments);
int quote_count = 0;
for(int i = 0; i < len; i++)
if(arguments[i] == '"')
quote_count++;
if(!(quote_count % 2))
{
for(int i = 0; i < len; i++)
if(arguments[i] == '"')
arguments[i] = 0;
for(int i = 0; i < len; i++)
if(arguments[i] == 1 and (i < len - 1 and arguments[i + 1] == 1))
{
arguments[i] = '\\';
arguments[i + 1] = '\\';
}
for(int i = 0, j = 0; i < len; i++)
{
if(!arguments[i])
{
i++;
int len2 = (int)strlen(arguments + i);
for(int k = 0; k < len2; k++)
{
if(arguments[i + k] == ',' or arguments[i + k] == ' ' or arguments[i + k] == '\\')
j += sprintf(temp + j, "\\%c", arguments[i + k]);
else
j += sprintf(temp + j, "%c", arguments[i + k]);
}
i += len2;
}
else
j += sprintf(temp + j, "%c", arguments[i]);
}
arguments = arguments_;
strcpy_s(arguments, deflen, temp);
}
len = (int)strlen(arguments);
for(int i = 0; i < len; i++)
if(arguments[i] == '\\' and arguments[i + 1] == '\\')
{
arguments[i] = 1;
arguments[i + 1] = 1;
}
len = (int)strlen(arguments);
for(int i = 0, j = 0; i < len; i++)
{
if(arguments[i] == ',' and arguments[i + 1] == ',')
i += 2;
j += sprintf(temp + j, "%c", arguments[i]);
}
strcpy_s(arguments, deflen, temp);
len = (int)strlen(arguments);
for(int i = 0, j = 0; i < len; i++)
{
while(arguments[i] == ' ' and arguments[i - 1] != '\\')
i++;
j += sprintf(temp + j, "%c", arguments[i]);
}
strcpy_s(arguments, deflen, temp);
len = (int)strlen(arguments);
for(int i = 0; i < len; i++)
if(arguments[i] == 1 and arguments[i + 1] == 1)
{
arguments[i] = '\\';
arguments[i + 1] = '\\';
}
if(strlen(arguments))
sprintf(cmd, "%s %s", command, arguments);
else
strcpy_s(cmd, deflen, command);
}
/*
1) remove double backslash
2) count unescaped commas
*/
/**
\brief Gets the argument count from a command formatted by argformat().
\param cmd The command to get the argument count from.
\return The argument count.
*/
int arggetcount(const char* cmd)
{
int len = (int)strlen(cmd);
if(!len or len >= deflen)
return -1;
int arg_count = 0;
int start = 0;
while(cmd[start] != ' ' and start < len)
start++;
if(start == len)
return arg_count;
arg_count = 1;
char temp_[deflen] = "";
char* temp = temp_ + 1;
strcpy_s(temp, deflen - 1, cmd);
for(int i = start; i < len; i++)
if(temp[i] == '\\' and (i < len - 1 and temp[i + 1] == '\\'))
{
temp[i] = 1;
temp[i + 1] = 1;
}
for(int i = start; i < len; i++)
{
if(temp[i] == ',' and temp[i - 1] != '\\')
arg_count++;
}
return arg_count;
}
/*
1) get arg count
2) remove double backslash
3) zero non-escaped commas
4) restore double backslash
5) handle escape characters
*/
/**
\brief Gets an argument from a command.
\param cmd The command to get the argument from.
\param [out] Buffer of size #deflen.
\param arg_num The zero-based argument number to retrieve.
\param optional true if the argument is optional. When false there will be error messages on the console. Used to skip writing error messages yourself.
\return true if the argument was found in the command.
*/
bool argget(const char* cmd, char* arg, int arg_num, bool optional)
{
if(strlen(cmd) >= deflen)
return false;
int argcount = arggetcount(cmd);
if((arg_num + 1) > argcount)
{
if(!optional)
dprintf("missing argument nr %d\n", arg_num + 1);
return false;
}
int start = 0;
while(cmd[start] != ' ') //ignore the command
start++;
while(cmd[start] == ' ') //ignore initial spaces
start++;
char temp_[deflen] = "";
char* temp = temp_ + 1;
strcpy_s(temp, deflen - 1, cmd + start);
int len = (int)strlen(temp);
for(int i = 0; i < len; i++)
if(temp[i] == '\\' and temp[i + 1] == '\\')
{
temp[i] = 1;
temp[i + 1] = 1;
}
for(int i = 0; i < len; i++)
{
if(temp[i] == ',' and temp[i - 1] != '\\')
temp[i] = 0;
}
for(int i = 0; i < len; i++)
if(temp[i] == 1 and temp[i + 1] == 1)
{
temp[i] = '\\';
temp[i + 1] = '\\';
}
char new_temp[deflen] = "";
int new_len = len;
for(int i = 0, j = 0; i < len; i++) //handle escape characters
{
if(temp[i] == '\\' and (temp[i + 1] == ',' or temp[i + 1] == ' ' or temp[i + 1] == '\\'))
{
new_len--;
j += sprintf(new_temp + j, "%c", temp[i + 1]);
i++;
}
else
j += sprintf(new_temp + j, "%c", temp[i]);
}
len = new_len;
memcpy(temp, new_temp, len + 1);
if(arg_num == 0) //first argument
{
strcpy_s(arg, deflen, temp);
return true;
}
for(int i = 0, j = 0; i < len; i++)
{
if(!temp[i])
j++;
if(j == arg_num)
{
strcpy_s(arg, deflen, temp + i + 1);
return true;
}
}
return false;
}

View File

@ -1,11 +0,0 @@
#ifndef _ARGUMENT_H
#define _ARGUMENT_H
#include "_global.h"
//functions
bool argget(const char* cmd, char* arg, int arg_num, bool optional);
int arggetcount(const char* cmd);
void argformat(char* cmd);
#endif

View File

@ -5,11 +5,11 @@
*/
#include "command.h"
#include "argument.h"
#include "value.h"
#include "console.h"
#include "debugger.h"
#include "math.h"
#include "commandparser.h"
/**
\brief Finds a ::COMMAND in a command list.
@ -205,7 +205,7 @@ CMDRESULT cmdloop(COMMAND* command_list, CBCOMMAND cbUnknownCommand, CBCOMMANDPR
break;
if(strlen(command))
{
argformat(command); //default formatting
strcpy_s(command, StringUtils::Trim(command).c_str());
COMMAND* cmd;
if(!cbCommandFinder) //'clean' command processing
cmd = cmdget(command_list, command);
@ -230,14 +230,15 @@ CMDRESULT cmdloop(COMMAND* command_list, CBCOMMAND cbUnknownCommand, CBCOMMANDPR
}
else
{
int argcount = arggetcount(command);
Command commandParsed(command);
int argcount = commandParsed.GetArgCount();
char** argv = (char**)emalloc((argcount + 1) * sizeof(char*), "cmdloop:argv");
argv[0] = command;
for(int i = 0; i < argcount; i++)
{
argv[i + 1] = (char*)emalloc(deflen, "cmdloop:argv[i+1]");
*argv[i + 1] = 0;
argget(command, argv[i + 1], i, true);
strcpy_s(argv[i + 1], deflen, commandParsed.GetArg(i).c_str());
}
CMDRESULT res = cmd->cbCommand(argcount + 1, argv);
for(int i = 0; i < argcount; i++)
@ -365,21 +366,21 @@ CMDRESULT cmddirectexec(COMMAND* cmd_list, const char* cmd)
if(!cmd or !strlen(cmd))
return STATUS_ERROR;
char command[deflen] = "";
strcpy(command, cmd);
argformat(command);
strcpy(command, StringUtils::Trim(cmd).c_str());
COMMAND* found = cmdfindmain(cmd_list, command);
if(!found or !found->cbCommand)
return STATUS_ERROR;
if(found->debugonly and !DbgIsDebugging())
return STATUS_ERROR;
int argcount = arggetcount(command);
Command cmdParsed(command);
int argcount = cmdParsed.GetArgCount();
char** argv = (char**)emalloc((argcount + 1) * sizeof(char*), "cmddirectexec:argv");
argv[0] = command;
for(int i = 0; i < argcount; i++)
{
argv[i + 1] = (char*)emalloc(deflen, "cmddirectexec:argv[i+1]");
*argv[i + 1] = 0;
argget(command, argv[i + 1], i, true);
strcpy_s(argv[i + 1], deflen, cmdParsed.GetArg(i).c_str());
}
CMDRESULT res = found->cbCommand(argcount + 1, argv);
for(int i = 0; i < argcount; i++)

View File

@ -0,0 +1,114 @@
#include "commandparser.h"
Command::Command(const String & command)
{
ParseState state = Default;
int len = command.length();
for(int i = 0; i < len; i++)
{
char ch = command[i];
switch(state)
{
case Default:
switch(ch)
{
case ' ':
if(!_tokens.size())
dataFinish();
break;
case ',':
dataFinish();
break;
case '\\':
state = Escaped;
break;
case '\"':
state = Text;
break;
default:
dataAppend(ch);
break;
}
break;
case Escaped:
switch(ch)
{
case ' ':
dataAppend(ch);
break;
case ',':
dataAppend(ch);
break;
case '\"':
dataAppend(ch);
break;
default:
dataAppend('\\');
dataAppend(ch);
break;
}
state = Default;
break;
case Text:
switch(ch)
{
case '\\':
state = TextEscaped;
break;
case '\"':
dataFinish();
state = Default;
break;
default:
dataAppend(ch);
break;
}
break;
case TextEscaped:
switch(ch)
{
case '\"':
dataAppend(ch);
break;
default:
dataAppend('\\');
dataAppend(ch);
break;
}
state = Text;
break;
}
}
if(state == Escaped || state == TextEscaped)
dataAppend('\\');
dataFinish();
}
const String Command::GetText()
{
return _tokens.size() ? _tokens[0] : String();
}
const int Command::GetArgCount()
{
return _tokens.size() ? _tokens.size() - 1 : 0;
}
const String Command::GetArg(int argnum)
{
return (int)_tokens.size() < argnum + 1 ? String() : _tokens[argnum + 1];
}
void Command::dataAppend(const char ch)
{
_data += ch;
}
void Command::dataFinish()
{
if(_data.length())
{
_tokens.push_back(_data);
_data = "";
}
}

View File

@ -0,0 +1,30 @@
#ifndef _COMMANDPARSER_H
#define _COMMANDPARSER_H
#include "_global.h"
class Command
{
public:
Command(const String & command);
const String GetText();
const String GetArg(const int argnum);
const int GetArgCount();
private:
String _data;
std::vector<String> _tokens;
enum ParseState
{
Default,
Escaped,
Text,
TextEscaped
};
void dataFinish();
void dataAppend(const char ch);
};
#endif // _COMMANDPARSER_H

View File

@ -42,6 +42,7 @@ char sqlitedb[deflen] = "";
PROCESS_INFORMATION* fdProcessInfo = &g_pi;
HANDLE hActiveThread;
bool bUndecorateSymbolNames = true;
bool bEnableSourceDebugging = true;
static DWORD WINAPI memMapThread(void* ptr)
{
@ -188,9 +189,18 @@ DWORD WINAPI updateCallStackThread(void* ptr)
void DebugUpdateGui(uint disasm_addr, bool stack)
{
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
if(MemIsValidReadPtr(disasm_addr))
GuiDisasmAt(disasm_addr, cip);
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
if (MemIsValidReadPtr(disasm_addr))
{
if (bEnableSourceDebugging)
{
char szSourceFile[MAX_STRING_SIZE] = "";
int line = 0;
if (SymGetSourceLine(cip, szSourceFile, &line))
GuiLoadSourceFile(szSourceFile, line);
}
GuiDisasmAt(disasm_addr, cip);
}
uint csp = GetContextDataEx(hActiveThread, UE_CSP);
if(stack)
GuiStackDumpAt(csp, csp);

View File

@ -131,5 +131,6 @@ extern HANDLE hActiveThread;
extern char szFileName[MAX_PATH];
extern char szSymbolCachePath[MAX_PATH];
extern bool bUndecorateSymbolNames;
extern bool bEnableSourceDebugging;
#endif // _DEBUGGER_H

View File

@ -11,7 +11,6 @@
#include "memory.h"
#include "threading.h"
#include "variable.h"
#include "argument.h"
#include "plugin_loader.h"
#include "simplescript.h"
#include "symbolinfo.h"
@ -35,8 +34,12 @@ CMDRESULT cbDebugInit(int argc, char* argv[])
DbgCmdExecDirect("stop");
static char arg1[deflen] = "";
if(!argget(*argv, arg1, 0, false))
if(argc < 2)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
strcpy_s(arg1, argv[1]);
char szResolvedPath[MAX_PATH] = "";
if(ResolveShortcut(GuiGetWindowHandle(), StringUtils::Utf8ToUtf16(arg1).c_str(), szResolvedPath, _countof(szResolvedPath)))
{
@ -76,13 +79,15 @@ CMDRESULT cbDebugInit(int argc, char* argv[])
}
static char arg2[deflen] = "";
argget(*argv, arg2, 1, true);
if(argc > 2)
strcpy_s(arg2, argv[2]);
char* commandline = 0;
if(strlen(arg2))
commandline = arg2;
char arg3[deflen] = "";
argget(*argv, arg3, 2, true);
if(argc > 3)
strcpy_s(arg3, argv[3]);
static char currentfolder[deflen] = "";
strcpy_s(currentfolder, arg1);
@ -140,25 +145,27 @@ CMDRESULT cbDebugErun(int argc, char* argv[])
CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[])
{
char argtype[deflen] = "";
DWORD type = 0;
if(!argget(*argv, argtype, 0, false))
if(argc < 2)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
DWORD type = 0;
const char* a = 0;
uint setting_type;
if(strstr(argtype, "long"))
if(strstr(argv[1], "long"))
{
setting_type = 1; //break_int3long
a = "TYPE_LONG_INT3";
type = UE_BREAKPOINT_LONG_INT3;
}
else if(strstr(argtype, "ud2"))
else if(strstr(argv[1], "ud2"))
{
setting_type = 2; //break_ud2
a = "TYPE_UD2";
type = UE_BREAKPOINT_UD2;
}
else if(strstr(argtype, "short"))
else if(strstr(argv[1], "short"))
{
setting_type = 0; //break_int3short
a = "TYPE_INT3";
@ -177,13 +184,20 @@ CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[])
CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]]
{
char argaddr[deflen] = "";
if(!argget(*argv, argaddr, 0, false))
if(argc < 2)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
char argaddr[deflen] = "";
strcpy_s(argaddr, argv[1]);
char argname[deflen] = "";
argget(*argv, argname, 1, true);
if(argc > 2)
strcpy_s(argname, argv[2]);
char argtype[deflen] = "";
bool has_arg2 = argget(*argv, argtype, 2, true);
bool has_arg2 = argc > 3;
if(has_arg2)
strcpy_s(argtype, argv[3]);
if(!has_arg2 and (scmp(argname, "ss") or scmp(argname, "long") or scmp(argname, "ud2")))
{
strcpy_s(argtype, argname);
@ -247,8 +261,7 @@ CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]]
CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
{
char arg1[deflen] = "";
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
if(argc < 2) //delete all breakpoints
{
if(!BpGetCount(BPNORMAL))
{
@ -262,7 +275,7 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
return STATUS_CONTINUE;
}
BREAKPOINT found;
if(BpGet(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name
{
if(!BpDelete(found.addr, BPNORMAL))
{
@ -278,9 +291,9 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
return STATUS_CONTINUE;
}
uint addr = 0;
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
if(!valfromstring(argv[1], &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
{
dprintf("No such breakpoint \"%s\"\n", arg1);
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(!BpDelete(found.addr, BPNORMAL))
@ -301,8 +314,7 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
{
char arg1[deflen] = "";
if(!argget(*argv, arg1, 0, true)) //enable all breakpoints
if(argc < 2) //enable all breakpoints
{
if(!BpGetCount(BPNORMAL))
{
@ -316,7 +328,7 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
return STATUS_CONTINUE;
}
BREAKPOINT found;
if(BpGet(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name
{
if(!BpEnable(found.addr, BPNORMAL, true) or !SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
{
@ -327,9 +339,9 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
return STATUS_CONTINUE;
}
uint addr = 0;
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
if(!valfromstring(argv[1], &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
{
dprintf("No such breakpoint \"%s\"\n", arg1);
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(found.enabled)
@ -350,8 +362,7 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
{
char arg1[deflen] = "";
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
if(argc < 2) //delete all breakpoints
{
if(!BpGetCount(BPNORMAL))
{
@ -365,7 +376,7 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
return STATUS_CONTINUE;
}
BREAKPOINT found;
if(BpGet(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name
{
if(!BpEnable(found.addr, BPNORMAL, false) or !DeleteBPX(found.addr))
{
@ -376,9 +387,9 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
return STATUS_CONTINUE;
}
uint addr = 0;
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
if(!valfromstring(argv[1], &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
{
dprintf("No such breakpoint \"%s\"\n", arg1);
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(!found.enabled)
@ -430,13 +441,10 @@ CMDRESULT cbDebugeStepOver(int argc, char* argv[])
CMDRESULT cbDebugSingleStep(int argc, char* argv[])
{
char arg1[deflen] = "";
uint stepcount = 1;
if(argget(*argv, arg1, 0, true))
{
if(!valfromstring(arg1, &stepcount))
if(argc > 1)
if(!valfromstring(argv[1], &stepcount))
stepcount = 1;
}
SingleStep((DWORD)stepcount, (void*)cbStep);
dbgsetstepping(true);
return cbDebugRun(argc, argv);
@ -459,10 +467,9 @@ CMDRESULT cbDebugHide(int argc, char* argv[])
CMDRESULT cbDebugDisasm(int argc, char* argv[])
{
char arg1[deflen] = "";
uint addr = GetContextDataEx(hActiveThread, UE_CIP);
if(argget(*argv, arg1, 0, true))
if(!valfromstring(arg1, &addr))
uint addr;
if(argc > 1)
if(!valfromstring(argv[1], &addr))
addr = GetContextDataEx(hActiveThread, UE_CIP);
if(!MemIsValidReadPtr(addr))
return STATUS_CONTINUE;
@ -472,24 +479,26 @@ CMDRESULT cbDebugDisasm(int argc, char* argv[])
CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[])
{
char arg1[deflen] = ""; //addr
if(!argget(*argv, arg1, 0, false))
if(argc < 2)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
uint addr;
if(!valfromstring(arg1, &addr))
if(!valfromstring(argv[1], &addr))
return STATUS_ERROR;
bool restore = false;
char arg2[deflen] = ""; //restore
char arg3[deflen] = ""; //type
argget(*argv, arg3, 2, true);
if(argget(*argv, arg2, 1, true))
char arg3[deflen] = "";
if(argc > 3)
strcpy_s(arg3, argv[3]);
if(argc > 2)
{
if(*arg2 == '1')
if(*argv[2] == '1')
restore = true;
else if(*arg2 == '0')
else if(*argv[2] == '0')
restore = false;
else
strcpy_s(arg3, arg2);
strcpy_s(arg3, argv[2]);
}
DWORD type = UE_MEMORY;
if(*arg3)
@ -533,7 +542,7 @@ CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[])
CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
{
char arg1[deflen] = "";
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
if(argc < 2) //delete all breakpoints
{
if(!BpGetCount(BPMEMORY))
{
@ -591,17 +600,18 @@ CMDRESULT cbDebugeRtr(int argc, char* argv[])
CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
{
char arg1[deflen] = ""; //addr
if(!argget(*argv, arg1, 0, false))
if(argc < 2)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
uint addr;
if(!valfromstring(arg1, &addr))
if(!valfromstring(argv[1], &addr))
return STATUS_ERROR;
DWORD type = UE_HARDWARE_EXECUTE;
char arg2[deflen] = ""; //type
if(argget(*argv, arg2, 1, true))
if(argc > 2)
{
switch(*arg2)
switch(*argv[2])
{
case 'r':
type = UE_HARDWARE_READWRITE;
@ -616,12 +626,11 @@ CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
break;
}
}
char arg3[deflen] = ""; //size
DWORD titsize = UE_HARDWARE_SIZE_1;
if(argget(*argv, arg3, 2, true))
if(argc > 3)
{
uint size;
if(!valfromstring(arg3, &size))
if(!valfromstring(argv[3], &size))
return STATUS_ERROR;
switch(size)
{
@ -683,8 +692,7 @@ CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
{
char arg1[deflen] = "";
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
if(argc < 2) //delete all breakpoints
{
if(!BpGetCount(BPHARDWARE))
{
@ -698,7 +706,7 @@ CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
return STATUS_CONTINUE;
}
BREAKPOINT found;
if(BpGet(0, BPHARDWARE, arg1, &found)) //found a breakpoint with name
if(BpGet(0, BPHARDWARE, argv[1], &found)) //found a breakpoint with name
{
if(!BpDelete(found.addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
{
@ -708,9 +716,9 @@ CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
return STATUS_CONTINUE;
}
uint addr = 0;
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid breakpoint
if(!valfromstring(argv[1], &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid breakpoint
{
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
dprintf("No such hardware breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(!BpDelete(found.addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
@ -725,10 +733,9 @@ CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
CMDRESULT cbDebugAlloc(int argc, char* argv[])
{
char arg1[deflen] = ""; //size
uint size = 0x1000;
if(argget(*argv, arg1, 0, true))
if(!valfromstring(arg1, &size, false))
if(argc > 1)
if(!valfromstring(argv[1], &size, false))
return STATUS_ERROR;
uint mem = (uint)MemAllocRemote(0, size, PAGE_EXECUTE_READWRITE);
if(!mem)
@ -748,11 +755,10 @@ CMDRESULT cbDebugFree(int argc, char* argv[])
{
uint lastalloc;
varget("$lastalloc", &lastalloc, 0, 0);
char arg1[deflen] = ""; //addr
uint addr = lastalloc;
if(argget(*argv, arg1, 0, true))
if(argc > 1)
{
if(!valfromstring(arg1, &addr, false))
if(!valfromstring(argv[1], &addr, false))
return STATUS_ERROR;
}
else if(!lastalloc)
@ -774,7 +780,6 @@ CMDRESULT cbDebugFree(int argc, char* argv[])
CMDRESULT cbDebugMemset(int argc, char* argv[])
{
char arg3[deflen] = ""; //size
uint addr;
uint value;
uint size;
@ -785,9 +790,9 @@ CMDRESULT cbDebugMemset(int argc, char* argv[])
}
if(!valfromstring(argv[1], &addr, false) or !valfromstring(argv[2], &value, false))
return STATUS_ERROR;
if(argget(*argv, arg3, 2, true))
if(argc > 3)
{
if(!valfromstring(arg3, &size, false))
if(!valfromstring(argv[3], &size, false))
return STATUS_ERROR;
}
else
@ -1207,14 +1212,13 @@ CMDRESULT cbDebugSetPriority(int argc, char* argv[])
CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
{
char arg1[deflen] = "";
DWORD drx = 0;
if(!GetUnusedHardwareBreakPointRegister(&drx))
{
dputs("You can only set 4 hardware breakpoints");
return STATUS_ERROR;
}
if(!argget(*argv, arg1, 0, true)) //enable all hardware breakpoints
if(argc < 2) //enable all hardware breakpoints
{
if(!BpGetCount(BPHARDWARE))
{
@ -1229,9 +1233,9 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
}
BREAKPOINT found;
uint addr = 0;
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
if(!valfromstring(argv[1], &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
{
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
dprintf("No such hardware breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(found.enabled)
@ -1254,8 +1258,7 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
{
char arg1[deflen] = "";
if(!argget(*argv, arg1, 0, true)) //delete all hardware breakpoints
if(argc < 2) //delete all hardware breakpoints
{
if(!BpGetCount(BPHARDWARE))
{
@ -1270,9 +1273,9 @@ CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
}
BREAKPOINT found;
uint addr = 0;
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
if(!valfromstring(argv[1], &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
{
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
dprintf("No such hardware breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(!found.enabled)
@ -1292,21 +1295,14 @@ CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
{
char arg1[deflen] = "";
DWORD drx = 0;
if(!GetUnusedHardwareBreakPointRegister(0))
{
dputs("You can only set 4 hardware breakpoints");
return STATUS_ERROR;
}
if(!argget(*argv, arg1, 0, true)) //enable all memory breakpoints
if(argc < 2) //enable all memory breakpoints
{
if(!BpGetCount(BPMEMORY))
{
dputs("No hardware breakpoints to enable!");
dputs("No memory breakpoints to enable!");
return STATUS_CONTINUE;
}
if(!BpEnumAll(cbEnableAllHardwareBreakpoints)) //at least one enable failed
if(!BpEnumAll(cbEnableAllMemoryBreakpoints)) //at least one enable failed
return STATUS_ERROR;
dputs("All memory breakpoints enabled!");
GuiUpdateAllViews();
@ -1314,14 +1310,14 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
}
BREAKPOINT found;
uint addr = 0;
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
if(!valfromstring(argv[1], &addr) or !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
{
dprintf("No such memory breakpoint \"%s\"\n", arg1);
dprintf("No such memory breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(found.enabled)
{
dputs("Hardware memory already enabled!");
dputs("Memory memory already enabled!");
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
@ -1339,8 +1335,7 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
{
char arg1[deflen] = "";
if(!argget(*argv, arg1, 0, true)) //delete all memory breakpoints
if(argc < 2) //delete all memory breakpoints
{
if(!BpGetCount(BPMEMORY))
{
@ -1355,9 +1350,9 @@ CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
}
BREAKPOINT found;
uint addr = 0;
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
if(!valfromstring(argv[1], &addr) or !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
{
dprintf("No such memory breakpoint \"%s\"\n", arg1);
dprintf("No such memory breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(!found.enabled)

View File

@ -5,7 +5,6 @@
*/
#include "instruction.h"
#include "argument.h"
#include "variable.h"
#include "console.h"
#include "value.h"
@ -25,6 +24,7 @@
#include "loop.h"
#include "patternfind.h"
#include "module.h"
#include "stringformat.h"
static bool bRefinit = false;
@ -91,8 +91,9 @@ CMDRESULT cbInstrVar(int argc, char* argv[])
dputs("not enough arguments!");
return STATUS_ERROR;
}
char arg2[deflen] = "";
argget(*argv, arg2, 1, true); //var value (optional)
char arg2[deflen] = ""; //var value (optional)
if(argc > 2)
strcpy_s(arg2, argv[2]);
uint value = 0;
int add = 0;
if(*argv[1] == '$')
@ -219,15 +220,16 @@ CMDRESULT cbInstrMov(int argc, char* argv[])
CMDRESULT cbInstrVarList(int argc, char* argv[])
{
char arg1[deflen] = "";
argget(*argv, arg1, 0, true);
int filter = 0;
if(!_stricmp(arg1, "USER"))
filter = VAR_USER;
else if(!_stricmp(arg1, "READONLY"))
filter = VAR_READONLY;
else if(!_stricmp(arg1, "SYSTEM"))
filter = VAR_SYSTEM;
if(argc > 1)
{
if(!_stricmp(argv[1], "USER"))
filter = VAR_USER;
else if(!_stricmp(argv[1], "READONLY"))
filter = VAR_READONLY;
else if(!_stricmp(argv[1], "SYSTEM"))
filter = VAR_SYSTEM;
}
size_t cbsize = 0;
if(!varenum(0, &cbsize))
@ -1777,3 +1779,19 @@ CMDRESULT cbInstrYaramod(int argc, char* argv[])
sprintf_s(newcmd, "yara \"%s\",%p,%p", argv[1], base, size);
return cmddirectexec(dbggetcommandlist(), newcmd);
}
CMDRESULT cbInstrLog(int argc, char* argv[])
{
//log "format {0} string",arg1, arg2, argN
if(argc == 1) //just log newline
{
dputs("");
return STATUS_CONTINUE;
}
FormatValueVector formatArgs;
for(int i = 2; i < argc; i++)
formatArgs.push_back(argv[i]);
String logString = stringformat(argv[1], formatArgs);
dputs(logString.c_str());
return STATUS_CONTINUE;
}

View File

@ -64,5 +64,6 @@ CMDRESULT cbInstrSleep(int argc, char* argv[]);
CMDRESULT cbInstrFindAsm(int argc, char* argv[]);
CMDRESULT cbInstrYara(int argc, char* argv[]);
CMDRESULT cbInstrYaramod(int argc, char* argv[]);
CMDRESULT cbInstrLog(int argc, char* argv[]);
#endif // _INSTRUCTIONS_H

View File

@ -7,11 +7,11 @@
#include "simplescript.h"
#include "value.h"
#include "console.h"
#include "argument.h"
#include "variable.h"
#include "threading.h"
#include "x64_dbg.h"
#include "debugger.h"
#include "commandparser.h"
static std::vector<LINEMAPENTRY> linemap;
@ -28,8 +28,7 @@ static bool volatile bIsRunning = false;
static SCRIPTBRANCHTYPE scriptgetbranchtype(const char* text)
{
char newtext[MAX_SCRIPT_LINE_SIZE] = "";
strcpy_s(newtext, text);
argformat(newtext); //format jump commands
strcpy_s(newtext, StringUtils::Trim(text).c_str());
if(!strstr(newtext, " "))
strcat(newtext, " ");
if(!strncmp(newtext, "jmp ", 4) or !strncmp(newtext, "goto ", 5))
@ -187,7 +186,7 @@ static bool scriptcreatelinemap(const char* filename)
{
cur.type = linelabel;
sprintf(cur.u.label, "l %.*s", rawlen - 1, cur.raw); //create a fake command for formatting
argformat(cur.u.label); //format labels
strcpy_s(cur.u.label, StringUtils::Trim(cur.u.label).c_str());
char temp[256] = "";
strcpy_s(temp, cur.u.label + 2);
strcpy_s(cur.u.label, temp); //remove fake command
@ -214,8 +213,7 @@ static bool scriptcreatelinemap(const char* filename)
cur.type = linebranch;
cur.u.branch.type = scriptgetbranchtype(cur.raw);
char newraw[MAX_SCRIPT_LINE_SIZE] = "";
strcpy_s(newraw, cur.raw);
argformat(newraw);
strcpy_s(newraw, StringUtils::Trim(cur.raw).c_str());
int len = (int)strlen(newraw);
for(int i = 0; i < len; i++)
if(newraw[i] == ' ')
@ -354,8 +352,7 @@ static CMDRESULT scriptinternalcmdexec(const char* cmd)
else if(scriptisinternalcommand(cmd, "nop")) //do nothing
return STATUS_CONTINUE;
char command[deflen] = "";
strcpy_s(command, cmd);
argformat(command);
strcpy_s(command, StringUtils::Trim(cmd).c_str());
COMMAND* found = cmdfindmain(dbggetcommandlist(), command);
if(!found) //invalid command
return STATUS_ERROR;

View File

@ -0,0 +1,142 @@
#include "stringformat.h"
#include "console.h"
#include "value.h"
#include "disasm_helper.h"
namespace ValueType
{
enum ValueType
{
Unknown,
SignedDecimal,
UnsignedDecimal,
Hex,
Pointer,
String
};
}
static String printValue(FormatValueType value, ValueType::ValueType type)
{
uint valuint = 0;
bool validval = valfromstring(value, &valuint);
char result[deflen] = "???";
switch(type)
{
case ValueType::Unknown:
break;
case ValueType::SignedDecimal:
if(validval)
sprintf_s(result, "%"fext"d", valuint);
break;
case ValueType::UnsignedDecimal:
if(validval)
sprintf_s(result, "%"fext"u", valuint);
break;
case ValueType::Hex:
if(validval)
sprintf_s(result, "%"fext"X", valuint);
break;
case ValueType::Pointer:
if(validval)
sprintf_s(result, "0x%"fhex, valuint);
break;
case ValueType::String:
if(validval)
{
STRING_TYPE strtype;
char string[512] = "";
if(disasmgetstringat(valuint, &strtype, string, string, 500))
strcpy_s(result, string);
}
break;
}
return result;
}
static unsigned int getArgNumType(const String & formatString, ValueType::ValueType & type)
{
int add = 0;
switch(formatString[0])
{
case 'd':
type = ValueType::SignedDecimal;
add++;
break;
case 'u':
type = ValueType::UnsignedDecimal;
add++;
break;
case 'p':
type = ValueType::Pointer;
add++;
break;
case 's':
type = ValueType::String;
add++;
break;
default:
type = ValueType::Hex;
}
unsigned int argnum = 0;
if(sscanf(formatString.c_str() + add, "%u", &argnum) != 1)
type = ValueType::Unknown;
return argnum;
}
static String handleFormatString(const String & formatString, const FormatValueVector & values)
{
String result;
ValueType::ValueType type = ValueType::Unknown;
unsigned int argnum = getArgNumType(formatString, type);
if(argnum < values.size())
return printValue(values.at(argnum), type);
return "[Formatting Error]";
}
String stringformat(String format, const FormatValueVector & values)
{
StringUtils::ReplaceAll(format, "\\n", "\n");
int len = (int)format.length();
String output;
String formatString;
bool inFormatter = false;
for(int i = 0; i < len; i++)
{
//handle escaped format sequences "{{" and "}}"
if(format[i] == '{' && (i + 1 < len && format[i + 1] == '{'))
{
output += "{";
i++;
continue;
}
else if(format[i] == '}' && (i + 1 < len && format[i + 1] == '}'))
{
output += "}";
i++;
continue;
}
//handle actual formatting
if(format[i] == '{' && !inFormatter) //opening bracket
{
inFormatter = true;
formatString.clear();
}
else if(format[i] == '}' && inFormatter) //closing bracket
{
inFormatter = false;
if(formatString.length())
{
output += handleFormatString(formatString, values);
formatString.clear();
}
}
else if(inFormatter) //inside brackets
formatString += format[i];
else //outside brackets
output += format[i];
}
if(inFormatter && formatString.size())
output += handleFormatString(formatString, values);
return output;
}

View File

@ -0,0 +1,11 @@
#ifndef _STRINGFORMAT_H
#define _STRINGFORMAT_H
#include "_global.h"
typedef const char* FormatValueType;
typedef std::vector<FormatValueType> FormatValueVector;
String stringformat(String format, const FormatValueVector & values);
#endif //_STRINGFORMAT_H

View File

@ -122,4 +122,25 @@ WString StringUtils::Utf8ToUtf16(const String & str)
WString StringUtils::Utf8ToUtf16(const char* str)
{
return Utf8ToUtf16(str ? String(str) : String());
}
//Taken from: http://stackoverflow.com/a/24315631
void StringUtils::ReplaceAll(String & s, const String & from, const String & to)
{
size_t start_pos = 0;
while((start_pos = s.find(from, start_pos)) != std::string::npos)
{
s.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
}
}
void StringUtils::ReplaceAll(WString & s, const WString & from, const WString & to)
{
size_t start_pos = 0;
while((start_pos = s.find(from, start_pos)) != std::string::npos)
{
s.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
}
}

View File

@ -22,6 +22,8 @@ public:
static String Utf16ToUtf8(const wchar_t* wstr);
static WString Utf8ToUtf16(const String & str);
static WString Utf8ToUtf16(const char* str);
static void ReplaceAll(String & s, const String & from, const String & to);
static void ReplaceAll(WString & s, const WString & from, const WString & to);
private:
static const String WHITESPACE;

View File

@ -248,3 +248,27 @@ const char* SymGetSymbolicName(uint Address)
return symbolicname;
}
bool SymGetSourceLine(uint Cip, char* FileName, int* Line)
{
IMAGEHLP_LINE64 lineInfo;
memset(&lineInfo, 0, sizeof(IMAGEHLP_LINE64));
lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
// Perform a symbol lookup from a specific address
DWORD displacement;
if(!SafeSymGetLineFromAddr64(fdProcessInfo->hProcess, Cip, &displacement, &lineInfo))
return false;
// Copy line number if requested
if(Line)
*Line = lineInfo.LineNumber;
// Copy file name if requested
if(FileName)
strcpy_s(FileName, MAX_STRING_SIZE, lineInfo.FileName);
return true;
}

View File

@ -7,4 +7,13 @@ bool SymGetModuleList(std::vector<SYMBOLMODULEINFO>* List);
void SymUpdateModuleList();
void SymDownloadAllSymbols(const char* SymbolStore);
bool SymAddrFromName(const char* Name, uint* Address);
const char* SymGetSymbolicName(uint Address);
const char* SymGetSymbolicName(uint Address);
/**
\brief Gets the source code file name and line from an address.
\param cip The address to check.
\param [out] szFileName Source code file. Buffer of MAX_STRING_SIZE length. UTF-8. Can be null.
\param [out] nLine Line number. Can be null.
\return true if it succeeds, false if it fails.
*/
bool SymGetSourceLine(uint Cip, char* FileName, int* Line);

View File

@ -36,14 +36,14 @@ void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
GuiUpdateThreadView();
}
void ThreadExit(DWORD dwThreadId)
void ThreadExit(DWORD ThreadId)
{
EXCLUSIVE_ACQUIRE(LockThreads);
// Don't use a foreach loop here because of the erase() call
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
{
if(itr->ThreadId == dwThreadId)
if(itr->ThreadId == ThreadId)
{
threadList.erase(itr);
break;
@ -71,7 +71,7 @@ int ThreadGetCount()
return (int)threadList.size();
}
void ThreadGetList(THREADLIST* list)
void ThreadGetList(THREADLIST* List)
{
SHARED_ACQUIRE(LockThreads);
@ -84,8 +84,8 @@ void ThreadGetList(THREADLIST* list)
if(count <= 0)
return;
list->count = (int)count;
list->list = (THREADALLINFO*)BridgeAlloc(count * sizeof(THREADALLINFO));
List->count = (int)count;
List->list = (THREADALLINFO*)BridgeAlloc(count * sizeof(THREADALLINFO));
// Fill out the list data
for(size_t i = 0; i < count; i++)
@ -94,25 +94,25 @@ void ThreadGetList(THREADLIST* list)
// Get the debugger's current thread index
if(threadHandle == hActiveThread)
list->CurrentThread = (int)i;
List->CurrentThread = (int)i;
memcpy(&list->list[i].BasicInfo, &threadList[i], sizeof(THREADINFO));
memcpy(&List->list[i].BasicInfo, &threadList[i], sizeof(THREADINFO));
list->list[i].ThreadCip = GetContextDataEx(threadHandle, UE_CIP);
list->list[i].SuspendCount = ThreadGetSuspendCount(threadHandle);
list->list[i].Priority = ThreadGetPriority(threadHandle);
list->list[i].WaitReason = ThreadGetWaitReason(threadHandle);
list->list[i].LastError = ThreadGetLastError(list->list[i].BasicInfo.ThreadLocalBase);
List->list[i].ThreadCip = GetContextDataEx(threadHandle, UE_CIP);
List->list[i].SuspendCount = ThreadGetSuspendCount(threadHandle);
List->list[i].Priority = ThreadGetPriority(threadHandle);
List->list[i].WaitReason = ThreadGetWaitReason(threadHandle);
List->list[i].LastError = ThreadGetLastError(List->list[i].BasicInfo.ThreadLocalBase);
}
}
bool ThreadIsValid(DWORD dwThreadId)
bool ThreadIsValid(DWORD ThreadId)
{
SHARED_ACQUIRE(LockThreads);
for(auto & entry : threadList)
{
if(entry.ThreadId == dwThreadId)
if(entry.ThreadId == ThreadId)
return true;
}
@ -159,31 +159,39 @@ THREADWAITREASON ThreadGetWaitReason(HANDLE Thread)
return _Executive;
}
DWORD ThreadGetLastError(uint tebAddress)
DWORD ThreadGetLastError(DWORD ThreadId)
{
TEB teb;
if(!ThreadGetTeb(tebAddress, &teb))
{
// TODO: Assert (Why would the TEB fail?)
return 0;
}
SHARED_ACQUIRE(LockThreads);
TEB teb;
for (auto & entry : threadList)
{
if (entry.ThreadId != ThreadId)
continue;
if (!ThreadGetTeb(entry.ThreadLocalBase, &teb))
{
// TODO: Assert (Why would the TEB fail?)
return 0;
}
}
return teb.LastErrorValue;
}
bool ThreadSetName(DWORD dwThreadId, const char* name)
bool ThreadSetName(DWORD ThreadId, const char* Name)
{
EXCLUSIVE_ACQUIRE(LockThreads);
// Modifies a variable (name), so an exclusive lock is required
for(auto & entry : threadList)
{
if(entry.ThreadId == dwThreadId)
if(entry.ThreadId == ThreadId)
{
if(!name)
name = "";
if(!Name)
Name = "";
strcpy_s(entry.threadName, name);
strcpy_s(entry.threadName, Name);
return true;
}
}
@ -191,13 +199,13 @@ bool ThreadSetName(DWORD dwThreadId, const char* name)
return false;
}
HANDLE ThreadGetHandle(DWORD dwThreadId)
HANDLE ThreadGetHandle(DWORD ThreadId)
{
SHARED_ACQUIRE(LockThreads);
for(auto & entry : threadList)
{
if(entry.ThreadId == dwThreadId)
if(entry.ThreadId == ThreadId)
return entry.Handle;
}
@ -206,20 +214,20 @@ HANDLE ThreadGetHandle(DWORD dwThreadId)
return 0;
}
DWORD ThreadGetId(HANDLE hThread)
DWORD ThreadGetId(HANDLE Thread)
{
SHARED_ACQUIRE(LockThreads);
// Search for the ID in the local list
for(auto & entry : threadList)
{
if(entry.Handle == hThread)
if(entry.Handle == Thread)
return entry.ThreadId;
}
// Wasn't found, check with Windows
// NOTE: Requires VISTA+
DWORD id = GetThreadId(hThread);
DWORD id = GetThreadId(Thread);
// Returns 0 on error;
// TODO: Same problem with ThreadGetHandle()

View File

@ -4,19 +4,19 @@
#include "debugger.h"
void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread);
void ThreadExit(DWORD dwThreadId);
void ThreadExit(DWORD ThreadId);
void ThreadClear();
int ThreadGetCount();
void ThreadGetList(THREADLIST* list);
bool ThreadIsValid(DWORD dwThreadId);
bool ThreadSetName(DWORD dwTHreadId, const char* name);
bool ThreadIsValid(DWORD ThreadId);
bool ThreadSetName(DWORD ThreadId, const char* name);
bool ThreadGetTeb(uint TEBAddress, TEB* Teb);
int ThreadGetSuspendCount(HANDLE Thread);
THREADPRIORITY ThreadGetPriority(HANDLE Thread);
THREADWAITREASON ThreadGetWaitReason(HANDLE Thread);
DWORD ThreadGetLastError(uint tebAddress);
DWORD ThreadGetLastError(DWORD ThreadId);
bool ThreadSetName(DWORD dwThreadId, const char* name);
HANDLE ThreadGetHandle(DWORD dwThreadId);
DWORD ThreadGetId(HANDLE hThread);
HANDLE ThreadGetHandle(DWORD ThreadId);
DWORD ThreadGetId(HANDLE Thread);
int ThreadSuspendAll();
int ThreadResumeAll();

View File

@ -5,7 +5,6 @@
*/
#include "_global.h"
#include "argument.h"
#include "command.h"
#include "variable.h"
#include "instruction.h"
@ -199,7 +198,8 @@ static void registercommands()
dbgcmdnew("copystr\1strcpy", cbInstrCopystr, true); //write a string variable to memory
dbgcmdnew("looplist", cbInstrLoopList, true); //list loops
dbgcmdnew("yara", cbInstrYara, true); //yara test command
dbgcmdnew("yaramod", cbInstrYaramod, true);
dbgcmdnew("yaramod", cbInstrYaramod, true); //yara rule on module
dbgcmdnew("log", cbInstrLog, false); //log command with superawesome hax
}
static bool cbCommandProvider(char* cmd, int maxlen)

View File

@ -20,11 +20,11 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="addrinfo.cpp" />
<ClCompile Include="argument.cpp" />
<ClCompile Include="assemble.cpp" />
<ClCompile Include="bookmark.cpp" />
<ClCompile Include="breakpoint.cpp" />
<ClCompile Include="command.cpp" />
<ClCompile Include="commandparser.cpp" />
<ClCompile Include="comment.cpp" />
<ClCompile Include="console.cpp" />
<ClCompile Include="dbghelp_safe.cpp" />
@ -50,6 +50,7 @@
<ClCompile Include="reference.cpp" />
<ClCompile Include="simplescript.cpp" />
<ClCompile Include="stackinfo.cpp" />
<ClCompile Include="stringformat.cpp" />
<ClCompile Include="stringutils.cpp" />
<ClCompile Include="symbolinfo.cpp" />
<ClCompile Include="thread.cpp" />
@ -64,7 +65,6 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="addrinfo.h" />
<ClInclude Include="argument.h" />
<ClInclude Include="assemble.h" />
<ClInclude Include="BeaEngine\basic_types.h" />
<ClInclude Include="BeaEngine\BeaEngine.h" />
@ -73,6 +73,7 @@
<ClInclude Include="bookmark.h" />
<ClInclude Include="breakpoint.h" />
<ClInclude Include="command.h" />
<ClInclude Include="commandparser.h" />
<ClInclude Include="comment.h" />
<ClInclude Include="console.h" />
<ClInclude Include="dbghelp\dbghelp.h" />
@ -106,6 +107,7 @@
<ClInclude Include="reference.h" />
<ClInclude Include="simplescript.h" />
<ClInclude Include="stackinfo.h" />
<ClInclude Include="stringformat.h" />
<ClInclude Include="stringutils.h" />
<ClInclude Include="symbolinfo.h" />
<ClInclude Include="thread.h" />

View File

@ -93,9 +93,6 @@
<ClCompile Include="_global.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
<ClCompile Include="argument.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
<ClCompile Include="command.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
@ -201,6 +198,12 @@
<ClCompile Include="dbghelp_safe.cpp">
<Filter>Source Files\Utilities</Filter>
</ClCompile>
<ClCompile Include="stringformat.cpp">
<Filter>Source Files\Utilities</Filter>
</ClCompile>
<ClCompile Include="commandparser.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="x64_dbg.h">
@ -248,9 +251,6 @@
<ClInclude Include="_global.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="argument.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="console.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
@ -467,5 +467,11 @@
<ClInclude Include="yara\yara\utils.h">
<Filter>Header Files\Third Party\yara\yara</Filter>
</ClInclude>
<ClInclude Include="stringformat.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="commandparser.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -370,6 +370,11 @@ void Bridge::emitSymbolRefreshCurrent()
emit symbolRefreshCurrent();
}
void Bridge::emitLoadSourceFile(const QString path, int line)
{
emit loadSourceFile(path, line);
}
/************************************************************************************
Static Functions
************************************************************************************/
@ -828,6 +833,12 @@ void* Bridge::GuiDispatchMessage(GUIMSG type, void* param1, void* param2)
}
break;
case GUI_LOAD_SOURCE_FILE:
{
Bridge::getBridge()->emitLoadSourceFile(QString((const char*)param1), (int)param2);
}
break;
default:
{

View File

@ -83,6 +83,7 @@ public:
void emitUpdatePatches();
void emitUpdateCallStack();
void emitSymbolRefreshCurrent();
void emitLoadSourceFile(const QString path, int line = 0);
static DWORD WINAPI GuiDisptacherThread(LPVOID Argument);
static void* GuiDispatchMessage(GUIMSG type, void* param1, void* param2);
@ -151,6 +152,7 @@ signals:
void updatePatches();
void updateCallStack();
void symbolRefreshCurrent();
void loadSourceFile(const QString path, int line);
private:
QMutex* mBridgeMutex;

View File

@ -125,10 +125,12 @@ void HexEditDialog::dataChangedSlot()
void HexEditDialog::on_lineEditAscii_textEdited(const QString & arg1)
{
Q_UNUSED(arg1);
on_btnAscii2Hex_clicked();
}
void HexEditDialog::on_lineEditUnicode_textEdited(const QString & arg1)
{
Q_UNUSED(arg1);
on_btnUnicode2Hex_clicked();
}

View File

@ -67,6 +67,12 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
mSymbolView->setWindowIcon(QIcon(":/icons/images/pdb.png"));
mSymbolView->hide();
// Source View
mSourceViewManager = new SourceViewerManager();
mSourceViewManager->setWindowTitle("Source");
mSourceViewManager->setWindowIcon(QIcon(":/icons/images/source.png"));
mSourceViewManager->hide();
// Breakpoints
mBreakpointsView = new BreakpointsView();
mBreakpointsView->setWindowTitle("Breakpoints");
@ -122,6 +128,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
mTabWidget->addTab(mCallStackView, mCallStackView->windowIcon(), mCallStackView->windowTitle());
mTabWidget->addTab(mScriptView, mScriptView->windowIcon(), mScriptView->windowTitle());
mTabWidget->addTab(mSymbolView, mSymbolView->windowIcon(), mSymbolView->windowTitle());
mTabWidget->addTab(mSourceViewManager, mSourceViewManager->windowIcon(), mSourceViewManager->windowTitle());
mTabWidget->addTab(mReferenceManager, mReferenceManager->windowIcon(), mReferenceManager->windowTitle());
mTabWidget->addTab(mThreadView, mThreadView->windowIcon(), mThreadView->windowTitle());
@ -168,6 +175,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(ui->actionRunSelection, SIGNAL(triggered()), this, SLOT(runSelection()));
connect(ui->actionCpu, SIGNAL(triggered()), this, SLOT(displayCpuWidget()));
connect(ui->actionSymbolInfo, SIGNAL(triggered()), this, SLOT(displaySymbolWidget()));
connect(ui->actionSource, SIGNAL(triggered()), this, SLOT(displaySourceViewWidget()));
connect(mSymbolView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget()));
connect(mSymbolView, SIGNAL(showReferences()), this, SLOT(displayReferencesWidget()));
connect(mReferenceManager, SIGNAL(showCpu()), this, SLOT(displayCpuWidget()));
@ -256,60 +264,65 @@ void MainWindow::setTab(QWidget* widget)
}
}
void MainWindow::setGlobalShortcut(QAction* action, const QKeySequence & key)
{
action->setShortcut(key);
action->setShortcutContext(Qt::ApplicationShortcut);
}
void MainWindow::refreshShortcuts()
{
ui->actionOpen->setShortcut(ConfigShortcut("FileOpen"));
ui->actionAttach->setShortcut(ConfigShortcut("FileAttach"));
ui->actionDetach->setShortcut(ConfigShortcut("FileDetach"));
ui->actionExit->setShortcut(ConfigShortcut("FileExit"));
setGlobalShortcut(ui->actionOpen, ConfigShortcut("FileOpen"));
setGlobalShortcut(ui->actionAttach, ConfigShortcut("FileAttach"));
setGlobalShortcut(ui->actionDetach, ConfigShortcut("FileDetach"));
setGlobalShortcut(ui->actionExit, ConfigShortcut("FileExit"));
ui->actionCpu->setShortcut(ConfigShortcut("ViewCpu"));
ui->actionLog->setShortcut(ConfigShortcut("ViewLog"));
ui->actionBreakpoints->setShortcut(ConfigShortcut("ViewBreakpoints"));
ui->actionMemoryMap->setShortcut(ConfigShortcut("ViewMemoryMap"));
ui->actionCallStack->setShortcut(ConfigShortcut("ViewCallStack"));
ui->actionScript->setShortcut(ConfigShortcut("ViewScript"));
ui->actionSymbolInfo->setShortcut(ConfigShortcut("ViewSymbolInfo"));
ui->actionReferences->setShortcut(ConfigShortcut("ViewReferences"));
ui->actionThreads->setShortcut(ConfigShortcut("ViewThreads"));
ui->actionPatches->setShortcut(ConfigShortcut("ViewPatches"));
ui->actionComments->setShortcut(ConfigShortcut("ViewComments"));
ui->actionLabels->setShortcut(ConfigShortcut("ViewLabels"));
ui->actionBookmarks->setShortcut(ConfigShortcut("ViewBookmarks"));
ui->actionFunctions->setShortcut(ConfigShortcut("ViewFunctions"));
setGlobalShortcut(ui->actionCpu, ConfigShortcut("ViewCpu"));
setGlobalShortcut(ui->actionLog, ConfigShortcut("ViewLog"));
setGlobalShortcut(ui->actionBreakpoints, ConfigShortcut("ViewBreakpoints"));
setGlobalShortcut(ui->actionMemoryMap, ConfigShortcut("ViewMemoryMap"));
setGlobalShortcut(ui->actionCallStack, ConfigShortcut("ViewCallStack"));
setGlobalShortcut(ui->actionScript, ConfigShortcut("ViewScript"));
setGlobalShortcut(ui->actionSymbolInfo, ConfigShortcut("ViewSymbolInfo"));
setGlobalShortcut(ui->actionSource, ConfigShortcut("ViewSource"));
setGlobalShortcut(ui->actionReferences, ConfigShortcut("ViewReferences"));
setGlobalShortcut(ui->actionThreads, ConfigShortcut("ViewThreads"));
setGlobalShortcut(ui->actionPatches, ConfigShortcut("ViewPatches"));
setGlobalShortcut(ui->actionComments, ConfigShortcut("ViewComments"));
setGlobalShortcut(ui->actionLabels, ConfigShortcut("ViewLabels"));
setGlobalShortcut(ui->actionBookmarks, ConfigShortcut("ViewBookmarks"));
setGlobalShortcut(ui->actionFunctions, ConfigShortcut("ViewFunctions"));
ui->actionRun->setShortcut(ConfigShortcut("DebugRun"));
ui->actioneRun->setShortcut(ConfigShortcut("DebugeRun"));
ui->actionRunSelection->setShortcut(ConfigShortcut("DebugRunSelection"));
ui->actionPause->setShortcut(ConfigShortcut("DebugPause"));
ui->actionRestart->setShortcut(ConfigShortcut("DebugRestart"));
ui->actionClose->setShortcut(ConfigShortcut("DebugClose"));
ui->actionStepInto->setShortcut(ConfigShortcut("DebugStepInto"));
ui->actioneStepInto->setShortcut(ConfigShortcut("DebugeStepInfo"));
ui->actionStepOver->setShortcut(ConfigShortcut("DebugStepOver"));
ui->actioneStepOver->setShortcut(ConfigShortcut("DebugeStepOver"));
ui->actionRtr->setShortcut(ConfigShortcut("DebugRtr"));
ui->actioneRtr->setShortcut(ConfigShortcut("DebugeRtr"));
ui->actionCommand->setShortcut(ConfigShortcut("DebugCommand"));
ui->actionSkipNextInstruction->setShortcut(ConfigShortcut("DebugSkipNextInstruction"));
setGlobalShortcut(ui->actionRun, ConfigShortcut("DebugRun"));
setGlobalShortcut(ui->actioneRun, ConfigShortcut("DebugeRun"));
setGlobalShortcut(ui->actionRunSelection, ConfigShortcut("DebugRunSelection"));
setGlobalShortcut(ui->actionPause, ConfigShortcut("DebugPause"));
setGlobalShortcut(ui->actionRestart, ConfigShortcut("DebugRestart"));
setGlobalShortcut(ui->actionClose, ConfigShortcut("DebugClose"));
setGlobalShortcut(ui->actionStepInto, ConfigShortcut("DebugStepInto"));
setGlobalShortcut(ui->actioneStepInto, ConfigShortcut("DebugeStepInfo"));
setGlobalShortcut(ui->actionStepOver, ConfigShortcut("DebugStepOver"));
setGlobalShortcut(ui->actioneStepOver, ConfigShortcut("DebugeStepOver"));
setGlobalShortcut(ui->actionRtr, ConfigShortcut("DebugRtr"));
setGlobalShortcut(ui->actioneRtr, ConfigShortcut("DebugeRtr"));
setGlobalShortcut(ui->actionCommand, ConfigShortcut("DebugCommand"));
setGlobalShortcut(ui->actionSkipNextInstruction, ConfigShortcut("DebugSkipNextInstruction"));
ui->actionScylla->setShortcut(ConfigShortcut("PluginsScylla"));
setGlobalShortcut(ui->actionScylla, ConfigShortcut("PluginsScylla"));
ui->actionSettings->setShortcut(ConfigShortcut("OptionsPreferences"));
ui->actionAppearance->setShortcut(ConfigShortcut("OptionsAppearance"));
ui->actionShortcuts->setShortcut(ConfigShortcut("OptionsShortcuts"));
ui->actionTopmost->setShortcut(ConfigShortcut("OptionsTopmost"));
ui->actionAbout->setShortcut(ConfigShortcut("HelpAbout"));
ui->actionDonate->setShortcut(ConfigShortcut("HelpDonate"));
ui->actionCheckUpdates->setShortcut(ConfigShortcut("HelpCheckForUpdates"));
ui->actionCalculator->setShortcut(ConfigShortcut("HelpCalculator"));
ui->actionReportBug->setShortcut(ConfigShortcut("HelpReportBug"));
ui->actionStrings->setShortcut(ConfigShortcut("ActionFindStrings"));
ui->actionCalls->setShortcut(ConfigShortcut("ActionFindIntermodularCalls"));
setGlobalShortcut(ui->actionSettings, ConfigShortcut("OptionsPreferences"));
setGlobalShortcut(ui->actionAppearance, ConfigShortcut("OptionsAppearance"));
setGlobalShortcut(ui->actionShortcuts, ConfigShortcut("OptionsShortcuts"));
setGlobalShortcut(ui->actionTopmost, ConfigShortcut("OptionsTopmost"));
setGlobalShortcut(ui->actionAbout, ConfigShortcut("HelpAbout"));
setGlobalShortcut(ui->actionDonate, ConfigShortcut("HelpDonate"));
setGlobalShortcut(ui->actionCheckUpdates, ConfigShortcut("HelpCheckForUpdates"));
setGlobalShortcut(ui->actionCalculator, ConfigShortcut("HelpCalculator"));
setGlobalShortcut(ui->actionReportBug, ConfigShortcut("HelpReportBug"));
setGlobalShortcut(ui->actionStrings, ConfigShortcut("ActionFindStrings"));
setGlobalShortcut(ui->actionCalls, ConfigShortcut("ActionFindIntermodularCalls"));
}
//Reads recent files list from settings
@ -653,6 +666,13 @@ void MainWindow::displaySymbolWidget()
setTab(mSymbolView);
}
void MainWindow::displaySourceViewWidget()
{
mSourceViewManager->show();
mSourceViewManager->setFocus();
setTab(mSourceViewManager);
}
void MainWindow::displayReferencesWidget()
{
mReferenceManager->show();

View File

@ -19,6 +19,7 @@
#include "CalculatorDialog.h"
#include "StatusLabel.h"
#include "UpdateChecker.h"
#include "SourceViewerManager.h"
namespace Ui
{
@ -62,6 +63,7 @@ public slots:
void execSkip();
void displayCpuWidget();
void displaySymbolWidget();
void displaySourceViewWidget();
void displayReferencesWidget();
void displayThreadsWidget();
void openSettings();
@ -87,6 +89,7 @@ public slots:
void displayFunctions();
void checkUpdates();
void displayCallstack();
void setGlobalShortcut(QAction* action, const QKeySequence & key);
void refreshShortcuts();
void openShortcuts();
void changeTopmost(bool checked);
@ -106,6 +109,7 @@ private:
CallStackView* mCallStackView;
LogView* mLogView;
SymbolView* mSymbolView;
SourceViewerManager* mSourceViewManager;
BreakpointsView* mBreakpointsView;
ScriptView* mScriptView;
ReferenceManager* mReferenceManager;

View File

@ -54,6 +54,7 @@
<addaction name="actionCallStack"/>
<addaction name="actionScript"/>
<addaction name="actionSymbolInfo"/>
<addaction name="actionSource"/>
<addaction name="actionReferences"/>
<addaction name="actionThreads"/>
<addaction name="actionPatches"/>
@ -152,6 +153,7 @@
<addaction name="actionCallStack"/>
<addaction name="actionScript"/>
<addaction name="actionSymbolInfo"/>
<addaction name="actionSource"/>
<addaction name="actionReferences"/>
<addaction name="actionThreads"/>
<addaction name="separator"/>
@ -649,6 +651,18 @@
<string>Report Bug</string>
</property>
</action>
<action name="actionSource">
<property name="icon">
<iconset resource="../../resource.qrc">
<normaloff>:/icons/images/source.png</normaloff>:/icons/images/source.png</iconset>
</property>
<property name="text">
<string>&amp;Source</string>
</property>
<property name="toolTip">
<string>Source</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>

View File

@ -121,6 +121,11 @@ void RegistersView::InitMappings()
offset++;
mRegisterMapping.insert(LastError, "LastError");
mRegisterPlaces.insert(LastError, Register_Position(offset++, 0, 10, 20));
offset++;
mRegisterMapping.insert(GS, "GS");
mRegisterPlaces.insert(GS, Register_Position(offset, 0, 3, 4));
mRegisterMapping.insert(FS, "FS");
@ -1025,6 +1030,8 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff
mFPU.insert(YMM15);
#endif
//registers that should not be changed
mNoChange.insert(LastError);
mNoChange.insert(GS);
mUSHORTDISPLAY.insert(GS);
@ -1452,6 +1459,15 @@ QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value
valueText += QString(")");
}
}
else if(reg == LastError)
{
LASTERROR* data = (LASTERROR*)value;
if(data->name)
valueText = QString().sprintf("%08X (%s)", data->code, data->name);
else
valueText = QString().sprintf("%08X", data->code);
mRegisterPlaces[LastError].valuesize = valueText.length();
}
else
{
SIZE_T size = GetSizeRegister(reg);
@ -1705,6 +1721,9 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value)
else
p->setPen(ConfigColor("RegistersColor"));
//get register value
QString valueText = GetRegStringValueFromValue(reg, value);
//selection
if(mSelected == reg)
{
@ -1712,9 +1731,7 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value)
//p->fillRect(QRect(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line)+2, mRegisterPlaces[reg].valuesize*mCharWidth, mRowHeight), QBrush(ConfigColor("RegistersSelectionColor")));
}
QString valueText;
// draw value
valueText = GetRegStringValueFromValue(reg, value);
width = mCharWidth * valueText.length();
p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, valueText);
//p->drawText(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line+1),QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper());
@ -2211,6 +2228,8 @@ SIZE_T RegistersView::GetSizeRegister(const REGISTER_NAME reg_name)
size = 16;
else if(mFPUYMM.contains(reg_name))
size = 32;
else if(reg_name == LastError)
return sizeof(LASTERROR);
else
size = 0;
@ -2274,6 +2293,8 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg)
if(reg == CS) return (char*) & (regd->regcontext.cs);
if(reg == SS) return (char*) & (regd->regcontext.ss);
if(reg == LastError) return (char*) & (regd->lastError);
if(reg == DR0) return (char*) & (regd->regcontext.dr0);
if(reg == DR1) return (char*) & (regd->regcontext.dr1);
if(reg == DR2) return (char*) & (regd->regcontext.dr2);

View File

@ -34,6 +34,7 @@ public:
CIP,
EFLAGS, CF, PF, AF, ZF, SF, TF, IF, DF, OF,
GS, FS, ES, DS, CS, SS,
LastError,
DR0, DR1, DR2, DR3, DR6, DR7,
// x87 stuff
x87r0, x87r1, x87r2, x87r3, x87r4, x87r5, x87r6, x87r7,

View File

@ -55,6 +55,7 @@ void SettingsDialog::LoadSettings()
settings.engineCalcType = calc_unsigned;
settings.engineBreakpointType = break_int3short;
settings.engineUndecorateSymbolNames = true;
settings.engineEnableSourceDebugging = true;
settings.exceptionRanges = &realExceptionRanges;
settings.disasmArgumentSpaces = false;
settings.disasmMemorySpaces = false;
@ -110,6 +111,7 @@ void SettingsDialog::LoadSettings()
}
GetSettingBool("Engine", "UndecorateSymbolNames", &settings.engineUndecorateSymbolNames);
GetSettingBool("Engine", "EnableDebugPrivilege", &settings.engineEnableDebugPrivilege);
GetSettingBool("Engine", "EnableSourceDebugging", &settings.engineEnableSourceDebugging);
switch(settings.engineCalcType)
{
case calc_signed:
@ -133,6 +135,7 @@ void SettingsDialog::LoadSettings()
}
ui->chkUndecorateSymbolNames->setChecked(settings.engineUndecorateSymbolNames);
ui->chkEnableDebugPrivilege->setChecked(settings.engineEnableDebugPrivilege);
ui->chkEnableSourceDebugging->setChecked(settings.engineEnableSourceDebugging);
//Exceptions tab
char exceptionRange[MAX_SETTING_SIZE] = "";
@ -229,6 +232,7 @@ void SettingsDialog::SaveSettings()
BridgeSettingSetUint("Engine", "BreakpointType", settings.engineBreakpointType);
BridgeSettingSetUint("Engine", "UndecorateSymbolNames", settings.engineUndecorateSymbolNames);
BridgeSettingSetUint("Engine", "EnableDebugPrivilege", settings.engineEnableDebugPrivilege);
BridgeSettingSetUint("Engine", "EnableSourceDebugging", settings.engineEnableSourceDebugging);
//Exceptions tab
QString exceptionRange = "";
@ -485,12 +489,17 @@ void SettingsDialog::on_chkUndecorateSymbolNames_stateChanged(int arg1)
void SettingsDialog::on_chkEnableDebugPrivilege_stateChanged(int arg1)
{
if(arg1 == Qt::Unchecked)
if(arg1 == Qt::Unchecked) //wtf stupid shit
settings.engineEnableDebugPrivilege = false;
else
settings.engineEnableDebugPrivilege = true;
}
void SettingsDialog::on_chkEnableSourceDebugging_stateChanged(int arg1)
{
settings.engineEnableSourceDebugging = arg1 == Qt::Checked;
}
void SettingsDialog::on_btnAddRange_clicked()
{
ExceptionRangeDialog exceptionRange(this);

View File

@ -43,6 +43,7 @@ private slots:
void on_radioUd2_clicked();
void on_chkUndecorateSymbolNames_stateChanged(int arg1);
void on_chkEnableDebugPrivilege_stateChanged(int arg1);
void on_chkEnableSourceDebugging_stateChanged(int arg1);
//Exception tab
void on_btnAddRange_clicked();
void on_btnDeleteRange_clicked();
@ -56,7 +57,6 @@ private slots:
void on_chkSetJIT_stateChanged(int arg1);
void on_chkConfirmBeforeAtt_stateChanged(int arg1);
private:
//enums
enum CalcType
@ -106,6 +106,7 @@ private:
BreakpointType engineBreakpointType;
bool engineUndecorateSymbolNames;
bool engineEnableDebugPrivilege;
bool engineEnableSourceDebugging;
//Exception Tab
QList<RangeStruct>* exceptionRanges;
//Disasm Tab

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>308</width>
<height>220</height>
<width>350</width>
<height>250</height>
</rect>
</property>
<property name="sizePolicy">
@ -245,6 +245,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkEnableSourceDebugging">
<property name="text">
<string>Enable Source Debugging</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

View File

@ -0,0 +1,95 @@
#include "SourceView.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include "Configuration.h"
SourceView::SourceView(QString path, int line, StdTable* parent) : StdTable(parent)
{
mSourcePath = path;
addColumnAt(8 + 4 * getCharWidth(), "Line", true);
addColumnAt(0, "Code", true);
loadFile();
setInstructionPointer(line);
}
void SourceView::setInstructionPointer(int line)
{
int offset = line - 1;
if(!isValidIndex(offset, 0))
{
mIpLine = 0;
return;
}
mIpLine = line;
int rangefrom = getTableOffset();
int rangeto = rangefrom + getViewableRowsCount() - 1;
if(offset < rangefrom) //ip lays before the current view
setTableOffset(offset);
else if(offset > (rangeto - 1)) //ip lays after the current view
setTableOffset(offset - getViewableRowsCount() + 2);
setSingleSelection(offset);
reloadData(); //repaint
}
QString SourceView::getSourcePath()
{
return mSourcePath;
}
void SourceView::loadFile()
{
QFile file(mSourcePath);
if(!file.open(QIODevice::ReadOnly))
{
return; //error?
}
QTextStream in(&file);
int lineNum = 0;
while(!in.atEnd())
{
QString line = in.readLine().replace('\t', " "); //replace tabs with four spaces
setRowCount(lineNum + 1);
setCellContent(lineNum, 0, QString().sprintf("%04d", lineNum + 1));
setCellContent(lineNum, 1, line);
lineNum++;
}
reloadData();
file.close();
}
QString SourceView::paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)
{
painter->save();
bool wIsSelected = isSelected(rowBase, rowOffset);
// Highlight if selected
if(wIsSelected)
painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); //ScriptViewSelectionColor
QString returnString;
int line = rowBase + rowOffset + 1;
switch(col)
{
case 0: //line number
{
if(line == mIpLine) //IP
{
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyCipBackgroundColor")));
painter->setPen(QPen(ConfigColor("DisassemblyCipColor"))); //white address (ScriptViewIpTextColor)
}
else
painter->setPen(QPen(this->textColor));
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, QString().sprintf("%04d", line));
}
break;
case 1: //command
{
returnString = getCellContent(rowBase + rowOffset, col); //TODO: simple keyword/regex-based syntax highlighting
}
break;
}
painter->restore();
return returnString;
}

View File

@ -0,0 +1,22 @@
#ifndef SOURCEVIEW_H
#define SOURCEVIEW_H
#include <QWidget>
#include "StdTable.h"
class SourceView : public StdTable
{
Q_OBJECT
public:
explicit SourceView(QString path, int line = 0, StdTable* parent = 0);
QString getSourcePath();
void setInstructionPointer(int line);
QString paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h);
private:
QString mSourcePath;
int mIpLine;
void loadFile();
};
#endif // SOURCEVIEW_H

View File

@ -0,0 +1,58 @@
#include "SourceViewerManager.h"
#include "Bridge.h"
#include <QFileInfo>
#include <QDir>
SourceViewerManager::SourceViewerManager(QWidget* parent) : QTabWidget(parent)
{
setMovable(true);
setTabsClosable(true);
//Close All Tabs
mCloseAllTabs = new QPushButton(this);
mCloseAllTabs->setIcon(QIcon(":/icons/images/close-all-tabs.png"));
mCloseAllTabs->setToolTip("Close All Tabs");
connect(mCloseAllTabs, SIGNAL(clicked()), this, SLOT(closeAllTabs()));
setCornerWidget(mCloseAllTabs, Qt::TopLeftCorner);
connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
connect(Bridge::getBridge(), SIGNAL(loadSourceFile(QString, int)), this, SLOT(loadSourceFile(QString, int)));
}
void SourceViewerManager::loadSourceFile(QString path, int line)
{
for(int i = 0; i < count(); i++) //remove all other instruction pointers (only one is possible)
((SourceView*)this->widget(i))->setInstructionPointer(0);
for(int i = 0; i < count(); i++)
{
SourceView* curView = (SourceView*)this->widget(i);
if(curView->getSourcePath().compare(path, Qt::CaseInsensitive) == 0) //file already loaded
{
curView->setInstructionPointer(line);
setCurrentIndex(i); //show that loaded tab
return;
}
}
//check if file actually exists
if(!QFileInfo(path).exists())
{
return; //error?
}
//load the new file
QString title = path;
int idx = path.lastIndexOf(QDir::separator());
if(idx != -1)
title = path.mid(idx + 1);
addTab(new SourceView(path, line), title);
setCurrentIndex(count() - 1);
}
void SourceViewerManager::closeTab(int index)
{
removeTab(index);
}
void SourceViewerManager::closeAllTabs()
{
clear();
}

View File

@ -0,0 +1,24 @@
#ifndef SOURCEVIEWERMANAGER_H
#define SOURCEVIEWERMANAGER_H
#include <QTabWidget>
#include <QPushButton>
#include <QMap>
#include "SourceView.h"
class SourceViewerManager : public QTabWidget
{
Q_OBJECT
public:
explicit SourceViewerManager(QWidget* parent = 0);
public slots:
void loadSourceFile(QString path, int line);
void closeTab(int index);
void closeAllTabs();
private:
QPushButton* mCloseAllTabs;
};
#endif // SOURCEVIEWERMANAGER_H

View File

@ -52,6 +52,11 @@ void StatusLabel::logUpdate(QString message)
if(labelText.contains(QChar('\n'))) //newline
labelText = "";
labelText += message;
setText(labelText);
//only show the last line in the status label
QStringList lineList = labelText.split(QChar('\n'), QString::SkipEmptyParts);
if(lineList.size())
setText(lineList[lineList.length() - 1]);
else
setText(labelText);
this->repaint();
}

View File

@ -55,6 +55,8 @@ void YaraRuleSelectionDialog::on_buttonFile_clicked()
void YaraRuleSelectionDialog::on_buttonSelect_clicked()
{
if(!ui->listRules->selectedItems().size()) //no selection
return;
int selectedIndex = ui->listRules->row(ui->listRules->selectedItems().at(0));
selectedFile = ruleFiles.at(selectedIndex).first;
this->accept();

View File

@ -187,6 +187,7 @@ Configuration::Configuration() : QObject()
defaultShortcuts.insert("ViewCallStack", Shortcut(tr("View -> Call Stack"), "Alt+K", true));
defaultShortcuts.insert("ViewScript", Shortcut(tr("View -> Script"), "Alt+S", true));
defaultShortcuts.insert("ViewSymbolInfo", Shortcut(tr("View -> Symbol Info"), "Ctrl+Alt+S", true));
defaultShortcuts.insert("ViewSource", Shortcut(tr("View -> Source"), "Ctrl+Shift+S", true));
defaultShortcuts.insert("ViewReferences", Shortcut(tr("View -> References"), "Alt+R", true));
defaultShortcuts.insert("ViewThreads", Shortcut(tr("View -> Threads"), "Alt+T", true));
defaultShortcuts.insert("ViewPatches", Shortcut(tr("View -> Patches"), "Ctrl+P", true));

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

View File

@ -53,5 +53,6 @@
<file>images/bug-report.png</file>
<file>images/yara.png</file>
<file>images/data-copy.png</file>
<file>images/source.png</file>
</qresource>
</RCC>

View File

@ -88,7 +88,9 @@ SOURCES += \
Src/Gui/ReferenceManager.cpp \
Src/Bridge/BridgeResult.cpp \
Src/Gui/YaraRuleSelectionDialog.cpp \
Src/Gui/DataCopyDialog.cpp
Src/Gui/DataCopyDialog.cpp \
Src/Gui/SourceViewerManager.cpp \
Src/Gui/SourceView.cpp
HEADERS += \
@ -155,7 +157,9 @@ HEADERS += \
Src/Gui/ReferenceManager.h \
Src/Bridge/BridgeResult.h \
Src/Gui/YaraRuleSelectionDialog.h \
Src/Gui/DataCopyDialog.h
Src/Gui/DataCopyDialog.h \
Src/Gui/SourceViewerManager.h \
Src/Gui/SourceView.h
INCLUDEPATH += \