1
0
Fork 0

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:
Mr. eXoDia 2015-04-02 19:58:39 +02:00
commit 439507f306
138 changed files with 10360 additions and 2507 deletions

View File

@ -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>&nbsp;&nbsp;&nbsp; <EM>//data provided by the debugger to
the plugin.</EM>
<BR>&nbsp;&nbsp;&nbsp; [IN] <STRONG>HWND</STRONG> hwndDlg; //GUI window
handle<BR>&nbsp;&nbsp;&nbsp; [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>&nbsp;&nbsp;&nbsp; <EM>//data provided by the debugger to
the plugin.</EM>
<BR>&nbsp;&nbsp;&nbsp; [IN] <STRONG>HWND</STRONG> hwndDlg; //GUI window
handle<BR>&nbsp;&nbsp;&nbsp; [IN]
<STRONG>int</STRONG> hMenu; //plugin menu
handle<BR>&nbsp;&nbsp;&nbsp; [IN] <STRONG>int</STRONG> hMenuDisasm;
//plugin disasm menu handle<BR>&nbsp;&nbsp;&nbsp; [IN] <STRONG>int</STRONG>
hMenuDump; //plugin dump menu handle<BR>&nbsp;&nbsp;&nbsp; [IN]
<STRONG>int</STRONG> hMenuStack; //plugin stack menu
handle<BR>
};</P></body>
</html>

View File

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

93
rpm.cpp Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

162
x64_dbg_dbg/bookmark.cpp Normal file
View File

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

22
x64_dbg_dbg/bookmark.h Normal file
View File

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

View File

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

View File

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

View File

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

182
x64_dbg_dbg/comment.cpp Normal file
View File

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

23
x64_dbg_dbg/comment.h Normal file
View File

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

View File

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

105
x64_dbg_dbg/dbghelp_safe.h Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

2202
x64_dbg_dbg/error.cpp Normal file

File diff suppressed because it is too large Load Diff

7
x64_dbg_dbg/error.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _ERROR_H
#define _ERROR_H
void errorinit();
const char* errornamefromcode(unsigned int ErrorCode);
#endif //_ERROR_H

77
x64_dbg_dbg/exception.cpp Normal file
View File

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

7
x64_dbg_dbg/exception.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _EXCEPTION_H
#define _EXCEPTION_H
void exceptioninit();
const char* exceptionnamefromcode(unsigned int ExceptionCode);
#endif //_EXCEPTIONS_H

192
x64_dbg_dbg/function.cpp Normal file
View File

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

24
x64_dbg_dbg/function.h Normal file
View File

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

View File

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

View File

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

204
x64_dbg_dbg/label.cpp Normal file
View File

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

24
x64_dbg_dbg/label.h Normal file
View File

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

203
x64_dbg_dbg/loop.cpp Normal file
View File

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

25
x64_dbg_dbg/loop.h Normal file
View File

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

View File

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

View File

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

199
x64_dbg_dbg/module.cpp Normal file
View File

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

40
x64_dbg_dbg/module.h Normal file
View File

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

View File

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

169
x64_dbg_dbg/patternfind.cpp Normal file
View File

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

35
x64_dbg_dbg/patternfind.h Normal file
View File

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

View File

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

View File

@ -24,6 +24,9 @@ struct PLUG_DATA
PLUGSTOP plugstop;
PLUGSETUP plugsetup;
int hMenu;
int hMenuDisasm;
int hMenuDump;
int hMenuStack;
PLUG_INITSTRUCT initStruct;
};

View File

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

View File

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

View File

@ -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] = "";

View File

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

View File

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

View File

@ -34,6 +34,7 @@ enum CriticalSectionLock
LockPatches,
LockThreads,
LockDprintf,
LockSym,
LockLast
};

View File

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

View File

@ -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] = "";

View File

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

View File

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

28
x64_dbg_dbg/yara/yara.h Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

202
x64_dbg_dbg/yara/yara/elf.h Normal file
View File

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

View File

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

View File

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