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()