Merge branch 'master' of https://bitbucket.org/mrexodia/x64_dbg
Conflicts: x64_dbg_bridge/bridgemain.cpp x64_dbg_dbg/_dbgfunctions.cpp x64_dbg_dbg/_plugins.cpp x64_dbg_dbg/addrinfo.cpp x64_dbg_dbg/bookmark.cpp x64_dbg_dbg/breakpoint.cpp x64_dbg_dbg/comment.cpp x64_dbg_dbg/console.cpp x64_dbg_dbg/console.h x64_dbg_dbg/dbghelp_safe.cpp x64_dbg_dbg/debugger_commands.cpp x64_dbg_dbg/disasm_fast.cpp x64_dbg_dbg/function.cpp x64_dbg_dbg/instruction.cpp x64_dbg_dbg/label.cpp x64_dbg_dbg/memory.cpp x64_dbg_dbg/memory.h x64_dbg_dbg/module.cpp x64_dbg_dbg/msgqueue.cpp x64_dbg_dbg/patches.cpp x64_dbg_dbg/reference.cpp x64_dbg_dbg/symbolinfo.cpp x64_dbg_dbg/thread.cpp x64_dbg_dbg/x64_dbg.cpp x64_dbg_dbg/x64_dbg_dbg.vcxproj
This commit is contained in:
commit
fbbe47ccdb
|
@ -8,6 +8,8 @@ release/
|
|||
build/
|
||||
debug/
|
||||
*XE Results*/
|
||||
doxygen*/
|
||||
doc/
|
||||
|
||||
#global filetypes to ignore
|
||||
*.depend
|
||||
|
|
|
@ -31,6 +31,7 @@ copy bin\x32\jansson.dll %RELEASEDIR%\bin_base\x32\jansson.dll
|
|||
copy bin\x32\lz4.dll %RELEASEDIR%\bin_base\x32\lz4.dll
|
||||
copy bin\x32\TitanEngine.dll %RELEASEDIR%\bin_base\x32\TitanEngine.dll
|
||||
copy bin\x32\XEDParse.dll %RELEASEDIR%\bin_base\x32\XEDParse.dll
|
||||
copy bin\x32\yara.dll %RELEASEDIR%\bin_base\x32\yara.dll
|
||||
copy bin\x64\BeaEngine.dll %RELEASEDIR%\bin_base\x64\BeaEngine.dll
|
||||
copy bin\x64\dbghelp.dll %RELEASEDIR%\bin_base\x64\dbghelp.dll
|
||||
copy bin\x64\symsrv.dll %RELEASEDIR%\bin_base\x64\symsrv.dll
|
||||
|
@ -40,6 +41,7 @@ copy bin\x64\jansson.dll %RELEASEDIR%\bin_base\x64\jansson.dll
|
|||
copy bin\x64\lz4.dll %RELEASEDIR%\bin_base\x64\lz4.dll
|
||||
copy bin\x64\TitanEngine.dll %RELEASEDIR%\bin_base\x64\TitanEngine.dll
|
||||
copy bin\x64\XEDParse.dll %RELEASEDIR%\bin_base\x64\XEDParse.dll
|
||||
copy bin\x64\yara.dll %RELEASEDIR%\bin_base\x64\yara.dll
|
||||
|
||||
echo help
|
||||
|
||||
|
@ -57,6 +59,8 @@ mkdir %RELEASEDIR%\pluginsdk\jansson
|
|||
mkdir %RELEASEDIR%\pluginsdk\lz4
|
||||
mkdir %RELEASEDIR%\pluginsdk\TitanEngine
|
||||
mkdir %RELEASEDIR%\pluginsdk\XEDParse
|
||||
mkdir %RELEASEDIR%\pluginsdk\yara
|
||||
mkdir %RELEASEDIR%\pluginsdk\yara\yara
|
||||
|
||||
xcopy x64_dbg_dbg\BeaEngine %RELEASEDIR%\pluginsdk\BeaEngine /S /Y
|
||||
xcopy x64_dbg_dbg\dbghelp %RELEASEDIR%\pluginsdk\dbghelp /S /Y
|
||||
|
@ -66,6 +70,7 @@ xcopy x64_dbg_dbg\lz4 %RELEASEDIR%\pluginsdk\lz4 /S /Y
|
|||
xcopy x64_dbg_dbg\TitanEngine %RELEASEDIR%\pluginsdk\TitanEngine /S /Y
|
||||
del %RELEASEDIR%\pluginsdk\TitanEngine\TitanEngine.txt /F /Q
|
||||
xcopy x64_dbg_dbg\XEDParse %RELEASEDIR%\pluginsdk\XEDParse /S /Y
|
||||
xcopy x64_dbg_dbg\yara %RELEASEDIR%\pluginsdk\yara /S /Y
|
||||
copy x64_dbg_dbg\_plugin_types.h %RELEASEDIR%\pluginsdk\_plugin_types.h
|
||||
copy x64_dbg_dbg\_plugins.h %RELEASEDIR%\pluginsdk\_plugins.h
|
||||
copy x64_dbg_dbg\_dbgfunctions.h %RELEASEDIR%\pluginsdk\_dbgfunctions.h
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
|
||||
#define uint size_t
|
||||
#define PAGE_SIZE 0x1000
|
||||
|
||||
#ifdef _WIN64
|
||||
#define HIGHEST_USER_ADDR 0x7FFFFFEFFFF
|
||||
#else //x86
|
||||
#define HIGHEST_USER_ADDR 0x7FFEFFFF
|
||||
#endif // _WIN64
|
||||
|
||||
bool readblock(uint addr, unsigned char block[PAGE_SIZE])
|
||||
{
|
||||
printf("readblock(%X[%X])\n", addr, PAGE_SIZE);
|
||||
memset(block, 0xFF, PAGE_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool memread(uint addr, unsigned char* data, uint size)
|
||||
{
|
||||
//check if the address is inside user space
|
||||
if(addr > HIGHEST_USER_ADDR)
|
||||
return false;
|
||||
|
||||
puts("-start-");
|
||||
printf(" addr: %X\n size: %X\n", addr, size);
|
||||
|
||||
//calculate the start page
|
||||
uint start = addr & ~(PAGE_SIZE - 1);
|
||||
printf(" start: %X\n", start);
|
||||
|
||||
//calculate the end page
|
||||
uint end = addr + size;
|
||||
uint x = end & (PAGE_SIZE - 1);
|
||||
if(x)
|
||||
end += (PAGE_SIZE - x);
|
||||
printf(" end: %X\n", end);
|
||||
|
||||
//calculate the number of pages to read
|
||||
uint npages = (end - start) / PAGE_SIZE;
|
||||
printf("npages: %d\n\n", npages);
|
||||
|
||||
//go over all pages
|
||||
for(uint i = 0, j = start; i < npages; i++)
|
||||
{
|
||||
//read one page (j should always align with PAGE_SIZE)
|
||||
unsigned char block[PAGE_SIZE];
|
||||
if(!readblock(j, block))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//these are the offsets and sizes in the block to write to append to the output buffer
|
||||
uint roffset = 0;
|
||||
uint rsize = PAGE_SIZE;
|
||||
|
||||
if(i == npages - 1) //last page (first because there might only be one page)
|
||||
{
|
||||
rsize = size - (j - start); //remaining size
|
||||
}
|
||||
else if(i == 0) //first page
|
||||
{
|
||||
roffset = addr & (PAGE_SIZE - 1);
|
||||
rsize = PAGE_SIZE - roffset;
|
||||
}
|
||||
|
||||
printf("roffset: %X\n rsize: %X\n", roffset, rsize);
|
||||
puts("");
|
||||
|
||||
//copy the required block data in the output buffer
|
||||
memcpy(data, block + roffset, rsize);
|
||||
data += rsize;
|
||||
|
||||
j += rsize;
|
||||
}
|
||||
|
||||
puts("--end--\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned char out[0x10000] = {0};
|
||||
memread(0x12A45, out, 0x3456);
|
||||
memread(0x12000, out, 0x456);
|
||||
memread(0x12000, out, 0x3456);
|
||||
memread(0x12000, out, 0x4000);
|
||||
memread(0x12ff0, out, 0x16);
|
||||
memread(0x100, out, 0x3090);
|
||||
return 0;
|
||||
}
|
|
@ -33,10 +33,10 @@ Global
|
|||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Release|Win32.Build.0 = Release|Win32
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Release|x64.ActiveCfg = Release|x64
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Release|x64.Build.0 = Release|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|x64.Build.0 = Debug|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|Win32.Build.0 = Release|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|x64.ActiveCfg = Release|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|x64.Build.0 = Release|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Release|Win32.Build.0 = Release|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Release|x64.ActiveCfg = Release|x64
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#include "_global.h"
|
||||
|
||||
//GUI functions
|
||||
GUIGUIINIT _gui_guiinit;
|
||||
GUISENDMESSAGE _gui_sendmessage;
|
||||
GUISENDMESSAGEASYNC _gui_sendmessageasync;
|
||||
|
||||
//DBG functions
|
||||
DBGDBGINIT _dbg_dbginit;
|
||||
DBGMEMFINDBASEADDR _dbg_memfindbaseaddr;
|
||||
DBGMEMREAD _dbg_memread;
|
||||
|
|
|
@ -29,7 +29,7 @@ typedef bool (*DBGADDRINFOGET)(duint addr, SEGMENTREG segment, ADDRINFO* addrinf
|
|||
typedef bool (*DBGADDRINFOSET)(duint addr, ADDRINFO* addrinfo);
|
||||
typedef BPXTYPE (*DBGBPGETTYPEAT)(duint addr);
|
||||
typedef bool (*DBGGETREGDUMP)(REGDUMP* regdump);
|
||||
typedef bool (*DBGVALTOSTRING)(const char* string, duint* value);
|
||||
typedef bool (*DBGVALTOSTRING)(const char* string, duint value);
|
||||
typedef bool (*DBGMEMISVALIDREADPTR)(duint addr);
|
||||
typedef int (*DBGGETBPLIST)(BPXTYPE type, BPMAP* bplist);
|
||||
typedef bool (*DBGDBGCMDEXECDIRECT)(const char* cmd);
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
/**
|
||||
* \file bridgemain.cpp
|
||||
*
|
||||
* \brief Defines functions to initialize and start the Bridge and
|
||||
* to interface with the GUI and the DBG.
|
||||
*/
|
||||
#include "_global.h"
|
||||
#include "bridgemain.h"
|
||||
#include "simpleini.h"
|
||||
#include <stdio.h>
|
||||
#include "simpleini.h"
|
||||
|
||||
static HINSTANCE hInst;
|
||||
|
||||
static wchar_t szIniFile[MAX_PATH] = L"";
|
||||
static CRITICAL_SECTION csIni;
|
||||
|
||||
|
@ -29,7 +36,6 @@ static CRITICAL_SECTION csIni;
|
|||
return szError; \
|
||||
}
|
||||
|
||||
//Bridge
|
||||
BRIDGE_IMPEXP const char* BridgeInit()
|
||||
{
|
||||
//Initialize critial section
|
||||
|
@ -53,8 +59,7 @@ BRIDGE_IMPEXP const char* BridgeInit()
|
|||
//GUI Load
|
||||
LOADLIBRARY(gui_lib);
|
||||
LOADEXPORT(_gui_guiinit);
|
||||
LOADEXPORT(_gui_sendmessage);
|
||||
LOADEXPORT(_gui_sendmessageasync);
|
||||
LOADEXPORT(_gui_sendmessage);
|
||||
|
||||
//DBG Load
|
||||
LOADLIBRARY(dbg_lib);
|
||||
|
@ -180,7 +185,6 @@ BRIDGE_IMPEXP int BridgeGetDbgVersion()
|
|||
return DBG_VERSION;
|
||||
}
|
||||
|
||||
//Debugger
|
||||
BRIDGE_IMPEXP bool DbgMemRead(duint va, unsigned char* dest, duint size)
|
||||
{
|
||||
if(IsBadWritePtr(dest, size))
|
||||
|
@ -204,6 +208,7 @@ BRIDGE_IMPEXP bool DbgMemWrite(duint va, const unsigned char* src, duint size)
|
|||
return _dbg_memwrite(va, src, size, 0);
|
||||
}
|
||||
|
||||
// FIXME, not exactly base if it still does a find?
|
||||
BRIDGE_IMPEXP duint DbgMemGetPageSize(duint base)
|
||||
{
|
||||
duint size = 0;
|
||||
|
@ -221,6 +226,7 @@ BRIDGE_IMPEXP bool DbgCmdExec(const char* cmd)
|
|||
return _dbg_dbgcmdexec(cmd);
|
||||
}
|
||||
|
||||
// FIXME
|
||||
BRIDGE_IMPEXP bool DbgMemMap(MEMMAP* memmap)
|
||||
{
|
||||
return _dbg_memmap(memmap);
|
||||
|
@ -242,6 +248,7 @@ BRIDGE_IMPEXP bool DbgIsJumpGoingToExecute(duint addr)
|
|||
return _dbg_isjumpgoingtoexecute(addr);
|
||||
}
|
||||
|
||||
// FIXME required size of arg _text_?
|
||||
BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text) //(module.)+label
|
||||
{
|
||||
if(!text || !addr)
|
||||
|
@ -277,6 +284,7 @@ BRIDGE_IMPEXP bool DbgSetLabelAt(duint addr, const char* text)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME required size of arg _text_?
|
||||
BRIDGE_IMPEXP bool DbgGetCommentAt(duint addr, char* text) //comment (not live)
|
||||
{
|
||||
if(!text || !addr)
|
||||
|
@ -303,6 +311,7 @@ BRIDGE_IMPEXP bool DbgSetCommentAt(duint addr, const char* text)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME required size of arg _text_?
|
||||
BRIDGE_IMPEXP bool DbgGetModuleAt(duint addr, char* text)
|
||||
{
|
||||
if(!text || !addr)
|
||||
|
@ -339,6 +348,7 @@ BRIDGE_IMPEXP bool DbgSetBookmarkAt(duint addr, bool isbookmark)
|
|||
return _dbg_addrinfoset(addr, &info);
|
||||
}
|
||||
|
||||
// FIXME return on success?
|
||||
BRIDGE_IMPEXP const char* DbgInit()
|
||||
{
|
||||
return _dbg_dbginit();
|
||||
|
@ -366,10 +376,10 @@ BRIDGE_IMPEXP bool DbgGetRegDump(REGDUMP* regdump)
|
|||
return _dbg_getregdump(regdump);
|
||||
}
|
||||
|
||||
// FIXME all
|
||||
BRIDGE_IMPEXP bool DbgValToString(const char* string, duint value)
|
||||
{
|
||||
duint valueCopy = value;
|
||||
return _dbg_valtostring(string, &valueCopy);
|
||||
return _dbg_valtostring(string, value);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP bool DbgMemIsValidReadPtr(duint addr)
|
||||
|
@ -377,11 +387,13 @@ BRIDGE_IMPEXP bool DbgMemIsValidReadPtr(duint addr)
|
|||
return _dbg_memisvalidreadptr(addr);
|
||||
}
|
||||
|
||||
// FIXME return
|
||||
BRIDGE_IMPEXP int DbgGetBpList(BPXTYPE type, BPMAP* list)
|
||||
{
|
||||
return _dbg_getbplist(type, list);
|
||||
}
|
||||
|
||||
// FIXME all
|
||||
BRIDGE_IMPEXP bool DbgCmdExecDirect(const char* cmd)
|
||||
{
|
||||
return _dbg_dbgcmddirectexec(cmd);
|
||||
|
@ -405,6 +417,7 @@ BRIDGE_IMPEXP FUNCTYPE DbgGetFunctionTypeAt(duint addr)
|
|||
return FUNC_MIDDLE;
|
||||
}
|
||||
|
||||
// FIXME depth
|
||||
BRIDGE_IMPEXP LOOPTYPE DbgGetLoopTypeAt(duint addr, int depth)
|
||||
{
|
||||
ADDRINFO info;
|
||||
|
@ -432,11 +445,13 @@ BRIDGE_IMPEXP void DbgScriptLoad(const char* filename)
|
|||
_dbg_sendmessage(DBG_SCRIPT_LOAD, (void*)filename, 0);
|
||||
}
|
||||
|
||||
// FIXME every?
|
||||
BRIDGE_IMPEXP void DbgScriptUnload()
|
||||
{
|
||||
_dbg_sendmessage(DBG_SCRIPT_UNLOAD, 0, 0);
|
||||
}
|
||||
|
||||
// FIXME "the script?"; destline
|
||||
BRIDGE_IMPEXP void DbgScriptRun(int destline)
|
||||
{
|
||||
_dbg_sendmessage(DBG_SCRIPT_RUN, (void*)(duint)destline, 0);
|
||||
|
@ -483,11 +498,13 @@ BRIDGE_IMPEXP void DbgScriptSetIp(int line)
|
|||
_dbg_sendmessage(DBG_SCRIPT_SETIP, (void*)(duint)line, 0);
|
||||
}
|
||||
|
||||
// FIXME non-null?
|
||||
BRIDGE_IMPEXP bool DbgScriptGetBranchInfo(int line, SCRIPTBRANCH* info)
|
||||
{
|
||||
return !!_dbg_sendmessage(DBG_SCRIPT_GETBRANCHINFO, (void*)(duint)line, info);
|
||||
}
|
||||
|
||||
// FIXME all
|
||||
BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user)
|
||||
{
|
||||
SYMBOLCBINFO cbInfo;
|
||||
|
@ -539,7 +556,7 @@ BRIDGE_IMPEXP void DbgMenuEntryClicked(int hEntry)
|
|||
_dbg_sendmessage(DBG_MENU_ENTRY_CLICKED, (void*)(duint)hEntry, 0);
|
||||
}
|
||||
|
||||
|
||||
// FIXME not sure
|
||||
BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end)
|
||||
{
|
||||
FUNCTION_LOOP_INFO info;
|
||||
|
@ -551,6 +568,7 @@ BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME brief, return
|
||||
BRIDGE_IMPEXP bool DbgFunctionOverlaps(duint start, duint end)
|
||||
{
|
||||
FUNCTION_LOOP_INFO info;
|
||||
|
@ -561,6 +579,7 @@ BRIDGE_IMPEXP bool DbgFunctionOverlaps(duint start, duint end)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME brief, return
|
||||
BRIDGE_IMPEXP bool DbgFunctionAdd(duint start, duint end)
|
||||
{
|
||||
FUNCTION_LOOP_INFO info;
|
||||
|
@ -572,6 +591,7 @@ BRIDGE_IMPEXP bool DbgFunctionAdd(duint start, duint end)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME brief, return
|
||||
BRIDGE_IMPEXP bool DbgFunctionDel(duint addr)
|
||||
{
|
||||
FUNCTION_LOOP_INFO info;
|
||||
|
@ -581,6 +601,7 @@ BRIDGE_IMPEXP bool DbgFunctionDel(duint addr)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME depth
|
||||
BRIDGE_IMPEXP bool DbgLoopGet(int depth, duint addr, duint* start, duint* end)
|
||||
{
|
||||
FUNCTION_LOOP_INFO info;
|
||||
|
@ -593,6 +614,7 @@ BRIDGE_IMPEXP bool DbgLoopGet(int depth, duint addr, duint* start, duint* end)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME brief, depth, return
|
||||
BRIDGE_IMPEXP bool DbgLoopOverlaps(int depth, duint start, duint end)
|
||||
{
|
||||
FUNCTION_LOOP_INFO info;
|
||||
|
@ -604,6 +626,7 @@ BRIDGE_IMPEXP bool DbgLoopOverlaps(int depth, duint start, duint end)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME brief, return
|
||||
BRIDGE_IMPEXP bool DbgLoopAdd(duint start, duint end)
|
||||
{
|
||||
FUNCTION_LOOP_INFO info;
|
||||
|
@ -615,6 +638,7 @@ BRIDGE_IMPEXP bool DbgLoopAdd(duint start, duint end)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME brief, brief
|
||||
BRIDGE_IMPEXP bool DbgLoopDel(int depth, duint addr)
|
||||
{
|
||||
FUNCTION_LOOP_INFO info;
|
||||
|
@ -625,6 +649,7 @@ BRIDGE_IMPEXP bool DbgLoopDel(int depth, duint addr)
|
|||
return true;
|
||||
}
|
||||
|
||||
// FIXME all
|
||||
BRIDGE_IMPEXP bool DbgIsRunLocked()
|
||||
{
|
||||
if(_dbg_sendmessage(DBG_IS_RUN_LOCKED, 0, 0))
|
||||
|
@ -646,6 +671,7 @@ BRIDGE_IMPEXP bool DbgSetAutoCommentAt(duint addr, const char* text)
|
|||
return false;
|
||||
}
|
||||
|
||||
// FIXME brief
|
||||
BRIDGE_IMPEXP void DbgClearAutoCommentRange(duint start, duint end)
|
||||
{
|
||||
_dbg_sendmessage(DBG_DELETE_AUTO_COMMENT_RANGE, (void*)start, (void*)end);
|
||||
|
@ -658,6 +684,7 @@ BRIDGE_IMPEXP bool DbgSetAutoLabelAt(duint addr, const char* text)
|
|||
return false;
|
||||
}
|
||||
|
||||
// FIXME brief
|
||||
BRIDGE_IMPEXP void DbgClearAutoLabelRange(duint start, duint end)
|
||||
{
|
||||
_dbg_sendmessage(DBG_DELETE_AUTO_LABEL_RANGE, (void*)start, (void*)end);
|
||||
|
@ -670,6 +697,7 @@ BRIDGE_IMPEXP bool DbgSetAutoBookmarkAt(duint addr)
|
|||
return false;
|
||||
}
|
||||
|
||||
// FIXME brief
|
||||
BRIDGE_IMPEXP void DbgClearAutoBookmarkRange(duint start, duint end)
|
||||
{
|
||||
_dbg_sendmessage(DBG_DELETE_AUTO_BOOKMARK_RANGE, (void*)start, (void*)end);
|
||||
|
@ -682,11 +710,13 @@ BRIDGE_IMPEXP bool DbgSetAutoFunctionAt(duint start, duint end)
|
|||
return false;
|
||||
}
|
||||
|
||||
// FIXME brief
|
||||
BRIDGE_IMPEXP void DbgClearAutoFunctionRange(duint start, duint end)
|
||||
{
|
||||
_dbg_sendmessage(DBG_DELETE_AUTO_FUNCTION_RANGE, (void*)start, (void*)end);
|
||||
}
|
||||
|
||||
// FIXME size of the buffer?
|
||||
BRIDGE_IMPEXP bool DbgGetStringAt(duint addr, char* text)
|
||||
{
|
||||
if(_dbg_sendmessage(DBG_GET_STRING_AT, (void*)addr, text))
|
||||
|
@ -694,11 +724,13 @@ BRIDGE_IMPEXP bool DbgGetStringAt(duint addr, char* text)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP const DBGFUNCTIONS* DbgFunctions()
|
||||
{
|
||||
return (const DBGFUNCTIONS*)_dbg_sendmessage(DBG_GET_FUNCTIONS, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result)
|
||||
{
|
||||
if(_dbg_sendmessage(DBG_WIN_EVENT, message, result))
|
||||
|
@ -706,6 +738,7 @@ BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message)
|
||||
{
|
||||
if(_dbg_sendmessage(DBG_WIN_EVENT_GLOBAL, message, 0))
|
||||
|
@ -713,27 +746,31 @@ BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message)
|
|||
return false;
|
||||
}
|
||||
|
||||
//GUI
|
||||
|
||||
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_DISASSEMBLE_AT, (void*)addr, (void*)cip);
|
||||
_gui_sendmessage(GUI_DISASSEMBLE_AT, (void*)addr, (void*)cip);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_SET_DEBUG_STATE, (void*)state, 0);
|
||||
_gui_sendmessage(GUI_SET_DEBUG_STATE, (void*)state, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg)
|
||||
{
|
||||
_gui_sendmessage(GUI_ADD_MSG_TO_LOG, (void*)msg, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiLogClear()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_CLEAR_LOG, 0, 0);
|
||||
_gui_sendmessage(GUI_CLEAR_LOG, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateAllViews()
|
||||
{
|
||||
GuiUpdateRegisterView();
|
||||
|
@ -745,124 +782,148 @@ BRIDGE_IMPEXP void GuiUpdateAllViews()
|
|||
GuiRepaintTableView();
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateRegisterView()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_REGISTER_VIEW, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_REGISTER_VIEW, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateDisassemblyView()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_DISASSEMBLY_VIEW, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_DISASSEMBLY_VIEW, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateBreakpointsView()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_BREAKPOINTS_VIEW, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_BREAKPOINTS_VIEW, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateWindowTitle(const char* filename)
|
||||
{
|
||||
_gui_sendmessage(GUI_UPDATE_WINDOW_TITLE, (void*)filename, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP HWND GuiGetWindowHandle()
|
||||
{
|
||||
return (HWND)_gui_sendmessage(GUI_GET_WINDOW_HANDLE, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiDumpAt(duint va)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_DUMP_AT, (void*)va, 0);
|
||||
_gui_sendmessage(GUI_DUMP_AT, (void*)va, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptAdd(int count, const char** lines)
|
||||
{
|
||||
_gui_sendmessage(GUI_SCRIPT_ADD, (void*)(duint)count, (void*)lines);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptClear()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_SCRIPT_CLEAR, 0, 0);
|
||||
_gui_sendmessage(GUI_SCRIPT_CLEAR, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptSetIp(int line)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_SCRIPT_SETIP, (void*)(duint)line, 0);
|
||||
_gui_sendmessage(GUI_SCRIPT_SETIP, (void*)(duint)line, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptError(int line, const char* message)
|
||||
{
|
||||
_gui_sendmessage(GUI_SCRIPT_ERROR, (void*)(duint)line, (void*)message);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptSetTitle(const char* title)
|
||||
{
|
||||
_gui_sendmessage(GUI_SCRIPT_SETTITLE, (void*)title, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info)
|
||||
{
|
||||
_gui_sendmessage(GUI_SCRIPT_SETINFOLINE, (void*)(duint)line, (void*)info);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptMessage(const char* message)
|
||||
{
|
||||
_gui_sendmessage(GUI_SCRIPT_MESSAGE, (void*)message, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP int GuiScriptMsgyn(const char* message)
|
||||
{
|
||||
return (int)(duint)_gui_sendmessage(GUI_SCRIPT_MSGYN, (void*)message, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiScriptEnableHighlighting(bool enable)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_SCRIPT_ENABLEHIGHLIGHTING, (void*)(duint)enable, 0);
|
||||
_gui_sendmessage(GUI_SCRIPT_ENABLEHIGHLIGHTING, (void*)(duint)enable, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiSymbolLogAdd(const char* message)
|
||||
{
|
||||
_gui_sendmessage(GUI_SYMBOL_LOG_ADD, (void*)message, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiSymbolLogClear()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_SYMBOL_LOG_CLEAR, 0, 0);
|
||||
_gui_sendmessage(GUI_SYMBOL_LOG_CLEAR, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiSymbolSetProgress(int percent)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_SYMBOL_SET_PROGRESS, (void*)(duint)percent, 0);
|
||||
_gui_sendmessage(GUI_SYMBOL_SET_PROGRESS, (void*)(duint)percent, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiSymbolUpdateModuleList(int count, SYMBOLMODULEINFO* modules)
|
||||
{
|
||||
_gui_sendmessage(GUI_SYMBOL_UPDATE_MODULE_LIST, (void*)(duint)count, (void*)modules);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiReferenceAddColumn(int width, const char* title)
|
||||
{
|
||||
_gui_sendmessage(GUI_REF_ADDCOLUMN, (void*)(duint)width, (void*)title);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiSymbolRefreshCurrent()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_SYMBOL_REFRESH_CURRENT, 0, 0);
|
||||
_gui_sendmessage(GUI_SYMBOL_REFRESH_CURRENT, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiReferenceSetRowCount(int count)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_REF_SETROWCOUNT, (void*)(duint)count, 0);
|
||||
_gui_sendmessage(GUI_REF_SETROWCOUNT, (void*)(duint)count, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP int GuiReferenceGetRowCount()
|
||||
{
|
||||
return (int)(duint)_gui_sendmessage(GUI_REF_GETROWCOUNT, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiReferenceDeleteAllColumns()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_REF_DELETEALLCOLUMNS, 0, 0);
|
||||
_gui_sendmessage(GUI_REF_DELETEALLCOLUMNS, 0, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiReferenceInitialize(const char* name)
|
||||
|
@ -879,141 +940,169 @@ BRIDGE_IMPEXP void GuiReferenceSetCellContent(int row, int col, const char* str)
|
|||
_gui_sendmessage(GUI_REF_SETCELLCONTENT, &info, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP const char* GuiReferenceGetCellContent(int row, int col)
|
||||
{
|
||||
return (const char*)_gui_sendmessage(GUI_REF_GETCELLCONTENT, (void*)(duint)row, (void*)(duint)col);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiReferenceReloadData()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_REF_RELOADDATA, 0, 0);
|
||||
_gui_sendmessage(GUI_REF_RELOADDATA, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiReferenceSetSingleSelection(int index, bool scroll)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_REF_SETSINGLESELECTION, (void*)(duint)index, (void*)(duint)scroll);
|
||||
_gui_sendmessage(GUI_REF_SETSINGLESELECTION, (void*)(duint)index, (void*)(duint)scroll);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiReferenceSetProgress(int progress)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_REF_SETPROGRESS, (void*)(duint)progress, 0);
|
||||
_gui_sendmessage(GUI_REF_SETPROGRESS, (void*)(duint)progress, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiReferenceSetSearchStartCol(int col)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_REF_SETSEARCHSTARTCOL, (void*)(duint)col, 0);
|
||||
_gui_sendmessage(GUI_REF_SETSEARCHSTARTCOL, (void*)(duint)col, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiStackDumpAt(duint addr, duint csp)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_STACK_DUMP_AT, (void*)addr, (void*)csp);
|
||||
_gui_sendmessage(GUI_STACK_DUMP_AT, (void*)addr, (void*)csp);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateDumpView()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_DUMP_VIEW, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_DUMP_VIEW, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateMemoryView()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_MEMORY_VIEW, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_MEMORY_VIEW, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateThreadView()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_THREAD_VIEW, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_THREAD_VIEW, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiAddRecentFile(const char* file)
|
||||
{
|
||||
_gui_sendmessage(GUI_ADD_RECENT_FILE, (void*)file, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiSetLastException(unsigned int exception)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_SET_LAST_EXCEPTION, (void*)(duint)exception, 0);
|
||||
_gui_sendmessage(GUI_SET_LAST_EXCEPTION, (void*)(duint)exception, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP bool GuiGetDisassembly(duint addr, char* text)
|
||||
{
|
||||
return !!_gui_sendmessage(GUI_GET_DISASSEMBLY, (void*)addr, text);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP int GuiMenuAdd(int hMenu, const char* title)
|
||||
{
|
||||
return (int)(duint)_gui_sendmessage(GUI_MENU_ADD, (void*)(duint)hMenu, (void*)title);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP int GuiMenuAddEntry(int hMenu, const char* title)
|
||||
{
|
||||
return (int)(duint)_gui_sendmessage(GUI_MENU_ADD_ENTRY, (void*)(duint)hMenu, (void*)title);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiMenuAddSeparator(int hMenu)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_MENU_ADD_SEPARATOR, (void*)(duint)hMenu, 0);
|
||||
_gui_sendmessage(GUI_MENU_ADD_SEPARATOR, (void*)(duint)hMenu, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiMenuClear(int hMenu)
|
||||
{
|
||||
_gui_sendmessageasync(GUI_MENU_CLEAR, (void*)(duint)hMenu, 0);
|
||||
_gui_sendmessage(GUI_MENU_CLEAR, (void*)(duint)hMenu, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP bool GuiSelectionGet(int hWindow, SELECTIONDATA* selection)
|
||||
{
|
||||
return !!_gui_sendmessage(GUI_SELECTION_GET, (void*)(duint)hWindow, selection);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP bool GuiSelectionSet(int hWindow, const SELECTIONDATA* selection)
|
||||
{
|
||||
return !!_gui_sendmessage(GUI_SELECTION_SET, (void*)(duint)hWindow, (void*)selection);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP bool GuiGetLineWindow(const char* title, char* text)
|
||||
{
|
||||
return !!_gui_sendmessage(GUI_GETLINE_WINDOW, (void*)title, text);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiAutoCompleteAddCmd(const char* cmd)
|
||||
{
|
||||
_gui_sendmessage(GUI_AUTOCOMPLETE_ADDCMD, (void*)cmd, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiAutoCompleteDelCmd(const char* cmd)
|
||||
{
|
||||
_gui_sendmessage(GUI_AUTOCOMPLETE_DELCMD, (void*)cmd, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiAutoCompleteClearAll()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_AUTOCOMPLETE_CLEARALL, 0, 0);
|
||||
_gui_sendmessage(GUI_AUTOCOMPLETE_CLEARALL, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiAddStatusBarMessage(const char* msg)
|
||||
{
|
||||
_gui_sendmessage(GUI_ADD_MSG_TO_STATUSBAR, (void*)msg, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateSideBar()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_SIDEBAR, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_SIDEBAR, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiRepaintTableView()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_REPAINT_TABLE_VIEW, 0, 0);
|
||||
_gui_sendmessage(GUI_REPAINT_TABLE_VIEW, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdatePatches()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_PATCHES, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_PATCHES, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateCallStack()
|
||||
{
|
||||
_gui_sendmessageasync(GUI_UPDATE_CALLSTACK, 0, 0);
|
||||
_gui_sendmessage(GUI_UPDATE_CALLSTACK, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
hInst = hinstDLL;
|
||||
|
|
|
@ -37,7 +37,7 @@ extern "C"
|
|||
|
||||
//Bridge defines
|
||||
#define MAX_SETTING_SIZE 65536
|
||||
#define DBG_VERSION 24
|
||||
#define DBG_VERSION 25
|
||||
|
||||
//Bridge functions
|
||||
BRIDGE_IMPEXP const char* BridgeInit();
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file _dbgfunctions.cpp
|
||||
|
||||
@brief Implements the dbgfunctions class.
|
||||
*/
|
||||
|
||||
#include "_global.h"
|
||||
#include "_dbgfunctions.h"
|
||||
#include "assemble.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file _exports.cpp
|
||||
|
||||
@brief Implements the exports class.
|
||||
*/
|
||||
|
||||
#include "_exports.h"
|
||||
#include "memory.h"
|
||||
#include "debugger.h"
|
||||
|
@ -494,9 +500,9 @@ extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump)
|
|||
return true;
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT bool _dbg_valtostring(const char* string, duint* value)
|
||||
extern "C" DLL_EXPORT bool _dbg_valtostring(const char* string, duint value)
|
||||
{
|
||||
return valtostring(string, value, true);
|
||||
return valtostring(string, value, true);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap)
|
||||
|
|
|
@ -20,7 +20,7 @@ DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addri
|
|||
DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo);
|
||||
DLL_EXPORT int _dbg_bpgettypeat(duint addr);
|
||||
DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump);
|
||||
DLL_EXPORT bool _dbg_valtostring(const char* string, duint* value);
|
||||
DLL_EXPORT bool _dbg_valtostring(const char* string, duint value);
|
||||
DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* list);
|
||||
DLL_EXPORT uint _dbg_getbranchdestination(uint addr);
|
||||
DLL_EXPORT bool _dbg_functionoverlaps(uint start, uint end);
|
||||
|
|
|
@ -1,15 +1,44 @@
|
|||
/**
|
||||
\file _global.cpp
|
||||
\brief Implements the global class.
|
||||
*/
|
||||
|
||||
#include "_global.h"
|
||||
#include <objbase.h>
|
||||
#include <shlobj.h>
|
||||
#include <new>
|
||||
|
||||
/**
|
||||
\brief x64_dbg library instance.
|
||||
*/
|
||||
HINSTANCE hInst;
|
||||
|
||||
/**
|
||||
\brief Directory where program databases are stored (usually in \db). UTF-8 encoding.
|
||||
*/
|
||||
char dbbasepath[deflen] = "";
|
||||
|
||||
/**
|
||||
\brief Path of the current program database. UTF-8 encoding.
|
||||
*/
|
||||
char dbpath[3 * deflen] = "";
|
||||
|
||||
/**
|
||||
\brief Number of allocated buffers by emalloc(). This should be 0 when x64_dbg ends.
|
||||
*/
|
||||
static int emalloc_count = 0;
|
||||
|
||||
/**
|
||||
\brief Path for debugging, used to create an allocation trace file on emalloc() or efree(). Not used.
|
||||
*/
|
||||
static char alloctrace[MAX_PATH] = "";
|
||||
|
||||
/**
|
||||
\brief Allocates a new buffer.
|
||||
\param size The size of the buffer to allocate (in bytes).
|
||||
\param reason The reason for allocation (can be used for memory allocation tracking).
|
||||
\return Always returns a valid pointer to the buffer you requested. Will quit the application on errors.
|
||||
*/
|
||||
void* emalloc(size_t size, const char* reason)
|
||||
{
|
||||
unsigned char* a = (unsigned char*)GlobalAlloc(GMEM_FIXED, size);
|
||||
|
@ -28,6 +57,13 @@ void* emalloc(size_t size, const char* reason)
|
|||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Reallocates a buffer allocated with emalloc().
|
||||
\param [in] Pointer to memory previously allocated with emalloc(). When NULL a new buffer will be allocated by emalloc().
|
||||
\param size The new memory size.
|
||||
\param reason The reason for allocation (can be used for memory allocation tracking).
|
||||
\return Always returns a valid pointer to the buffer you requested. Will quit the application on errors.
|
||||
*/
|
||||
void* erealloc(void* ptr, size_t size, const char* reason)
|
||||
{
|
||||
if(!ptr)
|
||||
|
@ -47,6 +83,11 @@ void* erealloc(void* ptr, size_t size, const char* reason)
|
|||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Free memory previously allocated with emalloc().
|
||||
\param [in] Pointer to the memory to free.
|
||||
\param reason The reason for freeing, should be the same as the reason for allocating.
|
||||
*/
|
||||
void efree(void* ptr, const char* reason)
|
||||
{
|
||||
emalloc_count--;
|
||||
|
@ -58,16 +99,30 @@ void efree(void* ptr, const char* reason)
|
|||
GlobalFree(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets the number of memory leaks. This number is only valid in _dbg_dbgexitsignal().
|
||||
\return The number of memory leaks.
|
||||
*/
|
||||
int memleaks()
|
||||
{
|
||||
return emalloc_count;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Sets the path for the allocation trace file.
|
||||
\param file UTF-8 filepath.
|
||||
*/
|
||||
void setalloctrace(const char* file)
|
||||
{
|
||||
strcpy_s(alloctrace, file);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief A function to determine if a string is contained in a specifically formatted 'array string'.
|
||||
\param cmd_list Array of strings separated by '\1'.
|
||||
\param cmd The string to look for.
|
||||
\return true if \p cmd is contained in \p cmd_list.
|
||||
*/
|
||||
bool arraycontains(const char* cmd_list, const char* cmd)
|
||||
{
|
||||
//TODO: fix this function a little
|
||||
|
@ -95,11 +150,23 @@ bool arraycontains(const char* cmd_list, const char* cmd)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Compares two strings without case-sensitivity.
|
||||
\param a The first string.
|
||||
\param b The second string.
|
||||
\return true if the strings are equal (case-insensitive).
|
||||
*/
|
||||
bool scmp(const char* a, const char* b)
|
||||
{
|
||||
return _stricmp(a, b) == 0;
|
||||
if(_stricmp(a, b))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Formats a string to hexadecimal format (removes all non-hex characters).
|
||||
\param [in,out] String to format.
|
||||
*/
|
||||
void formathex(char* string)
|
||||
{
|
||||
int len = (int)strlen(string);
|
||||
|
@ -112,6 +179,10 @@ void formathex(char* string)
|
|||
strcpy_s(string, len + 1, new_string);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Formats a string to decimal format (removed all non-numeric characters).
|
||||
\param [in,out] String to format.
|
||||
*/
|
||||
void formatdec(char* string)
|
||||
{
|
||||
int len = (int)strlen(string);
|
||||
|
@ -124,18 +195,34 @@ void formatdec(char* string)
|
|||
strcpy_s(string, len + 1, new_string);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Queries if a given file exists.
|
||||
\param file Path to the file to check (UTF-8).
|
||||
\return true if the file exists on the hard drive.
|
||||
*/
|
||||
bool FileExists(const char* file)
|
||||
{
|
||||
DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(file).c_str());
|
||||
return (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Queries if a given directory exists.
|
||||
\param dir Path to the directory to check (UTF-8).
|
||||
\return true if the directory exists.
|
||||
*/
|
||||
bool DirExists(const char* dir)
|
||||
{
|
||||
DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(dir).c_str());
|
||||
return (attrib == FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets file path from a file handle.
|
||||
\param hFile File handle to get the path from.
|
||||
\param [in,out] szFileName Buffer of size MAX_PATH.
|
||||
\return true if it succeeds, false if it fails.
|
||||
*/
|
||||
bool GetFileNameFromHandle(HANDLE hFile, char* szFileName)
|
||||
{
|
||||
wchar_t wszFileName[MAX_PATH] = L"";
|
||||
|
@ -145,6 +232,12 @@ bool GetFileNameFromHandle(HANDLE hFile, char* szFileName)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get a boolean setting from the configuration file.
|
||||
\param section The section of the setting (UTF-8).
|
||||
\param name The name of the setting (UTF-8).
|
||||
\return true if the setting was set and equals to true, otherwise returns false.
|
||||
*/
|
||||
bool settingboolget(const char* section, const char* name)
|
||||
{
|
||||
uint setting;
|
||||
|
@ -155,6 +248,11 @@ bool settingboolget(const char* section, const char* name)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets file architecture.
|
||||
\param szFileName UTF-8 encoded file path.
|
||||
\return The file architecture (::arch).
|
||||
*/
|
||||
arch GetFileArchitecture(const char* szFileName)
|
||||
{
|
||||
arch retval = notfound;
|
||||
|
@ -188,6 +286,10 @@ arch GetFileArchitecture(const char* szFileName)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Query if x64_dbg is running in Wow64 mode.
|
||||
\return true if running in Wow64, false otherwise.
|
||||
*/
|
||||
bool IsWow64()
|
||||
{
|
||||
BOOL bIsWow64Process = FALSE;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#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"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file _plugins.cpp
|
||||
|
||||
@brief Implements the plugins class.
|
||||
*/
|
||||
|
||||
#include "_plugins.h"
|
||||
#include "plugin_loader.h"
|
||||
#include "console.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file addrinfo.cpp
|
||||
|
||||
@brief Implements the addrinfo class.
|
||||
*/
|
||||
|
||||
#include "addrinfo.h"
|
||||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
\file argument.cpp
|
||||
\brief Implements the argument class.
|
||||
*/
|
||||
|
||||
#include "argument.h"
|
||||
#include "console.h"
|
||||
|
||||
|
@ -22,6 +27,11 @@ formatarg:
|
|||
12) restore double backslash
|
||||
13) combine formatted arguments and command
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Formats a command string (see source code for more information).
|
||||
\param [in,out] Command to format.
|
||||
*/
|
||||
void argformat(char* cmd)
|
||||
{
|
||||
if(strlen(cmd) >= deflen)
|
||||
|
@ -157,6 +167,12 @@ void argformat(char* cmd)
|
|||
1) remove double backslash
|
||||
2) count unescaped commas
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Gets the argument count from a command formatted by argformat().
|
||||
\param cmd The command to get the argument count from.
|
||||
\return The argument count.
|
||||
*/
|
||||
int arggetcount(const char* cmd)
|
||||
{
|
||||
int len = (int)strlen(cmd);
|
||||
|
@ -188,6 +204,7 @@ int arggetcount(const char* cmd)
|
|||
}
|
||||
return arg_count;
|
||||
}
|
||||
|
||||
/*
|
||||
1) get arg count
|
||||
2) remove double backslash
|
||||
|
@ -195,6 +212,15 @@ int arggetcount(const char* cmd)
|
|||
4) restore double backslash
|
||||
5) handle escape characters
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Gets an argument from a command.
|
||||
\param cmd The command to get the argument from.
|
||||
\param [out] Buffer of size #deflen.
|
||||
\param arg_num The zero-based argument number to retrieve.
|
||||
\param optional true if the argument is optional. When false there will be error messages on the console. Used to skip writing error messages yourself.
|
||||
\return true if the argument was found in the command.
|
||||
*/
|
||||
bool argget(const char* cmd, char* arg, int arg_num, bool optional)
|
||||
{
|
||||
if(strlen(cmd) >= deflen)
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file assemble.cpp
|
||||
|
||||
@brief Implements the assemble class.
|
||||
*/
|
||||
|
||||
#include "assemble.h"
|
||||
#include "memory.h"
|
||||
#include "debugger.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file breakpoint.cpp
|
||||
|
||||
@brief Implements the breakpoint class.
|
||||
*/
|
||||
|
||||
#include "breakpoint.h"
|
||||
#include "debugger.h"
|
||||
#include "addrinfo.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file command.cpp
|
||||
|
||||
@brief Implements the command class.
|
||||
*/
|
||||
|
||||
#include "command.h"
|
||||
#include "argument.h"
|
||||
#include "value.h"
|
||||
|
@ -5,6 +11,13 @@
|
|||
#include "debugger.h"
|
||||
#include "math.h"
|
||||
|
||||
/**
|
||||
\brief Finds a ::COMMAND in a command list.
|
||||
\param [in] command list.
|
||||
\param name The name of the command to find.
|
||||
\param [out] Link to the command.
|
||||
\return null if it fails, else a ::COMMAND*.
|
||||
*/
|
||||
COMMAND* cmdfind(COMMAND* command_list, const char* name, COMMAND** link)
|
||||
{
|
||||
COMMAND* cur = command_list;
|
||||
|
@ -25,6 +38,10 @@ COMMAND* cmdfind(COMMAND* command_list, const char* name, COMMAND** link)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Initialize a command list.
|
||||
\return a ::COMMAND*
|
||||
*/
|
||||
COMMAND* cmdinit()
|
||||
{
|
||||
COMMAND* cmd = (COMMAND*)emalloc(sizeof(COMMAND), "cmdinit:cmd");
|
||||
|
@ -32,6 +49,10 @@ COMMAND* cmdinit()
|
|||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Clear a command list.
|
||||
\param [in] cmd_list Command list to clear.
|
||||
*/
|
||||
void cmdfree(COMMAND* cmd_list)
|
||||
{
|
||||
COMMAND* cur = cmd_list;
|
||||
|
@ -44,6 +65,14 @@ void cmdfree(COMMAND* cmd_list)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Creates a new command and adds it to the list.
|
||||
\param [in,out] command_list Command list. Cannot be null.
|
||||
\param name The command name.
|
||||
\param cbCommand The command callback.
|
||||
\param debugonly true if the command can only be executed in a debugging context.
|
||||
\return true if the command was successfully added to the list.
|
||||
*/
|
||||
bool cmdnew(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly)
|
||||
{
|
||||
if(!command_list or !cbCommand or !name or !*name or cmdfind(command_list, name, 0))
|
||||
|
@ -72,6 +101,12 @@ bool cmdnew(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool d
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets a ::COMMAND from the command list.
|
||||
\param [in] command_list Command list.
|
||||
\param cmd The command to get from the list.
|
||||
\return null if the command was not found. Otherwise a ::COMMAND*.
|
||||
*/
|
||||
COMMAND* cmdget(COMMAND* command_list, const char* cmd)
|
||||
{
|
||||
char new_cmd[deflen] = "";
|
||||
|
@ -87,6 +122,14 @@ COMMAND* cmdget(COMMAND* command_list, const char* cmd)
|
|||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Sets a new command callback and debugonly property in a command list.
|
||||
\param [in] command_list Command list.
|
||||
\param name The name of the command to change.
|
||||
\param cbCommand The new command callback.
|
||||
\param debugonly The new debugonly value.
|
||||
\return The old command callback.
|
||||
*/
|
||||
CBCOMMAND cmdset(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly)
|
||||
{
|
||||
if(!cbCommand)
|
||||
|
@ -100,6 +143,12 @@ CBCOMMAND cmdset(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, b
|
|||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Deletes a command from a command list.
|
||||
\param [in] command_list Command list.
|
||||
\param name The name of the command to delete.
|
||||
\return true if the command was deleted.
|
||||
*/
|
||||
bool cmddel(COMMAND* command_list, const char* name)
|
||||
{
|
||||
COMMAND* prev = 0;
|
||||
|
@ -134,6 +183,16 @@ cbCommandProvider: function that provides commands (fgets for example), does
|
|||
cbCommandFinder: non-default command finder
|
||||
error_is_fatal: error return of a command callback stops the command processing
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Initiates a command loop. This function will not return until a command returns ::STATUS_EXIT.
|
||||
\param [in] command_list Command list to use for the command lookups.
|
||||
\param cbUnknownCommand The unknown command callback.
|
||||
\param cbCommandProvider The command provider callback.
|
||||
\param cbCommandFinder The command finder callback.
|
||||
\param error_is_fatal true if commands that return ::STATUS_ERROR terminate the command loop.
|
||||
\return A CMDRESULT, will always be ::STATUS_EXIT.
|
||||
*/
|
||||
CMDRESULT cmdloop(COMMAND* command_list, CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal)
|
||||
{
|
||||
if(!cbUnknownCommand or !cbCommandProvider)
|
||||
|
@ -197,12 +256,21 @@ CMDRESULT cmdloop(COMMAND* command_list, CBCOMMAND cbUnknownCommand, CBCOMMANDPR
|
|||
- custom command formatting rules
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Query if a string is a valid expression.
|
||||
\param expression The expression to check.
|
||||
\return true if the string is a valid expression.
|
||||
*/
|
||||
static bool isvalidexpression(const char* expression)
|
||||
{
|
||||
uint value;
|
||||
return valfromstring(expression, &value);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Special formats a given command. Used as a little hack to support stuff like 'x++' and 'x=y'
|
||||
\param [in,out] string String to format.
|
||||
*/
|
||||
static void specialformat(char* string)
|
||||
{
|
||||
int len = (int)strlen(string);
|
||||
|
@ -266,6 +334,13 @@ static void specialformat(char* string)
|
|||
/*
|
||||
- 'default' command finder, with some custom rules
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Default command finder. It uses specialformat() and mathformat() to make sure the command is optimally checked.
|
||||
\param [in] cmd_list Command list.
|
||||
\param [in] command Command name.
|
||||
\return null if it fails, else a COMMAND*.
|
||||
*/
|
||||
COMMAND* cmdfindmain(COMMAND* cmd_list, char* command)
|
||||
{
|
||||
COMMAND* cmd = cmdfind(cmd_list, command, 0);
|
||||
|
@ -279,6 +354,12 @@ COMMAND* cmdfindmain(COMMAND* cmd_list, char* command)
|
|||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Directly execute a command.
|
||||
\param [in,out] cmd_list Command list.
|
||||
\param cmd The command to execute.
|
||||
\return A CMDRESULT.
|
||||
*/
|
||||
CMDRESULT cmddirectexec(COMMAND* cmd_list, const char* cmd)
|
||||
{
|
||||
if(!cmd or !strlen(cmd))
|
||||
|
|
|
@ -1,24 +1,41 @@
|
|||
/**
|
||||
\file console.cpp
|
||||
\brief Implements the console class.
|
||||
*/
|
||||
|
||||
#include "console.h"
|
||||
|
||||
/**
|
||||
\brief Print a line with text, terminated with a newline to the console.
|
||||
\param text The text to print.
|
||||
*/
|
||||
void dputs(const char* Text)
|
||||
{
|
||||
dprintf("%s\n", Text);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Print a formatted string to the console.
|
||||
\param format The printf format to use (see documentation of printf for more information).
|
||||
*/
|
||||
void dprintf(const char* Format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[16384];
|
||||
va_list args;
|
||||
|
||||
va_start(args, Format);
|
||||
dprintf_args(Format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Print a formatted string to the console.
|
||||
\param format The printf format to use (see documentation of printf for more information).
|
||||
\param Args The argument buffer passed to the string parser.
|
||||
*/
|
||||
void dprintf_args(const char* Format, va_list Args)
|
||||
{
|
||||
char buffer[16384];
|
||||
vsnprintf_s(buffer, _TRUNCATE, Format, Args);
|
||||
|
||||
GuiAddLogMessage(buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,40 +8,40 @@
|
|||
#endif //__GNUC__
|
||||
|
||||
DWORD
|
||||
SafeUnDecorateSymbolName(
|
||||
SafeUnDecorateSymbolName(
|
||||
__in PCSTR name,
|
||||
__out_ecount(maxStringLength) PSTR outputString,
|
||||
__in DWORD maxStringLength,
|
||||
__in DWORD flags
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymUnloadModule64(
|
||||
SafeSymUnloadModule64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 BaseOfDll
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymSetSearchPath(
|
||||
SafeSymSetSearchPath(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt PCSTR SearchPath
|
||||
);
|
||||
);
|
||||
DWORD
|
||||
SafeSymSetOptions(
|
||||
SafeSymSetOptions(
|
||||
__in DWORD SymOptions
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymInitialize(
|
||||
SafeSymInitialize(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt PCSTR UserSearchPath,
|
||||
__in BOOL fInvadeProcess
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymRegisterCallback64(
|
||||
SafeSymRegisterCallback64(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
|
||||
__in ULONG64 UserContext
|
||||
);
|
||||
);
|
||||
DWORD64
|
||||
SafeSymLoadModuleEx(
|
||||
SafeSymLoadModuleEx(
|
||||
__in HANDLE hProcess,
|
||||
__in_opt HANDLE hFile,
|
||||
__in_opt PCSTR ImageName,
|
||||
|
@ -50,62 +50,56 @@ DWORD64
|
|||
__in DWORD DllSize,
|
||||
__in_opt PMODLOAD_DATA Data,
|
||||
__in_opt DWORD Flags
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymGetModuleInfo64(
|
||||
SafeSymGetModuleInfo64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 qwAddr,
|
||||
__out PIMAGEHLP_MODULE64 ModuleInfo
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymGetSearchPath(
|
||||
SafeSymGetSearchPath(
|
||||
__in HANDLE hProcess,
|
||||
__out_ecount(SearchPathLength) PSTR SearchPath,
|
||||
__in DWORD SearchPathLength
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymEnumSymbols(
|
||||
SafeSymEnumSymbols(
|
||||
__in HANDLE hProcess,
|
||||
__in ULONG64 BaseOfDll,
|
||||
__in_opt PCSTR Mask,
|
||||
__in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
|
||||
__in_opt PVOID UserContext
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymEnumerateModules64(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
|
||||
__in_opt PVOID UserContext
|
||||
);
|
||||
BOOL
|
||||
SafeSymEnumerateModules(
|
||||
SafeSymEnumerateModules(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
|
||||
__in_opt PVOID UserContext
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymGetLineFromAddr64(
|
||||
SafeSymGetLineFromAddr64(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 qwAddr,
|
||||
__out PDWORD pdwDisplacement,
|
||||
__out PIMAGEHLP_LINE64 Line64
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymFromName(
|
||||
SafeSymFromName(
|
||||
__in HANDLE hProcess,
|
||||
__in PCSTR Name,
|
||||
__inout PSYMBOL_INFO Symbol
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymFromAddr(
|
||||
SafeSymFromAddr(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 Address,
|
||||
__out_opt PDWORD64 Displacement,
|
||||
__inout PSYMBOL_INFO Symbol
|
||||
);
|
||||
);
|
||||
BOOL
|
||||
SafeSymCleanup(
|
||||
SafeSymCleanup(
|
||||
__in HANDLE hProcess
|
||||
);
|
||||
);
|
||||
|
||||
#endif //_DBGHELP_SAFE_H
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file debugger.cpp
|
||||
|
||||
@brief Implements the debugger class.
|
||||
*/
|
||||
|
||||
#include "debugger.h"
|
||||
#include "console.h"
|
||||
#include "memory.h"
|
||||
|
@ -30,8 +36,6 @@ static std::vector<ExceptionRange> ignoredExceptionRange;
|
|||
static SIZE_T cachePrivateUsage = 0;
|
||||
static HANDLE hEvent = 0;
|
||||
static String lastDebugText;
|
||||
|
||||
//Superglobal variables
|
||||
char szFileName[MAX_PATH] = "";
|
||||
char szSymbolCachePath[MAX_PATH] = "";
|
||||
char sqlitedb[deflen] = "";
|
||||
|
@ -589,7 +593,6 @@ void cbRtrStep()
|
|||
StepOver((void*)cbRtrStep);
|
||||
}
|
||||
|
||||
///custom handlers
|
||||
static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
||||
{
|
||||
void* base = CreateProcessInfo->lpBaseOfImage;
|
||||
|
@ -933,6 +936,7 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
|||
|
||||
static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
||||
{
|
||||
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
PLUG_CB_OUTPUTDEBUGSTRING callbackInfo;
|
||||
callbackInfo.DebugString = DebugString;
|
||||
|
@ -1021,7 +1025,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
if(nameInfo.dwType == 0x1000 and nameInfo.dwFlags == 0 and ThreadIsValid(nameInfo.dwThreadID)) //passed basic checks
|
||||
{
|
||||
Memory<char*> ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName");
|
||||
if(MemRead((void*)nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
|
||||
if(MemRead((void *)nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
|
||||
{
|
||||
String ThreadNameEscaped = StringUtils::Escape(ThreadName);
|
||||
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||
|
@ -1752,7 +1756,6 @@ static bool getcommandlineaddr(uint* addr, cmdline_error_t* cmd_line_error)
|
|||
return true;
|
||||
}
|
||||
|
||||
//update the pointer in the GetCommandLine function
|
||||
static bool patchcmdline(uint getcommandline, uint new_command_line, cmdline_error_t* cmd_line_error)
|
||||
{
|
||||
uint command_line_stored = 0;
|
||||
|
@ -1878,7 +1881,7 @@ bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error)
|
|||
return false;
|
||||
}
|
||||
|
||||
if(!MemWrite((void*)(mem + new_command_line.Length), (void*)cmd_line, strlen(cmd_line) + 1, &size))
|
||||
if(!MemWrite((void*)(mem + new_command_line.Length), (void *)cmd_line, strlen(cmd_line) + 1, &size))
|
||||
{
|
||||
cmd_line_error->addr = mem + new_command_line.Length;
|
||||
cmd_line_error->type = CMDL_ERR_WRITE_ANSI_COMMANDLINE;
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file debugger_commands.cpp
|
||||
|
||||
@brief Implements the debugger commands class.
|
||||
*/
|
||||
|
||||
#include "debugger_commands.h"
|
||||
#include "console.h"
|
||||
#include "value.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file disasm_fast.cpp
|
||||
|
||||
@brief Implements the disasm fast class.
|
||||
*/
|
||||
|
||||
#include "disasm_fast.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file disasm_helper.cpp
|
||||
|
||||
@brief Implements the disasm helper class.
|
||||
*/
|
||||
|
||||
#include "disasm_helper.h"
|
||||
#include "BeaEngine\BeaEngine.h"
|
||||
#include "value.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file instruction.cpp
|
||||
|
||||
@brief Implements the instruction class.
|
||||
*/
|
||||
|
||||
#include "instruction.h"
|
||||
#include "argument.h"
|
||||
#include "variable.h"
|
||||
|
@ -18,6 +24,7 @@
|
|||
#include "function.h"
|
||||
#include "loop.h"
|
||||
#include "patternfind.h"
|
||||
#include "module.h"
|
||||
|
||||
static bool bRefinit = false;
|
||||
|
||||
|
@ -196,7 +203,7 @@ CMDRESULT cbInstrMov(int argc, char* argv[])
|
|||
valfromstring(argv[1], &temp, true, false, 0, &isvar, 0);
|
||||
if(!isvar)
|
||||
isvar = vargettype(argv[1], 0);
|
||||
if(!isvar or !valtostring(argv[1], &set_value, true))
|
||||
if(!isvar or !valtostring(argv[1], set_value, true))
|
||||
{
|
||||
uint value;
|
||||
if(valfromstring(argv[1], &value)) //if the var is a value already it's an invalid destination
|
||||
|
@ -803,7 +810,6 @@ struct VALUERANGE
|
|||
uint end;
|
||||
};
|
||||
|
||||
//reffind value[,page]
|
||||
static bool cbRefFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
|
||||
{
|
||||
if(!disasm && !basicinfo) //initialize
|
||||
|
@ -886,13 +892,17 @@ CMDRESULT cbInstrRefFindRange(int argc, char* argv[])
|
|||
if(!valfromstring(argv[4], &size))
|
||||
size = 0;
|
||||
uint ticks = GetTickCount();
|
||||
int found = RefFind(addr, size, cbRefFind, &range, false, "Constant");
|
||||
char title[256] = "";
|
||||
if(range.start == range.end)
|
||||
sprintf_s(title, "Constant: %"fext"X", range.start);
|
||||
else
|
||||
sprintf_s(title, "Range: %"fext"X-%"fext"X", range.start, range.end);
|
||||
int found = RefFind(addr, size, cbRefFind, &range, false, title);
|
||||
dprintf("%u reference(s) in %ums\n", found, GetTickCount() - ticks);
|
||||
varset("$result", found, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
//refstr [page]
|
||||
bool cbRefStr(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
|
||||
{
|
||||
if(!disasm && !basicinfo) //initialize
|
||||
|
@ -1166,7 +1176,13 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
|
|||
else
|
||||
find_size = size - start;
|
||||
//setup reference view
|
||||
GuiReferenceInitialize("Occurrences");
|
||||
char patternshort[256] = "";
|
||||
strncpy_s(patternshort, pattern, min(16, len));
|
||||
if(len > 16)
|
||||
strcat_s(patternshort, "...");
|
||||
char patterntitle[256] = "";
|
||||
sprintf_s(patterntitle, "Pattern: %s", patternshort);
|
||||
GuiReferenceInitialize(patterntitle);
|
||||
GuiReferenceAddColumn(2 * sizeof(uint), "Address");
|
||||
if(findData)
|
||||
GuiReferenceAddColumn(0, "&Data&");
|
||||
|
@ -1212,7 +1228,6 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
//modcallfind [page]
|
||||
static bool cbModCallFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
|
||||
{
|
||||
if(!disasm && !basicinfo) //initialize
|
||||
|
@ -1468,7 +1483,6 @@ CMDRESULT cbInstrSleep(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
//reffindasm value[,page]
|
||||
static bool cbFindAsm(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
|
||||
{
|
||||
if(!disasm && !basicinfo) //initialize
|
||||
|
@ -1525,8 +1539,241 @@ CMDRESULT cbInstrFindAsm(int argc, char* argv[])
|
|||
disasmfast(dest, addr + size / 2, &basicinfo);
|
||||
|
||||
uint ticks = GetTickCount();
|
||||
int found = RefFind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false, "Command");
|
||||
char title[256] = "";
|
||||
sprintf_s(title, "Command: \"%s\"", basicinfo.instruction);
|
||||
int found = RefFind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false, title);
|
||||
dprintf("%u result(s) in %ums\n", found, GetTickCount() - ticks);
|
||||
varset("$result", found, false);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static void yaraCompilerCallback(int error_level, const char* file_name, int line_number, const char* message, void* user_data)
|
||||
{
|
||||
switch(error_level)
|
||||
{
|
||||
case YARA_ERROR_LEVEL_ERROR:
|
||||
dprintf("[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((void*)base, data(), size, 0))
|
||||
{
|
||||
dprintf("failed to read memory page %p[%X]!\n", base, size);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
FILE* rulesFile = 0;
|
||||
if(_wfopen_s(&rulesFile, StringUtils::Utf8ToUtf16(argv[1]).c_str(), L"rb"))
|
||||
{
|
||||
dputs("failed to open yara rules file!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
bool bSuccess = false;
|
||||
YR_COMPILER* yrCompiler;
|
||||
if(yr_compiler_create(&yrCompiler) == ERROR_SUCCESS)
|
||||
{
|
||||
yr_compiler_set_callback(yrCompiler, yaraCompilerCallback, 0);
|
||||
if(yr_compiler_add_file(yrCompiler, rulesFile, NULL, argv[1]) == 0) //no errors found
|
||||
{
|
||||
fclose(rulesFile);
|
||||
YR_RULES* yrRules;
|
||||
if(yr_compiler_get_rules(yrCompiler, &yrRules) == ERROR_SUCCESS)
|
||||
{
|
||||
//initialize new reference tab
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
if(!ModNameFromAddr(base, modname, true))
|
||||
sprintf_s(modname, "%p", base);
|
||||
String fullName;
|
||||
const char* fileName = strrchr(argv[1], '\\');
|
||||
if(fileName)
|
||||
fullName = fileName + 1;
|
||||
else
|
||||
fullName = argv[1];
|
||||
fullName += " (";
|
||||
fullName += modname;
|
||||
fullName += ")"; //nanana, very ugly code (long live open source)
|
||||
GuiReferenceInitialize(fullName.c_str());
|
||||
GuiReferenceAddColumn(sizeof(uint) * 2, "Address");
|
||||
GuiReferenceAddColumn(48, "Rule");
|
||||
GuiReferenceAddColumn(0, "Data");
|
||||
GuiReferenceSetRowCount(0);
|
||||
GuiReferenceReloadData();
|
||||
YaraScanInfo scanInfo;
|
||||
scanInfo.base = base;
|
||||
scanInfo.index = 0;
|
||||
uint ticks = GetTickCount();
|
||||
dputs("[YARA] Scan started...");
|
||||
int err = yr_rules_scan_mem(yrRules, data(), size, 0, yaraScanCallback, &scanInfo, 0);
|
||||
GuiReferenceReloadData();
|
||||
switch(err)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
dprintf("%u scan results in %ums...\n", scanInfo.index, GetTickCount() - ticks);
|
||||
bSuccess = true;
|
||||
break;
|
||||
case ERROR_TOO_MANY_MATCHES:
|
||||
dputs("too many matches!");
|
||||
break;
|
||||
default:
|
||||
dputs("error while scanning memory!");
|
||||
break;
|
||||
}
|
||||
yr_rules_destroy(yrRules);
|
||||
}
|
||||
else
|
||||
dputs("error while getting the rules!");
|
||||
}
|
||||
else
|
||||
dputs("errors in the rules file!");
|
||||
yr_compiler_destroy(yrCompiler);
|
||||
}
|
||||
else
|
||||
dputs("yr_compiler_create failed!");
|
||||
return bSuccess ? STATUS_CONTINUE : STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMDRESULT cbInstrYaramod(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
dputs("not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint base = ModBaseFromName(argv[2]);
|
||||
if(!base)
|
||||
{
|
||||
dprintf("invalid module \"%s\"!\n", argv[2]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint size = ModSizeFromAddr(base);
|
||||
char newcmd[deflen] = "";
|
||||
sprintf_s(newcmd, "yara \"%s\",%p,%p", argv[1], base, size);
|
||||
return cmddirectexec(dbggetcommandlist(), newcmd);
|
||||
}
|
||||
|
|
|
@ -62,5 +62,7 @@ CMDRESULT cbInstrFunctionList(int argc, char* argv[]);
|
|||
CMDRESULT cbInstrLoopList(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrSleep(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrFindAsm(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrYara(int argc, char* argv[]);
|
||||
CMDRESULT cbInstrYaramod(int argc, char* argv[]);
|
||||
|
||||
#endif // _INSTRUCTIONS_H
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file main.cpp
|
||||
|
||||
@brief Implements the main class.
|
||||
*/
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
|
|
|
@ -1,55 +1,84 @@
|
|||
/**
|
||||
@file math.cpp
|
||||
|
||||
@brief Implements various functionalities that have to do with handling expression text.
|
||||
*/
|
||||
|
||||
#include "math.h"
|
||||
#include "value.h"
|
||||
|
||||
enum BRACKET_TYPE
|
||||
{
|
||||
BRACKET_FREE,
|
||||
BRACKET_OPEN,
|
||||
BRACKET_CLOSE,
|
||||
};
|
||||
|
||||
/**
|
||||
\brief A bracket pair. This structure describes a piece of brackets '(' and ')'
|
||||
*/
|
||||
struct BRACKET_PAIR
|
||||
{
|
||||
/**
|
||||
\brief The position in the string of the opening bracket '('.
|
||||
*/
|
||||
int openpos;
|
||||
|
||||
/**
|
||||
\brief The position in the string of the closing bracket ')'.
|
||||
*/
|
||||
int closepos;
|
||||
|
||||
/**
|
||||
\brief The depth of the pair (for example when you have "((1+4)*4)" the second '(' has layer 2).
|
||||
*/
|
||||
int layer;
|
||||
BRACKET_TYPE isset;
|
||||
|
||||
/**
|
||||
\brief 0 when there is nothing set, 1 when the openpos is set, 2 when everything is set (aka pair is complete).
|
||||
*/
|
||||
int isset;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief An expression. This structure describes an expression in form of bracket pairs.
|
||||
*/
|
||||
struct EXPRESSION
|
||||
{
|
||||
/**
|
||||
\brief The bracket pairs.
|
||||
*/
|
||||
BRACKET_PAIR* pairs;
|
||||
|
||||
/**
|
||||
\brief The total number of bracket pairs.
|
||||
*/
|
||||
int total_pairs;
|
||||
|
||||
/**
|
||||
\brief The expression text everything is derived from.
|
||||
*/
|
||||
char* expression;
|
||||
};
|
||||
|
||||
/*
|
||||
operator precedence
|
||||
0 (INVALID/NONE)
|
||||
1 ( ) (PARENTHESIS)
|
||||
2 ~ (NOT)
|
||||
3 * / % (MUL DIV)
|
||||
4 + - (ADD SUB)
|
||||
5 < > (SHL SHR)
|
||||
6 & (AND)
|
||||
7 ^ (XOR)
|
||||
8 | (OR)
|
||||
/**
|
||||
\brief Determines if a characters is an operator.
|
||||
\param ch The character to check.
|
||||
\return The number of the operator. 0 when the character is no operator. Otherwise it returns one of the following numbers:
|
||||
|
||||
- 1 ( )
|
||||
- 2 ~ (NOT)
|
||||
- 3 * / % (MUL DIV)
|
||||
- 4 + - (ADD SUB)
|
||||
- 5 < > (SHL SHR)
|
||||
- 6 & (AND)
|
||||
- 7 ^ (XOR)
|
||||
- 8 | (OR)
|
||||
*/
|
||||
int mathisoperator(char ch)
|
||||
{
|
||||
//
|
||||
// The lower the number, the higher the priority.
|
||||
// Zero indicates no operator was found.
|
||||
//
|
||||
if(ch == '(' || ch == ')')
|
||||
if(ch == '(' or ch == ')')
|
||||
return 1;
|
||||
else if(ch == '~')
|
||||
return 2;
|
||||
else if(ch == '*' || ch == '`' || ch == '/' || ch == '%')
|
||||
else if(ch == '*' or ch == '`' or ch == '/' or ch == '%')
|
||||
return 3;
|
||||
else if(ch == '+' || ch == '-')
|
||||
else if(ch == '+' or ch == '-')
|
||||
return 4;
|
||||
else if(ch == '<' || ch == '>')
|
||||
else if(ch == '<' or ch == '>')
|
||||
return 5;
|
||||
else if(ch == '&')
|
||||
return 6;
|
||||
|
@ -57,165 +86,225 @@ int mathisoperator(char ch)
|
|||
return 7;
|
||||
else if(ch == '|')
|
||||
return 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
mathformat:
|
||||
- remove doubles
|
||||
/**
|
||||
\brief Formats the given text. It removes double operators like "**" and "||"
|
||||
\param [in,out] text The text to format.
|
||||
*/
|
||||
void mathformat(char* text)
|
||||
{
|
||||
int len = (int)strlen(text);
|
||||
Memory<char*> temp(len + 1, "mathformat:temp");
|
||||
|
||||
for (int i = 0, j = 0; i < len; i++)
|
||||
{
|
||||
if (mathisoperator(text[i]) < 3 || text[i] != text[i + 1])
|
||||
j += sprintf(temp + j, "%c", text[i]);
|
||||
}
|
||||
|
||||
memset(temp, 0, len + 1);
|
||||
for(int i = 0, j = 0; i < len; i++)
|
||||
if(mathisoperator(text[i]) < 3 or text[i] != text[i + 1])
|
||||
j += sprintf(temp + j, "%c", text[i]);
|
||||
strcpy(text, temp);
|
||||
}
|
||||
|
||||
/*
|
||||
- check for math operators
|
||||
/**
|
||||
\brief Checks if the given text contains operators.
|
||||
\param text The text to check.
|
||||
\return true if the text contains operator, false if not.
|
||||
*/
|
||||
bool mathcontains(const char* text)
|
||||
{
|
||||
// Skip negative values
|
||||
if(*text == '-')
|
||||
if(*text == '-') //ignore negative values
|
||||
text++;
|
||||
|
||||
// Search the entire string looking for a math operator
|
||||
for (; text[0] != '\0'; text++)
|
||||
{
|
||||
if (mathisoperator(text[0]))
|
||||
return true;
|
||||
}
|
||||
|
||||
int len = (int)strlen(text);
|
||||
for(int i = 0; i < len; i++)
|
||||
if(mathisoperator(text[i]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __MINGW64__
|
||||
inline unsigned long long umulhi(unsigned long long x, unsigned long long y)
|
||||
static inline unsigned long long umulhi(unsigned long long x, unsigned long long y)
|
||||
{
|
||||
return (unsigned long long)(((__uint128_t)x * y) >> 64);
|
||||
}
|
||||
|
||||
inline long long mulhi(long long x, long long y)
|
||||
static inline long long mulhi(long long x, long long y)
|
||||
{
|
||||
return (long long)(((__int128_t)x * y) >> 64);
|
||||
}
|
||||
#elif _WIN64
|
||||
#include <intrin.h>
|
||||
inline unsigned long long umulhi(unsigned long long x, unsigned long long y)
|
||||
static inline unsigned long long umulhi(unsigned long long x, unsigned long long y)
|
||||
{
|
||||
unsigned __int64 res;
|
||||
_umul128(x, y, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline long long mulhi(long long x, long long y)
|
||||
static inline long long mulhi(long long x, long long y)
|
||||
{
|
||||
__int64 res;
|
||||
_mul128(x, y, &res);
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
inline unsigned int umulhi(unsigned int x, unsigned int y)
|
||||
static inline unsigned int umulhi(unsigned int x, unsigned int y)
|
||||
{
|
||||
return (unsigned int)(((unsigned long long)x * y) >> 32);
|
||||
}
|
||||
|
||||
inline int mulhi(int x, int y)
|
||||
static inline int mulhi(int x, int y)
|
||||
{
|
||||
return (int)(((long long)x * y) >> 32);
|
||||
}
|
||||
#endif //__MINGW64__
|
||||
|
||||
template<typename T>
|
||||
bool MathDoOperation(char op, T left, T right, T* result)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case '*':
|
||||
*result = left * right;
|
||||
return true;
|
||||
case '`':
|
||||
*result = umulhi(left, right);
|
||||
return true;
|
||||
case '/':
|
||||
if (right)
|
||||
{
|
||||
*result = left / right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '%':
|
||||
if (right)
|
||||
{
|
||||
*result = left % right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '+':
|
||||
*result = left + right;
|
||||
return true;
|
||||
case '-':
|
||||
*result = left - right;
|
||||
return true;
|
||||
case '<':
|
||||
*result = left << right;
|
||||
return true;
|
||||
case '>':
|
||||
*result = left >> right;
|
||||
return true;
|
||||
case '&':
|
||||
*result = left & right;
|
||||
return true;
|
||||
case '^':
|
||||
*result = left ^ right;
|
||||
return true;
|
||||
case '|':
|
||||
*result = left | right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Do an operation on two unsigned numbers.
|
||||
\param op The operation to do (this must be a valid operator).
|
||||
\param left The number left of the operator.
|
||||
\param right The number right of the operator.
|
||||
\param [out] result The result of the operator. Cannot be null.
|
||||
\return true if the operation succeeded. It could fail on zero devision or an invalid operator.
|
||||
*/
|
||||
bool mathdounsignedoperation(char op, uint left, uint right, uint* result)
|
||||
{
|
||||
return MathDoOperation<uint>(op, left, right, result);
|
||||
switch(op)
|
||||
{
|
||||
case '*':
|
||||
*result = left * right;
|
||||
return true;
|
||||
case '`':
|
||||
*result = umulhi(left, right);
|
||||
return true;
|
||||
case '/':
|
||||
if(right)
|
||||
{
|
||||
*result = left / right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '%':
|
||||
if(right)
|
||||
{
|
||||
*result = left % right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '+':
|
||||
*result = left + right;
|
||||
return true;
|
||||
case '-':
|
||||
*result = left - right;
|
||||
return true;
|
||||
case '<':
|
||||
*result = left << right;
|
||||
return true;
|
||||
case '>':
|
||||
*result = left >> right;
|
||||
return true;
|
||||
case '&':
|
||||
*result = left & right;
|
||||
return true;
|
||||
case '^':
|
||||
*result = left ^ right;
|
||||
return true;
|
||||
case '|':
|
||||
*result = left | right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Do an operation on two signed numbers.
|
||||
\param op The operation to do (this must be a valid operator).
|
||||
\param left The number left of the operator.
|
||||
\param right The number right of the operator.
|
||||
\param [out] result The result of the operator. Cannot be null.
|
||||
\return true if the operation succeeded. It could fail on zero devision or an invalid operator.
|
||||
*/
|
||||
bool mathdosignedoperation(char op, sint left, sint right, sint* result)
|
||||
{
|
||||
return MathDoOperation<sint>(op, left, right, result);
|
||||
switch(op)
|
||||
{
|
||||
case '*':
|
||||
*result = left * right;
|
||||
return true;
|
||||
case '`':
|
||||
*result = mulhi(left, right);
|
||||
return true;
|
||||
case '/':
|
||||
if(right)
|
||||
{
|
||||
*result = left / right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '%':
|
||||
if(right)
|
||||
{
|
||||
*result = left % right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '+':
|
||||
*result = left + right;
|
||||
return true;
|
||||
case '-':
|
||||
*result = left - right;
|
||||
return true;
|
||||
case '<':
|
||||
*result = left << right;
|
||||
return true;
|
||||
case '>':
|
||||
*result = left >> right;
|
||||
return true;
|
||||
case '&':
|
||||
*result = left & right;
|
||||
return true;
|
||||
case '^':
|
||||
*result = left ^ right;
|
||||
return true;
|
||||
case '|':
|
||||
*result = left | right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void fillpair(EXPRESSION* expstruct, int pos, int layer)
|
||||
/**
|
||||
\brief Fills a BRACKET_PAIR structure.
|
||||
\param [in,out] expstruct The expression structure. Cannot be null.
|
||||
\param pos The position to fill, position of '(' or ')'.
|
||||
\param layer The layer this bracket is in.
|
||||
*/
|
||||
static void fillpair(EXPRESSION* expstruct, int pos, int layer)
|
||||
{
|
||||
for(int i = 0; i < expstruct->total_pairs; i++)
|
||||
{
|
||||
if(expstruct->pairs[i].isset == BRACKET_FREE)
|
||||
if(!expstruct->pairs[i].isset)
|
||||
{
|
||||
expstruct->pairs[i].layer = layer;
|
||||
expstruct->pairs[i].openpos = pos;
|
||||
expstruct->pairs[i].isset = BRACKET_OPEN;
|
||||
expstruct->pairs[i].layer = layer;
|
||||
expstruct->pairs[i].openpos = pos;
|
||||
expstruct->pairs[i].isset = 1;
|
||||
break;
|
||||
}
|
||||
else if(expstruct->pairs[i].layer == layer && expstruct->pairs[i].isset == BRACKET_OPEN)
|
||||
else if(expstruct->pairs[i].layer == layer and expstruct->pairs[i].isset == 1)
|
||||
{
|
||||
expstruct->pairs[i].closepos = pos;
|
||||
expstruct->pairs[i].isset = BRACKET_CLOSE;
|
||||
expstruct->pairs[i].closepos = pos;
|
||||
expstruct->pairs[i].isset = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int matchpairs(EXPRESSION* expstruct, char* expression, int endlayer)
|
||||
/**
|
||||
\brief This function recursively matches bracket pair in an EXPRESSION.
|
||||
\param [in,out] expstruct The expression structure. Cannot be null.
|
||||
\param [in,out] expression The expression text to parse. Cannot be null.
|
||||
\param endlayer The layer to stop on. This variable is used for the recursion termination condition.
|
||||
\return The position in the \p expression mathpairs ended in.
|
||||
*/
|
||||
static int matchpairs(EXPRESSION* expstruct, char* expression, int endlayer = 0)
|
||||
{
|
||||
int layer = endlayer;
|
||||
int len = (int)strlen(expression);
|
||||
|
@ -243,7 +332,12 @@ int matchpairs(EXPRESSION* expstruct, char* expression, int endlayer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int expressionformat(char* exp)
|
||||
/**
|
||||
\brief Formats a given expression. This function checks if the number of brackets is even and adds brackets to the end if needed.
|
||||
\param [in,out] exp The expression to format.
|
||||
\return The number of bracket pairs in the expression or -1 on error.
|
||||
*/
|
||||
static int expressionformat(char* exp)
|
||||
{
|
||||
int len = (int)strlen(exp);
|
||||
int open = 0;
|
||||
|
@ -266,36 +360,52 @@ int expressionformat(char* exp)
|
|||
return open;
|
||||
}
|
||||
|
||||
void adjustpairs(EXPRESSION* exps, int cur_open, int cur_close, int cur_len, int new_len)
|
||||
/**
|
||||
\brief Adjusts bracket pair positions to insert a new string in the expression.
|
||||
\param [in,out] exps The expression structure.
|
||||
\param cur_open The current opening bracket '(' position.
|
||||
\param cur_close The current closing bracket ')' position.
|
||||
\param cur_len The current string length in between the brackets.
|
||||
\param new_len Length of the new string.
|
||||
*/
|
||||
static void adjustpairs(EXPRESSION* exps, int cur_open, int cur_close, int cur_len, int new_len)
|
||||
{
|
||||
for(int i = 0; i < exps->total_pairs; i++)
|
||||
{
|
||||
if(exps->pairs[i].openpos > cur_open)
|
||||
exps->pairs[i].openpos += new_len - cur_len;
|
||||
|
||||
if(exps->pairs[i].closepos > cur_close)
|
||||
exps->pairs[i].closepos += new_len - cur_len;
|
||||
}
|
||||
}
|
||||
|
||||
bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool baseonly)
|
||||
/**
|
||||
\brief Prints value of expressions in between brackets on a certain bracket layer (expression is resolved using mathfromstring(), which means the whole thing can work recursively).
|
||||
\param [in,out] exp The expression to print. Cannot be null.
|
||||
\param [in,out] exps The expression structure. Cannot be null.
|
||||
\param layer The layer to print.
|
||||
\param silent Value to pass on to mathfromstring().
|
||||
\param baseonly Value to pass on to mathfromstring().
|
||||
\return true if printing the layer was succesful, false otherwise.
|
||||
*/
|
||||
static bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool baseonly)
|
||||
{
|
||||
for(int i = 0; i < exps->total_pairs; i++)
|
||||
{
|
||||
if(exps->pairs[i].layer == layer)
|
||||
{
|
||||
int open = exps->pairs[i].openpos;
|
||||
int close = exps->pairs[i].closepos;
|
||||
int len = close - open;
|
||||
char temp[256] = "";
|
||||
char backup[256] = "";
|
||||
|
||||
char temp[256];
|
||||
int open = exps->pairs[i].openpos;
|
||||
int close = exps->pairs[i].closepos;
|
||||
int len = close - open;
|
||||
strncpy(temp, exp + open + 1, len - 1);
|
||||
|
||||
char backup[256];
|
||||
strcpy_s(backup, exp + open + len + 1);
|
||||
|
||||
uint value;
|
||||
if(!mathfromstring(temp, &value, silent, baseonly, nullptr, nullptr))
|
||||
if(!mathfromstring(temp, &value, silent, baseonly, 0, 0))
|
||||
return false;
|
||||
|
||||
adjustpairs(exps, open, close, len + 1, sprintf(exp + open, "%"fext"X", value));
|
||||
|
@ -304,46 +414,51 @@ bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool baseon
|
|||
strcat(exp, backup);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Handle brackets in an expression (calculate the values of expressions in between brackets).
|
||||
\param [in,out] expression Expression to handle. Cannot be null.
|
||||
\param silent Value to pass on to printlayer().
|
||||
\param baseonly Value to pass on to printlayer().
|
||||
\return true if the brackets are correctly expanded, false otherwise.
|
||||
*/
|
||||
bool mathhandlebrackets(char* expression, bool silent, bool baseonly)
|
||||
{
|
||||
int totalPairs = expressionformat(expression);
|
||||
|
||||
if(totalPairs == -1)
|
||||
EXPRESSION expstruct;
|
||||
expstruct.expression = expression;
|
||||
int total_pairs = expressionformat(expression);
|
||||
if(total_pairs == -1)
|
||||
return false;
|
||||
else if(!totalPairs)
|
||||
else if(!total_pairs)
|
||||
return true;
|
||||
expstruct.total_pairs = total_pairs;
|
||||
|
||||
Memory<BRACKET_PAIR*> pairs(totalPairs * sizeof(BRACKET_PAIR), "mathhandlebrackets:pairs");
|
||||
|
||||
EXPRESSION expStruct;
|
||||
expStruct.expression = expression;
|
||||
expStruct.total_pairs = totalPairs;
|
||||
expStruct.pairs = pairs;
|
||||
|
||||
matchpairs(&expStruct, expression, 0);
|
||||
|
||||
Memory<BRACKET_PAIR*> pairs(expstruct.total_pairs * sizeof(BRACKET_PAIR), "mathhandlebrackets:expstruct.pairs");
|
||||
expstruct.pairs = pairs;
|
||||
memset(expstruct.pairs, 0, expstruct.total_pairs * sizeof(BRACKET_PAIR));
|
||||
matchpairs(&expstruct, expression);
|
||||
int deepest = 0;
|
||||
for (int i = 0; i < expStruct.total_pairs; i++)
|
||||
{
|
||||
if (expStruct.pairs[i].layer > deepest)
|
||||
deepest = expStruct.pairs[i].layer;
|
||||
}
|
||||
|
||||
for (int i = deepest; i > 0; i--)
|
||||
{
|
||||
if (!printlayer(expression, &expStruct, i, silent, baseonly))
|
||||
return false;
|
||||
}
|
||||
for(int i = 0; i < expstruct.total_pairs; i++)
|
||||
if(expstruct.pairs[i].layer > deepest)
|
||||
deepest = expstruct.pairs[i].layer;
|
||||
|
||||
for(int i = deepest; i > 0; i--)
|
||||
if(!printlayer(expression, &expstruct, i, silent, baseonly))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
- handle math
|
||||
/**
|
||||
\brief Calculate the value of an expression string.
|
||||
\param string The string to calculate the value of. Cannot be null.
|
||||
\param [in,out] value The resulting value. Cannot be null.
|
||||
\param silent Value to pass on to valfromstring().
|
||||
\param baseonly Value to pass on to valfromstring().
|
||||
\param [in,out] value_size Value to pass on to valfromstring(). Can be null.
|
||||
\param [in,out] isvar Value to pass on to valfromstring(). Can be null.
|
||||
\return true if the string was successfully parsed and the value was calculated.
|
||||
*/
|
||||
bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly, int* value_size, bool* isvar)
|
||||
{
|
||||
|
@ -369,6 +484,8 @@ bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
return valfromstring(string, value, silent, baseonly, value_size, isvar, 0);
|
||||
Memory<char*> strleft(len + 1 + negative, "mathfromstring:strleft");
|
||||
Memory<char*> strright(len + 1, "mathfromstring:strright");
|
||||
memset(strleft, 0, len + 1);
|
||||
memset(strright, 0, len + 1);
|
||||
strncpy(strleft, string - negative, highestop_pos + negative);
|
||||
strcpy(strright, string + highestop_pos + 1);
|
||||
strcpy(strleft, StringUtils::Trim(strleft).c_str());
|
||||
|
@ -397,5 +514,4 @@ bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
else
|
||||
math_ok = mathdounsignedoperation(string[highestop_pos], left, right, value);
|
||||
return math_ok;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#ifndef _MATH_H
|
||||
#define _MATH_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
|
@ -8,4 +9,6 @@ bool mathcontains(const char* text);
|
|||
bool mathhandlebrackets(char* expression, bool silent, bool baseonly);
|
||||
bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly, int* value_size, bool* isvar);
|
||||
bool mathdounsignedoperation(char op, uint left, uint right, uint* result);
|
||||
bool mathdosignedoperation(char op, sint left, sint right, sint* result);
|
||||
bool mathdosignedoperation(char op, sint left, sint right, sint* result);
|
||||
|
||||
#endif // _MATH_H
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file memory.cpp
|
||||
|
||||
@brief Implements the memory class.
|
||||
*/
|
||||
|
||||
#include "memory.h"
|
||||
#include "debugger.h"
|
||||
#include "patches.h"
|
||||
|
|
|
@ -5,28 +5,28 @@
|
|||
|
||||
struct MODSECTIONINFO
|
||||
{
|
||||
uint addr; // Virtual address
|
||||
uint size; // Virtual size
|
||||
char name[50]; // Escaped section name
|
||||
uint addr; // Virtual address
|
||||
uint size; // Virtual size
|
||||
char name[50]; // Escaped section name
|
||||
};
|
||||
|
||||
struct MODINFO
|
||||
{
|
||||
uint base; // Module base
|
||||
uint size; // Module size
|
||||
uint hash; // Full module name hash
|
||||
uint entry; // Entry point
|
||||
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
|
||||
char path[MAX_PATH]; // File path (in UTF8)
|
||||
char name[MAX_MODULE_SIZE]; // Module name (without extension)
|
||||
char extension[MAX_MODULE_SIZE]; // File extension
|
||||
char path[MAX_PATH]; // File path (in UTF8)
|
||||
|
||||
HANDLE Handle; // Handle to the file opened by TitanEngine
|
||||
HANDLE MapHandle; // Handle to the memory map
|
||||
ULONG_PTR FileMapVA; // File map virtual address (Debugger local)
|
||||
DWORD FileMapSize; // File map virtual size
|
||||
HANDLE Handle; // Handle to the file opened by TitanEngine
|
||||
HANDLE MapHandle; // Handle to the memory map
|
||||
ULONG_PTR FileMapVA; // File map virtual address (Debugger local)
|
||||
DWORD FileMapSize; // File map virtual size
|
||||
|
||||
std::vector<MODSECTIONINFO> sections;
|
||||
std::vector<MODSECTIONINFO> sections;
|
||||
};
|
||||
|
||||
typedef std::map<Range, MODINFO, RangeCompare> ModulesInfo;
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
/**
|
||||
@file msgqueue.cpp
|
||||
|
||||
@brief Implements the msgqueue class.
|
||||
*/
|
||||
|
||||
#include "msgqueue.h"
|
||||
|
||||
// Allocate a message stack
|
||||
MESSAGE_STACK* MsgAllocStack()
|
||||
{
|
||||
// Use placement new to ensure all constructors are called correctly
|
||||
PVOID memoryBuffer = emalloc(sizeof(MESSAGE_STACK), "MsgAllocStack:memoryBuffer");
|
||||
MESSAGE_STACK* messageStack = new(memoryBuffer) MESSAGE_STACK;
|
||||
|
||||
if(!messageStack)
|
||||
return nullptr;
|
||||
// Allocate memory for the structure
|
||||
PVOID memoryBuffer = emalloc(sizeof(MESSAGE_STACK), "MsgAllocStack:memoryBuffer");
|
||||
|
||||
return messageStack;
|
||||
if (!memoryBuffer)
|
||||
return nullptr;
|
||||
|
||||
// Use placement new to ensure all constructors are called correctly
|
||||
return new(memoryBuffer) MESSAGE_STACK;
|
||||
}
|
||||
|
||||
// Free a message stack and all messages in the queue
|
||||
|
|
|
@ -16,19 +16,56 @@
|
|||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
/**
|
||||
@def FORCE_INLINE
|
||||
|
||||
@brief A macro that defines force inline.
|
||||
*/
|
||||
|
||||
#define FORCE_INLINE __forceinline
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
@def ROTL32(x,y) _rotl(x,y)
|
||||
|
||||
@brief A macro that defines rotl 32.
|
||||
|
||||
@param x The void to process.
|
||||
@param y The void to process.
|
||||
*/
|
||||
|
||||
#define ROTL32(x,y) _rotl(x,y)
|
||||
|
||||
/**
|
||||
@def ROTL64(x,y) _rotl64(x,y)
|
||||
|
||||
@brief A macro that defines rotl 64.
|
||||
|
||||
@param x The void to process.
|
||||
@param y The void to process.
|
||||
*/
|
||||
|
||||
#define ROTL64(x,y) _rotl64(x,y)
|
||||
|
||||
/**
|
||||
@def BIG_CONSTANT(x) (x)
|
||||
|
||||
@brief A macro that defines big constant.
|
||||
|
||||
@param x The void to process.
|
||||
*/
|
||||
|
||||
#define BIG_CONSTANT(x) (x)
|
||||
|
||||
// Other compilers
|
||||
|
||||
#else // defined(_MSC_VER)
|
||||
|
||||
/**
|
||||
@brief The force inline.
|
||||
*/
|
||||
|
||||
#define FORCE_INLINE inline __attribute__((always_inline))
|
||||
|
||||
inline uint32_t rotl32(uint32_t x, int8_t r)
|
||||
|
@ -41,29 +78,84 @@ inline uint64_t rotl64(uint64_t x, int8_t r)
|
|||
return (x << r) | (x >> (64 - r));
|
||||
}
|
||||
|
||||
/**
|
||||
@def ROTL32(x,y) rotl32(x,y)
|
||||
|
||||
@brief A macro that defines rotl 32.
|
||||
|
||||
@param x The void to process.
|
||||
@param y The void to process.
|
||||
*/
|
||||
|
||||
#define ROTL32(x,y) rotl32(x,y)
|
||||
|
||||
/**
|
||||
@def ROTL64(x,y) rotl64(x,y)
|
||||
|
||||
@brief A macro that defines rotl 64.
|
||||
|
||||
@param x The void to process.
|
||||
@param y The void to process.
|
||||
*/
|
||||
|
||||
#define ROTL64(x,y) rotl64(x,y)
|
||||
|
||||
/**
|
||||
@def BIG_CONSTANT(x) (x##LLU)
|
||||
|
||||
@brief A macro that defines big constant.
|
||||
|
||||
@param x The void to process.
|
||||
*/
|
||||
|
||||
#define BIG_CONSTANT(x) (x##LLU)
|
||||
|
||||
#endif // !defined(_MSC_VER)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Block read - if your platform needs to do endian-swapping or can only
|
||||
// handle aligned reads, do the conversion here
|
||||
/**
|
||||
@fn FORCE_INLINE uint32_t getblock32(const uint32_t* p, int i)
|
||||
|
||||
@brief -----------------------------------------------------------------------------
|
||||
Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do
|
||||
the conversion here.
|
||||
|
||||
@param p The const uint32_t* to process.
|
||||
@param i Zero-based index of the.
|
||||
|
||||
@return An uint32_t.
|
||||
*/
|
||||
|
||||
FORCE_INLINE uint32_t getblock32(const uint32_t* p, int i)
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
|
||||
/**
|
||||
@fn FORCE_INLINE uint64_t getblock64(const uint64_t* p, int i)
|
||||
|
||||
@brief Getblock 64.
|
||||
|
||||
@param p The const uint64_t* to process.
|
||||
@param i Zero-based index of the.
|
||||
|
||||
@return An uint64_t.
|
||||
*/
|
||||
|
||||
FORCE_INLINE uint64_t getblock64(const uint64_t* p, int i)
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finalization mix - force all bits of a hash block to avalanche
|
||||
/**
|
||||
@fn FORCE_INLINE uint32_t fmix32(uint32_t h)
|
||||
|
||||
@brief -----------------------------------------------------------------------------
|
||||
Finalization mix - force all bits of a hash block to avalanche.
|
||||
|
||||
@param h The uint32_t to process.
|
||||
|
||||
@return An uint32_t.
|
||||
*/
|
||||
|
||||
FORCE_INLINE uint32_t fmix32(uint32_t h)
|
||||
{
|
||||
|
@ -78,6 +170,16 @@ FORCE_INLINE uint32_t fmix32(uint32_t h)
|
|||
|
||||
//----------
|
||||
|
||||
/**
|
||||
@fn FORCE_INLINE uint64_t fmix64(uint64_t k)
|
||||
|
||||
@brief Fmix 64.
|
||||
|
||||
@param k The uint64_t to process.
|
||||
|
||||
@return An uint64_t.
|
||||
*/
|
||||
|
||||
FORCE_INLINE uint64_t fmix64(uint64_t k)
|
||||
{
|
||||
k ^= k >> 33;
|
||||
|
@ -91,6 +193,17 @@ FORCE_INLINE uint64_t fmix64(uint64_t k)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@fn void MurmurHash3_x86_32(const void* key, int len, uint32_t seed, void* out)
|
||||
|
||||
@brief Murmur hash 3 x coordinate 86 32.
|
||||
|
||||
@param key The key.
|
||||
@param len The length.
|
||||
@param seed The seed.
|
||||
@param [in,out] out If non-null, the out.
|
||||
*/
|
||||
|
||||
void MurmurHash3_x86_32(const void* key, int len,
|
||||
uint32_t seed, void* out)
|
||||
{
|
||||
|
@ -153,6 +266,17 @@ void MurmurHash3_x86_32(const void* key, int len,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@fn void MurmurHash3_x86_128(const void* key, const int len, uint32_t seed, void* out)
|
||||
|
||||
@brief Murmur hash 3 x coordinate 86 128.
|
||||
|
||||
@param key The key.
|
||||
@param len The length.
|
||||
@param seed The seed.
|
||||
@param [in,out] out If non-null, the out.
|
||||
*/
|
||||
|
||||
void MurmurHash3_x86_128(const void* key, const int len,
|
||||
uint32_t seed, void* out)
|
||||
{
|
||||
|
@ -316,6 +440,17 @@ void MurmurHash3_x86_128(const void* key, const int len,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@fn void MurmurHash3_x64_128(const void* key, const int len, const uint32_t seed, void* out)
|
||||
|
||||
@brief Murmur hash 3 x coordinate 64 128.
|
||||
|
||||
@param key The key.
|
||||
@param len The length.
|
||||
@param seed The seed.
|
||||
@param [in,out] out If non-null, the out.
|
||||
*/
|
||||
|
||||
void MurmurHash3_x64_128(const void* key, const int len,
|
||||
const uint32_t seed, void* out)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file patches.cpp
|
||||
|
||||
@brief Implements the patches class.
|
||||
*/
|
||||
|
||||
#include "patches.h"
|
||||
#include "addrinfo.h"
|
||||
#include "memory.h"
|
||||
|
|
|
@ -16,7 +16,7 @@ struct PatternByte
|
|||
static string formathexpattern(string patterntext)
|
||||
{
|
||||
string result;
|
||||
int len = patterntext.length();
|
||||
int len = (int)patterntext.length();
|
||||
for(int i = 0; i < len; i++)
|
||||
if(patterntext[i] == '?' || isxdigit(patterntext[i]))
|
||||
result += toupper(patterntext[i]);
|
||||
|
@ -38,7 +38,7 @@ static bool patterntransform(string patterntext, vector<PatternByte> & pattern)
|
|||
{
|
||||
pattern.clear();
|
||||
patterntext = formathexpattern(patterntext);
|
||||
int len = patterntext.length();
|
||||
int len = (int)patterntext.length();
|
||||
if(!len)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -1,16 +1,44 @@
|
|||
/**
|
||||
@file plugin_loader.cpp
|
||||
|
||||
@brief Implements the plugin loader.
|
||||
*/
|
||||
|
||||
#include "plugin_loader.h"
|
||||
#include "console.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
#include "x64_dbg.h"
|
||||
|
||||
/**
|
||||
\brief List of plugins.
|
||||
*/
|
||||
static std::vector<PLUG_DATA> pluginList;
|
||||
|
||||
/**
|
||||
\brief The current plugin handle.
|
||||
*/
|
||||
static int curPluginHandle = 0;
|
||||
|
||||
/**
|
||||
\brief List of plugin callbacks.
|
||||
*/
|
||||
static std::vector<PLUG_CALLBACK> pluginCallbackList;
|
||||
|
||||
/**
|
||||
\brief List of plugin commands.
|
||||
*/
|
||||
static std::vector<PLUG_COMMAND> pluginCommandList;
|
||||
|
||||
/**
|
||||
\brief List of plugin menus.
|
||||
*/
|
||||
static std::vector<PLUG_MENU> pluginMenuList;
|
||||
|
||||
///internal plugin functions
|
||||
/**
|
||||
\brief Loads plugins from a specified directory.
|
||||
\param pluginDir The directory to load plugins from.
|
||||
*/
|
||||
void pluginload(const char* pluginDir)
|
||||
{
|
||||
//load new plugins
|
||||
|
@ -240,6 +268,10 @@ void pluginload(const char* pluginDir)
|
|||
SetCurrentDirectoryW(currentDir);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unregister all plugin commands.
|
||||
\param pluginHandle Handle of the plugin to remove the commands from.
|
||||
*/
|
||||
static void plugincmdunregisterall(int pluginHandle)
|
||||
{
|
||||
int listsize = (int)pluginCommandList.size();
|
||||
|
@ -253,6 +285,9 @@ static void plugincmdunregisterall(int pluginHandle)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unloads all plugins.
|
||||
*/
|
||||
void pluginunload()
|
||||
{
|
||||
int pluginCount = (int)pluginList.size();
|
||||
|
@ -270,7 +305,12 @@ void pluginunload()
|
|||
GuiMenuClear(GUI_PLUGIN_MENU); //clear the plugin menu
|
||||
}
|
||||
|
||||
///debugging plugin exports
|
||||
/**
|
||||
\brief Register a plugin callback.
|
||||
\param pluginHandle Handle of the plugin to register a callback for.
|
||||
\param cbType The type of the callback to register.
|
||||
\param cbPlugin The actual callback function.
|
||||
*/
|
||||
void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin)
|
||||
{
|
||||
pluginunregistercallback(pluginHandle, cbType); //remove previous callback
|
||||
|
@ -281,6 +321,11 @@ void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin)
|
|||
pluginCallbackList.push_back(cbStruct);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unregister all plugin callbacks of a certain type.
|
||||
\param pluginHandle Handle of the plugin to unregister a callback from.
|
||||
\param cbType The type of the callback to unregister.
|
||||
*/
|
||||
bool pluginunregistercallback(int pluginHandle, CBTYPE cbType)
|
||||
{
|
||||
int pluginCallbackCount = (int)pluginCallbackList.size();
|
||||
|
@ -295,6 +340,11 @@ bool pluginunregistercallback(int pluginHandle, CBTYPE cbType)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Call all registered callbacks of a certain type.
|
||||
\param cbType The type of callbacks to call.
|
||||
\param [in,out] callbackInfo Information describing the callback. See plugin documentation for more information on this.
|
||||
*/
|
||||
void plugincbcall(CBTYPE cbType, void* callbackInfo)
|
||||
{
|
||||
int pluginCallbackCount = (int)pluginCallbackList.size();
|
||||
|
@ -303,12 +353,20 @@ void plugincbcall(CBTYPE cbType, void* callbackInfo)
|
|||
if(pluginCallbackList.at(i).cbType == cbType)
|
||||
{
|
||||
CBPLUGIN cbPlugin = pluginCallbackList.at(i).cbPlugin;
|
||||
if(!IsBadReadPtr((const void*)cbPlugin, sizeof(uint)))
|
||||
if(!IsBadReadPtr((const void *)cbPlugin, sizeof(uint)))
|
||||
cbPlugin(cbType, callbackInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Register a plugin command.
|
||||
\param pluginHandle Handle of the plugin to register a command for.
|
||||
\param command The command text to register. This text cannot contain the '\1' character. This text is not case sensitive.
|
||||
\param cbCommand The command callback.
|
||||
\param debugonly true if the command can only be called during debugging.
|
||||
\return true if it the registration succeeded, false otherwise.
|
||||
*/
|
||||
bool plugincmdregister(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly)
|
||||
{
|
||||
if(!command or strlen(command) >= deflen or strstr(command, "\1"))
|
||||
|
@ -323,6 +381,12 @@ bool plugincmdregister(int pluginHandle, const char* command, CBPLUGINCOMMAND cb
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unregister a plugin command.
|
||||
\param pluginHandle Handle of the plugin to unregister the command from.
|
||||
\param command The command text to unregister. This text is not case sensitive.
|
||||
\return true if the command was found and removed, false otherwise.
|
||||
*/
|
||||
bool plugincmdunregister(int pluginHandle, const char* command)
|
||||
{
|
||||
if(!command or strlen(command) >= deflen or strstr(command, "\1"))
|
||||
|
@ -342,6 +406,12 @@ bool plugincmdunregister(int pluginHandle, const char* command)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Add a new plugin (sub)menu.
|
||||
\param hMenu The menu handle to add the (sub)menu to.
|
||||
\param title The title of the (sub)menu.
|
||||
\return The handle of the new (sub)menu.
|
||||
*/
|
||||
int pluginmenuadd(int hMenu, const char* title)
|
||||
{
|
||||
if(!title or !strlen(title))
|
||||
|
@ -366,6 +436,13 @@ int pluginmenuadd(int hMenu, const char* title)
|
|||
return hMenuNew;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Add a plugin menu entry to a menu.
|
||||
\param hMenu The menu to add the entry to.
|
||||
\param hEntry The handle you like to have the entry. This should be a unique value in the scope of the plugin that registered the \p hMenu.
|
||||
\param title The menu entry title.
|
||||
\return true if the \p hEntry was unique and the entry was successfully added, false otherwise.
|
||||
*/
|
||||
bool pluginmenuaddentry(int hMenu, int hEntry, const char* title)
|
||||
{
|
||||
if(!title or !strlen(title) or hEntry == -1)
|
||||
|
@ -397,6 +474,11 @@ bool pluginmenuaddentry(int hMenu, int hEntry, const char* title)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Add a menu separator to a menu.
|
||||
\param hMenu The menu to add the separator to.
|
||||
\return true if it succeeds, false otherwise.
|
||||
*/
|
||||
bool pluginmenuaddseparator(int hMenu)
|
||||
{
|
||||
bool bFound = false;
|
||||
|
@ -414,6 +496,11 @@ bool pluginmenuaddseparator(int hMenu)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Clears a plugin menu.
|
||||
\param hMenu The menu to clear.
|
||||
\return true if it succeeds, false otherwise.
|
||||
*/
|
||||
bool pluginmenuclear(int hMenu)
|
||||
{
|
||||
bool bFound = false;
|
||||
|
@ -431,6 +518,10 @@ bool pluginmenuclear(int hMenu)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Call the registered CB_MENUENTRY callbacks for a menu entry.
|
||||
\param hEntry The menu entry that triggered the event.
|
||||
*/
|
||||
void pluginmenucall(int hEntry)
|
||||
{
|
||||
if(hEntry == -1)
|
||||
|
@ -456,6 +547,12 @@ void pluginmenucall(int hEntry)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calls the registered CB_WINEVENT callbacks.
|
||||
\param [in,out] message the message that triggered the event. Cannot be null.
|
||||
\param [out] result The result value. Cannot be null.
|
||||
\return The value the plugin told it to return. See plugin documentation for more information.
|
||||
*/
|
||||
bool pluginwinevent(MSG* message, long* result)
|
||||
{
|
||||
PLUG_CB_WINEVENT winevent;
|
||||
|
@ -466,6 +563,11 @@ bool pluginwinevent(MSG* message, long* result)
|
|||
return winevent.retval;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Calls the registered CB_WINEVENTGLOBAL callbacks.
|
||||
\param [in,out] message the message that triggered the event. Cannot be null.
|
||||
\return The value the plugin told it to return. See plugin documentation for more information.
|
||||
*/
|
||||
bool pluginwineventglobal(MSG* message)
|
||||
{
|
||||
PLUG_CB_WINEVENTGLOBAL winevent;
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file reference.cpp
|
||||
|
||||
@brief Implements the reference class.
|
||||
*/
|
||||
|
||||
#include "reference.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file simplescript.cpp
|
||||
|
||||
@brief Implements the simplescript class.
|
||||
*/
|
||||
|
||||
#include "simplescript.h"
|
||||
#include "value.h"
|
||||
#include "console.h"
|
||||
|
@ -8,10 +14,15 @@
|
|||
#include "debugger.h"
|
||||
|
||||
static std::vector<LINEMAPENTRY> linemap;
|
||||
|
||||
static std::vector<SCRIPTBP> scriptbplist;
|
||||
|
||||
static std::vector<int> scriptstack;
|
||||
|
||||
static int scriptIp = 0;
|
||||
|
||||
static bool volatile bAbort = false;
|
||||
|
||||
static bool volatile bIsRunning = false;
|
||||
|
||||
static SCRIPTBRANCHTYPE scriptgetbranchtype(const char* text)
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file stackinfo.cpp
|
||||
|
||||
@brief Implements the stackinfo class.
|
||||
*/
|
||||
|
||||
#include "stackinfo.h"
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file symbolinfo.cpp
|
||||
|
||||
@brief Implements the symbolinfo class.
|
||||
*/
|
||||
|
||||
#include "symbolinfo.h"
|
||||
#include "debugger.h"
|
||||
#include "addrinfo.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file thread.cpp
|
||||
|
||||
@brief Implements the thread class.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
#include "console.h"
|
||||
#include "undocumented.h"
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file value.cpp
|
||||
|
||||
@brief Implements the value class.
|
||||
*/
|
||||
|
||||
#include "value.h"
|
||||
#include "variable.h"
|
||||
#include "debugger.h"
|
||||
|
@ -11,16 +17,29 @@
|
|||
|
||||
static bool dosignedcalc = false;
|
||||
|
||||
/**
|
||||
\brief Returns whether we do signed or unsigned calculations.
|
||||
\return true if we do signed calculations, false for unsigned calculationss.
|
||||
*/
|
||||
bool valuesignedcalc()
|
||||
{
|
||||
return dosignedcalc;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set whether we do signed or unsigned calculations.
|
||||
\param a true for signed calculations, false for unsigned calculations.
|
||||
*/
|
||||
void valuesetsignedcalc(bool a)
|
||||
{
|
||||
dosignedcalc = a;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Check if a string is a flag.
|
||||
\param string The string to check.
|
||||
\return true if the string is a flag, false otherwise.
|
||||
*/
|
||||
static bool isflag(const char* string)
|
||||
{
|
||||
if(scmp(string, "cf"))
|
||||
|
@ -56,6 +75,11 @@ static bool isflag(const char* string)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Check if a string is a register.
|
||||
\param string The string to check.
|
||||
\return true if the string is a register, false otherwise.
|
||||
*/
|
||||
static bool isregister(const char* string)
|
||||
{
|
||||
if(scmp(string, "eax"))
|
||||
|
@ -282,7 +306,12 @@ typedef struct
|
|||
|
||||
#define MXCSR_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, MXCSRFLAG_##flag_name }
|
||||
|
||||
unsigned int getmxcsrflagfromstring(const char* string)
|
||||
/**
|
||||
\brief Gets the MXCSR flag AND value from a string.
|
||||
\param string The flag name.
|
||||
\return The value to AND the MXCSR value with to get the flag. 0 when not found.
|
||||
*/
|
||||
static unsigned int getmxcsrflagfromstring(const char* string)
|
||||
{
|
||||
static FLAG_NAME_VALUE_TABLE_t mxcsrnameflagtable[] =
|
||||
{
|
||||
|
@ -301,9 +330,8 @@ unsigned int getmxcsrflagfromstring(const char* string)
|
|||
MXCSR_NAME_FLAG_TABLE_ENTRY(PM),
|
||||
MXCSR_NAME_FLAG_TABLE_ENTRY(FZ)
|
||||
};
|
||||
int i;
|
||||
|
||||
for(i = 0; i < (sizeof(mxcsrnameflagtable) / sizeof(*mxcsrnameflagtable)); i++)
|
||||
for(int i = 0; i < (sizeof(mxcsrnameflagtable) / sizeof(*mxcsrnameflagtable)); i++)
|
||||
{
|
||||
if(scmp(string, mxcsrnameflagtable[i].name))
|
||||
return mxcsrnameflagtable[i].flag;
|
||||
|
@ -312,6 +340,12 @@ unsigned int getmxcsrflagfromstring(const char* string)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets the MXCSR flag from a string and a flags value.
|
||||
\param mxcsrflags The flags value to get the flag from.
|
||||
\param string The string with the flag name.
|
||||
\return true if the flag is 1, false if the flag is 0.
|
||||
*/
|
||||
bool valmxcsrflagfromstring(uint mxcsrflags, const char* string)
|
||||
{
|
||||
unsigned int flag = getmxcsrflagfromstring(string);
|
||||
|
@ -337,7 +371,12 @@ bool valmxcsrflagfromstring(uint mxcsrflags, const char* string)
|
|||
|
||||
#define X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87STATUSWORD_FLAG_##flag_name }
|
||||
|
||||
unsigned int getx87statuswordflagfromstring(const char* string)
|
||||
/**
|
||||
\brief Gets the x87 status word AND value from a string.
|
||||
\param string The status word name.
|
||||
\return The value to AND the status word with to get the flag. 0 when not found.
|
||||
*/
|
||||
static unsigned int getx87statuswordflagfromstring(const char* string)
|
||||
{
|
||||
static FLAG_NAME_VALUE_TABLE_t statuswordflagtable[] =
|
||||
{
|
||||
|
@ -355,9 +394,8 @@ unsigned int getx87statuswordflagfromstring(const char* string)
|
|||
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C3),
|
||||
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(B)
|
||||
};
|
||||
int i;
|
||||
|
||||
for(i = 0; i < (sizeof(statuswordflagtable) / sizeof(*statuswordflagtable)); i++)
|
||||
for(int i = 0; i < (sizeof(statuswordflagtable) / sizeof(*statuswordflagtable)); i++)
|
||||
{
|
||||
if(scmp(string, statuswordflagtable[i].name))
|
||||
return statuswordflagtable[i].flag;
|
||||
|
@ -366,6 +404,12 @@ unsigned int getx87statuswordflagfromstring(const char* string)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets an x87 status flag from a string.
|
||||
\param statusword The status word value.
|
||||
\param string The flag name.
|
||||
\return true if the flag is 1, false if the flag is 0.
|
||||
*/
|
||||
bool valx87statuswordflagfromstring(uint statusword, const char* string)
|
||||
{
|
||||
unsigned int flag = getx87statuswordflagfromstring(string);
|
||||
|
@ -386,7 +430,12 @@ bool valx87statuswordflagfromstring(uint statusword, const char* string)
|
|||
|
||||
#define X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87CONTROLWORD_FLAG_##flag_name }
|
||||
|
||||
unsigned int getx87controlwordflagfromstring(const char* string)
|
||||
/**
|
||||
\brief Gets the x87 control word flag AND value from a string.
|
||||
\param string The name of the control word.
|
||||
\return The value to AND the control word with to get the flag. 0 when not found.
|
||||
*/
|
||||
static unsigned int getx87controlwordflagfromstring(const char* string)
|
||||
{
|
||||
static FLAG_NAME_VALUE_TABLE_t controlwordflagtable[] =
|
||||
{
|
||||
|
@ -399,9 +448,8 @@ unsigned int getx87controlwordflagfromstring(const char* string)
|
|||
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IEM),
|
||||
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IC)
|
||||
};
|
||||
int i;
|
||||
|
||||
for(i = 0; i < (sizeof(controlwordflagtable) / sizeof(*controlwordflagtable)); i++)
|
||||
for(int i = 0; i < (sizeof(controlwordflagtable) / sizeof(*controlwordflagtable)); i++)
|
||||
{
|
||||
if(scmp(string, controlwordflagtable[i].name))
|
||||
return controlwordflagtable[i].flag;
|
||||
|
@ -410,6 +458,12 @@ unsigned int getx87controlwordflagfromstring(const char* string)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get an x87 control word flag from a string.
|
||||
\param controlword The control word to get the flag from.
|
||||
\param string The flag name.
|
||||
\return true if the flag is 1, false when the flag is 0.
|
||||
*/
|
||||
bool valx87controlwordflagfromstring(uint controlword, const char* string)
|
||||
{
|
||||
unsigned int flag = getx87controlwordflagfromstring(string);
|
||||
|
@ -420,6 +474,12 @@ bool valx87controlwordflagfromstring(uint controlword, const char* string)
|
|||
return (bool)((int)(controlword & flag) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets the MXCSR field from a string.
|
||||
\param mxcsrflags The mxcsrflags to get the field from.
|
||||
\param string The name of the field (should be "RC").
|
||||
\return The MXCSR field word.
|
||||
*/
|
||||
unsigned short valmxcsrfieldfromstring(uint mxcsrflags, const char* string)
|
||||
{
|
||||
if(scmp(string, "RC"))
|
||||
|
@ -428,6 +488,12 @@ unsigned short valmxcsrfieldfromstring(uint mxcsrflags, const char* string)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets the x87 status word field from a string.
|
||||
\param statusword The status word to get the field from.
|
||||
\param string The name of the field (should be "TOP").
|
||||
\return The x87 status word field.
|
||||
*/
|
||||
unsigned short valx87statuswordfieldfromstring(uint statusword, const char* string)
|
||||
{
|
||||
if(scmp(string, "TOP"))
|
||||
|
@ -436,6 +502,12 @@ unsigned short valx87statuswordfieldfromstring(uint statusword, const char* stri
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets the x87 control word field from a string.
|
||||
\param controlword The control word to get the field from.
|
||||
\param string The name of the field.
|
||||
\return The x87 control word field.
|
||||
*/
|
||||
unsigned short valx87controlwordfieldfromstring(uint controlword, const char* string)
|
||||
{
|
||||
if(scmp(string, "PC"))
|
||||
|
@ -446,6 +518,12 @@ unsigned short valx87controlwordfieldfromstring(uint controlword, const char* st
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets a flag from a string.
|
||||
\param eflags The eflags value to get the flag from.
|
||||
\param string The name of the flag.
|
||||
\return true if the flag equals to 1, false if the flag is 0 or not found.
|
||||
*/
|
||||
bool valflagfromstring(uint eflags, const char* string)
|
||||
{
|
||||
if(scmp(string, "cf"))
|
||||
|
@ -481,6 +559,12 @@ bool valflagfromstring(uint eflags, const char* string)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Sets a flag value.
|
||||
\param string The name of the flag.
|
||||
\param set The value of the flag.
|
||||
\return true if the flag was successfully set, false otherwise.
|
||||
*/
|
||||
static bool setflag(const char* string, bool set)
|
||||
{
|
||||
uint eflags = GetContextDataEx(hActiveThread, UE_CFLAGS);
|
||||
|
@ -523,6 +607,12 @@ static bool setflag(const char* string, bool set)
|
|||
return SetContextDataEx(hActiveThread, UE_CFLAGS, eflags ^ xorval);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets a register from a string.
|
||||
\param [out] size This function can store the register size in bytes in this parameter. Can be null, in that case it will be ignored.
|
||||
\param string The name of the register to get.
|
||||
\return The register value.
|
||||
*/
|
||||
static uint getregister(int* size, const char* string)
|
||||
{
|
||||
if(size)
|
||||
|
@ -961,6 +1051,12 @@ static uint getregister(int* size, const char* string)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Sets a register value based on the register name.
|
||||
\param string The name of the register to set.
|
||||
\param value The new register value.
|
||||
\return true if the register was set, false otherwise.
|
||||
*/
|
||||
static bool setregister(const char* string, uint value)
|
||||
{
|
||||
if(scmp(string, "eax"))
|
||||
|
@ -1165,6 +1261,16 @@ static bool setregister(const char* string, uint value)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets the address of an API from a name.
|
||||
\param name The name of the API, see the command help for more information about valid constructions.
|
||||
\param [out] value The address of the retrieved API. Cannot be null.
|
||||
\param [out] value_size This function sets this value to the size of the address, sizeof(uint).
|
||||
\param printall true to print all possible API values to the console.
|
||||
\param silent true to have no console output. If true, the \p printall parameter is ignored.
|
||||
\param [out] hexonly If set to true, the values should be printed in hex only. Usually this function sets it to true.
|
||||
\return true if the API was found and a value retrieved, false otherwise.
|
||||
*/
|
||||
bool valapifromstring(const char* name, uint* value, int* value_size, bool printall, bool silent, bool* hexonly)
|
||||
{
|
||||
if(!value or !DbgIsDebugging())
|
||||
|
@ -1338,8 +1444,10 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
check whether a string is a valid dec number
|
||||
/**
|
||||
\brief Check if a string is a valid decimal number. This function also accepts "-" or "." as prefix.
|
||||
\param string The string to check.
|
||||
\return true if the string is a valid decimal number.
|
||||
*/
|
||||
static bool isdecnumber(const char* string)
|
||||
{
|
||||
|
@ -1359,8 +1467,10 @@ static bool isdecnumber(const char* string)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
check whether a string is a valid hex number
|
||||
/**
|
||||
\brief Check if a string is a valid hexadecimal number. This function also accepts "0x" or "x" as prefix.
|
||||
\param string The string to check.
|
||||
\return true if the string is a valid hexadecimal number.
|
||||
*/
|
||||
static bool ishexnumber(const char* string)
|
||||
{
|
||||
|
@ -1378,6 +1488,17 @@ static bool ishexnumber(const char* string)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets a value from a string. This function can parse expressions, memory locations, registers, flags, API names, labels, symbols and variables.
|
||||
\param string The string to parse.
|
||||
\param [out] value The value of the expression. This value cannot be null.
|
||||
\param silent true to not output anything to the console.
|
||||
\param baseonly true to skip parsing API names, labels, symbols and variables (basic expressions only).
|
||||
\param [out] value_size This function can output the value size parsed (for example memory location size or register size). Can be null.
|
||||
\param [out] isvar This function can output if the expression is variable (for example memory locations, registers or variables are variable). Can be null.
|
||||
\param [out] hexonly This function can output if the output value should only be printed as hexadecimal (for example addresses). Can be null.
|
||||
\return true if the expression was parsed successfull, false otherwise.
|
||||
*/
|
||||
bool valfromstring(const char* string, uint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly)
|
||||
{
|
||||
if(!value or !string)
|
||||
|
@ -1572,6 +1693,12 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
return false; //nothing was OK
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Checks if a string is long enough.
|
||||
\param str The string to check.
|
||||
\param min_length The minimum length of \p str.
|
||||
\return true if the string is long enough, false otherwise.
|
||||
*/
|
||||
static bool longEnough(const char* str, size_t min_length)
|
||||
{
|
||||
size_t length = 0;
|
||||
|
@ -1582,6 +1709,12 @@ static bool longEnough(const char* str, size_t min_length)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Checks if a string starts with another string.
|
||||
\param pre The desired prefix of the string.
|
||||
\param str The complete string.
|
||||
\return true if \p str starts with \p pre.
|
||||
*/
|
||||
static bool startsWith(const char* pre, const char* str)
|
||||
{
|
||||
size_t lenpre = strlen(pre);
|
||||
|
@ -1598,7 +1731,12 @@ static bool startsWith(const char* pre, const char* str)
|
|||
#define x8780BITFPU_PRE_FIELD_STRING "x87r"
|
||||
#define STRLEN_USING_SIZEOF(string) (sizeof(string) - 1)
|
||||
|
||||
static void fpustuff(const char* string, uint value)
|
||||
/**
|
||||
\brief Sets an FPU value (MXCSR fields, MMX fields, etc.) by name.
|
||||
\param string The name of the FPU value to set.
|
||||
\param value The value to set.
|
||||
*/
|
||||
static void setfpuvalue(const char* string, uint value)
|
||||
{
|
||||
uint xorval = 0;
|
||||
uint flags = 0;
|
||||
|
@ -1978,9 +2116,16 @@ static void fpustuff(const char* string, uint value)
|
|||
}
|
||||
}
|
||||
|
||||
bool valtostring(const char* string, uint* value, bool silent)
|
||||
/**
|
||||
\brief Sets a register, variable, flag, memory location or FPU value by name.
|
||||
\param string The name of the thing to set.
|
||||
\param value The value to set.
|
||||
\param silent true to not have output to the console.
|
||||
\return true if the value was set successfully, false otherwise.
|
||||
*/
|
||||
bool valtostring(const char* string, uint value, bool silent)
|
||||
{
|
||||
if(!*string or !value)
|
||||
if(!*string)
|
||||
return false;
|
||||
else if(*string == '@' or strstr(string, "[")) //memory location
|
||||
{
|
||||
|
@ -2025,7 +2170,8 @@ bool valtostring(const char* string, uint* value, bool silent)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if(!MemPatch((void*)temp, value, read_size, 0))
|
||||
uint value_ = value;
|
||||
if(!MemPatch((void*)temp, &value_, read_size, 0))
|
||||
{
|
||||
if(!silent)
|
||||
dputs("failed to write memory");
|
||||
|
@ -2043,7 +2189,7 @@ bool valtostring(const char* string, uint* value, bool silent)
|
|||
dputs("not debugging!");
|
||||
return false;
|
||||
}
|
||||
bool ok = setregister(string, *value);
|
||||
bool ok = setregister(string, value);
|
||||
int len = (int)strlen(string);
|
||||
Memory<char*> regName(len + 1, "valtostring:regname");
|
||||
strcpy_s(regName, len + 1, string);
|
||||
|
@ -2060,7 +2206,7 @@ bool valtostring(const char* string, uint* value, bool silent)
|
|||
GuiUpdateAllViews(); //repaint gui
|
||||
return ok;
|
||||
}
|
||||
else if((*string == '_'))
|
||||
else if((*string == '_')) //FPU values
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
{
|
||||
|
@ -2068,9 +2214,8 @@ bool valtostring(const char* string, uint* value, bool silent)
|
|||
dputs("not debugging!");
|
||||
return false;
|
||||
}
|
||||
fpustuff(string + 1, * value);
|
||||
setfpuvalue(string + 1, value);
|
||||
GuiUpdateAllViews(); //repaint gui
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(*string == '!' and isflag(string + 1)) //flag
|
||||
|
@ -2082,15 +2227,21 @@ bool valtostring(const char* string, uint* value, bool silent)
|
|||
return false;
|
||||
}
|
||||
bool set = false;
|
||||
if(*value)
|
||||
if(value)
|
||||
set = true;
|
||||
setflag(string + 1, set);
|
||||
GuiUpdateAllViews(); //repaint gui
|
||||
return true;
|
||||
}
|
||||
return varset(string, *value, false); //variable
|
||||
return varset(string, value, false); //variable
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Converts a file offset to a virtual address.
|
||||
\param modname The name (not the path) of the module the file offset is in.
|
||||
\param offset The file offset.
|
||||
\return The VA of the file offset, 0 when there was a problem with the conversion.
|
||||
*/
|
||||
uint valfileoffsettova(const char* modname, uint offset)
|
||||
{
|
||||
char modpath[MAX_PATH] = "";
|
||||
|
@ -2112,6 +2263,11 @@ uint valfileoffsettova(const char* modname, uint offset)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Converts a virtual address to a file offset.
|
||||
\param va The virtual address (must be inside a module).
|
||||
\return The file offset. 0 when there was a problem with the conversion.
|
||||
*/
|
||||
uint valvatofileoffset(uint va)
|
||||
{
|
||||
char modpath[MAX_PATH] = "";
|
||||
|
|
|
@ -9,7 +9,7 @@ void valuesetsignedcalc(bool a);
|
|||
bool valapifromstring(const char* name, uint* value, int* value_size, bool printall, bool silent, bool* hexonly);
|
||||
bool valfromstring(const char* string, uint* value, bool silent = true, bool baseonly = false, int* value_size = 0, bool* isvar = 0, bool* hexonly = 0);
|
||||
bool valflagfromstring(uint eflags, const char* string);
|
||||
bool valtostring(const char* string, uint* value, bool silent);
|
||||
bool valtostring(const char* string, uint value, bool silent);
|
||||
bool valmxcsrflagfromstring(uint mxcsrflags, const char* string);
|
||||
bool valx87statuswordflagfromstring(uint statusword, const char* string);
|
||||
bool valx87controlwordflagfromstring(uint controlword, const char* string);
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
/**
|
||||
@file variable.cpp
|
||||
|
||||
@brief Implements the variable class.
|
||||
*/
|
||||
|
||||
#include "variable.h"
|
||||
#include "threading.h"
|
||||
|
||||
/**
|
||||
\brief The container that stores the variables.
|
||||
*/
|
||||
static VariableMap variables;
|
||||
static VAR* vars;
|
||||
|
||||
/**
|
||||
\brief Sets a variable with a value.
|
||||
\param [in,out] var The variable to set the value of. The previous value will be freed. Cannot be null.
|
||||
\param [in] value The new value. Cannot be null.
|
||||
*/
|
||||
static void varsetvalue(VAR* var, VAR_VALUE* value)
|
||||
{
|
||||
// VAR_STRING needs to be freed before destroying it
|
||||
|
@ -17,6 +30,13 @@ static void varsetvalue(VAR* var, VAR_VALUE* value)
|
|||
memcpy(&var->value, value, sizeof(VAR_VALUE));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Sets a variable by name.
|
||||
\param name The name of the variable. Cannot be null.
|
||||
\param value The new value. Cannot be null.
|
||||
\param setreadonly true to set read-only variables (like $hProcess etc.).
|
||||
\return true if the variable was set correctly, false otherwise.
|
||||
*/
|
||||
static bool varset(const char* name, VAR_VALUE* value, bool setreadonly)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
@ -42,6 +62,9 @@ static bool varset(const char* name, VAR_VALUE* value, bool setreadonly)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Initializes various default variables.
|
||||
*/
|
||||
void varinit()
|
||||
{
|
||||
varfree();
|
||||
|
@ -66,6 +89,9 @@ void varinit()
|
|||
varnew("$_BS_FLAG", 0, VAR_READONLY); // Bigger/smaller flag for internal use (1=bigger, 0=smaller)
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Clears all variables.
|
||||
*/
|
||||
void varfree()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
@ -81,12 +107,13 @@ void varfree()
|
|||
variables.clear();
|
||||
}
|
||||
|
||||
VAR* vargetptr()
|
||||
{
|
||||
// TODO: Implement this? Or remove it
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Creates a new variable.
|
||||
\param name The name of the variable. You can specify alias names by separating the names by '\1'. Cannot be null.
|
||||
\param value The new variable value.
|
||||
\param type The variable type.
|
||||
\return true if the new variables was created and set successfully, false otherwise.
|
||||
*/
|
||||
bool varnew(const char* name, uint value, VAR_TYPE type)
|
||||
{
|
||||
if(!name)
|
||||
|
@ -120,6 +147,14 @@ bool varnew(const char* name, uint value, VAR_TYPE type)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets a variable value.
|
||||
\param name The name of the variable.
|
||||
\param [out] value This function can get the variable value. If this value is null, it is ignored.
|
||||
\param [out] size This function can get the variable size. If this value is null, it is ignored.
|
||||
\param [out] type This function can get the variable type. If this value is null, it is ignored.
|
||||
\return true if the variable was found and the optional values were retrieved successfully, false otherwise.
|
||||
*/
|
||||
static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type)
|
||||
{
|
||||
SHARED_ACQUIRE(LockVariables);
|
||||
|
@ -147,6 +182,14 @@ static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets a variable value.
|
||||
\param name The name of the variable.
|
||||
\param [out] value This function can get the variable value. If this value is null, it is ignored.
|
||||
\param [out] size This function can get the variable size. If this value is null, it is ignored.
|
||||
\param [out] type This function can get the variable type. If this value is null, it is ignored.
|
||||
\return true if the variable was found and the optional values were retrieved successfully, false otherwise.
|
||||
*/
|
||||
bool varget(const char* name, uint* value, int* size, VAR_TYPE* type)
|
||||
{
|
||||
VAR_VALUE varvalue;
|
||||
|
@ -165,6 +208,14 @@ bool varget(const char* name, uint* value, int* size, VAR_TYPE* type)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets a variable value.
|
||||
\param name The name of the variable.
|
||||
\param [out] string This function can get the variable value. If this value is null, it is ignored.
|
||||
\param [out] size This function can get the variable size. If this value is null, it is ignored.
|
||||
\param [out] type This function can get the variable type. If this value is null, it is ignored.
|
||||
\return true if the variable was found and the optional values were retrieved successfully, false otherwise.
|
||||
*/
|
||||
bool varget(const char* name, char* string, int* size, VAR_TYPE* type)
|
||||
{
|
||||
VAR_VALUE varvalue;
|
||||
|
@ -179,10 +230,17 @@ bool varget(const char* name, char* string, int* size, VAR_TYPE* type)
|
|||
if(type)
|
||||
*type = vartype;
|
||||
if(string)
|
||||
memcpy(string, &varvalue.u.data->front(), varsize);
|
||||
memcpy(string, varvalue.u.data->data(), varsize);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Sets a variable by name.
|
||||
\param name The name of the variable. Cannot be null.
|
||||
\param value The new value.
|
||||
\param setreadonly true to set read-only variables (like $hProcess etc.).
|
||||
\return true if the variable was set successfully, false otherwise.
|
||||
*/
|
||||
bool varset(const char* name, uint value, bool setreadonly)
|
||||
{
|
||||
VAR_VALUE varvalue;
|
||||
|
@ -192,6 +250,13 @@ bool varset(const char* name, uint value, bool setreadonly)
|
|||
return varset(name, &varvalue, setreadonly);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Sets a variable by name.
|
||||
\param name The name of the variable. Cannot be null.
|
||||
\param string The new value. Cannot be null.
|
||||
\param setreadonly true to set read-only variables (like $hProcess etc.).
|
||||
\return true if the variable was set successfully, false otherwise.
|
||||
*/
|
||||
bool varset(const char* name, const char* string, bool setreadonly)
|
||||
{
|
||||
VAR_VALUE varvalue;
|
||||
|
@ -210,6 +275,12 @@ bool varset(const char* name, const char* string, bool setreadonly)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Deletes a variable.
|
||||
\param name The name of the variable to delete. Cannot be null.
|
||||
\param delsystem true to allow deleting system variables.
|
||||
\return true if the variable was deleted successfully, false otherwise.
|
||||
*/
|
||||
bool vardel(const char* name, bool delsystem)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
@ -242,6 +313,13 @@ bool vardel(const char* name, bool delsystem)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets a variable type.
|
||||
\param name The name of the variable. Cannot be null.
|
||||
\param [out] type This function can retrieve the variable type. If null it is ignored.
|
||||
\param [out] valtype This function can retrieve the variable value type. If null it is ignored.
|
||||
\return true if getting the type was successful, false otherwise.
|
||||
*/
|
||||
bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype)
|
||||
{
|
||||
SHARED_ACQUIRE(LockVariables);
|
||||
|
@ -262,6 +340,12 @@ bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Enumerates all variables.
|
||||
\param [in,out] entries A pointer to place the variables in. If null, \p cbsize will be filled to the number of bytes required.
|
||||
\param [in,out] cbsize This function retrieves the number of bytes required to store all variables. Can be null if \p entries is not null.
|
||||
\return true if it succeeds, false if it fails.
|
||||
*/
|
||||
bool varenum(VAR* List, size_t* Size)
|
||||
{
|
||||
// A list or size must be requested
|
||||
|
|
|
@ -51,7 +51,6 @@ typedef std::map<String, VAR, CaseInsensitiveCompare> VariableMap;
|
|||
//functions
|
||||
void varinit();
|
||||
void varfree();
|
||||
VAR* vargetptr();
|
||||
bool varnew(const char* name, uint value, VAR_TYPE type);
|
||||
bool varget(const char* name, uint* value, int* size, VAR_TYPE* type);
|
||||
bool varget(const char* name, char* string, int* size, VAR_TYPE* type);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/**
|
||||
@file x64_dbg.cpp
|
||||
|
||||
@brief Implements the 64 debug class.
|
||||
*/
|
||||
|
||||
#include "_global.h"
|
||||
#include "argument.h"
|
||||
#include "command.h"
|
||||
|
@ -17,8 +23,11 @@
|
|||
#include "debugger_commands.h"
|
||||
|
||||
static MESSAGE_STACK* gMsgStack = 0;
|
||||
|
||||
static COMMAND* command_list = 0;
|
||||
|
||||
static HANDLE hCommandLoopThread = 0;
|
||||
|
||||
static char alloctrace[MAX_PATH] = "";
|
||||
|
||||
static CMDRESULT cbStrLen(int argc, char* argv[])
|
||||
|
@ -189,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)
|
||||
|
@ -236,10 +247,12 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
return "Invalid TITAN_ENGINE_CONTEXT_t alignment!";
|
||||
if(sizeof(TITAN_ENGINE_CONTEXT_t) != sizeof(REGISTERCONTEXT))
|
||||
return "Invalid REGISTERCONTEXT alignment!";
|
||||
SectionLockerGlobal::Initialize();
|
||||
SectionLockerGlobal::Initialize();
|
||||
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!";
|
||||
|
@ -307,6 +320,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
|
|||
cmdfree(command_list);
|
||||
varfree();
|
||||
MsgFreeStack(gMsgStack);
|
||||
yr_finalize();
|
||||
if(memleaks())
|
||||
{
|
||||
char msg[256] = "";
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Interfaces/Exports">
|
||||
<UniqueIdentifier>{44fd9eb7-2017-49b8-8d9a-dec680632343}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
@ -63,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">
|
||||
|
@ -367,5 +377,95 @@
|
|||
<ClInclude Include="dbghelp_safe.h">
|
||||
<Filter>Header Files\Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara.h">
|
||||
<Filter>Header Files\Third Party\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\ahocorasick.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\arena.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\atoms.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\compiler.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\elf.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\error.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\exec.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\exefiles.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\filemap.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\globals.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\hash.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\hex_lexer.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\lexer.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\libyara.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\limits.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\mem.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\modules.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\object.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\parser.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\pe.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\proc.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\re.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\re_lexer.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\rules.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\scan.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\sizedstr.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\strutils.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\types.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="yara\yara\utils.h">
|
||||
<Filter>Header Files\Third Party\yara\yara</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright (c) 2007-2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_YARA_H
|
||||
#define YR_YARA_H
|
||||
|
||||
#include "yara/utils.h"
|
||||
#include "yara/filemap.h"
|
||||
#include "yara/compiler.h"
|
||||
#include "yara/modules.h"
|
||||
#include "yara/object.h"
|
||||
#include "yara/libyara.h"
|
||||
#include "yara/error.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _AHOCORASICK_H
|
||||
#define _AHOCORASICK_H
|
||||
|
||||
#include "limits.h"
|
||||
#include "atoms.h"
|
||||
#include "types.h"
|
||||
|
||||
|
||||
int yr_ac_create_automaton(
|
||||
YR_ARENA* arena,
|
||||
YR_AC_AUTOMATON** automaton);
|
||||
|
||||
|
||||
int yr_ac_add_string(
|
||||
YR_ARENA* arena,
|
||||
YR_AC_AUTOMATON* automaton,
|
||||
YR_STRING* string,
|
||||
YR_ATOM_LIST_ITEM* atom);
|
||||
|
||||
|
||||
YR_AC_STATE* yr_ac_next_state(
|
||||
YR_AC_STATE* state,
|
||||
uint8_t input);
|
||||
|
||||
|
||||
int yr_ac_create_failure_links(
|
||||
YR_ARENA* arena,
|
||||
YR_AC_AUTOMATON* automaton);
|
||||
|
||||
|
||||
void yr_ac_print_automaton(
|
||||
YR_AC_AUTOMATON* automaton);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_ARENA_H
|
||||
#define YR_ARENA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#define ARENA_FLAGS_FIXED_SIZE 1
|
||||
#define ARENA_FLAGS_COALESCED 2
|
||||
#define ARENA_FILE_VERSION 6
|
||||
|
||||
#define EOL ((size_t) -1)
|
||||
|
||||
|
||||
typedef struct _YR_RELOC
|
||||
{
|
||||
int32_t offset;
|
||||
struct _YR_RELOC* next;
|
||||
|
||||
} YR_RELOC;
|
||||
|
||||
|
||||
typedef struct _YR_ARENA_PAGE
|
||||
{
|
||||
|
||||
uint8_t* new_address;
|
||||
uint8_t* address;
|
||||
|
||||
size_t size;
|
||||
size_t used;
|
||||
|
||||
YR_RELOC* reloc_list_head;
|
||||
YR_RELOC* reloc_list_tail;
|
||||
|
||||
struct _YR_ARENA_PAGE* next;
|
||||
struct _YR_ARENA_PAGE* prev;
|
||||
|
||||
} YR_ARENA_PAGE;
|
||||
|
||||
|
||||
typedef struct _YR_ARENA
|
||||
{
|
||||
int flags;
|
||||
|
||||
YR_ARENA_PAGE* page_list_head;
|
||||
YR_ARENA_PAGE* current_page;
|
||||
|
||||
} YR_ARENA;
|
||||
|
||||
|
||||
int yr_arena_create(
|
||||
size_t initial_size,
|
||||
int flags,
|
||||
YR_ARENA** arena);
|
||||
|
||||
|
||||
void yr_arena_destroy(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
void* yr_arena_base_address(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
void* yr_arena_next_address(
|
||||
YR_ARENA* arena,
|
||||
void* address,
|
||||
int offset);
|
||||
|
||||
|
||||
int yr_arena_coalesce(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
int yr_arena_reserve_memory(
|
||||
YR_ARENA* arena,
|
||||
size_t size);
|
||||
|
||||
|
||||
int yr_arena_allocate_memory(
|
||||
YR_ARENA* arena,
|
||||
size_t size,
|
||||
void** allocated_memory);
|
||||
|
||||
|
||||
int yr_arena_allocate_struct(
|
||||
YR_ARENA* arena,
|
||||
size_t size,
|
||||
void** allocated_memory,
|
||||
...);
|
||||
|
||||
|
||||
int yr_arena_make_relocatable(
|
||||
YR_ARENA* arena,
|
||||
void* base,
|
||||
...);
|
||||
|
||||
|
||||
int yr_arena_write_data(
|
||||
YR_ARENA* arena,
|
||||
void* data,
|
||||
size_t size,
|
||||
void** written_data);
|
||||
|
||||
|
||||
int yr_arena_write_string(
|
||||
YR_ARENA* arena,
|
||||
const char* string,
|
||||
char** written_string);
|
||||
|
||||
|
||||
int yr_arena_append(
|
||||
YR_ARENA* target_arena,
|
||||
YR_ARENA* source_arena);
|
||||
|
||||
|
||||
int yr_arena_save(
|
||||
YR_ARENA* arena,
|
||||
const char* filename);
|
||||
|
||||
|
||||
int yr_arena_load(
|
||||
const char* filename,
|
||||
YR_ARENA** arena);
|
||||
|
||||
|
||||
int yr_arena_duplicate(
|
||||
YR_ARENA* arena,
|
||||
YR_ARENA** duplicated);
|
||||
|
||||
|
||||
void yr_arena_print(
|
||||
YR_ARENA* arena);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_ATOMS_H
|
||||
#define YR_ATOMS_H
|
||||
|
||||
#include "limits.h"
|
||||
#include "re.h"
|
||||
|
||||
#define ATOM_TREE_LEAF 1
|
||||
#define ATOM_TREE_AND 2
|
||||
#define ATOM_TREE_OR 3
|
||||
|
||||
|
||||
typedef struct _ATOM_TREE_NODE
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t atom_length;
|
||||
uint8_t atom[MAX_ATOM_LENGTH];
|
||||
|
||||
uint8_t* forward_code;
|
||||
uint8_t* backward_code;
|
||||
|
||||
RE_NODE* recent_nodes[MAX_ATOM_LENGTH];
|
||||
|
||||
struct _ATOM_TREE_NODE* children_head;
|
||||
struct _ATOM_TREE_NODE* children_tail;
|
||||
struct _ATOM_TREE_NODE* next_sibling;
|
||||
|
||||
} ATOM_TREE_NODE;
|
||||
|
||||
|
||||
typedef struct _ATOM_TREE
|
||||
{
|
||||
ATOM_TREE_NODE* current_leaf;
|
||||
ATOM_TREE_NODE* root_node;
|
||||
|
||||
} ATOM_TREE;
|
||||
|
||||
|
||||
typedef struct _YR_ATOM_LIST_ITEM
|
||||
{
|
||||
uint8_t atom_length;
|
||||
uint8_t atom[MAX_ATOM_LENGTH];
|
||||
|
||||
uint16_t backtrack;
|
||||
|
||||
uint8_t* forward_code;
|
||||
uint8_t* backward_code;
|
||||
|
||||
struct _YR_ATOM_LIST_ITEM* next;
|
||||
|
||||
} YR_ATOM_LIST_ITEM;
|
||||
|
||||
|
||||
int yr_atoms_extract_from_re(
|
||||
RE* re,
|
||||
int flags,
|
||||
YR_ATOM_LIST_ITEM** atoms);
|
||||
|
||||
|
||||
int yr_atoms_extract_from_string(
|
||||
uint8_t* string,
|
||||
int string_length,
|
||||
int flags,
|
||||
YR_ATOM_LIST_ITEM** atoms);
|
||||
|
||||
|
||||
int yr_atoms_min_quality(
|
||||
YR_ATOM_LIST_ITEM* atom_list);
|
||||
|
||||
|
||||
void yr_atoms_list_destroy(
|
||||
YR_ATOM_LIST_ITEM* list_head);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_COMPILER_H
|
||||
#define YR_COMPILER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "ahocorasick.h"
|
||||
#include "arena.h"
|
||||
#include "hash.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define YARA_ERROR_LEVEL_ERROR 0
|
||||
#define YARA_ERROR_LEVEL_WARNING 1
|
||||
|
||||
|
||||
typedef void (*YR_COMPILER_CALLBACK_FUNC)(
|
||||
int error_level,
|
||||
const char* file_name,
|
||||
int line_number,
|
||||
const char* message,
|
||||
void* user_data);
|
||||
|
||||
|
||||
typedef struct _YR_COMPILER
|
||||
{
|
||||
int errors;
|
||||
int error_line;
|
||||
int last_error;
|
||||
int last_error_line;
|
||||
int last_result;
|
||||
|
||||
jmp_buf error_recovery;
|
||||
|
||||
YR_ARENA* sz_arena;
|
||||
YR_ARENA* rules_arena;
|
||||
YR_ARENA* strings_arena;
|
||||
YR_ARENA* code_arena;
|
||||
YR_ARENA* re_code_arena;
|
||||
YR_ARENA* automaton_arena;
|
||||
YR_ARENA* compiled_rules_arena;
|
||||
YR_ARENA* externals_arena;
|
||||
YR_ARENA* namespaces_arena;
|
||||
YR_ARENA* metas_arena;
|
||||
|
||||
YR_AC_AUTOMATON* automaton;
|
||||
YR_HASH_TABLE* rules_table;
|
||||
YR_HASH_TABLE* objects_table;
|
||||
YR_NAMESPACE* current_namespace;
|
||||
YR_STRING* current_rule_strings;
|
||||
|
||||
int current_rule_flags;
|
||||
int namespaces_count;
|
||||
|
||||
int8_t* loop_address[MAX_LOOP_NESTING];
|
||||
char* loop_identifier[MAX_LOOP_NESTING];
|
||||
int loop_depth;
|
||||
int loop_for_of_mem_offset;
|
||||
|
||||
int allow_includes;
|
||||
|
||||
char* file_name_stack[MAX_INCLUDE_DEPTH];
|
||||
int file_name_stack_ptr;
|
||||
|
||||
FILE* file_stack[MAX_INCLUDE_DEPTH];
|
||||
int file_stack_ptr;
|
||||
|
||||
char last_error_extra_info[MAX_COMPILER_ERROR_EXTRA_INFO];
|
||||
|
||||
char lex_buf[LEX_BUF_SIZE];
|
||||
char* lex_buf_ptr;
|
||||
unsigned short lex_buf_len;
|
||||
|
||||
char include_base_dir[MAX_PATH];
|
||||
void* user_data;
|
||||
|
||||
YR_COMPILER_CALLBACK_FUNC callback;
|
||||
|
||||
} YR_COMPILER;
|
||||
|
||||
|
||||
#define yr_compiler_set_error_extra_info(compiler, info) \
|
||||
strlcpy( \
|
||||
compiler->last_error_extra_info, \
|
||||
info, \
|
||||
sizeof(compiler->last_error_extra_info)); \
|
||||
|
||||
|
||||
#define yr_compiler_set_error_extra_info_fmt(compiler, fmt, ...) \
|
||||
snprintf( \
|
||||
compiler->last_error_extra_info, \
|
||||
sizeof(compiler->last_error_extra_info), \
|
||||
fmt, __VA_ARGS__);
|
||||
|
||||
|
||||
int _yr_compiler_push_file(
|
||||
YR_COMPILER* compiler,
|
||||
FILE* fh);
|
||||
|
||||
|
||||
FILE* _yr_compiler_pop_file(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
int _yr_compiler_push_file_name(
|
||||
YR_COMPILER* compiler,
|
||||
const char* file_name);
|
||||
|
||||
|
||||
void _yr_compiler_pop_file_name(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
YR_API int yr_compiler_create(
|
||||
YR_COMPILER** compiler);
|
||||
|
||||
|
||||
YR_API void yr_compiler_destroy(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
YR_API void yr_compiler_set_callback(
|
||||
YR_COMPILER* compiler,
|
||||
YR_COMPILER_CALLBACK_FUNC callback,
|
||||
void* user_data);
|
||||
|
||||
|
||||
YR_API int yr_compiler_add_file(
|
||||
YR_COMPILER* compiler,
|
||||
FILE* rules_file,
|
||||
const char* namespace_,
|
||||
const char* file_name);
|
||||
|
||||
|
||||
YR_API int yr_compiler_add_string(
|
||||
YR_COMPILER* compiler,
|
||||
const char* rules_string,
|
||||
const char* namespace_);
|
||||
|
||||
|
||||
YR_API char* yr_compiler_get_error_message(
|
||||
YR_COMPILER* compiler,
|
||||
char* buffer,
|
||||
int buffer_size);
|
||||
|
||||
|
||||
YR_API char* yr_compiler_get_current_file_name(
|
||||
YR_COMPILER* context);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_integer_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
int64_t value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_boolean_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
int value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_float_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
double value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_string_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
const char* value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_get_rules(
|
||||
YR_COMPILER* compiler,
|
||||
YR_RULES** rules);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ELF_H
|
||||
#define _ELF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// 32-bit ELF base types
|
||||
|
||||
typedef uint32_t elf32_addr_t;
|
||||
typedef uint16_t elf32_half_t;
|
||||
typedef uint32_t elf32_off_t;
|
||||
typedef uint32_t elf32_word_t;
|
||||
|
||||
// 64-bit ELF base types
|
||||
|
||||
typedef uint64_t elf64_addr_t;
|
||||
typedef uint16_t elf64_half_t;
|
||||
typedef uint64_t elf64_off_t;
|
||||
typedef uint32_t elf64_word_t;
|
||||
typedef uint64_t elf64_xword_t;
|
||||
|
||||
#define ELF_MAGIC 0x464C457F
|
||||
|
||||
#define ELF_ET_NONE 0x0000 // no type
|
||||
#define ELF_ET_REL 0x0001 // relocatable
|
||||
#define ELF_ET_EXEC 0x0002 // executeable
|
||||
#define ELF_ET_DYN 0x0003 // Shared-Object-File
|
||||
#define ELF_ET_CORE 0x0004 // Corefile
|
||||
#define ELF_ET_LOPROC 0xFF00 // Processor-specific
|
||||
#define ELF_ET_HIPROC 0x00FF // Processor-specific
|
||||
|
||||
#define ELF_EM_NONE 0x0000 // no type
|
||||
#define ELF_EM_M32 0x0001 // AT&T WE 32100
|
||||
#define ELF_EM_SPARC 0x0002 // SPARC
|
||||
#define ELF_EM_386 0x0003 // Intel 80386
|
||||
#define ELF_EM_68K 0x0004 // Motorola 68000
|
||||
#define ELF_EM_88K 0x0005 // Motorola 88000
|
||||
#define ELF_EM_860 0x0007 // Intel 80860
|
||||
#define ELF_EM_MIPS 0x0008 // MIPS RS3000
|
||||
#define ELF_EM_ARM 0x0032 // ARM
|
||||
#define ELF_EM_X86_64 0x003E // AMD/Intel x86_64
|
||||
|
||||
#define ELF_CLASS_NONE 0x0000
|
||||
#define ELF_CLASS_32 0x0001 // 32bit file
|
||||
#define ELF_CLASS_64 0x0002 // 64bit file
|
||||
|
||||
#define ELF_DATA_NONE 0x0000
|
||||
#define ELF_DATA_2LSB 0x0001
|
||||
#define ELF_DATA_2MSB 0x002
|
||||
|
||||
|
||||
#define ELF_SHT_NULL 0 // Section header table entry unused
|
||||
#define ELF_SHT_PROGBITS 1 // Program data
|
||||
#define ELF_SHT_SYMTAB 2 // Symbol table
|
||||
#define ELF_SHT_STRTAB 3 // String table
|
||||
#define ELF_SHT_RELA 4 // Relocation entries with addends
|
||||
#define ELF_SHT_HASH 5 // Symbol hash table
|
||||
#define ELF_SHT_DYNAMIC 6 // Dynamic linking information
|
||||
#define ELF_SHT_NOTE 7 // Notes
|
||||
#define ELF_SHT_NOBITS 8 // Program space with no data (bss)
|
||||
#define ELF_SHT_REL 9 // Relocation entries, no addends
|
||||
#define ELF_SHT_SHLIB 10 // Reserved
|
||||
#define ELF_SHT_DYNSYM 11 // Dynamic linker symbol table
|
||||
#define ELF_SHT_NUM 12 // Number of defined types
|
||||
|
||||
#define ELF_SHF_WRITE 0x1 // Section is writable
|
||||
#define ELF_SHF_ALLOC 0x2 // Section is present during execution
|
||||
#define ELF_SHF_EXECINSTR 0x4 // Section contains executable instructions
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t magic;
|
||||
uint8_t _class;
|
||||
uint8_t data;
|
||||
uint8_t version;
|
||||
uint8_t pad[8];
|
||||
uint8_t nident;
|
||||
|
||||
} elf_ident_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf_ident_t ident;
|
||||
elf32_half_t type;
|
||||
elf32_half_t machine;
|
||||
elf32_word_t version;
|
||||
elf32_addr_t entry;
|
||||
elf32_off_t ph_offset;
|
||||
elf32_off_t sh_offset;
|
||||
elf32_word_t flags;
|
||||
elf32_half_t header_size;
|
||||
elf32_half_t ph_entry_size;
|
||||
elf32_half_t ph_entry_count;
|
||||
elf32_half_t sh_entry_size;
|
||||
elf32_half_t sh_entry_count;
|
||||
elf32_half_t sh_str_table_index;
|
||||
|
||||
} elf32_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf_ident_t ident;
|
||||
elf64_half_t type;
|
||||
elf64_half_t machine;
|
||||
elf64_word_t version;
|
||||
elf64_addr_t entry;
|
||||
elf64_off_t ph_offset;
|
||||
elf64_off_t sh_offset;
|
||||
elf64_word_t flags;
|
||||
elf64_half_t header_size;
|
||||
elf64_half_t ph_entry_size;
|
||||
elf64_half_t ph_entry_count;
|
||||
elf64_half_t sh_entry_size;
|
||||
elf64_half_t sh_entry_count;
|
||||
elf64_half_t sh_str_table_index;
|
||||
|
||||
} elf64_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t type;
|
||||
elf32_off_t offset;
|
||||
elf32_addr_t virt_addr;
|
||||
elf32_addr_t phys_addr;
|
||||
elf32_word_t file_size;
|
||||
elf32_word_t mem_size;
|
||||
elf32_word_t flags;
|
||||
elf32_word_t alignment;
|
||||
|
||||
} elf32_program_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf64_word_t type;
|
||||
elf64_word_t flags;
|
||||
elf64_off_t offset;
|
||||
elf64_addr_t virt_addr;
|
||||
elf64_addr_t phys_addr;
|
||||
elf64_xword_t file_size;
|
||||
elf64_xword_t mem_size;
|
||||
elf64_xword_t alignment;
|
||||
|
||||
} elf64_program_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t name;
|
||||
elf32_word_t type;
|
||||
elf32_word_t flags;
|
||||
elf32_addr_t addr;
|
||||
elf32_off_t offset;
|
||||
elf32_word_t size;
|
||||
elf32_word_t link;
|
||||
elf32_word_t info;
|
||||
elf32_word_t align;
|
||||
elf32_word_t entry_size;
|
||||
|
||||
} elf32_section_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf64_word_t name;
|
||||
elf64_word_t type;
|
||||
elf64_xword_t flags;
|
||||
elf64_addr_t addr;
|
||||
elf64_off_t offset;
|
||||
elf64_xword_t size;
|
||||
elf64_word_t link;
|
||||
elf64_word_t info;
|
||||
elf64_xword_t align;
|
||||
elf64_xword_t entry_size;
|
||||
|
||||
} elf64_section_header_t;
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright (c) 2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_ERROR_H
|
||||
#define YR_ERROR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef ERROR_SUCCESS
|
||||
#define ERROR_SUCCESS 0
|
||||
#endif
|
||||
|
||||
#define ERROR_INSUFICIENT_MEMORY 1
|
||||
#define ERROR_COULD_NOT_ATTACH_TO_PROCESS 2
|
||||
#define ERROR_COULD_NOT_OPEN_FILE 3
|
||||
#define ERROR_COULD_NOT_MAP_FILE 4
|
||||
#define ERROR_INVALID_FILE 6
|
||||
#define ERROR_CORRUPT_FILE 7
|
||||
#define ERROR_UNSUPPORTED_FILE_VERSION 8
|
||||
#define ERROR_INVALID_REGULAR_EXPRESSION 9
|
||||
#define ERROR_INVALID_HEX_STRING 10
|
||||
#define ERROR_SYNTAX_ERROR 11
|
||||
#define ERROR_LOOP_NESTING_LIMIT_EXCEEDED 12
|
||||
#define ERROR_DUPLICATED_LOOP_IDENTIFIER 13
|
||||
#define ERROR_DUPLICATED_IDENTIFIER 14
|
||||
#define ERROR_DUPLICATED_TAG_IDENTIFIER 15
|
||||
#define ERROR_DUPLICATED_META_IDENTIFIER 16
|
||||
#define ERROR_DUPLICATED_STRING_IDENTIFIER 17
|
||||
#define ERROR_UNREFERENCED_STRING 18
|
||||
#define ERROR_UNDEFINED_STRING 19
|
||||
#define ERROR_UNDEFINED_IDENTIFIER 20
|
||||
#define ERROR_MISPLACED_ANONYMOUS_STRING 21
|
||||
#define ERROR_INCLUDES_CIRCULAR_REFERENCE 22
|
||||
#define ERROR_INCLUDE_DEPTH_EXCEEDED 23
|
||||
#define ERROR_WRONG_TYPE 24
|
||||
#define ERROR_EXEC_STACK_OVERFLOW 25
|
||||
#define ERROR_SCAN_TIMEOUT 26
|
||||
#define ERROR_TOO_MANY_SCAN_THREADS 27
|
||||
#define ERROR_CALLBACK_ERROR 28
|
||||
#define ERROR_INVALID_ARGUMENT 29
|
||||
#define ERROR_TOO_MANY_MATCHES 30
|
||||
#define ERROR_INTERNAL_FATAL_ERROR 31
|
||||
#define ERROR_NESTED_FOR_OF_LOOP 32
|
||||
#define ERROR_INVALID_FIELD_NAME 33
|
||||
#define ERROR_UNKNOWN_MODULE 34
|
||||
#define ERROR_NOT_A_STRUCTURE 35
|
||||
#define ERROR_NOT_INDEXABLE 36
|
||||
#define ERROR_NOT_A_FUNCTION 37
|
||||
#define ERROR_INVALID_FORMAT 38
|
||||
#define ERROR_TOO_MANY_ARGUMENTS 39
|
||||
#define ERROR_WRONG_ARGUMENTS 40
|
||||
#define ERROR_WRONG_RETURN_TYPE 41
|
||||
#define ERROR_DUPLICATED_STRUCTURE_MEMBER 42
|
||||
|
||||
|
||||
#define FAIL_ON_ERROR(x) { \
|
||||
int result = (x); \
|
||||
if (result != ERROR_SUCCESS) \
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define FAIL_ON_ERROR_WITH_CLEANUP(x, cleanup) { \
|
||||
int result = (x); \
|
||||
if (result != ERROR_SUCCESS) { \
|
||||
cleanup; \
|
||||
return result; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FAIL_ON_COMPILER_ERROR(x) { \
|
||||
compiler->last_result = (x); \
|
||||
if (compiler->last_result != ERROR_SUCCESS) \
|
||||
return compiler->last_result; \
|
||||
}
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assertf(expr, msg) ((void)0)
|
||||
#else
|
||||
#define assertf(expr, msg, ...) \
|
||||
if(!(expr)) { \
|
||||
fprintf(stderr, "%s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
abort(); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
Copyright (c) 2013-2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef YR_EXEC_H
|
||||
#define YR_EXEC_H
|
||||
|
||||
#include "hash.h"
|
||||
#include "scan.h"
|
||||
#include "types.h"
|
||||
#include "rules.h"
|
||||
|
||||
|
||||
#define UNDEFINED 0xFFFABADAFABADAFFLL
|
||||
#define IS_UNDEFINED(x) ((size_t)(x) == (size_t) UNDEFINED)
|
||||
|
||||
#define OP_ERROR 0
|
||||
#define OP_HALT 255
|
||||
|
||||
#define OP_AND 1
|
||||
#define OP_OR 2
|
||||
#define OP_NOT 3
|
||||
#define OP_BITWISE_NOT 4
|
||||
#define OP_BITWISE_AND 5
|
||||
#define OP_BITWISE_OR 6
|
||||
#define OP_BITWISE_XOR 7
|
||||
#define OP_SHL 8
|
||||
#define OP_SHR 9
|
||||
#define OP_MOD 10
|
||||
#define OP_INT_TO_DBL 11
|
||||
#define OP_STR_TO_BOOL 12
|
||||
#define OP_PUSH 13
|
||||
#define OP_POP 14
|
||||
#define OP_CALL 15
|
||||
#define OP_OBJ_LOAD 16
|
||||
#define OP_OBJ_VALUE 17
|
||||
#define OP_OBJ_FIELD 18
|
||||
#define OP_INDEX_ARRAY 19
|
||||
#define OP_COUNT 20
|
||||
#define OP_FOUND 21
|
||||
#define OP_FOUND_AT 22
|
||||
#define OP_FOUND_IN 23
|
||||
#define OP_OFFSET 24
|
||||
#define OP_OF 25
|
||||
#define OP_PUSH_RULE 26
|
||||
#define OP_MATCH_RULE 27
|
||||
#define OP_INCR_M 28
|
||||
#define OP_CLEAR_M 29
|
||||
#define OP_ADD_M 30
|
||||
#define OP_POP_M 31
|
||||
#define OP_PUSH_M 32
|
||||
#define OP_SWAPUNDEF 33
|
||||
#define OP_JNUNDEF 34
|
||||
#define OP_JLE 35
|
||||
#define OP_FILESIZE 36
|
||||
#define OP_ENTRYPOINT 37
|
||||
#define OP_CONTAINS 38
|
||||
#define OP_MATCHES 39
|
||||
#define OP_IMPORT 40
|
||||
#define OP_LOOKUP_DICT 41
|
||||
|
||||
#define _OP_EQ 0
|
||||
#define _OP_NEQ 1
|
||||
#define _OP_LT 2
|
||||
#define _OP_GT 3
|
||||
#define _OP_LE 4
|
||||
#define _OP_GE 5
|
||||
#define _OP_ADD 6
|
||||
#define _OP_SUB 7
|
||||
#define _OP_MUL 8
|
||||
#define _OP_DIV 9
|
||||
#define _OP_MINUS 10
|
||||
|
||||
#define OP_INT_BEGIN 100
|
||||
#define OP_INT_EQ (OP_INT_BEGIN + _OP_EQ)
|
||||
#define OP_INT_NEQ (OP_INT_BEGIN + _OP_NEQ)
|
||||
#define OP_INT_LT (OP_INT_BEGIN + _OP_LT)
|
||||
#define OP_INT_GT (OP_INT_BEGIN + _OP_GT)
|
||||
#define OP_INT_LE (OP_INT_BEGIN + _OP_LE)
|
||||
#define OP_INT_GE (OP_INT_BEGIN + _OP_GE)
|
||||
#define OP_INT_ADD (OP_INT_BEGIN + _OP_ADD)
|
||||
#define OP_INT_SUB (OP_INT_BEGIN + _OP_SUB)
|
||||
#define OP_INT_MUL (OP_INT_BEGIN + _OP_MUL)
|
||||
#define OP_INT_DIV (OP_INT_BEGIN + _OP_DIV)
|
||||
#define OP_INT_MINUS (OP_INT_BEGIN + _OP_MINUS)
|
||||
#define OP_INT_END OP_INT_MINUS
|
||||
|
||||
#define OP_DBL_BEGIN 120
|
||||
#define OP_DBL_EQ (OP_DBL_BEGIN + _OP_EQ)
|
||||
#define OP_DBL_NEQ (OP_DBL_BEGIN + _OP_NEQ)
|
||||
#define OP_DBL_LT (OP_DBL_BEGIN + _OP_LT)
|
||||
#define OP_DBL_GT (OP_DBL_BEGIN + _OP_GT)
|
||||
#define OP_DBL_LE (OP_DBL_BEGIN + _OP_LE)
|
||||
#define OP_DBL_GE (OP_DBL_BEGIN + _OP_GE)
|
||||
#define OP_DBL_ADD (OP_DBL_BEGIN + _OP_ADD)
|
||||
#define OP_DBL_SUB (OP_DBL_BEGIN + _OP_SUB)
|
||||
#define OP_DBL_MUL (OP_DBL_BEGIN + _OP_MUL)
|
||||
#define OP_DBL_DIV (OP_DBL_BEGIN + _OP_DIV)
|
||||
#define OP_DBL_MINUS (OP_DBL_BEGIN + _OP_MINUS)
|
||||
#define OP_DBL_END OP_DBL_MINUS
|
||||
|
||||
#define OP_STR_BEGIN 140
|
||||
#define OP_STR_EQ (OP_STR_BEGIN + _OP_EQ)
|
||||
#define OP_STR_NEQ (OP_STR_BEGIN + _OP_NEQ)
|
||||
#define OP_STR_LT (OP_STR_BEGIN + _OP_LT)
|
||||
#define OP_STR_GT (OP_STR_BEGIN + _OP_GT)
|
||||
#define OP_STR_LE (OP_STR_BEGIN + _OP_LE)
|
||||
#define OP_STR_GE (OP_STR_BEGIN + _OP_GE)
|
||||
#define OP_STR_END OP_STR_GE
|
||||
|
||||
#define IS_INT_OP(x) ((x) >= OP_INT_BEGIN && (x) <= OP_INT_END)
|
||||
#define IS_DBL_OP(x) ((x) >= OP_DBL_BEGIN && (x) <= OP_DBL_END)
|
||||
#define IS_STR_OP(x) ((x) >= OP_STR_BEGIN && (x) <= OP_STR_END)
|
||||
|
||||
#define OP_READ_INT 240
|
||||
#define OP_INT8 (OP_READ_INT + 0)
|
||||
#define OP_INT16 (OP_READ_INT + 1)
|
||||
#define OP_INT32 (OP_READ_INT + 2)
|
||||
#define OP_UINT8 (OP_READ_INT + 3)
|
||||
#define OP_UINT16 (OP_READ_INT + 4)
|
||||
#define OP_UINT32 (OP_READ_INT + 5)
|
||||
#define OP_INT8BE (OP_READ_INT + 6)
|
||||
#define OP_INT16BE (OP_READ_INT + 7)
|
||||
#define OP_INT32BE (OP_READ_INT + 8)
|
||||
#define OP_UINT8BE (OP_READ_INT + 9)
|
||||
#define OP_UINT16BE (OP_READ_INT + 10)
|
||||
#define OP_UINT32BE (OP_READ_INT + 11)
|
||||
|
||||
|
||||
#define OPERATION(operator, op1, op2) \
|
||||
(IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (UNDEFINED) : (op1 operator op2)
|
||||
|
||||
|
||||
#define COMPARISON(operator, op1, op2) \
|
||||
(IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (0) : (op1 operator op2)
|
||||
|
||||
|
||||
int yr_execute_code(
|
||||
YR_RULES* rules,
|
||||
YR_SCAN_CONTEXT* context,
|
||||
int timeout,
|
||||
time_t start_time);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright (c) 2007. 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_EXEFILES_H
|
||||
#define YR_EXEFILES_H
|
||||
|
||||
uint64_t yr_get_entry_point_offset(
|
||||
uint8_t* buffer,
|
||||
size_t buffer_length);
|
||||
|
||||
|
||||
uint64_t yr_get_entry_point_address(
|
||||
uint8_t* buffer,
|
||||
size_t buffer_length,
|
||||
size_t base_address);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Copyright (c) 2007-2015. 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_FILEMAP_H
|
||||
#define YR_FILEMAP_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#define FILE_DESCRIPTOR HANDLE
|
||||
#define off_t int64_t
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#define FILE_DESCRIPTOR int
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
typedef struct _YR_MAPPED_FILE
|
||||
{
|
||||
FILE_DESCRIPTOR file;
|
||||
size_t size;
|
||||
uint8_t* data;
|
||||
#ifdef _WIN32
|
||||
HANDLE mapping;
|
||||
#endif
|
||||
|
||||
} YR_MAPPED_FILE;
|
||||
|
||||
|
||||
YR_API int yr_filemap_map(
|
||||
const char* file_path,
|
||||
YR_MAPPED_FILE* pmapped_file);
|
||||
|
||||
|
||||
YR_API int yr_filemap_map_ex(
|
||||
const char* file_path,
|
||||
off_t offset,
|
||||
size_t size,
|
||||
YR_MAPPED_FILE* pmapped_file);
|
||||
|
||||
|
||||
YR_API void yr_filemap_unmap(
|
||||
YR_MAPPED_FILE* pmapped_file);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
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_GLOBALS_H
|
||||
#define YR_GLOBALS_H
|
||||
|
||||
extern char lowercase[256];
|
||||
extern char altercase[256];
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
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_HASH_H
|
||||
#define YR_HASH_H
|
||||
|
||||
|
||||
typedef struct _YR_HASH_TABLE_ENTRY
|
||||
{
|
||||
char* key;
|
||||
char* ns;
|
||||
void* value;
|
||||
|
||||
struct _YR_HASH_TABLE_ENTRY* next;
|
||||
|
||||
} YR_HASH_TABLE_ENTRY;
|
||||
|
||||
|
||||
typedef struct _YR_HASH_TABLE
|
||||
{
|
||||
int size;
|
||||
|
||||
YR_HASH_TABLE_ENTRY* buckets[1];
|
||||
|
||||
} YR_HASH_TABLE;
|
||||
|
||||
|
||||
typedef int (*YR_HASH_TABLE_FREE_VALUE_FUNC)(void* value);
|
||||
|
||||
|
||||
int yr_hash_table_create(
|
||||
int size,
|
||||
YR_HASH_TABLE** table);
|
||||
|
||||
|
||||
void yr_hash_table_destroy(
|
||||
YR_HASH_TABLE* table,
|
||||
YR_HASH_TABLE_FREE_VALUE_FUNC free_value);
|
||||
|
||||
|
||||
void* yr_hash_table_lookup(
|
||||
YR_HASH_TABLE* table,
|
||||
const char* key,
|
||||
const char* ns);
|
||||
|
||||
|
||||
int yr_hash_table_add(
|
||||
YR_HASH_TABLE* table,
|
||||
const char* key,
|
||||
const char* ns,
|
||||
void* value);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Copyright (c) 2007. Victor M. Alvarez [plusvic@gmail.com].
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "re.h"
|
||||
|
||||
#undef yyparse
|
||||
#undef yylex
|
||||
#undef yyerror
|
||||
#undef yyfatal
|
||||
#undef yychar
|
||||
#undef yydebug
|
||||
#undef yynerrs
|
||||
#undef yyget_extra
|
||||
#undef yyget_lineno
|
||||
|
||||
#undef YY_FATAL_ERROR
|
||||
#undef YY_DECL
|
||||
#undef LEX_ENV
|
||||
|
||||
#define yyparse hex_yyparse
|
||||
#define yylex hex_yylex
|
||||
#define yyerror hex_yyerror
|
||||
#define yyfatal hex_yyfatal
|
||||
#define yychar hex_yychar
|
||||
#define yydebug hex_yydebug
|
||||
#define yynerrs hex_yynerrs
|
||||
#define yyget_extra hex_yyget_extra
|
||||
#define yyget_lineno hex_yyget_lineno
|
||||
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
#define YY_EXTRA_TYPE RE*
|
||||
#define YY_USE_CONST
|
||||
|
||||
|
||||
typedef struct _HEX_LEX_ENVIRONMENT
|
||||
{
|
||||
int token_count;
|
||||
int inside_or;
|
||||
int last_error_code;
|
||||
char last_error_message[256];
|
||||
|
||||
} HEX_LEX_ENVIRONMENT;
|
||||
|
||||
|
||||
#define YY_FATAL_ERROR(msg) hex_yyfatal(yyscanner, msg)
|
||||
|
||||
#define LEX_ENV ((HEX_LEX_ENVIRONMENT*) lex_env)
|
||||
|
||||
#include <hex_grammar.h>
|
||||
|
||||
#define YY_DECL int hex_yylex \
|
||||
(YYSTYPE * yylval_param , yyscan_t yyscanner, HEX_LEX_ENVIRONMENT* lex_env)
|
||||
|
||||
|
||||
YY_EXTRA_TYPE yyget_extra(
|
||||
yyscan_t yyscanner);
|
||||
|
||||
int yylex(
|
||||
YYSTYPE* yylval_param,
|
||||
yyscan_t yyscanner,
|
||||
HEX_LEX_ENVIRONMENT* lex_env);
|
||||
|
||||
int yyparse(
|
||||
void* yyscanner,
|
||||
HEX_LEX_ENVIRONMENT* lex_env);
|
||||
|
||||
void yyerror(
|
||||
yyscan_t yyscanner,
|
||||
HEX_LEX_ENVIRONMENT* lex_env,
|
||||
const char* error_message);
|
||||
|
||||
void yyfatal(
|
||||
yyscan_t yyscanner,
|
||||
const char* error_message);
|
||||
|
||||
int yr_parse_hex_string(
|
||||
const char* hex_string,
|
||||
int flags,
|
||||
RE** re,
|
||||
RE_ERROR* error);
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
Copyright (c) 2007. Victor M. Alvarez [plusvic@gmail.com].
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
|
||||
#undef yyparse
|
||||
#undef yylex
|
||||
#undef yyerror
|
||||
#undef yyfatal
|
||||
#undef yychar
|
||||
#undef yydebug
|
||||
#undef yynerrs
|
||||
#undef yyget_extra
|
||||
#undef yyget_lineno
|
||||
|
||||
#undef YY_DECL
|
||||
#undef YY_FATAL_ERROR
|
||||
#undef YY_EXTRA_TYPE
|
||||
|
||||
#define yyparse yara_yyparse
|
||||
#define yylex yara_yylex
|
||||
#define yyerror yara_yyerror
|
||||
#define yyfatal yara_yyfatal
|
||||
#define yywarning yara_yywarning
|
||||
#define yychar yara_yychar
|
||||
#define yydebug yara_yydebug
|
||||
#define yynerrs yara_yynerrs
|
||||
#define yyget_extra yara_yyget_extra
|
||||
#define yyget_lineno yara_yyget_lineno
|
||||
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_EXPRESSION_T
|
||||
#define YY_TYPEDEF_EXPRESSION_T
|
||||
|
||||
|
||||
// Expression type constants are powers of two because they are used as flags.
|
||||
// For example:
|
||||
// CHECK_TYPE(whatever, EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT)
|
||||
// The expression above is used to ensure that the type of "whatever" is either
|
||||
// integer or float.
|
||||
|
||||
#define EXPRESSION_TYPE_BOOLEAN 1
|
||||
#define EXPRESSION_TYPE_INTEGER 2
|
||||
#define EXPRESSION_TYPE_STRING 4
|
||||
#define EXPRESSION_TYPE_REGEXP 8
|
||||
#define EXPRESSION_TYPE_OBJECT 16
|
||||
#define EXPRESSION_TYPE_FLOAT 32
|
||||
|
||||
typedef struct _EXPRESSION
|
||||
{
|
||||
int type;
|
||||
|
||||
union
|
||||
{
|
||||
int64_t integer;
|
||||
YR_OBJECT* object;
|
||||
} value;
|
||||
|
||||
const char* identifier;
|
||||
|
||||
} EXPRESSION;
|
||||
|
||||
union YYSTYPE;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define YY_DECL int yylex( \
|
||||
union YYSTYPE* yylval_param, yyscan_t yyscanner, YR_COMPILER* compiler)
|
||||
|
||||
|
||||
#define YY_FATAL_ERROR(msg) yara_yyfatal(yyscanner, msg)
|
||||
|
||||
|
||||
#define YY_EXTRA_TYPE YR_COMPILER*
|
||||
#define YY_USE_CONST
|
||||
|
||||
|
||||
int yyget_lineno(yyscan_t yyscanner);
|
||||
|
||||
int yylex(
|
||||
union YYSTYPE* yylval_param,
|
||||
yyscan_t yyscanner,
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
int yyparse(
|
||||
void* yyscanner,
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
void yyerror(
|
||||
yyscan_t yyscanner,
|
||||
YR_COMPILER* compiler,
|
||||
const char* error_message);
|
||||
|
||||
void yywarning(
|
||||
yyscan_t yyscanner,
|
||||
const char* warning_message);
|
||||
|
||||
void yyfatal(
|
||||
yyscan_t yyscanner,
|
||||
const char* error_message);
|
||||
|
||||
YY_EXTRA_TYPE yyget_extra(
|
||||
yyscan_t yyscanner);
|
||||
|
||||
int yr_lex_parse_rules_string(
|
||||
const char* rules_string,
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
int yr_lex_parse_rules_file(
|
||||
FILE* rules_file,
|
||||
YR_COMPILER* compiler);
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
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_LIBYARA_H
|
||||
#define YR_LIBYARA_H
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define YR_MAJOR_VERSION 3
|
||||
#define YR_MINOR_VERSION 3
|
||||
#define YR_MICRO_VERSION 0
|
||||
|
||||
// Version as a string
|
||||
#define YR_VERSION "3.3.0"
|
||||
|
||||
// Version as a single 4-byte hex number, e.g. 0x030401 == 3.4.1.
|
||||
#define YR_VERSION_HEX ((YR_MAJOR_VERSION << 16) | \
|
||||
(YR_MINOR_VERSION << 8) | \
|
||||
(YR_MICRO_VERSION << 0)
|
||||
|
||||
|
||||
YR_API int yr_initialize(void);
|
||||
|
||||
|
||||
YR_API int yr_finalize(void);
|
||||
|
||||
|
||||
YR_API void yr_finalize_thread(void);
|
||||
|
||||
|
||||
YR_API int yr_get_tidx(void);
|
||||
|
||||
|
||||
YR_API void yr_set_tidx(int);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
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_LIMITS_H
|
||||
#define YR_LIMITS_H
|
||||
|
||||
|
||||
// MAX_THREADS is the number of threads that can use a YR_RULES
|
||||
// object simultaneosly. This value is limited by the number of
|
||||
// bits in tidx_mask.
|
||||
|
||||
#define MAX_THREADS 32
|
||||
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 1024
|
||||
#endif
|
||||
|
||||
#define MAX_COMPILER_ERROR_EXTRA_INFO 256
|
||||
#define MAX_ATOM_LENGTH 4
|
||||
#define MAX_LOOP_NESTING 4
|
||||
#define MAX_ARENA_PAGES 32
|
||||
#define MAX_INCLUDE_DEPTH 16
|
||||
#define MAX_STRING_MATCHES 1000000
|
||||
#define MAX_FUNCTION_ARGS 128
|
||||
#define MAX_FAST_HEX_RE_STACK 300
|
||||
#define MAX_OVERLOADED_FUNCTIONS 10
|
||||
#define MAX_HEX_STRING_TOKENS 10000
|
||||
|
||||
#define LOOP_LOCAL_VARS 4
|
||||
#define STRING_CHAINING_THRESHOLD 200
|
||||
#define LEX_BUF_SIZE 1024
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Copyright (c) 2007. 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_MEM_H
|
||||
#define YR_MEM_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef DMALLOC
|
||||
|
||||
#define yr_malloc malloc
|
||||
#define yr_calloc calloc
|
||||
#define yr_realloc realloc
|
||||
#define yr_free free
|
||||
#define yr_strdup strdup
|
||||
#define yr_strndup strndup
|
||||
|
||||
#include <dmalloc.h>
|
||||
|
||||
#else
|
||||
|
||||
void* yr_calloc(
|
||||
size_t count,
|
||||
size_t size);
|
||||
|
||||
void* yr_malloc(
|
||||
size_t size);
|
||||
|
||||
void* yr_realloc(
|
||||
void* ptr,
|
||||
size_t size);
|
||||
|
||||
void yr_free(
|
||||
void* ptr);
|
||||
|
||||
char* yr_strdup(
|
||||
const char* str);
|
||||
|
||||
char* yr_strndup(
|
||||
const char* str, size_t n);
|
||||
|
||||
#endif
|
||||
|
||||
int yr_heap_alloc();
|
||||
|
||||
int yr_heap_free();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
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_MODULES_H
|
||||
#define YR_MODULES_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "limits.h"
|
||||
#include "error.h"
|
||||
#include "exec.h"
|
||||
#include "types.h"
|
||||
#include "object.h"
|
||||
#include "libyara.h"
|
||||
|
||||
// Concatenation that macro-expands its arguments.
|
||||
|
||||
#define CONCAT(arg1, arg2) _CONCAT(arg1, arg2) // expands the arguments.
|
||||
#define _CONCAT(arg1, arg2) arg1 ## arg2 // do the actual concatenation.
|
||||
|
||||
|
||||
#define module_declarations CONCAT(MODULE_NAME, __declarations)
|
||||
#define module_load CONCAT(MODULE_NAME, __load)
|
||||
#define module_unload CONCAT(MODULE_NAME, __unload)
|
||||
#define module_initialize CONCAT(MODULE_NAME, __initialize)
|
||||
#define module_finalize CONCAT(MODULE_NAME, __finalize)
|
||||
|
||||
#define begin_declarations \
|
||||
int module_declarations(YR_OBJECT* module) { \
|
||||
YR_OBJECT* stack[64]; \
|
||||
int stack_top = 0; \
|
||||
stack[stack_top] = module;
|
||||
|
||||
|
||||
#define end_declarations \
|
||||
return ERROR_SUCCESS; }
|
||||
|
||||
|
||||
#define begin_struct(name) { \
|
||||
YR_OBJECT* structure; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_STRUCTURE, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&structure)); \
|
||||
assertf( \
|
||||
stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \
|
||||
"too many nested structures"); \
|
||||
stack[++stack_top] = structure; \
|
||||
}
|
||||
|
||||
|
||||
#define begin_struct_array(name) { \
|
||||
YR_OBJECT* structure; \
|
||||
YR_OBJECT* array; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_ARRAY, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&array)); \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_STRUCTURE, \
|
||||
name, \
|
||||
array, \
|
||||
&structure)); \
|
||||
assertf( \
|
||||
stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \
|
||||
"too many nested structures"); \
|
||||
stack[++stack_top] = structure; \
|
||||
}
|
||||
|
||||
|
||||
#define begin_struct_dictionary(name) { \
|
||||
YR_OBJECT* structure; \
|
||||
YR_OBJECT* array; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_DICTIONARY, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&array)); \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_STRUCTURE, \
|
||||
name, \
|
||||
array, \
|
||||
&structure)); \
|
||||
assertf( \
|
||||
stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \
|
||||
"too many nested structures"); \
|
||||
stack[++stack_top] = structure; \
|
||||
}
|
||||
|
||||
|
||||
#define end_struct(name) { \
|
||||
assert(stack[stack_top]->type == OBJECT_TYPE_STRUCTURE); \
|
||||
assertf( \
|
||||
strcmp(stack[stack_top]->identifier, name) == 0, \
|
||||
"unbalanced begin_struct/end_struct"); \
|
||||
stack_top--; \
|
||||
}
|
||||
|
||||
|
||||
#define end_struct_array(name) end_struct(name)
|
||||
|
||||
|
||||
#define end_struct_dictionary(name) end_struct(name)
|
||||
|
||||
|
||||
#define declare_integer(name) { \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_INTEGER, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_integer_array(name) { \
|
||||
YR_OBJECT* array; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_ARRAY, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&array)); \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_INTEGER, \
|
||||
name, \
|
||||
array, \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_integer_dictionary(name) { \
|
||||
YR_OBJECT* dict; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_DICTIONARY, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&dict)); \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_INTEGER, \
|
||||
name, \
|
||||
dict, \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_float(name) { \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_FLOAT, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_float_array(name) { \
|
||||
YR_OBJECT* array; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_ARRAY, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&array)); \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_FLOAT, \
|
||||
name, \
|
||||
array, \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_float_dictionary(name) { \
|
||||
YR_OBJECT* dict; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_DICTIONARY, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&dict)); \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_FLOAT, \
|
||||
name, \
|
||||
dict, \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_string(name) { \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_STRING, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_string_array(name) { \
|
||||
YR_OBJECT* array; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_ARRAY, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&array)); \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_STRING, \
|
||||
name, \
|
||||
array, \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_string_dictionary(name) { \
|
||||
YR_OBJECT* dict; \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_DICTIONARY, \
|
||||
name, \
|
||||
stack[stack_top], \
|
||||
&dict)); \
|
||||
FAIL_ON_ERROR(yr_object_create( \
|
||||
OBJECT_TYPE_STRING, \
|
||||
name, \
|
||||
dict, \
|
||||
NULL)); \
|
||||
}
|
||||
|
||||
|
||||
#define declare_function(name, args_fmt, ret_fmt, func) { \
|
||||
YR_OBJECT* function; \
|
||||
FAIL_ON_ERROR(yr_object_function_create( \
|
||||
name, \
|
||||
args_fmt, \
|
||||
ret_fmt, \
|
||||
func, \
|
||||
stack[stack_top], \
|
||||
&function)); \
|
||||
}
|
||||
|
||||
|
||||
#define define_function(func) \
|
||||
int func ( \
|
||||
void* __args, \
|
||||
YR_SCAN_CONTEXT* __context, \
|
||||
YR_OBJECT_FUNCTION* __function_obj)
|
||||
|
||||
|
||||
#define sized_string_argument(n) \
|
||||
((SIZED_STRING*)(size_t)((int64_t*) __args)[n-1])
|
||||
|
||||
#define string_argument(n) \
|
||||
(sized_string_argument(n)->c_string)
|
||||
|
||||
#define integer_argument(n) \
|
||||
(((int64_t*) __args)[n-1])
|
||||
|
||||
#define float_argument(n) \
|
||||
(((double*) __args)[n-1])
|
||||
|
||||
#define regexp_argument(n) \
|
||||
((RE_CODE)((int64_t*) __args)[n-1])
|
||||
|
||||
|
||||
#define module() yr_object_get_root((YR_OBJECT*) __function_obj)
|
||||
#define parent() (__function_obj->parent)
|
||||
#define scan_context() (__context)
|
||||
|
||||
|
||||
#define foreach_memory_block(context, block) \
|
||||
for (block = (context)->mem_block; \
|
||||
block != NULL; \
|
||||
block = block->next) \
|
||||
|
||||
|
||||
#define first_memory_block(context) \
|
||||
(context)->mem_block
|
||||
|
||||
|
||||
#define is_undefined(object, ...) \
|
||||
yr_object_has_undefined_value(object, __VA_ARGS__)
|
||||
|
||||
|
||||
#define get_object(object, ...) \
|
||||
yr_object_lookup(object, 0, __VA_ARGS__)
|
||||
|
||||
|
||||
#define get_integer(object, ...) \
|
||||
yr_object_get_integer(object, __VA_ARGS__)
|
||||
|
||||
|
||||
#define get_float(object, ...) \
|
||||
yr_object_get_float(object, __VA_ARGS__)
|
||||
|
||||
|
||||
#define get_string(object, ...) \
|
||||
yr_object_get_string(object, __VA_ARGS__)
|
||||
|
||||
|
||||
#define set_integer(value, object, ...) \
|
||||
yr_object_set_integer(value, object, __VA_ARGS__)
|
||||
|
||||
|
||||
#define set_float(value, object, ...) \
|
||||
yr_object_set_float(value, object, __VA_ARGS__)
|
||||
|
||||
|
||||
#define set_sized_string(value, len, object, ...) \
|
||||
yr_object_set_string(value, len, object, __VA_ARGS__)
|
||||
|
||||
|
||||
#define set_string(value, object, ...) \
|
||||
set_sized_string(value, strlen(value), object, __VA_ARGS__)
|
||||
|
||||
|
||||
#define return_integer(integer) { \
|
||||
assertf( \
|
||||
__function_obj->return_obj->type == OBJECT_TYPE_INTEGER, \
|
||||
"return type differs from function declaration"); \
|
||||
yr_object_set_integer( \
|
||||
(integer), \
|
||||
__function_obj->return_obj, \
|
||||
NULL); \
|
||||
return ERROR_SUCCESS; \
|
||||
}
|
||||
|
||||
|
||||
#define return_float(double_) { \
|
||||
assertf( \
|
||||
__function_obj->return_obj->type == OBJECT_TYPE_FLOAT, \
|
||||
"return type differs from function declaration"); \
|
||||
double d = (double) (double_); \
|
||||
yr_object_set_float( \
|
||||
(d != (double) UNDEFINED) ? d : NAN, \
|
||||
__function_obj->return_obj, \
|
||||
NULL); \
|
||||
return ERROR_SUCCESS; \
|
||||
}
|
||||
|
||||
|
||||
#define return_string(string) { \
|
||||
assertf( \
|
||||
__function_obj->return_obj->type == OBJECT_TYPE_STRING, \
|
||||
"return type differs from function declaration"); \
|
||||
char* s = (char*) (string); \
|
||||
yr_object_set_string( \
|
||||
(s != (char*) UNDEFINED) ? s : NULL, \
|
||||
(s != (char*) UNDEFINED) ? strlen(s) : 0, \
|
||||
__function_obj->return_obj, \
|
||||
NULL); \
|
||||
return ERROR_SUCCESS; \
|
||||
}
|
||||
|
||||
|
||||
struct _YR_MODULE;
|
||||
|
||||
|
||||
typedef int (*YR_EXT_INITIALIZE_FUNC)(
|
||||
struct _YR_MODULE* module);
|
||||
|
||||
|
||||
typedef int (*YR_EXT_FINALIZE_FUNC)(
|
||||
struct _YR_MODULE* module);
|
||||
|
||||
|
||||
typedef int (*YR_EXT_DECLARATIONS_FUNC)(
|
||||
YR_OBJECT* module_object);
|
||||
|
||||
|
||||
typedef int (*YR_EXT_LOAD_FUNC)(
|
||||
YR_SCAN_CONTEXT* context,
|
||||
YR_OBJECT* module_object,
|
||||
void* module_data,
|
||||
size_t module_data_size);
|
||||
|
||||
|
||||
typedef int (*YR_EXT_UNLOAD_FUNC)(
|
||||
YR_OBJECT* module_object);
|
||||
|
||||
|
||||
typedef struct _YR_MODULE
|
||||
{
|
||||
tidx_mask_t is_loaded;
|
||||
|
||||
char* name;
|
||||
|
||||
YR_EXT_DECLARATIONS_FUNC declarations;
|
||||
YR_EXT_LOAD_FUNC load;
|
||||
YR_EXT_UNLOAD_FUNC unload;
|
||||
YR_EXT_INITIALIZE_FUNC initialize;
|
||||
YR_EXT_FINALIZE_FUNC finalize;
|
||||
|
||||
} YR_MODULE;
|
||||
|
||||
|
||||
typedef struct _YR_MODULE_IMPORT
|
||||
{
|
||||
const char* module_name;
|
||||
void* module_data;
|
||||
size_t module_data_size;
|
||||
|
||||
} YR_MODULE_IMPORT;
|
||||
|
||||
|
||||
int yr_modules_initialize(void);
|
||||
|
||||
|
||||
int yr_modules_finalize(void);
|
||||
|
||||
|
||||
int yr_modules_do_declarations(
|
||||
const char* module_name,
|
||||
YR_OBJECT* main_structure);
|
||||
|
||||
|
||||
int yr_modules_load(
|
||||
const char* module_name,
|
||||
YR_SCAN_CONTEXT* context);
|
||||
|
||||
|
||||
int yr_modules_unload_all(
|
||||
YR_SCAN_CONTEXT* context);
|
||||
|
||||
|
||||
void yr_modules_print_data(
|
||||
YR_SCAN_CONTEXT* context);
|
||||
#endif
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
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_OBJECT_H
|
||||
#define YR_OBJECT_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <float.h>
|
||||
#define isnan _isnan
|
||||
#define INFINITY (DBL_MAX + DBL_MAX)
|
||||
#define NAN (INFINITY-INFINITY)
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
||||
#define OBJECT_CREATE 1
|
||||
|
||||
#define OBJECT_TYPE_INTEGER 1
|
||||
#define OBJECT_TYPE_STRING 2
|
||||
#define OBJECT_TYPE_STRUCTURE 3
|
||||
#define OBJECT_TYPE_ARRAY 4
|
||||
#define OBJECT_TYPE_FUNCTION 5
|
||||
#define OBJECT_TYPE_REGEXP 6
|
||||
#define OBJECT_TYPE_DICTIONARY 7
|
||||
#define OBJECT_TYPE_FLOAT 8
|
||||
|
||||
|
||||
int yr_object_create(
|
||||
int8_t type,
|
||||
const char* identifier,
|
||||
YR_OBJECT* parent,
|
||||
YR_OBJECT** object);
|
||||
|
||||
|
||||
int yr_object_function_create(
|
||||
const char* identifier,
|
||||
const char* arguments_fmt,
|
||||
const char* return_fmt,
|
||||
YR_MODULE_FUNC func,
|
||||
YR_OBJECT* parent,
|
||||
YR_OBJECT** function);
|
||||
|
||||
|
||||
int yr_object_from_external_variable(
|
||||
YR_EXTERNAL_VARIABLE* external,
|
||||
YR_OBJECT** object);
|
||||
|
||||
|
||||
void yr_object_destroy(
|
||||
YR_OBJECT* object);
|
||||
|
||||
|
||||
YR_OBJECT* yr_object_lookup_field(
|
||||
YR_OBJECT* object,
|
||||
const char* field_name);
|
||||
|
||||
|
||||
YR_OBJECT* yr_object_lookup(
|
||||
YR_OBJECT* root,
|
||||
int flags,
|
||||
const char* pattern,
|
||||
...);
|
||||
|
||||
|
||||
int yr_object_has_undefined_value(
|
||||
YR_OBJECT* object,
|
||||
const char* field,
|
||||
...);
|
||||
|
||||
int64_t yr_object_get_integer(
|
||||
YR_OBJECT* object,
|
||||
const char* field,
|
||||
...);
|
||||
|
||||
|
||||
SIZED_STRING* yr_object_get_string(
|
||||
YR_OBJECT* object,
|
||||
const char* field,
|
||||
...);
|
||||
|
||||
|
||||
int yr_object_set_integer(
|
||||
int64_t value,
|
||||
YR_OBJECT* object,
|
||||
const char* field,
|
||||
...);
|
||||
|
||||
|
||||
int yr_object_set_float(
|
||||
double value,
|
||||
YR_OBJECT* object,
|
||||
const char* field,
|
||||
...);
|
||||
|
||||
|
||||
int yr_object_set_string(
|
||||
const char* value,
|
||||
size_t len,
|
||||
YR_OBJECT* object,
|
||||
const char* field,
|
||||
...);
|
||||
|
||||
|
||||
YR_OBJECT* yr_object_array_get_item(
|
||||
YR_OBJECT* object,
|
||||
int flags,
|
||||
int index);
|
||||
|
||||
|
||||
int yr_object_array_set_item(
|
||||
YR_OBJECT* object,
|
||||
YR_OBJECT* item,
|
||||
int index);
|
||||
|
||||
|
||||
YR_OBJECT* yr_object_dict_get_item(
|
||||
YR_OBJECT* object,
|
||||
int flags,
|
||||
const char* key);
|
||||
|
||||
|
||||
int yr_object_dict_set_item(
|
||||
YR_OBJECT* object,
|
||||
YR_OBJECT* item,
|
||||
const char* key);
|
||||
|
||||
|
||||
int yr_object_structure_set_member(
|
||||
YR_OBJECT* object,
|
||||
YR_OBJECT* member);
|
||||
|
||||
|
||||
YR_OBJECT* yr_object_get_root(
|
||||
YR_OBJECT* object);
|
||||
|
||||
|
||||
void yr_object_print_data(
|
||||
YR_OBJECT* object,
|
||||
int indent);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
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_PARSER_H
|
||||
#define YR_PARSER_H
|
||||
|
||||
|
||||
#include "lexer.h"
|
||||
|
||||
|
||||
int yr_parser_emit(
|
||||
yyscan_t yyscanner,
|
||||
int8_t instruction,
|
||||
int8_t** instruction_address);
|
||||
|
||||
|
||||
int yr_parser_emit_with_arg(
|
||||
yyscan_t yyscanner,
|
||||
int8_t instruction,
|
||||
int64_t argument,
|
||||
int8_t** instruction_address);
|
||||
|
||||
|
||||
int yr_parser_emit_with_arg_double(
|
||||
yyscan_t yyscanner,
|
||||
int8_t instruction,
|
||||
double argument,
|
||||
int8_t** instruction_address);
|
||||
|
||||
|
||||
int yr_parser_emit_with_arg_reloc(
|
||||
yyscan_t yyscanner,
|
||||
int8_t instruction,
|
||||
int64_t argument,
|
||||
int8_t** instruction_address);
|
||||
|
||||
|
||||
int yr_parser_check_types(
|
||||
YR_COMPILER* compiler,
|
||||
YR_OBJECT_FUNCTION* function,
|
||||
const char* actual_args_fmt);
|
||||
|
||||
|
||||
YR_STRING* yr_parser_lookup_string(
|
||||
yyscan_t yyscanner,
|
||||
const char* identifier);
|
||||
|
||||
|
||||
int yr_parser_lookup_loop_variable(
|
||||
yyscan_t yyscanner,
|
||||
const char* identifier);
|
||||
|
||||
|
||||
int yr_parser_reduce_rule_declaration(
|
||||
yyscan_t yyscanner,
|
||||
int flags,
|
||||
const char* identifier,
|
||||
char* tags,
|
||||
YR_STRING* strings,
|
||||
YR_META* metas);
|
||||
|
||||
|
||||
YR_STRING* yr_parser_reduce_string_declaration(
|
||||
yyscan_t yyscanner,
|
||||
int flags,
|
||||
const char* identifier,
|
||||
SIZED_STRING* str);
|
||||
|
||||
|
||||
YR_META* yr_parser_reduce_meta_declaration(
|
||||
yyscan_t yyscanner,
|
||||
int32_t type,
|
||||
const char* identifier,
|
||||
const char* string,
|
||||
int32_t integer);
|
||||
|
||||
|
||||
int yr_parser_reduce_string_identifier(
|
||||
yyscan_t yyscanner,
|
||||
const char* identifier,
|
||||
int8_t instruction,
|
||||
uint64_t at_offset);
|
||||
|
||||
|
||||
int yr_parser_emit_pushes_for_strings(
|
||||
yyscan_t yyscanner,
|
||||
const char* identifier);
|
||||
|
||||
|
||||
int yr_parser_reduce_external(
|
||||
yyscan_t yyscanner,
|
||||
const char* identifier,
|
||||
int8_t intruction);
|
||||
|
||||
|
||||
int yr_parser_reduce_import(
|
||||
yyscan_t yyscanner,
|
||||
SIZED_STRING* module_name);
|
||||
|
||||
|
||||
int yr_parser_reduce_operation(
|
||||
yyscan_t yyscanner,
|
||||
const char* operation,
|
||||
EXPRESSION left_operand,
|
||||
EXPRESSION right_operand);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,491 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
// These definitions are not present in older Windows headers.
|
||||
|
||||
#ifndef IMAGE_FILE_MACHINE_ARMNT
|
||||
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
|
||||
#endif
|
||||
|
||||
#ifndef IMAGE_FILE_MACHINE_ARM64
|
||||
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uint8_t BYTE;
|
||||
typedef uint16_t WORD;
|
||||
typedef uint32_t DWORD;
|
||||
typedef int32_t LONG;
|
||||
typedef uint32_t ULONG;
|
||||
typedef uint64_t ULONGLONG;
|
||||
|
||||
|
||||
#define FIELD_OFFSET(type, field) ((size_t)&(((type *)0)->field))
|
||||
|
||||
#ifndef _MAC
|
||||
|
||||
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
|
||||
#define IMAGE_OS2_SIGNATURE 0x454E // NE
|
||||
#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
|
||||
#define IMAGE_VXD_SIGNATURE 0x454C // LE
|
||||
#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
|
||||
|
||||
#else
|
||||
|
||||
#define IMAGE_DOS_SIGNATURE 0x4D5A // MZ
|
||||
#define IMAGE_OS2_SIGNATURE 0x4E45 // NE
|
||||
#define IMAGE_OS2_SIGNATURE_LE 0x4C45 // LE
|
||||
#define IMAGE_NT_SIGNATURE 0x50450000 // PE00
|
||||
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 2)
|
||||
|
||||
typedef struct _IMAGE_DOS_HEADER // DOS .EXE header
|
||||
{
|
||||
WORD e_magic; // Magic number
|
||||
WORD e_cblp; // Bytes on last page of file
|
||||
WORD e_cp; // Pages in file
|
||||
WORD e_crlc; // Relocations
|
||||
WORD e_cparhdr; // Size of header in paragraphs
|
||||
WORD e_minalloc; // Minimum extra paragraphs needed
|
||||
WORD e_maxalloc; // Maximum extra paragraphs needed
|
||||
WORD e_ss; // Initial (relative) SS value
|
||||
WORD e_sp; // Initial SP value
|
||||
WORD e_csum; // Checksum
|
||||
WORD e_ip; // Initial IP value
|
||||
WORD e_cs; // Initial (relative) CS value
|
||||
WORD e_lfarlc; // File address of relocation table
|
||||
WORD e_ovno; // Overlay number
|
||||
WORD e_res[4]; // Reserved words
|
||||
WORD e_oemid; // OEM identifier (for e_oeminfo)
|
||||
WORD e_oeminfo; // OEM information; e_oemid specific
|
||||
WORD e_res2[10]; // Reserved words
|
||||
LONG e_lfanew; // File address of new exe header
|
||||
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
//
|
||||
// File header format.
|
||||
//
|
||||
|
||||
#pragma pack(push,4)
|
||||
|
||||
typedef struct _IMAGE_FILE_HEADER
|
||||
{
|
||||
WORD Machine;
|
||||
WORD NumberOfSections;
|
||||
DWORD TimeDateStamp;
|
||||
DWORD PointerToSymbolTable;
|
||||
DWORD NumberOfSymbols;
|
||||
WORD SizeOfOptionalHeader;
|
||||
WORD Characteristics;
|
||||
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
|
||||
|
||||
|
||||
|
||||
#define IMAGE_SIZEOF_FILE_HEADER 20
|
||||
|
||||
|
||||
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
|
||||
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
|
||||
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
|
||||
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
|
||||
#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Agressively trim working set
|
||||
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses
|
||||
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
|
||||
#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
|
||||
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
|
||||
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file.
|
||||
#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file.
|
||||
#define IMAGE_FILE_SYSTEM 0x1000 // System File.
|
||||
#define IMAGE_FILE_DLL 0x2000 // File is a DLL.
|
||||
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine
|
||||
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
|
||||
|
||||
|
||||
#define IMAGE_FILE_MACHINE_UNKNOWN 0x0000
|
||||
#define IMAGE_FILE_MACHINE_AM33 0x01d3
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define IMAGE_FILE_MACHINE_ARM 0x01c0
|
||||
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
|
||||
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
|
||||
#define IMAGE_FILE_MACHINE_EBC 0x0ebc
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||
#define IMAGE_FILE_MACHINE_IA64 0x0200
|
||||
#define IMAGE_FILE_MACHINE_M32R 0x9041
|
||||
#define IMAGE_FILE_MACHINE_MIPS16 0x0266
|
||||
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366
|
||||
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466
|
||||
#define IMAGE_FILE_MACHINE_POWERPC 0x01f0
|
||||
#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
|
||||
#define IMAGE_FILE_MACHINE_R4000 0x0166
|
||||
#define IMAGE_FILE_MACHINE_SH3 0x01a2
|
||||
#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
|
||||
#define IMAGE_FILE_MACHINE_SH4 0x01a6
|
||||
#define IMAGE_FILE_MACHINE_SH5 0x01a8
|
||||
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
|
||||
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
|
||||
|
||||
// Section characteristics
|
||||
#define IMAGE_SCN_CNT_CODE 0x00000020
|
||||
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
|
||||
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
|
||||
#define IMAGE_SCN_GPREL 0x00008000
|
||||
#define IMAGE_SCN_MEM_16BIT 0x00020000
|
||||
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
|
||||
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
|
||||
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
|
||||
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
|
||||
#define IMAGE_SCN_MEM_SHARED 0x10000000
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||
#define IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
|
||||
//
|
||||
// Directory format.
|
||||
//
|
||||
|
||||
typedef struct _IMAGE_DATA_DIRECTORY
|
||||
{
|
||||
DWORD VirtualAddress;
|
||||
DWORD Size;
|
||||
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
|
||||
|
||||
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||
|
||||
|
||||
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
|
||||
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
|
||||
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
|
||||
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
|
||||
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
|
||||
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
|
||||
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
|
||||
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
|
||||
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
|
||||
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
|
||||
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
|
||||
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
|
||||
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
|
||||
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
|
||||
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
|
||||
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
|
||||
|
||||
|
||||
//
|
||||
// Optional header format.
|
||||
//
|
||||
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER32
|
||||
{
|
||||
WORD Magic;
|
||||
BYTE MajorLinkerVersion;
|
||||
BYTE MinorLinkerVersion;
|
||||
DWORD SizeOfCode;
|
||||
DWORD SizeOfInitializedData;
|
||||
DWORD SizeOfUninitializedData;
|
||||
DWORD AddressOfEntryPoint;
|
||||
DWORD BaseOfCode;
|
||||
DWORD BaseOfData;
|
||||
DWORD ImageBase;
|
||||
DWORD SectionAlignment;
|
||||
DWORD FileAlignment;
|
||||
WORD MajorOperatingSystemVersion;
|
||||
WORD MinorOperatingSystemVersion;
|
||||
WORD MajorImageVersion;
|
||||
WORD MinorImageVersion;
|
||||
WORD MajorSubsystemVersion;
|
||||
WORD MinorSubsystemVersion;
|
||||
DWORD Win32VersionValue;
|
||||
DWORD SizeOfImage;
|
||||
DWORD SizeOfHeaders;
|
||||
DWORD CheckSum;
|
||||
WORD Subsystem;
|
||||
WORD DllCharacteristics;
|
||||
DWORD SizeOfStackReserve;
|
||||
DWORD SizeOfStackCommit;
|
||||
DWORD SizeOfHeapReserve;
|
||||
DWORD SizeOfHeapCommit;
|
||||
DWORD LoaderFlags;
|
||||
DWORD NumberOfRvaAndSizes;
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||
|
||||
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
|
||||
|
||||
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER64
|
||||
{
|
||||
WORD Magic;
|
||||
BYTE MajorLinkerVersion;
|
||||
BYTE MinorLinkerVersion;
|
||||
DWORD SizeOfCode;
|
||||
DWORD SizeOfInitializedData;
|
||||
DWORD SizeOfUninitializedData;
|
||||
DWORD AddressOfEntryPoint;
|
||||
DWORD BaseOfCode;
|
||||
ULONGLONG ImageBase;
|
||||
DWORD SectionAlignment;
|
||||
DWORD FileAlignment;
|
||||
WORD MajorOperatingSystemVersion;
|
||||
WORD MinorOperatingSystemVersion;
|
||||
WORD MajorImageVersion;
|
||||
WORD MinorImageVersion;
|
||||
WORD MajorSubsystemVersion;
|
||||
WORD MinorSubsystemVersion;
|
||||
DWORD Win32VersionValue;
|
||||
DWORD SizeOfImage;
|
||||
DWORD SizeOfHeaders;
|
||||
DWORD CheckSum;
|
||||
WORD Subsystem;
|
||||
WORD DllCharacteristics;
|
||||
ULONGLONG SizeOfStackReserve;
|
||||
ULONGLONG SizeOfStackCommit;
|
||||
ULONGLONG SizeOfHeapReserve;
|
||||
ULONGLONG SizeOfHeapCommit;
|
||||
DWORD LoaderFlags;
|
||||
DWORD NumberOfRvaAndSizes;
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||
|
||||
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
|
||||
|
||||
|
||||
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
|
||||
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
|
||||
|
||||
|
||||
typedef struct _IMAGE_NT_HEADERS32
|
||||
{
|
||||
DWORD Signature;
|
||||
IMAGE_FILE_HEADER FileHeader;
|
||||
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
|
||||
|
||||
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
|
||||
|
||||
|
||||
typedef struct _IMAGE_NT_HEADERS64
|
||||
{
|
||||
DWORD Signature;
|
||||
IMAGE_FILE_HEADER FileHeader;
|
||||
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
|
||||
|
||||
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
|
||||
|
||||
|
||||
// IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is
|
||||
// the same either way.
|
||||
|
||||
#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
|
||||
((BYTE*)ntheader + \
|
||||
FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) + \
|
||||
((PIMAGE_NT_HEADERS32)(ntheader))->FileHeader.SizeOfOptionalHeader \
|
||||
))
|
||||
|
||||
// Subsystem Values
|
||||
|
||||
#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem.
|
||||
#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem.
|
||||
#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
|
||||
#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
|
||||
#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem.
|
||||
#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image runs in the Posix character subsystem.
|
||||
#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 // image is a native Win9x driver.
|
||||
|
||||
//
|
||||
// Section header format.
|
||||
//
|
||||
|
||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||
|
||||
typedef struct _IMAGE_SECTION_HEADER
|
||||
{
|
||||
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
|
||||
union
|
||||
{
|
||||
DWORD PhysicalAddress;
|
||||
DWORD VirtualSize;
|
||||
} Misc;
|
||||
DWORD VirtualAddress;
|
||||
DWORD SizeOfRawData;
|
||||
DWORD PointerToRawData;
|
||||
DWORD PointerToRelocations;
|
||||
DWORD PointerToLinenumbers;
|
||||
WORD NumberOfRelocations;
|
||||
WORD NumberOfLinenumbers;
|
||||
DWORD Characteristics;
|
||||
|
||||
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
|
||||
|
||||
#define IMAGE_SIZEOF_SECTION_HEADER 40
|
||||
|
||||
|
||||
typedef struct _IMAGE_EXPORT_DIRECTORY
|
||||
{
|
||||
DWORD Characteristics;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD Name;
|
||||
DWORD Base;
|
||||
DWORD NumberOfFunctions;
|
||||
DWORD NumberOfNames;
|
||||
DWORD AddressOfFunctions;
|
||||
DWORD AddressOfNames;
|
||||
DWORD AddressOfNameOrdinals;
|
||||
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
|
||||
|
||||
|
||||
typedef struct _IMAGE_IMPORT_DESCRIPTOR
|
||||
{
|
||||
union
|
||||
{
|
||||
DWORD Characteristics;
|
||||
DWORD OriginalFirstThunk;
|
||||
} ;
|
||||
DWORD TimeDateStamp;
|
||||
DWORD ForwarderChain;
|
||||
DWORD Name;
|
||||
DWORD FirstThunk;
|
||||
|
||||
} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
|
||||
|
||||
|
||||
typedef struct _IMAGE_IMPORT_BY_NAME
|
||||
{
|
||||
WORD Hint;
|
||||
BYTE Name[1];
|
||||
|
||||
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
|
||||
|
||||
typedef struct _IMAGE_THUNK_DATA32
|
||||
{
|
||||
union
|
||||
{
|
||||
DWORD ForwarderString;
|
||||
DWORD Function;
|
||||
DWORD Ordinal;
|
||||
DWORD AddressOfData;
|
||||
} u1;
|
||||
|
||||
} IMAGE_THUNK_DATA32, *PIMAGE_THUNK_DATA32;
|
||||
|
||||
|
||||
#define IMAGE_ORDINAL_FLAG32 0x80000000
|
||||
#define IMAGE_ORDINAL_FLAG64 0x8000000000000000L
|
||||
|
||||
typedef struct _IMAGE_THUNK_DATA64
|
||||
{
|
||||
union
|
||||
{
|
||||
ULONGLONG ForwarderString;
|
||||
ULONGLONG Function;
|
||||
ULONGLONG Ordinal;
|
||||
ULONGLONG AddressOfData;
|
||||
} u1;
|
||||
|
||||
} IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64;
|
||||
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
|
||||
{
|
||||
DWORD Name;
|
||||
DWORD OffsetToData;
|
||||
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DATA_ENTRY
|
||||
{
|
||||
DWORD OffsetToData;
|
||||
DWORD Size;
|
||||
DWORD CodePage;
|
||||
DWORD Reserved;
|
||||
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DIRECTORY
|
||||
{
|
||||
DWORD Characteristics;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
WORD NumberOfNamedEntries;
|
||||
WORD NumberOfIdEntries;
|
||||
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
typedef struct _VERSION_INFO
|
||||
{
|
||||
WORD Length;
|
||||
WORD ValueLength;
|
||||
WORD Type;
|
||||
char Key[0];
|
||||
} VERSION_INFO, *PVERSION_INFO;
|
||||
|
||||
|
||||
#define WIN_CERT_REVISION_1_0 0x0100
|
||||
#define WIN_CERT_REVISION_2_0 0x0200
|
||||
|
||||
#define WIN_CERT_TYPE_X509 0x0001
|
||||
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||||
#define WIN_CERT_TYPE_RESERVED_1 0x0003
|
||||
#define WIN_CERT_TYPE_TS_STACK_SIGNED 0x0004
|
||||
|
||||
typedef struct _WIN_CERTIFICATE
|
||||
{
|
||||
DWORD Length;
|
||||
WORD Revision;
|
||||
WORD CertificateType;
|
||||
BYTE Certificate[1];
|
||||
} WIN_CERTIFICATE, *PWIN_CERTIFICATE;
|
||||
|
||||
|
||||
//
|
||||
// Rich signature.
|
||||
// http://www.ntcore.com/files/richsign.htm
|
||||
//
|
||||
|
||||
typedef struct _RICH_SIGNATURE
|
||||
{
|
||||
DWORD dans;
|
||||
DWORD key1;
|
||||
DWORD key2;
|
||||
DWORD key3;
|
||||
} RICH_SIGNATURE, *PRICH_SIGNATURE;
|
||||
|
||||
#define RICH_DANS 0x536e6144 // "DanS"
|
||||
#define RICH_RICH 0x68636952 // "Rich"
|
||||
|
||||
typedef struct _RICH_DATA
|
||||
{
|
||||
size_t len;
|
||||
BYTE* raw_data;
|
||||
BYTE* clear_data;
|
||||
} RICH_DATA, *PRICH_DATA;
|
||||
|
||||
#pragma pack(pop)
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright (c) 2007. 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_PROC_H
|
||||
#define YR_PROC_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
int yr_process_get_memory(
|
||||
int pid,
|
||||
YR_MEMORY_BLOCK** first_block);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
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_RE_H
|
||||
#define YR_RE_H
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "arena.h"
|
||||
#include "sizedstr.h"
|
||||
|
||||
#define RE_NODE_LITERAL 1
|
||||
#define RE_NODE_MASKED_LITERAL 2
|
||||
#define RE_NODE_ANY 3
|
||||
#define RE_NODE_CONCAT 4
|
||||
#define RE_NODE_ALT 5
|
||||
#define RE_NODE_RANGE 6
|
||||
#define RE_NODE_STAR 7
|
||||
#define RE_NODE_PLUS 8
|
||||
#define RE_NODE_CLASS 9
|
||||
#define RE_NODE_WORD_CHAR 10
|
||||
#define RE_NODE_NON_WORD_CHAR 11
|
||||
#define RE_NODE_SPACE 12
|
||||
#define RE_NODE_NON_SPACE 13
|
||||
#define RE_NODE_DIGIT 14
|
||||
#define RE_NODE_NON_DIGIT 15
|
||||
#define RE_NODE_EMPTY 16
|
||||
#define RE_NODE_ANCHOR_START 17
|
||||
#define RE_NODE_ANCHOR_END 18
|
||||
#define RE_NODE_WORD_BOUNDARY 19
|
||||
#define RE_NODE_NON_WORD_BOUNDARY 20
|
||||
|
||||
|
||||
#define RE_OPCODE_ANY 0xA0
|
||||
#define RE_OPCODE_ANY_EXCEPT_NEW_LINE 0xA1
|
||||
#define RE_OPCODE_LITERAL 0xA2
|
||||
#define RE_OPCODE_LITERAL_NO_CASE 0xA3
|
||||
#define RE_OPCODE_MASKED_LITERAL 0xA4
|
||||
#define RE_OPCODE_CLASS 0xA5
|
||||
#define RE_OPCODE_CLASS_NO_CASE 0xA6
|
||||
#define RE_OPCODE_WORD_CHAR 0xA7
|
||||
#define RE_OPCODE_NON_WORD_CHAR 0xA8
|
||||
#define RE_OPCODE_SPACE 0xA9
|
||||
#define RE_OPCODE_NON_SPACE 0xAA
|
||||
#define RE_OPCODE_DIGIT 0xAB
|
||||
#define RE_OPCODE_NON_DIGIT 0xAC
|
||||
#define RE_OPCODE_MATCH 0xAD
|
||||
|
||||
#define RE_OPCODE_MATCH_AT_END 0xB0
|
||||
#define RE_OPCODE_MATCH_AT_START 0xB1
|
||||
#define RE_OPCODE_WORD_BOUNDARY 0xB2
|
||||
#define RE_OPCODE_NON_WORD_BOUNDARY 0xB3
|
||||
|
||||
#define RE_OPCODE_SPLIT_A 0xC0
|
||||
#define RE_OPCODE_SPLIT_B 0xC1
|
||||
#define RE_OPCODE_PUSH 0xC2
|
||||
#define RE_OPCODE_POP 0xC3
|
||||
#define RE_OPCODE_JNZ 0xC4
|
||||
#define RE_OPCODE_JUMP 0xC5
|
||||
|
||||
|
||||
#define RE_FLAGS_FAST_HEX_REGEXP 0x02
|
||||
#define RE_FLAGS_BACKWARDS 0x04
|
||||
#define RE_FLAGS_EXHAUSTIVE 0x08
|
||||
#define RE_FLAGS_WIDE 0x10
|
||||
#define RE_FLAGS_NO_CASE 0x20
|
||||
#define RE_FLAGS_SCAN 0x40
|
||||
#define RE_FLAGS_DOT_ALL 0x80
|
||||
#define RE_FLAGS_NOT_AT_START 0x100
|
||||
|
||||
|
||||
typedef struct RE RE;
|
||||
typedef struct RE_NODE RE_NODE;
|
||||
typedef struct RE_ERROR RE_ERROR;
|
||||
|
||||
typedef uint8_t* RE_CODE;
|
||||
|
||||
#define CHAR_IN_CLASS(chr, cls) \
|
||||
((cls)[(chr) / 8] & 1 << ((chr) % 8))
|
||||
|
||||
|
||||
#define IS_WORD_CHAR(chr) \
|
||||
(isalnum(chr) || (chr) == '_')
|
||||
|
||||
|
||||
struct RE_NODE
|
||||
{
|
||||
int type;
|
||||
|
||||
union
|
||||
{
|
||||
int value;
|
||||
int count;
|
||||
int start;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
int mask;
|
||||
int end;
|
||||
};
|
||||
|
||||
int greedy;
|
||||
|
||||
uint8_t* class_vector;
|
||||
|
||||
RE_NODE* left;
|
||||
RE_NODE* right;
|
||||
|
||||
RE_CODE forward_code;
|
||||
RE_CODE backward_code;
|
||||
};
|
||||
|
||||
|
||||
struct RE
|
||||
{
|
||||
|
||||
uint32_t flags;
|
||||
RE_NODE* root_node;
|
||||
YR_ARENA* code_arena;
|
||||
RE_CODE code;
|
||||
};
|
||||
|
||||
|
||||
struct RE_ERROR
|
||||
{
|
||||
|
||||
char message[512];
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef int RE_MATCH_CALLBACK_FUNC(
|
||||
uint8_t* match,
|
||||
int match_length,
|
||||
int flags,
|
||||
void* args);
|
||||
|
||||
|
||||
int yr_re_create(
|
||||
RE** re);
|
||||
|
||||
|
||||
int yr_re_parse(
|
||||
const char* re_string,
|
||||
int flags,
|
||||
RE** re,
|
||||
RE_ERROR* error);
|
||||
|
||||
|
||||
int yr_re_parse_hex(
|
||||
const char* hex_string,
|
||||
int flags,
|
||||
RE** re,
|
||||
RE_ERROR* error);
|
||||
|
||||
|
||||
int yr_re_compile(
|
||||
const char* re_string,
|
||||
int flags,
|
||||
YR_ARENA* code_arena,
|
||||
RE** re,
|
||||
RE_ERROR* error);
|
||||
|
||||
|
||||
void yr_re_destroy(
|
||||
RE* re);
|
||||
|
||||
|
||||
void yr_re_print(
|
||||
RE* re);
|
||||
|
||||
|
||||
RE_NODE* yr_re_node_create(
|
||||
int type,
|
||||
RE_NODE* left,
|
||||
RE_NODE* right);
|
||||
|
||||
|
||||
void yr_re_node_destroy(
|
||||
RE_NODE* node);
|
||||
|
||||
|
||||
SIZED_STRING* yr_re_extract_literal(
|
||||
RE* re);
|
||||
|
||||
|
||||
int yr_re_contains_dot_star(
|
||||
RE* re);
|
||||
|
||||
|
||||
int yr_re_split_at_chaining_point(
|
||||
RE* re,
|
||||
RE** result_re,
|
||||
RE** remainder_re,
|
||||
int32_t* min_gap,
|
||||
int32_t* max_gap);
|
||||
|
||||
|
||||
int yr_re_emit_code(
|
||||
RE* re,
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
int yr_re_exec(
|
||||
RE_CODE re_code,
|
||||
uint8_t* input,
|
||||
size_t input_size,
|
||||
int flags,
|
||||
RE_MATCH_CALLBACK_FUNC callback,
|
||||
void* callback_args);
|
||||
|
||||
|
||||
int yr_re_match(
|
||||
RE_CODE re_code,
|
||||
const char* target);
|
||||
|
||||
|
||||
int yr_re_initialize(void);
|
||||
|
||||
|
||||
int yr_re_finalize(void);
|
||||
|
||||
|
||||
int yr_re_finalize_thread(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#undef yyparse
|
||||
#undef yylex
|
||||
#undef yyerror
|
||||
#undef yyfatal
|
||||
#undef yychar
|
||||
#undef yydebug
|
||||
#undef yynerrs
|
||||
#undef yyget_extra
|
||||
#undef yyget_lineno
|
||||
|
||||
#undef YY_FATAL_ERROR
|
||||
#undef YY_DECL
|
||||
#undef LEX_ENV
|
||||
|
||||
|
||||
#define yyparse re_yyparse
|
||||
#define yylex re_yylex
|
||||
#define yyerror re_yyerror
|
||||
#define yyfatal re_yyfatal
|
||||
#define yychar re_yychar
|
||||
#define yydebug re_yydebug
|
||||
#define yynerrs re_yynerrs
|
||||
#define yyget_extra re_yyget_extra
|
||||
#define yyget_lineno re_yyget_lineno
|
||||
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
#define YY_EXTRA_TYPE RE*
|
||||
#define YY_USE_CONST
|
||||
|
||||
|
||||
typedef struct _RE_LEX_ENVIRONMENT
|
||||
{
|
||||
int negated_class;
|
||||
uint8_t class_vector[32];
|
||||
int last_error_code;
|
||||
char last_error_message[256];
|
||||
|
||||
} RE_LEX_ENVIRONMENT;
|
||||
|
||||
|
||||
#define LEX_ENV ((RE_LEX_ENVIRONMENT*) lex_env)
|
||||
|
||||
#define YY_FATAL_ERROR(msg) re_yyfatal(yyscanner, msg)
|
||||
|
||||
#include <re_grammar.h>
|
||||
|
||||
#define YY_DECL int re_yylex \
|
||||
(YYSTYPE * yylval_param , yyscan_t yyscanner, RE_LEX_ENVIRONMENT* lex_env)
|
||||
|
||||
|
||||
YY_EXTRA_TYPE yyget_extra(
|
||||
yyscan_t yyscanner);
|
||||
|
||||
int yylex(
|
||||
YYSTYPE* yylval_param,
|
||||
yyscan_t yyscanner,
|
||||
RE_LEX_ENVIRONMENT* lex_env);
|
||||
|
||||
int yyparse(
|
||||
void* yyscanner,
|
||||
RE_LEX_ENVIRONMENT* lex_env);
|
||||
|
||||
void yyerror(
|
||||
yyscan_t yyscanner,
|
||||
RE_LEX_ENVIRONMENT* lex_env,
|
||||
const char* error_message);
|
||||
|
||||
void yyfatal(
|
||||
yyscan_t yyscanner,
|
||||
const char* error_message);
|
||||
|
||||
int yr_parse_re_string(
|
||||
const char* re_string,
|
||||
int flags,
|
||||
RE** re,
|
||||
RE_ERROR* error);
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
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_RULES_H
|
||||
#define YR_RULES_H
|
||||
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define CALLBACK_MSG_RULE_MATCHING 1
|
||||
#define CALLBACK_MSG_RULE_NOT_MATCHING 2
|
||||
#define CALLBACK_MSG_SCAN_FINISHED 3
|
||||
#define CALLBACK_MSG_IMPORT_MODULE 4
|
||||
|
||||
#define CALLBACK_CONTINUE 0
|
||||
#define CALLBACK_ABORT 1
|
||||
#define CALLBACK_ERROR 2
|
||||
|
||||
|
||||
#define yr_rule_tags_foreach(rule, tag_name) \
|
||||
for (tag_name = rule->tags; \
|
||||
tag_name != NULL && *tag_name != '\0'; \
|
||||
tag_name += strlen(tag_name) + 1)
|
||||
|
||||
|
||||
#define yr_rule_metas_foreach(rule, meta) \
|
||||
for (meta = rule->metas; !META_IS_NULL(meta); meta++)
|
||||
|
||||
|
||||
#define yr_rule_strings_foreach(rule, string) \
|
||||
for (string = rule->strings; !STRING_IS_NULL(string); string++)
|
||||
|
||||
|
||||
#define yr_string_matches_foreach(string, match) \
|
||||
for (match = STRING_MATCHES(string).head; match != NULL; match = match->next)
|
||||
|
||||
|
||||
#define yr_rules_foreach(rules, rule) \
|
||||
for (rule = rules->rules_list_head; !RULE_IS_NULL(rule); rule++)
|
||||
|
||||
|
||||
|
||||
YR_API int yr_rules_scan_mem(
|
||||
YR_RULES* rules,
|
||||
uint8_t* buffer,
|
||||
size_t buffer_size,
|
||||
int flags,
|
||||
YR_CALLBACK_FUNC callback,
|
||||
void* user_data,
|
||||
int timeout);
|
||||
|
||||
|
||||
YR_API int yr_rules_scan_file(
|
||||
YR_RULES* rules,
|
||||
const char* filename,
|
||||
int flags,
|
||||
YR_CALLBACK_FUNC callback,
|
||||
void* user_data,
|
||||
int timeout);
|
||||
|
||||
|
||||
YR_API int yr_rules_scan_proc(
|
||||
YR_RULES* rules,
|
||||
int pid,
|
||||
int flags,
|
||||
YR_CALLBACK_FUNC callback,
|
||||
void* user_data,
|
||||
int timeout);
|
||||
|
||||
|
||||
YR_API int yr_rules_save(
|
||||
YR_RULES* rules,
|
||||
const char* filename);
|
||||
|
||||
|
||||
YR_API int yr_rules_load(
|
||||
const char* filename,
|
||||
YR_RULES** rules);
|
||||
|
||||
|
||||
YR_API int yr_rules_destroy(
|
||||
YR_RULES* rules);
|
||||
|
||||
|
||||
YR_API int yr_rules_define_integer_variable(
|
||||
YR_RULES* rules,
|
||||
const char* identifier,
|
||||
int64_t value);
|
||||
|
||||
|
||||
YR_API int yr_rules_define_boolean_variable(
|
||||
YR_RULES* rules,
|
||||
const char* identifier,
|
||||
int value);
|
||||
|
||||
|
||||
YR_API int yr_rules_define_float_variable(
|
||||
YR_RULES* rules,
|
||||
const char* identifier,
|
||||
double value);
|
||||
|
||||
|
||||
YR_API int yr_rules_define_string_variable(
|
||||
YR_RULES* rules,
|
||||
const char* identifier,
|
||||
const char* value);
|
||||
|
||||
|
||||
YR_API void yr_rules_print_profiling_info(
|
||||
YR_RULES* rules);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
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_SCAN_H
|
||||
#define YR_SCAN_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define SCAN_FLAGS_FAST_MODE 1
|
||||
#define SCAN_FLAGS_PROCESS_MEMORY 2
|
||||
|
||||
|
||||
int yr_scan_verify_match(
|
||||
YR_AC_MATCH* ac_match,
|
||||
uint8_t* data,
|
||||
size_t data_size,
|
||||
size_t data_base,
|
||||
size_t offset,
|
||||
YR_ARENA* matches_arena,
|
||||
int flags);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright (c) 2007-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 _SIZEDSTR_H
|
||||
#define _SIZEDSTR_H
|
||||
|
||||
//
|
||||
// This struct is used to support strings containing null chars. The length of
|
||||
// the string is stored along the string data. However the string data is also
|
||||
// terminated with a null char.
|
||||
//
|
||||
|
||||
#define SIZED_STRING_FLAGS_NO_CASE 1
|
||||
#define SIZED_STRING_FLAGS_DOT_ALL 2
|
||||
|
||||
typedef struct _SIZED_STRING
|
||||
{
|
||||
int length;
|
||||
int flags;
|
||||
char c_string[1];
|
||||
|
||||
} SIZED_STRING;
|
||||
|
||||
|
||||
int sized_string_cmp(
|
||||
SIZED_STRING* s1,
|
||||
SIZED_STRING* s2);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright (c) 2007-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_STRUTILS_H
|
||||
#define YR_STRUTILS_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define snprintf _snprintf
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
|
||||
uint64_t xtoi(
|
||||
const char* hexstr);
|
||||
|
||||
|
||||
#if !HAVE_STRLCPY
|
||||
size_t strlcpy(
|
||||
char* dst,
|
||||
const char* src,
|
||||
size_t size);
|
||||
#endif
|
||||
|
||||
|
||||
#if !HAVE_STRLCAT
|
||||
size_t strlcat(
|
||||
char* dst,
|
||||
const char* src,
|
||||
size_t size);
|
||||
#endif
|
||||
|
||||
|
||||
#if !HAVE_MEMMEM
|
||||
void* memmem(
|
||||
const void* haystack,
|
||||
size_t haystack_size,
|
||||
const void* needle,
|
||||
size_t needle_size);
|
||||
#endif
|
||||
|
||||
|
||||
int strlen_w(
|
||||
const char* w_str);
|
||||
|
||||
|
||||
int strcmp_w(
|
||||
const char* w_str,
|
||||
const char* str);
|
||||
|
||||
|
||||
size_t strlcpy_w(
|
||||
char* dst,
|
||||
const char* w_src,
|
||||
size_t n);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
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_TYPES_H
|
||||
#define YR_TYPES_H
|
||||
|
||||
|
||||
#include "arena.h"
|
||||
#include "re.h"
|
||||
#include "limits.h"
|
||||
#include "hash.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
typedef HANDLE mutex_t;
|
||||
#else
|
||||
#include <pthread.h>
|
||||
typedef pthread_mutex_t mutex_t;
|
||||
#endif
|
||||
|
||||
typedef int32_t tidx_mask_t;
|
||||
|
||||
|
||||
#define DECLARE_REFERENCE(type, name) \
|
||||
union { type name; int64_t name##_; }
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
|
||||
#define NAMESPACE_TFLAGS_UNSATISFIED_GLOBAL 0x01
|
||||
|
||||
#define NAMESPACE_HAS_UNSATISFIED_GLOBAL(x) \
|
||||
((x)->t_flags[yr_get_tidx()] & NAMESPACE_TFLAGS_UNSATISFIED_GLOBAL)
|
||||
|
||||
|
||||
typedef struct _YR_NAMESPACE
|
||||
{
|
||||
int32_t t_flags[MAX_THREADS]; // Thread-specific flags
|
||||
DECLARE_REFERENCE(char*, name);
|
||||
|
||||
} YR_NAMESPACE;
|
||||
|
||||
|
||||
#define META_TYPE_NULL 0
|
||||
#define META_TYPE_INTEGER 1
|
||||
#define META_TYPE_STRING 2
|
||||
#define META_TYPE_BOOLEAN 3
|
||||
|
||||
#define META_IS_NULL(x) \
|
||||
((x) != NULL ? (x)->type == META_TYPE_NULL : TRUE)
|
||||
|
||||
|
||||
typedef struct _YR_META
|
||||
{
|
||||
int32_t type;
|
||||
int32_t integer;
|
||||
|
||||
DECLARE_REFERENCE(const char*, identifier);
|
||||
DECLARE_REFERENCE(char*, string);
|
||||
|
||||
} YR_META;
|
||||
|
||||
|
||||
typedef struct _YR_MATCH
|
||||
{
|
||||
int64_t base;
|
||||
int64_t offset;
|
||||
int32_t length;
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t* data; // Confirmed matches use "data",
|
||||
int32_t chain_length; // unconfirmed ones use "chain_length"
|
||||
};
|
||||
|
||||
struct _YR_MATCH* prev;
|
||||
struct _YR_MATCH* next;
|
||||
|
||||
} YR_MATCH;
|
||||
|
||||
|
||||
typedef struct _YR_MATCHES
|
||||
{
|
||||
int32_t count;
|
||||
|
||||
DECLARE_REFERENCE(YR_MATCH*, head);
|
||||
DECLARE_REFERENCE(YR_MATCH*, tail);
|
||||
|
||||
} YR_MATCHES;
|
||||
|
||||
|
||||
#define STRING_GFLAGS_REFERENCED 0x01
|
||||
#define STRING_GFLAGS_HEXADECIMAL 0x02
|
||||
#define STRING_GFLAGS_NO_CASE 0x04
|
||||
#define STRING_GFLAGS_ASCII 0x08
|
||||
#define STRING_GFLAGS_WIDE 0x10
|
||||
#define STRING_GFLAGS_REGEXP 0x20
|
||||
#define STRING_GFLAGS_FAST_HEX_REGEXP 0x40
|
||||
#define STRING_GFLAGS_FULL_WORD 0x80
|
||||
#define STRING_GFLAGS_ANONYMOUS 0x100
|
||||
#define STRING_GFLAGS_SINGLE_MATCH 0x200
|
||||
#define STRING_GFLAGS_LITERAL 0x400
|
||||
#define STRING_GFLAGS_FITS_IN_ATOM 0x800
|
||||
#define STRING_GFLAGS_NULL 0x1000
|
||||
#define STRING_GFLAGS_CHAIN_PART 0x2000
|
||||
#define STRING_GFLAGS_CHAIN_TAIL 0x4000
|
||||
#define STRING_GFLAGS_FIXED_OFFSET 0x8000
|
||||
|
||||
|
||||
#define STRING_IS_HEX(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_HEXADECIMAL)
|
||||
|
||||
#define STRING_IS_NO_CASE(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_NO_CASE)
|
||||
|
||||
#define STRING_IS_ASCII(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_ASCII)
|
||||
|
||||
#define STRING_IS_WIDE(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_WIDE)
|
||||
|
||||
#define STRING_IS_REGEXP(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_REGEXP)
|
||||
|
||||
#define STRING_IS_FULL_WORD(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_FULL_WORD)
|
||||
|
||||
#define STRING_IS_ANONYMOUS(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_ANONYMOUS)
|
||||
|
||||
#define STRING_IS_REFERENCED(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_REFERENCED)
|
||||
|
||||
#define STRING_IS_SINGLE_MATCH(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_SINGLE_MATCH)
|
||||
|
||||
#define STRING_IS_FIXED_OFFSET(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_FIXED_OFFSET)
|
||||
|
||||
#define STRING_IS_LITERAL(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_LITERAL)
|
||||
|
||||
#define STRING_IS_FAST_HEX_REGEXP(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_FAST_HEX_REGEXP)
|
||||
|
||||
#define STRING_IS_CHAIN_PART(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_CHAIN_PART)
|
||||
|
||||
#define STRING_IS_CHAIN_TAIL(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_CHAIN_TAIL)
|
||||
|
||||
#define STRING_IS_NULL(x) \
|
||||
((x) == NULL || ((x)->g_flags) & STRING_GFLAGS_NULL)
|
||||
|
||||
#define STRING_FITS_IN_ATOM(x) \
|
||||
(((x)->g_flags) & STRING_GFLAGS_FITS_IN_ATOM)
|
||||
|
||||
#define STRING_FOUND(x) \
|
||||
((x)->matches[yr_get_tidx()].tail != NULL)
|
||||
|
||||
#define STRING_MATCHES(x) \
|
||||
((x)->matches[yr_get_tidx()])
|
||||
|
||||
|
||||
typedef struct _YR_STRING
|
||||
{
|
||||
int32_t g_flags;
|
||||
int32_t length;
|
||||
|
||||
DECLARE_REFERENCE(char*, identifier);
|
||||
DECLARE_REFERENCE(uint8_t*, string);
|
||||
DECLARE_REFERENCE(struct _YR_STRING*, chained_to);
|
||||
|
||||
int32_t chain_gap_min;
|
||||
int32_t chain_gap_max;
|
||||
|
||||
int64_t fixed_offset;
|
||||
|
||||
YR_MATCHES matches[MAX_THREADS];
|
||||
YR_MATCHES unconfirmed_matches[MAX_THREADS];
|
||||
|
||||
#ifdef PROFILING_ENABLED
|
||||
uint64_t clock_ticks;
|
||||
#endif
|
||||
|
||||
} YR_STRING;
|
||||
|
||||
|
||||
#define RULE_TFLAGS_MATCH 0x01
|
||||
|
||||
#define RULE_GFLAGS_PRIVATE 0x01
|
||||
#define RULE_GFLAGS_GLOBAL 0x02
|
||||
#define RULE_GFLAGS_REQUIRE_EXECUTABLE 0x04
|
||||
#define RULE_GFLAGS_REQUIRE_FILE 0x08
|
||||
#define RULE_GFLAGS_NULL 0x1000
|
||||
|
||||
#define RULE_IS_PRIVATE(x) \
|
||||
(((x)->g_flags) & RULE_GFLAGS_PRIVATE)
|
||||
|
||||
#define RULE_IS_GLOBAL(x) \
|
||||
(((x)->g_flags) & RULE_GFLAGS_GLOBAL)
|
||||
|
||||
#define RULE_IS_NULL(x) \
|
||||
(((x)->g_flags) & RULE_GFLAGS_NULL)
|
||||
|
||||
#define RULE_MATCHES(x) \
|
||||
((x)->t_flags[yr_get_tidx()] & RULE_TFLAGS_MATCH)
|
||||
|
||||
|
||||
typedef struct _YR_RULE
|
||||
{
|
||||
int32_t g_flags; // Global flags
|
||||
int32_t t_flags[MAX_THREADS]; // Thread-specific flags
|
||||
|
||||
DECLARE_REFERENCE(const char*, identifier);
|
||||
DECLARE_REFERENCE(const char*, tags);
|
||||
DECLARE_REFERENCE(YR_META*, metas);
|
||||
DECLARE_REFERENCE(YR_STRING*, strings);
|
||||
DECLARE_REFERENCE(YR_NAMESPACE*, ns);
|
||||
|
||||
#ifdef PROFILING_ENABLED
|
||||
uint64_t clock_ticks;
|
||||
#endif
|
||||
|
||||
} YR_RULE;
|
||||
|
||||
|
||||
#define EXTERNAL_VARIABLE_TYPE_NULL 0
|
||||
#define EXTERNAL_VARIABLE_TYPE_FLOAT 1
|
||||
#define EXTERNAL_VARIABLE_TYPE_INTEGER 2
|
||||
#define EXTERNAL_VARIABLE_TYPE_BOOLEAN 3
|
||||
#define EXTERNAL_VARIABLE_TYPE_STRING 4
|
||||
#define EXTERNAL_VARIABLE_TYPE_MALLOC_STRING 5
|
||||
|
||||
|
||||
#define EXTERNAL_VARIABLE_IS_NULL(x) \
|
||||
((x) != NULL ? (x)->type == EXTERNAL_VARIABLE_TYPE_NULL : TRUE)
|
||||
|
||||
|
||||
typedef struct _YR_EXTERNAL_VARIABLE
|
||||
{
|
||||
int32_t type;
|
||||
|
||||
union
|
||||
{
|
||||
int64_t i;
|
||||
double f;
|
||||
char* s;
|
||||
} value;
|
||||
|
||||
DECLARE_REFERENCE(char*, identifier);
|
||||
|
||||
} YR_EXTERNAL_VARIABLE;
|
||||
|
||||
|
||||
typedef struct _YR_AC_MATCH
|
||||
{
|
||||
uint16_t backtrack;
|
||||
|
||||
DECLARE_REFERENCE(YR_STRING*, string);
|
||||
DECLARE_REFERENCE(uint8_t*, forward_code);
|
||||
DECLARE_REFERENCE(uint8_t*, backward_code);
|
||||
DECLARE_REFERENCE(struct _YR_AC_MATCH*, next);
|
||||
|
||||
} YR_AC_MATCH;
|
||||
|
||||
|
||||
typedef struct _YR_AC_STATE
|
||||
{
|
||||
int8_t depth;
|
||||
|
||||
DECLARE_REFERENCE(struct _YR_AC_STATE*, failure);
|
||||
DECLARE_REFERENCE(YR_AC_MATCH*, matches);
|
||||
|
||||
} YR_AC_STATE;
|
||||
|
||||
|
||||
typedef struct _YR_AC_STATE_TRANSITION
|
||||
{
|
||||
uint8_t input;
|
||||
|
||||
DECLARE_REFERENCE(YR_AC_STATE*, state);
|
||||
DECLARE_REFERENCE(struct _YR_AC_STATE_TRANSITION*, next);
|
||||
|
||||
} YR_AC_STATE_TRANSITION;
|
||||
|
||||
|
||||
typedef struct _YR_AC_TABLE_BASED_STATE
|
||||
{
|
||||
int8_t depth;
|
||||
|
||||
DECLARE_REFERENCE(YR_AC_STATE*, failure);
|
||||
DECLARE_REFERENCE(YR_AC_MATCH*, matches);
|
||||
DECLARE_REFERENCE(YR_AC_STATE*, state) transitions[256];
|
||||
|
||||
} YR_AC_TABLE_BASED_STATE;
|
||||
|
||||
|
||||
typedef struct _YR_AC_LIST_BASED_STATE
|
||||
{
|
||||
int8_t depth;
|
||||
|
||||
DECLARE_REFERENCE(YR_AC_STATE*, failure);
|
||||
DECLARE_REFERENCE(YR_AC_MATCH*, matches);
|
||||
DECLARE_REFERENCE(YR_AC_STATE_TRANSITION*, transitions);
|
||||
|
||||
} YR_AC_LIST_BASED_STATE;
|
||||
|
||||
|
||||
typedef struct _YR_AC_AUTOMATON
|
||||
{
|
||||
DECLARE_REFERENCE(YR_AC_STATE*, root);
|
||||
|
||||
} YR_AC_AUTOMATON;
|
||||
|
||||
|
||||
typedef struct _YARA_RULES_FILE_HEADER
|
||||
{
|
||||
uint32_t version;
|
||||
|
||||
DECLARE_REFERENCE(YR_RULE*, rules_list_head);
|
||||
DECLARE_REFERENCE(YR_EXTERNAL_VARIABLE*, externals_list_head);
|
||||
DECLARE_REFERENCE(uint8_t*, code_start);
|
||||
DECLARE_REFERENCE(YR_AC_AUTOMATON*, automaton);
|
||||
|
||||
} YARA_RULES_FILE_HEADER;
|
||||
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
typedef struct _YR_RULES
|
||||
{
|
||||
|
||||
tidx_mask_t tidx_mask;
|
||||
uint8_t* code_start;
|
||||
|
||||
mutex_t mutex;
|
||||
|
||||
YR_ARENA* arena;
|
||||
YR_RULE* rules_list_head;
|
||||
YR_EXTERNAL_VARIABLE* externals_list_head;
|
||||
YR_AC_AUTOMATON* automaton;
|
||||
|
||||
} YR_RULES;
|
||||
|
||||
|
||||
typedef struct _YR_MEMORY_BLOCK
|
||||
{
|
||||
uint8_t* data;
|
||||
size_t size;
|
||||
size_t base;
|
||||
|
||||
struct _YR_MEMORY_BLOCK* next;
|
||||
|
||||
} YR_MEMORY_BLOCK;
|
||||
|
||||
|
||||
typedef int (*YR_CALLBACK_FUNC)(
|
||||
int message,
|
||||
void* message_data,
|
||||
void* user_data);
|
||||
|
||||
|
||||
typedef struct _YR_SCAN_CONTEXT
|
||||
{
|
||||
uint64_t file_size;
|
||||
uint64_t entry_point;
|
||||
|
||||
int flags;
|
||||
void* user_data;
|
||||
|
||||
YR_MEMORY_BLOCK* mem_block;
|
||||
YR_HASH_TABLE* objects_table;
|
||||
YR_CALLBACK_FUNC callback;
|
||||
|
||||
} YR_SCAN_CONTEXT;
|
||||
|
||||
|
||||
|
||||
#define OBJECT_COMMON_FIELDS \
|
||||
int8_t type; \
|
||||
const char* identifier; \
|
||||
void* data; \
|
||||
struct _YR_OBJECT* parent;
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
|
||||
} YR_OBJECT;
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT_INTEGER
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
int64_t value;
|
||||
|
||||
} YR_OBJECT_INTEGER;
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT_DOUBLE
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
double value;
|
||||
|
||||
} YR_OBJECT_DOUBLE;
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT_STRING
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
SIZED_STRING* value;
|
||||
|
||||
} YR_OBJECT_STRING;
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT_REGEXP
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
RE* value;
|
||||
|
||||
} YR_OBJECT_REGEXP;
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT_STRUCTURE
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
struct _YR_STRUCTURE_MEMBER* members;
|
||||
|
||||
} YR_OBJECT_STRUCTURE;
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT_ARRAY
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
YR_OBJECT* prototype_item;
|
||||
struct _YR_ARRAY_ITEMS* items;
|
||||
|
||||
} YR_OBJECT_ARRAY;
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT_DICTIONARY
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
YR_OBJECT* prototype_item;
|
||||
struct _YR_DICTIONARY_ITEMS* items;
|
||||
|
||||
} YR_OBJECT_DICTIONARY;
|
||||
|
||||
|
||||
struct _YR_OBJECT_FUNCTION;
|
||||
|
||||
|
||||
typedef int (*YR_MODULE_FUNC)(
|
||||
void* args,
|
||||
YR_SCAN_CONTEXT* context,
|
||||
struct _YR_OBJECT_FUNCTION* function_obj);
|
||||
|
||||
|
||||
typedef struct _YR_OBJECT_FUNCTION
|
||||
{
|
||||
OBJECT_COMMON_FIELDS
|
||||
|
||||
YR_OBJECT* return_obj;
|
||||
|
||||
struct
|
||||
{
|
||||
const char* arguments_fmt;
|
||||
YR_MODULE_FUNC code;
|
||||
} prototypes[MAX_OVERLOADED_FUNCTIONS];
|
||||
|
||||
} YR_OBJECT_FUNCTION;
|
||||
|
||||
|
||||
typedef struct _YR_STRUCTURE_MEMBER
|
||||
{
|
||||
YR_OBJECT* object;
|
||||
struct _YR_STRUCTURE_MEMBER* next;
|
||||
|
||||
} YR_STRUCTURE_MEMBER;
|
||||
|
||||
|
||||
typedef struct _YR_ARRAY_ITEMS
|
||||
{
|
||||
int count;
|
||||
YR_OBJECT* objects[1];
|
||||
|
||||
} YR_ARRAY_ITEMS;
|
||||
|
||||
|
||||
typedef struct _YR_DICTIONARY_ITEMS
|
||||
{
|
||||
int used;
|
||||
int free;
|
||||
|
||||
struct
|
||||
{
|
||||
|
||||
char* key;
|
||||
YR_OBJECT* obj;
|
||||
|
||||
} objects[1];
|
||||
|
||||
} YR_DICTIONARY_ITEMS;
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
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_UTILS_H
|
||||
#define YR_UTILS_H
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define YR_API extern "C" __declspec(dllimport)
|
||||
#else
|
||||
#define YR_API
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(x, y) ((x < y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(x, y) ((x > y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
|
||||
#define PTR_TO_UINT64(x) ((uint64_t) (size_t) x)
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
#define assertf(expr, msg) ((void)0)
|
||||
|
||||
#else
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define assertf(expr, msg, ...) \
|
||||
if(!(expr)) { \
|
||||
fprintf(stderr, "%s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -67,8 +67,8 @@ IDI_ICON1 ICON "..\\bug.ico"
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,0,2,4
|
||||
PRODUCTVERSION 0,0,2,4
|
||||
FILEVERSION 0,0,2,5
|
||||
PRODUCTVERSION 0,0,2,5
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -84,10 +84,10 @@ BEGIN
|
|||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "x64_dbg"
|
||||
VALUE "FileVersion", "0.0.2.4"
|
||||
VALUE "FileVersion", "0.0.2.5"
|
||||
VALUE "LegalCopyright", "x64dbg.com"
|
||||
VALUE "ProductName", "x64_dbg"
|
||||
VALUE "ProductVersion", "0.0.2.4"
|
||||
VALUE "ProductVersion", "0.0.2.5"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -1,7 +1,26 @@
|
|||
/**
|
||||
@file x64_dbg_exe.cpp
|
||||
|
||||
@brief Implements the 64 debug executable class.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "..\x64_dbg_bridge\bridgemain.h"
|
||||
|
||||
/**
|
||||
@fn int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||
|
||||
@brief Window main.
|
||||
|
||||
@param hInstance The instance.
|
||||
@param hPrevInstance The previous instance.
|
||||
@param lpCmdLine The command line.
|
||||
@param nShowCmd The show command.
|
||||
|
||||
@return An APIENTRY.
|
||||
*/
|
||||
|
||||
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||
{
|
||||
const char* errormsg = BridgeInit();
|
||||
|
|
|
@ -32,7 +32,6 @@ AbstractTableView::AbstractTableView(QWidget* parent) : QAbstractScrollArea(pare
|
|||
setVerticalScrollBar(new AbstractTableScrollBar(verticalScrollBar()));
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
memset(&mScrollBarAttributes, 0, sizeof(mScrollBarAttributes));
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
horizontalScrollBar()->setRange(0, 0);
|
||||
horizontalScrollBar()->setPageStep(650);
|
||||
mMouseWheelScrollDelta = 4;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include "NewTypes.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
//Hacky class that fixes a really annoying cursor problem
|
||||
class AbstractTableScrollBar : public QScrollBar
|
||||
|
|
|
@ -1480,7 +1480,7 @@ QString Disassembly::getAddrText(int_t cur_addr, char label[MAX_LABEL_SIZE])
|
|||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
addrText += AddressToString(cur_addr);
|
||||
addrText += QString("%1").arg(cur_addr, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
char label_[MAX_LABEL_SIZE] = "";
|
||||
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label_)) //has label
|
||||
{
|
||||
|
|
|
@ -99,8 +99,18 @@ bool SearchListView::findTextInList(SearchListViewTable* list, QString text, int
|
|||
else
|
||||
{
|
||||
for(int i = startcol; i < count; i++)
|
||||
if(list->getCellContent(row, i).contains(text, Qt::CaseInsensitive))
|
||||
return true;
|
||||
{
|
||||
if(ui->checkBoxRegex->checkState() == Qt::Checked)
|
||||
{
|
||||
if(list->getCellContent(row, i).contains(QRegExp(text)))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(list->getCellContent(row, i).contains(text, Qt::CaseInsensitive))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -117,7 +127,8 @@ void SearchListView::searchTextChanged(const QString & arg1)
|
|||
{
|
||||
mSearchList->hide();
|
||||
mList->show();
|
||||
mList->setFocus();
|
||||
if(ui->checkBoxRegex->checkState() != Qt::Checked)
|
||||
mList->setFocus();
|
||||
mCurList = mList;
|
||||
}
|
||||
mSearchList->setRowCount(0);
|
||||
|
@ -150,9 +161,11 @@ void SearchListView::searchTextChanged(const QString & arg1)
|
|||
break;
|
||||
}
|
||||
}
|
||||
mSearchList->highlightText = arg1;
|
||||
if(ui->checkBoxRegex->checkState() != Qt::Checked) //do not highlight with regex
|
||||
mSearchList->highlightText = arg1;
|
||||
mSearchList->reloadData();
|
||||
mSearchList->setFocus();
|
||||
if(ui->checkBoxRegex->checkState() != Qt::Checked)
|
||||
mSearchList->setFocus();
|
||||
}
|
||||
|
||||
void SearchListView::listContextMenu(const QPoint & pos)
|
||||
|
@ -175,3 +188,9 @@ void SearchListView::doubleClickedSlot()
|
|||
{
|
||||
emit enterPressedSignal();
|
||||
}
|
||||
|
||||
void SearchListView::on_checkBoxRegex_toggled(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked);
|
||||
searchTextChanged(ui->searchBox->text());
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ private slots:
|
|||
void listKeyPressed(QKeyEvent* event);
|
||||
void listContextMenu(const QPoint & pos);
|
||||
void doubleClickedSlot();
|
||||
void on_checkBoxRegex_toggled(bool checked);
|
||||
|
||||
signals:
|
||||
void enterPressedSignal();
|
||||
|
|
|
@ -61,6 +61,13 @@
|
|||
<item>
|
||||
<widget class="QLineEdit" name="searchBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxRegex">
|
||||
<property name="text">
|
||||
<string>Re&gEx</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "LineEditDialog.h"
|
||||
#include "WordEditDialog.h"
|
||||
#include "HexEditDialog.h"
|
||||
#include "YaraRuleSelectionDialog.h"
|
||||
|
||||
CPUDisassembly::CPUDisassembly(QWidget* parent) : Disassembly(parent)
|
||||
{
|
||||
|
@ -85,52 +86,71 @@ void CPUDisassembly::mouseDoubleClickEvent(QMouseEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
void CPUDisassembly::addFollowMenuItem(QString name, int_t value)
|
||||
void CPUDisassembly::addFollowReferenceMenuItem(QString name, int_t value, QMenu* menu, bool isReferences)
|
||||
{
|
||||
foreach(QAction * action, mFollowMenu->actions()) //check for duplicate action
|
||||
foreach(QAction * action, menu->actions()) //check for duplicate action
|
||||
if(action->text() == name)
|
||||
return;
|
||||
QAction* newAction = new QAction(name, this);
|
||||
newAction->setFont(QFont("Courier New", 8));
|
||||
mFollowMenu->addAction(newAction);
|
||||
newAction->setObjectName(QString("DUMP|") + QString("%1").arg(value, sizeof(int_t) * 2, 16, QChar('0')).toUpper());
|
||||
menu->addAction(newAction);
|
||||
newAction->setObjectName(QString(isReferences ? "REF|" : "DUMP|") + QString("%1").arg(value, sizeof(int_t) * 2, 16, QChar('0')).toUpper());
|
||||
connect(newAction, SIGNAL(triggered()), this, SLOT(followActionSlot()));
|
||||
}
|
||||
|
||||
void CPUDisassembly::setupFollowMenu(int_t wVA)
|
||||
void CPUDisassembly::setupFollowReferenceMenu(int_t wVA, QMenu* menu, bool isReferences)
|
||||
{
|
||||
//remove previous actions
|
||||
QList<QAction*> list = mFollowMenu->actions();
|
||||
QList<QAction*> list = menu->actions();
|
||||
for(int i = 0; i < list.length(); i++)
|
||||
mFollowMenu->removeAction(list.at(i));
|
||||
menu->removeAction(list.at(i));
|
||||
|
||||
//most basic follow action
|
||||
addFollowMenuItem("&Selection", wVA);
|
||||
if(isReferences)
|
||||
menu->addAction(mReferenceSelectedAddress);
|
||||
else
|
||||
addFollowReferenceMenuItem("&Selected Address", wVA, menu, isReferences);
|
||||
|
||||
//add follow actions
|
||||
DISASM_INSTR instr;
|
||||
DbgDisasmAt(wVA, &instr);
|
||||
|
||||
for(int i = 0; i < instr.argcount; i++)
|
||||
if(!isReferences) //follow in dump
|
||||
{
|
||||
const DISASM_ARG arg = instr.arg[i];
|
||||
if(arg.type == arg_memory)
|
||||
for(int i = 0; i < instr.argcount; i++)
|
||||
{
|
||||
if(DbgMemIsValidReadPtr(arg.value))
|
||||
addFollowMenuItem("&Address: " + QString(arg.mnemonic).toUpper().trimmed(), arg.value);
|
||||
if(arg.value != arg.constant)
|
||||
const DISASM_ARG arg = instr.arg[i];
|
||||
if(arg.type == arg_memory)
|
||||
{
|
||||
QString constant = QString("%1").arg(arg.constant, 1, 16, QChar('0')).toUpper();
|
||||
if(DbgMemIsValidReadPtr(arg.constant))
|
||||
addFollowMenuItem("&Constant: " + constant, arg.constant);
|
||||
if(DbgMemIsValidReadPtr(arg.value))
|
||||
addFollowReferenceMenuItem("&Address: " + QString(arg.mnemonic).toUpper().trimmed(), arg.value, menu, isReferences);
|
||||
if(arg.value != arg.constant)
|
||||
{
|
||||
QString constant = QString("%1").arg(arg.constant, 1, 16, QChar('0')).toUpper();
|
||||
if(DbgMemIsValidReadPtr(arg.constant))
|
||||
addFollowReferenceMenuItem("&Constant: " + constant, arg.constant, menu, isReferences);
|
||||
}
|
||||
if(DbgMemIsValidReadPtr(arg.memvalue))
|
||||
addFollowReferenceMenuItem("&Value: [" + QString(arg.mnemonic) + "]", arg.memvalue, menu, isReferences);
|
||||
|
||||
}
|
||||
else //arg_normal
|
||||
{
|
||||
if(DbgMemIsValidReadPtr(arg.value))
|
||||
addFollowReferenceMenuItem(QString(arg.mnemonic).toUpper().trimmed(), arg.value, menu, isReferences);
|
||||
}
|
||||
if(DbgMemIsValidReadPtr(arg.memvalue))
|
||||
addFollowMenuItem("&Value: [" + QString(arg.mnemonic) + "]", arg.memvalue);
|
||||
}
|
||||
else
|
||||
}
|
||||
else //find references
|
||||
{
|
||||
for(int i = 0; i < instr.argcount; i++)
|
||||
{
|
||||
if(DbgMemIsValidReadPtr(arg.value))
|
||||
addFollowMenuItem(QString(arg.mnemonic).toUpper().trimmed(), arg.value);
|
||||
const DISASM_ARG arg = instr.arg[i];
|
||||
QString constant = QString("%1").arg(arg.constant, 1, 16, QChar('0')).toUpper();
|
||||
if(DbgMemIsValidReadPtr(arg.constant))
|
||||
addFollowReferenceMenuItem("Address: " + constant, arg.constant, menu, isReferences);
|
||||
else if(arg.constant)
|
||||
addFollowReferenceMenuItem("Constant: " + constant, arg.constant, menu, isReferences);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +244,7 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event)
|
|||
}
|
||||
wMenu->addMenu(mBPMenu);
|
||||
wMenu->addMenu(mFollowMenu);
|
||||
setupFollowMenu(wVA);
|
||||
setupFollowReferenceMenu(wVA, mFollowMenu, false);
|
||||
wMenu->addAction(mEnableHighlightingMode);
|
||||
wMenu->addSeparator();
|
||||
|
||||
|
@ -248,6 +268,7 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event)
|
|||
wMenu->addAction(mAssemble);
|
||||
|
||||
wMenu->addAction(mPatchesAction);
|
||||
wMenu->addAction(mYaraAction);
|
||||
|
||||
wMenu->addSeparator();
|
||||
|
||||
|
@ -269,8 +290,8 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event)
|
|||
|
||||
wMenu->addMenu(mSearchMenu);
|
||||
|
||||
mReferencesMenu->addAction(mReferenceSelectedAddress);
|
||||
wMenu->addMenu(mReferencesMenu);
|
||||
setupFollowReferenceMenu(wVA, mReferencesMenu, true);
|
||||
|
||||
wMenu->addSeparator();
|
||||
wMenu->addActions(mPluginMenu->actions());
|
||||
|
@ -404,6 +425,11 @@ void CPUDisassembly::setupRightClickContextMenu()
|
|||
mPatchesAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
connect(mPatchesAction, SIGNAL(triggered()), this, SLOT(showPatchesSlot()));
|
||||
|
||||
mYaraAction = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this);
|
||||
mYaraAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mYaraAction);
|
||||
connect(mYaraAction, SIGNAL(triggered()), this, SLOT(yaraSlot()));
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
//---------------------- New origin here -----------------------------
|
||||
|
@ -477,7 +503,8 @@ void CPUDisassembly::setupRightClickContextMenu()
|
|||
mReferencesMenu = new QMenu("Find &references to", this);
|
||||
|
||||
// Selected address
|
||||
mReferenceSelectedAddress = new QAction("&Selected address", this);
|
||||
mReferenceSelectedAddress = new QAction("&Selected Address(es)", this);
|
||||
mReferenceSelectedAddress->setFont(QFont("Courier New", 8));
|
||||
mReferenceSelectedAddress->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mReferenceSelectedAddress);
|
||||
connect(mReferenceSelectedAddress, SIGNAL(triggered()), this, SLOT(findReferences()));
|
||||
|
@ -545,6 +572,7 @@ void CPUDisassembly::refreshShortcutsSlot()
|
|||
mAssemble->setShortcut(ConfigShortcut("ActionAssemble"));
|
||||
mToggleInt3BpAction->setShortcut(ConfigShortcut("ActionToggleBreakpoint"));
|
||||
mPatchesAction->setShortcut(ConfigShortcut("ViewPatches"));
|
||||
mYaraAction->setShortcut(ConfigShortcut("ActionYara"));
|
||||
mSetNewOriginHere->setShortcut(ConfigShortcut("ActionSetNewOriginHere"));
|
||||
mGotoOrigin->setShortcut(ConfigShortcut("ActionGotoOrigin"));
|
||||
mGotoPrevious->setShortcut(ConfigShortcut("ActionGotoPrevious"));
|
||||
|
@ -931,8 +959,17 @@ void CPUDisassembly::gotoFileOffset()
|
|||
void CPUDisassembly::followActionSlot()
|
||||
{
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if(action && action->objectName().startsWith("DUMP|"))
|
||||
if(!action)
|
||||
return;
|
||||
if(action->objectName().startsWith("DUMP|"))
|
||||
DbgCmdExec(QString().sprintf("dump \"%s\"", action->objectName().mid(5).toUtf8().constData()).toUtf8().constData());
|
||||
else if(action->objectName().startsWith("REF|"))
|
||||
{
|
||||
QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
QString value = action->objectName().mid(4);
|
||||
DbgCmdExec(QString("findref \"" + value + "\", " + addrText).toUtf8().constData());
|
||||
emit displayReferencesWidget();
|
||||
}
|
||||
}
|
||||
|
||||
void CPUDisassembly::gotoPrevious()
|
||||
|
@ -947,8 +984,10 @@ void CPUDisassembly::gotoNext()
|
|||
|
||||
void CPUDisassembly::findReferences()
|
||||
{
|
||||
QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
DbgCmdExec(QString("findref " + addrText + ", " + addrText).toUtf8().constData());
|
||||
QString addrStart = QString("%1").arg(rvaToVa(getSelectionStart()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
QString addrEnd = QString("%1").arg(rvaToVa(getSelectionEnd()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
QString addrDisasm = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
DbgCmdExec(QString("findrefrange " + addrStart + ", " + addrEnd + ", " + addrDisasm).toUtf8().constData());
|
||||
emit displayReferencesWidget();
|
||||
}
|
||||
|
||||
|
@ -1143,6 +1182,17 @@ void CPUDisassembly::showPatchesSlot()
|
|||
emit showPatches();
|
||||
}
|
||||
|
||||
void CPUDisassembly::yaraSlot()
|
||||
{
|
||||
YaraRuleSelectionDialog yaraDialog(this);
|
||||
if(yaraDialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
DbgCmdExec(QString("yara \"%0\",%1").arg(yaraDialog.getSelectedFile()).arg(addrText).toUtf8().constData());
|
||||
emit displayReferencesWidget();
|
||||
}
|
||||
}
|
||||
|
||||
void CPUDisassembly::copySelection(bool copyBytes)
|
||||
{
|
||||
QList<Instruction_t> instBuffer;
|
||||
|
|
|
@ -17,8 +17,8 @@ public:
|
|||
|
||||
// Context Menu Management
|
||||
void setupRightClickContextMenu();
|
||||
void addFollowMenuItem(QString name, int_t value);
|
||||
void setupFollowMenu(int_t wVA);
|
||||
void addFollowReferenceMenuItem(QString name, int_t value, QMenu* menu, bool isReferences);
|
||||
void setupFollowReferenceMenu(int_t wVA, QMenu* menu, bool isReferences);
|
||||
void setHwBpAt(uint_t va, int slot);
|
||||
|
||||
void copySelection(bool copyBytes);
|
||||
|
@ -63,6 +63,7 @@ public slots:
|
|||
void binaryPasteIgnoreSizeSlot();
|
||||
void undoSelectionSlot();
|
||||
void showPatchesSlot();
|
||||
void yaraSlot();
|
||||
void copySelection();
|
||||
void copySelectionNoBytes();
|
||||
void copyAddress();
|
||||
|
@ -115,6 +116,7 @@ private:
|
|||
QAction* mSearchPattern;
|
||||
QAction* mEnableHighlightingMode;
|
||||
QAction* mPatchesAction;
|
||||
QAction* mYaraAction;
|
||||
QAction* mCopySelection;
|
||||
QAction* mCopySelectionNoBytes;
|
||||
QAction* mCopyAddress;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "Bridge.h"
|
||||
#include "LineEditDialog.h"
|
||||
#include "HexEditDialog.h"
|
||||
#include "YaraRuleSelectionDialog.h"
|
||||
#include "DataCopyDialog.h"
|
||||
|
||||
CPUDump::CPUDump(QWidget* parent) : HexDump(parent)
|
||||
{
|
||||
|
@ -232,6 +234,16 @@ void CPUDump::setupContextMenu()
|
|||
this->addAction(mFindPatternAction);
|
||||
connect(mFindPatternAction, SIGNAL(triggered()), this, SLOT(findPattern()));
|
||||
|
||||
//Yara
|
||||
mYaraAction = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this);
|
||||
mYaraAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mYaraAction);
|
||||
connect(mYaraAction, SIGNAL(triggered()), this, SLOT(yaraSlot()));
|
||||
|
||||
//Data copy
|
||||
mDataCopyAction = new QAction(QIcon(":/icons/images/data-copy.png"), "Data copy...", this);
|
||||
connect(mDataCopyAction, SIGNAL(triggered()), this, SLOT(dataCopySlot()));
|
||||
|
||||
//Find References
|
||||
mFindReferencesAction = new QAction("Find &References", this);
|
||||
mFindReferencesAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
|
@ -362,6 +374,7 @@ void CPUDump::refreshShortcutsSlot()
|
|||
mFindPatternAction->setShortcut(ConfigShortcut("ActionFindPattern"));
|
||||
mFindReferencesAction->setShortcut(ConfigShortcut("ActionFindReferences"));
|
||||
mGotoExpression->setShortcut(ConfigShortcut("ActionGotoExpression"));
|
||||
mYaraAction->setShortcut(ConfigShortcut("ActionYara"));
|
||||
}
|
||||
|
||||
QString CPUDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
||||
|
@ -404,7 +417,7 @@ QString CPUDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, i
|
|||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
addrText += AddressToString(cur_addr);
|
||||
addrText += QString("%1").arg(cur_addr, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label
|
||||
{
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
|
@ -464,6 +477,9 @@ void CPUDump::contextMenuEvent(QContextMenuEvent* event)
|
|||
wMenu->addAction(mSetLabelAction);
|
||||
wMenu->addMenu(mBreakpointMenu);
|
||||
wMenu->addAction(mFindPatternAction);
|
||||
wMenu->addAction(mFindReferencesAction);
|
||||
wMenu->addAction(mYaraAction);
|
||||
wMenu->addAction(mDataCopyAction);
|
||||
wMenu->addMenu(mGotoMenu);
|
||||
wMenu->addSeparator();
|
||||
wMenu->addMenu(mHexMenu);
|
||||
|
@ -1320,5 +1336,31 @@ void CPUDump::selectionUpdatedSlot()
|
|||
{
|
||||
QString selStart = QString("%1").arg(rvaToVa(getSelectionStart()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
QString selEnd = QString("%1").arg(rvaToVa(getSelectionEnd()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
GuiAddStatusBarMessage(QString("Dump: " + selStart + " -> " + selEnd + QString().sprintf(" (0x%.8X bytes)\n", getSelectionEnd() - getSelectionStart() + 1)).toUtf8().constData());
|
||||
QString info = "Dump";
|
||||
char mod[MAX_MODULE_SIZE] = "";
|
||||
if(DbgFunctions()->ModNameFromAddr(rvaToVa(getSelectionStart()), mod, true))
|
||||
info = QString(mod) + "";
|
||||
GuiAddStatusBarMessage(QString(info + ": " + selStart + " -> " + selEnd + QString().sprintf(" (0x%.8X bytes)\n", getSelectionEnd() - getSelectionStart() + 1)).toUtf8().constData());
|
||||
}
|
||||
|
||||
void CPUDump::yaraSlot()
|
||||
{
|
||||
YaraRuleSelectionDialog yaraDialog(this);
|
||||
if(yaraDialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
DbgCmdExec(QString("yara \"%0\",%1").arg(yaraDialog.getSelectedFile()).arg(addrText).toUtf8().constData());
|
||||
emit displayReferencesWidget();
|
||||
}
|
||||
}
|
||||
|
||||
void CPUDump::dataCopySlot()
|
||||
{
|
||||
int_t selStart = getSelectionStart();
|
||||
int_t selSize = getSelectionEnd() - selStart + 1;
|
||||
QVector<byte_t> data;
|
||||
data.resize(selSize);
|
||||
mMemPage->read(data.data(), selStart, selSize);
|
||||
DataCopyDialog dataDialog(&data, this);
|
||||
dataDialog.exec();
|
||||
}
|
||||
|
|
|
@ -78,6 +78,8 @@ public slots:
|
|||
void findReferencesSlot();
|
||||
|
||||
void selectionUpdatedSlot();
|
||||
void yaraSlot();
|
||||
void dataCopySlot();
|
||||
|
||||
private:
|
||||
QMenu* mBreakpointMenu;
|
||||
|
@ -158,6 +160,8 @@ private:
|
|||
QAction* mBinaryPasteIgnoreSizeAction;
|
||||
QAction* mFindPatternAction;
|
||||
QAction* mFindReferencesAction;
|
||||
QAction* mYaraAction;
|
||||
QAction* mDataCopyAction;
|
||||
QAction* mUndoSelection;
|
||||
|
||||
QMenu* mSpecialMenu;
|
||||
|
|
|
@ -184,7 +184,7 @@ void CPUInfoBox::disasmSelectionChanged(int_t parVA)
|
|||
char section[MAX_SECTION_SIZE] = "";
|
||||
if(DbgFunctions()->SectionFromAddr(parVA, section))
|
||||
info += "\"" + QString(section) + "\":";
|
||||
info += AddressToString(parVA);
|
||||
info += QString("%1").arg(parVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(DbgGetLabelAt(parVA, SEG_DEFAULT, label))
|
||||
info += " <" + QString(label) + ">";
|
||||
|
|
|
@ -224,7 +224,7 @@ QString CPUStack::paintContent(QPainter* painter, int_t rowBase, int rowOffset,
|
|||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
addrText += AddressToString(cur_addr);
|
||||
addrText += QString("%1").arg(cur_addr, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label
|
||||
{
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
#include "DataCopyDialog.h"
|
||||
#include "ui_DataCopyDialog.h"
|
||||
#include "Bridge.h"
|
||||
|
||||
DataCopyDialog::DataCopyDialog(const QVector<byte_t>* data, QWidget* parent) : QDialog(parent), ui(new Ui::DataCopyDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint);
|
||||
#endif
|
||||
setFixedSize(this->size()); //fixed size
|
||||
mData = data;
|
||||
|
||||
ui->comboType->addItem("C-Style BYTE (Hex)");
|
||||
ui->comboType->addItem("C-Style WORD (Hex)");
|
||||
ui->comboType->addItem("C-Style DWORD (Hex)");
|
||||
ui->comboType->addItem("C-Style String");
|
||||
ui->comboType->addItem("C-Style Unicode String");
|
||||
|
||||
ui->comboType->setCurrentIndex(DataCByte);
|
||||
|
||||
printData((DataType)ui->comboType->currentIndex());
|
||||
}
|
||||
|
||||
QString DataCopyDialog::printEscapedString(bool & bPrevWasHex, int ch, const char* hexFormat)
|
||||
{
|
||||
QString data = "";
|
||||
switch(ch) //escaping
|
||||
{
|
||||
case '\t':
|
||||
data = "\\t";
|
||||
bPrevWasHex = false;
|
||||
break;
|
||||
case '\f':
|
||||
data = "\\f";
|
||||
bPrevWasHex = false;
|
||||
break;
|
||||
case '\v':
|
||||
data = "\\v";
|
||||
bPrevWasHex = false;
|
||||
break;
|
||||
case '\n':
|
||||
data = "\\n";
|
||||
bPrevWasHex = false;
|
||||
break;
|
||||
case '\r':
|
||||
data = "\\r";
|
||||
bPrevWasHex = false;
|
||||
break;
|
||||
case '\\':
|
||||
data = "\\\\";
|
||||
bPrevWasHex = false;
|
||||
break;
|
||||
case '\"':
|
||||
data = "\\\"";
|
||||
bPrevWasHex = false;
|
||||
break;
|
||||
default:
|
||||
if(ch >= ' ' && ch <= '~')
|
||||
{
|
||||
if(bPrevWasHex && isxdigit(ch))
|
||||
data = QString().sprintf("\"\"%c", ch);
|
||||
else
|
||||
data = QString().sprintf("%c", ch);
|
||||
bPrevWasHex = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bPrevWasHex = true;
|
||||
data = QString().sprintf(hexFormat, ch);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void DataCopyDialog::printData(DataType type)
|
||||
{
|
||||
ui->editCode->clear();
|
||||
QString data;
|
||||
switch(type)
|
||||
{
|
||||
case DataCByte:
|
||||
{
|
||||
data += "{";
|
||||
for(int i = 0; i < mData->size(); i++)
|
||||
{
|
||||
if(i)
|
||||
data += ", ";
|
||||
data += QString().sprintf("0x%02X", mData->at(i));
|
||||
}
|
||||
data += "};";
|
||||
}
|
||||
break;
|
||||
|
||||
case DataCWord:
|
||||
{
|
||||
int numwords = mData->size() / sizeof(unsigned short);
|
||||
data += "{";
|
||||
for(int i = 0; i < numwords; i++)
|
||||
{
|
||||
if(i)
|
||||
data += ", ";
|
||||
data += QString().sprintf("0x%04X", ((unsigned short*)mData->constData())[i]);
|
||||
}
|
||||
data += "};";
|
||||
}
|
||||
break;
|
||||
|
||||
case DataCDword:
|
||||
{
|
||||
int numdwords = mData->size() / sizeof(unsigned int);
|
||||
data += "{";
|
||||
for(int i = 0; i < numdwords; i++)
|
||||
{
|
||||
if(i)
|
||||
data += ", ";
|
||||
data += QString().sprintf("0x%08X", ((unsigned int*)mData->constData())[i]);
|
||||
}
|
||||
data += "};";
|
||||
}
|
||||
break;
|
||||
|
||||
case DataCString:
|
||||
{
|
||||
data += "\"";
|
||||
bool bPrevWasHex = false;
|
||||
for(int i = 0; i < mData->size(); i++)
|
||||
{
|
||||
byte_t ch = mData->at(i);
|
||||
data += printEscapedString(bPrevWasHex, ch, "\\x%02X");
|
||||
}
|
||||
data += "\"";
|
||||
}
|
||||
break;
|
||||
|
||||
case DataCUnicodeString: //extended ASCII + hex escaped only
|
||||
{
|
||||
data += "L\"";
|
||||
int numwchars = mData->size() / sizeof(unsigned short);
|
||||
bool bPrevWasHex = false;
|
||||
for(int i = 0; i < numwchars; i++)
|
||||
{
|
||||
unsigned short ch = ((unsigned short*)mData->constData())[i];
|
||||
if((ch & 0xFF00) == 0) //extended ASCII
|
||||
{
|
||||
data += printEscapedString(bPrevWasHex, ch, "\\x%04X");
|
||||
}
|
||||
else //full unicode character
|
||||
{
|
||||
bPrevWasHex = true;
|
||||
data += QString().sprintf("\\x%04X", ch);
|
||||
}
|
||||
}
|
||||
data += "\"";
|
||||
}
|
||||
break;
|
||||
}
|
||||
ui->editCode->setPlainText(data);
|
||||
}
|
||||
|
||||
DataCopyDialog::~DataCopyDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DataCopyDialog::on_comboType_currentIndexChanged(int index)
|
||||
{
|
||||
printData((DataType)index);
|
||||
}
|
||||
|
||||
void DataCopyDialog::on_buttonCopy_clicked()
|
||||
{
|
||||
Bridge::CopyToClipboard(ui->editCode->toPlainText());
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef DATACOPYDIALOG_H
|
||||
#define DATACOPYDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QVector>
|
||||
#include "NewTypes.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class DataCopyDialog;
|
||||
}
|
||||
|
||||
class DataCopyDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DataCopyDialog(const QVector<byte_t>* data, QWidget* parent = 0);
|
||||
~DataCopyDialog();
|
||||
|
||||
private slots:
|
||||
void on_comboType_currentIndexChanged(int index);
|
||||
void on_buttonCopy_clicked();
|
||||
|
||||
private:
|
||||
Ui::DataCopyDialog* ui;
|
||||
const QVector<byte_t>* mData;
|
||||
|
||||
enum DataType
|
||||
{
|
||||
DataCByte = 0,
|
||||
DataCWord,
|
||||
DataCDword,
|
||||
DataCString,
|
||||
DataCUnicodeString,
|
||||
};
|
||||
|
||||
void printData(DataType type);
|
||||
QString printEscapedString(bool & bPrevWasHex, int ch, const char* hexFormat);
|
||||
};
|
||||
|
||||
#endif // DATACOPYDIALOG_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue