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