1
0
Fork 0

DBG: moved all commands to separate cpp files

This commit is contained in:
mrexodia 2016-09-27 03:45:28 +02:00
parent 23472fc36f
commit e4f0654326
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
51 changed files with 7043 additions and 7070 deletions

View File

@ -3,8 +3,6 @@
#include "module.h"
#include "memory.h"
#include "threading.h"
#include "console.h"
#include <algorithm>
TraceRecordManager TraceRecord;

View File

@ -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"

View File

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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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[]);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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[]);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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[]);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,9 +0,0 @@
#ifndef _INSTRUCTION_H
#define _INSTRUCTION_H
#include "command.h"
//functions
CMDRESULT cbBadCmd(int argc, char* argv[]);
#endif // _INSTRUCTION_H

View File

@ -10,7 +10,6 @@
#include "threading.h"
#include "thread.h"
#include "module.h"
#include "console.h"
#include "taskthread.h"
#define PAGE_SHIFT (12)

View File

@ -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;

View File

@ -2,7 +2,6 @@
#define _MSGQUEUE_H
#include "_global.h"
#include <windows.h>
#include <agents.h>
#define MAX_MESSAGES 256

View File

@ -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);

View File

@ -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;
}

View File

@ -8,7 +8,6 @@
#include "debugger.h"
#include "console.h"
#include "module.h"
#include "label.h"
#include "addrinfo.h"
struct SYMBOLCBDATA

View File

@ -3,6 +3,7 @@
#include "_global.h"
#include "debugger.h"
#include "undocumented.h"
void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread);
void ThreadExit(DWORD ThreadId);

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;

View File

@ -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" />

View File

@ -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>

View File

@ -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 \