DBG: moved all commands to separate cpp files
This commit is contained in:
parent
23472fc36f
commit
e4f0654326
|
@ -3,8 +3,6 @@
|
|||
#include "module.h"
|
||||
#include "memory.h"
|
||||
#include "threading.h"
|
||||
#include "console.h"
|
||||
#include <algorithm>
|
||||
|
||||
TraceRecordManager TraceRecord;
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include "loop.h"
|
||||
#include "exception.h"
|
||||
#include "x64dbg.h"
|
||||
#include "threading.h"
|
||||
#include "stringformat.h"
|
||||
#include "xrefs.h"
|
||||
#include "encodemap.h"
|
||||
#include "argument.h"
|
||||
|
|
|
@ -6,17 +6,8 @@
|
|||
|
||||
#include "addrinfo.h"
|
||||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
#include "memory.h"
|
||||
#include "breakpoint.h"
|
||||
#include "lz4\lz4file.h"
|
||||
#include "patches.h"
|
||||
#include "module.h"
|
||||
#include "comment.h"
|
||||
#include "label.h"
|
||||
#include "bookmark.h"
|
||||
#include "function.h"
|
||||
#include "loop.h"
|
||||
|
||||
///api functions
|
||||
bool apienumexports(duint base, EXPORTENUMCALLBACK cbEnum)
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
#include "XEDParse\XEDParse.h"
|
||||
#include "value.h"
|
||||
#include "disasm_fast.h"
|
||||
#include "debugger.h"
|
||||
#include "disasm_helper.h"
|
||||
#include "memory.h"
|
||||
#include "keystone\keystone.h"
|
||||
#include "datainst_helper.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#include "bookmark.h"
|
||||
#include "module.h"
|
||||
#include "memory.h"
|
||||
|
||||
struct BookmarkSerializer : AddrInfoSerializer<BOOKMARKSINFO>
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,18 @@
|
|||
#define _COMMAND_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "console.h"
|
||||
|
||||
inline bool IsArgumentsLessThan(int argc, int minimumCount)
|
||||
{
|
||||
if(argc < minimumCount)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Not enough arguments! At least %d arguments must be specified.\n"), minimumCount - 1);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//typedefs
|
||||
|
||||
|
|
|
@ -2,10 +2,72 @@
|
|||
#include "threading.h"
|
||||
#include "memory.h"
|
||||
#include "debugger.h"
|
||||
#include "debugger_commands.h"
|
||||
#include "console.h"
|
||||
|
||||
char commandLine[MAX_COMMAND_LINE_SIZE];
|
||||
|
||||
void showcommandlineerror(cmdline_error_t* cmdline_error)
|
||||
{
|
||||
bool unkown = false;
|
||||
|
||||
switch(cmdline_error->type)
|
||||
{
|
||||
case CMDL_ERR_ALLOC:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error allocating memory for cmdline"));
|
||||
break;
|
||||
case CMDL_ERR_CONVERTUNICODE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error converting UNICODE cmdline"));
|
||||
break;
|
||||
case CMDL_ERR_READ_PEBBASE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error reading PEB base addres"));
|
||||
break;
|
||||
case CMDL_ERR_READ_PROCPARM_CMDLINE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error reading PEB -> ProcessParameters -> CommandLine UNICODE_STRING"));
|
||||
break;
|
||||
case CMDL_ERR_READ_PROCPARM_PTR:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error reading PEB -> ProcessParameters pointer address"));
|
||||
break;
|
||||
case CMDL_ERR_GET_PEB:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error Getting remote PEB address"));
|
||||
break;
|
||||
case CMDL_ERR_READ_GETCOMMANDLINEBASE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error Getting command line base address"));
|
||||
break;
|
||||
case CMDL_ERR_CHECK_GETCOMMANDLINESTORED:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error checking the pattern of the commandline stored"));
|
||||
break;
|
||||
case CMDL_ERR_WRITE_GETCOMMANDLINESTORED:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error writing the new command line stored"));
|
||||
break;
|
||||
case CMDL_ERR_GET_GETCOMMANDLINE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error getting getcommandline"));
|
||||
break;
|
||||
case CMDL_ERR_ALLOC_UNICODEANSI_COMMANDLINE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error allocating the page with UNICODE and ANSI command lines"));
|
||||
break;
|
||||
case CMDL_ERR_WRITE_ANSI_COMMANDLINE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error writing the ANSI command line in the page"));
|
||||
break;
|
||||
case CMDL_ERR_WRITE_UNICODE_COMMANDLINE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error writing the UNICODE command line in the page"));
|
||||
break;
|
||||
case CMDL_ERR_WRITE_PEBUNICODE_COMMANDLINE:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error writing command line UNICODE in PEB"));
|
||||
break;
|
||||
default:
|
||||
unkown = true;
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error getting cmdline"));
|
||||
break;
|
||||
}
|
||||
|
||||
if(!unkown)
|
||||
{
|
||||
if(cmdline_error->addr != 0)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", " (Address: %p)"), cmdline_error->addr);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", ""));
|
||||
}
|
||||
}
|
||||
|
||||
bool isCmdLineEmpty()
|
||||
{
|
||||
return !strlen(commandLine);
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#include "_global.h"
|
||||
#include "command.h"
|
||||
#include "debugger.h"
|
||||
|
||||
void showcommandlineerror(cmdline_error_t* cmdline_error);
|
||||
bool isCmdLineEmpty();
|
||||
char* getCommandLineArgs();
|
||||
void CmdLineCacheSave(JSON Root);
|
||||
|
|
|
@ -1 +1,425 @@
|
|||
#include "cmd-analysis.h"
|
||||
#include "cmd-analysis.h"
|
||||
#include "linearanalysis.h"
|
||||
#include "memory.h"
|
||||
#include "exceptiondirectoryanalysis.h"
|
||||
#include "controlflowanalysis.h"
|
||||
#include "analysis_nukem.h"
|
||||
#include "xrefsanalysis.h"
|
||||
#include "recursiveanalysis.h"
|
||||
#include "value.h"
|
||||
#include "advancedanalysis.h"
|
||||
#include "debugger.h"
|
||||
#include "variable.h"
|
||||
#include "exhandlerinfo.h"
|
||||
#include "symbolinfo.h"
|
||||
#include "exception.h"
|
||||
#include "TraceRecord.h"
|
||||
|
||||
CMDRESULT cbInstrAnalyse(int argc, char* argv[])
|
||||
{
|
||||
SELECTIONDATA sel;
|
||||
GuiSelectionGet(GUI_DISASSEMBLY, &sel);
|
||||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(sel.start, &size);
|
||||
LinearAnalysis anal(base, size);
|
||||
anal.Analyse();
|
||||
anal.SetMarkers();
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrExanalyse(int argc, char* argv[])
|
||||
{
|
||||
SELECTIONDATA sel;
|
||||
GuiSelectionGet(GUI_DISASSEMBLY, &sel);
|
||||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(sel.start, &size);
|
||||
ExceptionDirectoryAnalysis anal(base, size);
|
||||
anal.Analyse();
|
||||
anal.SetMarkers();
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrCfanalyse(int argc, char* argv[])
|
||||
{
|
||||
bool exceptionDirectory = false;
|
||||
if(argc > 1)
|
||||
exceptionDirectory = true;
|
||||
SELECTIONDATA sel;
|
||||
GuiSelectionGet(GUI_DISASSEMBLY, &sel);
|
||||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(sel.start, &size);
|
||||
ControlFlowAnalysis anal(base, size, exceptionDirectory);
|
||||
anal.Analyse();
|
||||
anal.SetMarkers();
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAnalyseNukem(int argc, char* argv[])
|
||||
{
|
||||
SELECTIONDATA sel;
|
||||
GuiSelectionGet(GUI_DISASSEMBLY, &sel);
|
||||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(sel.start, &size);
|
||||
Analyse_nukem(base, size);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAnalxrefs(int argc, char* argv[])
|
||||
{
|
||||
SELECTIONDATA sel;
|
||||
GuiSelectionGet(GUI_DISASSEMBLY, &sel);
|
||||
duint size = 0;
|
||||
auto base = MemFindBaseAddr(sel.start, &size);
|
||||
XrefsAnalysis anal(base, size);
|
||||
anal.Analyse();
|
||||
anal.SetMarkers();
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAnalrecur(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint entry;
|
||||
if(!valfromstring(argv[1], &entry, false))
|
||||
return STATUS_ERROR;
|
||||
duint size;
|
||||
auto base = MemFindBaseAddr(entry, &size);
|
||||
if(!base)
|
||||
return STATUS_ERROR;
|
||||
RecursiveAnalysis analysis(base, size, entry, 0);
|
||||
analysis.Analyse();
|
||||
analysis.SetMarkers();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAnalyseadv(int argc, char* argv[])
|
||||
{
|
||||
SELECTIONDATA sel;
|
||||
GuiSelectionGet(GUI_DISASSEMBLY, &sel);
|
||||
duint size = 0;
|
||||
auto base = MemFindBaseAddr(sel.start, &size);
|
||||
AdvancedAnalysis anal(base, size);
|
||||
anal.Analyse();
|
||||
anal.SetMarkers();
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrVirtualmod(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint base;
|
||||
if(!valfromstring(argv[2], &base))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Invalid parameter [base]!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!MemIsValidReadPtr(base))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Invalid memory address!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint size;
|
||||
if(argc < 4)
|
||||
base = MemFindBaseAddr(base, &size);
|
||||
else if(!valfromstring(argv[3], &size))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Invalid parameter [size]"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
auto name = String("virtual:\\") + (argv[1]);
|
||||
if(!ModLoad(base, size, name.c_str()))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to load module (ModLoad)..."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
char modname[256] = "";
|
||||
if(ModNameFromAddr(base, modname, true))
|
||||
BpEnumAll(cbSetModuleBreakpoints, modname);
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Virtual module \"%s\" loaded on %p[%p]!\n"), argv[1], base, size);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "This may take very long, depending on your network connection and data in the debug directory..."));
|
||||
char szDefaultStore[MAX_SETTING_SIZE] = "";
|
||||
const char* szSymbolStore = szDefaultStore;
|
||||
if(!BridgeSettingGet("Symbols", "DefaultStore", szDefaultStore)) //get default symbol store from settings
|
||||
{
|
||||
strcpy_s(szDefaultStore, "http://msdl.microsoft.com/download/symbols");
|
||||
BridgeSettingSet("Symbols", "DefaultStore", szDefaultStore);
|
||||
}
|
||||
if(argc < 2) //no arguments
|
||||
{
|
||||
SymDownloadAllSymbols(szSymbolStore); //download symbols for all modules
|
||||
GuiSymbolRefreshCurrent();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Done! See symbol log for more information"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
//get some module information
|
||||
duint modbase = ModBaseFromName(argv[1]);
|
||||
if(!modbase)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid module \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
wchar_t wszModulePath[MAX_PATH] = L"";
|
||||
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbase, wszModulePath, MAX_PATH))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "GetModuleFileNameExA failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
wchar_t szOldSearchPath[MAX_PATH] = L"";
|
||||
if(!SafeSymGetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current search path
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "SymGetSearchPath failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
char szServerSearchPath[MAX_PATH * 2] = "";
|
||||
if(argc > 2)
|
||||
szSymbolStore = argv[2];
|
||||
sprintf_s(szServerSearchPath, "SRV*%s*%s", szSymbolCachePath, szSymbolStore);
|
||||
if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, StringUtils::Utf8ToUtf16(szServerSearchPath).c_str())) //set new search path
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "SymSetSearchPath (1) failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase)) //unload module
|
||||
{
|
||||
SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "SymUnloadModule64 failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
auto symOptions = SafeSymGetOptions();
|
||||
SafeSymSetOptions(symOptions & ~SYMOPT_IGNORE_CVREC);
|
||||
if(!SymLoadModuleExW(fdProcessInfo->hProcess, 0, wszModulePath, 0, (DWORD64)modbase, 0, 0, 0)) //load module
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "SymLoadModuleEx failed!"));
|
||||
SafeSymSetOptions(symOptions);
|
||||
SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
SafeSymSetOptions(symOptions);
|
||||
if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "SymSetSearchPathW (2) failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiSymbolRefreshCurrent();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Done! See symbol log for more information"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrImageinfo(int argc, char* argv[])
|
||||
{
|
||||
duint mod;
|
||||
if(argc < 2 || !valfromstring(argv[1], &mod) || !ModBaseFromAddr(mod))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "invalid argument"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
auto info = ModInfoFromAddr(mod);
|
||||
auto c = GetPE32DataFromMappedFile(info->fileMapVA, 0, UE_CHARACTERISTICS);
|
||||
auto dllc = GetPE32DataFromMappedFile(info->fileMapVA, 0, UE_DLLCHARACTERISTICS);
|
||||
SHARED_RELEASE();
|
||||
|
||||
auto pFlag = [](ULONG_PTR value, ULONG_PTR flag, const char* name)
|
||||
{
|
||||
if((value & flag) == flag)
|
||||
{
|
||||
dprintf(" ");
|
||||
dputs(name);
|
||||
}
|
||||
};
|
||||
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
ModNameFromAddr(mod, modname, true);
|
||||
|
||||
dputs_untranslated("---------------");
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Image information for %s\n"), modname);
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Characteristics (0x%X):\n"), c);
|
||||
if(!c)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", " None\n"));
|
||||
pFlag(c, IMAGE_FILE_RELOCS_STRIPPED, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_RELOCS_STRIPPED: Relocation info stripped from file."));
|
||||
pFlag(c, IMAGE_FILE_EXECUTABLE_IMAGE, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_EXECUTABLE_IMAGE: File is executable (i.e. no unresolved externel references)."));
|
||||
pFlag(c, IMAGE_FILE_LINE_NUMS_STRIPPED, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_LINE_NUMS_STRIPPED: Line numbers stripped from file."));
|
||||
pFlag(c, IMAGE_FILE_LOCAL_SYMS_STRIPPED, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_LOCAL_SYMS_STRIPPED: Local symbols stripped from file."));
|
||||
pFlag(c, IMAGE_FILE_AGGRESIVE_WS_TRIM, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_AGGRESIVE_WS_TRIM: Agressively trim working set"));
|
||||
pFlag(c, IMAGE_FILE_LARGE_ADDRESS_AWARE, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_LARGE_ADDRESS_AWARE: App can handle >2gb addresses"));
|
||||
pFlag(c, IMAGE_FILE_BYTES_REVERSED_LO, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_BYTES_REVERSED_LO: Bytes of machine word are reversed."));
|
||||
pFlag(c, IMAGE_FILE_32BIT_MACHINE, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_32BIT_MACHINE: 32 bit word machine."));
|
||||
pFlag(c, IMAGE_FILE_DEBUG_STRIPPED, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_DEBUG_STRIPPED: Debugging info stripped from file in .DBG file"));
|
||||
pFlag(c, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP: If Image is on removable media, copy and run from the swap file."));
|
||||
pFlag(c, IMAGE_FILE_NET_RUN_FROM_SWAP, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_NET_RUN_FROM_SWAP: If Image is on Net, copy and run from the swap file."));
|
||||
pFlag(c, IMAGE_FILE_SYSTEM, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_SYSTEM: System File."));
|
||||
pFlag(c, IMAGE_FILE_DLL, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_DLL: File is a DLL."));
|
||||
pFlag(c, IMAGE_FILE_UP_SYSTEM_ONLY, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_UP_SYSTEM_ONLY: File should only be run on a UP machine"));
|
||||
pFlag(c, IMAGE_FILE_BYTES_REVERSED_HI, QT_TRANSLATE_NOOP("DBG", "IMAGE_FILE_BYTES_REVERSED_HI: Bytes of machine word are reversed."));
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Characteristics (0x%X):\n"), dllc);
|
||||
if(!dllc)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", " None\n"));
|
||||
pFlag(dllc, IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE, QT_TRANSLATE_NOOP("DBG", "IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE: DLL can move."));
|
||||
pFlag(dllc, IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY, QT_TRANSLATE_NOOP("DBG", "IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY: Code Integrity Image"));
|
||||
pFlag(dllc, IMAGE_DLLCHARACTERISTICS_NX_COMPAT, QT_TRANSLATE_NOOP("DBG", "IMAGE_DLLCHARACTERISTICS_NX_COMPAT: Image is NX compatible"));
|
||||
pFlag(dllc, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION, QT_TRANSLATE_NOOP("DBG", "IMAGE_DLLCHARACTERISTICS_NO_ISOLATION: Image understands isolation and doesn't want it"));
|
||||
pFlag(dllc, IMAGE_DLLCHARACTERISTICS_NO_SEH, QT_TRANSLATE_NOOP("DBG", "IMAGE_DLLCHARACTERISTICS_NO_SEH: Image does not use SEH. No SE handler may reside in this image"));
|
||||
pFlag(dllc, IMAGE_DLLCHARACTERISTICS_NO_BIND, QT_TRANSLATE_NOOP("DBG", "IMAGE_DLLCHARACTERISTICS_NO_BIND: Do not bind this image."));
|
||||
pFlag(dllc, IMAGE_DLLCHARACTERISTICS_WDM_DRIVER, QT_TRANSLATE_NOOP("DBG", "IMAGE_DLLCHARACTERISTICS_WDM_DRIVER: Driver uses WDM model."));
|
||||
pFlag(dllc, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE, QT_TRANSLATE_NOOP("DBG", "IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE: Remote Desktop Services aware."));
|
||||
|
||||
dputs_untranslated("---------------");
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrGetRelocSize(int argc, char* argv[])
|
||||
{
|
||||
//Original tool "GetRelocSize" by Killboy/SND
|
||||
if(argc < 2)
|
||||
{
|
||||
_plugin_logputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
duint RelocDirAddr;
|
||||
if(!valfromstring(argv[1], &RelocDirAddr, false))
|
||||
return STATUS_ERROR;
|
||||
|
||||
duint RelocSize = 0;
|
||||
varset("$result", RelocSize, false);
|
||||
IMAGE_RELOCATION RelocDir;
|
||||
do
|
||||
{
|
||||
if(!MemRead(RelocDirAddr, &RelocDir, sizeof(IMAGE_RELOCATION)))
|
||||
{
|
||||
_plugin_logputs(QT_TRANSLATE_NOOP("DBG", "Invalid relocation table!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!RelocDir.SymbolTableIndex)
|
||||
break;
|
||||
RelocSize += RelocDir.SymbolTableIndex;
|
||||
RelocDirAddr += RelocDir.SymbolTableIndex;
|
||||
}
|
||||
while(RelocDir.VirtualAddress);
|
||||
|
||||
if(!RelocSize)
|
||||
{
|
||||
_plugin_logputs(QT_TRANSLATE_NOOP("DBG", "Invalid relocation table!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
varset("$result", RelocSize, false);
|
||||
_plugin_logprintf(QT_TRANSLATE_NOOP("DBG", "Relocation table size: %X\n"), RelocSize);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static void printExhandlers(const char* name, const std::vector<duint> & entries)
|
||||
{
|
||||
if(!entries.size())
|
||||
return;
|
||||
dprintf("%s:\n", name);
|
||||
for(auto entry : entries)
|
||||
{
|
||||
auto symbolic = SymGetSymbolicName(entry);
|
||||
if(symbolic.length())
|
||||
dprintf("%p %s\n", entry, symbolic.c_str());
|
||||
else
|
||||
dprintf("%p\n", entry);
|
||||
}
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrExhandlers(int argc, char* argv[])
|
||||
{
|
||||
std::vector<duint> entries;
|
||||
#ifndef _WIN64
|
||||
if(ExHandlerGetInfo(EX_HANDLER_SEH, entries))
|
||||
{
|
||||
std::vector<duint> handlers;
|
||||
for(auto entry : entries)
|
||||
{
|
||||
duint handler;
|
||||
if(MemRead(entry + sizeof(duint), &handler, sizeof(handler)))
|
||||
handlers.push_back(handler);
|
||||
}
|
||||
printExhandlers("StructuredExceptionHandler (SEH)", handlers);
|
||||
}
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to get SEH (disabled?)"));
|
||||
#endif //_WIN64
|
||||
|
||||
if(ExHandlerGetInfo(EX_HANDLER_VEH, entries))
|
||||
printExhandlers("VectoredExceptionHandler (VEH)", entries);
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to get VEH (loaded symbols for ntdll.dll?)"));
|
||||
|
||||
if(ExHandlerGetInfo(EX_HANDLER_VCH, entries))
|
||||
printExhandlers("VectoredContinueHandler (VCH)", entries);
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to get VCH (loaded symbols for ntdll.dll?)"));
|
||||
|
||||
if(ExHandlerGetInfo(EX_HANDLER_UNHANDLED, entries))
|
||||
printExhandlers("UnhandledExceptionFilter", entries);
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to get UnhandledExceptionFilter (loaded symbols for kernelbase.dll?)"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrExinfo(int argc, char* argv[])
|
||||
{
|
||||
auto info = getLastExceptionInfo();
|
||||
const auto & record = info.ExceptionRecord;
|
||||
dputs("EXCEPTION_DEBUG_INFO:");
|
||||
dprintf(" dwFirstChance: %X\n", info.dwFirstChance);
|
||||
auto exceptionName = ExceptionCodeToName(record.ExceptionCode);
|
||||
if(!exceptionName.size()) //if no exception was found, try the error codes (RPC_S_*)
|
||||
exceptionName = ErrorCodeToName(record.ExceptionCode);
|
||||
if(exceptionName.size())
|
||||
dprintf(" ExceptionCode: %08X (%s)\n", record.ExceptionCode, exceptionName.c_str());
|
||||
else
|
||||
dprintf(" ExceptionCode: %08X\n", record.ExceptionCode);
|
||||
dprintf(" ExceptionFlags: %08X\n", record.ExceptionFlags);
|
||||
auto symbolic = SymGetSymbolicName(duint(record.ExceptionAddress));
|
||||
if(symbolic.length())
|
||||
dprintf(" ExceptionAddress: %p %s\n", record.ExceptionAddress, symbolic.c_str());
|
||||
else
|
||||
dprintf(" ExceptionAddress: %p\n", record.ExceptionAddress);
|
||||
dprintf(" NumberParameters: %d\n", record.NumberParameters);
|
||||
if(record.NumberParameters)
|
||||
for(DWORD i = 0; i < record.NumberParameters; i++)
|
||||
{
|
||||
symbolic = SymGetSymbolicName(duint(record.ExceptionInformation[i]));
|
||||
if(symbolic.length())
|
||||
dprintf("ExceptionInformation[%02d]: %p %s\n", i, record.ExceptionInformation[i], symbolic.c_str());
|
||||
else
|
||||
dprintf("ExceptionInformation[%02d]: %p\n", i, record.ExceptionInformation[i]);
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrTraceexecute(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
_dbg_dbgtraceexecute(addr);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1 +1,468 @@
|
|||
#include "cmd-conditional-breakpoint-control.h"
|
||||
#include "cmd-conditional-breakpoint-control.h"
|
||||
#include "breakpoint.h"
|
||||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
#include "variable.h"
|
||||
#include "value.h"
|
||||
|
||||
static CMDRESULT cbDebugSetBPXTextCommon(BP_TYPE Type, int argc, char* argv[], const String & description, std::function<bool(duint, BP_TYPE, const char*)> setFunction)
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
char* value = "";
|
||||
if(argc > 2)
|
||||
value = argv[2];
|
||||
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "No such breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!setFunction(bp.addr, Type, value))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set %s on breakpoint \"%s\"\n"), description, argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXNameCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, String(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "breakpoint name"))), BpSetName);
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXConditionCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, String(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "break condition"))), BpSetBreakCondition);
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXLogCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, String(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "logging text"))), BpSetLogText);
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXLogConditionCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, String(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "logging condition"))), BpSetLogCondition);
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXCommandCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, String(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "command on hit"))), BpSetCommandText);
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXCommandConditionCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXTextCommon(Type, argc, argv, String(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "command condition"))), BpSetCommandCondition);
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXFastResumeCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "not enough arguments!\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
auto fastResume = true;
|
||||
if(argc > 2)
|
||||
{
|
||||
duint value;
|
||||
if(!valfromstring(argv[2], &value, false))
|
||||
return STATUS_ERROR;
|
||||
fastResume = value != 0;
|
||||
}
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "No such breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!BpSetFastResume(bp.addr, Type, fastResume))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set fast resume on breakpoint \"%1\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXSingleshootCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "not enough arguments!\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
auto singleshoot = true;
|
||||
if(argc > 2)
|
||||
{
|
||||
duint value;
|
||||
if(!valfromstring(argv[2], &value, false))
|
||||
return STATUS_ERROR;
|
||||
singleshoot = value != 0;
|
||||
}
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "No such breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!BpSetSingleshoot(bp.addr, Type, singleshoot))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set singleshoot on breakpoint \"%1\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugSetBPXSilentCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "not enough arguments!\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
auto silent = true;
|
||||
if(argc > 2)
|
||||
{
|
||||
duint value;
|
||||
if(!valfromstring(argv[2], &value, false))
|
||||
return STATUS_ERROR;
|
||||
silent = value != 0;
|
||||
}
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "No such breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!BpSetSilent(bp.addr, Type, silent))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set silent on breakpoint \"%1\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugGetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "not enough arguments!\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
BREAKPOINT bp;
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "No such breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
varset("$result", bp.hitcount, false);
|
||||
return STATUS_CONTINUE;
|
||||
|
||||
}
|
||||
|
||||
static CMDRESULT cbDebugResetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "not enough arguments!\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint value = 0;
|
||||
if(argc > 2)
|
||||
if(!valfromstring(argv[2], &value, false))
|
||||
return STATUS_ERROR;
|
||||
BREAKPOINT bp;
|
||||
if(!BpGetAny(Type, argv[1], &bp))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "No such breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!BpResetHitCount(bp.addr, Type, (uint32)value))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set hit count on breakpoint \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DebugUpdateBreakpointsViewAsync();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXName(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXNameCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXConditionCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXLog(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXLogCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogConditionCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXCommand(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXCommandCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandConditionCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXFastResume(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXFastResumeCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXSingleshoot(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSingleshootCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXSilent(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSilentCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetBPXHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugGetBPXHitCountCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResetBPXHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugResetBPXHitCountCommon(BPNORMAL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareName(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXNameCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXConditionCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareLog(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareLogCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogConditionCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareCommand(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareCommandCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandConditionCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareFastResume(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXFastResumeCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareSingleshoot(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSingleshootCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXHardwareSilent(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSilentCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetBPXHardwareHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugGetBPXHitCountCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResetBPXHardwareHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugResetBPXHitCountCommon(BPHARDWARE, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryName(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXNameCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXConditionCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryLog(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryLogCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogConditionCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryCommand(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryCommandCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandConditionCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemoryFastResume(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXFastResumeCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemorySingleshoot(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSingleshootCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXMemorySilent(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSilentCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetBPXMemoryHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugGetBPXHitCountCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResetBPXMemoryHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugResetBPXHitCountCommon(BPMEMORY, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLName(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXNameCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXConditionCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLLog(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLLogCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogConditionCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLCommand(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLCommandCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandConditionCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLFastResume(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXFastResumeCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLSingleshoot(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSingleshootCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXDLLSilent(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSilentCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetBPXDLLHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugGetBPXHitCountCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResetBPXDLLHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugResetBPXHitCountCommon(BPDLL, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionName(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXNameCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXConditionCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionLog(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionLogCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXLogConditionCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionCommand(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionCommandCondition(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXCommandConditionCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionFastResume(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXFastResumeCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionSingleshoot(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSingleshootCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetBPXExceptionSilent(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugSetBPXSilentCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetBPXExceptionHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugGetBPXHitCountCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResetBPXExceptionHitCount(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugResetBPXHitCountCommon(BPEXCEPTION, argc, argv);
|
||||
}
|
|
@ -1 +1,888 @@
|
|||
#include "cmd-data.h"
|
||||
#include "cmd-data.h"
|
||||
#include "memory.h"
|
||||
#include "value.h"
|
||||
#include "variable.h"
|
||||
#include "reference.h"
|
||||
#include "assemble.h"
|
||||
#include "debugger.h"
|
||||
#include "filehelper.h"
|
||||
#include "label.h"
|
||||
|
||||
static int maxFindResults = 5000;
|
||||
|
||||
CMDRESULT cbInstrFind(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
char pattern[deflen] = "";
|
||||
//remove # from the start and end of the pattern (ODBGScript support)
|
||||
if(argv[2][0] == '#')
|
||||
strcpy_s(pattern, argv[2] + 1);
|
||||
else
|
||||
strcpy_s(pattern, argv[2]);
|
||||
int len = (int)strlen(pattern);
|
||||
if(pattern[len - 1] == '#')
|
||||
pattern[len - 1] = '\0';
|
||||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(addr, &size, true);
|
||||
if(!base)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid memory address %p!\n"), addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
Memory<unsigned char*> data(size, "cbInstrFind:data");
|
||||
if(!MemRead(base, data(), size))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to read memory!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint start = addr - base;
|
||||
duint find_size = 0;
|
||||
if(argc >= 4)
|
||||
{
|
||||
if(!valfromstring(argv[3], &find_size))
|
||||
find_size = size - start;
|
||||
if(find_size > (size - start))
|
||||
find_size = size - start;
|
||||
}
|
||||
else
|
||||
find_size = size - start;
|
||||
duint foundoffset = patternfind(data() + start, find_size, pattern);
|
||||
duint result = 0;
|
||||
if(foundoffset != -1)
|
||||
result = addr + foundoffset;
|
||||
varset("$result", result, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFindAll(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
|
||||
char pattern[deflen] = "";
|
||||
//remove # from the start and end of the pattern (ODBGScript support)
|
||||
if(argv[2][0] == '#')
|
||||
strcpy_s(pattern, argv[2] + 1);
|
||||
else
|
||||
strcpy_s(pattern, argv[2]);
|
||||
int len = (int)strlen(pattern);
|
||||
if(pattern[len - 1] == '#')
|
||||
pattern[len - 1] = '\0';
|
||||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(addr, &size, true);
|
||||
if(!base)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid memory address %p!\n"), addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(argc >= 4)
|
||||
{
|
||||
duint usersize;
|
||||
if(valfromstring(argv[3], &usersize))
|
||||
size = usersize;
|
||||
}
|
||||
Memory<unsigned char*> data(size, "cbInstrFindAll:data");
|
||||
if(!MemRead(base, data(), size))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to read memory!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint start = addr - base;
|
||||
duint find_size = 0;
|
||||
bool findData = false;
|
||||
if(argc >= 4)
|
||||
{
|
||||
if(!_stricmp(argv[3], "&data&"))
|
||||
{
|
||||
find_size = size - start;
|
||||
findData = true;
|
||||
}
|
||||
else
|
||||
find_size = size - start;
|
||||
}
|
||||
else
|
||||
find_size = size - start;
|
||||
//setup reference view
|
||||
char patternshort[256] = "";
|
||||
strncpy_s(patternshort, pattern, min(16, len));
|
||||
if(len > 16)
|
||||
strcat_s(patternshort, "...");
|
||||
char patterntitle[256] = "";
|
||||
sprintf_s(patterntitle, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Pattern: %s")), patternshort);
|
||||
GuiReferenceInitialize(patterntitle);
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
if(findData)
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Data")));
|
||||
else
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
DWORD ticks = GetTickCount();
|
||||
int refCount = 0;
|
||||
duint i = 0;
|
||||
duint result = 0;
|
||||
std::vector<PatternByte> searchpattern;
|
||||
if(!patterntransform(pattern, searchpattern))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to transform pattern!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
while(refCount < maxFindResults)
|
||||
{
|
||||
duint foundoffset = patternfind(data() + start + i, find_size - i, searchpattern);
|
||||
if(foundoffset == -1)
|
||||
break;
|
||||
i += foundoffset + 1;
|
||||
result = addr + i - 1;
|
||||
char msg[deflen] = "";
|
||||
sprintf(msg, "%p", result);
|
||||
GuiReferenceSetRowCount(refCount + 1);
|
||||
GuiReferenceSetCellContent(refCount, 0, msg);
|
||||
if(findData)
|
||||
{
|
||||
Memory<unsigned char*> printData(searchpattern.size(), "cbInstrFindAll:printData");
|
||||
MemRead(result, printData(), printData.size());
|
||||
for(size_t j = 0, k = 0; j < printData.size(); j++)
|
||||
{
|
||||
if(j)
|
||||
k += sprintf(msg + k, " ");
|
||||
k += sprintf(msg + k, "%.2X", printData()[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!GuiGetDisassembly(result, msg))
|
||||
strcpy_s(msg, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "[Error disassembling]")));
|
||||
}
|
||||
GuiReferenceSetCellContent(refCount, 1, msg);
|
||||
result++;
|
||||
refCount++;
|
||||
}
|
||||
GuiReferenceReloadData();
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d occurrences found in %ums\n"), refCount, GetTickCount() - ticks);
|
||||
varset("$result", refCount, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFindAllMem(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
|
||||
char pattern[deflen] = "";
|
||||
//remove # from the start and end of the pattern (ODBGScript support)
|
||||
if(argv[2][0] == '#')
|
||||
strcpy_s(pattern, argv[2] + 1);
|
||||
else
|
||||
strcpy_s(pattern, argv[2]);
|
||||
int len = (int)strlen(pattern);
|
||||
if(pattern[len - 1] == '#')
|
||||
pattern[len - 1] = '\0';
|
||||
std::vector<PatternByte> searchpattern;
|
||||
if(!patterntransform(pattern, searchpattern))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to transform pattern!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
duint endAddr = -1;
|
||||
bool findData = false;
|
||||
if(argc >= 4)
|
||||
{
|
||||
if(!_stricmp(argv[3], "&data&"))
|
||||
findData = true;
|
||||
else if(!valfromstring(argv[3], &endAddr))
|
||||
findData = false;
|
||||
}
|
||||
|
||||
SHARED_ACQUIRE(LockMemoryPages);
|
||||
std::vector<SimplePage> searchPages;
|
||||
for(auto & itr : memoryPages)
|
||||
{
|
||||
if(itr.second.mbi.State != MEM_COMMIT)
|
||||
continue;
|
||||
SimplePage page(duint(itr.second.mbi.BaseAddress), itr.second.mbi.RegionSize);
|
||||
if(page.address >= addr && page.address + page.size <= endAddr)
|
||||
searchPages.push_back(page);
|
||||
}
|
||||
SHARED_RELEASE();
|
||||
|
||||
DWORD ticks = GetTickCount();
|
||||
|
||||
std::vector<duint> results;
|
||||
if(!MemFindInMap(searchPages, searchpattern, results, maxFindResults))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "MemFindInMap failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
//setup reference view
|
||||
char patternshort[256] = "";
|
||||
strncpy_s(patternshort, pattern, min(16, len));
|
||||
if(len > 16)
|
||||
strcat_s(patternshort, "...");
|
||||
char patterntitle[256] = "";
|
||||
sprintf_s(patterntitle, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Pattern: %s")), patternshort);
|
||||
GuiReferenceInitialize(patterntitle);
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
if(findData)
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Data")));
|
||||
else
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
|
||||
int refCount = 0;
|
||||
for(duint result : results)
|
||||
{
|
||||
char msg[deflen] = "";
|
||||
sprintf(msg, "%p", result);
|
||||
GuiReferenceSetRowCount(refCount + 1);
|
||||
GuiReferenceSetCellContent(refCount, 0, msg);
|
||||
if(findData)
|
||||
{
|
||||
Memory<unsigned char*> printData(searchpattern.size(), "cbInstrFindAll:printData");
|
||||
MemRead(result, printData(), printData.size());
|
||||
for(size_t j = 0, k = 0; j < printData.size(); j++)
|
||||
{
|
||||
if(j)
|
||||
k += sprintf(msg + k, " ");
|
||||
k += sprintf(msg + k, "%.2X", printData()[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!GuiGetDisassembly(result, msg))
|
||||
strcpy_s(msg, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "[Error disassembling]")));
|
||||
}
|
||||
GuiReferenceSetCellContent(refCount, 1, msg);
|
||||
refCount++;
|
||||
}
|
||||
|
||||
GuiReferenceReloadData();
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d occurrences found in %ums\n"), refCount, GetTickCount() - ticks);
|
||||
varset("$result", refCount, false);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static bool cbFindAsm(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
|
||||
{
|
||||
if(!disasm || !basicinfo) //initialize
|
||||
{
|
||||
GuiReferenceInitialize(refinfo->name);
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
return true;
|
||||
}
|
||||
const char* instruction = (const char*)refinfo->userinfo;
|
||||
bool found = !_stricmp(instruction, basicinfo->instruction);
|
||||
if(found)
|
||||
{
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", disasm->Address());
|
||||
GuiReferenceSetRowCount(refinfo->refcount + 1);
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 0, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly((duint)disasm->Address(), disassembly))
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly);
|
||||
else
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str());
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFindAsm(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
|
||||
duint addr = 0;
|
||||
if(argc < 3 || !valfromstring(argv[2], &addr))
|
||||
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
duint size = 0;
|
||||
if(argc >= 4)
|
||||
if(!valfromstring(argv[3], &size))
|
||||
size = 0;
|
||||
|
||||
duint refFindType = CURRENT_REGION;
|
||||
if(argc >= 5 && valfromstring(argv[4], &refFindType, true))
|
||||
if(refFindType != CURRENT_REGION && refFindType != CURRENT_MODULE && refFindType != ALL_MODULES)
|
||||
refFindType = CURRENT_REGION;
|
||||
|
||||
unsigned char dest[16];
|
||||
int asmsize = 0;
|
||||
char error[MAX_ERROR_SIZE] = "";
|
||||
if(!assemble(addr + size / 2, dest, &asmsize, argv[1], error))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to assemble \"%s\" (%s)!\n"), argv[1], error);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
BASIC_INSTRUCTION_INFO basicinfo;
|
||||
memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO));
|
||||
disasmfast(dest, addr + size / 2, &basicinfo);
|
||||
|
||||
duint ticks = GetTickCount();
|
||||
char title[256] = "";
|
||||
sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Command: \"%s\"")), basicinfo.instruction);
|
||||
int found = RefFind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false, title, (REFFINDTYPE)refFindType, true);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%u result(s) in %ums\n"), found, GetTickCount() - ticks);
|
||||
varset("$result", found, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrRefFind(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
std::string newCommand = std::string("reffindrange ") + argv[1] + std::string(",") + argv[1];
|
||||
if(argc > 2)
|
||||
newCommand += std::string(",") + argv[2];
|
||||
if(argc > 3)
|
||||
newCommand += std::string(",") + argv[3];
|
||||
if(argc > 4)
|
||||
newCommand += std::string(",") + argv[4];
|
||||
return cmddirectexec(newCommand.c_str());
|
||||
}
|
||||
|
||||
struct VALUERANGE
|
||||
{
|
||||
duint start;
|
||||
duint end;
|
||||
};
|
||||
|
||||
static bool cbRefFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
|
||||
{
|
||||
if(!disasm || !basicinfo) //initialize
|
||||
{
|
||||
GuiReferenceInitialize(refinfo->name);
|
||||
GuiReferenceAddColumn(sizeof(duint) * 2, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(10, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
return true;
|
||||
}
|
||||
bool found = false;
|
||||
VALUERANGE* range = (VALUERANGE*)refinfo->userinfo;
|
||||
duint start = range->start;
|
||||
duint end = range->end;
|
||||
if((basicinfo->type & TYPE_VALUE) == TYPE_VALUE)
|
||||
{
|
||||
duint value = basicinfo->value.value;
|
||||
if(value >= start && value <= end)
|
||||
found = true;
|
||||
}
|
||||
if((basicinfo->type & TYPE_MEMORY) == TYPE_MEMORY)
|
||||
{
|
||||
duint value = basicinfo->memory.value;
|
||||
if(value >= start && value <= end)
|
||||
found = true;
|
||||
}
|
||||
if((basicinfo->type & TYPE_ADDR) == TYPE_ADDR)
|
||||
{
|
||||
duint value = basicinfo->addr;
|
||||
if(value >= start && value <= end)
|
||||
found = true;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", disasm->Address());
|
||||
GuiReferenceSetRowCount(refinfo->refcount + 1);
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 0, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly((duint)disasm->Address(), disassembly))
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly);
|
||||
else
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str());
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrRefFindRange(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
VALUERANGE range;
|
||||
if(!valfromstring(argv[1], &range.start, false))
|
||||
return STATUS_ERROR;
|
||||
if(argc < 3 || !valfromstring(argv[2], &range.end, false))
|
||||
range.end = range.start;
|
||||
duint addr = 0;
|
||||
if(argc < 4 || !valfromstring(argv[3], &addr))
|
||||
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
duint size = 0;
|
||||
if(argc >= 5)
|
||||
if(!valfromstring(argv[4], &size))
|
||||
size = 0;
|
||||
duint ticks = GetTickCount();
|
||||
char title[256] = "";
|
||||
if(range.start == range.end)
|
||||
sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Constant: %p")), range.start);
|
||||
else
|
||||
sprintf_s(title, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Range: %p-%p")), range.start, range.end);
|
||||
|
||||
duint refFindType = CURRENT_REGION;
|
||||
if(argc >= 6 && valfromstring(argv[5], &refFindType, true))
|
||||
if(refFindType != CURRENT_REGION && refFindType != CURRENT_MODULE && refFindType != ALL_MODULES)
|
||||
refFindType = CURRENT_REGION;
|
||||
|
||||
int found = RefFind(addr, size, cbRefFind, &range, false, title, (REFFINDTYPE)refFindType, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%u reference(s) in %ums\n"), found, GetTickCount() - ticks);
|
||||
varset("$result", found, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static bool cbRefStr(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
|
||||
{
|
||||
if(!disasm || !basicinfo) //initialize
|
||||
{
|
||||
GuiReferenceInitialize(refinfo->name);
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(64, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceAddColumn(500, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "String")));
|
||||
GuiReferenceSetSearchStartCol(2); //only search the strings
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
return true;
|
||||
}
|
||||
bool found = false;
|
||||
char string[MAX_STRING_SIZE] = "";
|
||||
if(basicinfo->branch) //branches have no strings (jmp dword [401000])
|
||||
return false;
|
||||
if((basicinfo->type & TYPE_VALUE) == TYPE_VALUE)
|
||||
{
|
||||
if(DbgGetStringAt(basicinfo->value.value, string))
|
||||
found = true;
|
||||
}
|
||||
if((basicinfo->type & TYPE_MEMORY) == TYPE_MEMORY)
|
||||
{
|
||||
if(DbgGetStringAt(basicinfo->memory.value, string))
|
||||
found = true;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", disasm->Address());
|
||||
GuiReferenceSetRowCount(refinfo->refcount + 1);
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 0, addrText);
|
||||
char disassembly[4096] = "";
|
||||
if(GuiGetDisassembly((duint)disasm->Address(), disassembly))
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly);
|
||||
else
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str());
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 2, string);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrRefStr(int argc, char* argv[])
|
||||
{
|
||||
duint ticks = GetTickCount();
|
||||
duint addr;
|
||||
duint size = 0;
|
||||
String TranslatedString;
|
||||
|
||||
// If not specified, assume CURRENT_REGION by default
|
||||
if(argc < 2 || !valfromstring(argv[1], &addr, true))
|
||||
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
if(argc >= 3)
|
||||
if(!valfromstring(argv[2], &size, true))
|
||||
size = 0;
|
||||
|
||||
duint refFindType = CURRENT_REGION;
|
||||
if(argc >= 4 && valfromstring(argv[3], &refFindType, true))
|
||||
if(refFindType != CURRENT_REGION && refFindType != CURRENT_MODULE && refFindType != ALL_MODULES)
|
||||
refFindType = CURRENT_REGION;
|
||||
|
||||
TranslatedString = GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Strings"));
|
||||
int found = RefFind(addr, size, cbRefStr, 0, false, TranslatedString.c_str(), (REFFINDTYPE)refFindType, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%u string(s) in %ums\n"), found, GetTickCount() - ticks);
|
||||
varset("$result", found, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static bool cbModCallFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
|
||||
{
|
||||
if(!disasm || !basicinfo) //initialize
|
||||
{
|
||||
GuiReferenceInitialize(refinfo->name);
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(20, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceAddColumn(MAX_LABEL_SIZE, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Destination")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
return true;
|
||||
}
|
||||
bool found = false;
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
if(basicinfo->call) //we are looking for calls
|
||||
{
|
||||
duint ptr = basicinfo->addr > 0 ? basicinfo->addr : basicinfo->memory.value;
|
||||
found = DbgGetLabelAt(ptr, SEG_DEFAULT, label) && !LabelGet(ptr, label) && !strstr(label, "sub_") && DbgGetModuleAt(ptr, module); //a non-user label
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
char addrText[20] = "";
|
||||
char moduleTargetText[256] = "";
|
||||
sprintf(addrText, "%p", disasm->Address());
|
||||
sprintf(moduleTargetText, "%s.%s", module, label);
|
||||
GuiReferenceSetRowCount(refinfo->refcount + 1);
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 0, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly((duint)disasm->Address(), disassembly))
|
||||
{
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly);
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 2, moduleTargetText);
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str());
|
||||
GuiReferenceSetCellContent(refinfo->refcount, 2, moduleTargetText);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrModCallFind(int argc, char* argv[])
|
||||
{
|
||||
duint addr;
|
||||
if(argc < 2 || !valfromstring(argv[1], &addr, true))
|
||||
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
duint size = 0;
|
||||
if(argc >= 3)
|
||||
if(!valfromstring(argv[2], &size, true))
|
||||
size = 0;
|
||||
|
||||
duint refFindType = CURRENT_REGION;
|
||||
if(argc >= 4 && valfromstring(argv[3], &refFindType, true))
|
||||
if(refFindType != CURRENT_REGION && refFindType != CURRENT_MODULE && refFindType != ALL_MODULES)
|
||||
refFindType = CURRENT_REGION;
|
||||
|
||||
duint ticks = GetTickCount();
|
||||
String Calls = GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Calls"));
|
||||
int found = RefFind(addr, size, cbModCallFind, 0, false, Calls.c_str(), (REFFINDTYPE)refFindType, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%u call(s) in %ums\n"), found, GetTickCount() - ticks);
|
||||
varset("$result", found, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static void yaraCompilerCallback(int error_level, const char* file_name, int line_number, const char* message, void* user_data)
|
||||
{
|
||||
switch(error_level)
|
||||
{
|
||||
case YARA_ERROR_LEVEL_ERROR:
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "[YARA ERROR] "));
|
||||
break;
|
||||
case YARA_ERROR_LEVEL_WARNING:
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "[YARA WARNING] "));
|
||||
break;
|
||||
}
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "File: \"%s\", Line: %d, Message: \"%s\"\n"), file_name, line_number, message);
|
||||
}
|
||||
|
||||
static String yara_print_string(const uint8_t* data, int length)
|
||||
{
|
||||
String result = "\"";
|
||||
const char* str = (const char*)data;
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
char cur[16] = "";
|
||||
if(str[i] >= 32 && str[i] <= 126)
|
||||
sprintf_s(cur, "%c", str[i]);
|
||||
else
|
||||
sprintf_s(cur, "\\x%02X", (uint8_t)str[i]);
|
||||
result += cur;
|
||||
}
|
||||
result += "\"";
|
||||
return result;
|
||||
}
|
||||
|
||||
static String yara_print_hex_string(const uint8_t* data, int length)
|
||||
{
|
||||
String result = "";
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(i)
|
||||
result += " ";
|
||||
char cur[16] = "";
|
||||
sprintf_s(cur, "%02X", (uint8_t)data[i]);
|
||||
result += cur;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct YaraScanInfo
|
||||
{
|
||||
duint base;
|
||||
int index;
|
||||
bool rawFile;
|
||||
const char* modname;
|
||||
bool debug;
|
||||
|
||||
YaraScanInfo(duint base, bool rawFile, const char* modname, bool debug)
|
||||
: base(base), index(0), rawFile(rawFile), modname(modname), debug(debug)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static int yaraScanCallback(int message, void* message_data, void* user_data)
|
||||
{
|
||||
YaraScanInfo* scanInfo = (YaraScanInfo*)user_data;
|
||||
bool debug = scanInfo->debug;
|
||||
switch(message)
|
||||
{
|
||||
case CALLBACK_MSG_RULE_MATCHING:
|
||||
{
|
||||
duint base = scanInfo->base;
|
||||
YR_RULE* yrRule = (YR_RULE*)message_data;
|
||||
auto addReference = [scanInfo, yrRule](duint addr, const char* identifier, const std::string & pattern)
|
||||
{
|
||||
auto index = scanInfo->index;
|
||||
GuiReferenceSetRowCount(index + 1);
|
||||
scanInfo->index++;
|
||||
|
||||
char addr_text[deflen] = "";
|
||||
sprintf(addr_text, "%p", addr);
|
||||
GuiReferenceSetCellContent(index, 0, addr_text); //Address
|
||||
String ruleFullName = "";
|
||||
ruleFullName += yrRule->identifier;
|
||||
if(identifier)
|
||||
{
|
||||
ruleFullName += ".";
|
||||
ruleFullName += identifier;
|
||||
}
|
||||
GuiReferenceSetCellContent(index, 1, ruleFullName.c_str()); //Rule
|
||||
GuiReferenceSetCellContent(index, 2, pattern.c_str()); //Data
|
||||
};
|
||||
|
||||
if(STRING_IS_NULL(yrRule->strings))
|
||||
{
|
||||
if(debug)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "[YARA] Global rule \"%s\' matched!\n"), yrRule->identifier);
|
||||
addReference(base, nullptr, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(debug)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "[YARA] Rule \"%s\" matched:\n"), yrRule->identifier);
|
||||
YR_STRING* string;
|
||||
yr_rule_strings_foreach(yrRule, string)
|
||||
{
|
||||
YR_MATCH* match;
|
||||
yr_string_matches_foreach(string, match)
|
||||
{
|
||||
String pattern;
|
||||
if(STRING_IS_HEX(string))
|
||||
pattern = yara_print_hex_string(match->data, match->match_length);
|
||||
else
|
||||
pattern = yara_print_string(match->data, match->match_length);
|
||||
auto offset = duint(match->base + match->offset);
|
||||
duint addr;
|
||||
if(scanInfo->rawFile) //convert raw offset to virtual offset
|
||||
addr = valfileoffsettova(scanInfo->modname, offset);
|
||||
else
|
||||
addr = base + offset;
|
||||
|
||||
if(debug)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "[YARA] String \"%s\" : %s on %p\n"), string->identifier, pattern.c_str(), addr);
|
||||
|
||||
addReference(addr, string->identifier, pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CALLBACK_MSG_RULE_NOT_MATCHING:
|
||||
{
|
||||
YR_RULE* yrRule = (YR_RULE*)message_data;
|
||||
if(debug)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "[YARA] Rule \"%s\" did not match!\n"), yrRule->identifier);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALLBACK_MSG_SCAN_FINISHED:
|
||||
{
|
||||
if(debug)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "[YARA] Scan finished!"));
|
||||
}
|
||||
break;
|
||||
|
||||
case CALLBACK_MSG_IMPORT_MODULE:
|
||||
{
|
||||
YR_MODULE_IMPORT* yrModuleImport = (YR_MODULE_IMPORT*)message_data;
|
||||
if(debug)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "[YARA] Imported module \"%s\"!\n"), yrModuleImport->module_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ERROR_SUCCESS; //nicely undocumented what this should be
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrYara(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
SELECTIONDATA sel;
|
||||
GuiSelectionGet(GUI_DISASSEMBLY, &sel);
|
||||
addr = sel.start;
|
||||
|
||||
duint base = 0;
|
||||
duint size = 0;
|
||||
duint mod = ModBaseFromName(argv[2]);
|
||||
bool rawFile = false;
|
||||
if(mod)
|
||||
{
|
||||
base = mod;
|
||||
size = ModSizeFromAddr(base);
|
||||
rawFile = argc > 3 && *argv[3] == '1';
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!valfromstring(argv[2], &addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid value \"%s\"!\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
if(argc >= 4)
|
||||
if(!valfromstring(argv[3], &size))
|
||||
size = 0;
|
||||
if(!size)
|
||||
addr = MemFindBaseAddr(addr, &size);
|
||||
base = addr;
|
||||
}
|
||||
std::vector<unsigned char> rawFileData;
|
||||
if(rawFile) //read the file from disk
|
||||
{
|
||||
char modPath[MAX_PATH] = "";
|
||||
if(!ModPathFromAddr(base, modPath, MAX_PATH))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to get module path for %p!\n"), base);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!FileHelper::ReadAllData(modPath, rawFileData))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to read file \"%s\"!\n"), modPath);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
size = rawFileData.size();
|
||||
}
|
||||
Memory<uint8_t*> data(size);
|
||||
if(rawFile)
|
||||
memcpy(data(), rawFileData.data(), size);
|
||||
else if(!MemRead(base, data(), size))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to read memory page %p[%X]!\n"), base, size);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
String rulesContent;
|
||||
if(!FileHelper::ReadAllText(argv[1], rulesContent))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to read the rules file \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
bool bSuccess = false;
|
||||
YR_COMPILER* yrCompiler;
|
||||
if(yr_compiler_create(&yrCompiler) == ERROR_SUCCESS)
|
||||
{
|
||||
yr_compiler_set_callback(yrCompiler, yaraCompilerCallback, 0);
|
||||
if(yr_compiler_add_string(yrCompiler, rulesContent.c_str(), nullptr) == 0) //no errors found
|
||||
{
|
||||
YR_RULES* yrRules;
|
||||
if(yr_compiler_get_rules(yrCompiler, &yrRules) == ERROR_SUCCESS)
|
||||
{
|
||||
//initialize new reference tab
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
if(!ModNameFromAddr(base, modname, true))
|
||||
sprintf_s(modname, "%p", base);
|
||||
String fullName;
|
||||
const char* fileName = strrchr(argv[1], '\\');
|
||||
if(fileName)
|
||||
fullName = fileName + 1;
|
||||
else
|
||||
fullName = argv[1];
|
||||
fullName += " (";
|
||||
fullName += modname;
|
||||
fullName += ")"; //nanana, very ugly code (long live open source)
|
||||
GuiReferenceInitialize(fullName.c_str());
|
||||
GuiReferenceAddColumn(sizeof(duint) * 2, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(48, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Rule")));
|
||||
GuiReferenceAddColumn(10, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Data")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
YaraScanInfo scanInfo(base, rawFile, argv[2], settingboolget("Engine", "YaraDebug"));
|
||||
duint ticks = GetTickCount();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "[YARA] Scan started..."));
|
||||
int err = yr_rules_scan_mem(yrRules, data(), size, 0, yaraScanCallback, &scanInfo, 0);
|
||||
GuiReferenceReloadData();
|
||||
switch(err)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%u scan results in %ums...\n"), scanInfo.index, GetTickCount() - ticks);
|
||||
bSuccess = true;
|
||||
break;
|
||||
case ERROR_TOO_MANY_MATCHES:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "too many matches!"));
|
||||
break;
|
||||
default:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "error while scanning memory!"));
|
||||
break;
|
||||
}
|
||||
yr_rules_destroy(yrRules);
|
||||
}
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "error while getting the rules!"));
|
||||
}
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "errors in the rules file!"));
|
||||
yr_compiler_destroy(yrCompiler);
|
||||
}
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "yr_compiler_create failed!"));
|
||||
return bSuccess ? STATUS_CONTINUE : STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrYaramod(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
if(!ModBaseFromName(argv[2]))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid module \"%s\"!\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return cmddirectexec(StringUtils::sprintf("yara \"%s\",\"%s\",%s", argv[1], argv[2], argc > 3 && *argv[3] == '1' ? "1" : "0").c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrSetMaxFindResult(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint num;
|
||||
if(!valfromstring(argv[1], &num))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid expression: \"%s\""), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
maxFindResults = int(num & 0x7FFFFFFF);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,384 @@
|
|||
#include "cmd-debug-control.h"
|
||||
#include "cmd-debug-control.h"
|
||||
#include "console.h"
|
||||
#include "debugger.h"
|
||||
#include "animate.h"
|
||||
#include "historycontext.h"
|
||||
#include "threading.h"
|
||||
#include "memory.h"
|
||||
#include "disasm_fast.h"
|
||||
#include "plugin_loader.h"
|
||||
#include "value.h"
|
||||
|
||||
CMDRESULT cbDebugRunInternal(int argc, char* argv[])
|
||||
{
|
||||
// Don't "run" twice if the program is already running
|
||||
if(dbgisrunning())
|
||||
return STATUS_ERROR;
|
||||
dbgsetispausedbyuser(false);
|
||||
GuiSetDebugStateAsync(running);
|
||||
unlock(WAITID_RUN);
|
||||
PLUG_CB_RESUMEDEBUG callbackInfo;
|
||||
callbackInfo.reserved = 0;
|
||||
plugincbcall(CB_RESUMEDEBUG, &callbackInfo);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugInit(int argc, char* argv[])
|
||||
{
|
||||
cbDebugStop(argc, argv);
|
||||
|
||||
static char arg1[deflen] = "";
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "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)))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Resolved shortcut \"%s\"->\"%s\"\n"), arg1, szResolvedPath);
|
||||
strcpy_s(arg1, szResolvedPath);
|
||||
}
|
||||
if(!FileExists(arg1))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "File does not exist!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(arg1).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Could not open file!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GetFileNameFromHandle(hFile, arg1); //get full path of the file
|
||||
hFile.Close();
|
||||
|
||||
//do some basic checks
|
||||
switch(GetFileArchitecture(arg1))
|
||||
{
|
||||
case invalid:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Invalid PE file!"));
|
||||
return STATUS_ERROR;
|
||||
#ifdef _WIN64
|
||||
case x32:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Use x32dbg to debug this file!"));
|
||||
#else //x86
|
||||
case x64:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Use x64dbg to debug this file!"));
|
||||
#endif //_WIN64
|
||||
return STATUS_ERROR;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
static char arg2[deflen] = "";
|
||||
if(argc > 2)
|
||||
strcpy_s(arg2, argv[2]);
|
||||
char* commandline = 0;
|
||||
if(strlen(arg2))
|
||||
commandline = arg2;
|
||||
|
||||
char arg3[deflen] = "";
|
||||
if(argc > 3)
|
||||
strcpy_s(arg3, argv[3]);
|
||||
|
||||
static char currentfolder[deflen] = "";
|
||||
strcpy_s(currentfolder, arg1);
|
||||
int len = (int)strlen(currentfolder);
|
||||
while(currentfolder[len] != '\\' && len != 0)
|
||||
len--;
|
||||
currentfolder[len] = 0;
|
||||
|
||||
if(DirExists(arg3))
|
||||
strcpy_s(currentfolder, arg3);
|
||||
|
||||
static INIT_STRUCT init;
|
||||
memset(&init, 0, sizeof(INIT_STRUCT));
|
||||
init.exe = arg1;
|
||||
init.commandline = commandline;
|
||||
if(*currentfolder)
|
||||
init.currentfolder = currentfolder;
|
||||
CloseHandle(CreateThread(0, 0, threadDebugLoop, &init, 0, 0));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugStop(int argc, char* argv[])
|
||||
{
|
||||
// HACK: TODO: Don't kill script on debugger ending a process
|
||||
//scriptreset(); //reset the currently-loaded script
|
||||
_dbg_animatestop();
|
||||
StopDebug();
|
||||
//history
|
||||
HistoryClear();
|
||||
DWORD BeginTick = GetTickCount();
|
||||
while(waitislocked(WAITID_STOP)) //custom waiting
|
||||
{
|
||||
unlock(WAITID_RUN);
|
||||
Sleep(100);
|
||||
DWORD CurrentTick = GetTickCount();
|
||||
if(CurrentTick - BeginTick > 10000)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "The debuggee does not stop after 10 seconds. The debugger state may be corrupted."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(CurrentTick - BeginTick >= 300)
|
||||
TerminateProcess(fdProcessInfo->hProcess, -1);
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugAttach(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint pid = 0;
|
||||
if(!valfromstring(argv[1], &pid, false))
|
||||
return STATUS_ERROR;
|
||||
if(argc > 2)
|
||||
{
|
||||
duint eventHandle = 0;
|
||||
if(!valfromstring(argv[2], &eventHandle, false))
|
||||
return STATUS_ERROR;
|
||||
dbgsetattachevent((HANDLE)eventHandle);
|
||||
}
|
||||
if(DbgIsDebugging())
|
||||
DbgCmdExecDirect("stop");
|
||||
Handle hProcess = TitanOpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid);
|
||||
if(!hProcess)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not open process %X!\n"), pid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
BOOL wow64 = false, mewow64 = false;
|
||||
if(!IsWow64Process(hProcess, &wow64) || !IsWow64Process(GetCurrentProcess(), &mewow64))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "IsWow64Process failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if((mewow64 && !wow64) || (!mewow64 && wow64))
|
||||
{
|
||||
#ifdef _WIN64
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Use x32dbg to debug this process!"));
|
||||
#else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Use x64dbg to debug this process!"));
|
||||
#endif // _WIN64
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
wchar_t wszFileName[MAX_PATH] = L"";
|
||||
if(!GetModuleFileNameExW(hProcess, 0, wszFileName, MAX_PATH))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not get module filename %X!\n"), pid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
strcpy_s(szFileName, StringUtils::Utf16ToUtf8(wszFileName).c_str());
|
||||
CloseHandle(CreateThread(0, 0, threadAttachLoop, (void*)pid, 0, 0));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugDetach(int argc, char* argv[])
|
||||
{
|
||||
unlock(WAITID_RUN); //run
|
||||
dbgsetisdetachedbyuser(true); //detach when paused
|
||||
StepInto((void*)cbDetach);
|
||||
DebugBreakProcess(fdProcessInfo->hProcess);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugRun(int argc, char* argv[])
|
||||
{
|
||||
HistoryClear();
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugErun(int argc, char* argv[])
|
||||
{
|
||||
HistoryClear();
|
||||
if(!dbgisrunning())
|
||||
dbgsetskipexceptions(true);
|
||||
else
|
||||
{
|
||||
dbgsetskipexceptions(false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSerun(int argc, char* argv[])
|
||||
{
|
||||
cbDebugContinue(argc, argv);
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugPause(int argc, char* argv[])
|
||||
{
|
||||
if(_dbg_isanimating())
|
||||
{
|
||||
_dbg_animatestop(); // pause when animating
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!DbgIsDebugging())
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not debugging!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!dbgisrunning())
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Program is not running"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(SuspendThread(hActiveThread) == -1)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error suspending thread"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint CIP = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
if(!SetBPX(CIP, UE_BREAKPOINT, (void*)cbPauseBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error setting breakpoint at %p! (SetBPX)\n"), CIP);
|
||||
if(ResumeThread(hActiveThread) == -1)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error resuming thread"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dbgsetispausedbyuser(true);
|
||||
if(ResumeThread(hActiveThread) == -1)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error resuming thread"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugContinue(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
SetNextDbgContinueStatus(DBG_CONTINUE);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Exception will be swallowed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextDbgContinueStatus(DBG_EXCEPTION_NOT_HANDLED);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Exception will be thrown in the program"));
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static bool skipInt3Stepping(int argc, char* argv[])
|
||||
{
|
||||
if(!bSkipInt3Stepping || dbgisrunning())
|
||||
return false;
|
||||
duint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
unsigned char ch;
|
||||
MemRead(cip, &ch, sizeof(ch));
|
||||
if(ch == 0xCC && getLastExceptionInfo().ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Skipped INT3!"));
|
||||
cbDebugSkip(argc, argv);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugStepInto(int argc, char* argv[])
|
||||
{
|
||||
if(skipInt3Stepping(argc, argv))
|
||||
return STATUS_CONTINUE;
|
||||
StepInto((void*)cbStep);
|
||||
// History
|
||||
HistoryAdd();
|
||||
dbgsetstepping(true);
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugeStepInto(int argc, char* argv[])
|
||||
{
|
||||
dbgsetskipexceptions(true);
|
||||
return cbDebugStepInto(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugseStepInto(int argc, char* argv[])
|
||||
{
|
||||
cbDebugContinue(argc, argv);
|
||||
return cbDebugStepInto(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugStepOver(int argc, char* argv[])
|
||||
{
|
||||
if(skipInt3Stepping(argc, argv))
|
||||
return STATUS_CONTINUE;
|
||||
StepOver((void*)cbStep);
|
||||
// History
|
||||
HistoryClear();
|
||||
dbgsetstepping(true);
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugeStepOver(int argc, char* argv[])
|
||||
{
|
||||
dbgsetskipexceptions(true);
|
||||
return cbDebugStepOver(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugseStepOver(int argc, char* argv[])
|
||||
{
|
||||
cbDebugContinue(argc, argv);
|
||||
return cbDebugStepOver(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSingleStep(int argc, char* argv[])
|
||||
{
|
||||
duint stepcount = 1;
|
||||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &stepcount))
|
||||
stepcount = 1;
|
||||
SingleStep((DWORD)stepcount, (void*)cbStep);
|
||||
HistoryClear();
|
||||
dbgsetstepping(true);
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugeSingleStep(int argc, char* argv[])
|
||||
{
|
||||
dbgsetskipexceptions(true);
|
||||
return cbDebugSingleStep(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugStepOut(int argc, char* argv[])
|
||||
{
|
||||
HistoryClear();
|
||||
StepOver((void*)cbRtrStep);
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugeStepOut(int argc, char* argv[])
|
||||
{
|
||||
dbgsetskipexceptions(true);
|
||||
return cbDebugStepOut(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSkip(int argc, char* argv[])
|
||||
{
|
||||
SetNextDbgContinueStatus(DBG_CONTINUE); //swallow the exception
|
||||
duint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
BASIC_INSTRUCTION_INFO basicinfo;
|
||||
memset(&basicinfo, 0, sizeof(basicinfo));
|
||||
disasmfast(cip, &basicinfo);
|
||||
cip += basicinfo.size;
|
||||
SetContextDataEx(hActiveThread, UE_CIP, cip);
|
||||
DebugUpdateGuiAsync(cip, false); //update GUI
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrInstrUndo(int argc, char* argv[])
|
||||
{
|
||||
HistoryRestore();
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "command.h"
|
||||
|
||||
CMDRESULT cbDebugRunInternal(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugInit(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugStop(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugAttach(int argc, char* argv[]);
|
||||
|
|
|
@ -1 +1,394 @@
|
|||
#include "cmd-general-purpose.h"
|
||||
#include "cmd-general-purpose.h"
|
||||
#include "value.h"
|
||||
#include "memory.h"
|
||||
#include "variable.h"
|
||||
#include "_scriptapi_stack.h"
|
||||
#include "debugger.h"
|
||||
|
||||
static CMDRESULT ReadWriteVariable(const char* varname, std::function<CMDRESULT(duint*, int)> callback)
|
||||
{
|
||||
duint set_value = 0;
|
||||
bool isvar;
|
||||
int varsize;
|
||||
if(!valfromstring(varname, &set_value, true, true, &varsize, &isvar))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid variable \"%s\"\n"), varname);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
CMDRESULT retVal = callback(&set_value, varsize);
|
||||
if(retVal != STATUS_CONTINUE)
|
||||
return retVal;
|
||||
duint temp = 0;
|
||||
valfromstring(varname, &temp, true, true, 0, nullptr, 0); //there is no return check on this because the destination might not exist yet
|
||||
if(!isvar)
|
||||
isvar = vargettype(varname, 0);
|
||||
if(!isvar || !valtostring(varname, set_value, true))
|
||||
{
|
||||
duint value;
|
||||
if(valfromstring(varname, &value)) //if the var is a value already it's an invalid destination
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid variable \"%s\"\n"), varname);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
varnew(varname, set_value, VAR_USER);
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrInc(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s++", argv[1]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDec(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s--", argv[1]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAdd(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s+=%s", argv[1], argv[2]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrSub(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s-=%s", argv[1], argv[2]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrMul(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s*=%s", argv[1], argv[2]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDiv(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s/=%s", argv[1], argv[2]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAnd(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s&=%s", argv[1], argv[2]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrOr(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s|=%s", argv[1], argv[2]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrXor(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s^=%s", argv[1], argv[2]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrNeg(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s=-%s", argv[1], argv[1]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrNot(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
return cmddirectexec(StringUtils::sprintf("%s=~%s", argv[1], argv[1]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrBswap(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
return ReadWriteVariable(argv[1], [argv](duint * value, int size)
|
||||
{
|
||||
if(size == 1)
|
||||
*value = *value;
|
||||
else if(size == 2)
|
||||
*value = _byteswap_ushort((uint16) * value);
|
||||
else if(size == 4)
|
||||
*value = _byteswap_ulong((uint32) * value);
|
||||
#ifdef _WIN64
|
||||
else if(size == 8)
|
||||
*value = _byteswap_uint64(*value);
|
||||
#endif //_WIN64
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Variable size not supported."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
});
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrRol(int argc, char* argv[])
|
||||
{
|
||||
duint value2;
|
||||
if(IsArgumentsLessThan(argc, 3) || !valfromstring(argv[2], &value2, false))
|
||||
return STATUS_ERROR;
|
||||
return ReadWriteVariable(argv[1], [value2](duint * value, int size)
|
||||
{
|
||||
if(size == 1)
|
||||
*value = _rotl8((uint8_t) * value, value2 % 8);
|
||||
else if(size == 2)
|
||||
*value = _rotl16((uint16) * value, value2 % 16);
|
||||
else if(size == 4)
|
||||
*value = _rotl((uint32) * value, value2 % 32);
|
||||
#ifdef _WIN64
|
||||
else if(size == 8)
|
||||
*value = _rotl64(*value, value2 % 64);
|
||||
#endif //_WIN64
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Variable size not supported."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
});
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrRor(int argc, char* argv[])
|
||||
{
|
||||
duint value2;
|
||||
if(IsArgumentsLessThan(argc, 3) || !valfromstring(argv[2], &value2, false))
|
||||
return STATUS_ERROR;
|
||||
return ReadWriteVariable(argv[1], [value2](duint * value, int size)
|
||||
{
|
||||
if(size == 1)
|
||||
*value = _rotr8((uint8_t) * value, value2 % 8);
|
||||
else if(size == 2)
|
||||
*value = _rotr16((uint16) * value, value2 % 16);
|
||||
else if(size == 4)
|
||||
*value = _rotr((uint32) * value, value2 % 32);
|
||||
#ifdef _WIN64
|
||||
else if(size == 8)
|
||||
*value = _rotr64(*value, value2 % 64);
|
||||
#endif //_WIN64
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Variable size not supported."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
});
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrShl(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
//SHL and SAL have the same semantics
|
||||
return cmddirectexec(StringUtils::sprintf("%s<<=%s", argv[1], argv[2]).c_str());
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrShr(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
auto oldType = valuesignedcalc();
|
||||
valuesetsignedcalc(false); //SHR is unsigned
|
||||
auto result = cmddirectexec(StringUtils::sprintf("%s>>=%s", argv[1], argv[2]).c_str());
|
||||
valuesetsignedcalc(oldType);
|
||||
return result;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrSar(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
auto oldType = valuesignedcalc();
|
||||
valuesetsignedcalc(true); //SAR is signed
|
||||
auto result = cmddirectexec(StringUtils::sprintf("%s>>=%s", argv[1], argv[2]).c_str());
|
||||
valuesetsignedcalc(oldType);
|
||||
return result;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrPush(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "not enough arguments!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint value;
|
||||
if(!valfromstring(argv[1], &value))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid argument \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
Script::Stack::Push(value);
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
DebugUpdateStack(csp, csp);
|
||||
GuiUpdateRegisterView();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrPop(int argc, char* argv[])
|
||||
{
|
||||
duint value = Script::Stack::Pop();
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
DebugUpdateStack(csp, csp);
|
||||
GuiUpdateRegisterView();
|
||||
if(argc > 1)
|
||||
{
|
||||
if(!valtostring(argv[1], value, false))
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrTest(int argc, char* argv[])
|
||||
{
|
||||
//TODO: test
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint arg1 = 0;
|
||||
if(!valfromstring(argv[1], &arg1, false))
|
||||
return STATUS_ERROR;
|
||||
duint arg2 = 0;
|
||||
if(!valfromstring(argv[2], &arg2, false))
|
||||
return STATUS_ERROR;
|
||||
duint ezflag;
|
||||
duint bsflag = 0;
|
||||
if(!(arg1 & arg2))
|
||||
ezflag = 1;
|
||||
else
|
||||
ezflag = 0;
|
||||
varset("$_EZ_FLAG", ezflag, true);
|
||||
varset("$_BS_FLAG", bsflag, true);
|
||||
//dprintf(QT_TRANSLATE_NOOP("DBG", "$_EZ_FLAG=%d, $_BS_FLAG=%d\n"), ezflag, bsflag);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrCmp(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint arg1 = 0;
|
||||
if(!valfromstring(argv[1], &arg1, false))
|
||||
return STATUS_ERROR;
|
||||
duint arg2 = 0;
|
||||
if(!valfromstring(argv[2], &arg2, false))
|
||||
return STATUS_ERROR;
|
||||
duint ezflag;
|
||||
duint bsflag;
|
||||
if(arg1 == arg2)
|
||||
ezflag = 1;
|
||||
else
|
||||
ezflag = 0;
|
||||
if(valuesignedcalc()) //signed comparision
|
||||
{
|
||||
if((dsint)arg1 < (dsint)arg2)
|
||||
bsflag = 0;
|
||||
else
|
||||
bsflag = 1;
|
||||
}
|
||||
else //unsigned comparision
|
||||
{
|
||||
if(arg1 > arg2)
|
||||
bsflag = 1;
|
||||
else
|
||||
bsflag = 0;
|
||||
}
|
||||
varset("$_EZ_FLAG", ezflag, true);
|
||||
varset("$_BS_FLAG", bsflag, true);
|
||||
//dprintf(QT_TRANSLATE_NOOP("DBG", "$_EZ_FLAG=%d, $_BS_FLAG=%d\n"), ezflag, bsflag);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrMov(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
String srcText = argv[2];
|
||||
if(srcText[0] == '#' && srcText[srcText.length() - 1] == '#') //handle mov addr, #DATA#
|
||||
{
|
||||
//do some checks on the data
|
||||
String dataText = srcText.substr(1, srcText.length() - 2);
|
||||
int len = (int)dataText.length();
|
||||
if(len % 2)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid hex string \"%s\" (length not divisible by 2)\n"), dataText.c_str());
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
if(!isxdigit(dataText[i]))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid hex string \"%s\" (contains invalid characters)\n"), dataText.c_str());
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
//Check the destination
|
||||
duint dest;
|
||||
if(!valfromstring(argv[1], &dest) || !MemIsValidReadPtr(dest))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid destination \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//Convert text to byte array (very ugly)
|
||||
Memory<unsigned char*> data(len / 2);
|
||||
for(int i = 0, j = 0; i < len; i += 2, j++)
|
||||
{
|
||||
char b[3] = "";
|
||||
b[0] = dataText[i];
|
||||
b[1] = dataText[i + 1];
|
||||
int res = 0;
|
||||
if(sscanf_s(b, "%X", &res) != 1)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid hex byte \"%s\"\n"), b);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
data()[j] = res;
|
||||
}
|
||||
//Move data to destination
|
||||
if(!MemWrite(dest, data(), data.size()))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to write to %p\n"), dest);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiUpdateAllViews(); //refresh disassembly/dump/etc
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
duint set_value = 0;
|
||||
if(!valfromstring(srcText.c_str(), &set_value))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid src \"%s\"\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
bool isvar = false;
|
||||
duint temp = 0;
|
||||
valfromstring(argv[1], &temp, true, true, 0, &isvar, 0); //there is no return check on this because the destination might not exist yet
|
||||
if(!isvar)
|
||||
isvar = vargettype(argv[1], 0);
|
||||
if(!isvar || !valtostring(argv[1], set_value, true))
|
||||
{
|
||||
duint value;
|
||||
if(valfromstring(argv[1], &value)) //if the var is a value already it's an invalid destination
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid dest \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
varnew(argv[1], set_value, VAR_USER);
|
||||
}
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,261 @@
|
|||
#include "cmd-gui.h"
|
||||
#include "cmd-gui.h"
|
||||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
#include "memory.h"
|
||||
#include "recursiveanalysis.h"
|
||||
#include "function.h"
|
||||
#include "stringformat.h"
|
||||
#include "value.h"
|
||||
|
||||
CMDRESULT cbDebugDisasm(int argc, char* argv[])
|
||||
{
|
||||
duint addr = 0;
|
||||
if(argc > 1)
|
||||
{
|
||||
if(!valfromstring(argv[1], &addr))
|
||||
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
}
|
||||
DebugUpdateGuiAsync(addr, false);
|
||||
GuiShowCpu();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugDump(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(argc > 2)
|
||||
{
|
||||
duint index = 0;
|
||||
if(!valfromstring(argv[2], &index))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address \"%s\"!\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiDumpAtN(addr, int(index));
|
||||
}
|
||||
else
|
||||
GuiDumpAt(addr);
|
||||
GuiShowCpu();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugStackDump(int argc, char* argv[])
|
||||
{
|
||||
duint addr = 0;
|
||||
if(argc < 2)
|
||||
addr = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
else if(!valfromstring(argv[1], &addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(csp, &size);
|
||||
if(base && addr >= base && addr < (base + size))
|
||||
DebugUpdateStack(addr, csp, true);
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Invalid stack address!"));
|
||||
GuiShowCpu();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugMemmapdump(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
return STATUS_ERROR;
|
||||
duint addr;
|
||||
if(!valfromstring(argv[1], &addr, false) || !MemIsValidReadPtr(addr, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiSelectInMemoryMap(addr);
|
||||
GuiShowCpu();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrGraph(int argc, char* argv[])
|
||||
{
|
||||
duint entry;
|
||||
if(argc < 2 || !valfromstring(argv[1], &entry))
|
||||
entry = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
duint start, size, sel = entry;
|
||||
if(FunctionGet(entry, &start))
|
||||
entry = start;
|
||||
auto base = MemFindBaseAddr(entry, &size);
|
||||
if(!base || !MemIsValidReadPtr(entry))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid memory address %p!\n"), entry);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!GuiGraphAt(sel))
|
||||
{
|
||||
auto modbase = ModBaseFromAddr(base);
|
||||
if(modbase)
|
||||
base = modbase, size = ModSizeFromAddr(modbase);
|
||||
RecursiveAnalysis analysis(base, size, entry, 0);
|
||||
analysis.Analyse();
|
||||
auto graph = analysis.GetFunctionGraph(entry);
|
||||
if(!graph)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No graph generated..."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
auto graphList = graph->ToGraphList();
|
||||
GuiLoadGraph(&graphList, sel);
|
||||
}
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrEnableGuiUpdate(int argc, char* argv[])
|
||||
{
|
||||
if(GuiIsUpdateDisabled())
|
||||
GuiUpdateEnable(false);
|
||||
duint value;
|
||||
//default: update gui
|
||||
if(argc > 1 && valfromstring(argv[1], &value) && value == 0)
|
||||
return STATUS_CONTINUE;
|
||||
duint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
DebugUpdateGuiAsync(cip, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDisableGuiUpdate(int argc, char* argv[])
|
||||
{
|
||||
if(!GuiIsUpdateDisabled())
|
||||
GuiUpdateDisable();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetfreezestack(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
bool freeze = *argv[1] != '0';
|
||||
dbgsetfreezestack(freeze);
|
||||
if(freeze)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Stack is now freezed\n"));
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Stack is now unfreezed\n"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static bool bRefinit = false;
|
||||
|
||||
CMDRESULT cbInstrRefinit(int argc, char* argv[])
|
||||
{
|
||||
GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Script")));
|
||||
GuiReferenceAddColumn(sizeof(duint) * 2, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Data")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
bRefinit = true;
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrRefadd(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!bRefinit)
|
||||
cbInstrRefinit(argc, argv);
|
||||
int index = GuiReferenceGetRowCount();
|
||||
GuiReferenceSetRowCount(index + 1);
|
||||
char addr_text[32] = "";
|
||||
sprintf_s(addr_text, "%p", addr);
|
||||
GuiReferenceSetCellContent(index, 0, addr_text);
|
||||
GuiReferenceSetCellContent(index, 1, stringformatinline(argv[2]).c_str());
|
||||
GuiReferenceReloadData();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrEnableLog(int argc, char* argv[])
|
||||
{
|
||||
GuiEnableLog();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDisableLog(int argc, char* argv[])
|
||||
{
|
||||
GuiDisableLog();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAddFavTool(int argc, char* argv[])
|
||||
{
|
||||
// filename, description
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
|
||||
if(argc == 2)
|
||||
GuiAddFavouriteTool(argv[1], nullptr);
|
||||
else
|
||||
GuiAddFavouriteTool(argv[1], argv[2]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAddFavCmd(int argc, char* argv[])
|
||||
{
|
||||
// command, shortcut
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
|
||||
if(argc == 2)
|
||||
GuiAddFavouriteCommand(argv[1], nullptr);
|
||||
else
|
||||
GuiAddFavouriteCommand(argv[1], argv[2]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrSetFavToolShortcut(int argc, char* argv[])
|
||||
{
|
||||
// filename, shortcut
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
|
||||
GuiSetFavouriteToolShortcut(argv[1], argv[2]);
|
||||
return STATUS_CONTINUE;
|
||||
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFoldDisassembly(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
|
||||
duint start, length;
|
||||
if(!valfromstring(argv[1], &start))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid argument 1 : %s\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!valfromstring(argv[2], &length))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid argument 2 : %s\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiFoldDisassembly(start, length);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -7,8 +7,8 @@ CMDRESULT cbDebugDump(int argc, char* argv[]);
|
|||
CMDRESULT cbDebugStackDump(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugMemmapdump(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrGraph(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrDisableGuiUpdate(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrEnableGuiUpdate(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrDisableGuiUpdate(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetfreezestack(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrRefinit(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrRefadd(int argc, char* argv[]);
|
||||
|
|
|
@ -1 +1,180 @@
|
|||
#include "cmd-memory-operations.h"
|
||||
#include "cmd-memory-operations.h"
|
||||
#include "console.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
#include "variable.h"
|
||||
#include "filehelper.h"
|
||||
#include "value.h"
|
||||
|
||||
CMDRESULT cbDebugAlloc(int argc, char* argv[])
|
||||
{
|
||||
duint size = 0x1000;
|
||||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &size, false))
|
||||
return STATUS_ERROR;
|
||||
duint mem = (duint)MemAllocRemote(0, size);
|
||||
if(!mem)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "VirtualAllocEx failed"));
|
||||
else
|
||||
dprintf("%p\n", mem);
|
||||
if(mem)
|
||||
varset("$lastalloc", mem, true);
|
||||
//update memory map
|
||||
MemUpdateMap();
|
||||
GuiUpdateMemoryView();
|
||||
|
||||
varset("$res", mem, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugFree(int argc, char* argv[])
|
||||
{
|
||||
duint lastalloc;
|
||||
varget("$lastalloc", &lastalloc, 0, 0);
|
||||
duint addr = lastalloc;
|
||||
if(argc > 1)
|
||||
{
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(!lastalloc)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "$lastalloc is zero, provide a page address"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(addr == lastalloc)
|
||||
varset("$lastalloc", (duint)0, true);
|
||||
bool ok = !!VirtualFreeEx(fdProcessInfo->hProcess, (void*)addr, 0, MEM_RELEASE);
|
||||
if(!ok)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "VirtualFreeEx failed"));
|
||||
//update memory map
|
||||
MemUpdateMap();
|
||||
GuiUpdateMemoryView();
|
||||
|
||||
varset("$res", ok, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugMemset(int argc, char* argv[])
|
||||
{
|
||||
duint addr;
|
||||
duint value;
|
||||
duint size;
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!valfromstring(argv[1], &addr, false) || !valfromstring(argv[2], &value, false))
|
||||
return STATUS_ERROR;
|
||||
if(argc > 3)
|
||||
{
|
||||
if(!valfromstring(argv[3], &size, false))
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
duint base = MemFindBaseAddr(addr, &size, true);
|
||||
if(!base)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Invalid address specified"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint diff = addr - base;
|
||||
addr = base + diff;
|
||||
size -= diff;
|
||||
}
|
||||
BYTE fi = value & 0xFF;
|
||||
if(!Fill((void*)addr, size & 0xFFFFFFFF, &fi))
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Memset failed"));
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Memory %p (size: %.8X) set to %.2X\n"), addr, size & 0xFFFFFFFF, value & 0xFF);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetPageRights(int argc, char* argv[])
|
||||
{
|
||||
duint addr = 0;
|
||||
char rights[RIGHTS_STRING_SIZE];
|
||||
|
||||
if(argc != 2 || !valfromstring(argv[1], &addr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: using an address as arg1\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!MemGetPageRights(addr, rights))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error getting rights of page: %s\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Page: %p, Rights: %s\n"), addr, rights);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetPageRights(int argc, char* argv[])
|
||||
{
|
||||
duint addr = 0;
|
||||
char rights[RIGHTS_STRING_SIZE];
|
||||
|
||||
if(argc < 3 || !valfromstring(argv[1], &addr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: Using an address as arg1 and as arg2: Execute, ExecuteRead, ExecuteReadWrite, ExecuteWriteCopy, NoAccess, ReadOnly, ReadWrite, WriteCopy. You can add a G at first for add PAGE GUARD, example: GReadOnly\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!MemSetPageRights(addr, argv[2]))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error: Set rights of %p with Rights: %s\n"), addr, argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!MemGetPageRights(addr, rights))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error getting rights of page: %s\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
//update the memory map
|
||||
MemUpdateMap();
|
||||
GuiUpdateMemoryView();
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "New rights of %p: %s\n"), addr, rights);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrSavedata(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 4))
|
||||
return STATUS_ERROR;
|
||||
duint addr, size;
|
||||
if(!valfromstring(argv[2], &addr, false) || !valfromstring(argv[3], &size, false))
|
||||
return STATUS_ERROR;
|
||||
|
||||
Memory<unsigned char*> data(size);
|
||||
if(!MemRead(addr, data(), data.size()))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to read memory..."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
String name = argv[1];
|
||||
if(name == ":memdump:")
|
||||
name = StringUtils::sprintf("%s\\memdumps\\memdump_%X_%p_%x.bin", szProgramDir, fdProcessInfo->dwProcessId, addr, size);
|
||||
|
||||
if(!FileHelper::WriteAllData(name, data(), data.size()))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to write file..."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
#ifdef _WIN64
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%p[% llX] written to \"%s\" !\n"), addr, size, name.c_str());
|
||||
#else //x86
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%p[% X] written to \"%s\" !\n"), addr, size, name.c_str());
|
||||
#endif
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,588 @@
|
|||
#include "cmd-misc.h"
|
||||
#include "cmd-misc.h"
|
||||
#include "exprfunc.h"
|
||||
#include "variable.h"
|
||||
#include "value.h"
|
||||
#include "debugger.h"
|
||||
#include "threading.h"
|
||||
#include "thread.h"
|
||||
#include "assemble.h"
|
||||
#include "memory.h"
|
||||
#include "plugin_loader.h"
|
||||
#include "jit.h"
|
||||
#include "mnemonichelp.h"
|
||||
#include "commandline.h"
|
||||
|
||||
CMDRESULT cbInstrChd(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
if(!DirExists(argv[1]))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "directory doesn't exist"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(argv[1]).c_str());
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "current directory changed!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrGetTickCount(int argc, char* argv[])
|
||||
{
|
||||
varset("$result", Exprfunc::gettickcount(), false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrSleep(int argc, char* argv[])
|
||||
{
|
||||
duint ms = 100;
|
||||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &ms, false))
|
||||
return STATUS_ERROR;
|
||||
if(ms >= 0xFFFFFFFF)
|
||||
ms = 100;
|
||||
Sleep((DWORD)ms);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugHide(int argc, char* argv[])
|
||||
{
|
||||
if(HideDebugger(fdProcessInfo->hProcess, UE_HIDE_PEBONLY))
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Debugger hidden"));
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Something went wrong"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static duint LoadLibThreadID;
|
||||
static duint DLLNameMem;
|
||||
static duint ASMAddr;
|
||||
static TITAN_ENGINE_CONTEXT_t backupctx = { 0 };
|
||||
|
||||
static void cbDebugLoadLibBPX()
|
||||
{
|
||||
HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID);
|
||||
#ifdef _WIN64
|
||||
duint LibAddr = GetContextDataEx(LoadLibThread, UE_RAX);
|
||||
#else
|
||||
duint LibAddr = GetContextDataEx(LoadLibThread, UE_EAX);
|
||||
#endif //_WIN64
|
||||
varset("$result", LibAddr, false);
|
||||
backupctx.eflags &= ~0x100;
|
||||
SetFullContextDataEx(LoadLibThread, &backupctx);
|
||||
MemFreeRemote(DLLNameMem);
|
||||
MemFreeRemote(ASMAddr);
|
||||
ThreadResumeAll();
|
||||
//update GUI
|
||||
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
//lock
|
||||
lock(WAITID_RUN);
|
||||
dbgsetforeground();
|
||||
PLUG_CB_PAUSEDEBUG pauseInfo = { nullptr };
|
||||
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
|
||||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: you must specify the name of the DLL to load\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
LoadLibThreadID = fdProcessInfo->dwThreadId;
|
||||
HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID);
|
||||
|
||||
DLLNameMem = MemAllocRemote(0, strlen(argv[1]) + 1);
|
||||
ASMAddr = MemAllocRemote(0, 0x1000);
|
||||
|
||||
if(!DLLNameMem || !ASMAddr)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't allocate memory in debuggee"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!MemWrite(DLLNameMem, argv[1], strlen(argv[1])))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't write process memory"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
int size = 0;
|
||||
int counter = 0;
|
||||
duint LoadLibraryA = 0;
|
||||
char command[50] = "";
|
||||
char error[MAX_ERROR_SIZE] = "";
|
||||
|
||||
GetFullContextDataEx(LoadLibThread, &backupctx);
|
||||
|
||||
if(!valfromstring("kernel32:LoadLibraryA", &LoadLibraryA, false))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't get kernel32:LoadLibraryA"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
// Arch specific asm code
|
||||
#ifdef _WIN64
|
||||
sprintf_s(command, "mov rcx, %p", (duint)DLLNameMem);
|
||||
#else
|
||||
sprintf_s(command, "push %p", DLLNameMem);
|
||||
#endif // _WIN64
|
||||
|
||||
assembleat((duint)ASMAddr, command, &size, error, true);
|
||||
counter += size;
|
||||
|
||||
#ifdef _WIN64
|
||||
sprintf_s(command, "mov rax, %p", LoadLibraryA);
|
||||
assembleat((duint)ASMAddr + counter, command, &size, error, true);
|
||||
counter += size;
|
||||
sprintf_s(command, "call rax");
|
||||
#else
|
||||
sprintf_s(command, "call %p", LoadLibraryA);
|
||||
#endif // _WIN64
|
||||
|
||||
assembleat((duint)ASMAddr + counter, command, &size, error, true);
|
||||
counter += size;
|
||||
|
||||
SetContextDataEx(LoadLibThread, UE_CIP, (duint)ASMAddr);
|
||||
auto ok = SetBPX((duint)ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbDebugLoadLibBPX);
|
||||
|
||||
ThreadSuspendAll();
|
||||
ResumeThread(LoadLibThread);
|
||||
|
||||
unlock(WAITID_RUN);
|
||||
|
||||
return ok ? STATUS_CONTINUE : STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrAssemble(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid expression: \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!DbgMemIsValidReadPtr(addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid address: %p!\n"), addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
bool fillnop = false;
|
||||
if(argc > 3)
|
||||
fillnop = true;
|
||||
char error[MAX_ERROR_SIZE] = "";
|
||||
int size = 0;
|
||||
if(!assembleat(addr, argv[2], &size, error, fillnop))
|
||||
{
|
||||
varset("$result", size, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to assemble \"%s\" (%s)\n"), argv[2], error);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
varset("$result", size, false);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrGpa(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
char newcmd[deflen] = "";
|
||||
if(argc >= 3)
|
||||
sprintf_s(newcmd, "\"%s\":%s", argv[2], argv[1]);
|
||||
else
|
||||
sprintf_s(newcmd, "%s", argv[1]);
|
||||
duint result = 0;
|
||||
if(!valfromstring(newcmd, &result, false))
|
||||
return STATUS_ERROR;
|
||||
varset("$RESULT", result, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetJIT(int argc, char* argv[])
|
||||
{
|
||||
arch actual_arch = invalid;
|
||||
char* jit_debugger_cmd = "";
|
||||
char oldjit[MAX_SETTING_SIZE] = "";
|
||||
char path[JIT_ENTRY_DEF_SIZE];
|
||||
if(!IsProcessElevated())
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error run the debugger as Admin to setjit\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(argc < 2)
|
||||
{
|
||||
dbggetdefjit(path);
|
||||
|
||||
jit_debugger_cmd = path;
|
||||
if(!dbgsetjit(jit_debugger_cmd, notfound, &actual_arch, NULL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error setting JIT %s\n"), (actual_arch == x64) ? "x64" : "x32");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else if(argc == 2)
|
||||
{
|
||||
if(!_strcmpi(argv[1], "old"))
|
||||
{
|
||||
jit_debugger_cmd = oldjit;
|
||||
if(!BridgeSettingGet("JIT", "Old", jit_debugger_cmd))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error there is no old JIT entry stored."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!dbgsetjit(jit_debugger_cmd, notfound, &actual_arch, NULL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error setting JIT %s\n"), (actual_arch == x64) ? "x64" : "x32");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else if(!_strcmpi(argv[1], "oldsave"))
|
||||
{
|
||||
char path[JIT_ENTRY_DEF_SIZE];
|
||||
dbggetdefjit(path);
|
||||
char get_entry[JIT_ENTRY_MAX_SIZE] = "";
|
||||
bool get_last_jit = true;
|
||||
|
||||
if(!dbggetjit(get_entry, notfound, &actual_arch, NULL))
|
||||
get_last_jit = false;
|
||||
else
|
||||
strcpy_s(oldjit, get_entry);
|
||||
|
||||
jit_debugger_cmd = path;
|
||||
if(!dbgsetjit(jit_debugger_cmd, notfound, &actual_arch, NULL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error setting JIT %s\n"), (actual_arch == x64) ? "x64" : "x32");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(get_last_jit)
|
||||
{
|
||||
if(_stricmp(oldjit, path))
|
||||
BridgeSettingSet("JIT", "Old", oldjit);
|
||||
}
|
||||
}
|
||||
else if(!_strcmpi(argv[1], "restore"))
|
||||
{
|
||||
jit_debugger_cmd = oldjit;
|
||||
|
||||
if(!BridgeSettingGet("JIT", "Old", jit_debugger_cmd))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error there is no old JIT entry stored."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!dbgsetjit(jit_debugger_cmd, notfound, &actual_arch, NULL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error setting JIT %s\n"), (actual_arch == x64) ? "x64" : "x32");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
BridgeSettingSet("JIT", 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
jit_debugger_cmd = argv[1];
|
||||
if(!dbgsetjit(jit_debugger_cmd, notfound, &actual_arch, NULL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error setting JIT %s\n"), (actual_arch == x64) ? "x64" : "x32");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(argc == 3)
|
||||
{
|
||||
readwritejitkey_error_t rw_error;
|
||||
|
||||
if(!_strcmpi(argv[1], "old"))
|
||||
{
|
||||
BridgeSettingSet("JIT", "Old", argv[2]);
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "New OLD JIT stored: %s\n"), argv[2]);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
else if(_strcmpi(argv[1], "x64") == 0)
|
||||
actual_arch = x64;
|
||||
else if(_strcmpi(argv[1], "x32") == 0)
|
||||
actual_arch = x32;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown JIT entry type. Use OLD, x64 or x32 as parameter."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
jit_debugger_cmd = argv[2];
|
||||
if(!dbgsetjit(jit_debugger_cmd, actual_arch, NULL, &rw_error))
|
||||
{
|
||||
if(rw_error == ERROR_RW_NOTWOW64)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error using x64 arg. The debugger is not a WOW64 process\n"));
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error setting JIT %s\n"), (actual_arch == x64) ? "x64" : "x32");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error unknown parameters. Use old, oldsave, restore, x86 or x64 as parameter."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "New JIT %s: %s\n"), (actual_arch == x64) ? "x64" : "x32", jit_debugger_cmd);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetJIT(int argc, char* argv[])
|
||||
{
|
||||
char get_entry[JIT_ENTRY_MAX_SIZE] = "";
|
||||
arch actual_arch;
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
if(!dbggetjit(get_entry, notfound, &actual_arch, NULL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error getting JIT %s\n"), (actual_arch == x64) ? "x64" : "x32");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
readwritejitkey_error_t rw_error;
|
||||
char oldjit[MAX_SETTING_SIZE] = "";
|
||||
if(_strcmpi(argv[1], "OLD") == 0)
|
||||
{
|
||||
if(!BridgeSettingGet("JIT", "Old", (char*)& oldjit))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: there is not an OLD JIT entry stored yet."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "OLD JIT entry stored: %s\n"), oldjit);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
}
|
||||
else if(_strcmpi(argv[1], "x64") == 0)
|
||||
actual_arch = x64;
|
||||
else if(_strcmpi(argv[1], "x32") == 0)
|
||||
actual_arch = x32;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown JIT entry type. Use OLD, x64 or x32 as parameter."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!dbggetjit(get_entry, actual_arch, NULL, &rw_error))
|
||||
{
|
||||
if(rw_error == ERROR_RW_NOTWOW64)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error using x64 arg. The debugger is not a WOW64 process\n"));
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error getting JIT %s\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "JIT %s: %s\n"), (actual_arch == x64) ? "x64" : "x32", get_entry);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetJITAuto(int argc, char* argv[])
|
||||
{
|
||||
bool jit_auto = false;
|
||||
arch actual_arch = invalid;
|
||||
|
||||
if(argc == 1)
|
||||
{
|
||||
if(!dbggetjitauto(&jit_auto, notfound, &actual_arch, NULL))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error getting JIT auto %s\n"), (actual_arch == x64) ? "x64" : "x32");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else if(argc == 2)
|
||||
{
|
||||
readwritejitkey_error_t rw_error;
|
||||
if(_strcmpi(argv[1], "x64") == 0)
|
||||
actual_arch = x64;
|
||||
else if(_strcmpi(argv[1], "x32") == 0)
|
||||
actual_arch = x32;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown JIT auto entry type. Use x64 or x32 as parameter."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!dbggetjitauto(&jit_auto, actual_arch, NULL, &rw_error))
|
||||
{
|
||||
if(rw_error == ERROR_RW_NOTWOW64)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error using x64 arg the debugger is not a WOW64 process\n"));
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error getting JIT auto %s\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown JIT auto entry type. Use x64 or x32 as parameter"));
|
||||
}
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "JIT auto %s: %s\n"), (actual_arch == x64) ? "x64" : "x32", jit_auto ? "ON" : "OFF");
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetJITAuto(int argc, char* argv[])
|
||||
{
|
||||
arch actual_arch;
|
||||
bool set_jit_auto;
|
||||
if(!IsProcessElevated())
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error run the debugger as Admin to setjitauto\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error setting JIT Auto. Use ON:1 or OFF:0 arg or x64/x32, ON:1 or OFF:0.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(argc == 2)
|
||||
{
|
||||
if(_strcmpi(argv[1], "1") == 0 || _strcmpi(argv[1], "ON") == 0)
|
||||
set_jit_auto = true;
|
||||
else if(_strcmpi(argv[1], "0") == 0 || _strcmpi(argv[1], "OFF") == 0)
|
||||
set_jit_auto = false;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error unknown parameters. Use ON:1 or OFF:0"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!dbgsetjitauto(set_jit_auto, notfound, &actual_arch, NULL))
|
||||
{
|
||||
if(actual_arch == x64)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error setting JIT auto x64"));
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error setting JIT auto x32"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else if(argc == 3)
|
||||
{
|
||||
readwritejitkey_error_t rw_error;
|
||||
actual_arch = x64;
|
||||
|
||||
if(_strcmpi(argv[1], "x64") == 0)
|
||||
actual_arch = x64;
|
||||
else if(_strcmpi(argv[1], "x32") == 0)
|
||||
actual_arch = x32;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown JIT auto entry type. Use x64 or x32 as parameter"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(_strcmpi(argv[2], "1") == 0 || _strcmpi(argv[2], "ON") == 0)
|
||||
set_jit_auto = true;
|
||||
else if(_strcmpi(argv[2], "0") == 0 || _strcmpi(argv[2], "OFF") == 0)
|
||||
set_jit_auto = false;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error unknown parameters. Use x86 or x64 and ON:1 or OFF:0\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!dbgsetjitauto(set_jit_auto, actual_arch, NULL, &rw_error))
|
||||
{
|
||||
if(rw_error == ERROR_RW_NOTWOW64)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error using x64 arg the debugger is not a WOW64 process\n"));
|
||||
else
|
||||
{
|
||||
if(actual_arch == x64)
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error getting JIT auto x64"));
|
||||
else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error getting JIT auto x32"));
|
||||
}
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error unknown parameters use x86 or x64, ON/1 or OFF/0\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "New JIT auto %s: %s\n"), (actual_arch == x64) ? "x64" : "x32", set_jit_auto ? "ON" : "OFF");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugGetCmdline(int argc, char* argv[])
|
||||
{
|
||||
char* cmd_line;
|
||||
cmdline_error_t cmdline_error = { (cmdline_error_type_t)0, 0 };
|
||||
|
||||
if(!dbggetcmdline(&cmd_line, &cmdline_error))
|
||||
{
|
||||
showcommandlineerror(&cmdline_error);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Command line: %s\n"), cmd_line);
|
||||
|
||||
efree(cmd_line);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetCmdline(int argc, char* argv[])
|
||||
{
|
||||
cmdline_error_t cmdline_error = { (cmdline_error_type_t)0, 0 };
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: write the arg1 with the new command line of the process debugged"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!dbgsetcmdline(argv[1], &cmdline_error))
|
||||
{
|
||||
showcommandlineerror(&cmdline_error);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
//update the memory map
|
||||
MemUpdateMap();
|
||||
GuiUpdateMemoryView();
|
||||
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "New command line: %s\n"), argv[1]);
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrMnemonichelp(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
auto description = MnemonicHelp::getDescription(argv[1]);
|
||||
if(!description.length())
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "no description or empty description"));
|
||||
else
|
||||
{
|
||||
auto padding = "================================================================";
|
||||
auto logText = StringUtils::sprintf("%s%s%s\n", padding, description.c_str(), padding);
|
||||
GuiAddLogMessage(logText.c_str());
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrMnemonicbrief(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
dputs(MnemonicHelp::getBriefDescription(argv[1]).c_str());
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,98 @@
|
|||
#include "cmd-operating-system-control.h"
|
||||
#include "cmd-operating-system-control.h"
|
||||
#include "variable.h"
|
||||
#include "debugger.h"
|
||||
#include "exception.h"
|
||||
#include "value.h"
|
||||
|
||||
CMDRESULT cbGetPrivilegeState(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
DWORD returnLength;
|
||||
LUID luid;
|
||||
if(LookupPrivilegeValueW(nullptr, StringUtils::Utf8ToUtf16(argv[1]).c_str(), &luid) == 0)
|
||||
{
|
||||
varset("$result", (duint)0, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory <TOKEN_PRIVILEGES*> Privileges(64 * 16 + 8, "_dbg_getprivilegestate");
|
||||
if(GetTokenInformation(hProcessToken, TokenPrivileges, Privileges(), 64 * 16 + 8, &returnLength) == 0)
|
||||
{
|
||||
if(returnLength > 4 * 1024 * 1024)
|
||||
{
|
||||
varset("$result", (duint)0, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Privileges.realloc(returnLength, "_dbg_getprivilegestate");
|
||||
if(GetTokenInformation(hProcessToken, TokenPrivileges, Privileges(), returnLength, &returnLength) == 0)
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
for(unsigned int i = 0; i < Privileges()->PrivilegeCount; i++)
|
||||
{
|
||||
if(4 + sizeof(LUID_AND_ATTRIBUTES) * i > returnLength)
|
||||
return STATUS_ERROR;
|
||||
if(memcmp(&Privileges()->Privileges[i].Luid, &luid, sizeof(LUID)) == 0)
|
||||
{
|
||||
varset("$result", (duint)(Privileges()->Privileges[i].Attributes + 1), false); // 2=enabled, 3=default, 1=disabled
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
}
|
||||
varset("$result", (duint)0, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbEnablePrivilege(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
LUID luid;
|
||||
if(LookupPrivilegeValueW(nullptr, StringUtils::Utf8ToUtf16(argv[1]).c_str(), &luid) == 0)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not find the specified privilege: %s\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
TOKEN_PRIVILEGES Privilege;
|
||||
Privilege.PrivilegeCount = 1;
|
||||
Privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
Privilege.Privileges[0].Luid = luid;
|
||||
bool ret = AdjustTokenPrivileges(hProcessToken, FALSE, &Privilege, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr) != NO_ERROR;
|
||||
return ret ? STATUS_CONTINUE : STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbDisablePrivilege(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
LUID luid;
|
||||
if(LookupPrivilegeValueW(nullptr, StringUtils::Utf8ToUtf16(argv[1]).c_str(), &luid) == 0)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not find the specified privilege: %s\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
TOKEN_PRIVILEGES Privilege;
|
||||
Privilege.PrivilegeCount = 1;
|
||||
Privilege.Privileges[0].Attributes = 0;
|
||||
Privilege.Privileges[0].Luid = luid;
|
||||
bool ret = AdjustTokenPrivileges(hProcessToken, FALSE, &Privilege, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr) != NO_ERROR;
|
||||
return ret ? STATUS_CONTINUE : STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbHandleClose(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint handle;
|
||||
if(!valfromstring(argv[1], &handle, false))
|
||||
return STATUS_ERROR;
|
||||
if(!DuplicateHandle(fdProcessInfo->hProcess, HANDLE(handle), NULL, NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "DuplicateHandle failed: %s\n"), ErrorCodeToName(GetLastError()).c_str());
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
#ifdef _WIN64
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Handle %llX closed!\n"), handle);
|
||||
#else //x86
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Handle %X closed!\n"), handle);
|
||||
#endif
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,65 @@
|
|||
#include "cmd-plugins.h"
|
||||
#include "cmd-plugins.h"
|
||||
#include "console.h"
|
||||
#include "debugger.h"
|
||||
#include "module.h"
|
||||
#include "plugin_loader.h"
|
||||
|
||||
static bool bScyllaLoaded = false;
|
||||
|
||||
static DWORD WINAPI scyllaThread(void* lpParam)
|
||||
{
|
||||
typedef INT(WINAPI * SCYLLASTARTGUI)(DWORD pid, HINSTANCE mod, DWORD_PTR entrypoint);
|
||||
SCYLLASTARTGUI ScyllaStartGui = 0;
|
||||
HINSTANCE hScylla = LoadLibraryW(L"Scylla.dll");
|
||||
if(!hScylla)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error loading Scylla.dll!"));
|
||||
bScyllaLoaded = false;
|
||||
FreeLibrary(hScylla);
|
||||
return 0;
|
||||
}
|
||||
ScyllaStartGui = (SCYLLASTARTGUI)GetProcAddress(hScylla, "ScyllaStartGui");
|
||||
if(!ScyllaStartGui)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Could not find export 'ScyllaStartGui' inside Scylla.dll"));
|
||||
bScyllaLoaded = false;
|
||||
FreeLibrary(hScylla);
|
||||
return 0;
|
||||
}
|
||||
auto cip = GetContextDataEx(fdProcessInfo->hThread, UE_CIP);
|
||||
auto cipModBase = ModBaseFromAddr(cip);
|
||||
ScyllaStartGui(fdProcessInfo->dwProcessId, (HINSTANCE)cipModBase, cip);
|
||||
FreeLibrary(hScylla);
|
||||
bScyllaLoaded = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugStartScylla(int argc, char* argv[])
|
||||
{
|
||||
if(bScyllaLoaded)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Scylla is already loaded"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
bScyllaLoaded = true;
|
||||
CloseHandle(CreateThread(0, 0, scyllaThread, 0, 0, 0));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrPluginLoad(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 1))
|
||||
return STATUS_ERROR;
|
||||
if(pluginload(argv[1]))
|
||||
return STATUS_CONTINUE;
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrPluginUnload(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 1))
|
||||
return STATUS_ERROR;
|
||||
if(pluginunload(argv[1]))
|
||||
return STATUS_CONTINUE;
|
||||
return STATUS_ERROR;
|
||||
}
|
|
@ -1 +1,56 @@
|
|||
#include "cmd-script.h"
|
||||
#include "cmd-script.h"
|
||||
#include "stringformat.h"
|
||||
#include "console.h"
|
||||
#include "variable.h"
|
||||
#include "simplescript.h"
|
||||
|
||||
CMDRESULT cbScriptLoad(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
return STATUS_ERROR;
|
||||
scriptload(argv[1]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptMsg(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "not enough arguments!")));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiScriptMessage(stringformatinline(argv[1]).c_str());
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptMsgyn(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "not enough arguments!")));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
varset("$RESULT", GuiScriptMsgyn(stringformatinline(argv[1]).c_str()), false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrLog(int argc, char* argv[])
|
||||
{
|
||||
if(argc == 1) //just log newline
|
||||
{
|
||||
dputs_untranslated("");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(argc == 2) //inline logging: log "format {rax}"
|
||||
{
|
||||
dputs_untranslated(stringformatinline(argv[1]).c_str());
|
||||
}
|
||||
else //log "format {0} string", arg1, arg2, argN
|
||||
{
|
||||
FormatValueVector formatArgs;
|
||||
for(auto i = 2; i < argc; i++)
|
||||
formatArgs.push_back(argv[i]);
|
||||
dputs_untranslated(stringformat(argv[1], formatArgs).c_str());
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,249 @@
|
|||
#include "cmd-thread-control.h"
|
||||
#include "cmd-thread-control.h"
|
||||
#include "variable.h"
|
||||
#include "memory.h"
|
||||
#include "value.h"
|
||||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
#include "label.h"
|
||||
#include "historycontext.h"
|
||||
#include "thread.h"
|
||||
|
||||
CMDRESULT cbDebugCreatethread(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
return STATUS_ERROR;
|
||||
duint Entry = 0;
|
||||
duint Argument = 0;
|
||||
if(!valfromstring(argv[1], &Entry))
|
||||
return STATUS_ERROR;
|
||||
if(!MemIsCodePage(Entry, false))
|
||||
return STATUS_ERROR;
|
||||
if(argc > 2)
|
||||
{
|
||||
if(!valfromstring(argv[2], &Argument))
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
DWORD ThreadId = 0;
|
||||
if(ThreaderCreateRemoteThread(Entry, true, reinterpret_cast<LPVOID>(Argument), &ThreadId) != 0)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Create thread failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
char label[MAX_LABEL_SIZE];
|
||||
if(!LabelGet(Entry, label))
|
||||
label[0] = 0;
|
||||
#ifdef _WIN64
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Thread %X created at %s %p(Argument=%llX)\n"), ThreadId, label, Entry, Argument);
|
||||
#else //x86
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Thread %X created at %s %p(Argument=%X)\n"), ThreadId, label, Entry, Argument);
|
||||
#endif
|
||||
varset("$result", ThreadId, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSwitchthread(int argc, char* argv[])
|
||||
{
|
||||
duint threadid = fdProcessInfo->dwThreadId; //main thread
|
||||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid thread %X\n"), threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//switch thread
|
||||
if(ThreadGetId(hActiveThread) != threadid)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle((DWORD)threadid);
|
||||
HistoryClear();
|
||||
DebugUpdateGuiAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Thread switched!"));
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSuspendthread(int argc, char* argv[])
|
||||
{
|
||||
duint threadid = fdProcessInfo->dwThreadId;
|
||||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid thread %X\n"), threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//suspend thread
|
||||
if(SuspendThread(ThreadGetHandle((DWORD)threadid)) == -1)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error suspending thread"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Thread suspended"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResumethread(int argc, char* argv[])
|
||||
{
|
||||
duint threadid = fdProcessInfo->dwThreadId;
|
||||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid thread %X\n"), threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//resume thread
|
||||
if(ResumeThread(ThreadGetHandle((DWORD)threadid)) == -1)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error resuming thread"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Thread resumed!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugKillthread(int argc, char* argv[])
|
||||
{
|
||||
duint threadid = fdProcessInfo->dwThreadId;
|
||||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
duint exitcode = 0;
|
||||
if(argc > 2)
|
||||
if(!valfromstring(argv[2], &exitcode, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid thread %X\n"), threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//terminate thread
|
||||
if(TerminateThread(ThreadGetHandle((DWORD)threadid), (DWORD)exitcode) != 0)
|
||||
{
|
||||
GuiUpdateAllViews();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Thread terminated"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error terminating thread!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[])
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d/%d thread(s) suspended\n"), ThreadSuspendAll(), ThreadGetCount());
|
||||
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[])
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d/%d thread(s) resumed\n"), ThreadResumeAll(), ThreadGetCount());
|
||||
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetPriority(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint threadid;
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
duint priority;
|
||||
if(!valfromstring(argv[2], &priority))
|
||||
{
|
||||
if(_strcmpi(argv[2], "Normal") == 0)
|
||||
priority = THREAD_PRIORITY_NORMAL;
|
||||
else if(_strcmpi(argv[2], "AboveNormal") == 0)
|
||||
priority = THREAD_PRIORITY_ABOVE_NORMAL;
|
||||
else if(_strcmpi(argv[2], "TimeCritical") == 0)
|
||||
priority = THREAD_PRIORITY_TIME_CRITICAL;
|
||||
else if(_strcmpi(argv[2], "Idle") == 0)
|
||||
priority = THREAD_PRIORITY_IDLE;
|
||||
else if(_strcmpi(argv[2], "BelowNormal") == 0)
|
||||
priority = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
else if(_strcmpi(argv[2], "Highest") == 0)
|
||||
priority = THREAD_PRIORITY_HIGHEST;
|
||||
else if(_strcmpi(argv[2], "Lowest") == 0)
|
||||
priority = THREAD_PRIORITY_LOWEST;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown priority value, read the help!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(priority) //check if the priority value is valid
|
||||
{
|
||||
case THREAD_PRIORITY_NORMAL:
|
||||
case THREAD_PRIORITY_ABOVE_NORMAL:
|
||||
case THREAD_PRIORITY_TIME_CRITICAL:
|
||||
case THREAD_PRIORITY_IDLE:
|
||||
case THREAD_PRIORITY_BELOW_NORMAL:
|
||||
case THREAD_PRIORITY_HIGHEST:
|
||||
case THREAD_PRIORITY_LOWEST:
|
||||
break;
|
||||
default:
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown priority value, read the help!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid thread %X\n"), threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//set thread priority
|
||||
if(SetThreadPriority(ThreadGetHandle((DWORD)threadid), (int)priority) == 0)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error setting thread priority"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Thread priority changed!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetthreadname(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint threadid;
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
THREADINFO info;
|
||||
if(!ThreadGetInfo(DWORD(threadid), info))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid thread %X\n"), threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
auto newname = argc > 2 ? argv[2] : "";
|
||||
if(!ThreadSetName(DWORD(threadid), newname))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Failed to change the name for thread %X\n"), threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!info.threadName)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Thread name set to \"%s\"!\n"), newname);
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Thread name changed from \"%s\" to \"%s\"!\n"), info.threadName, newname);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,128 @@
|
|||
#include "cmd-tracing.h"
|
||||
#include "cmd-tracing.h"
|
||||
#include "debugger.h"
|
||||
#include "historycontext.h"
|
||||
#include "threading.h"
|
||||
#include "module.h"
|
||||
#include "console.h"
|
||||
#include "cmd-debug-control.h"
|
||||
#include "value.h"
|
||||
|
||||
extern std::vector<std::pair<duint, duint>> RunToUserCodeBreakpoints;
|
||||
|
||||
static CMDRESULT cbDebugConditionalTrace(void* callBack, bool stepOver, int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(dbgtraceactive())
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Trace already active"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint maxCount = 50000;
|
||||
if(argc > 2 && !valfromstring(argv[2], &maxCount, false))
|
||||
return STATUS_ERROR;
|
||||
if(!dbgsettracecondition(argv[1], maxCount))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid expression \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
HistoryClear();
|
||||
if(stepOver)
|
||||
StepOver(callBack);
|
||||
else
|
||||
StepInto(callBack);
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugTraceIntoConditional(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugConditionalTrace((void*)cbTICNDStep, false, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugTraceOverConditional(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugConditionalTrace((void*)cbTOCNDStep, true, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugTraceIntoBeyondTraceRecord(int argc, char* argv[])
|
||||
{
|
||||
if(argc == 1)
|
||||
{
|
||||
char* new_argv[] = { "tibt", "0" };
|
||||
return cbDebugConditionalTrace((void*)cbTIBTStep, false, 2, new_argv);
|
||||
}
|
||||
else
|
||||
return cbDebugConditionalTrace((void*)cbTIBTStep, false, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugTraceOverBeyondTraceRecord(int argc, char* argv[])
|
||||
{
|
||||
if(argc == 1)
|
||||
{
|
||||
char* new_argv[] = { "tobt", "0" };
|
||||
return cbDebugConditionalTrace((void*)cbTOBTStep, true, 2, new_argv);
|
||||
}
|
||||
else
|
||||
return cbDebugConditionalTrace((void*)cbTOBTStep, true, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugTraceIntoIntoTraceRecord(int argc, char* argv[])
|
||||
{
|
||||
if(argc == 1)
|
||||
{
|
||||
char* new_argv[] = { "tiit", "0" };
|
||||
return cbDebugConditionalTrace((void*)cbTIITStep, false, 2, new_argv);
|
||||
}
|
||||
else
|
||||
return cbDebugConditionalTrace((void*)cbTIITStep, false, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugTraceOverIntoTraceRecord(int argc, char* argv[])
|
||||
{
|
||||
if(argc == 1)
|
||||
{
|
||||
char* new_argv[] = { "toit", "0" };
|
||||
return cbDebugConditionalTrace((void*)cbTOITStep, true, 2, new_argv);
|
||||
}
|
||||
else
|
||||
return cbDebugConditionalTrace((void*)cbTOITStep, true, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugRunToParty(int argc, char* argv[])
|
||||
{
|
||||
HistoryClear();
|
||||
EXCLUSIVE_ACQUIRE(LockRunToUserCode);
|
||||
std::vector<MODINFO> AllModules;
|
||||
ModGetList(AllModules);
|
||||
if(!RunToUserCodeBreakpoints.empty())
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Run to party is busy.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
int party = atoi(argv[1]); // party is a signed integer
|
||||
for(auto i : AllModules)
|
||||
{
|
||||
if(i.party == party)
|
||||
{
|
||||
for(auto j : i.sections)
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(!BpGet(j.addr, BPMEMORY, nullptr, &bp))
|
||||
{
|
||||
RunToUserCodeBreakpoints.push_back(std::make_pair(j.addr, j.size));
|
||||
SetMemoryBPXEx(j.addr, j.size, UE_MEMORY_EXECUTE, false, (void*)cbRunToUserCodeBreakpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugRunToUserCode(int argc, char* argv[])
|
||||
{
|
||||
char* newargv[] = { "RunToParty", "0" };
|
||||
return cbDebugRunToParty(argc, newargv);
|
||||
}
|
|
@ -1 +1,123 @@
|
|||
#include "cmd-types.h"
|
||||
#include "cmd-types.h"
|
||||
#include "console.h"
|
||||
#include "encodemap.h"
|
||||
#include "value.h"
|
||||
|
||||
static CMDRESULT cbInstrDataGeneric(ENCODETYPE type, int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
duint size = 1;
|
||||
if(argc >= 3)
|
||||
if(!valfromstring(argv[2], &size, false))
|
||||
return STATUS_ERROR;
|
||||
bool created;
|
||||
if(!EncodeMapSetType(addr, size, type, &created))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "EncodeMapSetType failed..."));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(created)
|
||||
DbgCmdExec("disasm dis.sel()");
|
||||
else
|
||||
GuiUpdateDisassemblyView();
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataUnknown(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_unknown, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataByte(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_byte, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataWord(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_word, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataDword(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_dword, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataFword(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_fword, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataQword(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_qword, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataTbyte(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_tbyte, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataOword(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_oword, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataMmword(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_mmword, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataXmmword(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_xmmword, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataYmmword(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_ymmword, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataFloat(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_real4, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataDouble(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_real8, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataLongdouble(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_real10, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataAscii(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_ascii, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataUnicode(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_unicode, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataCode(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_code, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataJunk(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_junk, argc, argv);
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDataMiddle(int argc, char* argv[])
|
||||
{
|
||||
return cbInstrDataGeneric(enc_middle, argc, argv);
|
||||
}
|
|
@ -1 +1,473 @@
|
|||
#include "cmd-undocumented.h"
|
||||
#include "cmd-undocumented.h"
|
||||
#include "console.h"
|
||||
#include "function.h"
|
||||
#include "bookmark.h"
|
||||
#include "label.h"
|
||||
#include "comment.h"
|
||||
#include "debugger.h"
|
||||
#include "variable.h"
|
||||
#include "loop.h"
|
||||
#include "capstone_wrapper.h"
|
||||
#include "mnemonichelp.h"
|
||||
#include "value.h"
|
||||
|
||||
CMDRESULT cbBadCmd(int argc, char* argv[])
|
||||
{
|
||||
duint value = 0;
|
||||
int valsize = 0;
|
||||
bool isvar = false;
|
||||
bool hexonly = false;
|
||||
if(valfromstring(*argv, &value, false, false, &valsize, &isvar, &hexonly, true)) //dump variable/value/register/etc
|
||||
{
|
||||
varset("$ans", value, true);
|
||||
//dprintf(QT_TRANSLATE_NOOP("DBG", "[DEBUG] valsize: %d\n"), valsize);
|
||||
if(valsize)
|
||||
valsize *= 2;
|
||||
else
|
||||
valsize = 1;
|
||||
char format_str[deflen] = "";
|
||||
if(isvar) // and *cmd!='.' and *cmd!='x') //prevent stupid 0=0 stuff
|
||||
{
|
||||
if(value > 9 && !hexonly)
|
||||
{
|
||||
if(!valuesignedcalc()) //signed numbers
|
||||
#ifdef _WIN64
|
||||
sprintf_s(format_str, "%%s=%%.%dllX (%%llud)\n", valsize); // TODO: This and the following statements use "%llX" for a "int"-typed variable. Maybe we can use "%X" everywhere?
|
||||
#else //x86
|
||||
sprintf_s(format_str, "%%s=%%.%dX (%%ud)\n", valsize);
|
||||
#endif //_WIN64
|
||||
else
|
||||
#ifdef _WIN64
|
||||
sprintf_s(format_str, "%%s=%%.%dllX (%%lld)\n", valsize);
|
||||
#else //x86
|
||||
sprintf_s(format_str, "%%s=%%.%dX (%%d)\n", valsize);
|
||||
#endif //_WIN64
|
||||
dprintf_untranslated(format_str, *argv, value, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(format_str, "%%s=%%.%dX\n", valsize);
|
||||
dprintf_untranslated(format_str, *argv, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(value > 9 && !hexonly)
|
||||
{
|
||||
if(!valuesignedcalc()) //signed numbers
|
||||
#ifdef _WIN64
|
||||
sprintf_s(format_str, "%%s=%%.%dllX (%%llud)\n", valsize);
|
||||
#else //x86
|
||||
sprintf_s(format_str, "%%s=%%.%dX (%%ud)\n", valsize);
|
||||
#endif //_WIN64
|
||||
else
|
||||
#ifdef _WIN64
|
||||
sprintf_s(format_str, "%%s=%%.%dllX (%%lld)\n", valsize);
|
||||
#else //x86
|
||||
sprintf_s(format_str, "%%s=%%.%dX (%%d)\n", valsize);
|
||||
#endif //_WIN64
|
||||
#ifdef _WIN64
|
||||
sprintf_s(format_str, "%%.%dllX (%%llud)\n", valsize);
|
||||
#else //x86
|
||||
sprintf_s(format_str, "%%.%dX (%%ud)\n", valsize);
|
||||
#endif //_WIN64
|
||||
dprintf_untranslated(format_str, value, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _WIN64
|
||||
sprintf_s(format_str, "%%.%dllX\n", valsize);
|
||||
#else //x86
|
||||
sprintf_s(format_str, "%%.%dX\n", valsize);
|
||||
#endif //_WIN64
|
||||
dprintf_untranslated(format_str, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else //unknown command
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "unknown command/expression: \"%s\"\n"), *argv);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugBenchmark(int argc, char* argv[])
|
||||
{
|
||||
duint addr = MemFindBaseAddr(GetContextDataEx(hActiveThread, UE_CIP), 0);
|
||||
DWORD ticks = GetTickCount();
|
||||
for(duint i = addr; i < addr + 100000; i++)
|
||||
{
|
||||
CommentSet(i, "test", false);
|
||||
LabelSet(i, "test", false);
|
||||
BookmarkSet(i, false);
|
||||
FunctionAdd(i, i, false);
|
||||
}
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%ums\n"), GetTickCount() - ticks);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrSetstr(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
varnew(argv[1], 0, VAR_USER);
|
||||
if(!vargettype(argv[1], 0))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "no such variable \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!varset(argv[1], argv[2], false))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to set variable \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
cmddirectexec(StringUtils::sprintf("getstr \"%s\"", argv[1]).c_str());
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrGetstr(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
VAR_VALUE_TYPE valtype;
|
||||
if(!vargettype(argv[1], 0, &valtype))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "no such variable \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(valtype != VAR_STRING)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "variable \"%s\" is not a string!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
int size;
|
||||
if(!varget(argv[1], (char*)0, &size, 0) || !size)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to get variable size \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
Memory<char*> string(size + 1, "cbInstrGetstr:string");
|
||||
if(!varget(argv[1], string(), &size, 0))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to get variable data \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf_untranslated("%s=\"%s\"\n", argv[1], string());
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrCopystr(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
VAR_VALUE_TYPE valtype;
|
||||
if(!vargettype(argv[2], 0, &valtype))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "no such variable \"%s\"!\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(valtype != VAR_STRING)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "variable \"%s\" is not a string!\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
int size;
|
||||
if(!varget(argv[2], (char*)0, &size, 0) || !size)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to get variable size \"%s\"!\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
Memory<char*> string(size + 1, "cbInstrGetstr:string");
|
||||
if(!varget(argv[2], string(), &size, 0))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "failed to get variable data \"%s\"!\n"), argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint addr;
|
||||
if(!valfromstring(argv[1], &addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid address \"%s\"!\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!MemPatch(addr, string(), strlen(string())))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "memwrite failed!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "string written!"));
|
||||
GuiUpdateAllViews();
|
||||
GuiUpdatePatches();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrLoopList(int argc, char* argv[])
|
||||
{
|
||||
//setup reference view
|
||||
GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Loops")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Start")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "End")));
|
||||
GuiReferenceAddColumn(64, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly (Start)")));
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Label/Comment")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
LoopEnum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "no loops"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<LOOPSINFO*> loops(cbsize, "cbInstrLoopList:loops");
|
||||
LoopEnum(loops(), 0);
|
||||
int count = (int)(cbsize / sizeof(LOOPSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
GuiReferenceSetRowCount(i + 1);
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", loops()[i].start);
|
||||
GuiReferenceSetCellContent(i, 0, addrText);
|
||||
sprintf(addrText, "%p", loops()[i].end);
|
||||
GuiReferenceSetCellContent(i, 1, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly(loops()[i].start, disassembly))
|
||||
GuiReferenceSetCellContent(i, 2, disassembly);
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(LabelGet(loops()[i].start, label))
|
||||
GuiReferenceSetCellContent(i, 3, label);
|
||||
else
|
||||
{
|
||||
char comment[MAX_COMMENT_SIZE] = "";
|
||||
if(CommentGet(loops()[i].start, comment))
|
||||
GuiReferenceSetCellContent(i, 3, comment);
|
||||
}
|
||||
}
|
||||
varset("$result", count, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d loop(s) listed\n"), count);
|
||||
GuiReferenceReloadData();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrCapstone(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr) || !MemIsValidReadPtr(addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid address \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
unsigned char data[16];
|
||||
if(!MemRead(addr, data, sizeof(data)))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "could not read memory at %p\n"), addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(argc > 2)
|
||||
if(!valfromstring(argv[2], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
|
||||
Capstone cp;
|
||||
if(!cp.Disassemble(addr, data))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to disassemble!\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
const cs_insn* instr = cp.GetInstr();
|
||||
const cs_x86 & x86 = cp.x86();
|
||||
int argcount = x86.op_count;
|
||||
dprintf("%s %s\n", instr->mnemonic, instr->op_str);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "size: %d, id: %d, opcount: %d\n"), cp.Size(), cp.GetId(), cp.OpCount());
|
||||
for(int i = 0; i < argcount; i++)
|
||||
{
|
||||
const cs_x86_op & op = x86.operands[i];
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "operand \"%s\" %d, "), cp.OperandText(i).c_str(), i + 1);
|
||||
switch(op.type)
|
||||
{
|
||||
case X86_OP_REG:
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "register: %s\n"), cp.RegName((x86_reg)op.reg));
|
||||
break;
|
||||
case X86_OP_IMM:
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "immediate: 0x%p\n"), op.imm);
|
||||
break;
|
||||
case X86_OP_MEM:
|
||||
{
|
||||
//[base + index * scale +/- disp]
|
||||
const x86_op_mem & mem = op.mem;
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "memory segment: %s, base: %s, index: %s, scale: %d, displacement: 0x%p\n"),
|
||||
cp.RegName((x86_reg)mem.segment),
|
||||
cp.RegName((x86_reg)mem.base),
|
||||
cp.RegName((x86_reg)mem.index),
|
||||
mem.scale,
|
||||
mem.disp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrVisualize(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint start;
|
||||
duint maxaddr;
|
||||
if(!valfromstring(argv[1], &start) || !valfromstring(argv[2], &maxaddr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "invalid arguments!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//actual algorithm
|
||||
//make sure to set these options in the INI (rest the default theme of x64dbg):
|
||||
//DisassemblyBookmarkBackgroundColor = #00FFFF
|
||||
//DisassemblyBookmarkColor = #000000
|
||||
//DisassemblyHardwareBreakpointBackgroundColor = #00FF00
|
||||
//DisassemblyHardwareBreakpointColor = #000000
|
||||
//DisassemblyBreakpointBackgroundColor = #FF0000
|
||||
//DisassemblyBreakpointColor = #000000
|
||||
{
|
||||
//initialize
|
||||
Capstone _cp;
|
||||
duint _base = start;
|
||||
duint _size = maxaddr - start;
|
||||
Memory<unsigned char*> _data(_size);
|
||||
MemRead(_base, _data(), _size);
|
||||
FunctionClear();
|
||||
|
||||
//linear search with some trickery
|
||||
duint end = 0;
|
||||
duint jumpback = 0;
|
||||
for(duint addr = start, fardest = 0; addr < maxaddr;)
|
||||
{
|
||||
//update GUI
|
||||
BpClear();
|
||||
BookmarkClear();
|
||||
LabelClear();
|
||||
SetContextDataEx(fdProcessInfo->hThread, UE_CIP, addr);
|
||||
if(end)
|
||||
BpNew(end, true, false, 0, BPNORMAL, 0, nullptr);
|
||||
if(jumpback)
|
||||
BookmarkSet(jumpback, false);
|
||||
if(fardest)
|
||||
BpNew(fardest, true, false, 0, BPHARDWARE, 0, nullptr);
|
||||
DebugUpdateGuiAsync(addr, false);
|
||||
Sleep(300);
|
||||
|
||||
//continue algorithm
|
||||
const unsigned char* curData = (addr >= _base && addr < _base + _size) ? _data() + (addr - _base) : nullptr;
|
||||
if(_cp.Disassemble(addr, curData, MAX_DISASM_BUFFER))
|
||||
{
|
||||
if(addr + _cp.Size() > maxaddr) //we went past the maximum allowed address
|
||||
break;
|
||||
|
||||
const cs_x86_op & operand = _cp.x86().operands[0];
|
||||
if((_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) && operand.type == X86_OP_IMM) //jump
|
||||
{
|
||||
duint dest = (duint)operand.imm;
|
||||
|
||||
if(dest >= maxaddr) //jump across function boundaries
|
||||
{
|
||||
//currently unused
|
||||
}
|
||||
else if(dest > addr && dest > fardest) //save the farthest JXX destination forward
|
||||
{
|
||||
fardest = dest;
|
||||
}
|
||||
else if(end && dest < end && _cp.GetId() == X86_INS_JMP) //save the last JMP backwards
|
||||
{
|
||||
jumpback = addr;
|
||||
}
|
||||
}
|
||||
else if(_cp.InGroup(CS_GRP_RET)) //possible function end?
|
||||
{
|
||||
end = addr;
|
||||
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET
|
||||
break;
|
||||
}
|
||||
|
||||
addr += _cp.Size();
|
||||
}
|
||||
else
|
||||
addr++;
|
||||
}
|
||||
end = end < jumpback ? jumpback : end;
|
||||
|
||||
//update GUI
|
||||
FunctionAdd(start, end, false);
|
||||
BpClear();
|
||||
BookmarkClear();
|
||||
SetContextDataEx(fdProcessInfo->hThread, UE_CIP, start);
|
||||
DebugUpdateGuiAsync(start, false);
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrMeminfo(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "usage: meminfo a/r, addr"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint addr;
|
||||
if(!valfromstring(argv[2], &addr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "invalid argument"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(argv[1][0] == 'a')
|
||||
{
|
||||
unsigned char buf = 0;
|
||||
if(!ReadProcessMemory(fdProcessInfo->hProcess, (void*)addr, &buf, sizeof(buf), nullptr))
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "ReadProcessMemory failed!"));
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "data: %02X\n"), buf);
|
||||
}
|
||||
else if(argv[1][0] == 'r')
|
||||
{
|
||||
MemUpdateMap();
|
||||
GuiUpdateMemoryView();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "memory map updated!"));
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrBriefcheck(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
duint size;
|
||||
auto base = DbgMemFindBaseAddr(addr, &size);
|
||||
if(!base)
|
||||
return STATUS_ERROR;
|
||||
Memory<unsigned char*> buffer(size + 16);
|
||||
DbgMemRead(base, buffer(), size);
|
||||
Capstone cp;
|
||||
std::unordered_set<String> reported;
|
||||
for(duint i = 0; i < size;)
|
||||
{
|
||||
if(!cp.Disassemble(base + i, buffer() + i, 16))
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
i += cp.Size();
|
||||
auto mnem = StringUtils::ToLower(cp.MnemonicId());
|
||||
auto brief = MnemonicHelp::getBriefDescription(mnem.c_str());
|
||||
if(brief.length() || reported.count(mnem))
|
||||
continue;
|
||||
reported.insert(mnem);
|
||||
dprintf("%p: %s\n", cp.Address(), mnem.c_str());
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "command.h"
|
||||
|
||||
CMDRESULT cbBadCmd(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugBenchmark(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrSetstr(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrGetstr(int argc, char* argv[]);
|
||||
|
|
|
@ -1 +1,435 @@
|
|||
#include "cmd-user-database.h"
|
||||
#include "cmd-user-database.h"
|
||||
#include "database.h"
|
||||
#include "console.h"
|
||||
#include "comment.h"
|
||||
#include "value.h"
|
||||
#include "variable.h"
|
||||
#include "label.h"
|
||||
#include "bookmark.h"
|
||||
#include "function.h"
|
||||
#include "argument.h"
|
||||
|
||||
CMDRESULT cbInstrDbsave(int argc, char* argv[])
|
||||
{
|
||||
DbSave(DbLoadSaveType::All);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDbload(int argc, char* argv[])
|
||||
{
|
||||
DbClear();
|
||||
DbLoad(DbLoadSaveType::All);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrDbclear(int argc, char* argv[])
|
||||
{
|
||||
DbClear();
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrCommentSet(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!CommentSet(addr, argv[2], true))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "error setting comment"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrCommentDel(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!CommentDelete(addr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "error deleting comment"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrCommentList(int argc, char* argv[])
|
||||
{
|
||||
//setup reference view
|
||||
GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Comments")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(64, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceAddColumn(10, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Comment")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
CommentEnum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "no comments"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<COMMENTSINFO*> comments(cbsize, "cbInstrCommentList:comments");
|
||||
CommentEnum(comments(), 0);
|
||||
int count = (int)(cbsize / sizeof(COMMENTSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
GuiReferenceSetRowCount(i + 1);
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", comments()[i].addr);
|
||||
GuiReferenceSetCellContent(i, 0, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly(comments()[i].addr, disassembly))
|
||||
GuiReferenceSetCellContent(i, 1, disassembly);
|
||||
GuiReferenceSetCellContent(i, 2, comments()[i].text);
|
||||
}
|
||||
varset("$result", count, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d comment(s) listed in Reference View\n"), count);
|
||||
GuiReferenceReloadData();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrCommentClear(int argc, char* argv[])
|
||||
{
|
||||
CommentClear();
|
||||
GuiUpdateAllViews();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "all comments deleted!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrLabelSet(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!LabelSet(addr, argv[2], true))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "error setting label"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrLabelDel(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!LabelDelete(addr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "error deleting label"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrLabelList(int argc, char* argv[])
|
||||
{
|
||||
//setup reference view
|
||||
GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Labels")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(64, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Label")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
LabelEnum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "no labels"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<LABELSINFO*> labels(cbsize, "cbInstrLabelList:labels");
|
||||
LabelEnum(labels(), 0);
|
||||
int count = (int)(cbsize / sizeof(LABELSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
GuiReferenceSetRowCount(i + 1);
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", labels()[i].addr);
|
||||
GuiReferenceSetCellContent(i, 0, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly(labels()[i].addr, disassembly))
|
||||
GuiReferenceSetCellContent(i, 1, disassembly);
|
||||
GuiReferenceSetCellContent(i, 2, labels()[i].text);
|
||||
}
|
||||
varset("$result", count, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d label(s) listed in Reference View\n"), count);
|
||||
GuiReferenceReloadData();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrLabelClear(int argc, char* argv[])
|
||||
{
|
||||
LabelClear();
|
||||
GuiUpdateAllViews();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "all labels deleted!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrBookmarkSet(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!BookmarkSet(addr, true))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to set bookmark!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "bookmark set!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrBookmarkDel(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!BookmarkDelete(addr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to delete bookmark!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "bookmark deleted!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrBookmarkList(int argc, char* argv[])
|
||||
{
|
||||
//setup reference view
|
||||
GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Bookmarks")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
BookmarkEnum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No bookmarks found"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<BOOKMARKSINFO*> bookmarks(cbsize, "cbInstrBookmarkList:bookmarks");
|
||||
BookmarkEnum(bookmarks(), 0);
|
||||
int count = (int)(cbsize / sizeof(BOOKMARKSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
GuiReferenceSetRowCount(i + 1);
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", bookmarks()[i].addr);
|
||||
GuiReferenceSetCellContent(i, 0, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly(bookmarks()[i].addr, disassembly))
|
||||
GuiReferenceSetCellContent(i, 1, disassembly);
|
||||
}
|
||||
varset("$result", count, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d bookmark(s) listed\n"), count);
|
||||
GuiReferenceReloadData();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrBookmarkClear(int argc, char* argv[])
|
||||
{
|
||||
LabelClear();
|
||||
GuiUpdateAllViews();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "all bookmarks deleted!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFunctionAdd(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint start = 0;
|
||||
duint end = 0;
|
||||
if(!valfromstring(argv[1], &start, false) || !valfromstring(argv[2], &end, false))
|
||||
return STATUS_ERROR;
|
||||
if(!FunctionAdd(start, end, true))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to add function"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "function added!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFunctionDel(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!FunctionDelete(addr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to delete function"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "function deleted!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFunctionList(int argc, char* argv[])
|
||||
{
|
||||
//setup reference view
|
||||
GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Functions")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Start")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "End")));
|
||||
GuiReferenceAddColumn(64, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly (Start)")));
|
||||
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Label/Comment")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
FunctionEnum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No functions"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<FUNCTIONSINFO*> functions(cbsize, "cbInstrFunctionList:functions");
|
||||
FunctionEnum(functions(), 0);
|
||||
int count = (int)(cbsize / sizeof(FUNCTIONSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
GuiReferenceSetRowCount(i + 1);
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", functions()[i].start);
|
||||
GuiReferenceSetCellContent(i, 0, addrText);
|
||||
sprintf(addrText, "%p", functions()[i].end);
|
||||
GuiReferenceSetCellContent(i, 1, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly(functions()[i].start, disassembly))
|
||||
GuiReferenceSetCellContent(i, 2, disassembly);
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(LabelGet(functions()[i].start, label))
|
||||
GuiReferenceSetCellContent(i, 3, label);
|
||||
else
|
||||
{
|
||||
char comment[MAX_COMMENT_SIZE] = "";
|
||||
if(CommentGet(functions()[i].start, comment))
|
||||
GuiReferenceSetCellContent(i, 3, comment);
|
||||
}
|
||||
}
|
||||
varset("$result", count, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d function(s) listed\n"), count);
|
||||
GuiReferenceReloadData();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrFunctionClear(int argc, char* argv[])
|
||||
{
|
||||
FunctionClear();
|
||||
GuiUpdateAllViews();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "all functions deleted!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrArgumentAdd(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 3))
|
||||
return STATUS_ERROR;
|
||||
duint start = 0;
|
||||
duint end = 0;
|
||||
if(!valfromstring(argv[1], &start, false) || !valfromstring(argv[2], &end, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ArgumentAdd(start, end, true))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to add argument"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "argument added!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrArgumentDel(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ArgumentDelete(addr))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "failed to delete argument"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "argument deleted!"));
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrArgumentList(int argc, char* argv[])
|
||||
{
|
||||
//setup reference view
|
||||
GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Arguments")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Start")));
|
||||
GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "End")));
|
||||
GuiReferenceAddColumn(64, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly (Start)")));
|
||||
GuiReferenceAddColumn(10, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Label/Comment")));
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
ArgumentEnum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No arguments"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<ARGUMENTSINFO*> arguments(cbsize, "cbInstrArgumentList:arguments");
|
||||
ArgumentEnum(arguments(), 0);
|
||||
int count = (int)(cbsize / sizeof(ARGUMENTSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
GuiReferenceSetRowCount(i + 1);
|
||||
char addrText[20] = "";
|
||||
sprintf(addrText, "%p", arguments()[i].start);
|
||||
GuiReferenceSetCellContent(i, 0, addrText);
|
||||
sprintf(addrText, "%p", arguments()[i].end);
|
||||
GuiReferenceSetCellContent(i, 1, addrText);
|
||||
char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = "";
|
||||
if(GuiGetDisassembly(arguments()[i].start, disassembly))
|
||||
GuiReferenceSetCellContent(i, 2, disassembly);
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(LabelGet(arguments()[i].start, label))
|
||||
GuiReferenceSetCellContent(i, 3, label);
|
||||
else
|
||||
{
|
||||
char comment[MAX_COMMENT_SIZE] = "";
|
||||
if(CommentGet(arguments()[i].start, comment))
|
||||
GuiReferenceSetCellContent(i, 3, comment);
|
||||
}
|
||||
}
|
||||
varset("$result", count, false);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "%d argument(s) listed\n"), count);
|
||||
GuiReferenceReloadData();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrArgumentClear(int argc, char* argv[])
|
||||
{
|
||||
ArgumentClear();
|
||||
GuiUpdateAllViews();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "all arguments deleted!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,115 @@
|
|||
#include "cmd-variables.h"
|
||||
#include "cmd-variables.h"
|
||||
#include "console.h"
|
||||
#include "variable.h"
|
||||
#include "value.h"
|
||||
|
||||
CMDRESULT cbInstrVar(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
char arg2[deflen] = ""; //var value (optional)
|
||||
if(argc > 2)
|
||||
strcpy_s(arg2, argv[2]);
|
||||
duint value = 0;
|
||||
int add = 0;
|
||||
if(*argv[1] == '$')
|
||||
add++;
|
||||
if(valfromstring(argv[1] + add, &value))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid variable name \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!valfromstring(arg2, &value))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "invalid value \"%s\"\n"), arg2);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!varnew(argv[1], value, VAR_USER))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "error creating variable \"%s\"\n"), argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(value > 15)
|
||||
#ifdef _WIN64
|
||||
dprintf_untranslated("%s=%llX (%llud)\n", argv[1], value, value);
|
||||
#else //x86
|
||||
dprintf_untranslated("%s=%X (%ud)\n", argv[1], value, value);
|
||||
#endif //_WIN64
|
||||
else
|
||||
#ifdef _WIN64
|
||||
dprintf_untranslated("%s=%llX\n", argv[1], value);
|
||||
#else //x86
|
||||
dprintf_untranslated("%s=%X\n", argv[1], value);
|
||||
#endif //_WIN64
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrVarDel(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return STATUS_ERROR;
|
||||
if(!vardel(argv[1], false))
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "could not delete variable \"%s\"\n"), argv[1]);
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "deleted variable \"%s\"\n"), argv[1]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrVarList(int argc, char* argv[])
|
||||
{
|
||||
int filter = 0;
|
||||
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))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "no variables!"));
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<VAR*> variables(cbsize, "cbInstrVarList:variables");
|
||||
if(!varenum(variables(), 0))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "error listing variables!"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
int varcount = (int)cbsize / sizeof(VAR);
|
||||
for(int i = 0; i < varcount; i++)
|
||||
{
|
||||
if(variables()[i].alias.length())
|
||||
continue;
|
||||
char name[deflen] = "";
|
||||
strcpy_s(name, variables()[i].name.c_str());
|
||||
duint value = (duint)variables()[i].value.u.value;
|
||||
if(variables()[i].type != VAR_HIDDEN)
|
||||
{
|
||||
if(!filter || variables()[i].type == filter)
|
||||
{
|
||||
if(value > 15)
|
||||
#ifdef _WIN64
|
||||
dprintf_untranslated("%s=%llX (%llud)\n", name, value, value);
|
||||
#else //x86
|
||||
dprintf_untranslated("%s=%X (%ud)\n", name, value, value);
|
||||
#endif //_WIN64
|
||||
else
|
||||
#ifdef _WIN64
|
||||
dprintf_untranslated("%s=%llX\n", name, value);
|
||||
#else //x86
|
||||
dprintf_untranslated("%s=%X\n", name, value);
|
||||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -1 +1,166 @@
|
|||
#include "cmd-watch-control.h"
|
||||
#include "cmd-watch-control.h"
|
||||
#include "variable.h"
|
||||
#include "watch.h"
|
||||
#include "console.h"
|
||||
#include "threading.h"
|
||||
|
||||
CMDRESULT cbAddWatch(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for addwatch\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
WATCHVARTYPE newtype = WATCHVARTYPE::TYPE_UINT;
|
||||
if(argc > 2)
|
||||
{
|
||||
if(_stricmp(argv[2], "uint") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_UINT;
|
||||
else if(_stricmp(argv[2], "int") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_INT;
|
||||
else if(_stricmp(argv[2], "float") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_FLOAT;
|
||||
else if(_stricmp(argv[2], "ascii") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_ASCII;
|
||||
else if(_stricmp(argv[2], "unicode") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_UNICODE;
|
||||
}
|
||||
unsigned int newid = WatchAddExpr(argv[1], newtype);
|
||||
varset("$result", newid, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDelWatch(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for delwatch\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint id;
|
||||
bool ok = valfromstring(argv[1], &id);
|
||||
if(!ok)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error expression in argument 1.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
WatchDelete((unsigned int)id);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbSetWatchdog(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for delwatch\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint id;
|
||||
bool ok = valfromstring(argv[1], &id);
|
||||
if(!ok)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error expression in argument 1.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
WATCHDOGMODE mode;
|
||||
if(argc > 2)
|
||||
{
|
||||
if(_stricmp(argv[2], "disabled") == 0)
|
||||
mode = WATCHDOGMODE::MODE_DISABLED;
|
||||
else if(_stricmp(argv[2], "changed") == 0)
|
||||
mode = WATCHDOGMODE::MODE_CHANGED;
|
||||
else if(_stricmp(argv[2], "unchanged") == 0)
|
||||
mode = WATCHDOGMODE::MODE_UNCHANGED;
|
||||
else if(_stricmp(argv[2], "istrue") == 0)
|
||||
mode = WATCHDOGMODE::MODE_ISTRUE;
|
||||
else if(_stricmp(argv[2], "isfalse") == 0)
|
||||
mode = WATCHDOGMODE::MODE_ISFALSE;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown watchdog mode.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
mode = (WatchGetWatchdogEnabled((unsigned int)id) == WATCHDOGMODE::MODE_DISABLED) ? WATCHDOGMODE::MODE_CHANGED : WATCHDOGMODE::MODE_DISABLED;
|
||||
WatchSetWatchdogMode((unsigned int)id, mode);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbSetWatchExpression(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for SetWatchExpression"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint id;
|
||||
bool ok = valfromstring(argv[1], &id);
|
||||
if(ok)
|
||||
{
|
||||
WATCHVARTYPE varType;
|
||||
if(argc > 3)
|
||||
{
|
||||
if(_stricmp(argv[3], "uint") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_UINT;
|
||||
else if(_stricmp(argv[3], "int") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_INT;
|
||||
else if(_stricmp(argv[3], "float") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_FLOAT;
|
||||
else if(_stricmp(argv[3], "ascii") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_ASCII;
|
||||
else if(_stricmp(argv[3], "unicode") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_UNICODE;
|
||||
else
|
||||
varType = WATCHVARTYPE::TYPE_UINT;
|
||||
}
|
||||
else
|
||||
varType = WATCHVARTYPE::TYPE_UINT;
|
||||
WatchModifyExpr((unsigned int)id, argv[2], varType);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error expression in argument 1.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
CMDRESULT cbSetWatchName(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for SetWatchName"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint id;
|
||||
bool ok = valfromstring(argv[1], &id);
|
||||
if(ok)
|
||||
{
|
||||
WatchModifyName((unsigned int)id, argv[2]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error expression in argument 1.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
CMDRESULT cbCheckWatchdog(int argc, char* argv[])
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockWatch);
|
||||
bool watchdogTriggered = false;
|
||||
for(auto j = watchexpr.begin(); j != watchexpr.end(); j++)
|
||||
{
|
||||
std::pair<unsigned int, WatchExpr*> i = *j;
|
||||
i.second->watchdogTriggered = false;
|
||||
duint intVal = i.second->getIntValue();
|
||||
watchdogTriggered |= i.second->watchdogTriggered;
|
||||
}
|
||||
EXCLUSIVE_RELEASE();
|
||||
if(watchdogTriggered)
|
||||
GuiUpdateWatchViewAsync();
|
||||
varset("$result", watchdogTriggered ? 1 : 0, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
#include "threading.h"
|
||||
#include "command.h"
|
||||
#include "database.h"
|
||||
#include "addrinfo.h"
|
||||
#include "watch.h"
|
||||
#include "thread.h"
|
||||
#include "plugin_loader.h"
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
#include "TitanEngine\TitanEngine.h"
|
||||
#include "command.h"
|
||||
#include "breakpoint.h"
|
||||
#include "undocumented.h"
|
||||
#include "expressionparser.h"
|
||||
#include "value.h"
|
||||
#include "_plugins.h"
|
||||
|
||||
//structures
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +0,0 @@
|
|||
#ifndef _DEBUGGER_COMMANDS_H
|
||||
#define _DEBUGGER_COMMANDS_H
|
||||
|
||||
#include "command.h"
|
||||
#include "debugger.h"
|
||||
|
||||
//command callbacks
|
||||
CMDRESULT cbDebugRunInternal(int argc, char* argv[]);
|
||||
|
||||
//misc
|
||||
void showcommandlineerror(cmdline_error_t* cmdline_error);
|
||||
|
||||
#endif //_DEBUGGER_COMMANDS_H
|
|
@ -6,11 +6,8 @@
|
|||
|
||||
#include "exhandlerinfo.h"
|
||||
#include "memory.h"
|
||||
#include "disasm_helper.h"
|
||||
#include "disasm_fast.h"
|
||||
#include "_exports.h"
|
||||
#include "module.h"
|
||||
#include "thread.h"
|
||||
#include "value.h"
|
||||
|
||||
bool ExHandlerGetInfo(EX_HANDLER_TYPE Type, std::vector<duint> & Entries)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +0,0 @@
|
|||
#ifndef _INSTRUCTION_H
|
||||
#define _INSTRUCTION_H
|
||||
|
||||
#include "command.h"
|
||||
|
||||
//functions
|
||||
CMDRESULT cbBadCmd(int argc, char* argv[]);
|
||||
|
||||
#endif // _INSTRUCTION_H
|
|
@ -10,7 +10,6 @@
|
|||
#include "threading.h"
|
||||
#include "thread.h"
|
||||
#include "module.h"
|
||||
#include "console.h"
|
||||
#include "taskthread.h"
|
||||
|
||||
#define PAGE_SHIFT (12)
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
#include "mnemonichelp.h"
|
||||
#include "threading.h"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <locale>
|
||||
|
||||
static std::unordered_map<String, String> MnemonicMap;
|
||||
static std::unordered_map<String, String> MnemonicBriefMap;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define _MSGQUEUE_H
|
||||
|
||||
#include "_global.h"
|
||||
#include <windows.h>
|
||||
#include <agents.h>
|
||||
|
||||
#define MAX_MESSAGES 256
|
||||
|
|
|
@ -627,7 +627,7 @@ bool pluginload(const char* pluginName)
|
|||
bool pluginunload(const char* pluginName)
|
||||
{
|
||||
bool foundPlugin = false;
|
||||
PLUGSTOP stop;
|
||||
PLUGSTOP stop = nullptr;
|
||||
PLUG_DATA currentPlugin;
|
||||
char name[MAX_PATH] = "";
|
||||
strncpy(name, pluginName, MAX_PATH);
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
#include "simplescript.h"
|
||||
#include "console.h"
|
||||
#include "variable.h"
|
||||
#include "x64dbg.h"
|
||||
#include "debugger.h"
|
||||
#include "filehelper.h"
|
||||
#include "stringformat.h"
|
||||
|
||||
static std::vector<LINEMAPENTRY> linemap;
|
||||
|
||||
|
@ -621,33 +619,3 @@ bool scriptgetbranchinfo(int line, SCRIPTBRANCH* info)
|
|||
memcpy(info, &linemap.at(line - 1).u.branch, sizeof(SCRIPTBRANCH));
|
||||
return true;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptLoad(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
return STATUS_ERROR;
|
||||
scriptload(argv[1]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptMsg(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "not enough arguments!")));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiScriptMessage(stringformatinline(argv[1]).c_str());
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbScriptMsgyn(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "not enough arguments!")));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
varset("$RESULT", GuiScriptMsgyn(stringformatinline(argv[1]).c_str()), false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
#include "module.h"
|
||||
#include "label.h"
|
||||
#include "addrinfo.h"
|
||||
|
||||
struct SYMBOLCBDATA
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "_global.h"
|
||||
#include "debugger.h"
|
||||
#include "undocumented.h"
|
||||
|
||||
void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread);
|
||||
void ThreadExit(DWORD ThreadId);
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
#include "watch.h"
|
||||
#include "console.h"
|
||||
#include "variable.h"
|
||||
#include "value.h"
|
||||
#include "threading.h"
|
||||
#include "debugger.h"
|
||||
#include "symbolinfo.h"
|
||||
#include "taskthread.h"
|
||||
#include <Windows.h>
|
||||
|
||||
|
@ -411,165 +408,4 @@ void WatchCacheLoad(JSON root)
|
|||
WatchSetWatchdogModeUnlocked(id, watchdog_mode);
|
||||
}
|
||||
WatchInitIdCounter(); // Initialize id counter so that it begin with a unused value
|
||||
}
|
||||
|
||||
CMDRESULT cbCheckWatchdog(int argc, char* argv[])
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockWatch);
|
||||
bool watchdogTriggered = false;
|
||||
for(auto j = watchexpr.begin(); j != watchexpr.end(); j++)
|
||||
{
|
||||
std::pair<unsigned int, WatchExpr*> i = *j;
|
||||
i.second->watchdogTriggered = false;
|
||||
duint intVal = i.second->getIntValue();
|
||||
watchdogTriggered |= i.second->watchdogTriggered;
|
||||
}
|
||||
EXCLUSIVE_RELEASE();
|
||||
if(watchdogTriggered)
|
||||
GuiUpdateWatchViewAsync();
|
||||
varset("$result", watchdogTriggered ? 1 : 0, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbAddWatch(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for addwatch\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
WATCHVARTYPE newtype = WATCHVARTYPE::TYPE_UINT;
|
||||
if(argc > 2)
|
||||
{
|
||||
if(_stricmp(argv[2], "uint") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_UINT;
|
||||
else if(_stricmp(argv[2], "int") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_INT;
|
||||
else if(_stricmp(argv[2], "float") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_FLOAT;
|
||||
else if(_stricmp(argv[2], "ascii") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_ASCII;
|
||||
else if(_stricmp(argv[2], "unicode") == 0)
|
||||
newtype = WATCHVARTYPE::TYPE_UNICODE;
|
||||
}
|
||||
unsigned int newid = WatchAddExpr(argv[1], newtype);
|
||||
varset("$result", newid, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDelWatch(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for delwatch\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint id;
|
||||
bool ok = valfromstring(argv[1], &id);
|
||||
if(!ok)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error expression in argument 1.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
WatchDelete((unsigned int)id);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbSetWatchName(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for SetWatchName"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint id;
|
||||
bool ok = valfromstring(argv[1], &id);
|
||||
if(ok)
|
||||
{
|
||||
WatchModifyName((unsigned int)id, argv[2]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error expression in argument 1.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
CMDRESULT cbSetWatchExpression(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for SetWatchExpression"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint id;
|
||||
bool ok = valfromstring(argv[1], &id);
|
||||
if(ok)
|
||||
{
|
||||
WATCHVARTYPE varType;
|
||||
if(argc > 3)
|
||||
{
|
||||
if(_stricmp(argv[3], "uint") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_UINT;
|
||||
else if(_stricmp(argv[3], "int") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_INT;
|
||||
else if(_stricmp(argv[3], "float") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_FLOAT;
|
||||
else if(_stricmp(argv[3], "ascii") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_ASCII;
|
||||
else if(_stricmp(argv[3], "unicode") == 0)
|
||||
varType = WATCHVARTYPE::TYPE_UNICODE;
|
||||
else
|
||||
varType = WATCHVARTYPE::TYPE_UINT;
|
||||
}
|
||||
else
|
||||
varType = WATCHVARTYPE::TYPE_UINT;
|
||||
WatchModifyExpr((unsigned int)id, argv[2], varType);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error expression in argument 1.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
CMDRESULT cbSetWatchdog(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "No enough arguments for delwatch\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint id;
|
||||
bool ok = valfromstring(argv[1], &id);
|
||||
if(!ok)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error expression in argument 1.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
WATCHDOGMODE mode;
|
||||
if(argc > 2)
|
||||
{
|
||||
if(_stricmp(argv[2], "disabled") == 0)
|
||||
mode = WATCHDOGMODE::MODE_DISABLED;
|
||||
else if(_stricmp(argv[2], "changed") == 0)
|
||||
mode = WATCHDOGMODE::MODE_CHANGED;
|
||||
else if(_stricmp(argv[2], "unchanged") == 0)
|
||||
mode = WATCHDOGMODE::MODE_UNCHANGED;
|
||||
else if(_stricmp(argv[2], "istrue") == 0)
|
||||
mode = WATCHDOGMODE::MODE_ISTRUE;
|
||||
else if(_stricmp(argv[2], "isfalse") == 0)
|
||||
mode = WATCHDOGMODE::MODE_ISFALSE;
|
||||
else
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unknown watchdog mode.\n"));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
mode = (WatchGetWatchdogEnabled((unsigned int)id) == WATCHDOGMODE::MODE_DISABLED) ? WATCHDOGMODE::MODE_CHANGED : WATCHDOGMODE::MODE_DISABLED;
|
||||
WatchSetWatchdogMode((unsigned int)id, mode);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "_global.h"
|
||||
#include "command.h"
|
||||
#include "expressionparser.h"
|
||||
#include "jansson\jansson.h"
|
||||
#include "..\bridge\bridgemain.h"
|
||||
|
||||
class WatchExpr
|
||||
{
|
||||
|
@ -56,24 +55,19 @@ public:
|
|||
|
||||
extern std::map<unsigned int, WatchExpr*> watchexpr;
|
||||
|
||||
void GuiUpdateWatchViewAsync();
|
||||
void WatchClear();
|
||||
unsigned int WatchAddExpr(const char* expr, WATCHVARTYPE type);
|
||||
bool WatchModifyExpr(unsigned int id, const char* expr, WATCHVARTYPE type);
|
||||
void WatchModifyName(unsigned int id, const char* newName);
|
||||
void WatchDelete(unsigned int id);
|
||||
void WatchSetWatchdogMode(unsigned int id, bool isEnabled);
|
||||
void WatchSetWatchdogMode(unsigned int id, WATCHDOGMODE mode);
|
||||
bool WatchIsWatchdogTriggered(unsigned int id);
|
||||
WATCHDOGMODE WatchGetWatchdogMode(unsigned int id);
|
||||
WATCHDOGMODE WatchGetWatchdogEnabled(unsigned int id);
|
||||
duint WatchGetUnsignedValue(unsigned int id);
|
||||
WATCHVARTYPE WatchGetType(unsigned int id);
|
||||
std::vector<WATCHINFO> WatchGetList();
|
||||
|
||||
void WatchCacheSave(JSON root); // Save watch data to database
|
||||
void WatchCacheLoad(JSON root); // Load watch data from database
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "_global.h"
|
||||
#include "command.h"
|
||||
#include "variable.h"
|
||||
#include "instruction.h"
|
||||
#include "debugger.h"
|
||||
#include "simplescript.h"
|
||||
#include "console.h"
|
||||
|
@ -17,7 +16,6 @@
|
|||
#include "watch.h"
|
||||
#include "plugin_loader.h"
|
||||
#include "_dbgfunctions.h"
|
||||
#include "debugger_commands.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include "_scriptapi_gui.h"
|
||||
#include "filehelper.h"
|
||||
|
@ -26,7 +24,6 @@
|
|||
#include "datainst_helper.h"
|
||||
#include "exception.h"
|
||||
#include "expressionfunctions.h"
|
||||
#include "historycontext.h"
|
||||
|
||||
static MESSAGE_STACK* gMsgStack = 0;
|
||||
static HANDLE hCommandLoopThread = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
|
@ -37,7 +37,6 @@
|
|||
<ClCompile Include="assemble.cpp" />
|
||||
<ClCompile Include="bookmark.cpp" />
|
||||
<ClCompile Include="breakpoint.cpp" />
|
||||
<ClCompile Include="breakpoint_commands.cpp" />
|
||||
<ClCompile Include="command.cpp" />
|
||||
<ClCompile Include="commandline.cpp" />
|
||||
<ClCompile Include="commandparser.cpp" />
|
||||
|
@ -66,7 +65,6 @@
|
|||
<ClCompile Include="datainst_helper.cpp" />
|
||||
<ClCompile Include="dbghelp_safe.cpp" />
|
||||
<ClCompile Include="debugger.cpp" />
|
||||
<ClCompile Include="debugger_commands.cpp" />
|
||||
<ClCompile Include="encodemap.cpp" />
|
||||
<ClCompile Include="disasm_fast.cpp" />
|
||||
<ClCompile Include="disasm_helper.cpp" />
|
||||
|
@ -80,7 +78,6 @@
|
|||
<ClCompile Include="function.cpp" />
|
||||
<ClCompile Include="historycontext.cpp" />
|
||||
<ClCompile Include="jit.cpp" />
|
||||
<ClCompile Include="instruction.cpp" />
|
||||
<ClCompile Include="label.cpp" />
|
||||
<ClCompile Include="loop.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
|
@ -179,7 +176,6 @@
|
|||
<ClInclude Include="dbghelp\dbghelp.h" />
|
||||
<ClInclude Include="dbghelp_safe.h" />
|
||||
<ClInclude Include="debugger.h" />
|
||||
<ClInclude Include="debugger_commands.h" />
|
||||
<ClInclude Include="encodemap.h" />
|
||||
<ClInclude Include="DeviceNameResolver\DeviceNameResolver.h" />
|
||||
<ClInclude Include="disasm_fast.h" />
|
||||
|
@ -205,7 +201,6 @@
|
|||
<ClInclude Include="keystone\systemz.h" />
|
||||
<ClInclude Include="keystone\x86.h" />
|
||||
<ClInclude Include="handle.h" />
|
||||
<ClInclude Include="instruction.h" />
|
||||
<ClInclude Include="jansson\jansson.h" />
|
||||
<ClInclude Include="jansson\jansson_config.h" />
|
||||
<ClInclude Include="jansson\jansson_x64dbg.h" />
|
||||
|
|
|
@ -149,12 +149,6 @@
|
|||
<ClCompile Include="symbolinfo.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="instruction.cpp">
|
||||
<Filter>Source Files\Debugger Core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="debugger_commands.cpp">
|
||||
<Filter>Source Files\Debugger Core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="debugger.cpp">
|
||||
<Filter>Source Files\Debugger Core</Filter>
|
||||
</ClCompile>
|
||||
|
@ -350,9 +344,6 @@
|
|||
<ClCompile Include="animate.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="breakpoint_commands.cpp">
|
||||
<Filter>Source Files\Debugger Core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="symcache.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
|
@ -469,12 +460,6 @@
|
|||
<ClInclude Include="debugger.h">
|
||||
<Filter>Header Files\Debugger Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="debugger_commands.h">
|
||||
<Filter>Header Files\Debugger Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="instruction.h">
|
||||
<Filter>Header Files\Debugger Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="addrinfo.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -103,7 +103,6 @@ SOURCES += \
|
|||
dbg/datainst_helper.cpp \
|
||||
dbg/dbghelp_safe.cpp \
|
||||
dbg/debugger.cpp \
|
||||
dbg/debugger_commands.cpp \
|
||||
dbg/disasm_fast.cpp \
|
||||
dbg/disasm_helper.cpp \
|
||||
dbg/encodemap.cpp \
|
||||
|
@ -116,7 +115,6 @@ SOURCES += \
|
|||
dbg/function.cpp \
|
||||
dbg/handles.cpp \
|
||||
dbg/historycontext.cpp \
|
||||
dbg/instruction.cpp \
|
||||
dbg/jit.cpp \
|
||||
dbg/label.cpp \
|
||||
dbg/log.cpp \
|
||||
|
@ -191,7 +189,25 @@ SOURCES += \
|
|||
dbg/animate.cpp \
|
||||
gui/Src/BasicView/LabeledSplitter.cpp \
|
||||
dbg/breakpoint_commands.cpp \
|
||||
dbg/symcache.cpp
|
||||
dbg/symcache.cpp \
|
||||
dbg/commands/cmd-breakpoint-control.cpp \
|
||||
dbg/commands/cmd-conditional-breakpoint-control.cpp \
|
||||
dbg/commands/cmd-data.cpp \
|
||||
dbg/commands/cmd-debug-control.cpp \
|
||||
dbg/commands/cmd-general-purpose.cpp \
|
||||
dbg/commands/cmd-gui.cpp \
|
||||
dbg/commands/cmd-memory-operations.cpp \
|
||||
dbg/commands/cmd-misc.cpp \
|
||||
dbg/commands/cmd-operating-system-control.cpp \
|
||||
dbg/commands/cmd-plugins.cpp \
|
||||
dbg/commands/cmd-script.cpp \
|
||||
dbg/commands/cmd-thread-control.cpp \
|
||||
dbg/commands/cmd-tracing.cpp \
|
||||
dbg/commands/cmd-types.cpp \
|
||||
dbg/commands/cmd-undocumented.cpp \
|
||||
dbg/commands/cmd-user-database.cpp \
|
||||
dbg/commands/cmd-variables.cpp \
|
||||
dbg/commands/cmd-watch-control.cpp
|
||||
|
||||
TRANSLATIONS = \
|
||||
gui/Translations/x64dbg.ts
|
||||
|
@ -300,7 +316,6 @@ HEADERS += \
|
|||
dbg/datainst_helper.h \
|
||||
dbg/dbghelp_safe.h \
|
||||
dbg/debugger.h \
|
||||
dbg/debugger_commands.h \
|
||||
dbg/disasm_fast.h \
|
||||
dbg/disasm_helper.h \
|
||||
dbg/dynamicmem.h \
|
||||
|
@ -315,7 +330,6 @@ HEADERS += \
|
|||
dbg/handle.h \
|
||||
dbg/handles.h \
|
||||
dbg/historycontext.h \
|
||||
dbg/instruction.h \
|
||||
dbg/jit.h \
|
||||
dbg/label.h \
|
||||
dbg/loop.h \
|
||||
|
@ -398,7 +412,25 @@ HEADERS += \
|
|||
dbg/analysis/xrefsanalysis.h \
|
||||
dbg/animate.h \
|
||||
gui/Src/BasicView/LabeledSplitter.h \
|
||||
dbg/symcache.h
|
||||
dbg/symcache.h \
|
||||
dbg/commands/cmd-breakpoint-control.h \
|
||||
dbg/commands/cmd-conditional-breakpoint-control.h \
|
||||
dbg/commands/cmd-data.h \
|
||||
dbg/commands/cmd-debug-control.h \
|
||||
dbg/commands/cmd-general-purpose.h \
|
||||
dbg/commands/cmd-gui.h \
|
||||
dbg/commands/cmd-memory-operations.h \
|
||||
dbg/commands/cmd-misc.h \
|
||||
dbg/commands/cmd-operating-system-control.h \
|
||||
dbg/commands/cmd-plugins.h \
|
||||
dbg/commands/cmd-script.h \
|
||||
dbg/commands/cmd-thread-control.h \
|
||||
dbg/commands/cmd-tracing.h \
|
||||
dbg/commands/cmd-types.h \
|
||||
dbg/commands/cmd-undocumented.h \
|
||||
dbg/commands/cmd-user-database.h \
|
||||
dbg/commands/cmd-variables.h \
|
||||
dbg/commands/cmd-watch-control.h
|
||||
|
||||
FORMS += \
|
||||
gui/Src/Gui/AppearanceDialog.ui \
|
||||
|
|
Loading…
Reference in New Issue