Merge branch 'master' into doxygen
Conflicts: x64_dbg_bridge/bridgemain.cpp x64_dbg_dbg/addrinfo.cpp x64_dbg_dbg/value.cpp
This commit is contained in:
commit
439507f306
|
|
@ -12,18 +12,24 @@ html,body {
|
|||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<P><STRONG>plugsetup</STRONG><BR>This structure is used by the function that allows the
|
||||
creation of plugin menu entries:</P>
|
||||
<P>
|
||||
struct <STRONG>PLUG_SETUPSTRUCT</STRONG>
|
||||
<BR>{<BR> <EM>//data provided by the debugger to
|
||||
the plugin.</EM>
|
||||
<BR> [IN] <STRONG>HWND</STRONG> hwndDlg; //GUI window
|
||||
handle<BR> [IN]
|
||||
<STRONG>int</STRONG> hMenu; //plugin menu
|
||||
handle<BR>
|
||||
|
||||
<body>
|
||||
<P><STRONG>plugsetup</STRONG><BR>This structure is used by the function that allows the
|
||||
creation of plugin menu entries:</P>
|
||||
<P>
|
||||
struct <STRONG>PLUG_SETUPSTRUCT</STRONG>
|
||||
<BR>{<BR> <EM>//data provided by the debugger to
|
||||
the plugin.</EM>
|
||||
<BR> [IN] <STRONG>HWND</STRONG> hwndDlg; //GUI window
|
||||
handle<BR> [IN]
|
||||
<STRONG>int</STRONG> hMenu; //plugin menu
|
||||
handle<BR> [IN] <STRONG>int</STRONG> hMenuDisasm;
|
||||
//plugin disasm menu handle<BR> [IN] <STRONG>int</STRONG>
|
||||
hMenuDump; //plugin dump menu handle<BR> [IN]
|
||||
<STRONG>int</STRONG> hMenuStack; //plugin stack menu
|
||||
handle<BR>
|
||||
};</P></body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ copy bin\x32\jansson.dll %RELEASEDIR%\bin_base\x32\jansson.dll
|
|||
copy bin\x32\lz4.dll %RELEASEDIR%\bin_base\x32\lz4.dll
|
||||
copy bin\x32\TitanEngine.dll %RELEASEDIR%\bin_base\x32\TitanEngine.dll
|
||||
copy bin\x32\XEDParse.dll %RELEASEDIR%\bin_base\x32\XEDParse.dll
|
||||
copy bin\x32\yara.dll %RELEASEDIR%\bin_base\x32\yara.dll
|
||||
copy bin\x64\BeaEngine.dll %RELEASEDIR%\bin_base\x64\BeaEngine.dll
|
||||
copy bin\x64\dbghelp.dll %RELEASEDIR%\bin_base\x64\dbghelp.dll
|
||||
copy bin\x64\symsrv.dll %RELEASEDIR%\bin_base\x64\symsrv.dll
|
||||
|
|
@ -40,6 +41,7 @@ copy bin\x64\jansson.dll %RELEASEDIR%\bin_base\x64\jansson.dll
|
|||
copy bin\x64\lz4.dll %RELEASEDIR%\bin_base\x64\lz4.dll
|
||||
copy bin\x64\TitanEngine.dll %RELEASEDIR%\bin_base\x64\TitanEngine.dll
|
||||
copy bin\x64\XEDParse.dll %RELEASEDIR%\bin_base\x64\XEDParse.dll
|
||||
copy bin\x64\yara.dll %RELEASEDIR%\bin_base\x64\yara.dll
|
||||
|
||||
echo help
|
||||
|
||||
|
|
@ -57,6 +59,8 @@ mkdir %RELEASEDIR%\pluginsdk\jansson
|
|||
mkdir %RELEASEDIR%\pluginsdk\lz4
|
||||
mkdir %RELEASEDIR%\pluginsdk\TitanEngine
|
||||
mkdir %RELEASEDIR%\pluginsdk\XEDParse
|
||||
mkdir %RELEASEDIR%\pluginsdk\yara
|
||||
mkdir %RELEASEDIR%\pluginsdk\yara\yara
|
||||
|
||||
xcopy x64_dbg_dbg\BeaEngine %RELEASEDIR%\pluginsdk\BeaEngine /S /Y
|
||||
xcopy x64_dbg_dbg\dbghelp %RELEASEDIR%\pluginsdk\dbghelp /S /Y
|
||||
|
|
@ -66,6 +70,7 @@ xcopy x64_dbg_dbg\lz4 %RELEASEDIR%\pluginsdk\lz4 /S /Y
|
|||
xcopy x64_dbg_dbg\TitanEngine %RELEASEDIR%\pluginsdk\TitanEngine /S /Y
|
||||
del %RELEASEDIR%\pluginsdk\TitanEngine\TitanEngine.txt /F /Q
|
||||
xcopy x64_dbg_dbg\XEDParse %RELEASEDIR%\pluginsdk\XEDParse /S /Y
|
||||
xcopy x64_dbg_dbg\yara %RELEASEDIR%\pluginsdk\yara /S /Y
|
||||
copy x64_dbg_dbg\_plugin_types.h %RELEASEDIR%\pluginsdk\_plugin_types.h
|
||||
copy x64_dbg_dbg\_plugins.h %RELEASEDIR%\pluginsdk\_plugins.h
|
||||
copy x64_dbg_dbg\_dbgfunctions.h %RELEASEDIR%\pluginsdk\_dbgfunctions.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
|
||||
#define uint size_t
|
||||
#define PAGE_SIZE 0x1000
|
||||
|
||||
#ifdef _WIN64
|
||||
#define HIGHEST_USER_ADDR 0x7FFFFFEFFFF
|
||||
#else //x86
|
||||
#define HIGHEST_USER_ADDR 0x7FFEFFFF
|
||||
#endif // _WIN64
|
||||
|
||||
bool readblock(uint addr, unsigned char block[PAGE_SIZE])
|
||||
{
|
||||
printf("readblock(%X[%X])\n", addr, PAGE_SIZE);
|
||||
memset(block, 0xFF, PAGE_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool memread(uint addr, unsigned char* data, uint size)
|
||||
{
|
||||
//check if the address is inside user space
|
||||
if(addr > HIGHEST_USER_ADDR)
|
||||
return false;
|
||||
|
||||
puts("-start-");
|
||||
printf(" addr: %X\n size: %X\n", addr, size);
|
||||
|
||||
//calculate the start page
|
||||
uint start = addr & ~(PAGE_SIZE - 1);
|
||||
printf(" start: %X\n", start);
|
||||
|
||||
//calculate the end page
|
||||
uint end = addr + size;
|
||||
uint x = end & (PAGE_SIZE - 1);
|
||||
if(x)
|
||||
end += (PAGE_SIZE - x);
|
||||
printf(" end: %X\n", end);
|
||||
|
||||
//calculate the number of pages to read
|
||||
uint npages = (end - start) / PAGE_SIZE;
|
||||
printf("npages: %d\n\n", npages);
|
||||
|
||||
//go over all pages
|
||||
for(uint i = 0, j = start; i < npages; i++)
|
||||
{
|
||||
//read one page (j should always align with PAGE_SIZE)
|
||||
unsigned char block[PAGE_SIZE];
|
||||
if(!readblock(j, block))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//these are the offsets and sizes in the block to write to append to the output buffer
|
||||
uint roffset = 0;
|
||||
uint rsize = PAGE_SIZE;
|
||||
|
||||
if(i == npages - 1) //last page (first because there might only be one page)
|
||||
{
|
||||
rsize = size - (j - start); //remaining size
|
||||
}
|
||||
else if(i == 0) //first page
|
||||
{
|
||||
roffset = addr & (PAGE_SIZE - 1);
|
||||
rsize = PAGE_SIZE - roffset;
|
||||
}
|
||||
|
||||
printf("roffset: %X\n rsize: %X\n", roffset, rsize);
|
||||
puts("");
|
||||
|
||||
//copy the required block data in the output buffer
|
||||
memcpy(data, block + roffset, rsize);
|
||||
data += rsize;
|
||||
|
||||
j += rsize;
|
||||
}
|
||||
|
||||
puts("--end--\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned char out[0x10000] = {0};
|
||||
memread(0x12A45, out, 0x3456);
|
||||
memread(0x12000, out, 0x456);
|
||||
memread(0x12000, out, 0x3456);
|
||||
memread(0x12000, out, 0x4000);
|
||||
memread(0x12ff0, out, 0x16);
|
||||
memread(0x100, out, 0x3090);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
static HINSTANCE hInst;
|
||||
|
||||
static wchar_t szIniFile[MAX_PATH] = L"";
|
||||
static CRITICAL_SECTION csIni;
|
||||
|
||||
#ifdef _WIN64
|
||||
#define dbg_lib "x64_dbg.dll"
|
||||
|
|
@ -37,6 +38,9 @@ static wchar_t szIniFile[MAX_PATH] = L"";
|
|||
|
||||
BRIDGE_IMPEXP const char* BridgeInit()
|
||||
{
|
||||
//Initialize critial section
|
||||
InitializeCriticalSection(&csIni);
|
||||
|
||||
//Settings load
|
||||
if(!GetModuleFileNameW(0, szIniFile, MAX_PATH))
|
||||
return "Error getting module path!";
|
||||
|
|
@ -87,6 +91,7 @@ BRIDGE_IMPEXP const char* BridgeStart()
|
|||
if(!_dbg_dbginit || !_gui_guiinit)
|
||||
return "\"_dbg_dbginit\" || \"_gui_guiinit\" was not loaded yet, call BridgeInit!";
|
||||
_gui_guiinit(0, 0); //remove arguments
|
||||
DeleteCriticalSection(&csIni);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -111,14 +116,20 @@ BRIDGE_IMPEXP bool BridgeSettingGet(const char* section, const char* key, char*
|
|||
{
|
||||
if(!section || !key || !value)
|
||||
return false;
|
||||
EnterCriticalSection(&csIni);
|
||||
CSimpleIniA inifile(true, false, false);
|
||||
if(inifile.LoadFile(szIniFile) < 0)
|
||||
return false;
|
||||
const char* szValue = inifile.GetValue(section, key);
|
||||
if(!szValue)
|
||||
return false;
|
||||
strcpy_s(value, MAX_SETTING_SIZE, szValue);
|
||||
return true;
|
||||
bool success = false;
|
||||
if(inifile.LoadFile(szIniFile) >= 0)
|
||||
{
|
||||
const char* szValue = inifile.GetValue(section, key);
|
||||
if(szValue)
|
||||
{
|
||||
strcpy_s(value, MAX_SETTING_SIZE, szValue);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&csIni);
|
||||
return success;
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP bool BridgeSettingGetUint(const char* section, const char* key, duint* value)
|
||||
|
|
@ -140,15 +151,20 @@ BRIDGE_IMPEXP bool BridgeSettingGetUint(const char* section, const char* key, du
|
|||
|
||||
BRIDGE_IMPEXP bool BridgeSettingSet(const char* section, const char* key, const char* value)
|
||||
{
|
||||
if(!section)
|
||||
return false;
|
||||
CSimpleIniA inifile(true, false, false);
|
||||
inifile.LoadFile(szIniFile);
|
||||
if(!key || !value) //delete value/key when 0
|
||||
inifile.Delete(section, key, true);
|
||||
else
|
||||
inifile.SetValue(section, key, value);
|
||||
return inifile.SaveFile(szIniFile, false) >= 0;
|
||||
bool success = false;
|
||||
if(section)
|
||||
{
|
||||
EnterCriticalSection(&csIni);
|
||||
CSimpleIniA inifile(true, false, false);
|
||||
inifile.LoadFile(szIniFile);
|
||||
if(!key || !value) //delete value/key when 0
|
||||
inifile.Delete(section, key, true);
|
||||
else
|
||||
inifile.SetValue(section, key, value);
|
||||
success = inifile.SaveFile(szIniFile, false) >= 0;
|
||||
LeaveCriticalSection(&csIni);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP bool BridgeSettingSetUint(const char* section, const char* key, duint value)
|
||||
|
|
@ -251,7 +267,7 @@ BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text) //(
|
|||
return false;
|
||||
sprintf_s(info.label, "&%s", ptrinfo.label);
|
||||
}
|
||||
strcpy(text, info.label);
|
||||
strcpy_s(text, MAX_LABEL_SIZE, info.label);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -262,7 +278,7 @@ BRIDGE_IMPEXP bool DbgSetLabelAt(duint addr, const char* text)
|
|||
ADDRINFO info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.flags = flaglabel;
|
||||
strcpy(info.label, text);
|
||||
strcpy_s(info.label, text);
|
||||
if(!_dbg_addrinfoset(addr, &info))
|
||||
return false;
|
||||
return true;
|
||||
|
|
@ -278,7 +294,7 @@ BRIDGE_IMPEXP bool DbgGetCommentAt(duint addr, char* text) //comment (not live)
|
|||
info.flags = flagcomment;
|
||||
if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info))
|
||||
return false;
|
||||
strcpy(text, info.comment);
|
||||
strcpy_s(text, MAX_COMMENT_SIZE, info.comment);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -289,7 +305,7 @@ BRIDGE_IMPEXP bool DbgSetCommentAt(duint addr, const char* text)
|
|||
ADDRINFO info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.flags = flagcomment;
|
||||
strcpy(info.comment, text);
|
||||
strcpy_s(info.comment, MAX_COMMENT_SIZE, text);
|
||||
if(!_dbg_addrinfoset(addr, &info))
|
||||
return false;
|
||||
return true;
|
||||
|
|
@ -305,7 +321,7 @@ BRIDGE_IMPEXP bool DbgGetModuleAt(duint addr, char* text)
|
|||
info.flags = flagmodule;
|
||||
if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info))
|
||||
return false;
|
||||
strcpy(text, info.module);
|
||||
strcpy_s(text, MAX_MODULE_SIZE, info.module);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1092,4 +1108,3 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
hInst = hinstDLL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ extern "C"
|
|||
|
||||
//Bridge defines
|
||||
#define MAX_SETTING_SIZE 65536
|
||||
#define DBG_VERSION 23
|
||||
#define DBG_VERSION 24
|
||||
|
||||
//Bridge functions
|
||||
BRIDGE_IMPEXP const char* BridgeInit();
|
||||
|
|
@ -60,6 +60,7 @@ BRIDGE_IMPEXP int BridgeGetDbgVersion();
|
|||
#define MAX_STRING_SIZE 512
|
||||
#define MAX_ERROR_SIZE 512
|
||||
#define RIGHTS_STRING_SIZE (sizeof("ERWCG") + 1)
|
||||
#define MAX_SECTION_SIZE 10
|
||||
|
||||
#define TYPE_VALUE 1
|
||||
#define TYPE_MEMORY 2
|
||||
|
|
@ -423,6 +424,18 @@ typedef struct
|
|||
|
||||
} X87CONTROLWORDFIELDS;
|
||||
|
||||
typedef struct DECLSPEC_ALIGN(16) _XMMREGISTER
|
||||
{
|
||||
ULONGLONG Low;
|
||||
LONGLONG High;
|
||||
} XMMREGISTER;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
XMMREGISTER Low; //XMM/SSE part
|
||||
XMMREGISTER High; //AVX part
|
||||
} YMMREGISTER;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE data[10];
|
||||
|
|
@ -480,11 +493,11 @@ typedef struct
|
|||
X87FPU x87fpu;
|
||||
DWORD MxCsr;
|
||||
#ifdef _WIN64
|
||||
M128A XmmRegisters[16];
|
||||
BYTE YmmRegisters[32 * 16];
|
||||
XMMREGISTER XmmRegisters[16];
|
||||
YMMREGISTER YmmRegisters[16];
|
||||
#else // x86
|
||||
M128A XmmRegisters[8];
|
||||
BYTE YmmRegisters[32 * 8];
|
||||
XMMREGISTER XmmRegisters[8];
|
||||
YMMREGISTER YmmRegisters[8];
|
||||
#endif
|
||||
} REGISTERCONTEXT;
|
||||
|
||||
|
|
@ -666,6 +679,9 @@ BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message);
|
|||
|
||||
//Gui defines
|
||||
#define GUI_PLUGIN_MENU 0
|
||||
#define GUI_DISASM_MENU 1
|
||||
#define GUI_DUMP_MENU 2
|
||||
#define GUI_STACK_MENU 3
|
||||
|
||||
#define GUI_DISASSEMBLY 0
|
||||
#define GUI_DUMP 1
|
||||
|
|
|
|||
|
|
@ -10,14 +10,6 @@
|
|||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
typedef struct DECLSPEC_ALIGN(16) _M128A
|
||||
{
|
||||
ULONGLONG Low;
|
||||
LONGLONG High;
|
||||
} M128A, *PM128A;
|
||||
#endif //__GNUC__
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// Global.Constant.Structure.Declaration:
|
||||
|
|
@ -594,10 +586,16 @@ typedef struct
|
|||
DWORD OriginalCOMTableSize;
|
||||
} FILE_FIX_INFO, *PFILE_FIX_INFO;
|
||||
|
||||
typedef struct DECLSPEC_ALIGN(16) _XmmRegister_t
|
||||
{
|
||||
ULONGLONG Low;
|
||||
LONGLONG High;
|
||||
} XmmRegister_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
M128A Low; //XMM/SSE part
|
||||
M128A High; //AVX part
|
||||
XmmRegister_t Low; //XMM/SSE part
|
||||
XmmRegister_t High; //AVX part
|
||||
} YmmRegister_t;
|
||||
|
||||
typedef struct
|
||||
|
|
@ -657,10 +655,10 @@ typedef struct
|
|||
x87FPU_t x87fpu;
|
||||
DWORD MxCsr;
|
||||
#ifdef _WIN64
|
||||
M128A XmmRegisters[16];
|
||||
XmmRegister_t XmmRegisters[16];
|
||||
YmmRegister_t YmmRegisters[16];
|
||||
#else // x86
|
||||
M128A XmmRegisters[8];
|
||||
XmmRegister_t XmmRegisters[8];
|
||||
YmmRegister_t YmmRegisters[8];
|
||||
#endif
|
||||
} TITAN_ENGINE_CONTEXT_t;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "disasm_fast.h"
|
||||
#include "stackinfo.h"
|
||||
#include "symbolinfo.h"
|
||||
#include "module.h"
|
||||
|
||||
static DBGFUNCTIONS _dbgfunctions;
|
||||
|
||||
|
|
@ -47,7 +48,7 @@ static bool _sectionfromaddr(duint addr, char* section)
|
|||
{
|
||||
const char* name = (const char*)GetPE32DataFromMappedFile(FileMapVA, sectionNumber, UE_SECTIONNAME);
|
||||
if(section)
|
||||
strcpy(section, name);
|
||||
strcpy_s(section, MAX_SECTION_SIZE, name); //maxi
|
||||
StaticFileUnloadW(curModPath, false, FileHandle, LoadedSize, FileMap, FileMapVA);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -138,7 +139,7 @@ static bool _getjit(char* jit, bool jit64)
|
|||
{
|
||||
if(!dbggetjit(jit_tmp, jit64 ? x64 : x32, &dummy, NULL))
|
||||
return false;
|
||||
strcpy(jit, jit_tmp);
|
||||
strcpy_s(jit, MAX_SETTING_SIZE, jit_tmp);
|
||||
}
|
||||
else // if jit input == NULL: it returns false if there are not an OLD JIT STORED.
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@
|
|||
#include "disasm_fast.h"
|
||||
#include "plugin_loader.h"
|
||||
#include "_dbgfunctions.h"
|
||||
#include "module.h"
|
||||
#include "comment.h"
|
||||
#include "label.h"
|
||||
#include "bookmark.h"
|
||||
#include "function.h"
|
||||
#include "loop.h"
|
||||
|
||||
static bool bOnlyCipAutoComments = false;
|
||||
|
||||
|
|
@ -107,10 +113,10 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
|
||||
if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
|
||||
{
|
||||
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
|
||||
if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
|
||||
if(!bUndecorateSymbolNames or !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
|
||||
strcpy_s(addrinfo->label, pSymbol->Name);
|
||||
retval = true;
|
||||
}
|
||||
|
|
@ -123,10 +129,10 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
uint val = 0;
|
||||
if(memread(fdProcessInfo->hProcess, (const void*)basicinfo.memory.value, &val, sizeof(val), 0))
|
||||
{
|
||||
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) and !displacement)
|
||||
if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) and !displacement)
|
||||
{
|
||||
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
|
||||
if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
|
||||
if(!bUndecorateSymbolNames or !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
|
||||
sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name);
|
||||
retval = true;
|
||||
}
|
||||
|
|
@ -160,10 +166,10 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
DWORD dwDisplacement;
|
||||
IMAGEHLP_LINE64 line;
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
if(SymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) and !dwDisplacement)
|
||||
if(SafeSymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) and !dwDisplacement)
|
||||
{
|
||||
char filename[deflen] = "";
|
||||
strcpy(filename, line.FileName);
|
||||
strcpy_s(filename, line.FileName);
|
||||
int len = (int)strlen(filename);
|
||||
while(filename[len] != '\\' and len != 0)
|
||||
len--;
|
||||
|
|
@ -568,8 +574,8 @@ extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap)
|
|||
//TODO: fix this
|
||||
if(memisvalidreadptr(fdProcessInfo->hProcess, curBp.addr))
|
||||
curBp.active = true;
|
||||
strcpy(curBp.mod, list[i].mod);
|
||||
strcpy(curBp.name, list[i].name);
|
||||
strcpy_s(curBp.mod, list[i].mod);
|
||||
strcpy_s(curBp.name, list[i].name);
|
||||
curBp.singleshoot = list[i].singleshoot;
|
||||
curBp.slot = slot;
|
||||
if(curBp.active)
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ void formathex(char* string)
|
|||
for(int i = 0, j = 0; i < len; i++)
|
||||
if(isxdigit(string[i]))
|
||||
j += sprintf(new_string + j, "%c", string[i]);
|
||||
strcpy(string, new_string);
|
||||
strcpy_s(string, len + 1, new_string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -192,7 +192,7 @@ void formatdec(char* string)
|
|||
for(int i = 0, j = 0; i < len; i++)
|
||||
if(isdigit(string[i]))
|
||||
j += sprintf(new_string + j, "%c", string[i]);
|
||||
strcpy(string, new_string);
|
||||
strcpy_s(string, len + 1, new_string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,23 +11,19 @@
|
|||
#include <stdlib.h>
|
||||
#include <conio.h>
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <stdarg.h>
|
||||
#include <psapi.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <tlhelp32.h>
|
||||
#include "..\x64_dbg_bridge\bridgemain.h"
|
||||
#include "jansson\jansson.h"
|
||||
#include "yara\yara.h"
|
||||
#include "DeviceNameResolver\DeviceNameResolver.h"
|
||||
#include "handle.h"
|
||||
#include "stringutils.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include "dbghelp\dbghelp.h"
|
||||
#else
|
||||
#include <dbghelp.h>
|
||||
#endif //__GNUC__
|
||||
#include "dbghelp_safe.h"
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define and &&
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ typedef struct
|
|||
//provided by the debugger
|
||||
HWND hwndDlg; //gui window handle
|
||||
int hMenu; //plugin menu handle
|
||||
int hMenuDisasm; //plugin disasm menu handle
|
||||
int hMenuDump; //plugin dump menu handle
|
||||
int hMenuStack; //plugin stack menu handle
|
||||
} PLUG_SETUPSTRUCT;
|
||||
|
||||
//callback structures
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -52,72 +52,6 @@ struct DepthModuleRangeCompare
|
|||
}
|
||||
};
|
||||
|
||||
//structures
|
||||
struct MODSECTIONINFO
|
||||
{
|
||||
uint addr; //va
|
||||
uint size; //virtual size
|
||||
char name[50];
|
||||
};
|
||||
|
||||
struct MODINFO
|
||||
{
|
||||
uint base; //module base
|
||||
uint size; //module size
|
||||
uint hash; //full module name hash
|
||||
uint entry; //entry point
|
||||
char name[MAX_MODULE_SIZE]; //module name (without extension)
|
||||
char extension[MAX_MODULE_SIZE]; //file extension
|
||||
std::vector<MODSECTIONINFO> sections;
|
||||
};
|
||||
typedef std::map<Range, MODINFO, RangeCompare> ModulesInfo;
|
||||
|
||||
struct COMMENTSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
char text[MAX_COMMENT_SIZE];
|
||||
bool manual;
|
||||
};
|
||||
typedef std::map<uint, COMMENTSINFO> CommentsInfo;
|
||||
|
||||
struct LABELSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
char text[MAX_LABEL_SIZE];
|
||||
bool manual;
|
||||
};
|
||||
typedef std::map<uint, LABELSINFO> LabelsInfo;
|
||||
|
||||
struct BOOKMARKSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
bool manual;
|
||||
};
|
||||
typedef std::map<uint, BOOKMARKSINFO> BookmarksInfo;
|
||||
|
||||
struct FUNCTIONSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint start;
|
||||
uint end;
|
||||
bool manual;
|
||||
};
|
||||
typedef std::map<ModuleRange, FUNCTIONSINFO, ModuleRangeCompare> FunctionsInfo;
|
||||
|
||||
struct LOOPSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint start;
|
||||
uint end;
|
||||
uint parent;
|
||||
int depth;
|
||||
bool manual;
|
||||
};
|
||||
typedef std::map<DepthModuleRange, LOOPSINFO, DepthModuleRangeCompare> LoopsInfo;
|
||||
|
||||
//typedefs
|
||||
typedef void (*EXPORTENUMCALLBACK)(uint base, const char* mod, const char* name, uint addr);
|
||||
|
||||
|
|
@ -125,62 +59,6 @@ void dbsave();
|
|||
void dbload();
|
||||
void dbclose();
|
||||
|
||||
bool modload(uint base, uint size, const char* fullpath);
|
||||
bool modunload(uint base);
|
||||
void modclear();
|
||||
bool modnamefromaddr(uint addr, char* modname, bool extension);
|
||||
uint modbasefromaddr(uint addr);
|
||||
uint modhashfromva(uint va);
|
||||
uint modhashfromname(const char* mod);
|
||||
uint modbasefromname(const char* modname);
|
||||
uint modsizefromaddr(uint addr);
|
||||
bool modsectionsfromaddr(uint addr, std::vector<MODSECTIONINFO>* sections);
|
||||
uint modentryfromaddr(uint addr);
|
||||
int modpathfromaddr(duint addr, char* path, int size);
|
||||
int modpathfromname(const char* modname, char* path, int size);
|
||||
|
||||
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum);
|
||||
|
||||
bool commentset(uint addr, const char* text, bool manual);
|
||||
bool commentget(uint addr, char* text);
|
||||
bool commentdel(uint addr);
|
||||
void commentdelrange(uint start, uint end);
|
||||
void commentcachesave(JSON root);
|
||||
void commentcacheload(JSON root);
|
||||
bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize);
|
||||
|
||||
bool labelset(uint addr, const char* text, bool manual);
|
||||
bool labelfromstring(const char* text, uint* addr);
|
||||
bool labelget(uint addr, char* text);
|
||||
bool labeldel(uint addr);
|
||||
void labeldelrange(uint start, uint end);
|
||||
void labelcachesave(JSON root);
|
||||
void labelcacheload(JSON root);
|
||||
bool labelenum(LABELSINFO* labellist, size_t* cbsize);
|
||||
|
||||
bool bookmarkset(uint addr, bool manual);
|
||||
bool bookmarkget(uint addr);
|
||||
bool bookmarkdel(uint addr);
|
||||
void bookmarkdelrange(uint start, uint end);
|
||||
void bookmarkcachesave(JSON root);
|
||||
void bookmarkcacheload(JSON root);
|
||||
bool bookmarkenum(BOOKMARKSINFO* bookmarklist, size_t* cbsize);
|
||||
|
||||
bool functionadd(uint start, uint end, bool manual);
|
||||
bool functionget(uint addr, uint* start, uint* end);
|
||||
bool functionoverlaps(uint start, uint end);
|
||||
bool functiondel(uint addr);
|
||||
void functiondelrange(uint start, uint end);
|
||||
void functioncachesave(JSON root);
|
||||
void functioncacheload(JSON root);
|
||||
bool functionenum(FUNCTIONSINFO* functionlist, size_t* cbsize);
|
||||
|
||||
bool loopadd(uint start, uint end, bool manual);
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end);
|
||||
bool loopoverlaps(int depth, uint start, uint end, int* finaldepth);
|
||||
bool loopdel(int depth, uint addr);
|
||||
void loopcachesave(JSON root);
|
||||
void loopcacheload(JSON root);
|
||||
bool loopenum(LOOPSINFO* looplist, size_t* cbsize);
|
||||
|
||||
#endif // _ADDRINFO_H
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ void argformat(char* cmd)
|
|||
|
||||
char command_[deflen] = "";
|
||||
char* command = command_;
|
||||
strcpy(command, cmd);
|
||||
strcpy_s(command, deflen, cmd);
|
||||
while(*command == ' ')
|
||||
command++;
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ void argformat(char* cmd)
|
|||
j += sprintf(temp + j, "%c", arguments[i]);
|
||||
}
|
||||
arguments = arguments_;
|
||||
strcpy(arguments, temp);
|
||||
strcpy_s(arguments, deflen, temp);
|
||||
}
|
||||
len = (int)strlen(arguments);
|
||||
for(int i = 0; i < len; i++)
|
||||
|
|
@ -138,7 +138,7 @@ void argformat(char* cmd)
|
|||
i += 2;
|
||||
j += sprintf(temp + j, "%c", arguments[i]);
|
||||
}
|
||||
strcpy(arguments, temp);
|
||||
strcpy_s(arguments, deflen, temp);
|
||||
|
||||
len = (int)strlen(arguments);
|
||||
for(int i = 0, j = 0; i < len; i++)
|
||||
|
|
@ -147,7 +147,7 @@ void argformat(char* cmd)
|
|||
i++;
|
||||
j += sprintf(temp + j, "%c", arguments[i]);
|
||||
}
|
||||
strcpy(arguments, temp);
|
||||
strcpy_s(arguments, deflen, temp);
|
||||
|
||||
len = (int)strlen(arguments);
|
||||
for(int i = 0; i < len; i++)
|
||||
|
|
@ -160,7 +160,7 @@ void argformat(char* cmd)
|
|||
if(strlen(arguments))
|
||||
sprintf(cmd, "%s %s", command, arguments);
|
||||
else
|
||||
strcpy(cmd, command);
|
||||
strcpy_s(cmd, deflen, command);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -189,7 +189,7 @@ int arggetcount(const char* cmd)
|
|||
arg_count = 1;
|
||||
char temp_[deflen] = "";
|
||||
char* temp = temp_ + 1;
|
||||
strcpy(temp, cmd);
|
||||
strcpy_s(temp, deflen - 1, cmd);
|
||||
for(int i = start; i < len; i++)
|
||||
if(temp[i] == '\\' and (i < len - 1 and temp[i + 1] == '\\'))
|
||||
{
|
||||
|
|
@ -239,7 +239,7 @@ bool argget(const char* cmd, char* arg, int arg_num, bool optional)
|
|||
start++;
|
||||
char temp_[deflen] = "";
|
||||
char* temp = temp_ + 1;
|
||||
strcpy(temp, cmd + start);
|
||||
strcpy_s(temp, deflen - 1, cmd + start);
|
||||
|
||||
int len = (int)strlen(temp);
|
||||
for(int i = 0; i < len; i++)
|
||||
|
|
@ -279,7 +279,7 @@ bool argget(const char* cmd, char* arg, int arg_num, bool optional)
|
|||
memcpy(temp, new_temp, len + 1);
|
||||
if(arg_num == 0) //first argument
|
||||
{
|
||||
strcpy(arg, temp);
|
||||
strcpy_s(arg, deflen, temp);
|
||||
return true;
|
||||
}
|
||||
for(int i = 0, j = 0; i < len; i++)
|
||||
|
|
@ -288,7 +288,7 @@ bool argget(const char* cmd, char* arg, int arg_num, bool optional)
|
|||
j++;
|
||||
if(j == arg_num)
|
||||
{
|
||||
strcpy(arg, temp + i + 1);
|
||||
strcpy_s(arg, deflen, temp + i + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,11 +36,15 @@ bool assemble(uint addr, unsigned char* dest, int* size, const char* instruction
|
|||
#endif
|
||||
parse.cbUnknown = cbUnknown;
|
||||
parse.cip = addr;
|
||||
strcpy(parse.instr, instruction);
|
||||
String instr = instruction;
|
||||
size_t pos = instr.find(" short ");
|
||||
if(pos != String::npos)
|
||||
instr.erase(pos, 6);
|
||||
strcpy_s(parse.instr, instr.c_str());
|
||||
if(XEDParseAssemble(&parse) == XEDPARSE_ERROR)
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, parse.error);
|
||||
strcpy_s(error, MAX_ERROR_SIZE, parse.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
#include "bookmark.h"
|
||||
#include "threading.h"
|
||||
#include "module.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
|
||||
typedef std::map<uint, BOOKMARKSINFO> BookmarksInfo;
|
||||
|
||||
static BookmarksInfo bookmarks;
|
||||
|
||||
bool bookmarkset(uint addr, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr))
|
||||
return false;
|
||||
BOOKMARKSINFO bookmark;
|
||||
modnamefromaddr(addr, bookmark.mod, true);
|
||||
bookmark.addr = addr - modbasefromaddr(addr);
|
||||
bookmark.manual = manual;
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
if(!bookmarks.insert(std::make_pair(modhashfromva(addr), bookmark)).second)
|
||||
return bookmarkdel(addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bookmarkget(uint addr)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
if(bookmarks.count(modhashfromva(addr)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bookmarkdel(uint addr)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
return (bookmarks.erase(modhashfromva(addr)) > 0);
|
||||
}
|
||||
|
||||
void bookmarkdelrange(uint start, uint end)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return;
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
BookmarksInfo::iterator i = bookmarks.begin();
|
||||
while(i != bookmarks.end())
|
||||
{
|
||||
if(i->second.manual) //ignore manual
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if(bDelAll || (i->second.addr >= start && i->second.addr < end))
|
||||
bookmarks.erase(i++);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void bookmarkcachesave(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
const JSON jsonbookmarks = json_array();
|
||||
const JSON jsonautobookmarks = json_array();
|
||||
for(BookmarksInfo::iterator i = bookmarks.begin(); i != bookmarks.end(); ++i)
|
||||
{
|
||||
const BOOKMARKSINFO curBookmark = i->second;
|
||||
JSON curjsonbookmark = json_object();
|
||||
json_object_set_new(curjsonbookmark, "module", json_string(curBookmark.mod));
|
||||
json_object_set_new(curjsonbookmark, "address", json_hex(curBookmark.addr));
|
||||
if(curBookmark.manual)
|
||||
json_array_append_new(jsonbookmarks, curjsonbookmark);
|
||||
else
|
||||
json_array_append_new(jsonautobookmarks, curjsonbookmark);
|
||||
}
|
||||
if(json_array_size(jsonbookmarks))
|
||||
json_object_set(root, "bookmarks", jsonbookmarks);
|
||||
json_decref(jsonbookmarks);
|
||||
if(json_array_size(jsonautobookmarks))
|
||||
json_object_set(root, "autobookmarks", jsonautobookmarks);
|
||||
json_decref(jsonautobookmarks);
|
||||
}
|
||||
|
||||
void bookmarkcacheload(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
bookmarks.clear();
|
||||
const JSON jsonbookmarks = json_object_get(root, "bookmarks");
|
||||
if(jsonbookmarks)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonbookmarks, i, value)
|
||||
{
|
||||
BOOKMARKSINFO curBookmark;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curBookmark.mod, mod);
|
||||
else
|
||||
*curBookmark.mod = '\0';
|
||||
curBookmark.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curBookmark.manual = true;
|
||||
const uint key = modhashfromname(curBookmark.mod) + curBookmark.addr;
|
||||
bookmarks.insert(std::make_pair(key, curBookmark));
|
||||
}
|
||||
}
|
||||
JSON jsonautobookmarks = json_object_get(root, "autobookmarks");
|
||||
if(jsonautobookmarks)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautobookmarks, i, value)
|
||||
{
|
||||
BOOKMARKSINFO curBookmark;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curBookmark.mod, mod);
|
||||
else
|
||||
*curBookmark.mod = '\0';
|
||||
curBookmark.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curBookmark.manual = false;
|
||||
const uint key = modhashfromname(curBookmark.mod) + curBookmark.addr;
|
||||
bookmarks.insert(std::make_pair(key, curBookmark));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bookmarkenum(BOOKMARKSINFO* bookmarklist, size_t* cbsize)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
if(!bookmarklist && !cbsize)
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
if(!bookmarklist && cbsize)
|
||||
{
|
||||
*cbsize = bookmarks.size() * sizeof(BOOKMARKSINFO);
|
||||
return true;
|
||||
}
|
||||
int j = 0;
|
||||
for(BookmarksInfo::iterator i = bookmarks.begin(); i != bookmarks.end(); ++i, j++)
|
||||
{
|
||||
bookmarklist[j] = i->second;
|
||||
bookmarklist[j].addr += modbasefromname(bookmarklist[j].mod);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void bookmarkclear()
|
||||
{
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
BookmarksInfo().swap(bookmarks);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef _BOOKMARK_H
|
||||
#define _BOOKMARK_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
struct BOOKMARKSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
bool manual;
|
||||
};
|
||||
|
||||
bool bookmarkset(uint addr, bool manual);
|
||||
bool bookmarkget(uint addr);
|
||||
bool bookmarkdel(uint addr);
|
||||
void bookmarkdelrange(uint start, uint end);
|
||||
void bookmarkcachesave(JSON root);
|
||||
void bookmarkcacheload(JSON root);
|
||||
bool bookmarkenum(BOOKMARKSINFO* bookmarklist, size_t* cbsize);
|
||||
void bookmarkclear();
|
||||
|
||||
#endif //_BOOKMARK_H
|
||||
|
|
@ -10,6 +10,10 @@
|
|||
#include "console.h"
|
||||
#include "memory.h"
|
||||
#include "threading.h"
|
||||
#include "module.h"
|
||||
|
||||
typedef std::pair<BP_TYPE, uint> BreakpointKey;
|
||||
typedef std::map<BreakpointKey, BREAKPOINT> BreakpointsInfo;
|
||||
|
||||
static BreakpointsInfo breakpoints;
|
||||
|
||||
|
|
@ -195,8 +199,8 @@ void bptobridge(const BREAKPOINT* bp, BRIDGEBP* bridge)
|
|||
bridge->active = bp->active;
|
||||
bridge->addr = bp->addr;
|
||||
bridge->enabled = bp->enabled;
|
||||
strcpy(bridge->mod, bp->mod);
|
||||
strcpy(bridge->name, bp->name);
|
||||
strcpy_s(bridge->mod, bp->mod);
|
||||
strcpy_s(bridge->name, bp->name);
|
||||
bridge->singleshoot = bp->singleshoot;
|
||||
switch(bp->type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ struct BREAKPOINT
|
|||
|
||||
//typedefs
|
||||
typedef bool (*BPENUMCALLBACK)(const BREAKPOINT* bp);
|
||||
typedef std::pair<BP_TYPE, uint> BreakpointKey;
|
||||
typedef std::map<BreakpointKey, BREAKPOINT> BreakpointsInfo;
|
||||
|
||||
//functions
|
||||
int bpgetlist(std::vector<BREAKPOINT>* list);
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ bool cmdnew(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool d
|
|||
COMMAND* cmdget(COMMAND* command_list, const char* cmd)
|
||||
{
|
||||
char new_cmd[deflen] = "";
|
||||
strcpy_s(new_cmd, cmd);
|
||||
strcpy_s(new_cmd, deflen, cmd);
|
||||
int len = (int)strlen(new_cmd);
|
||||
int start = 0;
|
||||
while(new_cmd[start] != ' ' and start < len)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,182 @@
|
|||
#include "comment.h"
|
||||
#include "threading.h"
|
||||
#include "module.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
|
||||
typedef std::map<uint, COMMENTSINFO> CommentsInfo;
|
||||
|
||||
static CommentsInfo comments;
|
||||
|
||||
bool commentset(uint addr, const char* text, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or text[0] == '\1' or strlen(text) >= MAX_COMMENT_SIZE - 1)
|
||||
return false;
|
||||
if(!*text) //NOTE: delete when there is no text
|
||||
{
|
||||
commentdel(addr);
|
||||
return true;
|
||||
}
|
||||
COMMENTSINFO comment;
|
||||
comment.manual = manual;
|
||||
strcpy_s(comment.text, text);
|
||||
modnamefromaddr(addr, comment.mod, true);
|
||||
comment.addr = addr - modbasefromaddr(addr);
|
||||
const uint key = modhashfromva(addr);
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
if(!comments.insert(std::make_pair(key, comment)).second) //key already present
|
||||
comments[key] = comment;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool commentget(uint addr, char* text)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
const CommentsInfo::iterator found = comments.find(modhashfromva(addr));
|
||||
if(found == comments.end()) //not found
|
||||
return false;
|
||||
strcpy_s(text, MAX_COMMENT_SIZE, found->second.text);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool commentdel(uint addr)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
return (comments.erase(modhashfromva(addr)) == 1);
|
||||
}
|
||||
|
||||
void commentdelrange(uint start, uint end)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return;
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
CommentsInfo::iterator i = comments.begin();
|
||||
while(i != comments.end())
|
||||
{
|
||||
if(i->second.manual) //ignore manual
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if(bDelAll || (i->second.addr >= start && i->second.addr < end))
|
||||
comments.erase(i++);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void commentcachesave(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
const JSON jsoncomments = json_array();
|
||||
const JSON jsonautocomments = json_array();
|
||||
for(CommentsInfo::iterator i = comments.begin(); i != comments.end(); ++i)
|
||||
{
|
||||
const COMMENTSINFO curComment = i->second;
|
||||
JSON curjsoncomment = json_object();
|
||||
json_object_set_new(curjsoncomment, "module", json_string(curComment.mod));
|
||||
json_object_set_new(curjsoncomment, "address", json_hex(curComment.addr));
|
||||
json_object_set_new(curjsoncomment, "text", json_string(curComment.text));
|
||||
if(curComment.manual)
|
||||
json_array_append_new(jsoncomments, curjsoncomment);
|
||||
else
|
||||
json_array_append_new(jsonautocomments, curjsoncomment);
|
||||
}
|
||||
if(json_array_size(jsoncomments))
|
||||
json_object_set(root, "comments", jsoncomments);
|
||||
json_decref(jsoncomments);
|
||||
if(json_array_size(jsonautocomments))
|
||||
json_object_set(root, "autocomments", jsonautocomments);
|
||||
json_decref(jsonautocomments);
|
||||
}
|
||||
|
||||
void commentcacheload(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
comments.clear();
|
||||
const JSON jsoncomments = json_object_get(root, "comments");
|
||||
if(jsoncomments)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsoncomments, i, value)
|
||||
{
|
||||
COMMENTSINFO curComment;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curComment.mod, mod);
|
||||
else
|
||||
*curComment.mod = '\0';
|
||||
curComment.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curComment.manual = true;
|
||||
const char* text = json_string_value(json_object_get(value, "text"));
|
||||
if(text)
|
||||
strcpy_s(curComment.text, text);
|
||||
else
|
||||
continue; //skip
|
||||
const uint key = modhashfromname(curComment.mod) + curComment.addr;
|
||||
comments.insert(std::make_pair(key, curComment));
|
||||
}
|
||||
}
|
||||
JSON jsonautocomments = json_object_get(root, "autocomments");
|
||||
if(jsonautocomments)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautocomments, i, value)
|
||||
{
|
||||
COMMENTSINFO curComment;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curComment.mod, mod);
|
||||
else
|
||||
*curComment.mod = '\0';
|
||||
curComment.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curComment.manual = false;
|
||||
const char* text = json_string_value(json_object_get(value, "text"));
|
||||
if(text)
|
||||
strcpy_s(curComment.text, text);
|
||||
else
|
||||
continue; //skip
|
||||
const uint key = modhashfromname(curComment.mod) + curComment.addr;
|
||||
comments.insert(std::make_pair(key, curComment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
if(!commentlist && !cbsize)
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
if(!commentlist && cbsize)
|
||||
{
|
||||
*cbsize = comments.size() * sizeof(COMMENTSINFO);
|
||||
return true;
|
||||
}
|
||||
int j = 0;
|
||||
for(CommentsInfo::iterator i = comments.begin(); i != comments.end(); ++i, j++)
|
||||
{
|
||||
commentlist[j] = i->second;
|
||||
commentlist[j].addr += modbasefromname(commentlist[j].mod);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void commentclear()
|
||||
{
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
CommentsInfo().swap(comments);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _COMMENT_H
|
||||
#define _COMMENT_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
struct COMMENTSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
char text[MAX_COMMENT_SIZE];
|
||||
bool manual;
|
||||
};
|
||||
|
||||
bool commentset(uint addr, const char* text, bool manual);
|
||||
bool commentget(uint addr, char* text);
|
||||
bool commentdel(uint addr);
|
||||
void commentdelrange(uint start, uint end);
|
||||
void commentcachesave(JSON root);
|
||||
void commentcacheload(JSON root);
|
||||
bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize);
|
||||
void commentclear();
|
||||
|
||||
#endif //_COMMENT_H
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
#include "_global.h"
|
||||
#include "dbghelp_safe.h"
|
||||
#include "threading.h"
|
||||
|
||||
DWORD
|
||||
SafeUnDecorateSymbolName(
|
||||
__in PCSTR name,
|
||||
__out_ecount(maxStringLength) PSTR outputString,
|
||||
__in DWORD maxStringLength,
|
||||
__in DWORD flags
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return UnDecorateSymbolName(name, outputString, maxStringLength, flags);
|
||||
}
|
||||
BOOL
|
||||
SafeSymUnloadModule64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 BaseOfDll
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymUnloadModule64(hProcess, BaseOfDll);
|
||||
}
|
||||
BOOL
|
||||
SafeSymSetSearchPath(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt PCSTR SearchPath
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymSetSearchPath(hProcess, SearchPath);
|
||||
}
|
||||
DWORD
|
||||
SafeSymSetOptions(
|
||||
__in DWORD SymOptions
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymSetOptions(SymOptions);
|
||||
}
|
||||
BOOL
|
||||
SafeSymInitialize(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt PCSTR UserSearchPath,
|
||||
__in BOOL fInvadeProcess
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymInitialize(hProcess, UserSearchPath, fInvadeProcess);
|
||||
}
|
||||
BOOL
|
||||
SafeSymRegisterCallback64(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
|
||||
__in ULONG64 UserContext
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymRegisterCallback64(hProcess, CallbackFunction, UserContext);
|
||||
}
|
||||
DWORD64
|
||||
SafeSymLoadModuleEx(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt HANDLE hFile,
|
||||
__in_opt PCSTR ImageName,
|
||||
__in_opt PCSTR ModuleName,
|
||||
__in DWORD64 BaseOfDll,
|
||||
__in DWORD DllSize,
|
||||
__in_opt PMODLOAD_DATA Data,
|
||||
__in_opt DWORD Flags
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll, DllSize, Data, Flags);
|
||||
}
|
||||
BOOL
|
||||
SafeSymGetModuleInfo64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 qwAddr,
|
||||
__out PIMAGEHLP_MODULE64 ModuleInfo
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymGetModuleInfo64(hProcess, qwAddr, ModuleInfo);
|
||||
}
|
||||
BOOL
|
||||
SafeSymGetSearchPath(
|
||||
__in HANDLE hProcess,
|
||||
__out_ecount(SearchPathLength) PSTR SearchPath,
|
||||
__in DWORD SearchPathLength
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymGetSearchPath(hProcess, SearchPath, SearchPathLength);
|
||||
}
|
||||
BOOL
|
||||
SafeSymEnumSymbols(
|
||||
__in HANDLE hProcess,
|
||||
__in ULONG64 BaseOfDll,
|
||||
__in_opt PCSTR Mask,
|
||||
__in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
|
||||
__in_opt PVOID UserContext
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymEnumSymbols(hProcess, BaseOfDll, Mask, EnumSymbolsCallback, UserContext);
|
||||
}
|
||||
BOOL
|
||||
SafeSymEnumerateModules(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
|
||||
__in_opt PVOID UserContext
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymEnumerateModules(hProcess, EnumModulesCallback, UserContext);
|
||||
}
|
||||
BOOL
|
||||
SafeSymGetLineFromAddr64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 qwAddr,
|
||||
__out PDWORD pdwDisplacement,
|
||||
__out PIMAGEHLP_LINE64 Line64
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymGetLineFromAddr64(hProcess, qwAddr, pdwDisplacement, Line64);
|
||||
}
|
||||
BOOL
|
||||
SafeSymFromName(
|
||||
__in HANDLE hProcess,
|
||||
__in PCSTR Name,
|
||||
__inout PSYMBOL_INFO Symbol
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymFromName(hProcess, Name, Symbol);
|
||||
}
|
||||
BOOL
|
||||
SafeSymFromAddr(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 Address,
|
||||
__out_opt PDWORD64 Displacement,
|
||||
__inout PSYMBOL_INFO Symbol
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymFromAddr(hProcess, Address, Displacement, Symbol);
|
||||
}
|
||||
BOOL
|
||||
SafeSymCleanup(
|
||||
__in HANDLE hProcess
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymCleanup(hProcess);
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
#ifndef _DBGHELP_SAFE_H
|
||||
#define _DBGHELP_SAFE_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include "dbghelp\dbghelp.h"
|
||||
#else
|
||||
#include <dbghelp.h>
|
||||
#endif //__GNUC__
|
||||
|
||||
DWORD
|
||||
SafeUnDecorateSymbolName(
|
||||
__in PCSTR name,
|
||||
__out_ecount(maxStringLength) PSTR outputString,
|
||||
__in DWORD maxStringLength,
|
||||
__in DWORD flags
|
||||
);
|
||||
BOOL
|
||||
SafeSymUnloadModule64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 BaseOfDll
|
||||
);
|
||||
BOOL
|
||||
SafeSymSetSearchPath(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt PCSTR SearchPath
|
||||
);
|
||||
DWORD
|
||||
SafeSymSetOptions(
|
||||
__in DWORD SymOptions
|
||||
);
|
||||
BOOL
|
||||
SafeSymInitialize(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt PCSTR UserSearchPath,
|
||||
__in BOOL fInvadeProcess
|
||||
);
|
||||
BOOL
|
||||
SafeSymRegisterCallback64(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
|
||||
__in ULONG64 UserContext
|
||||
);
|
||||
DWORD64
|
||||
SafeSymLoadModuleEx(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt HANDLE hFile,
|
||||
__in_opt PCSTR ImageName,
|
||||
__in_opt PCSTR ModuleName,
|
||||
__in DWORD64 BaseOfDll,
|
||||
__in DWORD DllSize,
|
||||
__in_opt PMODLOAD_DATA Data,
|
||||
__in_opt DWORD Flags
|
||||
);
|
||||
BOOL
|
||||
SafeSymGetModuleInfo64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 qwAddr,
|
||||
__out PIMAGEHLP_MODULE64 ModuleInfo
|
||||
);
|
||||
BOOL
|
||||
SafeSymGetSearchPath(
|
||||
__in HANDLE hProcess,
|
||||
__out_ecount(SearchPathLength) PSTR SearchPath,
|
||||
__in DWORD SearchPathLength
|
||||
);
|
||||
BOOL
|
||||
SafeSymEnumSymbols(
|
||||
__in HANDLE hProcess,
|
||||
__in ULONG64 BaseOfDll,
|
||||
__in_opt PCSTR Mask,
|
||||
__in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
|
||||
__in_opt PVOID UserContext
|
||||
);
|
||||
BOOL
|
||||
SafeSymEnumerateModules(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
|
||||
__in_opt PVOID UserContext
|
||||
);
|
||||
BOOL
|
||||
SafeSymGetLineFromAddr64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 qwAddr,
|
||||
__out PDWORD pdwDisplacement,
|
||||
__out PIMAGEHLP_LINE64 Line64
|
||||
);
|
||||
BOOL
|
||||
SafeSymFromName(
|
||||
__in HANDLE hProcess,
|
||||
__in PCSTR Name,
|
||||
__inout PSYMBOL_INFO Symbol
|
||||
);
|
||||
BOOL
|
||||
SafeSymFromAddr(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 Address,
|
||||
__out_opt PDWORD64 Displacement,
|
||||
__inout PSYMBOL_INFO Symbol
|
||||
);
|
||||
BOOL
|
||||
SafeSymCleanup(
|
||||
__in HANDLE hProcess
|
||||
);
|
||||
|
||||
#endif //_DBGHELP_SAFE_H
|
||||
|
|
@ -16,6 +16,9 @@
|
|||
#include "symbolinfo.h"
|
||||
#include "variable.h"
|
||||
#include "x64_dbg.h"
|
||||
#include "exception.h"
|
||||
#include "error.h"
|
||||
#include "module.h"
|
||||
|
||||
static PROCESS_INFORMATION g_pi = {0, 0, 0, 0};
|
||||
static char szBaseFileName[MAX_PATH] = "";
|
||||
|
|
@ -30,7 +33,6 @@ static bool bSkipExceptions = false;
|
|||
static bool bBreakOnNextDll = false;
|
||||
static int ecount = 0;
|
||||
static std::vector<ExceptionRange> ignoredExceptionRange;
|
||||
static std::map<unsigned int, const char*> exceptionNames;
|
||||
static SIZE_T cachePrivateUsage = 0;
|
||||
static HANDLE hEvent = 0;
|
||||
static String lastDebugText;
|
||||
|
|
@ -60,67 +62,8 @@ static DWORD WINAPI memMapThread(void* ptr)
|
|||
|
||||
void dbginit()
|
||||
{
|
||||
exceptionNames.insert(std::make_pair(0x40000005, "STATUS_SEGMENT_NOTIFICATION"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001C, "STATUS_WX86_UNSIMULATE"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001D, "STATUS_WX86_CONTINUE"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001E, "STATUS_WX86_SINGLE_STEP"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001F, "STATUS_WX86_BREAKPOINT"));
|
||||
exceptionNames.insert(std::make_pair(0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE"));
|
||||
exceptionNames.insert(std::make_pair(0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE"));
|
||||
exceptionNames.insert(std::make_pair(0x40000022, "STATUS_WX86_EXCEPTION_CHAIN"));
|
||||
exceptionNames.insert(std::make_pair(0x40000028, "STATUS_WX86_CREATEWX86TIB"));
|
||||
exceptionNames.insert(std::make_pair(0x40010003, "DBG_TERMINATE_THREAD"));
|
||||
exceptionNames.insert(std::make_pair(0x40010004, "DBG_TERMINATE_PROCESS"));
|
||||
exceptionNames.insert(std::make_pair(0x40010005, "DBG_CONTROL_C"));
|
||||
exceptionNames.insert(std::make_pair(0x40010006, "DBG_PRINTEXCEPTION_C"));
|
||||
exceptionNames.insert(std::make_pair(0x40010007, "DBG_RIPEXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0x40010008, "DBG_CONTROL_BREAK"));
|
||||
exceptionNames.insert(std::make_pair(0x40010009, "DBG_COMMAND_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0x80000001, "EXCEPTION_GUARD_PAGE"));
|
||||
exceptionNames.insert(std::make_pair(0x80000002, "EXCEPTION_DATATYPE_MISALIGNMENT"));
|
||||
exceptionNames.insert(std::make_pair(0x80000003, "EXCEPTION_BREAKPOINT"));
|
||||
exceptionNames.insert(std::make_pair(0x80000004, "EXCEPTION_SINGLE_STEP"));
|
||||
exceptionNames.insert(std::make_pair(0x80000026, "STATUS_LONGJUMP"));
|
||||
exceptionNames.insert(std::make_pair(0x80000029, "STATUS_UNWIND_CONSOLIDATE"));
|
||||
exceptionNames.insert(std::make_pair(0x80010001, "DBG_EXCEPTION_NOT_HANDLED"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000005, "EXCEPTION_ACCESS_VIOLATION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000006, "EXCEPTION_IN_PAGE_ERROR"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000008, "EXCEPTION_INVALID_HANDLE"));
|
||||
exceptionNames.insert(std::make_pair(0xC000000D, "STATUS_INVALID_PARAMETER"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000017, "STATUS_NO_MEMORY"));
|
||||
exceptionNames.insert(std::make_pair(0xC000001D, "EXCEPTION_ILLEGAL_INSTRUCTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000025, "EXCEPTION_NONCONTINUABLE_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000026, "EXCEPTION_INVALID_DISPOSITION"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008C, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008D, "EXCEPTION_FLT_DENORMAL_OPERAND"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008E, "EXCEPTION_FLT_DIVIDE_BY_ZERO"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008F, "EXCEPTION_FLT_INEXACT_RESULT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000090, "EXCEPTION_FLT_INVALID_OPERATION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000091, "EXCEPTION_FLT_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000092, "EXCEPTION_FLT_STACK_CHECK"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000093, "EXCEPTION_FLT_UNDERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000094, "EXCEPTION_INT_DIVIDE_BY_ZERO"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000095, "EXCEPTION_INT_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000096, "EXCEPTION_PRIV_INSTRUCTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC00000FD, "EXCEPTION_STACK_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000135, "STATUS_DLL_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000138, "STATUS_ORDINAL_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC000013A, "STATUS_CONTROL_C_EXIT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000142, "STATUS_DLL_INIT_FAILED"));
|
||||
exceptionNames.insert(std::make_pair(0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000194, "EXCEPTION_POSSIBLE_DEADLOCK"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002C9, "STATUS_REG_NAT_CONSUMPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000409, "STATUS_STACK_BUFFER_OVERRUN"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000417, "STATUS_INVALID_CRUNTIME_PARAMETER"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000420, "STATUS_ASSERTION_FAILURE"));
|
||||
exceptionNames.insert(std::make_pair(0x04242420, "CLRDBG_NOTIFICATION_EXCEPTION_CODE"));
|
||||
exceptionNames.insert(std::make_pair(0xE0434352, "CLR_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xE06D7363, "CPP_EH_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(MS_VC_EXCEPTION, "MS_VC_EXCEPTION"));
|
||||
exceptioninit();
|
||||
errorinit();
|
||||
CloseHandle(CreateThread(0, 0, memMapThread, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
|
@ -277,7 +220,7 @@ void cbUserBreakpoint()
|
|||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
bpInfo.breakpoint = 0;
|
||||
if(!bpget(GetContextDataEx(hActiveThread, UE_CIP), BPNORMAL, 0, &bp) and bp.enabled)
|
||||
dputs("breakpoint reached not in list!");
|
||||
dputs("Breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
const char* bptype = "INT3";
|
||||
|
|
@ -328,7 +271,7 @@ void cbHardwareBreakpoint(void* ExceptionAddress)
|
|||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
bpInfo.breakpoint = 0;
|
||||
if(!bpget((uint)ExceptionAddress, BPHARDWARE, 0, &bp))
|
||||
dputs("hardware breakpoint reached not in list!");
|
||||
dputs("Hardware breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
const char* bpsize = "";
|
||||
|
|
@ -367,16 +310,16 @@ void cbHardwareBreakpoint(void* ExceptionAddress)
|
|||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
dprintf("hardware breakpoint (%s%s) \"%s\" at %s ("fhex")!\n", bpsize, bptype, bp.name, symbolicname, bp.addr);
|
||||
dprintf("Hardware breakpoint (%s%s) \"%s\" at %s ("fhex")!\n", bpsize, bptype, bp.name, symbolicname, bp.addr);
|
||||
else
|
||||
dprintf("hardware breakpoint (%s%s) at %s ("fhex")!\n", bpsize, bptype, symbolicname, bp.addr);
|
||||
dprintf("Hardware breakpoint (%s%s) at %s ("fhex")!\n", bpsize, bptype, symbolicname, bp.addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(*bp.name)
|
||||
dprintf("hardware breakpoint (%s%s) \"%s\" at "fhex"!\n", bpsize, bptype, bp.name, bp.addr);
|
||||
dprintf("Hardware breakpoint (%s%s) \"%s\" at "fhex"!\n", bpsize, bptype, bp.name, bp.addr);
|
||||
else
|
||||
dprintf("hardware breakpoint (%s%s) at "fhex"!\n", bpsize, bptype, bp.addr);
|
||||
dprintf("Hardware breakpoint (%s%s) at "fhex"!\n", bpsize, bptype, bp.addr);
|
||||
}
|
||||
bptobridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint = &pluginBp;
|
||||
|
|
@ -405,7 +348,7 @@ void cbMemoryBreakpoint(void* ExceptionAddress)
|
|||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
bpInfo.breakpoint = 0;
|
||||
if(!bpget(base, BPMEMORY, 0, &bp))
|
||||
dputs("memory breakpoint reached not in list!");
|
||||
dputs("Memory breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
const char* bptype = "";
|
||||
|
|
@ -428,16 +371,16 @@ void cbMemoryBreakpoint(void* ExceptionAddress)
|
|||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
dprintf("memory breakpoint%s \"%s\" at %s ("fhex", "fhex")!\n", bptype, bp.name, symbolicname, bp.addr, ExceptionAddress);
|
||||
dprintf("Memory breakpoint%s \"%s\" at %s ("fhex", "fhex")!\n", bptype, bp.name, symbolicname, bp.addr, ExceptionAddress);
|
||||
else
|
||||
dprintf("memory breakpoint%s at %s ("fhex", "fhex")!\n", bptype, symbolicname, bp.addr, ExceptionAddress);
|
||||
dprintf("Memory breakpoint%s at %s ("fhex", "fhex")!\n", bptype, symbolicname, bp.addr, ExceptionAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(*bp.name)
|
||||
dprintf("memory breakpoint%s \"%s\" at "fhex" ("fhex")!\n", bptype, bp.name, bp.addr, ExceptionAddress);
|
||||
dprintf("Memory breakpoint%s \"%s\" at "fhex" ("fhex")!\n", bptype, bp.name, bp.addr, ExceptionAddress);
|
||||
else
|
||||
dprintf("memory breakpoint%s at "fhex" ("fhex")!\n", bptype, bp.addr, ExceptionAddress);
|
||||
dprintf("Memory breakpoint%s at "fhex" ("fhex")!\n", bptype, bp.addr, ExceptionAddress);
|
||||
}
|
||||
bptobridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint = &pluginBp;
|
||||
|
|
@ -495,7 +438,7 @@ static BOOL CALLBACK SymRegisterCallbackProc64(HANDLE hProcess, ULONG ActionCode
|
|||
if(strstr(text, " bytes - "))
|
||||
{
|
||||
Memory<char*> newtext(len + 1, "SymRegisterCallbackProc64:newtext");
|
||||
strcpy(newtext, text);
|
||||
strcpy_s(newtext, len + 1, text);
|
||||
strstr(newtext, " bytes - ")[8] = 0;
|
||||
GuiSymbolLogAdd(newtext);
|
||||
suspress = true;
|
||||
|
|
@ -541,7 +484,7 @@ static bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
|||
case BPNORMAL:
|
||||
{
|
||||
if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
|
||||
dprintf("could not set breakpoint "fhex"!\n", bp->addr);
|
||||
dprintf("Could not set breakpoint "fhex"!\n", bp->addr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -550,7 +493,7 @@ static bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
|||
uint size = 0;
|
||||
memfindbaseaddr(bp->addr, &size);
|
||||
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint))
|
||||
dprintf("could not set memory breakpoint "fhex"!\n", bp->addr);
|
||||
dprintf("Could not set memory breakpoint "fhex"!\n", bp->addr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -559,14 +502,14 @@ static bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
|||
DWORD drx = 0;
|
||||
if(!GetUnusedHardwareBreakPointRegister(&drx))
|
||||
{
|
||||
dputs("you can only set 4 hardware breakpoints");
|
||||
dputs("You can only set 4 hardware breakpoints");
|
||||
return false;
|
||||
}
|
||||
int titantype = bp->titantype;
|
||||
TITANSETDRX(titantype, drx);
|
||||
bpsettitantype(bp->addr, BPHARDWARE, titantype);
|
||||
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint))
|
||||
dprintf("could not set hardware breakpoint "fhex"!\n", bp->addr);
|
||||
dprintf("Could not set hardware breakpoint "fhex"!\n", bp->addr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -658,12 +601,15 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
{
|
||||
wchar_t wszFileName[MAX_PATH] = L"";
|
||||
if(!DevicePathFromFileHandleW(CreateProcessInfo->hFile, wszFileName, sizeof(wszFileName)))
|
||||
strcpy(DebugFileName, "??? (GetFileNameFromHandle failed!)");
|
||||
strcpy_s(DebugFileName, "??? (GetFileNameFromHandle failed!)");
|
||||
else
|
||||
strcpy_s(DebugFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str());
|
||||
}
|
||||
dprintf("Process Started: "fhex" %s\n", base, DebugFileName);
|
||||
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
GuiDumpAt(memfindbaseaddr(GetContextData(UE_CIP), 0) + PAGE_SIZE); //dump somewhere
|
||||
|
||||
//init program database
|
||||
int len = (int)strlen(szFileName);
|
||||
while(szFileName[len] != '\\' && len != 0)
|
||||
|
|
@ -679,17 +625,17 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
sprintf(dbpath, "%s\\%s", dbbasepath, sqlitedb);
|
||||
dprintf("Database file: %s\n", dbpath);
|
||||
dbload();
|
||||
SymSetOptions(SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_IGNORE_NT_SYMPATH);
|
||||
SafeSymSetOptions(SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_IGNORE_NT_SYMPATH);
|
||||
GuiSymbolLogClear();
|
||||
char szServerSearchPath[MAX_PATH * 2] = "";
|
||||
sprintf_s(szServerSearchPath, "SRV*%s", szSymbolCachePath);
|
||||
SymInitialize(fdProcessInfo->hProcess, szServerSearchPath, false); //initialize symbols
|
||||
SymRegisterCallback64(fdProcessInfo->hProcess, SymRegisterCallbackProc64, 0);
|
||||
SymLoadModuleEx(fdProcessInfo->hProcess, CreateProcessInfo->hFile, DebugFileName, 0, (DWORD64)base, 0, 0, 0);
|
||||
SafeSymInitialize(fdProcessInfo->hProcess, szServerSearchPath, false); //initialize symbols
|
||||
SafeSymRegisterCallback64(fdProcessInfo->hProcess, SymRegisterCallbackProc64, 0);
|
||||
SafeSymLoadModuleEx(fdProcessInfo->hProcess, CreateProcessInfo->hFile, DebugFileName, 0, (DWORD64)base, 0, 0, 0);
|
||||
IMAGEHLP_MODULE64 modInfo;
|
||||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct = sizeof(modInfo);
|
||||
if(SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
if(SafeSymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
modload((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
memupdatemap(fdProcessInfo->hProcess); //update memory map
|
||||
|
|
@ -711,12 +657,13 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
dprintf("TLS Callbacks: %d\n", NumberOfCallBacks);
|
||||
Memory<uint*> TLSCallBacks(NumberOfCallBacks * sizeof(uint), "cbCreateProcess:TLSCallBacks");
|
||||
if(!TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), TLSCallBacks, &NumberOfCallBacks))
|
||||
dputs("failed to get TLS callback addresses!");
|
||||
dputs("Failed to get TLS callback addresses!");
|
||||
else
|
||||
{
|
||||
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE);
|
||||
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
|
||||
{
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks[i], i + 1);
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks[i] - ImageBase + pDebuggedBase, i + 1);
|
||||
cmddirectexec(dbggetcommandlist(), command);
|
||||
}
|
||||
}
|
||||
|
|
@ -725,7 +672,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
|
||||
if(settingboolget("Events", "EntryBreakpoint"))
|
||||
{
|
||||
sprintf(command, "bp "fhex",\"entry breakpoint\",ss", CreateProcessInfo->lpStartAddress);
|
||||
sprintf(command, "bp "fhex",\"entry breakpoint\",ss", (uint)CreateProcessInfo->lpStartAddress);
|
||||
cmddirectexec(dbggetcommandlist(), command);
|
||||
}
|
||||
}
|
||||
|
|
@ -753,7 +700,7 @@ static void cbExitProcess(EXIT_PROCESS_DEBUG_INFO* ExitProcess)
|
|||
callbackInfo.ExitProcess = ExitProcess;
|
||||
plugincbcall(CB_EXITPROCESS, &callbackInfo);
|
||||
//Cleanup
|
||||
SymCleanup(fdProcessInfo->hProcess);
|
||||
SafeSymCleanup(fdProcessInfo->hProcess);
|
||||
}
|
||||
|
||||
static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
||||
|
|
@ -765,7 +712,7 @@ static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
|||
if(settingboolget("Events", "ThreadEntry"))
|
||||
{
|
||||
char command[256] = "";
|
||||
sprintf(command, "bp "fhex",\"Thread %X\",ss", CreateThread->lpStartAddress, dwThreadId);
|
||||
sprintf(command, "bp "fhex",\"Thread %X\",ss", (uint)CreateThread->lpStartAddress, dwThreadId);
|
||||
cmddirectexec(dbggetcommandlist(), command);
|
||||
}
|
||||
|
||||
|
|
@ -824,9 +771,9 @@ static void cbSystemBreakpoint(void* ExceptionData)
|
|||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
//log message
|
||||
if(bIsAttached)
|
||||
dputs("attach breakpoint reached!");
|
||||
dputs("Attach breakpoint reached!");
|
||||
else
|
||||
dputs("system breakpoint reached!");
|
||||
dputs("System breakpoint reached!");
|
||||
bSkipExceptions = false; //we are not skipping first-chance exceptions
|
||||
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
GuiDumpAt(memfindbaseaddr(cip, 0, true)); //dump somewhere
|
||||
|
|
@ -860,15 +807,15 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
{
|
||||
wchar_t wszFileName[MAX_PATH] = L"";
|
||||
if(!DevicePathFromFileHandleW(LoadDll->hFile, wszFileName, sizeof(wszFileName)))
|
||||
strcpy(DLLDebugFileName, "??? (GetFileNameFromHandle failed!)");
|
||||
strcpy_s(DLLDebugFileName, "??? (GetFileNameFromHandle failed!)");
|
||||
else
|
||||
strcpy_s(DLLDebugFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str());
|
||||
}
|
||||
SymLoadModuleEx(fdProcessInfo->hProcess, LoadDll->hFile, DLLDebugFileName, 0, (DWORD64)base, 0, 0, 0);
|
||||
SafeSymLoadModuleEx(fdProcessInfo->hProcess, LoadDll->hFile, DLLDebugFileName, 0, (DWORD64)base, 0, 0, 0);
|
||||
IMAGEHLP_MODULE64 modInfo;
|
||||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
|
||||
if(SymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
if(SafeSymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
modload((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
memupdatemap(fdProcessInfo->hProcess); //update memory map
|
||||
|
|
@ -877,10 +824,13 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
bpenumall(cbSetModuleBreakpoints, modname);
|
||||
GuiUpdateBreakpointsView();
|
||||
bool bAlreadySetEntry = false;
|
||||
|
||||
char command[256] = "";
|
||||
bool bIsDebuggingThis = false;
|
||||
if(bFileIsDll and !_stricmp(DLLDebugFileName, szFileName) and !bIsAttached) //Set entry breakpoint
|
||||
{
|
||||
bIsDebuggingThis = true;
|
||||
pDebuggedBase = (uint)base;
|
||||
char command[256] = "";
|
||||
if(settingboolget("Events", "EntryBreakpoint"))
|
||||
{
|
||||
bAlreadySetEntry = true;
|
||||
|
|
@ -890,6 +840,31 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
}
|
||||
GuiUpdateBreakpointsView();
|
||||
|
||||
if(settingboolget("Events", "TlsCallbacks"))
|
||||
{
|
||||
DWORD NumberOfCallBacks = 0;
|
||||
TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, &NumberOfCallBacks);
|
||||
if(NumberOfCallBacks)
|
||||
{
|
||||
dprintf("TLS Callbacks: %d\n", NumberOfCallBacks);
|
||||
Memory<uint*> TLSCallBacks(NumberOfCallBacks * sizeof(uint), "cbLoadDll:TLSCallBacks");
|
||||
if(!TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), TLSCallBacks, &NumberOfCallBacks))
|
||||
dputs("Failed to get TLS callback addresses!");
|
||||
else
|
||||
{
|
||||
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE);
|
||||
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
|
||||
{
|
||||
if(bIsDebuggingThis)
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks[i] - ImageBase + (uint)base, i + 1);
|
||||
else
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", TLSCallBacks[i] - ImageBase + (uint)base, i + 1, modname);
|
||||
cmddirectexec(dbggetcommandlist(), command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((bBreakOnNextDll || settingboolget("Events", "DllEntry")) && !bAlreadySetEntry)
|
||||
{
|
||||
uint oep = GetPE32Data(DLLDebugFileName, 0, UE_OEP);
|
||||
|
|
@ -938,7 +913,7 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
|||
if(modnamefromaddr((uint)base, modname, true))
|
||||
bpenumall(cbRemoveModuleBreakpoints, modname);
|
||||
GuiUpdateBreakpointsView();
|
||||
SymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base);
|
||||
SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base);
|
||||
dprintf("DLL Unloaded: "fhex" %s\n", base, modname);
|
||||
|
||||
if(bBreakOnNextDll || settingboolget("Events", "DllUnload"))
|
||||
|
|
@ -1018,7 +993,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
if(!DetachDebuggerEx(fdProcessInfo->dwProcessId))
|
||||
dputs("DetachDebuggerEx failed...");
|
||||
else
|
||||
dputs("detached!");
|
||||
dputs("Detached!");
|
||||
isDetachedByUser = false;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1058,15 +1033,13 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
}
|
||||
}
|
||||
}
|
||||
const char* exceptionName = 0;
|
||||
if(exceptionNames.count(ExceptionCode))
|
||||
exceptionName = exceptionNames[ExceptionCode];
|
||||
const char* exceptionName = exceptionnamefromcode(ExceptionCode);
|
||||
if(ExceptionData->dwFirstChance) //first chance exception
|
||||
{
|
||||
if(exceptionName)
|
||||
dprintf("first chance exception on "fhex" (%.8X, %s)!\n", addr, ExceptionCode, exceptionName);
|
||||
dprintf("First chance exception on "fhex" (%.8X, %s)!\n", addr, ExceptionCode, exceptionName);
|
||||
else
|
||||
dprintf("first chance exception on "fhex" (%.8X)!\n", addr, ExceptionCode);
|
||||
dprintf("First chance exception on "fhex" (%.8X)!\n", addr, ExceptionCode);
|
||||
SetNextDbgContinueStatus(DBG_EXCEPTION_NOT_HANDLED);
|
||||
if(bSkipExceptions || dbgisignoredexception(ExceptionCode))
|
||||
return;
|
||||
|
|
@ -1074,9 +1047,9 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
else //lock the exception
|
||||
{
|
||||
if(exceptionName)
|
||||
dprintf("last chance exception on "fhex" (%.8X, %s)!\n", addr, ExceptionCode, exceptionName);
|
||||
dprintf("Last chance exception on "fhex" (%.8X, %s)!\n", addr, ExceptionCode, exceptionName);
|
||||
else
|
||||
dprintf("last chance exception on "fhex" (%.8X)!\n", addr, ExceptionCode);
|
||||
dprintf("Last chance exception on "fhex" (%.8X)!\n", addr, ExceptionCode);
|
||||
SetNextDbgContinueStatus(DBG_CONTINUE);
|
||||
}
|
||||
|
||||
|
|
@ -1118,7 +1091,7 @@ DWORD WINAPI threadDebugLoop(void* lpParameter)
|
|||
if(!fdProcessInfo)
|
||||
{
|
||||
fdProcessInfo = &g_pi;
|
||||
dputs("error starting process (invalid pe?)!");
|
||||
dputs("Error starting process (invalid pe?)!");
|
||||
unlock(WAITID_STOP);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1159,12 +1132,12 @@ DWORD WINAPI threadDebugLoop(void* lpParameter)
|
|||
//inform GUI we started without problems
|
||||
GuiSetDebugState(initialized);
|
||||
//set GUI title
|
||||
strcpy(szBaseFileName, szFileName);
|
||||
strcpy_s(szBaseFileName, szFileName);
|
||||
int len = (int)strlen(szBaseFileName);
|
||||
while(szBaseFileName[len] != '\\' and len)
|
||||
len--;
|
||||
if(len)
|
||||
strcpy(szBaseFileName, szBaseFileName + len + 1);
|
||||
strcpy_s(szBaseFileName, szBaseFileName + len + 1);
|
||||
GuiUpdateWindowTitle(szBaseFileName);
|
||||
//call plugin callback
|
||||
PLUG_CB_INITDEBUG initInfo;
|
||||
|
|
@ -1195,7 +1168,8 @@ bool cbDeleteAllBreakpoints(const BREAKPOINT* bp)
|
|||
{
|
||||
if(bpdel(bp->addr, BPNORMAL) and (!bp->enabled or DeleteBPX(bp->addr)))
|
||||
return true;
|
||||
dprintf("delete breakpoint failed: "fhex"\n", bp->addr);
|
||||
|
||||
dprintf("Delete breakpoint failed: "fhex"\n", bp->addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1203,9 +1177,10 @@ bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
|
|||
{
|
||||
if(bp->type != BPNORMAL or bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!bpenable(bp->addr, BPNORMAL, true) or !SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
|
||||
{
|
||||
dprintf("could not enable breakpoint "fhex"\n", bp->addr);
|
||||
dprintf("Could not enable breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1215,9 +1190,10 @@ bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
|
|||
{
|
||||
if(bp->type != BPNORMAL or !bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!bpenable(bp->addr, BPNORMAL, false) or !DeleteBPX(bp->addr))
|
||||
{
|
||||
dprintf("could not disable breakpoint "fhex"\n", bp->addr);
|
||||
dprintf("Could not disable breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1230,7 +1206,7 @@ bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
|||
DWORD drx = 0;
|
||||
if(!GetUnusedHardwareBreakPointRegister(&drx))
|
||||
{
|
||||
dprintf("did not enable hardware breakpoint "fhex" (all slots full)\n", bp->addr);
|
||||
dprintf("Did not enable hardware breakpoint "fhex" (all slots full)\n", bp->addr);
|
||||
return true;
|
||||
}
|
||||
int titantype = bp->titantype;
|
||||
|
|
@ -1250,7 +1226,7 @@ bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
|||
return true;
|
||||
if(!bpenable(bp->addr, BPHARDWARE, false) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf("could not disable hardware breakpoint "fhex"\n", bp->addr);
|
||||
dprintf("Could not disable hardware breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1264,7 +1240,7 @@ bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
|||
memfindbaseaddr(bp->addr, &size);
|
||||
if(!bpenable(bp->addr, BPMEMORY, true) or !SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint))
|
||||
{
|
||||
dprintf("could not enable memory breakpoint "fhex"\n", bp->addr);
|
||||
dprintf("Could not enable memory breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1276,7 +1252,7 @@ bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
|||
return true;
|
||||
if(!bpenable(bp->addr, BPMEMORY, false) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf("could not disable memory breakpoint "fhex"\n", bp->addr);
|
||||
dprintf("Could not disable memory breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1312,7 +1288,7 @@ bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
|
|||
memfindbaseaddr(bp->addr, &size);
|
||||
if(!bpdel(bp->addr, BPMEMORY) or !RemoveMemoryBPX(bp->addr, size))
|
||||
{
|
||||
dprintf("delete memory breakpoint failed: "fhex"\n", bp->addr);
|
||||
dprintf("Delete memory breakpoint failed: "fhex"\n", bp->addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1324,7 +1300,7 @@ bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp)
|
|||
return true;
|
||||
if(!bpdel(bp->addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf("delete hardware breakpoint failed: "fhex"\n", bp->addr);
|
||||
dprintf("Delete hardware breakpoint failed: "fhex"\n", bp->addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1415,7 +1391,7 @@ void cbDetach()
|
|||
if(!DetachDebuggerEx(fdProcessInfo->dwProcessId))
|
||||
dputs("DetachDebuggerEx failed...");
|
||||
else
|
||||
dputs("detached!");
|
||||
dputs("Detached!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1527,35 +1503,35 @@ bool dbgpagerightstostring(DWORD protect, char* rights)
|
|||
switch(protect & 0xFF)
|
||||
{
|
||||
case PAGE_EXECUTE:
|
||||
strcpy(rights, "E---");
|
||||
strcpy_s(rights, RIGHTS_STRING_SIZE, "E---");
|
||||
break;
|
||||
case PAGE_EXECUTE_READ:
|
||||
strcpy(rights, "ER--");
|
||||
strcpy_s(rights, RIGHTS_STRING_SIZE, "ER--");
|
||||
break;
|
||||
case PAGE_EXECUTE_READWRITE:
|
||||
strcpy(rights, "ERW-");
|
||||
strcpy_s(rights, RIGHTS_STRING_SIZE, "ERW-");
|
||||
break;
|
||||
case PAGE_EXECUTE_WRITECOPY:
|
||||
strcpy(rights, "ERWC");
|
||||
strcpy_s(rights, RIGHTS_STRING_SIZE, "ERWC");
|
||||
break;
|
||||
case PAGE_NOACCESS:
|
||||
strcpy(rights, "----");
|
||||
strcpy_s(rights, RIGHTS_STRING_SIZE, "----");
|
||||
break;
|
||||
case PAGE_READONLY:
|
||||
strcpy(rights, "-R--");
|
||||
strcpy_s(rights, RIGHTS_STRING_SIZE, "-R--");
|
||||
break;
|
||||
case PAGE_READWRITE:
|
||||
strcpy(rights, "-RW-");
|
||||
strcpy_s(rights, RIGHTS_STRING_SIZE, "-RW-");
|
||||
break;
|
||||
case PAGE_WRITECOPY:
|
||||
strcpy(rights, "-RWC");
|
||||
strcpy_s(rights, RIGHTS_STRING_SIZE, "-RWC");
|
||||
break;
|
||||
}
|
||||
|
||||
if(protect & PAGE_GUARD)
|
||||
strcat(rights, "G");
|
||||
strcat_s(rights, RIGHTS_STRING_SIZE, "G");
|
||||
else
|
||||
strcat(rights, "-");
|
||||
strcat_s(rights, RIGHTS_STRING_SIZE, "-");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1701,9 +1677,9 @@ bool dbggetdefjit(char* jit_entry)
|
|||
path[0] = '"';
|
||||
wchar_t wszPath[MAX_PATH] = L"";
|
||||
GetModuleFileNameW(GetModuleHandleW(NULL), wszPath, MAX_PATH);
|
||||
strcpy(&path[1], StringUtils::Utf16ToUtf8(wszPath).c_str());
|
||||
strcpy_s(&path[1], JIT_ENTRY_DEF_SIZE - 1, StringUtils::Utf16ToUtf8(wszPath).c_str());
|
||||
strcat(path, ATTACH_CMD_LINE);
|
||||
strcpy(jit_entry, path);
|
||||
strcpy_s(jit_entry, JIT_ENTRY_DEF_SIZE, path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
#include "symbolinfo.h"
|
||||
#include "assemble.h"
|
||||
#include "disasm_fast.h"
|
||||
#include "module.h"
|
||||
#include "comment.h"
|
||||
#include "label.h"
|
||||
#include "bookmark.h"
|
||||
#include "function.h"
|
||||
|
||||
static bool bScyllaLoaded = false;
|
||||
uint LoadLibThreadID;
|
||||
|
|
@ -35,18 +40,18 @@ CMDRESULT cbDebugInit(int argc, char* argv[])
|
|||
char szResolvedPath[MAX_PATH] = "";
|
||||
if(ResolveShortcut(GuiGetWindowHandle(), StringUtils::Utf8ToUtf16(arg1).c_str(), szResolvedPath, _countof(szResolvedPath)))
|
||||
{
|
||||
dprintf("resolved shortcut \"%s\"->\"%s\"\n", arg1, szResolvedPath);
|
||||
dprintf("Resolved shortcut \"%s\"->\"%s\"\n", arg1, szResolvedPath);
|
||||
strcpy_s(arg1, szResolvedPath);
|
||||
}
|
||||
if(!FileExists(arg1))
|
||||
{
|
||||
dputs("file does not exist!");
|
||||
dputs("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("could not open file!");
|
||||
dputs("Could not open file!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GetFileNameFromHandle(hFile, arg1); //get full path of the file
|
||||
|
|
@ -56,14 +61,14 @@ CMDRESULT cbDebugInit(int argc, char* argv[])
|
|||
switch(GetFileArchitecture(arg1))
|
||||
{
|
||||
case invalid:
|
||||
dputs("invalid PE file!");
|
||||
dputs("Invalid PE file!");
|
||||
return STATUS_ERROR;
|
||||
#ifdef _WIN64
|
||||
case x32:
|
||||
dputs("use x32_dbg to debug this file!");
|
||||
dputs("Use x32_dbg to debug this file!");
|
||||
#else //x86
|
||||
case x64:
|
||||
dputs("use x64_dbg to debug this file!");
|
||||
dputs("Use x64_dbg to debug this file!");
|
||||
#endif //_WIN64
|
||||
return STATUS_ERROR;
|
||||
default:
|
||||
|
|
@ -80,14 +85,14 @@ CMDRESULT cbDebugInit(int argc, char* argv[])
|
|||
argget(*argv, arg3, 2, true);
|
||||
|
||||
static char currentfolder[deflen] = "";
|
||||
strcpy(currentfolder, arg1);
|
||||
strcpy_s(currentfolder, arg1);
|
||||
int len = (int)strlen(currentfolder);
|
||||
while(currentfolder[len] != '\\' and len != 0)
|
||||
len--;
|
||||
currentfolder[len] = 0;
|
||||
|
||||
if(DirExists(arg3))
|
||||
strcpy(currentfolder, arg3);
|
||||
strcpy_s(currentfolder, arg3);
|
||||
//initialize
|
||||
wait(WAITID_STOP); //wait for the debugger to stop
|
||||
waitclear(); //clear waiting flags NOTE: thread-unsafe
|
||||
|
|
@ -115,7 +120,7 @@ CMDRESULT cbDebugRun(int argc, char* argv[])
|
|||
{
|
||||
if(!waitislocked(WAITID_RUN))
|
||||
{
|
||||
dputs("program is already running");
|
||||
dputs("Program is already running");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiSetDebugState(running);
|
||||
|
|
@ -161,12 +166,12 @@ CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[])
|
|||
}
|
||||
else
|
||||
{
|
||||
dputs("invalid type specified!");
|
||||
dputs("Invalid type specified!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
SetBPXOptions(type);
|
||||
BridgeSettingSetUint("Engine", "BreakpointType", setting_type);
|
||||
dprintf("default breakpoint type set to: %s\n", a);
|
||||
dprintf("Default breakpoint type set to: %s\n", a);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -181,14 +186,14 @@ CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]]
|
|||
bool has_arg2 = argget(*argv, argtype, 2, true);
|
||||
if(!has_arg2 and (scmp(argname, "ss") or scmp(argname, "long") or scmp(argname, "ud2")))
|
||||
{
|
||||
strcpy(argtype, argname);
|
||||
strcpy_s(argtype, argname);
|
||||
*argname = 0;
|
||||
}
|
||||
_strlwr(argtype);
|
||||
uint addr = 0;
|
||||
if(!valfromstring(argaddr, &addr))
|
||||
{
|
||||
dprintf("invalid addr: \"%s\"\n", argaddr);
|
||||
dprintf("Invalid addr: \"%s\"\n", argaddr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
int type = 0;
|
||||
|
|
@ -212,30 +217,30 @@ CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]]
|
|||
bpname = argname;
|
||||
if(bpget(addr, BPNORMAL, bpname, 0))
|
||||
{
|
||||
dputs("breakpoint already set!");
|
||||
dputs("Breakpoint already set!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(IsBPXEnabled(addr))
|
||||
{
|
||||
dprintf("error setting breakpoint at "fhex"! (IsBPXEnabled)\n", addr);
|
||||
dprintf("Error setting breakpoint at "fhex"! (IsBPXEnabled)\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(!memread(fdProcessInfo->hProcess, (void*)addr, &oldbytes, sizeof(short), 0))
|
||||
{
|
||||
dprintf("error setting breakpoint at "fhex"! (memread)\n", addr);
|
||||
dprintf("Error setting breakpoint at "fhex"! (memread)\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(!bpnew(addr, true, singleshoot, oldbytes, BPNORMAL, type, bpname))
|
||||
{
|
||||
dprintf("error setting breakpoint at "fhex"! (bpnew)\n", addr);
|
||||
dprintf("Error setting breakpoint at "fhex"! (bpnew)\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(!SetBPX(addr, type, (void*)cbUserBreakpoint))
|
||||
{
|
||||
dprintf("error setting breakpoint at "fhex"! (SetBPX)\n", addr);
|
||||
dprintf("Error setting breakpoint at "fhex"! (SetBPX)\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("breakpoint at "fhex" set!\n", addr);
|
||||
dprintf("Breakpoint at "fhex" set!\n", addr);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -247,12 +252,12 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
|
|||
{
|
||||
if(!bpgetcount(BPNORMAL))
|
||||
{
|
||||
dputs("no breakpoints to delete!");
|
||||
dputs("No breakpoints to delete!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenumall(cbDeleteAllBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all breakpoints deleted!");
|
||||
dputs("All breakpoints deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -261,12 +266,12 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
|
|||
{
|
||||
if(!bpdel(found.addr, BPNORMAL))
|
||||
{
|
||||
dprintf("delete breakpoint failed (bpdel): "fhex"\n", found.addr);
|
||||
dprintf("Delete breakpoint failed (bpdel): "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(found.enabled && !DeleteBPX(found.addr))
|
||||
{
|
||||
dprintf("delete breakpoint failed (DeleteBPX): "fhex"\n", found.addr);
|
||||
dprintf("Delete breakpoint failed (DeleteBPX): "fhex"\n", found.addr);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
|
@ -275,21 +280,21 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("no such breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!bpdel(found.addr, BPNORMAL))
|
||||
{
|
||||
dprintf("delete breakpoint failed (bpdel): "fhex"\n", found.addr);
|
||||
dprintf("Delete breakpoint failed (bpdel): "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(found.enabled && !DeleteBPX(found.addr))
|
||||
{
|
||||
dprintf("delete breakpoint failed (DeleteBPX): "fhex"\n", found.addr);
|
||||
dprintf("Delete breakpoint failed (DeleteBPX): "fhex"\n", found.addr);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("breakpoint deleted!");
|
||||
dputs("Breakpoint deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -301,12 +306,12 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
|
|||
{
|
||||
if(!bpgetcount(BPNORMAL))
|
||||
{
|
||||
dputs("no breakpoints to enable!");
|
||||
dputs("No breakpoints to enable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenumall(cbEnableAllBreakpoints)) //at least one enable failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all breakpoints enabled!");
|
||||
dputs("All breakpoints enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -315,7 +320,7 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
|
|||
{
|
||||
if(!bpenable(found.addr, BPNORMAL, true) or !SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
|
||||
{
|
||||
dprintf("could not enable breakpoint "fhex"\n", found.addr);
|
||||
dprintf("Could not enable breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiUpdateAllViews();
|
||||
|
|
@ -324,21 +329,21 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("no such breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(found.enabled)
|
||||
{
|
||||
dputs("breakpoint already enabled!");
|
||||
dputs("Breakpoint already enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenable(found.addr, BPNORMAL, true) or !SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
|
||||
{
|
||||
dprintf("could not enable breakpoint "fhex"\n", found.addr);
|
||||
dprintf("Could not enable breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("breakpoint enabled!");
|
||||
dputs("Breakpoint enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -350,12 +355,12 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
|
|||
{
|
||||
if(!bpgetcount(BPNORMAL))
|
||||
{
|
||||
dputs("no breakpoints to disable!");
|
||||
dputs("No breakpoints to disable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenumall(cbDisableAllBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all breakpoints disabled!");
|
||||
dputs("All breakpoints disabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -364,7 +369,7 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
|
|||
{
|
||||
if(!bpenable(found.addr, BPNORMAL, false) or !DeleteBPX(found.addr))
|
||||
{
|
||||
dprintf("could not disable breakpoint "fhex"\n", found.addr);
|
||||
dprintf("Could not disable breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiUpdateAllViews();
|
||||
|
|
@ -373,20 +378,20 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("no such breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!found.enabled)
|
||||
{
|
||||
dputs("breakpoint already disabled!");
|
||||
dputs("Breakpoint already disabled!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenable(found.addr, BPNORMAL, false) or !DeleteBPX(found.addr))
|
||||
{
|
||||
dprintf("could not disable breakpoint "fhex"\n", found.addr);
|
||||
dprintf("Could not disable breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("breakpoint disabled!");
|
||||
dputs("Breakpoint disabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -446,9 +451,9 @@ CMDRESULT cbDebugeSingleStep(int argc, char* argv[])
|
|||
CMDRESULT cbDebugHide(int argc, char* argv[])
|
||||
{
|
||||
if(HideDebugger(fdProcessInfo->hProcess, UE_HIDE_PEBONLY))
|
||||
dputs("debugger hidden");
|
||||
dputs("Debugger hidden");
|
||||
else
|
||||
dputs("something went wrong");
|
||||
dputs("Something went wrong");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -484,7 +489,7 @@ CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[])
|
|||
else if(*arg2 == '0')
|
||||
restore = false;
|
||||
else
|
||||
strcpy(arg3, arg2);
|
||||
strcpy_s(arg3, arg2);
|
||||
}
|
||||
DWORD type = UE_MEMORY;
|
||||
if(*arg3)
|
||||
|
|
@ -501,7 +506,7 @@ CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[])
|
|||
type = UE_MEMORY_EXECUTE; //EXECUTE
|
||||
break;
|
||||
default:
|
||||
dputs("invalid type (argument ignored)");
|
||||
dputs("Invalid type (argument ignored)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -512,15 +517,15 @@ CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[])
|
|||
singleshoot = true;
|
||||
if(bpget(base, BPMEMORY, 0, 0))
|
||||
{
|
||||
dputs("hardware breakpoint already set!");
|
||||
dputs("Hardware breakpoint already set!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpnew(base, true, singleshoot, 0, BPMEMORY, type, 0) or !SetMemoryBPXEx(base, size, type, restore, (void*)cbMemoryBreakpoint))
|
||||
{
|
||||
dputs("error setting memory breakpoint!");
|
||||
dputs("Error setting memory breakpoint!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("memory breakpoint at "fhex" set!\n", addr);
|
||||
dprintf("Memory breakpoint at "fhex" set!\n", addr);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -537,7 +542,7 @@ CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
|
|||
}
|
||||
if(!bpenumall(cbDeleteAllMemoryBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all memory breakpoints deleted!");
|
||||
dputs("All memory breakpoints deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -548,7 +553,7 @@ CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
|
|||
memfindbaseaddr(found.addr, &size);
|
||||
if(!bpdel(found.addr, BPMEMORY) or !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf("delete memory breakpoint failed: "fhex"\n", found.addr);
|
||||
dprintf("Delete memory breakpoint failed: "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
|
|
@ -556,17 +561,17 @@ CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPMEMORY, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("no such memory breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such memory breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint size;
|
||||
memfindbaseaddr(found.addr, &size);
|
||||
if(!bpdel(found.addr, BPMEMORY) or !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf("delete memory breakpoint failed: "fhex"\n", found.addr);
|
||||
dprintf("Delete memory breakpoint failed: "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("memory breakpoint deleted!");
|
||||
dputs("Memory breakpoint deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -612,56 +617,66 @@ CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
char arg3[deflen] = ""; //size
|
||||
uint size = UE_HARDWARE_SIZE_1;
|
||||
DWORD titsize = UE_HARDWARE_SIZE_1;
|
||||
if(argget(*argv, arg3, 2, true))
|
||||
{
|
||||
uint size;
|
||||
if(!valfromstring(arg3, &size))
|
||||
return STATUS_ERROR;
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
titsize = UE_HARDWARE_SIZE_1;
|
||||
break;
|
||||
case 2:
|
||||
size = UE_HARDWARE_SIZE_2;
|
||||
titsize = UE_HARDWARE_SIZE_2;
|
||||
break;
|
||||
case 4:
|
||||
size = UE_HARDWARE_SIZE_4;
|
||||
titsize = UE_HARDWARE_SIZE_4;
|
||||
break;
|
||||
#ifdef _WIN64
|
||||
case 8:
|
||||
size = UE_HARDWARE_SIZE_8;
|
||||
titsize = UE_HARDWARE_SIZE_8;
|
||||
break;
|
||||
#endif // _WIN64
|
||||
default:
|
||||
dputs("invalid size, using 1");
|
||||
titsize = UE_HARDWARE_SIZE_1;
|
||||
dputs("Invalid size, using 1");
|
||||
break;
|
||||
}
|
||||
if((addr % size) != 0)
|
||||
{
|
||||
dprintf("address not aligned to %d\n", size);
|
||||
dprintf("Address not aligned to %d\n", size);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
DWORD drx = 0;
|
||||
if(!GetUnusedHardwareBreakPointRegister(&drx))
|
||||
{
|
||||
dputs("you can only set 4 hardware breakpoints");
|
||||
dputs("You can only set 4 hardware breakpoints");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
int titantype = 0;
|
||||
TITANSETDRX(titantype, drx);
|
||||
TITANSETTYPE(titantype, type);
|
||||
TITANSETSIZE(titantype, size);
|
||||
TITANSETSIZE(titantype, titsize);
|
||||
//TODO: hwbp in multiple threads TEST
|
||||
if(bpget(addr, BPHARDWARE, 0, 0))
|
||||
{
|
||||
dputs("hardware breakpoint already set!");
|
||||
dputs("Hardware breakpoint already set!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpnew(addr, true, false, 0, BPHARDWARE, titantype, 0) or !SetHardwareBreakPoint(addr, drx, type, (DWORD)size, (void*)cbHardwareBreakpoint))
|
||||
if(!bpnew(addr, true, false, 0, BPHARDWARE, titantype, 0))
|
||||
{
|
||||
dputs("error setting hardware breakpoint!");
|
||||
dputs("error setting hardware breakpoint (bpnew)!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("hardware breakpoint at "fhex" set!\n", addr);
|
||||
if(!SetHardwareBreakPoint(addr, drx, type, titsize, (void*)cbHardwareBreakpoint))
|
||||
{
|
||||
dputs("error setting hardware breakpoint (TitanEngine)!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dprintf("Hardware breakpoint at "fhex" set!\n", addr);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -673,12 +688,12 @@ CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
|
|||
{
|
||||
if(!bpgetcount(BPHARDWARE))
|
||||
{
|
||||
dputs("no hardware breakpoints to delete!");
|
||||
dputs("No hardware breakpoints to delete!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenumall(cbDeleteAllHardwareBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all hardware breakpoints deleted!");
|
||||
dputs("All hardware breakpoints deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -687,7 +702,7 @@ CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
|
|||
{
|
||||
if(!bpdel(found.addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
{
|
||||
dprintf("delete hardware breakpoint failed: "fhex"\n", found.addr);
|
||||
dprintf("Delete hardware breakpoint failed: "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
|
|
@ -695,15 +710,15 @@ CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPHARDWARE, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("no such hardware breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!bpdel(found.addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
{
|
||||
dprintf("delete hardware breakpoint failed: "fhex"\n", found.addr);
|
||||
dprintf("Delete hardware breakpoint failed: "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("hardware breakpoint deleted!");
|
||||
dputs("Hardware breakpoint deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -742,7 +757,7 @@ CMDRESULT cbDebugFree(int argc, char* argv[])
|
|||
}
|
||||
else if(!lastalloc)
|
||||
{
|
||||
dputs("lastalloc is zero, provide a page address");
|
||||
dputs("$lastalloc is zero, provide a page address");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(addr == lastalloc)
|
||||
|
|
@ -765,7 +780,7 @@ CMDRESULT cbDebugMemset(int argc, char* argv[])
|
|||
uint size;
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs("not enough arguments");
|
||||
dputs("Not enough arguments");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!valfromstring(argv[1], &addr, false) or !valfromstring(argv[2], &value, false))
|
||||
|
|
@ -789,9 +804,9 @@ CMDRESULT cbDebugMemset(int argc, char* argv[])
|
|||
}
|
||||
BYTE fi = value & 0xFF;
|
||||
if(!Fill((void*)addr, size & 0xFFFFFFFF, &fi))
|
||||
dputs("memset failed");
|
||||
dputs("Memset failed");
|
||||
else
|
||||
dprintf("memory "fhex" (size: %.8X) set to %.2X\n", addr, size & 0xFFFFFFFF, value & 0xFF);
|
||||
dprintf("Memory "fhex" (size: %.8X) set to %.2X\n", addr, size & 0xFFFFFFFF, value & 0xFF);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -815,7 +830,7 @@ CMDRESULT cbDebugPause(int argc, char* argv[])
|
|||
{
|
||||
if(waitislocked(WAITID_RUN))
|
||||
{
|
||||
dputs("program is not running");
|
||||
dputs("Program is not running");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dbgsetispausedbyuser(true);
|
||||
|
|
@ -830,7 +845,7 @@ static DWORD WINAPI scyllaThread(void* lpParam)
|
|||
HINSTANCE hScylla = LoadLibraryW(L"Scylla.dll");
|
||||
if(!hScylla)
|
||||
{
|
||||
dputs("error loading Scylla.dll!");
|
||||
dputs("Error loading Scylla.dll!");
|
||||
bScyllaLoaded = false;
|
||||
FreeLibrary(hScylla);
|
||||
return 0;
|
||||
|
|
@ -838,7 +853,7 @@ static DWORD WINAPI scyllaThread(void* lpParam)
|
|||
ScyllaStartGui = (SCYLLASTARTGUI)GetProcAddress(hScylla, "ScyllaStartGui");
|
||||
if(!ScyllaStartGui)
|
||||
{
|
||||
dputs("could not find export 'ScyllaStartGui' inside Scylla.dll");
|
||||
dputs("Could not find export 'ScyllaStartGui' inside Scylla.dll");
|
||||
bScyllaLoaded = false;
|
||||
FreeLibrary(hScylla);
|
||||
return 0;
|
||||
|
|
@ -868,7 +883,7 @@ CMDRESULT cbDebugAttach(int argc, char* argv[])
|
|||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
dputs("Not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint pid = 0;
|
||||
|
|
@ -886,7 +901,7 @@ CMDRESULT cbDebugAttach(int argc, char* argv[])
|
|||
Handle hProcess = TitanOpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid);
|
||||
if(!hProcess)
|
||||
{
|
||||
dprintf("could not open process %X!\n", pid);
|
||||
dprintf("Could not open process %X!\n", pid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
BOOL wow64 = false, mewow64 = false;
|
||||
|
|
@ -907,7 +922,7 @@ CMDRESULT cbDebugAttach(int argc, char* argv[])
|
|||
wchar_t wszFileName[MAX_PATH] = L"";
|
||||
if(!GetModuleFileNameExW(hProcess, 0, wszFileName, MAX_PATH))
|
||||
{
|
||||
dprintf("could not get module filename %X!\n", pid);
|
||||
dprintf("Could not get module filename %X!\n", pid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
strcpy_s(szFileName, StringUtils::Utf16ToUtf8(wszFileName).c_str());
|
||||
|
|
@ -934,7 +949,7 @@ CMDRESULT cbDebugDump(int argc, char* argv[])
|
|||
duint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr))
|
||||
{
|
||||
dprintf("invalid address \"%s\"!\n", argv[1]);
|
||||
dprintf("Invalid address \"%s\"!\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiDumpAt(addr);
|
||||
|
|
@ -948,7 +963,7 @@ CMDRESULT cbDebugStackDump(int argc, char* argv[])
|
|||
addr = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
else if(!valfromstring(argv[1], &addr))
|
||||
{
|
||||
dprintf("invalid address \"%s\"!\n", argv[1]);
|
||||
dprintf("Invalid address \"%s\"!\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
|
|
@ -957,7 +972,7 @@ CMDRESULT cbDebugStackDump(int argc, char* argv[])
|
|||
if(base && addr >= base && addr < (base + size))
|
||||
GuiStackDumpAt(addr, csp);
|
||||
else
|
||||
dputs("invalid stack address!");
|
||||
dputs("Invalid stack address!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -966,12 +981,12 @@ CMDRESULT cbDebugContinue(int argc, char* argv[])
|
|||
if(argc < 2)
|
||||
{
|
||||
SetNextDbgContinueStatus(DBG_CONTINUE);
|
||||
dputs("exception will be swallowed");
|
||||
dputs("Exception will be swallowed");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextDbgContinueStatus(DBG_EXCEPTION_NOT_HANDLED);
|
||||
dputs("exception will be thrown in the program");
|
||||
dputs("Exception will be thrown in the program");
|
||||
}
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1000,7 +1015,7 @@ CMDRESULT cbDebugBpDll(int argc, char* argv[])
|
|||
if(argc > 3)
|
||||
singleshoot = false;
|
||||
LibrarianSetBreakPoint(argv[1], type, singleshoot, (void*)cbLibrarianBreakpoint);
|
||||
dprintf("dll breakpoint set on \"%s\"!\n", argv[1]);
|
||||
dprintf("Dll breakpoint set on \"%s\"!\n", argv[1]);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -1008,15 +1023,15 @@ CMDRESULT cbDebugBcDll(int argc, char* argv[])
|
|||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
dputs("not enough arguments");
|
||||
dputs("Not enough arguments");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!LibrarianRemoveBreakPoint(argv[1], UE_ON_LIB_ALL))
|
||||
{
|
||||
dputs("failed to remove dll breakpoint...");
|
||||
dputs("Failed to remove DLL breakpoint...");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("dll breakpoint removed!");
|
||||
dputs("DLL breakpoint removed!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -1028,13 +1043,13 @@ CMDRESULT cbDebugSwitchthread(int argc, char* argv[])
|
|||
return STATUS_ERROR;
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("invalid thread %X\n", threadid);
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//switch thread
|
||||
hActiveThread = threadgethandle((DWORD)threadid);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
dputs("thread switched!");
|
||||
dputs("Thread switched!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -1046,16 +1061,16 @@ CMDRESULT cbDebugSuspendthread(int argc, char* argv[])
|
|||
return STATUS_ERROR;
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("invalid thread %X\n", threadid);
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//suspend thread
|
||||
if(SuspendThread(threadgethandle((DWORD)threadid)) == -1)
|
||||
{
|
||||
dputs("error suspending thread");
|
||||
dputs("Error suspending thread");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("thread suspended");
|
||||
dputs("Thread suspended");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1068,16 +1083,16 @@ CMDRESULT cbDebugResumethread(int argc, char* argv[])
|
|||
return STATUS_ERROR;
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("invalid thread %X\n", threadid);
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//resume thread
|
||||
if(ResumeThread(threadgethandle((DWORD)threadid)) == -1)
|
||||
{
|
||||
dputs("error resuming thread");
|
||||
dputs("Error resuming thread");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("thread resumed!");
|
||||
dputs("Thread resumed!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1094,17 +1109,17 @@ CMDRESULT cbDebugKillthread(int argc, char* argv[])
|
|||
return STATUS_ERROR;
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("invalid thread %X\n", threadid);
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//terminate thread
|
||||
if(TerminateThread(threadgethandle((DWORD)threadid), (DWORD)exitcode) != 0)
|
||||
{
|
||||
GuiUpdateAllViews();
|
||||
dputs("thread terminated");
|
||||
dputs("Thread terminated");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
dputs("error terminating thread!");
|
||||
dputs("Error terminating thread!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -1130,7 +1145,7 @@ CMDRESULT cbDebugSetPriority(int argc, char* argv[])
|
|||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
dputs("Not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint threadid;
|
||||
|
|
@ -1155,7 +1170,7 @@ CMDRESULT cbDebugSetPriority(int argc, char* argv[])
|
|||
priority = THREAD_PRIORITY_LOWEST;
|
||||
else
|
||||
{
|
||||
dputs("unknown priority value, read the help!");
|
||||
dputs("Unknown priority value, read the help!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
@ -1172,22 +1187,22 @@ CMDRESULT cbDebugSetPriority(int argc, char* argv[])
|
|||
case THREAD_PRIORITY_LOWEST:
|
||||
break;
|
||||
default:
|
||||
dputs("unknown priority value, read the help!");
|
||||
dputs("Unknown priority value, read the help!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("invalid thread %X\n", threadid);
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//set thread priority
|
||||
if(SetThreadPriority(threadgethandle((DWORD)threadid), (int)priority) == 0)
|
||||
{
|
||||
dputs("error setting thread priority");
|
||||
dputs("Error setting thread priority");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("thread priority changed!");
|
||||
dputs("Thread priority changed!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1198,19 +1213,19 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
|
|||
DWORD drx = 0;
|
||||
if(!GetUnusedHardwareBreakPointRegister(&drx))
|
||||
{
|
||||
dputs("you can only set 4 hardware breakpoints");
|
||||
dputs("You can only set 4 hardware breakpoints");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!argget(*argv, arg1, 0, true)) //enable all hardware breakpoints
|
||||
{
|
||||
if(!bpgetcount(BPHARDWARE))
|
||||
{
|
||||
dputs("no hardware breakpoints to enable!");
|
||||
dputs("No hardware breakpoints to enable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenumall(cbEnableAllHardwareBreakpoints)) //at least one enable failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all hardware breakpoints enabled!");
|
||||
dputs("All hardware breakpoints enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1218,12 +1233,12 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
|
||||
{
|
||||
dprintf("no such hardware breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(found.enabled)
|
||||
{
|
||||
dputs("hardware breakpoint already enabled!");
|
||||
dputs("Hardware breakpoint already enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1231,10 +1246,10 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
|
|||
bpsettitantype(found.addr, BPHARDWARE, found.titantype);
|
||||
if(!bpenable(found.addr, BPHARDWARE, true) or !SetHardwareBreakPoint(found.addr, drx, TITANGETTYPE(found.titantype), TITANGETSIZE(found.titantype), (void*)cbHardwareBreakpoint))
|
||||
{
|
||||
dprintf("could not enable hardware breakpoint "fhex"\n", found.addr);
|
||||
dprintf("Could not enable hardware breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("hardware breakpoint enabled!");
|
||||
dputs("Hardware breakpoint enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1246,12 +1261,12 @@ CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
|
|||
{
|
||||
if(!bpgetcount(BPHARDWARE))
|
||||
{
|
||||
dputs("no hardware breakpoints to disable!");
|
||||
dputs("No hardware breakpoints to disable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenumall(cbDisableAllHardwareBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all hardware breakpoints disabled!");
|
||||
dputs("All hardware breakpoints disabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1259,20 +1274,20 @@ CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
|
||||
{
|
||||
dprintf("no such hardware breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!found.enabled)
|
||||
{
|
||||
dputs("hardware breakpoint already disabled!");
|
||||
dputs("Hardware breakpoint already disabled!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenable(found.addr, BPHARDWARE, false) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
{
|
||||
dprintf("could not disable hardware breakpoint "fhex"\n", found.addr);
|
||||
dprintf("Could not disable hardware breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("hardware breakpoint disabled!");
|
||||
dputs("Hardware breakpoint disabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1283,19 +1298,19 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
|
|||
DWORD drx = 0;
|
||||
if(!GetUnusedHardwareBreakPointRegister(0))
|
||||
{
|
||||
dputs("you can only set 4 hardware breakpoints");
|
||||
dputs("You can only set 4 hardware breakpoints");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!argget(*argv, arg1, 0, true)) //enable all memory breakpoints
|
||||
{
|
||||
if(!bpgetcount(BPMEMORY))
|
||||
{
|
||||
dputs("no hardware breakpoints to enable!");
|
||||
dputs("No hardware breakpoints to enable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenumall(cbEnableAllHardwareBreakpoints)) //at least one enable failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all memory breakpoints enabled!");
|
||||
dputs("All memory breakpoints enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1303,12 +1318,12 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
|
||||
{
|
||||
dprintf("no such memory breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such memory breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(found.enabled)
|
||||
{
|
||||
dputs("hardware memory already enabled!");
|
||||
dputs("Hardware memory already enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1316,10 +1331,10 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
|
|||
memfindbaseaddr(found.addr, &size);
|
||||
if(!bpenable(found.addr, BPMEMORY, true) or !SetMemoryBPXEx(found.addr, size, found.titantype, !found.singleshoot, (void*)cbMemoryBreakpoint))
|
||||
{
|
||||
dprintf("could not enable memory breakpoint "fhex"\n", found.addr);
|
||||
dprintf("Could not enable memory breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("memory breakpoint enabled!");
|
||||
dputs("Memory breakpoint enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1331,12 +1346,12 @@ CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
|
|||
{
|
||||
if(!bpgetcount(BPMEMORY))
|
||||
{
|
||||
dputs("no memory breakpoints to disable!");
|
||||
dputs("No memory breakpoints to disable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!bpenumall(cbDisableAllMemoryBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("all memory breakpoints disabled!");
|
||||
dputs("All memory breakpoints disabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1344,22 +1359,22 @@ CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
|
||||
{
|
||||
dprintf("no such memory breakpoint \"%s\"\n", arg1);
|
||||
dprintf("No such memory breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!found.enabled)
|
||||
{
|
||||
dputs("memory breakpoint already disabled!");
|
||||
dputs("Memory breakpoint already disabled!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
uint size = 0;
|
||||
memfindbaseaddr(found.addr, &size);
|
||||
if(!bpenable(found.addr, BPMEMORY, false) or !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf("could not disable memory breakpoint "fhex"\n", found.addr);
|
||||
dprintf("Could not disable memory breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
dputs("memory breakpoint disabled!");
|
||||
dputs("Memory breakpoint disabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
|
@ -1370,21 +1385,21 @@ CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
|
|||
const char* szSymbolStore = szDefaultStore;
|
||||
if(!BridgeSettingGet("Symbols", "DefaultStore", szDefaultStore)) //get default symbol store from settings
|
||||
{
|
||||
strcpy(szDefaultStore, "http://msdl.microsoft.com/download/symbols");
|
||||
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("done! See symbol log for more information");
|
||||
dputs("Done! See symbol log for more information");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
//get some module information
|
||||
uint modbase = modbasefromname(argv[1]);
|
||||
if(!modbase)
|
||||
{
|
||||
dprintf("invalid module \"%s\"!\n", argv[1]);
|
||||
dprintf("Invalid module \"%s\"!\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
wchar_t wszModulePath[MAX_PATH] = L"";
|
||||
|
|
@ -1396,7 +1411,7 @@ CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
|
|||
char szModulePath[MAX_PATH] = "";
|
||||
strcpy_s(szModulePath, StringUtils::Utf16ToUtf8(wszModulePath).c_str());
|
||||
char szOldSearchPath[MAX_PATH] = "";
|
||||
if(!SymGetSearchPath(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current search path
|
||||
if(!SafeSymGetSearchPath(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current search path
|
||||
{
|
||||
dputs("SymGetSearchPath failed!");
|
||||
return STATUS_ERROR;
|
||||
|
|
@ -1405,30 +1420,30 @@ CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
|
|||
if(argc > 2)
|
||||
szSymbolStore = argv[2];
|
||||
sprintf_s(szServerSearchPath, "SRV*%s*%s", szSymbolCachePath, szSymbolStore);
|
||||
if(!SymSetSearchPath(fdProcessInfo->hProcess, szServerSearchPath)) //set new search path
|
||||
if(!SafeSymSetSearchPath(fdProcessInfo->hProcess, szServerSearchPath)) //set new search path
|
||||
{
|
||||
dputs("SymSetSearchPath (1) failed!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!SymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase)) //unload module
|
||||
if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase)) //unload module
|
||||
{
|
||||
SymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath);
|
||||
SafeSymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath);
|
||||
dputs("SymUnloadModule64 failed!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!SymLoadModuleEx(fdProcessInfo->hProcess, 0, szModulePath, 0, (DWORD64)modbase, 0, 0, 0)) //load module
|
||||
if(!SafeSymLoadModuleEx(fdProcessInfo->hProcess, 0, szModulePath, 0, (DWORD64)modbase, 0, 0, 0)) //load module
|
||||
{
|
||||
dputs("SymLoadModuleEx failed!");
|
||||
SymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath);
|
||||
SafeSymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!SymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath))
|
||||
if(!SafeSymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath))
|
||||
{
|
||||
dputs("SymSetSearchPath (2) failed!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
GuiSymbolRefreshCurrent();
|
||||
dputs("done! See symbol log for more information");
|
||||
dputs("Done! See symbol log for more information");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -1829,7 +1844,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
int counter = 0;
|
||||
uint LoadLibraryA = 0;
|
||||
char command[50] = "";
|
||||
char error[256] = "";
|
||||
char error[MAX_ERROR_SIZE] = "";
|
||||
|
||||
GetFullContextDataEx(LoadLibThread, &backupctx);
|
||||
|
||||
|
|
@ -1837,7 +1852,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
|
||||
// Arch specific asm code
|
||||
#ifdef _WIN64
|
||||
sprintf(command, "mov rcx, "fhex, DLLNameMem);
|
||||
sprintf(command, "mov rcx, "fhex, (uint)DLLNameMem);
|
||||
#else
|
||||
sprintf(command, "push "fhex, DLLNameMem);
|
||||
#endif // _WIN64
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ void fillbasicinfo(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo)
|
|||
//zero basicinfo
|
||||
memset(basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO));
|
||||
//copy instruction text
|
||||
strcpy(basicinfo->instruction, disasm->CompleteInstr);
|
||||
strcpy_s(basicinfo->instruction, disasm->CompleteInstr);
|
||||
//find immidiat
|
||||
if(disasm->Instruction.BranchType == 0) //no branch
|
||||
{
|
||||
|
|
@ -61,7 +61,7 @@ void fillbasicinfo(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo)
|
|||
{
|
||||
basicinfo->type |= TYPE_MEMORY;
|
||||
basicinfo->memory.value = (ULONG_PTR)disasm->Argument1.Memory.Displacement;
|
||||
strcpy(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
|
||||
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
|
||||
}
|
||||
basicinfo->memory.size = argsize2memsize(disasm->Argument1.ArgSize);
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ void fillbasicinfo(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo)
|
|||
{
|
||||
basicinfo->type |= TYPE_MEMORY;
|
||||
basicinfo->memory.value = (ULONG_PTR)disasm->Argument2.Memory.Displacement;
|
||||
strcpy(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
|
||||
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
|
||||
}
|
||||
basicinfo->memory.size = argsize2memsize(disasm->Argument2.ArgSize);
|
||||
}
|
||||
|
|
@ -88,14 +88,14 @@ void fillbasicinfo(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo)
|
|||
{
|
||||
basicinfo->type |= TYPE_MEMORY;
|
||||
basicinfo->memory.value = (ULONG_PTR)disasm->Instruction.AddrValue;
|
||||
strcpy(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
|
||||
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
|
||||
basicinfo->memory.size = argsize2memsize(disasm->Argument1.ArgSize);
|
||||
}
|
||||
else if((disasm->Argument2.ArgType & RELATIVE_) == RELATIVE_)
|
||||
{
|
||||
basicinfo->type |= TYPE_MEMORY;
|
||||
basicinfo->memory.value = (ULONG_PTR)disasm->Instruction.AddrValue;
|
||||
strcpy(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
|
||||
strcpy_s(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
|
||||
basicinfo->memory.size = argsize2memsize(disasm->Argument2.ArgSize);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,9 +133,9 @@ const char* disasmtext(uint addr)
|
|||
int len = Disasm(&disasm);
|
||||
static char instruction[INSTRUCT_LENGTH] = "";
|
||||
if(len == UNKNOWN_OPCODE)
|
||||
strcpy(instruction, "???");
|
||||
strcpy_s(instruction, "???");
|
||||
else
|
||||
strcpy(instruction, disasm.CompleteInstr);
|
||||
strcpy_s(instruction, disasm.CompleteInstr);
|
||||
return instruction;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ static bool HandleArgument(ARGTYPE* Argument, INSTRTYPE* Instruction, DISASM_ARG
|
|||
if(!*argmnemonic)
|
||||
return false;
|
||||
arg->memvalue = 0;
|
||||
strcpy(arg->mnemonic, argmnemonic);
|
||||
strcpy_s(arg->mnemonic, argmnemonic);
|
||||
if((argtype & MEMORY_TYPE) == MEMORY_TYPE)
|
||||
{
|
||||
arg->type = arg_memory;
|
||||
|
|
@ -239,7 +239,7 @@ void disasmget(unsigned char* buffer, uint addr, DISASM_INSTR* instr)
|
|||
disasm.VirtualAddr = addr;
|
||||
disasm.EIP = (UIntPtr)buffer;
|
||||
int len = Disasm(&disasm);
|
||||
strcpy(instr->instruction, disasm.CompleteInstr);
|
||||
strcpy_s(instr->instruction, disasm.CompleteInstr);
|
||||
if(len == UNKNOWN_OPCODE)
|
||||
{
|
||||
instr->instr_size = 1;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _ERROR_H
|
||||
#define _ERROR_H
|
||||
|
||||
void errorinit();
|
||||
const char* errornamefromcode(unsigned int ErrorCode);
|
||||
|
||||
#endif //_ERROR_H
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
#include "exception.h"
|
||||
#include <map>
|
||||
|
||||
static std::map<unsigned int, const char*> exceptionNames;
|
||||
|
||||
void exceptioninit()
|
||||
{
|
||||
exceptionNames.insert(std::make_pair(0x40000005, "STATUS_SEGMENT_NOTIFICATION"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001C, "STATUS_WX86_UNSIMULATE"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001D, "STATUS_WX86_CONTINUE"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001E, "STATUS_WX86_SINGLE_STEP"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001F, "STATUS_WX86_BREAKPOINT"));
|
||||
exceptionNames.insert(std::make_pair(0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE"));
|
||||
exceptionNames.insert(std::make_pair(0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE"));
|
||||
exceptionNames.insert(std::make_pair(0x40000022, "STATUS_WX86_EXCEPTION_CHAIN"));
|
||||
exceptionNames.insert(std::make_pair(0x40000028, "STATUS_WX86_CREATEWX86TIB"));
|
||||
exceptionNames.insert(std::make_pair(0x40010003, "DBG_TERMINATE_THREAD"));
|
||||
exceptionNames.insert(std::make_pair(0x40010004, "DBG_TERMINATE_PROCESS"));
|
||||
exceptionNames.insert(std::make_pair(0x40010005, "DBG_CONTROL_C"));
|
||||
exceptionNames.insert(std::make_pair(0x40010006, "DBG_PRINTEXCEPTION_C"));
|
||||
exceptionNames.insert(std::make_pair(0x40010007, "DBG_RIPEXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0x40010008, "DBG_CONTROL_BREAK"));
|
||||
exceptionNames.insert(std::make_pair(0x40010009, "DBG_COMMAND_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0x80000001, "EXCEPTION_GUARD_PAGE"));
|
||||
exceptionNames.insert(std::make_pair(0x80000002, "EXCEPTION_DATATYPE_MISALIGNMENT"));
|
||||
exceptionNames.insert(std::make_pair(0x80000003, "EXCEPTION_BREAKPOINT"));
|
||||
exceptionNames.insert(std::make_pair(0x80000004, "EXCEPTION_SINGLE_STEP"));
|
||||
exceptionNames.insert(std::make_pair(0x80000026, "STATUS_LONGJUMP"));
|
||||
exceptionNames.insert(std::make_pair(0x80000029, "STATUS_UNWIND_CONSOLIDATE"));
|
||||
exceptionNames.insert(std::make_pair(0x80010001, "DBG_EXCEPTION_NOT_HANDLED"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000005, "EXCEPTION_ACCESS_VIOLATION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000006, "EXCEPTION_IN_PAGE_ERROR"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000008, "EXCEPTION_INVALID_HANDLE"));
|
||||
exceptionNames.insert(std::make_pair(0xC000000D, "STATUS_INVALID_PARAMETER"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000017, "STATUS_NO_MEMORY"));
|
||||
exceptionNames.insert(std::make_pair(0xC000001D, "EXCEPTION_ILLEGAL_INSTRUCTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000025, "EXCEPTION_NONCONTINUABLE_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000026, "EXCEPTION_INVALID_DISPOSITION"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008C, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008D, "EXCEPTION_FLT_DENORMAL_OPERAND"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008E, "EXCEPTION_FLT_DIVIDE_BY_ZERO"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008F, "EXCEPTION_FLT_INEXACT_RESULT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000090, "EXCEPTION_FLT_INVALID_OPERATION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000091, "EXCEPTION_FLT_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000092, "EXCEPTION_FLT_STACK_CHECK"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000093, "EXCEPTION_FLT_UNDERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000094, "EXCEPTION_INT_DIVIDE_BY_ZERO"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000095, "EXCEPTION_INT_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000096, "EXCEPTION_PRIV_INSTRUCTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC00000FD, "EXCEPTION_STACK_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000135, "STATUS_DLL_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000138, "STATUS_ORDINAL_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC000013A, "STATUS_CONTROL_C_EXIT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000142, "STATUS_DLL_INIT_FAILED"));
|
||||
exceptionNames.insert(std::make_pair(0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000194, "EXCEPTION_POSSIBLE_DEADLOCK"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002C9, "STATUS_REG_NAT_CONSUMPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000409, "STATUS_STACK_BUFFER_OVERRUN"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000417, "STATUS_INVALID_CRUNTIME_PARAMETER"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000420, "STATUS_ASSERTION_FAILURE"));
|
||||
exceptionNames.insert(std::make_pair(0x04242420, "CLRDBG_NOTIFICATION_EXCEPTION_CODE"));
|
||||
exceptionNames.insert(std::make_pair(0xE0434352, "CLR_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xE06D7363, "CPP_EH_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0x406D1388, "MS_VC_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC00001A5, "STATUS_INVALID_EXCEPTION_HANDLER"));
|
||||
}
|
||||
|
||||
const char* exceptionnamefromcode(unsigned int ExceptionCode)
|
||||
{
|
||||
if(!exceptionNames.count(ExceptionCode))
|
||||
return 0;
|
||||
return exceptionNames[ExceptionCode];
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _EXCEPTION_H
|
||||
#define _EXCEPTION_H
|
||||
|
||||
void exceptioninit();
|
||||
const char* exceptionnamefromcode(unsigned int ExceptionCode);
|
||||
|
||||
#endif //_EXCEPTIONS_H
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
#include "function.h"
|
||||
#include "module.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
#include "threading.h"
|
||||
|
||||
typedef std::map<ModuleRange, FUNCTIONSINFO, ModuleRangeCompare> FunctionsInfo;
|
||||
|
||||
static FunctionsInfo functions;
|
||||
|
||||
bool functionadd(uint start, uint end, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or end < start or !memisvalidreadptr(fdProcessInfo->hProcess, start))
|
||||
return false;
|
||||
const uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end)) //the function boundaries are not in the same module
|
||||
return false;
|
||||
if(functionoverlaps(start, end))
|
||||
return false;
|
||||
FUNCTIONSINFO function;
|
||||
modnamefromaddr(start, function.mod, true);
|
||||
function.start = start - modbase;
|
||||
function.end = end - modbase;
|
||||
function.manual = manual;
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
functions.insert(std::make_pair(ModuleRange(modhashfromva(modbase), Range(function.start, function.end)), function));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool functionget(uint addr, uint* start, uint* end)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
uint modbase = modbasefromaddr(addr);
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
const FunctionsInfo::iterator found = functions.find(ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase)));
|
||||
if(found == functions.end()) //not found
|
||||
return false;
|
||||
if(start)
|
||||
*start = found->second.start + modbase;
|
||||
if(end)
|
||||
*end = found->second.end + modbase;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool functionoverlaps(uint start, uint end)
|
||||
{
|
||||
if(!DbgIsDebugging() or end < start)
|
||||
return false;
|
||||
const uint modbase = modbasefromaddr(start);
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
return (functions.count(ModuleRange(modhashfromva(modbase), Range(start - modbase, end - modbase))) > 0);
|
||||
}
|
||||
|
||||
bool functiondel(uint addr)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
const uint modbase = modbasefromaddr(addr);
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
return (functions.erase(ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase))) > 0);
|
||||
}
|
||||
|
||||
void functiondelrange(uint start, uint end)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return;
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
FunctionsInfo::iterator i = functions.begin();
|
||||
while(i != functions.end())
|
||||
{
|
||||
if(i->second.manual) //ignore manual
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if(bDelAll or !(i->second.start <= end and i->second.end >= start))
|
||||
functions.erase(i++);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void functioncachesave(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
const JSON jsonfunctions = json_array();
|
||||
const JSON jsonautofunctions = json_array();
|
||||
for(FunctionsInfo::iterator i = functions.begin(); i != functions.end(); ++i)
|
||||
{
|
||||
const FUNCTIONSINFO curFunction = i->second;
|
||||
JSON curjsonfunction = json_object();
|
||||
json_object_set_new(curjsonfunction, "module", json_string(curFunction.mod));
|
||||
json_object_set_new(curjsonfunction, "start", json_hex(curFunction.start));
|
||||
json_object_set_new(curjsonfunction, "end", json_hex(curFunction.end));
|
||||
if(curFunction.manual)
|
||||
json_array_append_new(jsonfunctions, curjsonfunction);
|
||||
else
|
||||
json_array_append_new(jsonautofunctions, curjsonfunction);
|
||||
}
|
||||
if(json_array_size(jsonfunctions))
|
||||
json_object_set(root, "functions", jsonfunctions);
|
||||
json_decref(jsonfunctions);
|
||||
if(json_array_size(jsonautofunctions))
|
||||
json_object_set(root, "autofunctions", jsonautofunctions);
|
||||
json_decref(jsonautofunctions);
|
||||
}
|
||||
|
||||
void functioncacheload(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
functions.clear();
|
||||
const JSON jsonfunctions = json_object_get(root, "functions");
|
||||
if(jsonfunctions)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonfunctions, i, value)
|
||||
{
|
||||
FUNCTIONSINFO curFunction;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curFunction.mod, mod);
|
||||
else
|
||||
*curFunction.mod = '\0';
|
||||
curFunction.start = (uint)json_hex_value(json_object_get(value, "start"));
|
||||
curFunction.end = (uint)json_hex_value(json_object_get(value, "end"));
|
||||
if(curFunction.end < curFunction.start)
|
||||
continue; //invalid function
|
||||
curFunction.manual = true;
|
||||
const uint key = modhashfromname(curFunction.mod);
|
||||
functions.insert(std::make_pair(ModuleRange(modhashfromname(curFunction.mod), Range(curFunction.start, curFunction.end)), curFunction));
|
||||
}
|
||||
}
|
||||
JSON jsonautofunctions = json_object_get(root, "autofunctions");
|
||||
if(jsonautofunctions)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautofunctions, i, value)
|
||||
{
|
||||
FUNCTIONSINFO curFunction;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curFunction.mod, mod);
|
||||
else
|
||||
*curFunction.mod = '\0';
|
||||
curFunction.start = (uint)json_hex_value(json_object_get(value, "start"));
|
||||
curFunction.end = (uint)json_hex_value(json_object_get(value, "end"));
|
||||
if(curFunction.end < curFunction.start)
|
||||
continue; //invalid function
|
||||
curFunction.manual = true;
|
||||
const uint key = modhashfromname(curFunction.mod);
|
||||
functions.insert(std::make_pair(ModuleRange(modhashfromname(curFunction.mod), Range(curFunction.start, curFunction.end)), curFunction));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool functionenum(FUNCTIONSINFO* functionlist, size_t* cbsize)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
if(!functionlist && !cbsize)
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
if(!functionlist && cbsize)
|
||||
{
|
||||
*cbsize = functions.size() * sizeof(FUNCTIONSINFO);
|
||||
return true;
|
||||
}
|
||||
int j = 0;
|
||||
for(FunctionsInfo::iterator i = functions.begin(); i != functions.end(); ++i, j++)
|
||||
{
|
||||
functionlist[j] = i->second;
|
||||
uint modbase = modbasefromname(functionlist[j].mod);
|
||||
functionlist[j].start += modbase;
|
||||
functionlist[j].end += modbase;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void functionclear()
|
||||
{
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
FunctionsInfo().swap(functions);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _FUNCTION_H
|
||||
#define _FUNCTION_H
|
||||
|
||||
#include "addrinfo.h"
|
||||
|
||||
struct FUNCTIONSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint start;
|
||||
uint end;
|
||||
bool manual;
|
||||
};
|
||||
|
||||
bool functionadd(uint start, uint end, bool manual);
|
||||
bool functionget(uint addr, uint* start, uint* end);
|
||||
bool functionoverlaps(uint start, uint end);
|
||||
bool functiondel(uint addr);
|
||||
void functiondelrange(uint start, uint end);
|
||||
void functioncachesave(JSON root);
|
||||
void functioncacheload(JSON root);
|
||||
bool functionenum(FUNCTIONSINFO* functionlist, size_t* cbsize);
|
||||
void functionclear();
|
||||
|
||||
#endif //_FUNCTION_H
|
||||
|
|
@ -18,6 +18,13 @@
|
|||
#include "disasm_fast.h"
|
||||
#include "reference.h"
|
||||
#include "disasm_helper.h"
|
||||
#include "comment.h"
|
||||
#include "label.h"
|
||||
#include "bookmark.h"
|
||||
#include "function.h"
|
||||
#include "loop.h"
|
||||
#include "patternfind.h"
|
||||
#include "module.h"
|
||||
|
||||
static bool bRefinit = false;
|
||||
|
||||
|
|
@ -241,7 +248,7 @@ CMDRESULT cbInstrVarList(int argc, char* argv[])
|
|||
if(variables[i].alias.length())
|
||||
continue;
|
||||
char name[deflen] = "";
|
||||
strcpy(name, variables[i].name.c_str());
|
||||
strcpy_s(name, variables[i].name.c_str());
|
||||
uint value = (uint)variables[i].value.u.value;
|
||||
if(variables[i].type != VAR_HIDDEN)
|
||||
{
|
||||
|
|
@ -430,7 +437,7 @@ CMDRESULT cbAssemble(int argc, char* argv[])
|
|||
bool fillnop = false;
|
||||
if(argc > 3)
|
||||
fillnop = true;
|
||||
char error[256] = "";
|
||||
char error[MAX_ERROR_SIZE] = "";
|
||||
int size = 0;
|
||||
if(!assembleat(addr, argv[2], &size, error, fillnop))
|
||||
{
|
||||
|
|
@ -1075,9 +1082,9 @@ CMDRESULT cbInstrFind(int argc, char* argv[])
|
|||
char pattern[deflen] = "";
|
||||
//remove # from the start and end of the pattern (ODBGScript support)
|
||||
if(argv[2][0] == '#')
|
||||
strcpy(pattern, argv[2] + 1);
|
||||
strcpy_s(pattern, argv[2] + 1);
|
||||
else
|
||||
strcpy(pattern, argv[2]);
|
||||
strcpy_s(pattern, argv[2]);
|
||||
int len = (int)strlen(pattern);
|
||||
if(pattern[len - 1] == '#')
|
||||
pattern[len - 1] = '\0';
|
||||
|
|
@ -1105,7 +1112,7 @@ CMDRESULT cbInstrFind(int argc, char* argv[])
|
|||
}
|
||||
else
|
||||
find_size = size - start;
|
||||
uint foundoffset = memfindpattern(data + start, find_size, pattern);
|
||||
uint foundoffset = patternfind(data + start, find_size, pattern);
|
||||
uint result = 0;
|
||||
if(foundoffset != -1)
|
||||
result = addr + foundoffset;
|
||||
|
|
@ -1127,9 +1134,9 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
|
|||
char pattern[deflen] = "";
|
||||
//remove # from the start and end of the pattern (ODBGScript support)
|
||||
if(argv[2][0] == '#')
|
||||
strcpy(pattern, argv[2] + 1);
|
||||
strcpy_s(pattern, argv[2] + 1);
|
||||
else
|
||||
strcpy(pattern, argv[2]);
|
||||
strcpy_s(pattern, argv[2]);
|
||||
int len = (int)strlen(pattern);
|
||||
if(pattern[len - 1] == '#')
|
||||
pattern[len - 1] = '\0';
|
||||
|
|
@ -1178,7 +1185,7 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
|
|||
while(refCount < 5000)
|
||||
{
|
||||
int patternsize = 0;
|
||||
uint foundoffset = memfindpattern(data + start + i, find_size - i, pattern, &patternsize);
|
||||
uint foundoffset = patternfind(data + start + i, find_size - i, pattern, &patternsize);
|
||||
if(foundoffset == -1)
|
||||
break;
|
||||
i += foundoffset + 1;
|
||||
|
|
@ -1510,7 +1517,7 @@ CMDRESULT cbInstrFindAsm(int argc, char* argv[])
|
|||
|
||||
unsigned char dest[16];
|
||||
int asmsize = 0;
|
||||
char error[256] = "";
|
||||
char error[MAX_ERROR_SIZE] = "";
|
||||
if(!assemble(addr + size / 2, dest, &asmsize, argv[1], error))
|
||||
{
|
||||
dprintf("failed to assemble \"%s\" (%s)!\n", argv[1], error);
|
||||
|
|
@ -1526,3 +1533,234 @@ CMDRESULT cbInstrFindAsm(int argc, char* argv[])
|
|||
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("[YARA ERROR] ");
|
||||
break;
|
||||
case YARA_ERROR_LEVEL_WARNING:
|
||||
dprintf("[YARA WARNING] ");
|
||||
break;
|
||||
}
|
||||
dprintf("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
|
||||
{
|
||||
uint base;
|
||||
int index;
|
||||
};
|
||||
|
||||
static int yaraScanCallback(int message, void* message_data, void* user_data)
|
||||
{
|
||||
YaraScanInfo* scanInfo = (YaraScanInfo*)user_data;
|
||||
switch(message)
|
||||
{
|
||||
case CALLBACK_MSG_RULE_MATCHING:
|
||||
{
|
||||
uint base = scanInfo->base;
|
||||
YR_RULE* yrRule = (YR_RULE*)message_data;
|
||||
dprintf("[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->length);
|
||||
else
|
||||
pattern = yara_print_string(match->data, match->length);
|
||||
uint addr = (uint)(base + match->base + match->offset);
|
||||
//dprintf("[YARA] String \"%s\" : %s on 0x%"fext"X\n", string->identifier, pattern.c_str(), addr);
|
||||
|
||||
//update references
|
||||
int index = scanInfo->index;
|
||||
GuiReferenceSetRowCount(index + 1);
|
||||
scanInfo->index++;
|
||||
char addr_text[deflen] = "";
|
||||
sprintf(addr_text, fhex, addr);
|
||||
GuiReferenceSetCellContent(index, 0, addr_text); //Address
|
||||
String ruleFullName = "";
|
||||
ruleFullName += yrRule->identifier;
|
||||
ruleFullName += ".";
|
||||
ruleFullName += string->identifier;
|
||||
GuiReferenceSetCellContent(index, 1, ruleFullName.c_str()); //Rule
|
||||
GuiReferenceSetCellContent(index, 2, pattern.c_str()); //Data
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CALLBACK_MSG_RULE_NOT_MATCHING:
|
||||
{
|
||||
YR_RULE* yrRule = (YR_RULE*)message_data;
|
||||
dprintf("[YARA] Rule \"%s\" did not match!\n", yrRule->identifier);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALLBACK_MSG_SCAN_FINISHED:
|
||||
{
|
||||
dputs("[YARA] Scan finished!");
|
||||
}
|
||||
break;
|
||||
|
||||
case CALLBACK_MSG_IMPORT_MODULE:
|
||||
{
|
||||
YR_MODULE_IMPORT* yrModuleImport = (YR_MODULE_IMPORT*)message_data;
|
||||
dprintf("[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(argc < 2) //yara rulesFile, addr_of_mempage, size_of_scan
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint addr = 0;
|
||||
if(argc < 3 || !valfromstring(argv[2], &addr))
|
||||
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
uint size = 0;
|
||||
if(argc >= 4)
|
||||
if(!valfromstring(argv[3], &size))
|
||||
size = 0;
|
||||
if(!size)
|
||||
addr = memfindbaseaddr(addr, &size);
|
||||
uint base=addr;
|
||||
dprintf("%p[%p]\n",base,size);
|
||||
Memory<uint8_t*> data(size);
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)base, data(), size, 0))
|
||||
{
|
||||
dprintf("failed to read memory page %p[%X]!\n", base, size);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
FILE* rulesFile = 0;
|
||||
if(_wfopen_s(&rulesFile, StringUtils::Utf8ToUtf16(argv[1]).c_str(), L"rb"))
|
||||
{
|
||||
dputs("failed to open yara rules file!");
|
||||
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_file(yrCompiler, rulesFile, NULL, argv[1]) == 0) //no errors found
|
||||
{
|
||||
fclose(rulesFile);
|
||||
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(uint) * 2, "Address");
|
||||
GuiReferenceAddColumn(48, "Rule");
|
||||
GuiReferenceAddColumn(0, "Data");
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
YaraScanInfo scanInfo;
|
||||
scanInfo.base = base;
|
||||
scanInfo.index = 0;
|
||||
uint ticks = GetTickCount();
|
||||
dputs("[YARA] Scan started...");
|
||||
int err = yr_rules_scan_mem(yrRules, data(), size, 0, yaraScanCallback, &scanInfo, 0);
|
||||
GuiReferenceReloadData();
|
||||
switch(err)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
dprintf("%u scan results in %ums...\n", scanInfo.index, GetTickCount() - ticks);
|
||||
bSuccess = true;
|
||||
break;
|
||||
case ERROR_TOO_MANY_MATCHES:
|
||||
dputs("too many matches!");
|
||||
break;
|
||||
default:
|
||||
dputs("error while scanning memory!");
|
||||
break;
|
||||
}
|
||||
yr_rules_destroy(yrRules);
|
||||
}
|
||||
else
|
||||
dputs("error while getting the rules!");
|
||||
}
|
||||
else
|
||||
dputs("errors in the rules file!");
|
||||
yr_compiler_destroy(yrCompiler);
|
||||
}
|
||||
else
|
||||
dputs("yr_compiler_create failed!");
|
||||
return bSuccess ? STATUS_CONTINUE : STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrYaramod(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint base = modbasefromname(argv[2]);
|
||||
if(!base)
|
||||
{
|
||||
dprintf("invalid module \"%s\"!\n", argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint size = modsizefromaddr(base);
|
||||
char newcmd[deflen]="";
|
||||
sprintf_s(newcmd, "yara \"%s\",%p,%p", argv[1], base, size);
|
||||
return cmddirectexec(dbggetcommandlist(), newcmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,5 +62,7 @@ CMDRESULT cbInstrFunctionList(int argc, char* argv[]);
|
|||
CMDRESULT cbInstrLoopList(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrSleep(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrFindAsm(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrYara(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrYaramod(int argc, char* argv[]);
|
||||
|
||||
#endif // _INSTRUCTIONS_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,204 @@
|
|||
#include "label.h"
|
||||
#include "threading.h"
|
||||
#include "module.h"
|
||||
#include "memory.h"
|
||||
#include "debugger.h"
|
||||
|
||||
typedef std::map<uint, LABELSINFO> LabelsInfo;
|
||||
|
||||
static LabelsInfo labels;
|
||||
|
||||
bool labelset(uint addr, const char* text, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text) >= MAX_LABEL_SIZE - 1 or strstr(text, "&"))
|
||||
return false;
|
||||
if(!*text) //NOTE: delete when there is no text
|
||||
{
|
||||
labeldel(addr);
|
||||
return true;
|
||||
}
|
||||
LABELSINFO label;
|
||||
label.manual = manual;
|
||||
strcpy_s(label.text, text);
|
||||
modnamefromaddr(addr, label.mod, true);
|
||||
label.addr = addr - modbasefromaddr(addr);
|
||||
uint key = modhashfromva(addr);
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
if(!labels.insert(std::make_pair(modhashfromva(key), label)).second) //already present
|
||||
labels[key] = label;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool labelfromstring(const char* text, uint* addr)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
for(LabelsInfo::iterator i = labels.begin(); i != labels.end(); ++i)
|
||||
{
|
||||
if(!strcmp(i->second.text, text))
|
||||
{
|
||||
if(addr)
|
||||
*addr = i->second.addr + modbasefromname(i->second.mod);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool labelget(uint addr, char* text)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
const LabelsInfo::iterator found = labels.find(modhashfromva(addr));
|
||||
if(found == labels.end()) //not found
|
||||
return false;
|
||||
if(text)
|
||||
strcpy_s(text, MAX_LABEL_SIZE, found->second.text);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool labeldel(uint addr)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
return (labels.erase(modhashfromva(addr)) > 0);
|
||||
}
|
||||
|
||||
void labeldelrange(uint start, uint end)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return;
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
LabelsInfo::iterator i = labels.begin();
|
||||
while(i != labels.end())
|
||||
{
|
||||
if(i->second.manual) //ignore manual
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if(bDelAll || (i->second.addr >= start && i->second.addr < end))
|
||||
labels.erase(i++);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void labelcachesave(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
const JSON jsonlabels = json_array();
|
||||
const JSON jsonautolabels = json_array();
|
||||
for(LabelsInfo::iterator i = labels.begin(); i != labels.end(); ++i)
|
||||
{
|
||||
const LABELSINFO curLabel = i->second;
|
||||
JSON curjsonlabel = json_object();
|
||||
json_object_set_new(curjsonlabel, "module", json_string(curLabel.mod));
|
||||
json_object_set_new(curjsonlabel, "address", json_hex(curLabel.addr));
|
||||
json_object_set_new(curjsonlabel, "text", json_string(curLabel.text));
|
||||
if(curLabel.manual)
|
||||
json_array_append_new(jsonlabels, curjsonlabel);
|
||||
else
|
||||
json_array_append_new(jsonautolabels, curjsonlabel);
|
||||
}
|
||||
if(json_array_size(jsonlabels))
|
||||
json_object_set(root, "labels", jsonlabels);
|
||||
json_decref(jsonlabels);
|
||||
if(json_array_size(jsonautolabels))
|
||||
json_object_set(root, "autolabels", jsonautolabels);
|
||||
json_decref(jsonautolabels);
|
||||
}
|
||||
|
||||
void labelcacheload(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
labels.clear();
|
||||
const JSON jsonlabels = json_object_get(root, "labels");
|
||||
if(jsonlabels)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonlabels, i, value)
|
||||
{
|
||||
LABELSINFO curLabel;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curLabel.mod, mod);
|
||||
else
|
||||
*curLabel.mod = '\0';
|
||||
curLabel.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curLabel.manual = true;
|
||||
const char* text = json_string_value(json_object_get(value, "text"));
|
||||
if(text)
|
||||
strcpy_s(curLabel.text, text);
|
||||
else
|
||||
continue; //skip
|
||||
int len = (int)strlen(curLabel.text);
|
||||
for(int i = 0; i < len; i++)
|
||||
if(curLabel.text[i] == '&')
|
||||
curLabel.text[i] = ' ';
|
||||
const uint key = modhashfromname(curLabel.mod) + curLabel.addr;
|
||||
labels.insert(std::make_pair(key, curLabel));
|
||||
}
|
||||
}
|
||||
JSON jsonautolabels = json_object_get(root, "autolabels");
|
||||
if(jsonautolabels)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautolabels, i, value)
|
||||
{
|
||||
LABELSINFO curLabel;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curLabel.mod, mod);
|
||||
else
|
||||
*curLabel.mod = '\0';
|
||||
curLabel.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curLabel.manual = false;
|
||||
const char* text = json_string_value(json_object_get(value, "text"));
|
||||
if(text)
|
||||
strcpy_s(curLabel.text, text);
|
||||
else
|
||||
continue; //skip
|
||||
const uint key = modhashfromname(curLabel.mod) + curLabel.addr;
|
||||
labels.insert(std::make_pair(key, curLabel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool labelenum(LABELSINFO* labellist, size_t* cbsize)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
if(!labellist && !cbsize)
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
if(!labellist && cbsize)
|
||||
{
|
||||
*cbsize = labels.size() * sizeof(LABELSINFO);
|
||||
return true;
|
||||
}
|
||||
int j = 0;
|
||||
for(LabelsInfo::iterator i = labels.begin(); i != labels.end(); ++i, j++)
|
||||
{
|
||||
labellist[j] = i->second;
|
||||
labellist[j].addr += modbasefromname(labellist[j].mod);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void labelclear()
|
||||
{
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
LabelsInfo().swap(labels);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _LABEL_H
|
||||
#define _LABEL_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
struct LABELSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint addr;
|
||||
char text[MAX_LABEL_SIZE];
|
||||
bool manual;
|
||||
};
|
||||
|
||||
bool labelset(uint addr, const char* text, bool manual);
|
||||
bool labelfromstring(const char* text, uint* addr);
|
||||
bool labelget(uint addr, char* text);
|
||||
bool labeldel(uint addr);
|
||||
void labeldelrange(uint start, uint end);
|
||||
void labelcachesave(JSON root);
|
||||
void labelcacheload(JSON root);
|
||||
bool labelenum(LABELSINFO* labellist, size_t* cbsize);
|
||||
void labelclear();
|
||||
|
||||
#endif //_LABEL_H
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
#include "loop.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
#include "threading.h"
|
||||
#include "module.h"
|
||||
|
||||
typedef std::map<DepthModuleRange, LOOPSINFO, DepthModuleRangeCompare> LoopsInfo;
|
||||
|
||||
static LoopsInfo loops;
|
||||
|
||||
bool loopadd(uint start, uint end, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or end < start or !memisvalidreadptr(fdProcessInfo->hProcess, start))
|
||||
return false;
|
||||
const uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end)) //the function boundaries are not in the same mem page
|
||||
return false;
|
||||
int finaldepth;
|
||||
if(loopoverlaps(0, start, end, &finaldepth)) //loop cannot overlap another loop
|
||||
return false;
|
||||
LOOPSINFO loop;
|
||||
modnamefromaddr(start, loop.mod, true);
|
||||
loop.start = start - modbase;
|
||||
loop.end = end - modbase;
|
||||
loop.depth = finaldepth;
|
||||
if(finaldepth)
|
||||
loopget(finaldepth - 1, start, &loop.parent, 0);
|
||||
else
|
||||
loop.parent = 0;
|
||||
loop.manual = manual;
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
loops.insert(std::make_pair(DepthModuleRange(finaldepth, ModuleRange(modhashfromva(modbase), Range(loop.start, loop.end))), loop));
|
||||
return true;
|
||||
}
|
||||
|
||||
//get the start/end of a loop at a certain depth and addr
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
const uint modbase = modbasefromaddr(addr);
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
LoopsInfo::iterator found = loops.find(DepthModuleRange(depth, ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase))));
|
||||
if(found == loops.end()) //not found
|
||||
return false;
|
||||
if(start)
|
||||
*start = found->second.start + modbase;
|
||||
if(end)
|
||||
*end = found->second.end + modbase;
|
||||
return true;
|
||||
}
|
||||
|
||||
//check if a loop overlaps a range, inside is not overlapping
|
||||
bool loopoverlaps(int depth, uint start, uint end, int* finaldepth)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
const uint modbase = modbasefromaddr(start);
|
||||
uint curStart = start - modbase;
|
||||
uint curEnd = end - modbase;
|
||||
const uint key = modhashfromva(modbase);
|
||||
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
|
||||
//check if the new loop fits in the old loop
|
||||
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i)
|
||||
{
|
||||
if(i->first.second.first != key) //only look in the current module
|
||||
continue;
|
||||
LOOPSINFO* curLoop = &i->second;
|
||||
if(curLoop->start < curStart and curLoop->end > curEnd and curLoop->depth == depth)
|
||||
return loopoverlaps(depth + 1, curStart, curEnd, finaldepth);
|
||||
}
|
||||
|
||||
if(finaldepth)
|
||||
*finaldepth = depth;
|
||||
|
||||
//check for loop overlaps
|
||||
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i)
|
||||
{
|
||||
if(i->first.second.first != key) //only look in the current module
|
||||
continue;
|
||||
LOOPSINFO* curLoop = &i->second;
|
||||
if(curLoop->start <= curEnd and curLoop->end >= curStart and curLoop->depth == depth)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//this should delete a loop and all sub-loops that matches a certain addr
|
||||
bool loopdel(int depth, uint addr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void loopcachesave(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
const JSON jsonloops = json_array();
|
||||
const JSON jsonautoloops = json_array();
|
||||
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i)
|
||||
{
|
||||
const LOOPSINFO curLoop = i->second;
|
||||
JSON curjsonloop = json_object();
|
||||
json_object_set_new(curjsonloop, "module", json_string(curLoop.mod));
|
||||
json_object_set_new(curjsonloop, "start", json_hex(curLoop.start));
|
||||
json_object_set_new(curjsonloop, "end", json_hex(curLoop.end));
|
||||
json_object_set_new(curjsonloop, "depth", json_integer(curLoop.depth));
|
||||
json_object_set_new(curjsonloop, "parent", json_hex(curLoop.parent));
|
||||
if(curLoop.manual)
|
||||
json_array_append_new(jsonloops, curjsonloop);
|
||||
else
|
||||
json_array_append_new(jsonautoloops, curjsonloop);
|
||||
}
|
||||
if(json_array_size(jsonloops))
|
||||
json_object_set(root, "loops", jsonloops);
|
||||
json_decref(jsonloops);
|
||||
if(json_array_size(jsonautoloops))
|
||||
json_object_set(root, "autoloops", jsonautoloops);
|
||||
json_decref(jsonautoloops);
|
||||
}
|
||||
|
||||
void loopcacheload(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
loops.clear();
|
||||
const JSON jsonloops = json_object_get(root, "loops");
|
||||
if(jsonloops)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonloops, i, value)
|
||||
{
|
||||
LOOPSINFO curLoop;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curLoop.mod, mod);
|
||||
else
|
||||
*curLoop.mod = '\0';
|
||||
curLoop.start = (uint)json_hex_value(json_object_get(value, "start"));
|
||||
curLoop.end = (uint)json_hex_value(json_object_get(value, "end"));
|
||||
curLoop.depth = (int)json_integer_value(json_object_get(value, "depth"));
|
||||
curLoop.parent = (uint)json_hex_value(json_object_get(value, "parent"));
|
||||
if(curLoop.end < curLoop.start)
|
||||
continue; //invalid loop
|
||||
curLoop.manual = true;
|
||||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(modhashfromname(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
}
|
||||
}
|
||||
JSON jsonautoloops = json_object_get(root, "autoloops");
|
||||
if(jsonautoloops)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautoloops, i, value)
|
||||
{
|
||||
LOOPSINFO curLoop;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curLoop.mod, mod);
|
||||
else
|
||||
*curLoop.mod = '\0';
|
||||
curLoop.start = (uint)json_hex_value(json_object_get(value, "start"));
|
||||
curLoop.end = (uint)json_hex_value(json_object_get(value, "end"));
|
||||
curLoop.depth = (int)json_integer_value(json_object_get(value, "depth"));
|
||||
curLoop.parent = (uint)json_hex_value(json_object_get(value, "parent"));
|
||||
if(curLoop.end < curLoop.start)
|
||||
continue; //invalid loop
|
||||
curLoop.manual = false;
|
||||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(modhashfromname(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool loopenum(LOOPSINFO* looplist, size_t* cbsize)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
if(!looplist && !cbsize)
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
if(!looplist && cbsize)
|
||||
{
|
||||
*cbsize = loops.size() * sizeof(LOOPSINFO);
|
||||
return true;
|
||||
}
|
||||
int j = 0;
|
||||
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i, j++)
|
||||
{
|
||||
looplist[j] = i->second;
|
||||
uint modbase = modbasefromname(looplist[j].mod);
|
||||
looplist[j].start += modbase;
|
||||
looplist[j].end += modbase;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void loopclear()
|
||||
{
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
LoopsInfo().swap(loops);
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _LOOP_H
|
||||
#define _LOOP_H
|
||||
|
||||
#include "addrinfo.h"
|
||||
|
||||
struct LOOPSINFO
|
||||
{
|
||||
char mod[MAX_MODULE_SIZE];
|
||||
uint start;
|
||||
uint end;
|
||||
uint parent;
|
||||
int depth;
|
||||
bool manual;
|
||||
};
|
||||
|
||||
bool loopadd(uint start, uint end, bool manual);
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end);
|
||||
bool loopoverlaps(int depth, uint start, uint end, int* finaldepth);
|
||||
bool loopdel(int depth, uint addr);
|
||||
void loopcachesave(JSON root);
|
||||
void loopcacheload(JSON root);
|
||||
bool loopenum(LOOPSINFO* looplist, size_t* cbsize);
|
||||
void loopclear();
|
||||
|
||||
#endif //_LOOP_H
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include "patches.h"
|
||||
#include "console.h"
|
||||
#include "threading.h"
|
||||
#include "module.h"
|
||||
|
||||
MemoryMap memoryPages;
|
||||
bool bListAllPages = false;
|
||||
|
|
@ -226,104 +227,4 @@ void* memalloc(HANDLE hProcess, uint addr, SIZE_T size, DWORD fdProtect)
|
|||
void memfree(HANDLE hProcess, uint addr)
|
||||
{
|
||||
VirtualFreeEx(hProcess, (void*)addr, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
static int formathexpattern(char* string)
|
||||
{
|
||||
int len = (int)strlen(string);
|
||||
_strupr(string);
|
||||
Memory<char*> new_string(len + 1, "formathexpattern:new_string");
|
||||
memset(new_string, 0, len + 1);
|
||||
for(int i = 0, j = 0; i < len; i++)
|
||||
if(string[i] == '?' or isxdigit(string[i]))
|
||||
j += sprintf(new_string + j, "%c", string[i]);
|
||||
strcpy(string, new_string);
|
||||
return (int)strlen(string);
|
||||
}
|
||||
|
||||
static bool patterntransform(const char* text, std::vector<PATTERNBYTE>* pattern)
|
||||
{
|
||||
if(!text or !pattern)
|
||||
return false;
|
||||
pattern->clear();
|
||||
int len = (int)strlen(text);
|
||||
if(!len)
|
||||
return false;
|
||||
Memory<char*> newtext(len + 2, "transformpattern:newtext");
|
||||
strcpy(newtext, text);
|
||||
len = formathexpattern(newtext);
|
||||
if(len % 2) //not a multiple of 2
|
||||
{
|
||||
newtext[len] = '?';
|
||||
newtext[len + 1] = '\0';
|
||||
len++;
|
||||
}
|
||||
PATTERNBYTE newByte;
|
||||
for(int i = 0, j = 0; i < len; i++)
|
||||
{
|
||||
if(newtext[i] == '?') //wildcard
|
||||
{
|
||||
newByte.n[j].all = true; //match anything
|
||||
newByte.n[j].n = 0;
|
||||
j++;
|
||||
}
|
||||
else //hex
|
||||
{
|
||||
char x[2] = "";
|
||||
*x = newtext[i];
|
||||
unsigned int val = 0;
|
||||
sscanf(x, "%x", &val);
|
||||
newByte.n[j].all = false;
|
||||
newByte.n[j].n = val & 0xF;
|
||||
j++;
|
||||
}
|
||||
|
||||
if(j == 2) //two nibbles = one byte
|
||||
{
|
||||
j = 0;
|
||||
pattern->push_back(newByte);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool patternmatchbyte(unsigned char byte, PATTERNBYTE* pbyte)
|
||||
{
|
||||
unsigned char n1 = (byte >> 4) & 0xF;
|
||||
unsigned char n2 = byte & 0xF;
|
||||
int matched = 0;
|
||||
if(pbyte->n[0].all)
|
||||
matched++;
|
||||
else if(pbyte->n[0].n == n1)
|
||||
matched++;
|
||||
if(pbyte->n[1].all)
|
||||
matched++;
|
||||
else if(pbyte->n[1].n == n2)
|
||||
matched++;
|
||||
return (matched == 2);
|
||||
}
|
||||
|
||||
uint memfindpattern(unsigned char* data, uint size, const char* pattern, int* patternsize)
|
||||
{
|
||||
std::vector<PATTERNBYTE> searchpattern;
|
||||
if(!patterntransform(pattern, &searchpattern))
|
||||
return -1;
|
||||
int searchpatternsize = (int)searchpattern.size();
|
||||
if(patternsize)
|
||||
*patternsize = searchpatternsize;
|
||||
for(uint i = 0, pos = 0; i < size; i++) //search for the pattern
|
||||
{
|
||||
if(patternmatchbyte(data[i], &searchpattern.at(pos))) //check if our pattern matches the current byte
|
||||
{
|
||||
pos++;
|
||||
if(pos == searchpatternsize) //everything matched
|
||||
return i - searchpatternsize + 1;
|
||||
}
|
||||
else if(pos > 0) //fix by Computer_Angel
|
||||
{
|
||||
i -= pos; // return to previous byte
|
||||
pos = 0; //reset current pattern position
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,17 +9,6 @@ typedef std::map<Range, MEMPAGE, RangeCompare> MemoryMap;
|
|||
extern MemoryMap memoryPages;
|
||||
extern bool bListAllPages;
|
||||
|
||||
struct PATTERNNIBBLE
|
||||
{
|
||||
unsigned char n;
|
||||
bool all;
|
||||
};
|
||||
|
||||
struct PATTERNBYTE
|
||||
{
|
||||
PATTERNNIBBLE n[2];
|
||||
};
|
||||
|
||||
void memupdatemap(HANDLE hProcess);
|
||||
uint memfindbaseaddr(uint addr, uint* size, bool refresh = false);
|
||||
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
|
||||
|
|
@ -28,6 +17,5 @@ bool mempatch(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T
|
|||
bool memisvalidreadptr(HANDLE hProcess, uint addr);
|
||||
void* memalloc(HANDLE hProcess, uint addr, SIZE_T size, DWORD fdProtect);
|
||||
void memfree(HANDLE hProcess, uint addr);
|
||||
uint memfindpattern(unsigned char* data, uint size, const char* pattern, int* patternsize = 0);
|
||||
|
||||
#endif // _MEMORY_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,199 @@
|
|||
#include "module.h"
|
||||
#include "debugger.h"
|
||||
#include "threading.h"
|
||||
#include "symbolinfo.h"
|
||||
#include "murmurhash.h"
|
||||
|
||||
static ModulesInfo modinfo;
|
||||
|
||||
///module functions
|
||||
bool modload(uint base, uint size, const char* fullpath)
|
||||
{
|
||||
if(!base or !size or !fullpath)
|
||||
return false;
|
||||
char name[deflen] = "";
|
||||
|
||||
int len = (int)strlen(fullpath);
|
||||
while(fullpath[len] != '\\' and len)
|
||||
len--;
|
||||
if(len)
|
||||
len++;
|
||||
strcpy_s(name, fullpath + len);
|
||||
_strlwr(name);
|
||||
len = (int)strlen(name);
|
||||
name[MAX_MODULE_SIZE - 1] = 0; //ignore later characters
|
||||
while(name[len] != '.' and len)
|
||||
len--;
|
||||
MODINFO info;
|
||||
memset(&info, 0, sizeof(MODINFO));
|
||||
info.sections.clear();
|
||||
info.hash = modhashfromname(name);
|
||||
if(len)
|
||||
{
|
||||
strcpy_s(info.extension, name + len);
|
||||
name[len] = 0; //remove extension
|
||||
}
|
||||
info.base = base;
|
||||
info.size = size;
|
||||
strcpy_s(info.name, name);
|
||||
|
||||
//process module sections
|
||||
HANDLE FileHandle;
|
||||
DWORD LoadedSize;
|
||||
HANDLE FileMap;
|
||||
ULONG_PTR FileMapVA;
|
||||
WString wszFullPath = StringUtils::Utf8ToUtf16(fullpath);
|
||||
if(StaticFileLoadW(wszFullPath.c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA))
|
||||
{
|
||||
info.entry = GetPE32DataFromMappedFile(FileMapVA, 0, UE_OEP) + info.base; //get entry point
|
||||
int SectionCount = (int)GetPE32DataFromMappedFile(FileMapVA, 0, UE_SECTIONNUMBER);
|
||||
if(SectionCount > 0)
|
||||
{
|
||||
for(int i = 0; i < SectionCount; i++)
|
||||
{
|
||||
MODSECTIONINFO curSection;
|
||||
curSection.addr = GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALOFFSET) + base;
|
||||
curSection.size = GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALSIZE);
|
||||
const char* SectionName = (const char*)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONNAME);
|
||||
//escape section name when needed
|
||||
int len = (int)strlen(SectionName);
|
||||
int escape_count = 0;
|
||||
for(int k = 0; k < len; k++)
|
||||
if(SectionName[k] == '\\' or SectionName[k] == '\"' or !isprint(SectionName[k]))
|
||||
escape_count++;
|
||||
strcpy_s(curSection.name, StringUtils::Escape(SectionName).c_str());
|
||||
info.sections.push_back(curSection);
|
||||
}
|
||||
}
|
||||
StaticFileUnloadW(wszFullPath.c_str(), false, FileHandle, LoadedSize, FileMap, FileMapVA);
|
||||
}
|
||||
|
||||
//add module to list
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
modinfo.insert(std::make_pair(Range(base, base + size - 1), info));
|
||||
symupdatemodulelist();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool modunload(uint base)
|
||||
{
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(base, base));
|
||||
if(found == modinfo.end()) //not found
|
||||
return false;
|
||||
modinfo.erase(found);
|
||||
symupdatemodulelist();
|
||||
return true;
|
||||
}
|
||||
|
||||
void modclear()
|
||||
{
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
ModulesInfo().swap(modinfo);
|
||||
symupdatemodulelist();
|
||||
}
|
||||
|
||||
bool modnamefromaddr(uint addr, char* modname, bool extension)
|
||||
{
|
||||
if(!modname)
|
||||
return false;
|
||||
*modname = '\0';
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return false;
|
||||
String mod = found->second.name;
|
||||
if(extension)
|
||||
mod += found->second.extension;
|
||||
strcpy_s(modname, MAX_MODULE_SIZE, mod.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
uint modbasefromaddr(uint addr)
|
||||
{
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return 0;
|
||||
return found->second.base;
|
||||
}
|
||||
|
||||
uint modhashfromva(uint va) //return a unique hash from a VA
|
||||
{
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(va, va));
|
||||
if(found == modinfo.end()) //not found
|
||||
return va;
|
||||
return found->second.hash + (va - found->second.base);
|
||||
}
|
||||
|
||||
uint modhashfromname(const char* mod) //return MODINFO.hash
|
||||
{
|
||||
if(!mod or !*mod)
|
||||
return 0;
|
||||
int len = (int)strlen(mod);
|
||||
return murmurhash(mod, len);
|
||||
}
|
||||
|
||||
uint modbasefromname(const char* modname)
|
||||
{
|
||||
if(!modname or strlen(modname) >= MAX_MODULE_SIZE)
|
||||
return 0;
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
for(ModulesInfo::iterator i = modinfo.begin(); i != modinfo.end(); ++i)
|
||||
{
|
||||
MODINFO* curMod = &i->second;
|
||||
char curmodname[MAX_MODULE_SIZE] = "";
|
||||
sprintf(curmodname, "%s%s", curMod->name, curMod->extension);
|
||||
if(!_stricmp(curmodname, modname)) //with extension
|
||||
return curMod->base;
|
||||
if(!_stricmp(curMod->name, modname)) //without extension
|
||||
return curMod->base;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint modsizefromaddr(uint addr)
|
||||
{
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return 0;
|
||||
return found->second.size;
|
||||
}
|
||||
|
||||
bool modsectionsfromaddr(uint addr, std::vector<MODSECTIONINFO>* sections)
|
||||
{
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return false;
|
||||
*sections = found->second.sections;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint modentryfromaddr(uint addr)
|
||||
{
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return 0;
|
||||
return found->second.entry;
|
||||
}
|
||||
|
||||
int modpathfromaddr(duint addr, char* path, int size)
|
||||
{
|
||||
Memory<wchar_t*> wszModPath(size * sizeof(wchar_t), "modpathfromaddr:wszModPath");
|
||||
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbasefromaddr(addr), wszModPath, size))
|
||||
{
|
||||
*path = '\0';
|
||||
return 0;
|
||||
}
|
||||
strcpy_s(path, size, StringUtils::Utf16ToUtf8(wszModPath()).c_str());
|
||||
return (int)strlen(path);
|
||||
}
|
||||
|
||||
int modpathfromname(const char* modname, char* path, int size)
|
||||
{
|
||||
return modpathfromaddr(modbasefromname(modname), path, size);
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef _MODULE_H
|
||||
#define _MODULE_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "addrinfo.h"
|
||||
|
||||
struct MODSECTIONINFO
|
||||
{
|
||||
uint addr; //va
|
||||
uint size; //virtual size
|
||||
char name[50];
|
||||
};
|
||||
|
||||
struct MODINFO
|
||||
{
|
||||
uint base; //module base
|
||||
uint size; //module size
|
||||
uint hash; //full module name hash
|
||||
uint entry; //entry point
|
||||
char name[MAX_MODULE_SIZE]; //module name (without extension)
|
||||
char extension[MAX_MODULE_SIZE]; //file extension
|
||||
std::vector<MODSECTIONINFO> sections;
|
||||
};
|
||||
typedef std::map<Range, MODINFO, RangeCompare> ModulesInfo;
|
||||
|
||||
bool modload(uint base, uint size, const char* fullpath);
|
||||
bool modunload(uint base);
|
||||
void modclear();
|
||||
bool modnamefromaddr(uint addr, char* modname, bool extension);
|
||||
uint modbasefromaddr(uint addr);
|
||||
uint modhashfromva(uint va);
|
||||
uint modhashfromname(const char* mod);
|
||||
uint modbasefromname(const char* modname);
|
||||
uint modsizefromaddr(uint addr);
|
||||
bool modsectionsfromaddr(uint addr, std::vector<MODSECTIONINFO>* sections);
|
||||
uint modentryfromaddr(uint addr);
|
||||
int modpathfromaddr(duint addr, char* path, int size);
|
||||
int modpathfromname(const char* modname, char* path, int size);
|
||||
|
||||
#endif //_MODULE_H
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
#include "threading.h"
|
||||
#include "module.h"
|
||||
|
||||
static PatchesInfo patches;
|
||||
|
||||
|
|
@ -129,7 +130,7 @@ bool patchenum(PATCHINFO* patcheslist, size_t* cbsize)
|
|||
CriticalSectionLocker locker(LockPatches);
|
||||
if(!patcheslist && cbsize)
|
||||
{
|
||||
*cbsize = patches.size() * sizeof(LOOPSINFO);
|
||||
*cbsize = patches.size() * sizeof(PATCHINFO);
|
||||
return true;
|
||||
}
|
||||
int j = 0;
|
||||
|
|
@ -147,11 +148,11 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha
|
|||
if(!count)
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "no patches to apply");
|
||||
strcpy_s(error, MAX_ERROR_SIZE, "no patches to apply");
|
||||
return -1;
|
||||
}
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
strcpy(modname, patchlist[0].mod);
|
||||
strcpy_s(modname, patchlist[0].mod);
|
||||
//check if all patches are in the same module
|
||||
for(int i = 0; i < count; i++)
|
||||
if(_stricmp(patchlist[i].mod, modname))
|
||||
|
|
@ -177,7 +178,7 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha
|
|||
if(!CopyFileW(szOriginalName, StringUtils::Utf8ToUtf16(szFileName).c_str(), false))
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "failed to make a copy of the original file (patch target is in use?)");
|
||||
strcpy_s(error, MAX_ERROR_SIZE, "failed to make a copy of the original file (patch target is in use?)");
|
||||
return -1;
|
||||
}
|
||||
HANDLE FileHandle;
|
||||
|
|
@ -199,11 +200,11 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha
|
|||
if(!StaticFileUnloadW(StringUtils::Utf8ToUtf16(szFileName).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA))
|
||||
{
|
||||
if(error)
|
||||
strcpy(error, "StaticFileUnload failed");
|
||||
strcpy_s(error, MAX_ERROR_SIZE, "StaticFileUnload failed");
|
||||
return -1;
|
||||
}
|
||||
return patched;
|
||||
}
|
||||
strcpy(error, "StaticFileLoad failed");
|
||||
strcpy_s(error, MAX_ERROR_SIZE, "StaticFileLoad failed");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,169 @@
|
|||
#include "patternfind.h"
|
||||
#include <cctype>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct PatternByte
|
||||
{
|
||||
struct PatternNibble
|
||||
{
|
||||
unsigned char data;
|
||||
bool wildcard;
|
||||
} nibble[2];
|
||||
};
|
||||
|
||||
static string formathexpattern(string patterntext)
|
||||
{
|
||||
string result;
|
||||
int len = patterntext.length();
|
||||
for(int i = 0; i < len; i++)
|
||||
if(patterntext[i] == '?' || isxdigit(patterntext[i]))
|
||||
result += toupper(patterntext[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int hexchtoint(char ch)
|
||||
{
|
||||
if(ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
else if(ch >= 'A' && ch <= 'F')
|
||||
return ch - 'A' + 10;
|
||||
else if(ch >= 'a' && ch <= 'f')
|
||||
return ch - 'a' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool patterntransform(string patterntext, vector<PatternByte> & pattern)
|
||||
{
|
||||
pattern.clear();
|
||||
patterntext = formathexpattern(patterntext);
|
||||
int len = patterntext.length();
|
||||
if(!len)
|
||||
return false;
|
||||
|
||||
if(len % 2) //not a multiple of 2
|
||||
{
|
||||
patterntext += '?';
|
||||
len++;
|
||||
}
|
||||
|
||||
PatternByte newByte;
|
||||
for(int i = 0, j = 0; i < len; i++)
|
||||
{
|
||||
if(patterntext[i] == '?') //wildcard
|
||||
{
|
||||
newByte.nibble[j].wildcard = true; //match anything
|
||||
}
|
||||
else //hex
|
||||
{
|
||||
newByte.nibble[j].wildcard = false;
|
||||
newByte.nibble[j].data = hexchtoint(patterntext[i]) & 0xF;
|
||||
}
|
||||
|
||||
j++;
|
||||
if(j == 2) //two nibbles = one byte
|
||||
{
|
||||
j = 0;
|
||||
pattern.push_back(newByte);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool patternmatchbyte(unsigned char byte, const PatternByte & pbyte)
|
||||
{
|
||||
int matched = 0;
|
||||
|
||||
unsigned char n1 = (byte >> 4) & 0xF;
|
||||
if(pbyte.nibble[0].wildcard)
|
||||
matched++;
|
||||
else if(pbyte.nibble[0].data == n1)
|
||||
matched++;
|
||||
|
||||
unsigned char n2 = byte & 0xF;
|
||||
if(pbyte.nibble[1].wildcard)
|
||||
matched++;
|
||||
else if(pbyte.nibble[1].data == n2)
|
||||
matched++;
|
||||
|
||||
return (matched == 2);
|
||||
}
|
||||
|
||||
size_t patternfind(unsigned char* data, size_t datasize, const char* pattern, int* patternsize)
|
||||
{
|
||||
vector<PatternByte> searchpattern;
|
||||
if(!patterntransform(pattern, searchpattern))
|
||||
return -1;
|
||||
size_t searchpatternsize = searchpattern.size();
|
||||
if(patternsize)
|
||||
*patternsize = (int)searchpatternsize;
|
||||
for(size_t i = 0, pos = 0; i < datasize; i++) //search for the pattern
|
||||
{
|
||||
if(patternmatchbyte(data[i], searchpattern.at(pos))) //check if our pattern matches the current byte
|
||||
{
|
||||
pos++;
|
||||
if(pos == searchpatternsize) //everything matched
|
||||
return i - searchpatternsize + 1;
|
||||
}
|
||||
else if(pos > 0) //fix by Computer_Angel
|
||||
{
|
||||
i -= pos;
|
||||
pos = 0; //reset current pattern position
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t patternfind(unsigned char* data, size_t datasize, unsigned char* pattern, size_t patternsize)
|
||||
{
|
||||
if(patternsize > datasize)
|
||||
patternsize = datasize;
|
||||
for(size_t i = 0, pos = 0; i < datasize; i++)
|
||||
{
|
||||
if(data[i] == pattern[pos])
|
||||
{
|
||||
pos++;
|
||||
if(pos == patternsize)
|
||||
return i - patternsize + 1;
|
||||
}
|
||||
else if(pos > 0)
|
||||
{
|
||||
i -= pos;
|
||||
pos = 0; //reset current pattern position
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void patternwritebyte(unsigned char* byte, const PatternByte & pbyte)
|
||||
{
|
||||
unsigned char n1 = (*byte >> 4) & 0xF;
|
||||
unsigned char n2 = *byte & 0xF;
|
||||
if(!pbyte.nibble[0].wildcard)
|
||||
n1 = pbyte.nibble[0].data;
|
||||
if(!pbyte.nibble[1].wildcard)
|
||||
n2 = pbyte.nibble[1].data;
|
||||
*byte = ((n1 << 4) & 0xF0) | (n2 & 0xF);
|
||||
}
|
||||
|
||||
void patternwrite(unsigned char* data, size_t datasize, const char* pattern)
|
||||
{
|
||||
vector<PatternByte> writepattern;
|
||||
if(!patterntransform(pattern, writepattern))
|
||||
return;
|
||||
size_t writepatternsize = writepattern.size();
|
||||
if(writepatternsize > datasize)
|
||||
writepatternsize = datasize;
|
||||
for(size_t i = 0; i < writepatternsize; i++)
|
||||
patternwritebyte(&data[i], writepattern.at(i));
|
||||
}
|
||||
|
||||
bool patternsnr(unsigned char* data, size_t datasize, const char* searchpattern, const char* replacepattern)
|
||||
{
|
||||
size_t found = patternfind(data, datasize, searchpattern);
|
||||
if(found == -1)
|
||||
return false;
|
||||
patternwrite(data + found, datasize - found, replacepattern);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef _PATTERNFIND_H
|
||||
#define _PATTERNFIND_H
|
||||
|
||||
//returns: offset to data when found, -1 when not found
|
||||
size_t patternfind(
|
||||
unsigned char* data, //data
|
||||
size_t datasize, //size of data
|
||||
const char* pattern, //pattern to search
|
||||
int* patternsize = 0 //outputs the number of bytes the pattern is
|
||||
);
|
||||
|
||||
//returns: offset to data when found, -1 when not found
|
||||
size_t patternfind(
|
||||
unsigned char* data, //data
|
||||
size_t datasize, //size of data
|
||||
unsigned char* pattern, //bytes to search
|
||||
size_t patternsize //size of bytes to search
|
||||
);
|
||||
|
||||
//returns: nothing
|
||||
void patternwrite(
|
||||
unsigned char* data, //data
|
||||
size_t datasize, //size of data
|
||||
const char* pattern //pattern to write
|
||||
);
|
||||
|
||||
//returns: true on success, false on failure
|
||||
bool patternsnr(
|
||||
unsigned char* data, //data
|
||||
size_t datasize, //size of data
|
||||
const char* searchpattern, //pattern to search
|
||||
const char* replacepattern //pattern to write
|
||||
);
|
||||
|
||||
#endif // _PATTERNFIND_H
|
||||
|
|
@ -190,7 +190,7 @@ void pluginload(const char* pluginDir)
|
|||
int hNewMenu = GuiMenuAdd(GUI_PLUGIN_MENU, pluginData.initStruct.pluginName);
|
||||
if(hNewMenu == -1)
|
||||
{
|
||||
dprintf("[PLUGIN] GuiMenuAdd failed for plugin: %s\n", pluginData.initStruct.pluginName);
|
||||
dprintf("[PLUGIN] GuiMenuAdd(GUI_PLUGIN_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName);
|
||||
pluginData.hMenu = -1;
|
||||
}
|
||||
else
|
||||
|
|
@ -200,7 +200,55 @@ void pluginload(const char* pluginDir)
|
|||
newMenu.hEntryPlugin = -1;
|
||||
newMenu.pluginHandle = pluginData.initStruct.pluginHandle;
|
||||
pluginMenuList.push_back(newMenu);
|
||||
pluginData.hMenu = hNewMenu;
|
||||
pluginData.hMenu = newMenu.hEntryMenu;
|
||||
}
|
||||
//add disasm plugin menu
|
||||
hNewMenu = GuiMenuAdd(GUI_DISASM_MENU, pluginData.initStruct.pluginName);
|
||||
if(hNewMenu == -1)
|
||||
{
|
||||
dprintf("[PLUGIN] GuiMenuAdd(GUI_DISASM_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName);
|
||||
pluginData.hMenu = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
PLUG_MENU newMenu;
|
||||
newMenu.hEntryMenu = hNewMenu;
|
||||
newMenu.hEntryPlugin = -1;
|
||||
newMenu.pluginHandle = pluginData.initStruct.pluginHandle;
|
||||
pluginMenuList.push_back(newMenu);
|
||||
pluginData.hMenuDisasm = newMenu.hEntryMenu;
|
||||
}
|
||||
//add dump plugin menu
|
||||
hNewMenu = GuiMenuAdd(GUI_DUMP_MENU, pluginData.initStruct.pluginName);
|
||||
if(hNewMenu == -1)
|
||||
{
|
||||
dprintf("[PLUGIN] GuiMenuAdd(GUI_DUMP_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName);
|
||||
pluginData.hMenu = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
PLUG_MENU newMenu;
|
||||
newMenu.hEntryMenu = hNewMenu;
|
||||
newMenu.hEntryPlugin = -1;
|
||||
newMenu.pluginHandle = pluginData.initStruct.pluginHandle;
|
||||
pluginMenuList.push_back(newMenu);
|
||||
pluginData.hMenuDump = newMenu.hEntryMenu;
|
||||
}
|
||||
//add stack plugin menu
|
||||
hNewMenu = GuiMenuAdd(GUI_STACK_MENU, pluginData.initStruct.pluginName);
|
||||
if(hNewMenu == -1)
|
||||
{
|
||||
dprintf("[PLUGIN] GuiMenuAdd(GUI_STACK_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName);
|
||||
pluginData.hMenu = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
PLUG_MENU newMenu;
|
||||
newMenu.hEntryMenu = hNewMenu;
|
||||
newMenu.hEntryPlugin = -1;
|
||||
newMenu.pluginHandle = pluginData.initStruct.pluginHandle;
|
||||
pluginMenuList.push_back(newMenu);
|
||||
pluginData.hMenuStack = newMenu.hEntryMenu;
|
||||
}
|
||||
pluginList.push_back(pluginData);
|
||||
//setup plugin
|
||||
|
|
@ -208,7 +256,10 @@ void pluginload(const char* pluginDir)
|
|||
{
|
||||
PLUG_SETUPSTRUCT setupStruct;
|
||||
setupStruct.hwndDlg = GuiGetWindowHandle();
|
||||
setupStruct.hMenu = hNewMenu;
|
||||
setupStruct.hMenu = pluginData.hMenu;
|
||||
setupStruct.hMenuDisasm = pluginData.hMenuDisasm;
|
||||
setupStruct.hMenuDump = pluginData.hMenuDump;
|
||||
setupStruct.hMenuStack = pluginData.hMenuStack;
|
||||
pluginData.plugsetup(&setupStruct);
|
||||
}
|
||||
curPluginHandle++;
|
||||
|
|
@ -322,7 +373,7 @@ bool plugincmdregister(int pluginHandle, const char* command, CBPLUGINCOMMAND cb
|
|||
return false;
|
||||
PLUG_COMMAND plugCmd;
|
||||
plugCmd.pluginHandle = pluginHandle;
|
||||
strcpy(plugCmd.command, command);
|
||||
strcpy_s(plugCmd.command, command);
|
||||
if(!dbgcmdnew(command, (CBCOMMAND)cbCommand, debugonly))
|
||||
return false;
|
||||
pluginCommandList.push_back(plugCmd);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ struct PLUG_DATA
|
|||
PLUGSTOP plugstop;
|
||||
PLUGSETUP plugsetup;
|
||||
int hMenu;
|
||||
int hMenuDisasm;
|
||||
int hMenuDump;
|
||||
int hMenuStack;
|
||||
PLUG_INITSTRUCT initStruct;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
#include "console.h"
|
||||
#include "module.h"
|
||||
|
||||
int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent, const char* name)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static bool scriptcreatelinemap(const char* filename)
|
|||
int add = 0;
|
||||
while(temp[add] == ' ')
|
||||
add++;
|
||||
strcpy(entry.raw, temp + add);
|
||||
strcpy_s(entry.raw, temp + add);
|
||||
*temp = 0;
|
||||
j = 0;
|
||||
i++;
|
||||
|
|
@ -121,7 +121,7 @@ static bool scriptcreatelinemap(const char* filename)
|
|||
int add = 0;
|
||||
while(temp[add] == ' ')
|
||||
add++;
|
||||
strcpy(entry.raw, temp + add);
|
||||
strcpy_s(entry.raw, temp + add);
|
||||
*temp = 0;
|
||||
j = 0;
|
||||
linemap.push_back(entry);
|
||||
|
|
@ -132,7 +132,7 @@ static bool scriptcreatelinemap(const char* filename)
|
|||
int add = 0;
|
||||
while(temp[add] == ' ')
|
||||
add++;
|
||||
strcpy(entry.raw, temp + add);
|
||||
strcpy_s(entry.raw, temp + add);
|
||||
*temp = 0;
|
||||
j = 0;
|
||||
linemap.push_back(entry);
|
||||
|
|
@ -143,7 +143,7 @@ static bool scriptcreatelinemap(const char* filename)
|
|||
if(*temp)
|
||||
{
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
strcpy(entry.raw, temp);
|
||||
strcpy_s(entry.raw, temp);
|
||||
linemap.push_back(entry);
|
||||
}
|
||||
unsigned int linemapsize = (unsigned int)linemap.size();
|
||||
|
|
@ -163,7 +163,7 @@ static bool scriptcreatelinemap(const char* filename)
|
|||
{
|
||||
if(*(comment - 1) == ' ') //space before comment
|
||||
{
|
||||
strcpy(line_comment, comment);
|
||||
strcpy_s(line_comment, comment);
|
||||
*(comment - 1) = '\0';
|
||||
}
|
||||
else //no space before comment
|
||||
|
|
@ -181,7 +181,7 @@ static bool scriptcreatelinemap(const char* filename)
|
|||
else if(!strncmp(cur.raw, "//", 2)) //comment
|
||||
{
|
||||
cur.type = linecomment;
|
||||
strcpy(cur.u.comment, cur.raw);
|
||||
strcpy_s(cur.u.comment, cur.raw);
|
||||
}
|
||||
else if(cur.raw[rawlen - 1] == ':') //label
|
||||
{
|
||||
|
|
@ -214,20 +214,20 @@ static bool scriptcreatelinemap(const char* filename)
|
|||
cur.type = linebranch;
|
||||
cur.u.branch.type = scriptgetbranchtype(cur.raw);
|
||||
char newraw[MAX_SCRIPT_LINE_SIZE] = "";
|
||||
strcpy(newraw, cur.raw);
|
||||
strcpy_s(newraw, cur.raw);
|
||||
argformat(newraw);
|
||||
int len = (int)strlen(newraw);
|
||||
for(int i = 0; i < len; i++)
|
||||
if(newraw[i] == ' ')
|
||||
{
|
||||
strcpy(cur.u.branch.branchlabel, newraw + i + 1);
|
||||
strcpy_s(cur.u.branch.branchlabel, newraw + i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cur.type = linecommand;
|
||||
strcpy(cur.u.command, cur.raw);
|
||||
strcpy_s(cur.u.command, cur.raw);
|
||||
}
|
||||
|
||||
//append the comment to the raw line again
|
||||
|
|
@ -257,8 +257,8 @@ static bool scriptcreatelinemap(const char* filename)
|
|||
{
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
entry.type = linecommand;
|
||||
strcpy(entry.raw, "ret");
|
||||
strcpy(entry.u.command, "ret");
|
||||
strcpy_s(entry.raw, "ret");
|
||||
strcpy_s(entry.u.command, "ret");
|
||||
linemap.push_back(entry);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "BeaEngine\BeaEngine.h"
|
||||
#include "addrinfo.h"
|
||||
#include "_exports.h"
|
||||
#include "module.h"
|
||||
|
||||
bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
||||
{
|
||||
|
|
@ -47,7 +48,7 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
ADDRINFO addrinfo;
|
||||
addrinfo.flags = flaglabel;
|
||||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy(label, addrinfo.label);
|
||||
strcpy_s(label, addrinfo.label);
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
modnamefromaddr(data, module, false);
|
||||
char returnToAddr[MAX_COMMENT_SIZE] = "";
|
||||
|
|
@ -63,7 +64,7 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
*label = 0;
|
||||
addrinfo.flags = flaglabel;
|
||||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy(label, addrinfo.label);
|
||||
strcpy_s(label, addrinfo.label);
|
||||
*module = 0;
|
||||
modnamefromaddr(data, module, false);
|
||||
char returnFromAddr[MAX_COMMENT_SIZE] = "";
|
||||
|
|
@ -76,7 +77,7 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
}
|
||||
else
|
||||
sprintf_s(comment->comment, "return to %s from ???", returnToAddr);
|
||||
strcpy(comment->color, "#ff0000");
|
||||
strcpy_s(comment->color, "#ff0000");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +98,7 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
ADDRINFO addrinfo;
|
||||
addrinfo.flags = flaglabel;
|
||||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy(label, addrinfo.label);
|
||||
strcpy_s(label, addrinfo.label);
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
modnamefromaddr(data, module, false);
|
||||
char addrInfo[MAX_COMMENT_SIZE] = "";
|
||||
|
|
@ -157,7 +158,7 @@ void stackgetcallstack(uint csp, CALLSTACK* callstack)
|
|||
ADDRINFO addrinfo;
|
||||
addrinfo.flags = flaglabel;
|
||||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy(label, addrinfo.label);
|
||||
strcpy_s(label, addrinfo.label);
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
modnamefromaddr(data, module, false);
|
||||
char returnToAddr[MAX_COMMENT_SIZE] = "";
|
||||
|
|
@ -180,7 +181,7 @@ void stackgetcallstack(uint csp, CALLSTACK* callstack)
|
|||
*label = 0;
|
||||
addrinfo.flags = flaglabel;
|
||||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy(label, addrinfo.label);
|
||||
strcpy_s(label, addrinfo.label);
|
||||
*module = 0;
|
||||
modnamefromaddr(data, module, false);
|
||||
char returnFromAddr[MAX_COMMENT_SIZE] = "";
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include "debugger.h"
|
||||
#include "addrinfo.h"
|
||||
#include "console.h"
|
||||
#include "module.h"
|
||||
#include "label.h"
|
||||
|
||||
struct SYMBOLCBDATA
|
||||
{
|
||||
|
|
@ -24,7 +26,7 @@ static BOOL CALLBACK EnumSymbols(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID
|
|||
memset(&curSymbol, 0, sizeof(SYMBOLINFO));
|
||||
curSymbol.addr = (duint)pSymInfo->Address;
|
||||
curSymbol.decoratedSymbol = (char*)BridgeAlloc(len + 1);
|
||||
strcpy(curSymbol.decoratedSymbol, pSymInfo->Name);
|
||||
strcpy_s(curSymbol.decoratedSymbol, len + 1, pSymInfo->Name);
|
||||
curSymbol.undecoratedSymbol = (char*)BridgeAlloc(MAX_SYM_NAME);
|
||||
if(strstr(pSymInfo->Name, "Ordinal"))
|
||||
{
|
||||
|
|
@ -32,7 +34,7 @@ static BOOL CALLBACK EnumSymbols(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID
|
|||
if(pSymInfo->Address == pSymInfo->ModBase)
|
||||
return TRUE;
|
||||
}
|
||||
if(!UnDecorateSymbolName(pSymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
if(!SafeUnDecorateSymbolName(pSymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
{
|
||||
BridgeFree(curSymbol.undecoratedSymbol);
|
||||
curSymbol.undecoratedSymbol = 0;
|
||||
|
|
@ -53,7 +55,7 @@ void symenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user)
|
|||
symbolCbData.cbSymbolEnum = cbSymbolEnum;
|
||||
symbolCbData.user = user;
|
||||
char mask[] = "*";
|
||||
SymEnumSymbols(fdProcessInfo->hProcess, base, mask, EnumSymbols, &symbolCbData);
|
||||
SafeSymEnumSymbols(fdProcessInfo->hProcess, base, mask, EnumSymbols, &symbolCbData);
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
|
|
@ -76,7 +78,7 @@ void symupdatemodulelist()
|
|||
{
|
||||
std::vector<SYMBOLMODULEINFO> modList;
|
||||
modList.clear();
|
||||
SymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList);
|
||||
SafeSymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList);
|
||||
int modcount = (int)modList.size();
|
||||
SYMBOLMODULEINFO* modListBridge = (SYMBOLMODULEINFO*)BridgeAlloc(sizeof(SYMBOLMODULEINFO) * modcount);
|
||||
for(int i = 0; i < modcount; i++)
|
||||
|
|
@ -90,19 +92,19 @@ void symdownloadallsymbols(const char* szSymbolStore)
|
|||
szSymbolStore = "http://msdl.microsoft.com/download/symbols";
|
||||
std::vector<SYMBOLMODULEINFO> modList;
|
||||
modList.clear();
|
||||
SymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList);
|
||||
SafeSymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList);
|
||||
int modcount = (int)modList.size();
|
||||
if(!modcount)
|
||||
return;
|
||||
char szOldSearchPath[MAX_PATH] = "";
|
||||
if(!SymGetSearchPath(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current path
|
||||
if(!SafeSymGetSearchPath(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current path
|
||||
{
|
||||
dputs("SymGetSearchPath failed!");
|
||||
return;
|
||||
}
|
||||
char szServerSearchPath[MAX_PATH * 2] = "";
|
||||
sprintf_s(szServerSearchPath, "SRV*%s*%s", szSymbolCachePath, szSymbolStore);
|
||||
if(!SymSetSearchPath(fdProcessInfo->hProcess, szServerSearchPath)) //update search path
|
||||
if(!SafeSymSetSearchPath(fdProcessInfo->hProcess, szServerSearchPath)) //update search path
|
||||
{
|
||||
dputs("SymSetSearchPath (1) failed!");
|
||||
return;
|
||||
|
|
@ -117,18 +119,18 @@ void symdownloadallsymbols(const char* szSymbolStore)
|
|||
dprintf("GetModuleFileNameExW("fhex") failed!\n", modbase);
|
||||
continue;
|
||||
}
|
||||
if(!SymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase))
|
||||
if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase))
|
||||
{
|
||||
dprintf("SymUnloadModule64("fhex") failed!\n", modbase);
|
||||
continue;
|
||||
}
|
||||
if(!SymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(szModulePath).c_str(), 0, (DWORD64)modbase, 0, 0, 0))
|
||||
if(!SafeSymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(szModulePath).c_str(), 0, (DWORD64)modbase, 0, 0, 0))
|
||||
{
|
||||
dprintf("SymLoadModuleEx("fhex") failed!\n", modbase);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(!SymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath)) //restore search path
|
||||
if(!SafeSymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath)) //restore search path
|
||||
{
|
||||
dputs("SymSetSearchPath (2) failed!");
|
||||
}
|
||||
|
|
@ -142,7 +144,7 @@ bool symfromname(const char* name, uint* addr)
|
|||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(!SymFromName(fdProcessInfo->hProcess, name, pSymbol))
|
||||
if(!SafeSymFromName(fdProcessInfo->hProcess, name, pSymbol))
|
||||
return false;
|
||||
*addr = (uint)pSymbol->Address;
|
||||
return true;
|
||||
|
|
@ -163,10 +165,10 @@ const char* symgetsymbolicname(uint addr)
|
|||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
|
||||
if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
|
||||
{
|
||||
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
|
||||
if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
if(!bUndecorateSymbolNames or !SafeUnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
strcpy_s(label, pSymbol->Name);
|
||||
retval = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
|||
curInfo.ThreadLocalBase = (uint)CreateThread->lpThreadLocalBase;
|
||||
*curInfo.threadName = '\0';
|
||||
if(!threadNum)
|
||||
strcpy(curInfo.threadName, "Main Thread");
|
||||
strcpy_s(curInfo.threadName, "Main Thread");
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
threadList.push_back(curInfo);
|
||||
threadNum++;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ enum CriticalSectionLock
|
|||
LockPatches,
|
||||
LockThreads,
|
||||
LockDprintf,
|
||||
LockSym,
|
||||
LockLast
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
#include "memory.h"
|
||||
#include "addrinfo.h"
|
||||
#include "symbolinfo.h"
|
||||
#include <psapi.h>
|
||||
#include "module.h"
|
||||
#include "label.h"
|
||||
|
||||
static bool dosignedcalc = false;
|
||||
|
||||
|
|
@ -1529,9 +1530,9 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
}
|
||||
}
|
||||
else
|
||||
strcpy(newstring, string);
|
||||
strcpy_s(newstring, len * 2, string);
|
||||
Memory<char*> string_(len + 256, "valfromstring:string_");
|
||||
strcpy(string_, newstring);
|
||||
strcpy_s(string_, len + 256, newstring);
|
||||
int add = 0;
|
||||
bool negative = (*string_ == '-');
|
||||
while(mathisoperator(string_[add + negative]) > 2)
|
||||
|
|
@ -1583,7 +1584,7 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
}
|
||||
}
|
||||
else
|
||||
strcpy(newstring, string);
|
||||
strcpy_s(newstring, len * 2, string);
|
||||
int read_size = sizeof(uint);
|
||||
int add = 1;
|
||||
if(newstring[2] == ':' and isdigit((newstring[1]))) //@n: (number of bytes to read)
|
||||
|
|
@ -2154,7 +2155,7 @@ bool valtostring(const char* string, uint value, bool silent)
|
|||
}
|
||||
}
|
||||
else
|
||||
strcpy(newstring, string);
|
||||
strcpy_s(newstring, len * 2, string);
|
||||
int read_size = sizeof(uint);
|
||||
int add = 1;
|
||||
if(newstring[2] == ':' and isdigit((newstring[1])))
|
||||
|
|
@ -2189,8 +2190,9 @@ bool valtostring(const char* string, uint value, bool silent)
|
|||
return false;
|
||||
}
|
||||
bool ok = setregister(string, value);
|
||||
Memory<char*> regName(strlen(string) + 1, "valtostring:regname");
|
||||
strcpy(regName, string);
|
||||
int len = (int)strlen(string);
|
||||
Memory<char*> regName(len + 1, "valtostring:regname");
|
||||
strcpy_s(regName, len + 1, string);
|
||||
_strlwr(regName);
|
||||
if(strstr(regName, "ip"))
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), false); //update disassembly + register view
|
||||
|
|
|
|||
|
|
@ -198,6 +198,8 @@ static void registercommands()
|
|||
dbgcmdnew("getstr\1strget", cbInstrGetstr, false); //get a string variable
|
||||
dbgcmdnew("copystr\1strcpy", cbInstrCopystr, true); //write a string variable to memory
|
||||
dbgcmdnew("looplist", cbInstrLoopList, true); //list loops
|
||||
dbgcmdnew("yara", cbInstrYara, true); //yara test command
|
||||
dbgcmdnew("yaramod", cbInstrYaramod, true);
|
||||
}
|
||||
|
||||
static bool cbCommandProvider(char* cmd, int maxlen)
|
||||
|
|
@ -210,7 +212,7 @@ static bool cbCommandProvider(char* cmd, int maxlen)
|
|||
dprintf("command cut at ~%d characters\n", deflen);
|
||||
newcmd[deflen - 2] = 0;
|
||||
}
|
||||
strcpy(cmd, newcmd);
|
||||
strcpy_s(cmd, deflen, newcmd);
|
||||
efree(newcmd, "cbCommandProvider:newcmd"); //free allocated command
|
||||
return true;
|
||||
}
|
||||
|
|
@ -219,7 +221,7 @@ extern "C" DLL_EXPORT bool _dbg_dbgcmdexec(const char* cmd)
|
|||
{
|
||||
int len = (int)strlen(cmd);
|
||||
char* newcmd = (char*)emalloc((len + 1) * sizeof(char), "_dbg_dbgcmdexec:newcmd");
|
||||
strcpy(newcmd, cmd);
|
||||
strcpy_s(newcmd, len + 1, cmd);
|
||||
return msgsend(gMsgStack, 0, (uint)newcmd, 0);
|
||||
}
|
||||
|
||||
|
|
@ -243,9 +245,13 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
{
|
||||
if(!EngineCheckStructAlignment(UE_STRUCT_TITAN_ENGINE_CONTEXT, sizeof(TITAN_ENGINE_CONTEXT_t)))
|
||||
return "Invalid TITAN_ENGINE_CONTEXT_t alignment!";
|
||||
if(sizeof(TITAN_ENGINE_CONTEXT_t) != sizeof(REGISTERCONTEXT))
|
||||
return "Invalid REGISTERCONTEXT alignment!";
|
||||
dbginit();
|
||||
dbgfunctionsinit();
|
||||
json_set_alloc_funcs(emalloc_json, efree_json);
|
||||
if(yr_initialize() != ERROR_SUCCESS)
|
||||
return "Failed to initialize Yara!";
|
||||
wchar_t wszDir[deflen] = L"";
|
||||
if(!GetModuleFileNameW(hInst, wszDir, deflen))
|
||||
return "GetModuleFileNameW failed!";
|
||||
|
|
@ -255,14 +261,14 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
while(dir[len] != '\\')
|
||||
len--;
|
||||
dir[len] = 0;
|
||||
strcpy(alloctrace, dir);
|
||||
strcpy_s(alloctrace, dir);
|
||||
PathAppendA(alloctrace, "\\alloctrace.txt");
|
||||
DeleteFileW(StringUtils::Utf8ToUtf16(alloctrace).c_str());
|
||||
setalloctrace(alloctrace);
|
||||
strcpy(dbbasepath, dir); //debug directory
|
||||
strcpy_s(dbbasepath, dir); //debug directory
|
||||
PathAppendA(dbbasepath, "db");
|
||||
CreateDirectoryW(StringUtils::Utf8ToUtf16(dbbasepath).c_str(), 0); //create database directory
|
||||
strcpy(szSymbolCachePath, dir);
|
||||
strcpy_s(szSymbolCachePath, dir);
|
||||
PathAppendA(szSymbolCachePath, "symbols");
|
||||
SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(dir).c_str());;
|
||||
gMsgStack = msgallocstack();
|
||||
|
|
@ -272,7 +278,7 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
registercommands();
|
||||
hCommandLoopThread = CreateThread(0, 0, DbgCommandLoopThread, 0, 0, 0);
|
||||
char plugindir[deflen] = "";
|
||||
strcpy(plugindir, dir);
|
||||
strcpy_s(plugindir, dir);
|
||||
PathAppendA(plugindir, "plugins");
|
||||
CreateDirectoryW(StringUtils::Utf8ToUtf16(plugindir).c_str(), 0);
|
||||
pluginload(plugindir);
|
||||
|
|
@ -313,6 +319,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
|
|||
cmdfree(command_list);
|
||||
varfree();
|
||||
msgfreestack(gMsgStack);
|
||||
yr_finalize();
|
||||
if(memleaks())
|
||||
{
|
||||
char msg[256] = "";
|
||||
|
|
|
|||
|
|
@ -14,21 +14,31 @@
|
|||
<ClCompile Include="addrinfo.cpp" />
|
||||
<ClCompile Include="argument.cpp" />
|
||||
<ClCompile Include="assemble.cpp" />
|
||||
<ClCompile Include="bookmark.cpp" />
|
||||
<ClCompile Include="breakpoint.cpp" />
|
||||
<ClCompile Include="command.cpp" />
|
||||
<ClCompile Include="comment.cpp" />
|
||||
<ClCompile Include="console.cpp" />
|
||||
<ClCompile Include="dbghelp_safe.cpp" />
|
||||
<ClCompile Include="debugger.cpp" />
|
||||
<ClCompile Include="debugger_commands.cpp" />
|
||||
<ClCompile Include="disasm_fast.cpp" />
|
||||
<ClCompile Include="disasm_helper.cpp" />
|
||||
<ClCompile Include="error.cpp" />
|
||||
<ClCompile Include="exception.cpp" />
|
||||
<ClCompile Include="function.cpp" />
|
||||
<ClCompile Include="instruction.cpp" />
|
||||
<ClCompile Include="label.cpp" />
|
||||
<ClCompile Include="log.cpp" />
|
||||
<ClCompile Include="loop.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="math.cpp" />
|
||||
<ClCompile Include="memory.cpp" />
|
||||
<ClCompile Include="module.cpp" />
|
||||
<ClCompile Include="msgqueue.cpp" />
|
||||
<ClCompile Include="murmurhash.cpp" />
|
||||
<ClCompile Include="patches.cpp" />
|
||||
<ClCompile Include="patternfind.cpp" />
|
||||
<ClCompile Include="plugin_loader.cpp" />
|
||||
<ClCompile Include="reference.cpp" />
|
||||
<ClCompile Include="simplescript.cpp" />
|
||||
|
|
@ -53,29 +63,39 @@
|
|||
<ClInclude Include="BeaEngine\BeaEngine.h" />
|
||||
<ClInclude Include="BeaEngine\export.h" />
|
||||
<ClInclude Include="BeaEngine\macros.h" />
|
||||
<ClInclude Include="bookmark.h" />
|
||||
<ClInclude Include="breakpoint.h" />
|
||||
<ClInclude Include="command.h" />
|
||||
<ClInclude Include="comment.h" />
|
||||
<ClInclude Include="console.h" />
|
||||
<ClInclude Include="dbghelp\dbghelp.h" />
|
||||
<ClInclude Include="dbghelp_safe.h" />
|
||||
<ClInclude Include="debugger.h" />
|
||||
<ClInclude Include="debugger_commands.h" />
|
||||
<ClInclude Include="DeviceNameResolver\DeviceNameResolver.h" />
|
||||
<ClInclude Include="disasm_fast.h" />
|
||||
<ClInclude Include="disasm_helper.h" />
|
||||
<ClInclude Include="dynamicmem.h" />
|
||||
<ClInclude Include="error.h" />
|
||||
<ClInclude Include="exception.h" />
|
||||
<ClInclude Include="function.h" />
|
||||
<ClInclude Include="handle.h" />
|
||||
<ClInclude Include="instruction.h" />
|
||||
<ClInclude Include="jansson\jansson.h" />
|
||||
<ClInclude Include="jansson\jansson_config.h" />
|
||||
<ClInclude Include="label.h" />
|
||||
<ClInclude Include="log.h" />
|
||||
<ClInclude Include="loop.h" />
|
||||
<ClInclude Include="lz4\lz4.h" />
|
||||
<ClInclude Include="lz4\lz4file.h" />
|
||||
<ClInclude Include="lz4\lz4hc.h" />
|
||||
<ClInclude Include="math.h" />
|
||||
<ClInclude Include="memory.h" />
|
||||
<ClInclude Include="module.h" />
|
||||
<ClInclude Include="msgqueue.h" />
|
||||
<ClInclude Include="murmurhash.h" />
|
||||
<ClInclude Include="patches.h" />
|
||||
<ClInclude Include="patternfind.h" />
|
||||
<ClInclude Include="plugin_loader.h" />
|
||||
<ClInclude Include="reference.h" />
|
||||
<ClInclude Include="simplescript.h" />
|
||||
|
|
@ -90,6 +110,36 @@
|
|||
<ClInclude Include="variable.h" />
|
||||
<ClInclude Include="x64_dbg.h" />
|
||||
<ClInclude Include="XEDParse\XEDParse.h" />
|
||||
<ClInclude Include="yara\yara.h" />
|
||||
<ClInclude Include="yara\yara\ahocorasick.h" />
|
||||
<ClInclude Include="yara\yara\arena.h" />
|
||||
<ClInclude Include="yara\yara\atoms.h" />
|
||||
<ClInclude Include="yara\yara\compiler.h" />
|
||||
<ClInclude Include="yara\yara\elf.h" />
|
||||
<ClInclude Include="yara\yara\error.h" />
|
||||
<ClInclude Include="yara\yara\exec.h" />
|
||||
<ClInclude Include="yara\yara\exefiles.h" />
|
||||
<ClInclude Include="yara\yara\filemap.h" />
|
||||
<ClInclude Include="yara\yara\globals.h" />
|
||||
<ClInclude Include="yara\yara\hash.h" />
|
||||
<ClInclude Include="yara\yara\hex_lexer.h" />
|
||||
<ClInclude Include="yara\yara\lexer.h" />
|
||||
<ClInclude Include="yara\yara\libyara.h" />
|
||||
<ClInclude Include="yara\yara\limits.h" />
|
||||
<ClInclude Include="yara\yara\mem.h" />
|
||||
<ClInclude Include="yara\yara\modules.h" />
|
||||
<ClInclude Include="yara\yara\object.h" />
|
||||
<ClInclude Include="yara\yara\parser.h" />
|
||||
<ClInclude Include="yara\yara\pe.h" />
|
||||
<ClInclude Include="yara\yara\proc.h" />
|
||||
<ClInclude Include="yara\yara\re.h" />
|
||||
<ClInclude Include="yara\yara\re_lexer.h" />
|
||||
<ClInclude Include="yara\yara\rules.h" />
|
||||
<ClInclude Include="yara\yara\scan.h" />
|
||||
<ClInclude Include="yara\yara\sizedstr.h" />
|
||||
<ClInclude Include="yara\yara\strutils.h" />
|
||||
<ClInclude Include="yara\yara\types.h" />
|
||||
<ClInclude Include="yara\yara\utils.h" />
|
||||
<ClInclude Include="_exports.h" />
|
||||
<ClInclude Include="_dbgfunctions.h" />
|
||||
<ClInclude Include="_global.h" />
|
||||
|
|
@ -143,7 +193,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>lz4\lz4_x86.lib;jansson\jansson_x86.lib;DeviceNameResolver\DeviceNameResolver_x86.lib;XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32_bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;BeaEngine\BeaEngine.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>yara\yara_x86.lib;lz4\lz4_x86.lib;jansson\jansson_x86.lib;DeviceNameResolver\DeviceNameResolver_x86.lib;XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32_bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;BeaEngine\BeaEngine.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
|
@ -158,7 +208,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64_bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;BeaEngine\BeaEngine_64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64_bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;BeaEngine\BeaEngine_64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@
|
|||
<Filter Include="Header Files\Information">
|
||||
<UniqueIdentifier>{b006b04c-d7ea-49cb-b097-0cac1388f98e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Third Party\yara">
|
||||
<UniqueIdentifier>{efe5d058-e77c-49e9-a25b-75b90346dbf2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Third Party\yara\yara">
|
||||
<UniqueIdentifier>{f79c5166-e315-44ca-9e93-dabc9f00fa78}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
|
|
@ -123,15 +129,9 @@
|
|||
<ClCompile Include="disasm_helper.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="memory.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="plugin_loader.cpp">
|
||||
<Filter>Source Files\Core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="patches.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="reference.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -144,9 +144,6 @@
|
|||
<ClCompile Include="symbolinfo.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thread.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="instruction.cpp">
|
||||
<Filter>Source Files\Debugger Core</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -168,6 +165,45 @@
|
|||
<ClCompile Include="msgqueue.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="label.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="module.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="comment.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="bookmark.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="function.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="loop.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="error.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="exception.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="memory.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="patches.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thread.cpp">
|
||||
<Filter>Source Files\Information</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="patternfind.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dbghelp_safe.cpp">
|
||||
<Filter>Source Files\Utilities</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="x64_dbg.h">
|
||||
|
|
@ -281,21 +317,12 @@
|
|||
<ClInclude Include="disasm_helper.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memory.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="patches.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="reference.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="simplescript.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thread.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dynamicmem.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -317,5 +344,134 @@
|
|||
<ClInclude Include="msgqueue.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="module.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="comment.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="label.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="bookmark.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="function.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="loop.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="patches.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="error.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="exception.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memory.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thread.h">
|
||||
<Filter>Header Files\Information</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="patternfind.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dbghelp_safe.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara.h">
|
||||
<Filter>Header Files\Third Party\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\ahocorasick.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\arena.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\atoms.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\compiler.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\elf.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\error.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\exec.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\exefiles.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\filemap.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\globals.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\hash.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\hex_lexer.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\lexer.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\libyara.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\limits.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\mem.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\modules.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\object.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\parser.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\pe.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\proc.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\re.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\re_lexer.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\rules.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\scan.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\sizedstr.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\strutils.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\types.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\utils.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright (c) 2007-2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_YARA_H
|
||||
#define YR_YARA_H
|
||||
|
||||
#include "yara/utils.h"
|
||||
#include "yara/filemap.h"
|
||||
#include "yara/compiler.h"
|
||||
#include "yara/modules.h"
|
||||
#include "yara/object.h"
|
||||
#include "yara/libyara.h"
|
||||
#include "yara/error.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _AHOCORASICK_H
|
||||
#define _AHOCORASICK_H
|
||||
|
||||
#include "limits.h"
|
||||
#include "atoms.h"
|
||||
#include "types.h"
|
||||
|
||||
|
||||
int yr_ac_create_automaton(
|
||||
YR_ARENA* arena,
|
||||
YR_AC_AUTOMATON** automaton);
|
||||
|
||||
|
||||
int yr_ac_add_string(
|
||||
YR_ARENA* arena,
|
||||
YR_AC_AUTOMATON* automaton,
|
||||
YR_STRING* string,
|
||||
YR_ATOM_LIST_ITEM* atom);
|
||||
|
||||
|
||||
YR_AC_STATE* yr_ac_next_state(
|
||||
YR_AC_STATE* state,
|
||||
uint8_t input);
|
||||
|
||||
|
||||
int yr_ac_create_failure_links(
|
||||
YR_ARENA* arena,
|
||||
YR_AC_AUTOMATON* automaton);
|
||||
|
||||
|
||||
void yr_ac_print_automaton(
|
||||
YR_AC_AUTOMATON* automaton);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_ARENA_H
|
||||
#define YR_ARENA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#define ARENA_FLAGS_FIXED_SIZE 1
|
||||
#define ARENA_FLAGS_COALESCED 2
|
||||
#define ARENA_FILE_VERSION 6
|
||||
|
||||
#define EOL ((size_t) -1)
|
||||
|
||||
|
||||
typedef struct _YR_RELOC
|
||||
{
|
||||
int32_t offset;
|
||||
struct _YR_RELOC* next;
|
||||
|
||||
} YR_RELOC;
|
||||
|
||||
|
||||
typedef struct _YR_ARENA_PAGE
|
||||
{
|
||||
|
||||
uint8_t* new_address;
|
||||
uint8_t* address;
|
||||
|
||||
size_t size;
|
||||
size_t used;
|
||||
|
||||
YR_RELOC* reloc_list_head;
|
||||
YR_RELOC* reloc_list_tail;
|
||||
|
||||
struct _YR_ARENA_PAGE* next;
|
||||
struct _YR_ARENA_PAGE* prev;
|
||||
|
||||
} YR_ARENA_PAGE;
|
||||
|
||||
|
||||
typedef struct _YR_ARENA
|
||||
{
|
||||
int flags;
|
||||
|
||||
YR_ARENA_PAGE* page_list_head;
|
||||
YR_ARENA_PAGE* current_page;
|
||||
|
||||
} YR_ARENA;
|
||||
|
||||
|
||||
int yr_arena_create(
|
||||
size_t initial_size,
|
||||
int flags,
|
||||
YR_ARENA** arena);
|
||||
|
||||
|
||||
void yr_arena_destroy(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
void* yr_arena_base_address(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
void* yr_arena_next_address(
|
||||
YR_ARENA* arena,
|
||||
void* address,
|
||||
int offset);
|
||||
|
||||
|
||||
int yr_arena_coalesce(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
int yr_arena_reserve_memory(
|
||||
YR_ARENA* arena,
|
||||
size_t size);
|
||||
|
||||
|
||||
int yr_arena_allocate_memory(
|
||||
YR_ARENA* arena,
|
||||
size_t size,
|
||||
void** allocated_memory);
|
||||
|
||||
|
||||
int yr_arena_allocate_struct(
|
||||
YR_ARENA* arena,
|
||||
size_t size,
|
||||
void** allocated_memory,
|
||||
...);
|
||||
|
||||
|
||||
int yr_arena_make_relocatable(
|
||||
YR_ARENA* arena,
|
||||
void* base,
|
||||
...);
|
||||
|
||||
|
||||
int yr_arena_write_data(
|
||||
YR_ARENA* arena,
|
||||
void* data,
|
||||
size_t size,
|
||||
void** written_data);
|
||||
|
||||
|
||||
int yr_arena_write_string(
|
||||
YR_ARENA* arena,
|
||||
const char* string,
|
||||
char** written_string);
|
||||
|
||||
|
||||
int yr_arena_append(
|
||||
YR_ARENA* target_arena,
|
||||
YR_ARENA* source_arena);
|
||||
|
||||
|
||||
int yr_arena_save(
|
||||
YR_ARENA* arena,
|
||||
const char* filename);
|
||||
|
||||
|
||||
int yr_arena_load(
|
||||
const char* filename,
|
||||
YR_ARENA** arena);
|
||||
|
||||
|
||||
int yr_arena_duplicate(
|
||||
YR_ARENA* arena,
|
||||
YR_ARENA** duplicated);
|
||||
|
||||
|
||||
void yr_arena_print(
|
||||
YR_ARENA* arena);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_ATOMS_H
|
||||
#define YR_ATOMS_H
|
||||
|
||||
#include "limits.h"
|
||||
#include "re.h"
|
||||
|
||||
#define ATOM_TREE_LEAF 1
|
||||
#define ATOM_TREE_AND 2
|
||||
#define ATOM_TREE_OR 3
|
||||
|
||||
|
||||
typedef struct _ATOM_TREE_NODE
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t atom_length;
|
||||
uint8_t atom[MAX_ATOM_LENGTH];
|
||||
|
||||
uint8_t* forward_code;
|
||||
uint8_t* backward_code;
|
||||
|
||||
RE_NODE* recent_nodes[MAX_ATOM_LENGTH];
|
||||
|
||||
struct _ATOM_TREE_NODE* children_head;
|
||||
struct _ATOM_TREE_NODE* children_tail;
|
||||
struct _ATOM_TREE_NODE* next_sibling;
|
||||
|
||||
} ATOM_TREE_NODE;
|
||||
|
||||
|
||||
typedef struct _ATOM_TREE
|
||||
{
|
||||
ATOM_TREE_NODE* current_leaf;
|
||||
ATOM_TREE_NODE* root_node;
|
||||
|
||||
} ATOM_TREE;
|
||||
|
||||
|
||||
typedef struct _YR_ATOM_LIST_ITEM
|
||||
{
|
||||
uint8_t atom_length;
|
||||
uint8_t atom[MAX_ATOM_LENGTH];
|
||||
|
||||
uint16_t backtrack;
|
||||
|
||||
uint8_t* forward_code;
|
||||
uint8_t* backward_code;
|
||||
|
||||
struct _YR_ATOM_LIST_ITEM* next;
|
||||
|
||||
} YR_ATOM_LIST_ITEM;
|
||||
|
||||
|
||||
int yr_atoms_extract_from_re(
|
||||
RE* re,
|
||||
int flags,
|
||||
YR_ATOM_LIST_ITEM** atoms);
|
||||
|
||||
|
||||
int yr_atoms_extract_from_string(
|
||||
uint8_t* string,
|
||||
int string_length,
|
||||
int flags,
|
||||
YR_ATOM_LIST_ITEM** atoms);
|
||||
|
||||
|
||||
int yr_atoms_min_quality(
|
||||
YR_ATOM_LIST_ITEM* atom_list);
|
||||
|
||||
|
||||
void yr_atoms_list_destroy(
|
||||
YR_ATOM_LIST_ITEM* list_head);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_COMPILER_H
|
||||
#define YR_COMPILER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "ahocorasick.h"
|
||||
#include "arena.h"
|
||||
#include "hash.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define YARA_ERROR_LEVEL_ERROR 0
|
||||
#define YARA_ERROR_LEVEL_WARNING 1
|
||||
|
||||
|
||||
typedef void (*YR_COMPILER_CALLBACK_FUNC)(
|
||||
int error_level,
|
||||
const char* file_name,
|
||||
int line_number,
|
||||
const char* message,
|
||||
void* user_data);
|
||||
|
||||
|
||||
typedef struct _YR_COMPILER
|
||||
{
|
||||
int errors;
|
||||
int error_line;
|
||||
int last_error;
|
||||
int last_error_line;
|
||||
int last_result;
|
||||
|
||||
jmp_buf error_recovery;
|
||||
|
||||
YR_ARENA* sz_arena;
|
||||
YR_ARENA* rules_arena;
|
||||
YR_ARENA* strings_arena;
|
||||
YR_ARENA* code_arena;
|
||||
YR_ARENA* re_code_arena;
|
||||
YR_ARENA* automaton_arena;
|
||||
YR_ARENA* compiled_rules_arena;
|
||||
YR_ARENA* externals_arena;
|
||||
YR_ARENA* namespaces_arena;
|
||||
YR_ARENA* metas_arena;
|
||||
|
||||
YR_AC_AUTOMATON* automaton;
|
||||
YR_HASH_TABLE* rules_table;
|
||||
YR_HASH_TABLE* objects_table;
|
||||
YR_NAMESPACE* current_namespace;
|
||||
YR_STRING* current_rule_strings;
|
||||
|
||||
int current_rule_flags;
|
||||
int namespaces_count;
|
||||
|
||||
int8_t* loop_address[MAX_LOOP_NESTING];
|
||||
char* loop_identifier[MAX_LOOP_NESTING];
|
||||
int loop_depth;
|
||||
int loop_for_of_mem_offset;
|
||||
|
||||
int allow_includes;
|
||||
|
||||
char* file_name_stack[MAX_INCLUDE_DEPTH];
|
||||
int file_name_stack_ptr;
|
||||
|
||||
FILE* file_stack[MAX_INCLUDE_DEPTH];
|
||||
int file_stack_ptr;
|
||||
|
||||
char last_error_extra_info[MAX_COMPILER_ERROR_EXTRA_INFO];
|
||||
|
||||
char lex_buf[LEX_BUF_SIZE];
|
||||
char* lex_buf_ptr;
|
||||
unsigned short lex_buf_len;
|
||||
|
||||
char include_base_dir[MAX_PATH];
|
||||
void* user_data;
|
||||
|
||||
YR_COMPILER_CALLBACK_FUNC callback;
|
||||
|
||||
} YR_COMPILER;
|
||||
|
||||
|
||||
#define yr_compiler_set_error_extra_info(compiler, info) \
|
||||
strlcpy( \
|
||||
compiler->last_error_extra_info, \
|
||||
info, \
|
||||
sizeof(compiler->last_error_extra_info)); \
|
||||
|
||||
|
||||
#define yr_compiler_set_error_extra_info_fmt(compiler, fmt, ...) \
|
||||
snprintf( \
|
||||
compiler->last_error_extra_info, \
|
||||
sizeof(compiler->last_error_extra_info), \
|
||||
fmt, __VA_ARGS__);
|
||||
|
||||
|
||||
int _yr_compiler_push_file(
|
||||
YR_COMPILER* compiler,
|
||||
FILE* fh);
|
||||
|
||||
|
||||
FILE* _yr_compiler_pop_file(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
int _yr_compiler_push_file_name(
|
||||
YR_COMPILER* compiler,
|
||||
const char* file_name);
|
||||
|
||||
|
||||
void _yr_compiler_pop_file_name(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
YR_API int yr_compiler_create(
|
||||
YR_COMPILER** compiler);
|
||||
|
||||
|
||||
YR_API void yr_compiler_destroy(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
YR_API void yr_compiler_set_callback(
|
||||
YR_COMPILER* compiler,
|
||||
YR_COMPILER_CALLBACK_FUNC callback,
|
||||
void* user_data);
|
||||
|
||||
|
||||
YR_API int yr_compiler_add_file(
|
||||
YR_COMPILER* compiler,
|
||||
FILE* rules_file,
|
||||
const char* namespace_,
|
||||
const char* file_name);
|
||||
|
||||
|
||||
YR_API int yr_compiler_add_string(
|
||||
YR_COMPILER* compiler,
|
||||
const char* rules_string,
|
||||
const char* namespace_);
|
||||
|
||||
|
||||
YR_API char* yr_compiler_get_error_message(
|
||||
YR_COMPILER* compiler,
|
||||
char* buffer,
|
||||
int buffer_size);
|
||||
|
||||
|
||||
YR_API char* yr_compiler_get_current_file_name(
|
||||
YR_COMPILER* context);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_integer_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
int64_t value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_boolean_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
int value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_float_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
double value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_string_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
const char* value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_get_rules(
|
||||
YR_COMPILER* compiler,
|
||||
YR_RULES** rules);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ELF_H
|
||||
#define _ELF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// 32-bit ELF base types
|
||||
|
||||
typedef uint32_t elf32_addr_t;
|
||||
typedef uint16_t elf32_half_t;
|
||||
typedef uint32_t elf32_off_t;
|
||||
typedef uint32_t elf32_word_t;
|
||||
|
||||
// 64-bit ELF base types
|
||||
|
||||
typedef uint64_t elf64_addr_t;
|
||||
typedef uint16_t elf64_half_t;
|
||||
typedef uint64_t elf64_off_t;
|
||||
typedef uint32_t elf64_word_t;
|
||||
typedef uint64_t elf64_xword_t;
|
||||
|
||||
#define ELF_MAGIC 0x464C457F
|
||||
|
||||
#define ELF_ET_NONE 0x0000 // no type
|
||||
#define ELF_ET_REL 0x0001 // relocatable
|
||||
#define ELF_ET_EXEC 0x0002 // executeable
|
||||
#define ELF_ET_DYN 0x0003 // Shared-Object-File
|
||||
#define ELF_ET_CORE 0x0004 // Corefile
|
||||
#define ELF_ET_LOPROC 0xFF00 // Processor-specific
|
||||
#define ELF_ET_HIPROC 0x00FF // Processor-specific
|
||||
|
||||
#define ELF_EM_NONE 0x0000 // no type
|
||||
#define ELF_EM_M32 0x0001 // AT&T WE 32100
|
||||
#define ELF_EM_SPARC 0x0002 // SPARC
|
||||
#define ELF_EM_386 0x0003 // Intel 80386
|
||||
#define ELF_EM_68K 0x0004 // Motorola 68000
|
||||
#define ELF_EM_88K 0x0005 // Motorola 88000
|
||||
#define ELF_EM_860 0x0007 // Intel 80860
|
||||
#define ELF_EM_MIPS 0x0008 // MIPS RS3000
|
||||
#define ELF_EM_ARM 0x0032 // ARM
|
||||
#define ELF_EM_X86_64 0x003E // AMD/Intel x86_64
|
||||
|
||||
#define ELF_CLASS_NONE 0x0000
|
||||
#define ELF_CLASS_32 0x0001 // 32bit file
|
||||
#define ELF_CLASS_64 0x0002 // 64bit file
|
||||
|
||||
#define ELF_DATA_NONE 0x0000
|
||||
#define ELF_DATA_2LSB 0x0001
|
||||
#define ELF_DATA_2MSB 0x002
|
||||
|
||||
|
||||
#define ELF_SHT_NULL 0 // Section header table entry unused
|
||||
#define ELF_SHT_PROGBITS 1 // Program data
|
||||
#define ELF_SHT_SYMTAB 2 // Symbol table
|
||||
#define ELF_SHT_STRTAB 3 // String table
|
||||
#define ELF_SHT_RELA 4 // Relocation entries with addends
|
||||
#define ELF_SHT_HASH 5 // Symbol hash table
|
||||
#define ELF_SHT_DYNAMIC 6 // Dynamic linking information
|
||||
#define ELF_SHT_NOTE 7 // Notes
|
||||
#define ELF_SHT_NOBITS 8 // Program space with no data (bss)
|
||||
#define ELF_SHT_REL 9 // Relocation entries, no addends
|
||||
#define ELF_SHT_SHLIB 10 // Reserved
|
||||
#define ELF_SHT_DYNSYM 11 // Dynamic linker symbol table
|
||||
#define ELF_SHT_NUM 12 // Number of defined types
|
||||
|
||||
#define ELF_SHF_WRITE 0x1 // Section is writable
|
||||
#define ELF_SHF_ALLOC 0x2 // Section is present during execution
|
||||
#define ELF_SHF_EXECINSTR 0x4 // Section contains executable instructions
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t magic;
|
||||
uint8_t _class;
|
||||
uint8_t data;
|
||||
uint8_t version;
|
||||
uint8_t pad[8];
|
||||
uint8_t nident;
|
||||
|
||||
} elf_ident_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf_ident_t ident;
|
||||
elf32_half_t type;
|
||||
elf32_half_t machine;
|
||||
elf32_word_t version;
|
||||
elf32_addr_t entry;
|
||||
elf32_off_t ph_offset;
|
||||
elf32_off_t sh_offset;
|
||||
elf32_word_t flags;
|
||||
elf32_half_t header_size;
|
||||
elf32_half_t ph_entry_size;
|
||||
elf32_half_t ph_entry_count;
|
||||
elf32_half_t sh_entry_size;
|
||||
elf32_half_t sh_entry_count;
|
||||
elf32_half_t sh_str_table_index;
|
||||
|
||||
} elf32_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf_ident_t ident;
|
||||
elf64_half_t type;
|
||||
elf64_half_t machine;
|
||||
elf64_word_t version;
|
||||
elf64_addr_t entry;
|
||||
elf64_off_t ph_offset;
|
||||
elf64_off_t sh_offset;
|
||||
elf64_word_t flags;
|
||||
elf64_half_t header_size;
|
||||
elf64_half_t ph_entry_size;
|
||||
elf64_half_t ph_entry_count;
|
||||
elf64_half_t sh_entry_size;
|
||||
elf64_half_t sh_entry_count;
|
||||
elf64_half_t sh_str_table_index;
|
||||
|
||||
} elf64_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t type;
|
||||
elf32_off_t offset;
|
||||
elf32_addr_t virt_addr;
|
||||
elf32_addr_t phys_addr;
|
||||
elf32_word_t file_size;
|
||||
elf32_word_t mem_size;
|
||||
elf32_word_t flags;
|
||||
elf32_word_t alignment;
|
||||
|
||||
} elf32_program_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf64_word_t type;
|
||||
elf64_word_t flags;
|
||||
elf64_off_t offset;
|
||||
elf64_addr_t virt_addr;
|
||||
elf64_addr_t phys_addr;
|
||||
elf64_xword_t file_size;
|
||||
elf64_xword_t mem_size;
|
||||
elf64_xword_t alignment;
|
||||
|
||||
} elf64_program_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t name;
|
||||
elf32_word_t type;
|
||||
elf32_word_t flags;
|
||||
elf32_addr_t addr;
|
||||
elf32_off_t offset;
|
||||
elf32_word_t size;
|
||||
elf32_word_t link;
|
||||
elf32_word_t info;
|
||||
elf32_word_t align;
|
||||
elf32_word_t entry_size;
|
||||
|
||||
} elf32_section_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf64_word_t name;
|
||||
elf64_word_t type;
|
||||
elf64_xword_t flags;
|
||||
elf64_addr_t addr;
|
||||
elf64_off_t offset;
|
||||
elf64_xword_t size;
|
||||
elf64_word_t link;
|
||||
elf64_word_t info;
|
||||
elf64_xword_t align;
|
||||
elf64_xword_t entry_size;
|
||||
|
||||
} elf64_section_header_t;
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright (c) 2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_ERROR_H
|
||||
#define YR_ERROR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef ERROR_SUCCESS
|
||||
#define ERROR_SUCCESS 0
|
||||
#endif
|
||||
|
||||
#define ERROR_INSUFICIENT_MEMORY 1
|
||||
#define ERROR_COULD_NOT_ATTACH_TO_PROCESS 2
|
||||
#define ERROR_COULD_NOT_OPEN_FILE 3
|
||||
#define ERROR_COULD_NOT_MAP_FILE 4
|
||||
#define ERROR_INVALID_FILE 6
|
||||
#define ERROR_CORRUPT_FILE 7
|
||||
#define ERROR_UNSUPPORTED_FILE_VERSION 8
|
||||
#define ERROR_INVALID_REGULAR_EXPRESSION 9
|
||||
#define ERROR_INVALID_HEX_STRING 10
|
||||
#define ERROR_SYNTAX_ERROR 11
|
||||
#define ERROR_LOOP_NESTING_LIMIT_EXCEEDED 12
|
||||
#define ERROR_DUPLICATED_LOOP_IDENTIFIER 13
|
||||
#define ERROR_DUPLICATED_IDENTIFIER 14
|
||||
#define ERROR_DUPLICATED_TAG_IDENTIFIER 15
|
||||
#define ERROR_DUPLICATED_META_IDENTIFIER 16
|
||||
#define ERROR_DUPLICATED_STRING_IDENTIFIER 17
|
||||
#define ERROR_UNREFERENCED_STRING 18
|
||||
#define ERROR_UNDEFINED_STRING 19
|
||||
#define ERROR_UNDEFINED_IDENTIFIER 20
|
||||
#define ERROR_MISPLACED_ANONYMOUS_STRING 21
|
||||
#define ERROR_INCLUDES_CIRCULAR_REFERENCE 22
|
||||
#define ERROR_INCLUDE_DEPTH_EXCEEDED 23
|
||||
#define ERROR_WRONG_TYPE 24
|
||||
#define ERROR_EXEC_STACK_OVERFLOW 25
|
||||
#define ERROR_SCAN_TIMEOUT 26
|
||||
#define ERROR_TOO_MANY_SCAN_THREADS 27
|
||||
#define ERROR_CALLBACK_ERROR 28
|
||||
#define ERROR_INVALID_ARGUMENT 29
|
||||
#define ERROR_TOO_MANY_MATCHES 30
|
||||
#define ERROR_INTERNAL_FATAL_ERROR 31
|
||||
#define ERROR_NESTED_FOR_OF_LOOP 32
|
||||
#define ERROR_INVALID_FIELD_NAME 33
|
||||
#define ERROR_UNKNOWN_MODULE 34
|
||||
#define ERROR_NOT_A_STRUCTURE 35
|
||||
#define ERROR_NOT_INDEXABLE 36
|
||||
#define ERROR_NOT_A_FUNCTION 37
|
||||
#define ERROR_INVALID_FORMAT 38
|
||||
#define ERROR_TOO_MANY_ARGUMENTS 39
|
||||
#define ERROR_WRONG_ARGUMENTS 40
|
||||
#define ERROR_WRONG_RETURN_TYPE 41
|
||||
#define ERROR_DUPLICATED_STRUCTURE_MEMBER 42
|
||||
|
||||
|
||||
#define FAIL_ON_ERROR(x) { \
|
||||
int result = (x); \
|
||||
if (result != ERROR_SUCCESS) \
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define FAIL_ON_ERROR_WITH_CLEANUP(x, cleanup) { \
|
||||
int result = (x); \
|
||||
if (result != ERROR_SUCCESS) { \
|
||||
cleanup; \
|
||||
return result; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FAIL_ON_COMPILER_ERROR(x) { \
|
||||
compiler->last_result = (x); \
|
||||
if (compiler->last_result != ERROR_SUCCESS) \
|
||||
return compiler->last_result; \
|
||||
}
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assertf(expr, msg) ((void)0)
|
||||
#else
|
||||
#define assertf(expr, msg, ...) \
|
||||
if(!(expr)) { \
|
||||
fprintf(stderr, "%s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
abort(); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
Copyright (c) 2013-2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_EXEC_H
|
||||
#define YR_EXEC_H
|
||||
|
||||
#include "hash.h"
|
||||
#include "scan.h"
|
||||
#include "types.h"
|
||||
#include "rules.h"
|
||||
|
||||
|
||||
#define UNDEFINED 0xFFFABADAFABADAFFLL
|
||||
#define IS_UNDEFINED(x) ((size_t)(x) == (size_t) UNDEFINED)
|
||||
|
||||
#define OP_ERROR 0
|
||||
#define OP_HALT 255
|
||||
|
||||
#define OP_AND 1
|
||||
#define OP_OR 2
|
||||
#define OP_NOT 3
|
||||
#define OP_BITWISE_NOT 4
|
||||
#define OP_BITWISE_AND 5
|
||||
#define OP_BITWISE_OR 6
|
||||
#define OP_BITWISE_XOR 7
|
||||
#define OP_SHL 8
|
||||
#define OP_SHR 9
|
||||
#define OP_MOD 10
|
||||
#define OP_INT_TO_DBL 11
|
||||
#define OP_STR_TO_BOOL 12
|
||||
#define OP_PUSH 13
|
||||
#define OP_POP 14
|
||||
#define OP_CALL 15
|
||||
#define OP_OBJ_LOAD 16
|
||||
#define OP_OBJ_VALUE 17
|
||||
#define OP_OBJ_FIELD 18
|
||||
#define OP_INDEX_ARRAY 19
|
||||
#define OP_COUNT 20
|
||||
#define OP_FOUND 21
|
||||
#define OP_FOUND_AT 22
|
||||
#define OP_FOUND_IN 23
|
||||
#define OP_OFFSET 24
|
||||
#define OP_OF 25
|
||||
#define OP_PUSH_RULE 26
|
||||
#define OP_MATCH_RULE 27
|
||||
#define OP_INCR_M 28
|
||||
#define OP_CLEAR_M 29
|
||||
#define OP_ADD_M 30
|
||||
#define OP_POP_M 31
|
||||
#define OP_PUSH_M 32
|
||||
#define OP_SWAPUNDEF 33
|
||||
#define OP_JNUNDEF 34
|
||||
#define OP_JLE 35
|
||||
#define OP_FILESIZE 36
|
||||
#define OP_ENTRYPOINT 37
|
||||
#define OP_CONTAINS 38
|
||||
#define OP_MATCHES 39
|
||||
#define OP_IMPORT 40
|
||||
#define OP_LOOKUP_DICT 41
|
||||
|
||||
#define _OP_EQ 0
|
||||
#define _OP_NEQ 1
|
||||
#define _OP_LT 2
|
||||
#define _OP_GT 3
|
||||
#define _OP_LE 4
|
||||
#define _OP_GE 5
|
||||
#define _OP_ADD 6
|
||||
#define _OP_SUB 7
|
||||
#define _OP_MUL 8
|
||||
#define _OP_DIV 9
|
||||
#define _OP_MINUS 10
|
||||
|
||||
#define OP_INT_BEGIN 100
|
||||
#define OP_INT_EQ (OP_INT_BEGIN + _OP_EQ)
|
||||
#define OP_INT_NEQ (OP_INT_BEGIN + _OP_NEQ)
|
||||
#define OP_INT_LT (OP_INT_BEGIN + _OP_LT)
|
||||
#define OP_INT_GT (OP_INT_BEGIN + _OP_GT)
|
||||
#define OP_INT_LE (OP_INT_BEGIN + _OP_LE)
|
||||
#define OP_INT_GE (OP_INT_BEGIN + _OP_GE)
|
||||
#define OP_INT_ADD (OP_INT_BEGIN + _OP_ADD)
|
||||
#define OP_INT_SUB (OP_INT_BEGIN + _OP_SUB)
|
||||
#define OP_INT_MUL (OP_INT_BEGIN + _OP_MUL)
|
||||
#define OP_INT_DIV (OP_INT_BEGIN + _OP_DIV)
|
||||
| ||||