├── SalityKiller ├── SalityKiller.def ├── SalityKiller.rc ├── resource.h ├── SalityKiller.vcxproj.filters ├── KillVirus.h └── main.cpp ├── tests ├── samples │ ├── testcase.bin │ ├── container.zip │ └── sub │ │ └── testcase.zip └── Unittests │ ├── FileFsAttribute_unittest.cpp │ ├── main.cpp │ ├── Unittests.vcxproj.filters │ ├── FileFs_unittest.cpp │ ├── FileFsEnum_unittest.cpp │ └── FileFsStream_unittest.cpp ├── TinyAvConsole ├── TinyAvConsole.rc ├── resource.h ├── getopt.h ├── ConsoleObserver.h ├── TinyAvConsole.vcxproj.filters ├── ConsoleObserver.cpp ├── main.cpp └── getopt.c ├── ci └── windows │ ├── test_appveyor.bat │ └── build_appveyor.bat ├── .gitmodules ├── TinyAvCore ├── Utils.h ├── FileSystem │ ├── zip │ │ ├── ZipFsEnum.h │ │ ├── ZipFsAttribute.h │ │ ├── ZipFs.h │ │ ├── UnzipHelper.h │ │ ├── ZipFsAttribute.cpp │ │ ├── ZipFs.cpp │ │ ├── ZipFsEnum.cpp │ │ └── UnzipHelper.cpp │ ├── FileFsAttribute.h │ ├── BufferedStream.h │ ├── FileFsStream.h │ ├── FileFs.h │ ├── FileFsEnumContext.h │ ├── FileFsEnum.h │ ├── FileFsAttribute.cpp │ ├── BufferedStream.cpp │ ├── FileFsEnumContext.cpp │ └── FileFsStream.cpp ├── Module │ ├── ModuleMgrService.h │ └── ModuleMgrService.cpp ├── Emulator │ ├── unicorn_dynload.h │ └── PeEmulator.h ├── Scanner │ └── ScanService.h ├── Utils.cpp ├── FileType │ └── PeFileParser.h └── TinyAvCore.vcxproj.filters ├── include ├── FileType │ ├── FileType.h │ └── PEFile.h ├── TinyAvBase.h ├── FileSystem │ ├── FsEnumObserver.h │ ├── FsEnum.h │ ├── FsAttribute.h │ ├── FsEnumContext.h │ ├── FsStream.h │ └── FsObject.h ├── RefCount.h ├── Scanner │ ├── ScanModule.h │ ├── ScanContext.h │ ├── ScanObserver.h │ └── Scanner.h ├── Module │ ├── Module.h │ └── ModuleManager.h ├── TinyAvCore.h └── Emulator │ └── Emulator.h ├── libs └── include │ └── unicorn │ ├── platform.h │ ├── m68k.h │ ├── sparc.h │ ├── arm.h │ ├── mips.h │ └── arm64.h ├── appveyor.yml ├── .gitattributes ├── README.md ├── TinyAntivirus.sln └── .gitignore /SalityKiller/SalityKiller.def: -------------------------------------------------------------------------------- 1 | LIBRARY 2 | EXPORTS 3 | CreateModuleObject @1 -------------------------------------------------------------------------------- /tests/samples/testcase.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/develbranch/TinyAntivirus/HEAD/tests/samples/testcase.bin -------------------------------------------------------------------------------- /SalityKiller/SalityKiller.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/develbranch/TinyAntivirus/HEAD/SalityKiller/SalityKiller.rc -------------------------------------------------------------------------------- /tests/samples/container.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/develbranch/TinyAntivirus/HEAD/tests/samples/container.zip -------------------------------------------------------------------------------- /TinyAvConsole/TinyAvConsole.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/develbranch/TinyAntivirus/HEAD/TinyAvConsole/TinyAvConsole.rc -------------------------------------------------------------------------------- /tests/samples/sub/testcase.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/develbranch/TinyAntivirus/HEAD/tests/samples/sub/testcase.zip -------------------------------------------------------------------------------- /ci/windows/test_appveyor.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | set APP_PATH="%2\Unittests.exe" 3 | if /I "%1" == "x64" (set APP_PATH="%1\%2\Unittests.exe") 4 | %APP_PATH% "%SAMPLE_DIR%" 5 | 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libs/googletest"] 2 | path = libs/googletest 3 | url = https://github.com/google/googletest.git 4 | [submodule "libs/zlib"] 5 | path = libs/zlib 6 | url = https://github.com/madler/zlib.git 7 | -------------------------------------------------------------------------------- /TinyAvCore/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | StringW AnsiToUnicode(__in StringA * str); 5 | StringW AnsiToUnicode(__in StringA& str); 6 | StringA UnicodeToAnsi(__in StringW * str); 7 | StringA UnicodeToAnsi(__in StringW& str); -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/zip/ZipFsEnum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../FileFsEnum.h" 3 | #include 4 | 5 | class CZipFsEnum : 6 | public CFileFsEnum 7 | { 8 | protected: 9 | 10 | virtual HRESULT WINAPI ReadArchiver(__in_opt IVirtualFs * container, __in IFsEnumContext * context, __in void * stream); 11 | virtual ~CZipFsEnum(void); 12 | 13 | public: 14 | CZipFsEnum(void); 15 | 16 | virtual HRESULT WINAPI Enum(__in IFsEnumContext *context) override; 17 | }; -------------------------------------------------------------------------------- /SalityKiller/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by SalityKiller.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /TinyAvConsole/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by TinyAvConsole.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /tests/Unittests/FileFsAttribute_unittest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define TEST_FILEFSATTRIBUTE 3 | #if defined TEST_FILEFSATTRIBUTE 4 | #include "../TinyAvCore/FileSystem/FileFsAttribute.h" 5 | #include 6 | 7 | extern WCHAR szTestcase[MAX_PATH]; 8 | 9 | TEST(FileFsAttribute, Size) 10 | { 11 | IFsAttribute * fsAttr = new CFileFsAttribute(); 12 | ASSERT_HRESULT_SUCCEEDED(fsAttr->SetFilePath(szTestcase)); 13 | ULARGE_INTEGER fileSize; 14 | ASSERT_HRESULT_SUCCEEDED(fsAttr->Size(&fileSize)); 15 | ASSERT_EQ(1024*1024, fileSize.QuadPart); 16 | fsAttr->Release(); 17 | } 18 | #endif -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/zip/ZipFsAttribute.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../FileFsAttribute.h" 3 | #include 4 | 5 | class CZipFsAttribute : 6 | public CFileFsAttribute 7 | { 8 | protected: 9 | virtual ~CZipFsAttribute(void); 10 | 11 | public: 12 | CZipFsAttribute(void); 13 | 14 | virtual HRESULT WINAPI QueryAttributes(void); 15 | 16 | virtual HRESULT WINAPI SetTime(__in_opt FILETIME *lpCreationTime, __in_opt FILETIME *lpLastAccessTime, __in_opt FILETIME *lpLastWriteTime) override; 17 | 18 | virtual HRESULT WINAPI SetFilePath(__in LPCWSTR lpFilePath, __in_opt void* handle /*= NULL*/) override; 19 | 20 | }; -------------------------------------------------------------------------------- /TinyAvConsole/getopt.h: -------------------------------------------------------------------------------- 1 | #ifndef GETOPT_H 2 | #define GETOPT_H 3 | #include 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | extern int opterr, // if error message should be printed / 9 | optind, // index into parent argv vector / 10 | optopt, // character checked for validity / 11 | optreset; // reset getopt / 12 | 13 | extern char *optarg; // argument associated with option */ 14 | extern wchar_t *optarg_w; // argument associated with option */ 15 | 16 | int getopt(int nargc, char * const nargv[], const char *ostr); 17 | int getopt_w(int nargc, wchar_t * const nargv[], const wchar_t *ostr); 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | #endif -------------------------------------------------------------------------------- /include/FileType/FileType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "../FileSystem/FsObject.h" 4 | // ----------------------------- 5 | // Interface for File parser 6 | // ----------------------------- 7 | 8 | MIDL_INTERFACE("2C5B9040-59F9-4ACE-B201-45A8F02851E4") 9 | IFileType : public IUnknown 10 | { 11 | public: 12 | 13 | BEGIN_INTERFACE 14 | 15 | // Check for type matching 16 | // @fsFile: a pointer to IFsObject object 17 | // @typeMatched: a pointer to a variable storing result. 18 | //@return: HRESULT on success, or other value on failure. 19 | virtual HRESULT WINAPI CheckType(__in IVirtualFs* fsFile, __out BOOL *typeMatched) = 0; 20 | 21 | END_INTERFACE 22 | }; -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/zip/ZipFs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../FileFs.h" 3 | #ifdef __cplusplus 4 | extern "C" 5 | { 6 | #endif // __cplusplus 7 | 8 | #include 9 | #ifdef __cplusplus 10 | } 11 | #endif // __cplusplus 12 | 13 | #define WRITEBUFFERSIZE ( 16 * 1024) 14 | class CZipFs : public CFileFs 15 | { 16 | protected: 17 | unz64_file_pos m_currentFilePos; 18 | virtual ~CZipFs(); 19 | public: 20 | CZipFs(); 21 | 22 | virtual HRESULT WINAPI Create(__in LPCWSTR path, __in ULONG const flags) override; 23 | 24 | virtual HRESULT WINAPI Close(void) override; 25 | 26 | virtual HRESULT WINAPI ReCreate(__in_opt void* handle, __in_opt ULONG const flags /*= 0*/) override; 27 | }; -------------------------------------------------------------------------------- /libs/include/unicorn/platform.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Axel Souchet & Nguyen Anh Quynh, 2014 */ 3 | 4 | // handle C99 issue (for pre-2013 VisualStudio) 5 | #ifndef UNICORN_PLATFORM_H 6 | #define UNICORN_PLATFORM_H 7 | 8 | #if !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) 9 | // MSVC 10 | 11 | // stdbool.h 12 | #if (_MSC_VER < 1800) 13 | #ifndef __cplusplus 14 | typedef unsigned char bool; 15 | #define false 0 16 | #define true 1 17 | #endif 18 | 19 | #else 20 | // VisualStudio 2013+ -> C99 is supported 21 | #include 22 | #endif 23 | 24 | #else // not MSVC -> C99 is supported 25 | #include 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/TinyAvBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "RefCount.h" 10 | 11 | ////////////////////////////////////////////////////////////////////////// 12 | // String 13 | #define StringA std::string 14 | 15 | #define StringW std::wstring 16 | #if defined _UNICODE || defined UNICODE 17 | #define StringT StringW 18 | #else 19 | #define StringT StringA 20 | #endif 21 | 22 | ////////////////////////////////////////////////////////////////////////// 23 | #define TEST_FLAG(x,y) (((x) & (y)) == (y)) 24 | #define CLR_FLAG(x,f) ((x)=(x)&(~(f))) 25 | 26 | ////////////////////////////////////////////////////////////////////////// 27 | #define MAX_NAME (256) 28 | 29 | #define EMULATOR_ERROR_CODE_BASE (100) 30 | #define ENUMERATION_ERROR_CODE_BASE (200) -------------------------------------------------------------------------------- /include/FileSystem/FsEnumObserver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "FsObject.h" 4 | #include "FsEnumContext.h" 5 | 6 | MIDL_INTERFACE("D172D234-9C5B-4C37-949F-E05B089F8CE9") 7 | IFsEnumObserver: public IUnknown 8 | { 9 | public: 10 | BEGIN_INTERFACE 11 | /* 12 | OnFileFound method is called when enumeration operation hits new file. 13 | @file: a pointer to IFsObject that describes new file. 14 | @context: a pointer to IFsEnumContext that describes enumeration context. 15 | @currentDepth: current depth. 16 | @return: the return value is S_OK if succeeds, or E_ABORT to stop enumeration. 17 | */ 18 | virtual HRESULT WINAPI OnFileFound(__in IVirtualFs *file, __in IFsEnumContext *context, __in const int currentDepth) = 0; 19 | 20 | //called when an error occurred 21 | // @dwErrorCode: error code 22 | // @lpMessage: Error message 23 | virtual void WINAPI OnError(__in DWORD dwErrorCode, __in_opt LPCWSTR lpMessage = NULL) = 0; 24 | END_INTERFACE 25 | }; -------------------------------------------------------------------------------- /tests/Unittests/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #pragma comment(lib, "gtest.lib" ) 3 | #pragma comment(lib, "TinyAvCore.lib" ) 4 | #include 5 | #include 6 | #pragma comment(lib, "shlwapi.lib" ) 7 | 8 | #if defined DEBUG || defined _DEBUG 9 | #include 10 | #endif 11 | 12 | WCHAR szTestcase[MAX_PATH] = {}; 13 | WCHAR szSampleDir[MAX_PATH] = {}; 14 | 15 | int main(int argc, char** argv) 16 | { 17 | #if defined DEBUG || defined _DEBUG 18 | { 19 | int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 20 | _CrtSetDbgFlag(flag | _CRTDBG_LEAK_CHECK_DF); 21 | //_CrtSetBreakAlloc(0x1337); 22 | } 23 | #endif 24 | 25 | if (argc >= 2) 26 | { 27 | MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, szSampleDir, MAX_PATH); 28 | } 29 | else 30 | { 31 | return 1; 32 | } 33 | 34 | wcscpy_s(szTestcase, MAX_PATH, szSampleDir); 35 | PathAppendW(szTestcase, L"testcase.bin"); 36 | 37 | ::testing::InitGoogleTest(&argc, argv); 38 | return RUN_ALL_TESTS(); 39 | } -------------------------------------------------------------------------------- /include/RefCount.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class CRefCount 6 | { 7 | private: 8 | mutable LONG m_RefCount; 9 | 10 | public: 11 | 12 | CRefCount(void) : m_RefCount(1) 13 | { 14 | } 15 | 16 | virtual ~CRefCount(void) { } 17 | 18 | virtual ULONG WINAPI AddRef(void) 19 | { 20 | return InterlockedIncrement(&m_RefCount); 21 | } 22 | 23 | virtual ULONG WINAPI Release(void) 24 | { 25 | if (!InterlockedDecrement(&m_RefCount)) 26 | { 27 | delete this; 28 | return 0; 29 | } 30 | return m_RefCount; 31 | } 32 | 33 | virtual ULONG WINAPI GetCount(void) 34 | { 35 | return m_RefCount; 36 | } 37 | }; 38 | 39 | 40 | #if !defined DECLARE_REF_COUNT 41 | 42 | #define DECLARE_REF_COUNT() \ 43 | public: \ 44 | virtual ULONG WINAPI GetCount( void ) { return CRefCount::GetCount(); } \ 45 | virtual ULONG WINAPI AddRef( void ) { return CRefCount::AddRef(); } \ 46 | virtual ULONG WINAPI Release( void ) { return CRefCount::Release(); } \ 47 | 48 | #endif -------------------------------------------------------------------------------- /libs/include/unicorn/m68k.h: -------------------------------------------------------------------------------- 1 | #ifndef UNICORN_M68K_H 2 | #define UNICORN_M68K_H 3 | 4 | /* Unicorn Emulator Engine */ 5 | /* By Nguyen Anh Quynh , 2014-2015 */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include 12 | #include "platform.h" 13 | 14 | #ifdef _MSC_VER 15 | #pragma warning(disable:4201) 16 | #endif 17 | 18 | //> M68K registers 19 | typedef enum m68k_reg { 20 | UC_M68K_REG_INVALID = 0, 21 | 22 | UC_M68K_REG_A0, 23 | UC_M68K_REG_A1, 24 | UC_M68K_REG_A2, 25 | UC_M68K_REG_A3, 26 | UC_M68K_REG_A4, 27 | UC_M68K_REG_A5, 28 | UC_M68K_REG_A6, 29 | UC_M68K_REG_A7, 30 | 31 | UC_M68K_REG_D0, 32 | UC_M68K_REG_D1, 33 | UC_M68K_REG_D2, 34 | UC_M68K_REG_D3, 35 | UC_M68K_REG_D4, 36 | UC_M68K_REG_D5, 37 | UC_M68K_REG_D6, 38 | UC_M68K_REG_D7, 39 | 40 | UC_M68K_REG_SR, 41 | UC_M68K_REG_PC, 42 | 43 | UC_M68K_REG_ENDING, // <-- mark the end of the list of registers 44 | } m68k_reg; 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/zip/UnzipHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | voidpf ZCALLBACK UHOpen (voidpf opaque, const char* filename, int mode); 6 | voidpf ZCALLBACK UHOpen64(voidpf opaque, const void* filename, int mode); 7 | uLong ZCALLBACK UHRead (voidpf opaque, voidpf stream, void* buf, uLong size); 8 | uLong ZCALLBACK UHWrite (voidpf opaque, voidpf stream, const void* buf, uLong size); 9 | long ZCALLBACK UHTell (voidpf opaque, voidpf stream ); 10 | ZPOS64_T ZCALLBACK UHTell64(voidpf opaque, voidpf stream ); 11 | long ZCALLBACK UHSeek (voidpf opaque, voidpf stream, uLong offset, int origin); 12 | long ZCALLBACK UHSeek64(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin); 13 | int ZCALLBACK UHClose (voidpf opaque, voidpf stream); 14 | int ZCALLBACK UHError (voidpf opaque, voidpf stream); 15 | void FillFunctions64( __in voidpf opaque, __out zlib_filefunc64_def* pzlib_filefunc_def); 16 | void FillFunctions( __in voidpf opaque, __out zlib_filefunc_def* pzlib_filefunc_def); -------------------------------------------------------------------------------- /include/Scanner/ScanModule.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "ScanObserver.h" 4 | #include "../FileSystem/FsObject.h" 5 | #include "../Module/Module.h" 6 | 7 | MIDL_INTERFACE("7C84DAA3-D4E2-485F-8FE6-89C4419D4159") 8 | IScanModule: public IModule 9 | { 10 | public: 11 | BEGIN_INTERFACE 12 | 13 | // Method is called when application initializes this module 14 | virtual HRESULT WINAPI OnScanInitialize(void) = 0; 15 | 16 | /* Scan file 17 | @file: a pointer to IFsObject object 18 | @context: a pointer to IFsEnumContext object 19 | @observer: a pointer to IScanObserver object 20 | @return: if function succeeds, the return value is S_OK. 21 | If file should be rescanned, the return value is S_FALSE. 22 | Otherwise, the return value is HRESULT error code. 23 | */ 24 | virtual HRESULT WINAPI Scan(__in IVirtualFs * file, __in IFsEnumContext * context, __in IScanObserver * observer) = 0; 25 | 26 | // Method is called when application shuts down this module 27 | virtual HRESULT WINAPI OnScanShutdown(void) = 0; 28 | 29 | END_INTERFACE 30 | }; -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/FileFsAttribute.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CFileFsAttribute: 5 | public CRefCount, 6 | public IFsAttribute 7 | { 8 | protected: 9 | virtual ~CFileFsAttribute(); 10 | StringW m_fileName; 11 | HANDLE m_handle; 12 | WIN32_FIND_DATAW m_wfd; 13 | BOOL m_bInited; 14 | public: 15 | CFileFsAttribute(); 16 | 17 | DECLARE_REF_COUNT(); 18 | 19 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 20 | 21 | virtual HRESULT WINAPI Size(__out ULARGE_INTEGER * fileSize) override; 22 | 23 | virtual HRESULT WINAPI Attributes(__out DWORD *attribs) override; 24 | 25 | virtual HRESULT WINAPI SetAttributes(__in DWORD attribs) override; 26 | 27 | virtual HRESULT WINAPI Time(__out_opt FILETIME *lpCreationTime, __out_opt FILETIME *lpLastAccessTime, __out_opt FILETIME *lpLastWriteTime) override; 28 | 29 | virtual HRESULT WINAPI SetTime(__in_opt FILETIME *lpCreationTime, __in_opt FILETIME *lpLastAccessTime, __in_opt FILETIME *lpLastWriteTime) override; 30 | 31 | virtual HRESULT WINAPI SetFilePath(__in LPCWSTR lpFilePath, __in_opt void* handle /*= NULL*/) override; 32 | 33 | protected: 34 | virtual HRESULT WINAPI QueryAttributes(void); 35 | 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /TinyAvCore/Module/ModuleMgrService.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef std::vector MODULE_ARRAY; 5 | 6 | class CModuleMgrService : 7 | public CRefCount, 8 | public IModuleManager 9 | { 10 | protected: 11 | MODULE_ARRAY m_modules; 12 | 13 | public: 14 | CModuleMgrService(); 15 | virtual ~CModuleMgrService(); 16 | 17 | DECLARE_REF_COUNT(); 18 | 19 | virtual HRESULT WINAPI QueryInterface( 20 | __in REFIID riid, 21 | _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 22 | 23 | virtual HRESULT WINAPI Load(__in LPCWSTR lpModuleDirectory = NULL, __in LPCWSTR lpModuleName = NULL, __in DWORD flags = 0) override; 24 | 25 | 26 | virtual HRESULT WINAPI Load(__in LPCWSTR lpModuleDirectory = NULL, __in ModuleType moduleType = DefaultModuleType, __in DWORD flags = 0) override; 27 | 28 | 29 | virtual HRESULT WINAPI Unload(__in LPCWSTR lpModuleName = NULL) override; 30 | 31 | 32 | virtual HRESULT WINAPI Unload(__in ModuleType moduleType = DefaultModuleType) override; 33 | 34 | 35 | virtual HRESULT WINAPI QueryModule(__out IModule **&module, __out size_t& moduleCount, __in LPCWSTR lpModuleName = NULL) override; 36 | 37 | 38 | virtual HRESULT WINAPI QueryModule(__out IModule **&module, __out size_t& moduleCount, __in ModuleType moduleType = DefaultModuleType) override; 39 | 40 | }; 41 | -------------------------------------------------------------------------------- /tests/Unittests/Unittests.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | -------------------------------------------------------------------------------- /include/Scanner/ScanContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | 4 | MIDL_INTERFACE("C832DE40-EEF1-4A5C-982C-7E3FA1E6F8F1") 5 | IScanContext: public IUnknown 6 | { 7 | public: 8 | BEGIN_INTERFACE 9 | virtual HRESULT WINAPI AddScanPath(__in LPCWSTR lpPath) = 0; 10 | virtual HRESULT WINAPI RemoveScanPath(__in LPCWSTR lpPath) = 0; 11 | virtual HRESULT WINAPI GetScanList(__out BSTR* lpPath, __out UINT *itemCount) = 0; 12 | virtual HRESULT WINAPI FreeScanList(__in BSTR lpPath, __in UINT itemCount) = 0; 13 | 14 | virtual HRESULT WINAPI AddIgnoreItem(__in LPCWSTR lpPath) = 0; 15 | virtual HRESULT WINAPI RemoveIgnoreItem(__in LPCWSTR lpPath) = 0; 16 | virtual HRESULT WINAPI GetIgnoreList(__out BSTR* lpPath, __out UINT *itemCount) = 0; 17 | virtual HRESULT WINAPI FreeIgnoreList(__in BSTR lpPath, __in UINT itemCount) = 0; 18 | 19 | virtual HRESULT WINAPI AddScanPattern(__in LPCWSTR lpPattern) = 0; 20 | virtual HRESULT WINAPI RemoveScanPattern(__in LPCWSTR lpPattern) = 0; 21 | virtual HRESULT WINAPI GetScanPattern(__out BSTR* lpPath, __out UINT *itemCount) = 0; 22 | virtual HRESULT WINAPI FreeScanPattern(__in BSTR lpPath, __in UINT itemCount) = 0; 23 | 24 | virtual HRESULT WINAPI SetMaxDepth(__in int maxDepth) = 0; 25 | virtual int WINAPI GetMaxDepth(void) = 0; 26 | 27 | virtual HRESULT WINAPI SetMaxFileSize(__in ULARGE_INTEGER fileSize) = 0; 28 | virtual HRESULT WINAPI GetMaxFileSize(__in ULARGE_INTEGER *fileSize) = 0; 29 | 30 | virtual UINT WINAPI GetScanMode(void) = 0; 31 | virtual HRESULT WINAPI SetScanMode(__in UINT status) = 0; 32 | END_INTERFACE 33 | }; -------------------------------------------------------------------------------- /ci/windows/build_appveyor.bat: -------------------------------------------------------------------------------- 1 | :: Build script for TinyAntivirus and all submodules 2 | :: compiler and linker: Visual Studio 2015 3 | @ECHO OFF 4 | 5 | :: verify parameters 6 | if "%1" == "" ( 7 | echo [!] Configure Projects to Target Platform 8 | exit /b 1 9 | ) 10 | 11 | if "%2" == "" ( 12 | echo [!] Configure projects configuration 13 | exit /b 1 14 | ) 15 | 16 | set generator=Visual Studio 14 2015 17 | if /I "%1" == "x64" (set generator=%generator% Win64) 18 | 19 | :: build googletest library 20 | set build_gtest_dir=libs\googletest\googletest\build 21 | if exist "%build_gtest_dir%" ( 22 | del /S /Q "%build_gtest_dir%" 23 | ) 24 | md "%build_gtest_dir%" 25 | pushd "%build_gtest_dir%" 26 | cmake -G "%generator%" -DCMAKE_CONFIGURATION_TYPES="%2" -DCMAKE_C_FLAGS_RELEASE="/MT" -DCMAKE_C_FLAGS_DEBUG="/MTd" .. 27 | cmake --build . --config "%2" 28 | popd 29 | 30 | :: build zlib library 31 | set build_zlib_dir=libs\zlib\build 32 | if exist "%build_zlib_dir%" ( 33 | del /S /Q "%build_zlib_dir%" 34 | ) 35 | md "%build_zlib_dir%" 36 | pushd "%build_zlib_dir%" 37 | cmake -G "%generator%" -DCMAKE_CONFIGURATION_TYPES="%2" -DCMAKE_C_FLAGS_RELEASE="/MT" -DCMAKE_C_FLAGS_DEBUG="/MTd" .. 38 | cmake --build . --config "%2" 39 | popd 40 | 41 | :: setup build environment 42 | IF EXIST "%PROGRAMFILES(X86)%" GOTO win64 43 | call "%PROGRAMFILES%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %1 44 | goto Build 45 | 46 | :win64 47 | call "%PROGRAMFILES(X86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %1 48 | 49 | :: build all projects 50 | :Build 51 | msbuild TinyAntivirus.sln /p:Configuration="%2" /p:Platform="%1" -------------------------------------------------------------------------------- /TinyAvConsole/ConsoleObserver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CConsoleObserver 5 | : public CRefCount 6 | , public IScanObserver 7 | { 8 | protected: 9 | BOOL m_bVirusDetected; 10 | BOOL m_bRescan; 11 | BOOL m_error; 12 | ULONGLONG m_TotalFileCnt; 13 | ULONGLONG m_TotalObjectCnt; 14 | ULONGLONG m_DetectedCnt; 15 | ULONGLONG m_RemovedCnt; 16 | ULONGLONG m_FailedCnt; 17 | 18 | virtual ~CConsoleObserver(); 19 | 20 | public: 21 | CConsoleObserver(); 22 | 23 | // Implementing IUnknown interface 24 | DECLARE_REF_COUNT(); 25 | 26 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __in void **ppvObject); 27 | 28 | // Implementing IScanObserver interface 29 | virtual HRESULT WINAPI OnScanStarted(__in IFsEnumContext * context) override; 30 | 31 | virtual HRESULT WINAPI OnScanPaused(__in IFsEnumContext * context) override; 32 | 33 | virtual HRESULT WINAPI OnScanResumed(__in IFsEnumContext * context) override; 34 | 35 | virtual HRESULT WINAPI OnScanStopping(__in IFsEnumContext * context) override; 36 | 37 | virtual HRESULT WINAPI OnPreScan(__in IVirtualFs * file, __in IFsEnumContext * context) override; 38 | 39 | virtual HRESULT WINAPI OnAllScanFinished(__in IVirtualFs * file, __in IFsEnumContext * context) override; 40 | 41 | virtual HRESULT WINAPI OnPreClean(__in IVirtualFs * file, __in IFsEnumContext * context, __inout SCAN_RESULT * result) override; 42 | 43 | virtual HRESULT WINAPI OnPostClean(__in IVirtualFs * file, __in IFsEnumContext * context, __in SCAN_RESULT * result) override; 44 | 45 | virtual void WINAPI OnError(__in DWORD dwErrorCode, __in_opt LPCWSTR lpMessage = NULL) override; 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/BufferedStream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class CBufferedStream : 6 | public CRefCount, 7 | public IFsStream 8 | { 9 | protected: 10 | ULONGLONG m_FileSize; 11 | ULONGLONG m_CurrPos; 12 | std::vector m_DataStream; 13 | virtual ~CBufferedStream(void); 14 | public: 15 | CBufferedStream(void); 16 | 17 | // implement IUnknown Interface 18 | DECLARE_REF_COUNT(); 19 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 20 | 21 | // implement IFsStream Interface 22 | virtual HRESULT WINAPI Read(__out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) override; 23 | 24 | virtual HRESULT WINAPI ReadAt(__in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, __out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) override; 25 | 26 | virtual HRESULT WINAPI Write(__in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) override; 27 | 28 | virtual HRESULT WINAPI WriteAt(__in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, __in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) override; 29 | 30 | virtual HRESULT WINAPI Tell(__out ULARGE_INTEGER * pos) override; 31 | 32 | virtual HRESULT WINAPI Seek(__out_opt ULARGE_INTEGER * pos, __in LARGE_INTEGER const distanceToMove, __in const FsStreamSeek MoveMethod) override; 33 | 34 | virtual void WINAPI SetFileHandle(__in void* const handle) override; 35 | 36 | virtual HRESULT WINAPI Shrink(void) override; 37 | 38 | }; 39 | -------------------------------------------------------------------------------- /SalityKiller/SalityKiller.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | 39 | 40 | Resource Files 41 | 42 | 43 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | #---------------------------------# 2 | # general configuration # 3 | #---------------------------------# 4 | 5 | # version format 6 | version: 0.1.{build}-{branch} 7 | 8 | # Do not build on tags (GitHub and BitBucket) 9 | skip_tags: true 10 | 11 | # Including commits with particular message or from specific user 12 | only_commits: 13 | message: /build/ # Start a new build if message contains 'build' 14 | 15 | #---------------------------------# 16 | # environment configuration # 17 | #---------------------------------# 18 | 19 | # Build worker image (VM template) 20 | image: Visual Studio 2015 21 | 22 | # scripts that are called at very beginning, before repo cloning 23 | init: 24 | - git config --global core.autocrlf input 25 | 26 | # clone directory 27 | clone_folder: c:\projects\TinyAntivirus 28 | 29 | # environment variables 30 | environment: 31 | SAMPLE_DIR: c:\projects\TinyAntivirus\tests\samples 32 | CONFIGURATION: Release 33 | matrix: 34 | - PLATFORM: x86 35 | 36 | - PLATFORM: x64 37 | 38 | 39 | #---------------------------------# 40 | # build configuration # 41 | #---------------------------------# 42 | 43 | # scripts to run before build 44 | before_build: 45 | - cmd: git submodule update --init --recursive 46 | 47 | # run custom scripts instead of automatic MSBuild 48 | build_script: 49 | - cmd: ci\windows\build_appveyor.bat %PLATFORM% %CONFIGURATION% 50 | 51 | #---------------------------------# 52 | # tests configuration # 53 | #---------------------------------# 54 | 55 | # run custom scripts instead of automatic tests 56 | test_script: 57 | - cmd: ci\windows\test_appveyor.bat %PLATFORM% %CONFIGURATION% 58 | 59 | 60 | deploy: off -------------------------------------------------------------------------------- /TinyAvConsole/TinyAvConsole.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | 40 | 41 | Resource Files 42 | 43 | 44 | -------------------------------------------------------------------------------- /tests/Unittests/FileFs_unittest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../TinyAvCore/FileSystem/FileFs.h" 4 | 5 | extern WCHAR szTestcase[MAX_PATH]; 6 | 7 | TEST(FileFs, All) 8 | { 9 | ULONG flags; 10 | BOOL isOpened; 11 | WCHAR szNewFile[MAX_PATH]; 12 | wcscpy_s(szNewFile, MAX_PATH, szTestcase); 13 | wcscat_s(szNewFile, MAX_PATH, L".new"); 14 | CopyFileW(szTestcase, szNewFile, FALSE); 15 | IVirtualFs * fs = new CFileFs(); 16 | ULONG creationFlags = IVirtualFs::fsRead | IVirtualFs::fsSharedRead | IVirtualFs::fsSharedWrite | IVirtualFs::fsOpenExisting | IVirtualFs::fsAttrNormal; 17 | 18 | ASSERT_HRESULT_SUCCEEDED(fs->Create(szNewFile, creationFlags)); 19 | ASSERT_HRESULT_SUCCEEDED(fs->IsOpened(&isOpened)); 20 | ASSERT_TRUE(isOpened); 21 | ASSERT_HRESULT_SUCCEEDED(fs->Close()); 22 | 23 | ASSERT_HRESULT_SUCCEEDED(fs->Create(szNewFile, 0)); 24 | ASSERT_HRESULT_SUCCEEDED(fs->IsOpened(&isOpened)); 25 | ASSERT_FALSE(isOpened); 26 | ASSERT_HRESULT_SUCCEEDED(fs->ReCreate(NULL, creationFlags)); 27 | ASSERT_HRESULT_SUCCEEDED(fs->IsOpened(&isOpened)); 28 | ASSERT_TRUE(isOpened); 29 | ASSERT_HRESULT_SUCCEEDED(fs->GetFlags(&flags)); 30 | ASSERT_EQ(creationFlags, flags); 31 | BSTR s; 32 | ASSERT_HRESULT_SUCCEEDED(fs->GetFullPath(&s)); 33 | ASSERT_STREQ(szNewFile, s); 34 | SysFreeString(s); 35 | ASSERT_HRESULT_SUCCEEDED(fs->GetFileName(&s)); 36 | ASSERT_STREQ(TEXT("testcase.bin.new"), s); 37 | SysFreeString(s); 38 | ASSERT_HRESULT_SUCCEEDED(fs->GetFileExt(&s)); 39 | ASSERT_STREQ(TEXT("new"), s); 40 | SysFreeString(s); 41 | ULONG fsType; 42 | ASSERT_HRESULT_SUCCEEDED(fs->GetFsType(&fsType)); 43 | ASSERT_EQ(IVirtualFs::basic, fsType); 44 | ASSERT_HRESULT_SUCCEEDED(fs->DeferredDelete()); 45 | ASSERT_HRESULT_SUCCEEDED(fs->Close()); 46 | fs->Release(); 47 | } -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/FileFsStream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #ifndef DEFAULT_MAX_CACHE_SIZE 5 | #define DEFAULT_MAX_CACHE_SIZE (16 * 1024) 6 | #endif 7 | 8 | class CFileFsStream : 9 | public CRefCount, 10 | public IFsStream 11 | { 12 | protected: 13 | char *m_cache; 14 | size_t m_cacheSize; 15 | ULARGE_INTEGER m_cachePos; 16 | ULARGE_INTEGER m_currentPos; 17 | HANDLE m_hFile; 18 | 19 | virtual ~CFileFsStream(); 20 | 21 | public: 22 | CFileFsStream(); 23 | 24 | // implement IUnknown interface 25 | DECLARE_REF_COUNT(); 26 | 27 | virtual HRESULT WINAPI QueryInterface( 28 | __in REFIID riid, 29 | __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 30 | 31 | // implement IFsStream interface 32 | virtual HRESULT WINAPI Read(__out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) override; 33 | 34 | virtual HRESULT WINAPI ReadAt(__in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, 35 | __out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) override; 36 | 37 | virtual HRESULT WINAPI Write(__in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) override; 38 | 39 | virtual HRESULT WINAPI WriteAt(__in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, 40 | __in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) override; 41 | 42 | virtual HRESULT WINAPI Tell(__out ULARGE_INTEGER * pos) override; 43 | 44 | virtual HRESULT WINAPI Seek(__out_opt ULARGE_INTEGER * pos, __in LARGE_INTEGER const distanceToMove, __in const FsStreamSeek MoveMethod) override; 45 | 46 | virtual void WINAPI SetFileHandle(__in void* const handle) override; 47 | 48 | virtual HRESULT WINAPI Shrink(void) override; 49 | 50 | }; 51 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/zip/ZipFsAttribute.cpp: -------------------------------------------------------------------------------- 1 | #include "ZipFsAttribute.h" 2 | #include "../../Utils.h" 3 | 4 | CZipFsAttribute::CZipFsAttribute(void) 5 | { 6 | } 7 | 8 | CZipFsAttribute::~CZipFsAttribute(void) 9 | { 10 | } 11 | 12 | HRESULT WINAPI CZipFsAttribute::QueryAttributes(void) 13 | { 14 | char filename_inzip[256]; 15 | unz_file_info64 file_info; 16 | if (m_handle == NULL) return E_NOT_SET; 17 | 18 | int err = unzGetCurrentFileInfo64((unzFile)m_handle, &file_info, 19 | filename_inzip, sizeof(filename_inzip), 20 | NULL, 0, NULL, 0); 21 | if (err != UNZ_OK) 22 | return E_FAIL; 23 | 24 | // file size 25 | m_wfd.nFileSizeHigh = file_info.uncompressed_size >> 32; 26 | m_wfd.nFileSizeLow = file_info.uncompressed_size & 0xFFFFFFFF; 27 | 28 | // attribute 29 | m_wfd.dwFileAttributes = file_info.external_fa; 30 | 31 | // time 32 | DosDateTimeToFileTime(file_info.dosDate >> 16, (WORD)file_info.dosDate, &m_wfd.ftLastWriteTime); 33 | m_wfd.ftCreationTime = m_wfd.ftLastWriteTime; 34 | m_wfd.ftLastAccessTime = m_wfd.ftLastWriteTime; 35 | 36 | // file name 37 | StringA strNameA = filename_inzip; 38 | StringW strNameW = AnsiToUnicode(&strNameA); 39 | wcscpy_s(m_wfd.cFileName, MAX_PATH, strNameW.c_str()); 40 | m_bInited = TRUE; 41 | return S_OK; 42 | } 43 | 44 | HRESULT WINAPI CZipFsAttribute::SetTime(__in_opt FILETIME *lpCreationTime, __in_opt FILETIME *lpLastAccessTime, __in_opt FILETIME *lpLastWriteTime) 45 | { 46 | UNREFERENCED_PARAMETER(lpCreationTime); 47 | UNREFERENCED_PARAMETER(lpLastWriteTime); 48 | UNREFERENCED_PARAMETER(lpLastAccessTime); 49 | 50 | return E_NOTIMPL; 51 | } 52 | 53 | HRESULT WINAPI CZipFsAttribute::SetFilePath(__in LPCWSTR lpFilePath, __in_opt void* handle /*= NULL*/) 54 | { 55 | m_handle = (HANDLE)handle; 56 | m_fileName = lpFilePath; 57 | return QueryAttributes(); 58 | } 59 | 60 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/FileFs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CFileFs: 5 | public CRefCount, 6 | public IVirtualFs 7 | { 8 | protected: 9 | StringW m_delimiter; 10 | StringW m_FileName; 11 | HANDLE m_handle; 12 | ULONG m_flags; 13 | ULONG m_error; 14 | ULONG m_fsType; 15 | IFsAttribute * m_attribute; 16 | IFsStream * m_stream; 17 | IVirtualFs * m_container; 18 | 19 | virtual ~CFileFs(); 20 | public: 21 | CFileFs(); 22 | 23 | // implementing IUnknown interface 24 | DECLARE_REF_COUNT(); 25 | 26 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 27 | 28 | // implementing IFsObject interface 29 | virtual HRESULT WINAPI Create(__in LPCWSTR lpFileName, __in ULONG const flags) ; 30 | 31 | virtual HRESULT WINAPI Close(void) override; 32 | 33 | virtual HRESULT WINAPI ReCreate(__in_opt void* handle /*= NULL*/, __in_opt ULONG const flags /*= 0*/) override; 34 | 35 | virtual HRESULT WINAPI IsOpened(__out BOOL *isOpened) override; 36 | 37 | virtual HRESULT WINAPI GetFlags(__out ULONG *flags) override; 38 | 39 | virtual HRESULT WINAPI GetFullPath(__out BSTR *fullPath) override; 40 | 41 | virtual HRESULT WINAPI GetFileName(__out BSTR *fileName) override; 42 | 43 | virtual HRESULT WINAPI GetFileExt(__out BSTR *fileExt) override; 44 | 45 | virtual HRESULT WINAPI GetContainer(__out IVirtualFs **container) override; 46 | 47 | virtual HRESULT WINAPI SetContainer(__in IVirtualFs *container) override; 48 | 49 | virtual ULONG WINAPI GetError(void) override; 50 | 51 | virtual void WINAPI SetError(__in const ULONG error) override; 52 | 53 | virtual HRESULT WINAPI GetHandle(__out LPVOID * fileHandle) override; 54 | 55 | virtual HRESULT WINAPI GetFsType(__out ULONG * fsType) override; 56 | 57 | virtual HRESULT WINAPI DeferredDelete(void) override; 58 | 59 | }; -------------------------------------------------------------------------------- /include/FileSystem/FsEnum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "FsEnumObserver.h" 4 | 5 | MIDL_INTERFACE("A438AF0B-883B-4852-B261-DF2A882418AB") 6 | IFsEnum : public IUnknown 7 | { 8 | BEGIN_INTERFACE 9 | 10 | public: 11 | enum FsEnumErrorCode 12 | { 13 | FsEnumErr = ENUMERATION_ERROR_CODE_BASE, 14 | FsEnumAccessDenied, 15 | FsEnumNotFound 16 | }; 17 | 18 | /* 19 | Register an observer for enumeration 20 | The observer will be called when a new file is hit. 21 | 22 | @observer: a pointer to IFsEnumObserver object 23 | @return: HRESULT on success, or other value on failure. 24 | */ 25 | virtual HRESULT WINAPI AddObserver(__in IFsEnumObserver *observer) = 0; 26 | 27 | /* 28 | Unregister (remove) an observer. 29 | This API removes the observer registered by AddObserver() 30 | 31 | @observer: a pointer to IFsEnumObserver object 32 | @return: HRESULT on success, or other value on failure. 33 | */ 34 | virtual HRESULT WINAPI RemoveObserver(__in IFsEnumObserver *observer) = 0; 35 | 36 | /* 37 | Register an archiver for enumeration 38 | The observer will be called when a new file is hit. 39 | 40 | @archiver: a pointer to IFsEnum object 41 | @return: HRESULT on success, or other value on failure. 42 | */ 43 | virtual HRESULT WINAPI AddArchiver(__in IFsEnum * archiver) = 0; 44 | 45 | /* 46 | Unregister (remove) an archiver. 47 | This API removes the observer registered by RemoveArchiver() 48 | 49 | @archiver: a pointer to IFsEnum object 50 | @return: HRESULT on success, or other value on failure. 51 | */ 52 | virtual HRESULT WINAPI RemoveArchiver(__in IFsEnum * archiver) = 0; 53 | 54 | // Enumerate files and directories 55 | // @context: enumeration context 56 | // @return: HRESULT on success, or other value on failure. 57 | virtual HRESULT WINAPI Enum( __in IFsEnumContext *context) = 0; 58 | 59 | // Stop enumeration 60 | virtual void WINAPI Stop(void) = 0; 61 | 62 | END_INTERFACE 63 | }; 64 | -------------------------------------------------------------------------------- /SalityKiller/KillVirus.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class CKillVirus : 6 | public CRefCount, 7 | public IScanModule, 8 | public IEmulObserver 9 | { 10 | private: 11 | uc_hook m_hookcode; 12 | uc_hook m_hookmem; 13 | 14 | protected: 15 | BYTE* m_OepCode; 16 | DWORD m_salityEp; 17 | DWORD m_dwOepCodeSize; 18 | DWORD m_OepAddr; 19 | ULONGLONG m_InsCount; 20 | SCAN_RESULT m_scanResult; 21 | MODULE_INFO m_info; 22 | IPeFile * m_parser; 23 | IEmulator * m_emul; 24 | DWORD m_emulErrCode; 25 | virtual ~CKillVirus(); 26 | 27 | public: 28 | CKillVirus(); 29 | 30 | // Implementing IUnknown interface 31 | DECLARE_REF_COUNT(); 32 | 33 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out void **ppvObject); 34 | 35 | // Implementing IModule interface 36 | virtual HRESULT WINAPI GetModuleInfo(__out MODULE_INFO * scanInfo) override; 37 | 38 | virtual ModuleType WINAPI GetType(void) override; 39 | 40 | virtual HRESULT WINAPI GetName(__out BSTR *name) override; 41 | 42 | // Implementing IScanModule interface 43 | virtual HRESULT WINAPI OnScanInitialize(void) override; 44 | 45 | virtual HRESULT WINAPI Scan(__in IVirtualFs * file, __in IFsEnumContext * context, __in IScanObserver * observer) override; 46 | 47 | virtual HRESULT WINAPI OnScanShutdown(void) override; 48 | 49 | protected: 50 | // Implementing IEmulObserver interface 51 | virtual HRESULT WINAPI OnEmulatorStarting(void) override; 52 | virtual void WINAPI OnError(__in DWORD const dwErrorCode) override; 53 | virtual HRESULT WINAPI OnEmulatorStopped(void) override; 54 | 55 | virtual void OnHookCode(uint64_t address, uint32_t size); 56 | // 57 | virtual BOOL VerifySignature(__in_bcount(size) LPBYTE buffer, __in DWORD const size); 58 | 59 | private: 60 | static void HookCode(uc_engine *uc, uint64_t address, uint32_t size, void *user_data); 61 | static bool HookMemInvalid(uc_engine *uc, uc_mem_type type, 62 | uint64_t address, int size, int64_t value, void *user_data); 63 | }; -------------------------------------------------------------------------------- /include/Scanner/ScanObserver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "../FileSystem/FsObject.h" 4 | #include "../FileSystem/FsEnumContext.h" 5 | 6 | enum ScanResult 7 | { 8 | NoVirus = 1, 9 | NotaVirus, 10 | VirusDetected, 11 | 12 | }; 13 | 14 | enum CleanResult 15 | { 16 | DonotClean = 1, 17 | CleanVirusSucceeded, 18 | CleanVirusDenied, 19 | VirusDeleted, 20 | }; 21 | 22 | enum ScanAction 23 | { 24 | KillVirus = 1, 25 | DeleteVirus, 26 | LeaveVirus, 27 | }; 28 | 29 | typedef struct SCAN_RESULT 30 | { 31 | ULONG scanResult; 32 | ULONG action; 33 | WCHAR malwareName[MAX_NAME]; 34 | ULONG cleanResult; 35 | }SCAN_RESULT, *LPSCAN_RESULT; 36 | 37 | MIDL_INTERFACE("494B0A6D-5289-403B-B0C3-5445124E14E4") 38 | IScanObserver : public IUnknown 39 | { 40 | public: 41 | BEGIN_INTERFACE 42 | 43 | // called when scanner started 44 | virtual HRESULT WINAPI OnScanStarted(__in IFsEnumContext * context) = 0; 45 | 46 | // called when scanner paused 47 | virtual HRESULT WINAPI OnScanPaused(__in IFsEnumContext * context) = 0; 48 | 49 | // called when scanner resumed 50 | virtual HRESULT WINAPI OnScanResumed(__in IFsEnumContext * context) = 0; 51 | 52 | // called when scanner is going to stop 53 | virtual HRESULT WINAPI OnScanStopping(__in IFsEnumContext * context) = 0; 54 | 55 | // pre-scan a file 56 | virtual HRESULT WINAPI OnPreScan(__in IVirtualFs * file, __in IFsEnumContext * context) = 0; 57 | 58 | // called when all scan-module finished 59 | virtual HRESULT WINAPI OnAllScanFinished(__in IVirtualFs * file, __in IFsEnumContext * context) = 0; 60 | 61 | //called before cleaning file 62 | virtual HRESULT WINAPI OnPreClean(__in IVirtualFs * file, __in IFsEnumContext * context, __inout SCAN_RESULT * result) = 0; 63 | 64 | //called after cleaning file 65 | virtual HRESULT WINAPI OnPostClean(__in IVirtualFs * file, __in IFsEnumContext * context, __in SCAN_RESULT * result) = 0; 66 | 67 | //called when an error occurred 68 | // @dwErrorCode: error code 69 | // @lpMessage: Error message 70 | virtual void WINAPI OnError(__in DWORD dwErrorCode, __in_opt LPCWSTR lpMessage = NULL) = 0; 71 | 72 | END_INTERFACE 73 | }; -------------------------------------------------------------------------------- /include/Module/Module.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | 4 | enum ModuleType 5 | { 6 | DefaultModuleType = 1, 7 | ScanModule 8 | }; 9 | 10 | typedef struct MODULE_INFO { 11 | ModuleType type; 12 | WCHAR name[MAX_NAME + 1]; 13 | HMODULE handle; 14 | }MODULE_INFO, *LPMODULE_INFO; 15 | 16 | MIDL_INTERFACE("151BBAB1-5D35-4A40-9940-09C08A412B89") 17 | IModule : public IUnknown 18 | { 19 | public: 20 | BEGIN_INTERFACE 21 | 22 | /* Retrieve module information 23 | @scanInfo: a pointer to an variable storing MODULE_INFO 24 | @return: HRESULT on success, or other value on failure. 25 | */ 26 | virtual HRESULT WINAPI GetModuleInfo(__out MODULE_INFO * scanInfo) = 0; 27 | 28 | /* Retrieve module information 29 | @return: module type 30 | */ 31 | virtual ModuleType WINAPI GetType(void) = 0; 32 | 33 | /* Retrieve module name 34 | @name: a pointer to an variable storing name 35 | @return: HRESULT on success, or other value on failure. 36 | */ 37 | virtual HRESULT WINAPI GetName(__out BSTR *name) = 0; 38 | 39 | END_INTERFACE 40 | }; 41 | 42 | /* 43 | All plug-in module MUST have .plg extension and export a function named CreateModuleObject. 44 | Exported function MUST have prototype that is declared as follows: 45 | 46 | HRESULT (WINAPI *CREATEMODULEOBJECT)(__in REFCLSID rclsid, __in DWORD dwClsContext, __in REFIID riid, __out LPVOID *ppv); 47 | 48 | @rclsid: The CLSID associated with the data and code that will be used to create the object. 49 | @dwClsContext: Context in which the code that manages the newly created object will run. 50 | @riid: A reference to the identifier of the interface to be used to communicate with the object. 51 | @ppv: Address of pointer variable that receives the interface pointer requested in riid. 52 | Upon successful return, *ppv contains the requested interface pointer. Upon failure, *ppv contains NULL. 53 | 54 | @return: HRESULT on success, or other value on failure. 55 | */ 56 | #define MODULE_EXTENSION L"plg" 57 | #define MODULE_EP ("CreateModuleObject") 58 | typedef HRESULT (WINAPI *CREATEMODULEOBJECT)(__in REFCLSID rclsid, __in DWORD dwClsContext, __in REFIID riid, __out LPVOID *ppv); 59 | -------------------------------------------------------------------------------- /SalityKiller/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #if defined DEBUG || defined _DEBUG 6 | #include 7 | #endif 8 | #include "KillVirus.h" 9 | 10 | HMODULE g_hMod = NULL; 11 | 12 | BOOL WINAPI DllMain( 13 | HINSTANCE hinstDLL, // handle to DLL module 14 | DWORD fdwReason, // reason for calling function 15 | LPVOID lpReserved) // reserved 16 | { 17 | #if defined DEBUG || defined _DEBUG 18 | { 19 | int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 20 | _CrtSetDbgFlag(flag | _CRTDBG_LEAK_CHECK_DF); 21 | //_CrtSetBreakAlloc(0x1337); 22 | } 23 | #endif 24 | 25 | UNREFERENCED_PARAMETER(lpReserved); 26 | 27 | // Perform actions based on the reason for calling. 28 | switch (fdwReason) 29 | { 30 | case DLL_PROCESS_ATTACH: 31 | DisableThreadLibraryCalls(hinstDLL); 32 | g_hMod = hinstDLL; 33 | break; 34 | 35 | case DLL_THREAD_ATTACH: 36 | case DLL_THREAD_DETACH: 37 | case DLL_PROCESS_DETACH: 38 | break; 39 | } 40 | return TRUE; // Successful DLL_PROCESS_ATTACH. 41 | } 42 | 43 | #ifdef __cplusplus 44 | extern "C" 45 | { 46 | #endif 47 | 48 | HRESULT WINAPI CreateModuleObject(__in REFCLSID rclsid, __in DWORD dwClsContext, __in REFIID riid, __out LPVOID *ppv) 49 | { 50 | UNREFERENCED_PARAMETER(rclsid); 51 | UNREFERENCED_PARAMETER(dwClsContext); 52 | if (ppv == NULL) return E_INVALIDARG; 53 | 54 | if (IsEqualIID(riid, __uuidof(IModule))) 55 | { 56 | *ppv = static_cast(new CKillVirus()); 57 | return S_OK; 58 | } 59 | 60 | return E_NOINTERFACE; 61 | } 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | ////////////////////////////////////////////////////////////////////////// 68 | 69 | // notelemetry 70 | #ifdef __cplusplus 71 | extern "C" 72 | { 73 | #endif // __cplusplus 74 | void _cdecl __vcrt_initialize_telemetry_provider() {} 75 | void _cdecl __telemetry_main_invoke_trigger() {} 76 | void _cdecl __telemetry_main_return_trigger() {} 77 | void _cdecl __vcrt_uninitialize_telemetry_provider() {} 78 | #ifdef __cplusplus 79 | }; 80 | #endif // __cplusplus 81 | ////////////////////////////////////////////////////////////////////////// 82 | -------------------------------------------------------------------------------- /include/Scanner/Scanner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "ScanModule.h" 4 | #include "ScanObserver.h" 5 | 6 | MIDL_INTERFACE("6BC6668B-E083-4FDA-9F27-EA4905BED319") 7 | IScanner : public IUnknown 8 | { 9 | public: 10 | BEGIN_INTERFACE 11 | 12 | /* Add new scan observer to the monitor list 13 | @observer: a pointer to IScanObserver object 14 | @return: HRESULT on success, or other value on failure. 15 | */ 16 | virtual HRESULT WINAPI AddScanObserver(__in IScanObserver *observer) = 0; 17 | 18 | /* Remove an scan observer from the monitor list 19 | @observer: a pointer to IScanObserver object 20 | @return: HRESULT on success, or other value on failure. 21 | */ 22 | virtual HRESULT WINAPI RemoveScanObserver(__in IScanObserver *observer) = 0; 23 | 24 | /* Add scan module to engine 25 | @observer: a pointer to IScanObserver object 26 | @return: HRESULT on success, or other value on failure. 27 | */ 28 | virtual HRESULT WINAPI AddScanModule(__in IScanModule *scanModule) = 0; 29 | 30 | /* Remove scan module from engine 31 | @observer: a pointer to IScanObserver object 32 | @return: HRESULT on success, or other value on failure. 33 | */ 34 | virtual HRESULT WINAPI RemoveScanModule(__in IScanModule *scanModule) = 0; 35 | 36 | /* Start scanning 37 | @enumContext: a pointer to IFsEnumContext object 38 | @return: HRESULT on success, or other value on failure. 39 | */ 40 | virtual HRESULT WINAPI Start(__in IFsEnumContext *enumContext) = 0; 41 | 42 | /* Stop scanning 43 | @enumContext: a pointer to IFsEnumContext object 44 | @return: HRESULT on success, or other value on failure. 45 | */ 46 | virtual HRESULT WINAPI Stop(__in IFsEnumContext *enumContext) = 0; 47 | 48 | /* Pause scanning 49 | @enumContext: a pointer to IFsEnumContext object 50 | @return: HRESULT on success, or other value on failure. 51 | */ 52 | virtual HRESULT WINAPI Pause(__in IFsEnumContext *enumContext) = 0; 53 | 54 | /* Resume scanning 55 | @enumContext: a pointer to IFsEnumContext object 56 | @return: HRESULT on success, or other value on failure. 57 | */ 58 | virtual HRESULT WINAPI Resume(__in IFsEnumContext *enumContext) = 0; 59 | 60 | // wait for all threads to stop 61 | virtual void WINAPI Forever(void) = 0; 62 | 63 | END_INTERFACE 64 | }; -------------------------------------------------------------------------------- /include/TinyAvCore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "TinyAvBase.h" 3 | #include "Module/Module.h" 4 | #include "Scanner/ScanModule.h" 5 | #include "FileType/PEFile.h" 6 | #include "Emulator/Emulator.h" 7 | #include "Module/ModuleManager.h" 8 | #include "Scanner/Scanner.h" 9 | #include "FileSystem/FsObject.h" 10 | #include "FileSystem/FsEnum.h" 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" 15 | { 16 | #endif 17 | 18 | /* 19 | Create a class object that refers to the specified CLSID 20 | 21 | @rclsid: The CLSID associated with the data and code that will be used to create the object. 22 | @dwClsContext: Context in which the code that manages the newly created object will run. 23 | @riid: A reference to the identifier of the interface to be used to communicate with the object. 24 | @ppv: Address of pointer variable that receives the interface pointer requested in riid. 25 | Upon successful return, *ppv contains the requested interface pointer. Upon failure, *ppv contains NULL. 26 | 27 | @return: HRESULT on success, or other value on failure. 28 | */ 29 | HRESULT WINAPI CreateClassObject(__in REFCLSID rclsid, __in DWORD dwClsContext, __in REFIID riid, __out LPVOID *ppv); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | // class UUID 36 | 37 | // {84BD7A7C-720C-4A3C-A7DD-6DAA90375F7B} 38 | DEFINE_GUID(CLSID_CPeFileParser, 39 | 0x84bd7a7c, 0x720c, 0x4a3c, 0xa7, 0xdd, 0x6d, 0xaa, 0x90, 0x37, 0x5f, 0x7b); 40 | 41 | // {B714C028-FE14-4CAA-81AC-7954E96EE3D2} 42 | DEFINE_GUID(CLSID_CPeEmulator, 43 | 0xb714c028, 0xfe14, 0x4caa, 0x81, 0xac, 0x79, 0x54, 0xe9, 0x6e, 0xe3, 0xd2); 44 | 45 | // {507A919C-9161-469F-8ACE-EFC3B886B6FC} 46 | DEFINE_GUID(CLSID_CModuleMgrService, 47 | 0x507a919c, 0x9161, 0x469f, 0x8a, 0xce, 0xef, 0xc3, 0xb8, 0x86, 0xb6, 0xfc); 48 | 49 | // {FCFAE438-4304-4FF9-8EEA-BF29D03AB5AC} 50 | DEFINE_GUID(CLSID_CScanService, 51 | 0xfcfae438, 0x4304, 0x4ff9, 0x8e, 0xea, 0xbf, 0x29, 0xd0, 0x3a, 0xb5, 0xac); 52 | 53 | // {BE54543C-AB95-411E-A8B6-6EB0E4E4E950} 54 | DEFINE_GUID(CLSID_CFileFsEnumContext, 55 | 0xbe54543c, 0xab95, 0x411e, 0xa8, 0xb6, 0x6e, 0xb0, 0xe4, 0xe4, 0xe9, 0x50); 56 | 57 | // {2928278F-CE4E-4263-9F8C-07089796643C} 58 | DEFINE_GUID(CLSID_CFileFs, 59 | 0x2928278f, 0xce4e, 0x4263, 0x9f, 0x8c, 0x7, 0x8, 0x97, 0x96, 0x64, 0x3c); 60 | 61 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/FileFsEnumContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #define MAX_FILE_SIZE (10 * 1024 * 1024) 6 | 7 | class CFileFsEnumContext: 8 | public CRefCount, 9 | public IFsEnumContext 10 | { 11 | protected: 12 | ~CFileFsEnumContext(); 13 | ULARGE_INTEGER m_maxSize; 14 | IVirtualFs *m_container; 15 | StringW m_searchPattern; 16 | std::vector m_ignore; 17 | int m_maxDepth; 18 | int m_depth; 19 | int m_maxArchiveDepth; 20 | int m_ArchiveDepth; 21 | ULONG m_flags; 22 | 23 | public: 24 | CFileFsEnumContext(); 25 | 26 | DECLARE_REF_COUNT(); 27 | 28 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 29 | 30 | virtual HRESULT WINAPI SetSearchContainer(__in IVirtualFs* container) override; 31 | 32 | virtual HRESULT WINAPI GetSearchContainer(__out IVirtualFs **container) override; 33 | 34 | virtual HRESULT WINAPI SetSearchPattern(__in LPCWSTR searchPattern) override; 35 | 36 | virtual HRESULT WINAPI GetSearchPattern(__out BSTR *searchPattern) override; 37 | 38 | virtual HRESULT WINAPI SetFlags(__in const ULONG flags) override; 39 | 40 | virtual ULONG WINAPI GetFlags(void) override; 41 | 42 | virtual HRESULT WINAPI SetMaxDepth(__in const int maxDepth) override; 43 | virtual HRESULT WINAPI SetDepth(__in const int depth) override; 44 | 45 | virtual int WINAPI GetMaxDepth(void) override; 46 | 47 | virtual int WINAPI GetDepth(void) override; 48 | 49 | virtual HRESULT WINAPI SetMaxFileSize(__in ULARGE_INTEGER fileSize) override; 50 | 51 | virtual HRESULT WINAPI GetMaxFileSize(__in ULARGE_INTEGER *fileSize) override; 52 | 53 | virtual HRESULT WINAPI AddIgnoreItem(__in LPCWSTR lpPath) override; 54 | 55 | virtual HRESULT WINAPI RemoveIgnoreItem(__in LPCWSTR lpPath) override; 56 | 57 | virtual HRESULT WINAPI GetIgnoreList(__out BSTR* lpPath, __out UINT *itemCount) override; 58 | 59 | virtual HRESULT WINAPI FreeIgnoreList(__in BSTR* lpPath, __in UINT itemCount) override; 60 | 61 | 62 | virtual int WINAPI GetMaxDepthInArchive(void) override; 63 | 64 | 65 | virtual int WINAPI GetDepthInArchive(void) override; 66 | 67 | 68 | virtual HRESULT WINAPI SetMaxDepthInArchive(__in const int maxDepth) override; 69 | 70 | 71 | virtual HRESULT WINAPI SetDepthInArchive(__in const int depth) override; 72 | 73 | }; 74 | 75 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/FileFsEnum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CFileFsEnum : 5 | public CRefCount, 6 | public IFsEnum, 7 | public IFsEnumObserver 8 | { 9 | protected: 10 | virtual ~CFileFsEnum(); 11 | 12 | std::vector m_Observers; 13 | std::vector m_Archivers; 14 | private: 15 | HANDLE m_hStop; 16 | public: 17 | CFileFsEnum(); 18 | 19 | DECLARE_REF_COUNT(); 20 | 21 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 22 | 23 | 24 | virtual HRESULT WINAPI AddObserver(__in IFsEnumObserver *observer) override; 25 | 26 | virtual HRESULT WINAPI RemoveObserver(__in IFsEnumObserver *observer) override; 27 | virtual HRESULT WINAPI AddArchiver(__in IFsEnum * archiver) override; 28 | virtual HRESULT WINAPI RemoveArchiver(__in IFsEnum * archiver) override; 29 | virtual HRESULT WINAPI Enum(__in IFsEnumContext *context) override; 30 | virtual void WINAPI Stop(void) override; 31 | virtual HRESULT WINAPI OnFileFound(__in IVirtualFs *file, __in IFsEnumContext *context, __in const int currentDepth) override; 32 | virtual void WINAPI OnError(__in DWORD dwErrorCode, __in_opt LPCWSTR lpMessage = NULL) override; 33 | 34 | private: 35 | virtual HRESULT WINAPI IsFileTooLarge(__in IVirtualFs * container, __in LPCWSTR fileName, __in IFsEnumContext *context, __out BOOL* over); 36 | virtual HRESULT WINAPI IsFileTooLarge(__in IVirtualFs * file, __in IFsEnumContext *context, __out BOOL* over); 37 | virtual HRESULT WINAPI OnEnumEntryFound(__in IVirtualFs * container, __in LPCWSTR fileName, __in IFsEnumContext *context, __in int currentDepth); 38 | virtual StringW MakePath(__in LPCWSTR str1, __in LPCWSTR str2); 39 | HRESULT CheckDeferredDeletion(__in IVirtualFs * container, __in IVirtualFs * file); 40 | 41 | protected: 42 | virtual void WINAPI InitArchiveObservers(void); 43 | virtual void WINAPI EnumByArchivers(__in IVirtualFs *file, __in IFsEnumContext *context, __in const int depth, __in const int depthInArchive); 44 | virtual void WINAPI CleanupArchiveObservers(void); 45 | virtual BOOL WINAPI TestFilePath(__in LPCWSTR lpFileName); 46 | 47 | HANDLE m_findHandle; 48 | WIN32_FIND_DATAW m_wfd; 49 | virtual BOOL WINAPI EnumInit(void); 50 | virtual BOOL WINAPI EnumFirstFile(__in LPCWSTR lpFileName); 51 | virtual BOOL WINAPI EnumNextFile(void); 52 | virtual void WINAPI EnumClose(void); 53 | }; 54 | 55 | -------------------------------------------------------------------------------- /TinyAvCore/Emulator/unicorn_dynload.h: -------------------------------------------------------------------------------- 1 | // 2 | // Dynamic loader for unicorn shared library in windows and linux. 3 | // This was made for v1.0 of unicorn. 4 | // Newer versions of unicorn may require changes to these files. 5 | // 6 | // Windows Notes: 7 | // If an absolute path to unicorn.dll is passed into uc_dyn_load() it will 8 | // still try to load the rest of the dependent dlls (ie libglib-2.0-0.dll etc) 9 | // from standard dll paths. This is usually the directory that the main 10 | // exe file, that loaded unicorn.dll, is in. This is standard behaviour for 11 | // Windows dll files, and not specific to unicorn dlls. 12 | // 13 | // So putting all dlls in their own directory and then attempting to load 14 | // unicorn.dll from that directory via an absolute path will cause 15 | // uc_dyn_load() to fail. 16 | // 17 | // The easiest way around this is to place all dlls in the same directory 18 | // as your main exe file. Other ways around this are using various flags 19 | // for LoadLibraryEx() or by calling SetDllDirectory(). 20 | // 21 | // LoadLibraryEx info: 22 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx 23 | // SetDllDirectory() info: 24 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686203(v=vs.85).aspx 25 | // 26 | // Zak Escano - November 2015 27 | // 28 | 29 | /* 30 | dynload doesn't work with v0.9 of unicorn and unicorn have only v0.9 for windows in release tag. 31 | I try to port this code to compatible with v0.9. 32 | */ 33 | 34 | #ifndef UNICORN_DYNLOAD_H 35 | #define UNICORN_DYNLOAD_H 36 | 37 | // Undefine shared here so that functions aren't defined as: "__declspec(dllexport)" 38 | #ifdef UNICORN_SHARED 39 | #undef UNICORN_SHARED 40 | #endif 41 | #include 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | 48 | /* 49 | Dynamically load shared library. 50 | Check the notes at the top for info regarding dll file locations in windows. 51 | 52 | @path: path to shared library file. (NULL to use default path) 53 | @flags: system specific flags for loading shared library file. (0 for default) 54 | 55 | @return true on success, false if failed. 56 | */ 57 | bool uc_dyn_load(const char* path, int flags); 58 | 59 | /* 60 | Free resources when done using shared library. 61 | 62 | @return true on success, false if failed. 63 | */ 64 | bool uc_dyn_free(void); 65 | 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | 71 | #endif // UNICORN_DYNLOAD_H 72 | 73 | -------------------------------------------------------------------------------- /include/FileSystem/FsAttribute.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | 4 | MIDL_INTERFACE("4ADFFF42-170A-475E-AF09-C20C405309B5") 5 | IFsAttribute : public IUnknown 6 | { 7 | BEGIN_INTERFACE 8 | 9 | public: 10 | 11 | /* 12 | Set file path and file handle 13 | @lpFilePath: a pointer to file path 14 | @handle: file handle 15 | @return: HRESULT on success, or other value on failure. 16 | */ 17 | virtual HRESULT WINAPI SetFilePath(__in LPCWSTR lpFilePath, __in_opt void* handle = NULL) = 0; 18 | 19 | /* 20 | Retrieve the file size. 21 | @fileSize: a pointer a variable storing result. 22 | @return: HRESULT on success, or other value on failure. 23 | */ 24 | virtual HRESULT WINAPI Size(__out ULARGE_INTEGER * fileSize) = 0; 25 | 26 | /* 27 | Retrieve the file attribute. 28 | @attribs: a pointer a variable storing result. 29 | @return: HRESULT on success, or other value on failure. 30 | */ 31 | virtual HRESULT WINAPI Attributes(__out DWORD *attribs) = 0; 32 | 33 | /* 34 | Set file attribute. 35 | @attribs: file attribute. 36 | @return: HRESULT on success, or other value on failure. 37 | */ 38 | virtual HRESULT WINAPI SetAttributes(__in DWORD attribs) = 0; 39 | 40 | /* 41 | Retrieve the date and time that a file . 42 | 43 | @lpCreationTime: A pointer to a FILETIME structure to receive the date and time the file was created. 44 | @lpLastAccessTime: A pointer to a FILETIME structure to receive the date and time the file was last accessed. 45 | @lpLastWriteTime: A pointer to a FILETIME structure to receive the date and time the file was last written to, truncated, or overwritten. 46 | 47 | @return: HRESULT on success, or other value on failure. 48 | */ 49 | virtual HRESULT WINAPI Time(__out_opt FILETIME *lpCreationTime, __out_opt FILETIME *lpLastAccessTime, __out_opt FILETIME *lpLastWriteTime) = 0; 50 | 51 | /* 52 | Set the date and time that the specified file or directory was created, last accessed, or last modified. 53 | 54 | @lpCreationTime: A pointer to a FILETIME structure that contains the new creation date and time for the file. 55 | @lpLastAccessTime: A pointer to a FILETIME structure that contains the new last access date and time for the file. 56 | @lpLastWriteTime: A pointer to a FILETIME structure that contains the new last modified date and time for the file. 57 | 58 | @return: HRESULT on success, or other value on failure. 59 | */ 60 | virtual HRESULT WINAPI SetTime(__in_opt FILETIME *lpCreationTime, __in_opt FILETIME *lpLastAccessTime, __in_opt FILETIME *lpLastWriteTime) = 0; 61 | 62 | END_INTERFACE 63 | }; 64 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /TinyAvCore/Emulator/PeEmulator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #ifndef DYNLOAD 5 | #define DYNLOAD 6 | #endif 7 | 8 | // windows specific 9 | #ifdef _MSC_VER 10 | #include 11 | #include 12 | #define PRIx64 "llx" 13 | #ifdef DYNLOAD 14 | #include "unicorn_dynload.h" 15 | #else // DYNLOAD 16 | #include 17 | #ifdef _WIN64 18 | #pragma comment(lib, "unicorn_staload64.lib") 19 | #else // _WIN64 20 | #pragma comment(lib, "unicorn_staload.lib") 21 | #endif // _WIN64 22 | #endif // DYNLOAD 23 | 24 | // posix specific 25 | #else // _MSC_VER 26 | #include 27 | #include 28 | #include 29 | #endif // _MSC_VER 30 | #include 31 | 32 | class CPeEmulator 33 | : public CRefCount 34 | , public IEmulator 35 | { 36 | protected: 37 | bool m_starting; 38 | bool m_bEmulatorEngineReady; 39 | uc_engine * m_engine; 40 | std::vector m_Observers; 41 | 42 | private: 43 | HRESULT WINAPI OnStarting(void); 44 | void WINAPI OnError(__in DWORD const dwErrorCode); 45 | HRESULT WINAPI OnStopped(void); 46 | 47 | protected: 48 | virtual ~CPeEmulator(); 49 | 50 | public: 51 | CPeEmulator(); 52 | 53 | DECLARE_REF_COUNT(); 54 | 55 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) override; 56 | 57 | virtual HRESULT WINAPI ReadRegister(__in DWORD const reg, __out DWORD_PTR *regValue) override; 58 | 59 | virtual HRESULT WINAPI WriteRegister(__in DWORD const reg, __out DWORD_PTR const regValue) override; 60 | 61 | virtual HRESULT WINAPI ReadMemory(__in DWORD_PTR memoryAddr, __out_bcount(nNumberOfBytesToRead) LPVOID lpBuffer, __in DWORD nNumberOfBytesToRead) override; 62 | 63 | virtual HRESULT WINAPI WriteMemory(__in DWORD_PTR memoryAddr, __out_bcount(nNumberOfBytesToWrite) LPVOID lpBuffer, __in DWORD nNumberOfBytesToWrite) override; 64 | 65 | virtual HRESULT WINAPI EmulateCode(__in_bcount(nSizeOfCode) LPBYTE lpCodeBuffer, __in DWORD nSizeOfCode, 66 | __in DWORD_PTR memoryMappedAddr, __in DWORD nSizeOfStackCommit, __in DWORD nSizeOfStackReserve, 67 | __in DWORD_PTR addressToStart, __in DWORD nNumberOfBytesToEmulate) override; 68 | 69 | virtual HRESULT WINAPI EmulatePeFile(__in IPeFile *peFile, __in DWORD_PTR rvaToStart, __in int origin, __in DWORD nNumberOfBytesToEmulate = 0) override; 70 | 71 | virtual HRESULT WINAPI AddObserver(__in IEmulObserver *observer) override; 72 | 73 | virtual HRESULT WINAPI RemoveObserver(__in IEmulObserver *observer) override; 74 | 75 | virtual HRESULT __cdecl AddHook(__out void *hookHandle, __in int type, __in void * callback, __in void *user_data, ...) override; 76 | 77 | virtual HRESULT WINAPI RemoveHook(__in size_t hookHandle) override; 78 | 79 | virtual HRESULT WINAPI StopEmulator(void) override; 80 | 81 | }; -------------------------------------------------------------------------------- /include/Module/ModuleManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "Module.h" 4 | 5 | MIDL_INTERFACE("19D1F804-DDBC-41CC-922A-DE4B177D5482") 6 | IModuleManager : public IUnknown 7 | { 8 | public: 9 | BEGIN_INTERFACE 10 | 11 | /*Load plug-in modules by directory, name and flag 12 | @lpModuleDirectory: The directory to be used to load modules. 13 | If this parameter is NULL, current directory is used. 14 | @lpModuleName: module name. 15 | If this parameter is NULL, all modules are loaded. 16 | @flags: The action to be taken when loading the module. 17 | @return: HRESULT on success, or other value on failure. 18 | */ 19 | virtual HRESULT WINAPI Load(__in LPCWSTR lpModuleDirectory = NULL, __in LPCWSTR lpModuleName = NULL, __in DWORD flags = 0) = 0; 20 | 21 | /*Load plug-in modules by directory, type and flag 22 | @lpModuleDirectory: The directory to be used to load modules. 23 | If this parameter is NULL, current directory is used. 24 | @moduleType: module type. If this parameter is DefaultModuleType, all modules are loaded. 25 | @flags: The action to be taken when loading the module. 26 | @return: HRESULT on success, or other value on failure. 27 | */ 28 | virtual HRESULT WINAPI Load(__in LPCWSTR lpModuleDirectory = NULL, __in ModuleType moduleType = DefaultModuleType, __in DWORD flags = 0) = 0; 29 | /*Unload plug-in modules by directory, name and flag 30 | @lpModuleName: module name. If this parameter is NULL, all modules are unloaded. 31 | @return: HRESULT on success, or other value on failure. 32 | */ 33 | virtual HRESULT WINAPI Unload(__in LPCWSTR lpModuleName = NULL) = 0; 34 | /*Unload plug-in modules by directory, type and flag 35 | @moduleType: module type. If this parameter is DefaultModuleType, all modules are unloaded. 36 | @return: HRESULT on success, or other value on failure. 37 | */ 38 | virtual HRESULT WINAPI Unload(__in ModuleType moduleType = DefaultModuleType) = 0; 39 | 40 | /*Retrieve modules by their names 41 | @module: a pointer to a variable storing IModule* array 42 | @moduleCount: reference to number of module. 43 | @lpModuleName: module name. If this parameter is NULL, all modules are used. 44 | @return: HRESULT on success, or other value on failure. 45 | */ 46 | 47 | virtual HRESULT WINAPI QueryModule(__out IModule **&module, __out size_t& moduleCount, __in LPCWSTR lpModuleName = NULL) = 0; 48 | /*Retrieve modules by their types 49 | @module: a pointer to a variable storing IModule* array 50 | @moduleCount: reference to number of module. 51 | @moduleType: module type. If this parameter is DefaultModuleType, all modules are used. 52 | @return: HRESULT on success, or other value on failure. 53 | */ 54 | virtual HRESULT WINAPI QueryModule(__out IModule **&module, __out size_t& moduleCount, __in ModuleType moduleType = DefaultModuleType) = 0; 55 | END_INTERFACE 56 | }; 57 | -------------------------------------------------------------------------------- /include/FileSystem/FsEnumContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "FsObject.h" 4 | 5 | MIDL_INTERFACE("B417E769-E4A4-4D99-BF5D-3B3C2514394A") 6 | IFsEnumContext: public IUnknown 7 | { 8 | 9 | public: 10 | enum EnumContextFlags 11 | { 12 | DetectOnly = 1, 13 | Disinfect = 2 14 | }; 15 | 16 | BEGIN_INTERFACE 17 | 18 | /*Set search container 19 | @container: a pointer to IFsObject that describes search area. 20 | @return: HRESULT on success, or other value on failure. 21 | */ 22 | virtual HRESULT WINAPI SetSearchContainer(__in IVirtualFs * container) = 0; 23 | 24 | /*Retrieve search container 25 | @container: pointer to a variable storing result. 26 | @return: HRESULT on success, or other value on failure. 27 | */ 28 | virtual HRESULT WINAPI GetSearchContainer(__out IVirtualFs **container) = 0; 29 | 30 | /*Set search pattern 31 | @searchPattern: a pointer to a variable storing search pattern. 32 | @return: HRESULT on success, or other value on failure. 33 | */ 34 | virtual HRESULT WINAPI SetSearchPattern(__in LPCWSTR searchPattern) = 0; 35 | 36 | /*Retrieve search pattern 37 | @searchPattern: a pointer to a variable storing result. 38 | @return: HRESULT on success, or other value on failure. 39 | */ 40 | virtual HRESULT WINAPI GetSearchPattern(__out BSTR *searchPattern) = 0; 41 | 42 | // Set search depth 43 | virtual HRESULT WINAPI SetMaxDepth(__in const int maxDepth) = 0; 44 | virtual HRESULT WINAPI SetDepth(__in const int depth) = 0; 45 | virtual HRESULT WINAPI SetMaxDepthInArchive(__in const int maxDepth) = 0; 46 | virtual HRESULT WINAPI SetDepthInArchive(__in const int depth) = 0; 47 | 48 | // Retrieve max depth 49 | // @return: max depth 50 | virtual int WINAPI GetMaxDepth(void) = 0; 51 | 52 | // Retrieve depth 53 | // @return: current depth 54 | virtual int WINAPI GetDepth(void) = 0; 55 | 56 | // Retrieve max depth in archive 57 | // @return: max depth 58 | virtual int WINAPI GetMaxDepthInArchive(void) = 0; 59 | 60 | // Retrieve current depth in archive 61 | // @return: current depth 62 | virtual int WINAPI GetDepthInArchive(void) = 0; 63 | 64 | // set max file size 65 | // @fileSize: max file size 66 | // @return: HRESULT on success, or other value on failure. 67 | virtual HRESULT WINAPI SetMaxFileSize(__in ULARGE_INTEGER fileSize) = 0; 68 | 69 | // Retrieve max file size 70 | // @fileSize: a pointer to a variable storing result. 71 | // @return: HRESULT on success, or other value on failure. 72 | virtual HRESULT WINAPI GetMaxFileSize(__in ULARGE_INTEGER *fileSize) = 0; 73 | 74 | virtual HRESULT WINAPI SetFlags(__in const ULONG flags) = 0; 75 | virtual ULONG WINAPI GetFlags( void ) = 0; 76 | 77 | // #todo: must implement 78 | virtual HRESULT WINAPI AddIgnoreItem(__in LPCWSTR lpPath) = 0; 79 | virtual HRESULT WINAPI RemoveIgnoreItem(__in LPCWSTR lpPath) = 0; 80 | virtual HRESULT WINAPI GetIgnoreList(__out BSTR* lpPath, __out UINT *itemCount) = 0; 81 | virtual HRESULT WINAPI FreeIgnoreList(__in BSTR* lpPath, __in UINT itemCount) = 0; 82 | 83 | END_INTERFACE 84 | }; -------------------------------------------------------------------------------- /libs/include/unicorn/sparc.h: -------------------------------------------------------------------------------- 1 | #ifndef UNICORN_SPARC_H 2 | #define UNICORN_SPARC_H 3 | 4 | /* Unicorn Emulator Engine */ 5 | /* By Nguyen Anh Quynh , 2014-2015 */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include 12 | #include "platform.h" 13 | 14 | // GCC SPARC toolchain has a default macro called "sparc" which breaks 15 | // compilation 16 | #undef sparc 17 | 18 | #ifdef _MSC_VER 19 | #pragma warning(disable:4201) 20 | #endif 21 | 22 | //> SPARC registers 23 | typedef enum uc_sparc_reg { 24 | UC_SPARC_REG_INVALID = 0, 25 | 26 | UC_SPARC_REG_F0, 27 | UC_SPARC_REG_F1, 28 | UC_SPARC_REG_F2, 29 | UC_SPARC_REG_F3, 30 | UC_SPARC_REG_F4, 31 | UC_SPARC_REG_F5, 32 | UC_SPARC_REG_F6, 33 | UC_SPARC_REG_F7, 34 | UC_SPARC_REG_F8, 35 | UC_SPARC_REG_F9, 36 | UC_SPARC_REG_F10, 37 | UC_SPARC_REG_F11, 38 | UC_SPARC_REG_F12, 39 | UC_SPARC_REG_F13, 40 | UC_SPARC_REG_F14, 41 | UC_SPARC_REG_F15, 42 | UC_SPARC_REG_F16, 43 | UC_SPARC_REG_F17, 44 | UC_SPARC_REG_F18, 45 | UC_SPARC_REG_F19, 46 | UC_SPARC_REG_F20, 47 | UC_SPARC_REG_F21, 48 | UC_SPARC_REG_F22, 49 | UC_SPARC_REG_F23, 50 | UC_SPARC_REG_F24, 51 | UC_SPARC_REG_F25, 52 | UC_SPARC_REG_F26, 53 | UC_SPARC_REG_F27, 54 | UC_SPARC_REG_F28, 55 | UC_SPARC_REG_F29, 56 | UC_SPARC_REG_F30, 57 | UC_SPARC_REG_F31, 58 | UC_SPARC_REG_F32, 59 | UC_SPARC_REG_F34, 60 | UC_SPARC_REG_F36, 61 | UC_SPARC_REG_F38, 62 | UC_SPARC_REG_F40, 63 | UC_SPARC_REG_F42, 64 | UC_SPARC_REG_F44, 65 | UC_SPARC_REG_F46, 66 | UC_SPARC_REG_F48, 67 | UC_SPARC_REG_F50, 68 | UC_SPARC_REG_F52, 69 | UC_SPARC_REG_F54, 70 | UC_SPARC_REG_F56, 71 | UC_SPARC_REG_F58, 72 | UC_SPARC_REG_F60, 73 | UC_SPARC_REG_F62, 74 | UC_SPARC_REG_FCC0, // Floating condition codes 75 | UC_SPARC_REG_FCC1, 76 | UC_SPARC_REG_FCC2, 77 | UC_SPARC_REG_FCC3, 78 | UC_SPARC_REG_G0, 79 | UC_SPARC_REG_G1, 80 | UC_SPARC_REG_G2, 81 | UC_SPARC_REG_G3, 82 | UC_SPARC_REG_G4, 83 | UC_SPARC_REG_G5, 84 | UC_SPARC_REG_G6, 85 | UC_SPARC_REG_G7, 86 | UC_SPARC_REG_I0, 87 | UC_SPARC_REG_I1, 88 | UC_SPARC_REG_I2, 89 | UC_SPARC_REG_I3, 90 | UC_SPARC_REG_I4, 91 | UC_SPARC_REG_I5, 92 | UC_SPARC_REG_FP, 93 | UC_SPARC_REG_I7, 94 | UC_SPARC_REG_ICC, // Integer condition codes 95 | UC_SPARC_REG_L0, 96 | UC_SPARC_REG_L1, 97 | UC_SPARC_REG_L2, 98 | UC_SPARC_REG_L3, 99 | UC_SPARC_REG_L4, 100 | UC_SPARC_REG_L5, 101 | UC_SPARC_REG_L6, 102 | UC_SPARC_REG_L7, 103 | UC_SPARC_REG_O0, 104 | UC_SPARC_REG_O1, 105 | UC_SPARC_REG_O2, 106 | UC_SPARC_REG_O3, 107 | UC_SPARC_REG_O4, 108 | UC_SPARC_REG_O5, 109 | UC_SPARC_REG_SP, 110 | UC_SPARC_REG_O7, 111 | UC_SPARC_REG_Y, 112 | 113 | // special register 114 | UC_SPARC_REG_XCC, 115 | 116 | // pseudo register 117 | UC_SPARC_REG_PC, // program counter register 118 | 119 | UC_SPARC_REG_ENDING, // <-- mark the end of the list of registers 120 | 121 | // extras 122 | UC_SPARC_REG_O6 = UC_SPARC_REG_SP, 123 | UC_SPARC_REG_I6 = UC_SPARC_REG_FP, 124 | } uc_sparc_reg; 125 | 126 | #ifdef __cplusplus 127 | } 128 | #endif 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /TinyAvCore/Scanner/ScanService.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | class CScanService; 7 | 8 | typedef struct SCAN_THREAD_PARAM { 9 | HANDLE threadHandle; 10 | HANDLE stopEvent; 11 | IFsEnumContext *enumContext; 12 | IFsEnum * enumurate; 13 | CScanService * instance; 14 | }SCAN_THREAD_PARAM; 15 | 16 | typedef std::map SCAN_CONTEXT_MAP; 17 | 18 | class CScanService: 19 | public CRefCount, 20 | public IScanner, 21 | public IFsEnumObserver, 22 | public IScanObserver 23 | { 24 | protected: 25 | std::vector m_Observers; 26 | std::vector m_ScanModules; 27 | 28 | virtual ~CScanService(); 29 | 30 | public: 31 | CScanService(); 32 | 33 | DECLARE_REF_COUNT(); 34 | 35 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 36 | 37 | // IScanner interface implementation 38 | virtual HRESULT WINAPI AddScanObserver(__in IScanObserver *observer) override; 39 | 40 | virtual HRESULT WINAPI RemoveScanObserver(__in IScanObserver *observer) override; 41 | 42 | virtual HRESULT WINAPI AddScanModule(__in IScanModule *scanModule) override; 43 | 44 | virtual HRESULT WINAPI RemoveScanModule(__in IScanModule *scanModule) override; 45 | 46 | virtual HRESULT WINAPI Start(__in IFsEnumContext *enumContext) override; 47 | 48 | virtual HRESULT WINAPI Stop(__in IFsEnumContext *enumContext) override; 49 | 50 | virtual HRESULT WINAPI Pause(__in IFsEnumContext *enumContext) override; 51 | 52 | virtual HRESULT WINAPI Resume(__in IFsEnumContext *enumContext) override; 53 | 54 | // IFsEnumObserver interface implementation 55 | virtual HRESULT WINAPI OnFileFound(__in IVirtualFs *file, __in IFsEnumContext *context, __in const int currentDepth) override; 56 | 57 | // IScanObserver interface implementation 58 | virtual HRESULT WINAPI OnScanStarted(__in IFsEnumContext * context) override; 59 | 60 | 61 | virtual HRESULT WINAPI OnScanPaused(__in IFsEnumContext * context) override; 62 | 63 | 64 | virtual HRESULT WINAPI OnScanResumed(__in IFsEnumContext * context) override; 65 | 66 | 67 | virtual HRESULT WINAPI OnScanStopping(__in IFsEnumContext * context) override; 68 | 69 | 70 | virtual HRESULT WINAPI OnPreScan(__in IVirtualFs * file, __in IFsEnumContext * context) override; 71 | 72 | virtual HRESULT WINAPI OnAllScanFinished(__in IVirtualFs * file, __in IFsEnumContext * context) override; 73 | 74 | virtual HRESULT WINAPI OnPreClean(__in IVirtualFs * file, __in IFsEnumContext * context, __inout SCAN_RESULT * result) override; 75 | 76 | virtual HRESULT WINAPI OnPostClean(__in IVirtualFs * file, __in IFsEnumContext * context, __in SCAN_RESULT * result) override; 77 | 78 | virtual void WINAPI OnError(__in DWORD dwErrorCode, __in_opt LPCWSTR lpMessage = NULL) override; 79 | 80 | virtual void WINAPI Forever(void) override; 81 | 82 | 83 | private: 84 | static DWORD WINAPI ScanThread(__in LPVOID lpParam); 85 | public: 86 | static SCAN_CONTEXT_MAP m_ContextMap; 87 | protected: 88 | virtual void WINAPI OnScanThread(__in SCAN_THREAD_PARAM * param); 89 | virtual void WINAPI AddArchivers(__inout IFsEnum * enumurate); 90 | }; -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/zip/ZipFs.cpp: -------------------------------------------------------------------------------- 1 | #include "ZipFs.h" 2 | #include "../../Utils.h" 3 | #include "../BufferedStream.h" 4 | #include "ZipFsAttribute.h" 5 | 6 | CZipFs::CZipFs() 7 | { 8 | m_fsType = IVirtualFs::archive; 9 | ZeroMemory(&m_currentFilePos, sizeof(m_currentFilePos)); 10 | if (m_attribute)m_attribute->Release(); 11 | m_attribute = static_cast (new CZipFsAttribute()); 12 | if (m_stream)m_stream->Release(); 13 | m_stream = static_cast (new CBufferedStream()); 14 | m_delimiter = StringW(L">"); 15 | } 16 | 17 | CZipFs::~CZipFs() 18 | { 19 | Close(); 20 | } 21 | 22 | HRESULT WINAPI CZipFs::Create(__in LPCWSTR lpFileName, __in ULONG const flags) 23 | { 24 | if (m_container == NULL) 25 | return E_NOT_SET; 26 | m_FileName = lpFileName; 27 | m_flags = flags; 28 | 29 | if (m_attribute == NULL) 30 | { 31 | Close(); 32 | return E_OUTOFMEMORY; 33 | } 34 | m_attribute->SetFilePath(m_FileName.c_str()); 35 | return S_OK; 36 | } 37 | 38 | HRESULT WINAPI CZipFs::Close(void) 39 | { 40 | HRESULT hr = S_OK; 41 | if (m_handle != INVALID_HANDLE_VALUE && m_handle != NULL) 42 | { 43 | hr = (unzCloseCurrentFile((void*)m_handle) == UNZ_OK) ? S_OK : E_FAIL; 44 | 45 | if (SUCCEEDED(hr)) 46 | { 47 | if (UNZ_OK != unzGoToFilePos64((void*)m_handle, &m_currentFilePos)) 48 | hr = E_UNEXPECTED; 49 | } 50 | } 51 | 52 | m_handle = INVALID_HANDLE_VALUE; 53 | m_stream->SetFileHandle(m_handle); 54 | return hr; 55 | } 56 | 57 | HRESULT WINAPI CZipFs::ReCreate(__in_opt void* handle, __in_opt ULONG const flags /*= 0*/) 58 | { 59 | if (flags) 60 | m_flags = flags; 61 | 62 | if ((HANDLE)handle == m_handle) 63 | return S_OK; 64 | 65 | m_handle = (HANDLE)handle; 66 | 67 | StringA strNameA = UnicodeToAnsi(m_FileName); 68 | 69 | if (UNZ_OK != unzGetFilePos64((unzFile)m_handle, &m_currentFilePos)) 70 | return E_NOT_SET; 71 | 72 | if (unzLocateFile((unzFile)m_handle, strNameA.c_str(), 0) != UNZ_OK) 73 | return E_FAIL; 74 | 75 | HRESULT hr = (unzOpenCurrentFile((unzFile)m_handle) == UNZ_OK) ? S_OK : E_FAIL; 76 | if (FAILED(hr)) 77 | { 78 | m_handle = INVALID_HANDLE_VALUE; 79 | return hr; 80 | } 81 | 82 | if (m_stream) 83 | { 84 | m_stream->Release(); 85 | m_stream = NULL; 86 | } 87 | m_stream = new CBufferedStream(); 88 | if (m_stream == NULL) 89 | { 90 | Close(); 91 | return E_OUTOFMEMORY; 92 | } 93 | 94 | int err = 0; 95 | unsigned char *pTemp = new unsigned char[WRITEBUFFERSIZE]; 96 | if (pTemp) 97 | { 98 | do 99 | { 100 | err = unzReadCurrentFile((unzFile)m_handle, pTemp, WRITEBUFFERSIZE); 101 | if (err < 0) 102 | { 103 | break; 104 | } 105 | if (err > 0) 106 | { 107 | ULONG writtenSize; 108 | if (FAILED(m_stream->Write(pTemp, (ULONG)err, &writtenSize))) 109 | break; 110 | if (writtenSize == 0) 111 | break; 112 | } 113 | } while (err > 0); 114 | delete[] pTemp; 115 | } 116 | 117 | // goto the beginning of file 118 | ULARGE_INTEGER pos = {}; 119 | LARGE_INTEGER distanceToMove = {}; 120 | m_stream->Seek(&pos, distanceToMove, IFsStream::FsStreamBegin); 121 | m_attribute->SetFilePath(m_FileName.c_str(), handle); 122 | return S_OK; 123 | } 124 | -------------------------------------------------------------------------------- /TinyAvCore/Utils.cpp: -------------------------------------------------------------------------------- 1 | #include "Utils.h" 2 | #include 3 | #include "TinyAvCore.h" 4 | #include "Module\ModuleMgrService.h" 5 | #include "Emulator\PeEmulator.h" 6 | #include "FileType\PeFileParser.h" 7 | #include "Scanner\ScanService.h" 8 | #include "FileSystem\FileFsEnumContext.h" 9 | #include "FileSystem\FileFs.h" 10 | 11 | StringW AnsiToUnicode(__in StringA * str) 12 | { 13 | if (str == NULL) return L""; 14 | 15 | int nRequired = MultiByteToWideChar(CP_UTF8, 0, str->c_str(), (int)str->length(), NULL, 0); 16 | if (nRequired == 0) return L""; 17 | 18 | WCHAR * lpWideChar = new WCHAR[nRequired + 1]; 19 | if (lpWideChar == NULL) return L""; 20 | nRequired = MultiByteToWideChar(CP_UTF8, 0, str->c_str(), (int)str->length(), lpWideChar, nRequired); 21 | if (nRequired == 0) return L""; 22 | lpWideChar[nRequired] = L'\0'; 23 | StringW wstr = lpWideChar; 24 | delete[]lpWideChar; 25 | return wstr; 26 | } 27 | 28 | StringW AnsiToUnicode(__in StringA& str) 29 | { 30 | return AnsiToUnicode(&str); 31 | } 32 | 33 | StringA UnicodeToAnsi(__in StringW * str) 34 | { 35 | if (str == NULL) return ""; 36 | 37 | int nRequired = WideCharToMultiByte(CP_UTF8, 0, str->c_str(), (int)str->length(), NULL, 0, NULL, NULL); 38 | if (nRequired == 0) return ""; 39 | 40 | CHAR * lpWideChar = new CHAR[nRequired + 1]; 41 | if (lpWideChar == NULL) return ""; 42 | nRequired = WideCharToMultiByte(CP_UTF8, 0, str->c_str(), (int)str->length(), lpWideChar, nRequired, NULL, NULL); 43 | if (nRequired == 0) return ""; 44 | lpWideChar[nRequired] = '\0'; 45 | StringA wstr = lpWideChar; 46 | delete[]lpWideChar; 47 | return wstr; 48 | } 49 | 50 | StringA UnicodeToAnsi(__in StringW& str) 51 | { 52 | return UnicodeToAnsi(&str); 53 | } 54 | 55 | HRESULT WINAPI CreateClassObject(__in REFCLSID rclsid, __in DWORD dwClsContext, __in REFIID riid, __out LPVOID *ppv) 56 | { 57 | UNREFERENCED_PARAMETER(dwClsContext); 58 | 59 | if (ppv == NULL) return E_INVALIDARG; 60 | 61 | if (IsEqualCLSID(rclsid, CLSID_CModuleMgrService) || 62 | IsEqualIID(riid, __uuidof(IModuleManager))) 63 | { 64 | *ppv = static_cast(new CModuleMgrService()); 65 | return S_OK; 66 | } 67 | 68 | else if (IsEqualCLSID(rclsid, CLSID_CPeEmulator) || 69 | IsEqualIID(riid, __uuidof(IEmulator))) 70 | { 71 | *ppv = static_cast(new CPeEmulator()); 72 | return S_OK; 73 | } 74 | 75 | else if (IsEqualCLSID(rclsid, CLSID_CPeFileParser) || 76 | IsEqualIID(riid, __uuidof(IPeFile))) 77 | { 78 | *ppv = static_cast(new CPeFileParser()); 79 | return S_OK; 80 | } 81 | 82 | else if (IsEqualCLSID(rclsid, CLSID_CScanService) || 83 | IsEqualIID(riid, __uuidof(IScanner))) 84 | { 85 | *ppv = static_cast(new CScanService()); 86 | return S_OK; 87 | } 88 | 89 | else if (IsEqualCLSID(rclsid, CLSID_CFileFsEnumContext) && 90 | IsEqualIID(riid, __uuidof(IFsEnumContext))) 91 | { 92 | *ppv = static_cast(new CFileFsEnumContext()); 93 | return S_OK; 94 | } 95 | 96 | else if (IsEqualCLSID(rclsid, CLSID_CFileFs) && 97 | IsEqualIID(riid, __uuidof(IVirtualFs))) 98 | { 99 | *ppv = static_cast(new CFileFs()); 100 | return S_OK; 101 | } 102 | 103 | return E_NOINTERFACE; 104 | } -------------------------------------------------------------------------------- /libs/include/unicorn/arm.h: -------------------------------------------------------------------------------- 1 | #ifndef UNICORN_ARM_H 2 | #define UNICORN_ARM_H 3 | 4 | /* Unicorn Engine */ 5 | /* By Nguyen Anh Quynh , 2015 */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef _MSC_VER 12 | #pragma warning(disable:4201) 13 | #endif 14 | 15 | //> ARM registers 16 | typedef enum uc_arm_reg { 17 | UC_ARM_REG_INVALID = 0, 18 | UC_ARM_REG_APSR, 19 | UC_ARM_REG_APSR_NZCV, 20 | UC_ARM_REG_CPSR, 21 | UC_ARM_REG_FPEXC, 22 | UC_ARM_REG_FPINST, 23 | UC_ARM_REG_FPSCR, 24 | UC_ARM_REG_FPSCR_NZCV, 25 | UC_ARM_REG_FPSID, 26 | UC_ARM_REG_ITSTATE, 27 | UC_ARM_REG_LR, 28 | UC_ARM_REG_PC, 29 | UC_ARM_REG_SP, 30 | UC_ARM_REG_SPSR, 31 | UC_ARM_REG_D0, 32 | UC_ARM_REG_D1, 33 | UC_ARM_REG_D2, 34 | UC_ARM_REG_D3, 35 | UC_ARM_REG_D4, 36 | UC_ARM_REG_D5, 37 | UC_ARM_REG_D6, 38 | UC_ARM_REG_D7, 39 | UC_ARM_REG_D8, 40 | UC_ARM_REG_D9, 41 | UC_ARM_REG_D10, 42 | UC_ARM_REG_D11, 43 | UC_ARM_REG_D12, 44 | UC_ARM_REG_D13, 45 | UC_ARM_REG_D14, 46 | UC_ARM_REG_D15, 47 | UC_ARM_REG_D16, 48 | UC_ARM_REG_D17, 49 | UC_ARM_REG_D18, 50 | UC_ARM_REG_D19, 51 | UC_ARM_REG_D20, 52 | UC_ARM_REG_D21, 53 | UC_ARM_REG_D22, 54 | UC_ARM_REG_D23, 55 | UC_ARM_REG_D24, 56 | UC_ARM_REG_D25, 57 | UC_ARM_REG_D26, 58 | UC_ARM_REG_D27, 59 | UC_ARM_REG_D28, 60 | UC_ARM_REG_D29, 61 | UC_ARM_REG_D30, 62 | UC_ARM_REG_D31, 63 | UC_ARM_REG_FPINST2, 64 | UC_ARM_REG_MVFR0, 65 | UC_ARM_REG_MVFR1, 66 | UC_ARM_REG_MVFR2, 67 | UC_ARM_REG_Q0, 68 | UC_ARM_REG_Q1, 69 | UC_ARM_REG_Q2, 70 | UC_ARM_REG_Q3, 71 | UC_ARM_REG_Q4, 72 | UC_ARM_REG_Q5, 73 | UC_ARM_REG_Q6, 74 | UC_ARM_REG_Q7, 75 | UC_ARM_REG_Q8, 76 | UC_ARM_REG_Q9, 77 | UC_ARM_REG_Q10, 78 | UC_ARM_REG_Q11, 79 | UC_ARM_REG_Q12, 80 | UC_ARM_REG_Q13, 81 | UC_ARM_REG_Q14, 82 | UC_ARM_REG_Q15, 83 | UC_ARM_REG_R0, 84 | UC_ARM_REG_R1, 85 | UC_ARM_REG_R2, 86 | UC_ARM_REG_R3, 87 | UC_ARM_REG_R4, 88 | UC_ARM_REG_R5, 89 | UC_ARM_REG_R6, 90 | UC_ARM_REG_R7, 91 | UC_ARM_REG_R8, 92 | UC_ARM_REG_R9, 93 | UC_ARM_REG_R10, 94 | UC_ARM_REG_R11, 95 | UC_ARM_REG_R12, 96 | UC_ARM_REG_S0, 97 | UC_ARM_REG_S1, 98 | UC_ARM_REG_S2, 99 | UC_ARM_REG_S3, 100 | UC_ARM_REG_S4, 101 | UC_ARM_REG_S5, 102 | UC_ARM_REG_S6, 103 | UC_ARM_REG_S7, 104 | UC_ARM_REG_S8, 105 | UC_ARM_REG_S9, 106 | UC_ARM_REG_S10, 107 | UC_ARM_REG_S11, 108 | UC_ARM_REG_S12, 109 | UC_ARM_REG_S13, 110 | UC_ARM_REG_S14, 111 | UC_ARM_REG_S15, 112 | UC_ARM_REG_S16, 113 | UC_ARM_REG_S17, 114 | UC_ARM_REG_S18, 115 | UC_ARM_REG_S19, 116 | UC_ARM_REG_S20, 117 | UC_ARM_REG_S21, 118 | UC_ARM_REG_S22, 119 | UC_ARM_REG_S23, 120 | UC_ARM_REG_S24, 121 | UC_ARM_REG_S25, 122 | UC_ARM_REG_S26, 123 | UC_ARM_REG_S27, 124 | UC_ARM_REG_S28, 125 | UC_ARM_REG_S29, 126 | UC_ARM_REG_S30, 127 | UC_ARM_REG_S31, 128 | 129 | UC_ARM_REG_ENDING, // <-- mark the end of the list or registers 130 | 131 | //> alias registers 132 | UC_ARM_REG_R13 = UC_ARM_REG_SP, 133 | UC_ARM_REG_R14 = UC_ARM_REG_LR, 134 | UC_ARM_REG_R15 = UC_ARM_REG_PC, 135 | 136 | UC_ARM_REG_SB = UC_ARM_REG_R9, 137 | UC_ARM_REG_SL = UC_ARM_REG_R10, 138 | UC_ARM_REG_FP = UC_ARM_REG_R11, 139 | UC_ARM_REG_IP = UC_ARM_REG_R12, 140 | } uc_arm_reg; 141 | 142 | #ifdef __cplusplus 143 | } 144 | #endif 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /tests/Unittests/FileFsEnum_unittest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../TinyAvCore/FileSystem/FileFsEnumContext.h" 5 | #include "../TinyAvCore/FileSystem/FileFsEnum.h" 6 | #include "../TinyAvCore/FileSystem/FileFs.h" 7 | #include "../TinyAvCore/FileSystem/zip/ZipFsEnum.h" 8 | 9 | extern WCHAR szSampleDir[MAX_PATH]; 10 | 11 | class CTestEnumObserver 12 | : public CRefCount 13 | , public IFsEnumObserver 14 | { 15 | private: 16 | UINT m_Count; 17 | public: 18 | CTestEnumObserver() : m_Count(0) {} 19 | virtual ~CTestEnumObserver() {} 20 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __in void **ppvObject) 21 | { 22 | if (ppvObject == NULL) return E_INVALIDARG; 23 | if (IsEqualIID(riid, IID_IUnknown) || 24 | IsEqualIID(riid, __uuidof(IFsEnumObserver)) 25 | ) 26 | { 27 | *ppvObject = static_cast(this); 28 | AddRef(); 29 | return S_OK; 30 | } 31 | else 32 | { 33 | *ppvObject = NULL; 34 | } 35 | return E_NOINTERFACE; 36 | } 37 | DECLARE_REF_COUNT(); 38 | 39 | UINT GetFileCount(void) 40 | { 41 | return m_Count; 42 | } 43 | 44 | virtual HRESULT WINAPI OnFileFound(__in IVirtualFs *file, __in IFsEnumContext *context, __in const int currentDepth) override 45 | { 46 | BSTR lpFileName = NULL; 47 | 48 | m_Count++; 49 | 50 | if (SUCCEEDED(file->GetFullPath(&lpFileName))) 51 | { 52 | wprintf(L"(%d) %s", currentDepth, lpFileName); 53 | SysFreeString(lpFileName); 54 | } 55 | 56 | printf("\n"); 57 | 58 | file->GetFileName(&lpFileName); 59 | SysFreeString(lpFileName); 60 | file->GetFileExt(&lpFileName); 61 | SysFreeString(lpFileName); 62 | return S_OK; 63 | } 64 | 65 | virtual void WINAPI OnError(__in DWORD dwErrorCode, __in_opt LPCWSTR lpMessage = NULL) override 66 | { 67 | UNREFERENCED_PARAMETER(dwErrorCode); 68 | UNREFERENCED_PARAMETER(lpMessage); 69 | } 70 | }; 71 | 72 | TEST(FileFsEnum, All) 73 | { 74 | IFsEnum * enumObj = static_cast(new CFileFsEnum); 75 | IFsEnumContext * enumContext = static_cast(new CFileFsEnumContext); 76 | CTestEnumObserver * testObj = new CTestEnumObserver(); 77 | IFsEnum * zip = new CZipFsEnum; 78 | IVirtualFs * container = static_cast(new CFileFs); 79 | 80 | if (!enumObj || !enumContext || !testObj || !zip || !container) 81 | goto EXIT; 82 | 83 | ASSERT_HRESULT_SUCCEEDED(enumContext->SetMaxDepth(-1)); 84 | ASSERT_HRESULT_SUCCEEDED(enumContext->SetSearchPattern(L"*.*")); 85 | ASSERT_HRESULT_SUCCEEDED(container->Create(szSampleDir, 0)); 86 | ASSERT_HRESULT_SUCCEEDED(enumContext->SetSearchContainer(container)); 87 | ASSERT_HRESULT_SUCCEEDED(enumContext->SetFlags(IFsEnumContext::DetectOnly)); 88 | ASSERT_HRESULT_SUCCEEDED(enumObj->AddObserver(testObj)); 89 | ASSERT_HRESULT_SUCCEEDED(enumObj->AddArchiver(zip)); 90 | ASSERT_HRESULT_SUCCEEDED(enumObj->Enum(enumContext)); 91 | ASSERT_EQ(6, testObj->GetFileCount()); 92 | printf("\n\n Count = %d\n", testObj->GetFileCount()); 93 | ASSERT_HRESULT_SUCCEEDED(enumObj->RemoveArchiver(zip)); 94 | ASSERT_HRESULT_SUCCEEDED(enumObj->RemoveObserver(testObj)); 95 | 96 | EXIT: 97 | if (testObj) testObj->Release(); 98 | if (container) container->Release(); 99 | if (zip) zip->Release(); 100 | if (enumContext) enumContext->Release(); 101 | if (enumObj) enumObj->Release(); 102 | } -------------------------------------------------------------------------------- /TinyAvCore/FileType/PeFileParser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class CPeFileParser: 5 | public CRefCount, 6 | public IPeFile 7 | { 8 | private: 9 | DWORD m_lfanew; 10 | protected: 11 | 12 | IMAGE_DOS_HEADER m_dosHeader; 13 | IMAGE_NT_HEADERS32 m_peHeader; 14 | UINT m_SectionCount; 15 | UINT m_OriginalSectionCount; 16 | IMAGE_SECTION_HEADER *m_SectionTable; 17 | BOOL m_typeMatched; 18 | IVirtualFs * m_file; 19 | IFsStream *m_stream; 20 | virtual ~CPeFileParser(); 21 | 22 | public: 23 | CPeFileParser(); 24 | 25 | DECLARE_REF_COUNT(); 26 | 27 | virtual HRESULT WINAPI QueryInterface(__in REFIID riid, __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject); 28 | 29 | virtual HRESULT WINAPI GetDosHeader(__out_bcount(sizeof(IMAGE_DOS_HEADER)) IMAGE_DOS_HEADER *dosHeader) override; 30 | 31 | virtual HRESULT WINAPI GetPEHeader(__out_bcount(sizeof(IMAGE_NT_HEADERS32)) IMAGE_NT_HEADERS32 *peHeader) override; 32 | 33 | virtual HRESULT WINAPI GetSectionHeader(__in UINT sectionIndex, __out_bcount(IMAGE_SIZEOF_SECTION_HEADER) IMAGE_SECTION_HEADER *sectionHeader) override; 34 | 35 | virtual UINT WINAPI GetSectionCount(void) override; 36 | 37 | virtual HRESULT WINAPI RvaToFileOffset(__in UINT rva, __out UINT *fileOffset) override; 38 | 39 | virtual HRESULT WINAPI VaToFileOffset(__in UINT va, __out UINT *fileOffset) override; 40 | 41 | virtual HRESULT WINAPI FileOffsetToRva(__in UINT fileOffset, __out UINT *rva) override; 42 | 43 | virtual HRESULT WINAPI FileOffsetToVa(__in UINT fileOffset, __out UINT *va) override; 44 | 45 | virtual HRESULT WINAPI ReadSectionData(__in UINT sectionIndex, __out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) override; 46 | 47 | virtual HRESULT WINAPI ReadEPSectionData(__out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) override; 48 | 49 | virtual HRESULT WINAPI FindSectionByRva(__in UINT rva, __out UINT *sectionIndex) override; 50 | 51 | virtual HRESULT WINAPI FindSectionByVa(__in UINT va, __out UINT *sectionIndex) override; 52 | 53 | virtual HRESULT WINAPI FindSectionByFileOffset(__in UINT fileOffset, __out UINT *sectionIndex) override; 54 | 55 | virtual HRESULT WINAPI ReadEntryPointData(__out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) override; 56 | 57 | virtual HRESULT WINAPI SetVaToEntryPoint(__in UINT va) override; 58 | 59 | virtual HRESULT WINAPI SetRvaToEntryPoint(__in UINT rva) override; 60 | 61 | virtual HRESULT WINAPI TruncateSectionUntilEndOfFile(__in UINT sectionIndex) override; 62 | 63 | // Check for type matching 64 | virtual HRESULT WINAPI CheckType(__in IVirtualFs* fsFile, __out BOOL *typeMatched) override; 65 | 66 | virtual void WINAPI ReleaseCurrentFile(void) override; 67 | 68 | virtual HRESULT WINAPI Truncate(__in UINT va, __in_opt BOOL padding = FALSE) override; 69 | 70 | // 71 | 72 | private: 73 | // ----------------------------- 74 | // Internal methods 75 | // ----------------------------- 76 | 77 | // Parse the PE header 78 | bool ParsePEHeader(__in IVirtualFs* fsFile); 79 | 80 | // check PE header for malformed header 81 | bool ValidatePeHeader(__in IFsStream *fsStream); 82 | 83 | // Initialize the section table 84 | bool InitSectionTable(__in IFsStream *fsStream); 85 | // Parse the section table 86 | bool ParseSectionTable(__in const BYTE *sectionData, __in ULONG maxSectionCount); 87 | 88 | protected: 89 | HRESULT FlushPeHeader(void); 90 | 91 | public: 92 | static DWORD SectionAlign(__in DWORD n, __in DWORD a); 93 | static DWORD FileAlign(__in DWORD n, __in DWORD a); 94 | }; 95 | 96 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/zip/ZipFsEnum.cpp: -------------------------------------------------------------------------------- 1 | #include "ZipFsEnum.h" 2 | #include "UnzipHelper.h" 3 | #include "../../Utils.h" 4 | #include "ZipFs.h" 5 | 6 | CZipFsEnum::CZipFsEnum(void) 7 | { 8 | } 9 | 10 | CZipFsEnum::~CZipFsEnum(void) 11 | { 12 | } 13 | 14 | HRESULT WINAPI CZipFsEnum::Enum(__in IFsEnumContext *context) 15 | { 16 | HRESULT hr; 17 | zlib_filefunc64_def ffunc; 18 | BSTR lpFileName = NULL; 19 | IVirtualFs * container = NULL; 20 | 21 | if (context == NULL) return E_INVALIDARG; 22 | 23 | hr = context->GetSearchContainer(&container); 24 | if (FAILED(hr)) return hr; 25 | 26 | FillFunctions64((voidpf)container, &ffunc); 27 | hr = container->GetFullPath(&lpFileName); 28 | if (FAILED(hr)) 29 | { 30 | container->Release(); 31 | return hr; 32 | } 33 | 34 | unzFile uf = NULL; 35 | uf = unzOpen2_64(lpFileName, &ffunc); 36 | SysFreeString(lpFileName); 37 | 38 | if (uf == NULL) 39 | { 40 | container->Release(); 41 | return E_FAIL; 42 | } 43 | 44 | hr = ReadArchiver(container, context, uf); 45 | 46 | unzClose(uf); 47 | container->Release(); 48 | return hr; 49 | } 50 | 51 | HRESULT WINAPI CZipFsEnum::ReadArchiver(__in_opt IVirtualFs * container, __in IFsEnumContext * context, __in void * stream) 52 | { 53 | char filename_inzip[256] = {}; 54 | unz_file_info64 file_info; 55 | unz_global_info64 gi; 56 | int err; 57 | bool stopSearch = false; 58 | ULARGE_INTEGER maxFileSize; 59 | if (container == NULL || stream == NULL) return E_INVALIDARG; 60 | HRESULT hr = context->GetMaxFileSize(&maxFileSize); 61 | if (FAILED(hr)) return hr; 62 | 63 | unzFile uf = (unzFile)stream; 64 | 65 | err = unzGetGlobalInfo64(uf, &gi); 66 | if (err != UNZ_OK) return E_UNEXPECTED; 67 | 68 | for (ZPOS64_T i = 0; (i < gi.number_entry) && (!stopSearch); i++) 69 | { 70 | err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); 71 | if (err != UNZ_OK) break; 72 | 73 | if (file_info.uncompressed_size > (ZPOS64_T)maxFileSize.QuadPart) // skip big-file 74 | continue; 75 | 76 | StringA strName = filename_inzip; 77 | StringW wstrName = AnsiToUnicode(&strName); 78 | 79 | IVirtualFs * zipFile = static_cast(new CZipFs()); 80 | if (zipFile) 81 | { 82 | if (SUCCEEDED(zipFile->SetContainer(container)) && 83 | SUCCEEDED(zipFile->Create(wstrName.c_str(), 0)) && 84 | SUCCEEDED(zipFile->ReCreate((void*)uf))) 85 | { 86 | IFsAttribute * fsAttrib = NULL; 87 | if (SUCCEEDED(zipFile->QueryInterface(__uuidof(IFsAttribute), (LPVOID*)&fsAttrib))) 88 | { 89 | DWORD dwAttrib; 90 | 91 | if (SUCCEEDED(fsAttrib->Attributes(&dwAttrib)) && 92 | (TEST_FLAG(dwAttrib, FILE_ATTRIBUTE_DIRECTORY) == 0)) 93 | { 94 | int currentDepthInArchive = context->GetDepthInArchive(); 95 | context->SetDepthInArchive(currentDepthInArchive + 1); 96 | hr = OnFileFound(zipFile, context, context->GetDepth() + 1); 97 | if (hr == E_ABORT) 98 | { 99 | stopSearch = true; 100 | } 101 | context->SetDepthInArchive(currentDepthInArchive); 102 | } 103 | 104 | fsAttrib->Release(); 105 | } 106 | } 107 | 108 | ULONG flags; 109 | if (SUCCEEDED(zipFile->GetFlags(&flags)) && 110 | TEST_FLAG(flags, IVirtualFs::fsDeferredDeletion)) 111 | { 112 | container->DeferredDelete(); 113 | stopSearch = true; 114 | } 115 | 116 | zipFile->Close(); 117 | zipFile->Release(); 118 | } 119 | 120 | err = unzGoToNextFile(uf); 121 | if (err != UNZ_OK) break; 122 | } 123 | 124 | return S_OK; 125 | } 126 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TinyAntivirus 2 | ============== 3 | 4 | [![Build status](https://ci.appveyor.com/api/projects/status/github/develbranch/TinyAntivirus?branch=master&svg=true)](https://ci.appveyor.com/project/quangnh89/TinyAntivirus/branch/master) 5 | [![License](https://img.shields.io/badge/license-gpl2-blue.svg)](LICENSE) 6 | ![Platform](https://img.shields.io/badge/platform-windows-lightgrey.svg) 7 | 8 | **TinyAntivirus (TinyAv)** is an open source antivirus engine designed for detecting polymorphic virus and disinfecting it. Now, TinyAv can detect and disinfect Sality polymorphic virus. In the future, I will deveplop some modules for removing other polymorphic viruses, such as Virut or Polip. 9 | 10 | ## License 11 | 12 | This project is released under the [GPL2](COPYING) [license](LICENSE). 13 | 14 | ## Requirements 15 | 16 | * Microsoft Visual Studio 2015 17 | * [zlib 1.2.8](http://www.zlib.net) or newer 18 | * [unicorn-engine 0.9](http://www.unicorn-engine.org/) 19 | 20 | ## Quick start 21 | 22 | * Clone the repository: `git clone https://github.com/develbranch/TinyAntivirus.git`. 23 | * Build: Core engine, Console and scan module. 24 | * You can see `Release` Directory. Change the `Release` directory and run `TinyAvConsole.exe`. 25 | 26 | ## Usage 27 | 28 | ``` 29 | TinyAvConsole.exe [options] 30 | 31 | ``` 32 | | Option | Meaning | Default value | 33 | |----------|-------------|:------:| 34 | | -e | plug-in directory | current directory | 35 | | -A | Archive scan depth | -1 : any depth| 36 | | -D | scan depth | -1 : any depth | 37 | | -d | path to scan | | 38 | | -p | file pattern | \*.\* | 39 | | -s | max file size in bytes| 10 \* 1024 \* 1024 (10 MB) | 40 | | -m | Scan mode: Kill-virus (k) or Scan-only(s) | Kill-virus (k) | 41 | | -h | Show usage || 42 | 43 | You may scan all directories and files by using default values. 44 | 45 | **Example:** Scan for all files (include ZIP files) to detect and disinfect virus. 46 | ZIP files which contain virus will be deleted. 47 | ``` 48 | C:\build>TinyAvConsole.exe -d C:\sample 49 | ------------------------------------------------------ 50 | TinyAntivirus version 0.1 51 | Copyright (C) 2016, Quang Nguyen. All rights reserved. 52 | Website: http://develbranch.com 53 | ------------------------------------------------------ 54 | Scanning ... 55 | C:\sample\calc.EXE 56 | W32.Sality.PE Disinfected 57 | C:\sample\container.zip OK 58 | C:\sample\container.zip>DiskView.exe OK 59 | C:\sample\container.zip>DMON.SYS OK 60 | C:\sample\container.zip>sub_container.zip OK 61 | C:\sample\container.zip>sub_container.zip>NOTEPAD.EXE 62 | W32.Sality.PE Deleted 63 | C:\sample\dbgview.chm OK 64 | C:\sample\sub\gmer.EXE 65 | W32.Sality.PE Disinfected 66 | 67 | ============================================= 68 | Scanned : 4 file(s) (10 object(s)) 69 | Detected : 3 file(s) 70 | Removed : 3 file(s) 71 | Access denied : 0 file(s) 72 | 73 | C:\build> 74 | ``` 75 | 76 | ## Contribute 77 | 78 | If you want to contribute, please pick up something from our [Github issues](https://github.com/develbranch/TinyAntivirus/issues). 79 | 80 | I also maintain a list of more problems in a [TODO list](https://github.com/develbranch/TinyAntivirus/wiki/TODO). 81 | 82 | I have only one Sality sample to develop Sality killer module. I think there are many variant types of this file infector. Please send me samples which TinyAv can not detect or other kinds of polymorphic viruses. Thank you. 83 | 84 | ## Author 85 | 86 | [Quang Nguyễn](https://github.com/quangnh89) 87 | 88 | Blog: [develbranch.com](https://develbranch.com) 89 | -------------------------------------------------------------------------------- /TinyAntivirus.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TinyAvCore", "TinyAvCore\TinyAvCore.vcxproj", "{6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TinyAvConsole", "TinyAvConsole\TinyAvConsole.vcxproj", "{63FACD86-7D04-4F8F-BC85-FECB879E8389}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3} = {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3} 11 | EndProjectSection 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SalityKiller", "SalityKiller\SalityKiller.vcxproj", "{29F78C28-341C-4D6F-BE65-2CD559672A56}" 14 | ProjectSection(ProjectDependencies) = postProject 15 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3} = {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3} 16 | EndProjectSection 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Unittests", "tests\Unittests\Unittests.vcxproj", "{39BBD212-79B1-4527-8D62-194A6A8428A8}" 19 | ProjectSection(ProjectDependencies) = postProject 20 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3} = {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3} 21 | EndProjectSection 22 | EndProject 23 | Global 24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 25 | Debug|x64 = Debug|x64 26 | Debug|x86 = Debug|x86 27 | Release|x64 = Release|x64 28 | Release|x86 = Release|x86 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}.Debug|x64.ActiveCfg = Debug|x64 32 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}.Debug|x64.Build.0 = Debug|x64 33 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}.Debug|x86.ActiveCfg = Debug|Win32 34 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}.Debug|x86.Build.0 = Debug|Win32 35 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}.Release|x64.ActiveCfg = Release|x64 36 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}.Release|x64.Build.0 = Release|x64 37 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}.Release|x86.ActiveCfg = Release|Win32 38 | {6A881F9E-4BC9-4F5B-A5DD-20626F66F5E3}.Release|x86.Build.0 = Release|Win32 39 | {63FACD86-7D04-4F8F-BC85-FECB879E8389}.Debug|x64.ActiveCfg = Debug|x64 40 | {63FACD86-7D04-4F8F-BC85-FECB879E8389}.Debug|x64.Build.0 = Debug|x64 41 | {63FACD86-7D04-4F8F-BC85-FECB879E8389}.Debug|x86.ActiveCfg = Debug|Win32 42 | {63FACD86-7D04-4F8F-BC85-FECB879E8389}.Debug|x86.Build.0 = Debug|Win32 43 | {63FACD86-7D04-4F8F-BC85-FECB879E8389}.Release|x64.ActiveCfg = Release|x64 44 | {63FACD86-7D04-4F8F-BC85-FECB879E8389}.Release|x64.Build.0 = Release|x64 45 | {63FACD86-7D04-4F8F-BC85-FECB879E8389}.Release|x86.ActiveCfg = Release|Win32 46 | {63FACD86-7D04-4F8F-BC85-FECB879E8389}.Release|x86.Build.0 = Release|Win32 47 | {29F78C28-341C-4D6F-BE65-2CD559672A56}.Debug|x64.ActiveCfg = Debug|x64 48 | {29F78C28-341C-4D6F-BE65-2CD559672A56}.Debug|x64.Build.0 = Debug|x64 49 | {29F78C28-341C-4D6F-BE65-2CD559672A56}.Debug|x86.ActiveCfg = Debug|Win32 50 | {29F78C28-341C-4D6F-BE65-2CD559672A56}.Debug|x86.Build.0 = Debug|Win32 51 | {29F78C28-341C-4D6F-BE65-2CD559672A56}.Release|x64.ActiveCfg = Release|x64 52 | {29F78C28-341C-4D6F-BE65-2CD559672A56}.Release|x64.Build.0 = Release|x64 53 | {29F78C28-341C-4D6F-BE65-2CD559672A56}.Release|x86.ActiveCfg = Release|Win32 54 | {29F78C28-341C-4D6F-BE65-2CD559672A56}.Release|x86.Build.0 = Release|Win32 55 | {39BBD212-79B1-4527-8D62-194A6A8428A8}.Debug|x64.ActiveCfg = Debug|x64 56 | {39BBD212-79B1-4527-8D62-194A6A8428A8}.Debug|x64.Build.0 = Debug|x64 57 | {39BBD212-79B1-4527-8D62-194A6A8428A8}.Debug|x86.ActiveCfg = Debug|Win32 58 | {39BBD212-79B1-4527-8D62-194A6A8428A8}.Debug|x86.Build.0 = Debug|Win32 59 | {39BBD212-79B1-4527-8D62-194A6A8428A8}.Release|x64.ActiveCfg = Release|x64 60 | {39BBD212-79B1-4527-8D62-194A6A8428A8}.Release|x64.Build.0 = Release|x64 61 | {39BBD212-79B1-4527-8D62-194A6A8428A8}.Release|x86.ActiveCfg = Release|Win32 62 | {39BBD212-79B1-4527-8D62-194A6A8428A8}.Release|x86.Build.0 = Release|Win32 63 | EndGlobalSection 64 | GlobalSection(SolutionProperties) = preSolution 65 | HideSolutionNode = FALSE 66 | EndGlobalSection 67 | EndGlobal 68 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/FileFsAttribute.cpp: -------------------------------------------------------------------------------- 1 | #include "FileFsAttribute.h" 2 | 3 | CFileFsAttribute::CFileFsAttribute() 4 | { 5 | m_handle = INVALID_HANDLE_VALUE; 6 | ZeroMemory(&m_wfd, sizeof(m_wfd)); 7 | m_bInited = FALSE; 8 | } 9 | 10 | CFileFsAttribute::~CFileFsAttribute() 11 | { 12 | } 13 | 14 | HRESULT WINAPI CFileFsAttribute::QueryInterface( 15 | __in REFIID riid, 16 | __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) 17 | { 18 | if (ppvObject == NULL) 19 | { 20 | return E_INVALIDARG; 21 | } 22 | if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, __uuidof(IFsAttribute))) 23 | { 24 | *ppvObject = static_cast(this); 25 | AddRef(); 26 | return S_OK; 27 | } 28 | 29 | return E_NOINTERFACE; 30 | } 31 | 32 | HRESULT WINAPI CFileFsAttribute::Size(__out ULARGE_INTEGER * fileSize) 33 | { 34 | if (m_bInited == FALSE) 35 | { 36 | return E_NOT_SET; 37 | } 38 | if (fileSize == NULL) 39 | { 40 | return E_INVALIDARG; 41 | } 42 | 43 | HRESULT hr = QueryAttributes(); 44 | if (FAILED(hr)) return hr; 45 | 46 | fileSize->u.HighPart = m_wfd.nFileSizeHigh; 47 | fileSize->u.LowPart = m_wfd.nFileSizeLow; 48 | return hr; 49 | } 50 | 51 | HRESULT WINAPI CFileFsAttribute::Attributes(__out DWORD *attribs) 52 | { 53 | if (m_bInited == FALSE) 54 | { 55 | return E_NOT_SET; 56 | } 57 | if (attribs == NULL) 58 | { 59 | return E_INVALIDARG; 60 | } 61 | HRESULT hr = QueryAttributes(); 62 | if (FAILED(hr)) return hr; 63 | 64 | *attribs = m_wfd.dwFileAttributes; 65 | return hr; 66 | } 67 | 68 | HRESULT WINAPI CFileFsAttribute::SetAttributes(__in DWORD attribs) 69 | { 70 | if (m_bInited == FALSE) 71 | { 72 | return E_NOT_SET; 73 | } 74 | if (SetFileAttributesW(m_fileName.c_str(), attribs)) 75 | { 76 | return S_OK; 77 | } 78 | else 79 | { 80 | return HRESULT_FROM_WIN32(GetLastError()); 81 | } 82 | } 83 | 84 | HRESULT WINAPI CFileFsAttribute::Time( 85 | __out_opt FILETIME *lpCreationTime, 86 | __out_opt FILETIME *lpLastAccessTime, 87 | __out_opt FILETIME *lpLastWriteTime) 88 | { 89 | if (m_bInited == FALSE) 90 | { 91 | return E_NOT_SET; 92 | } 93 | if (lpCreationTime == NULL && lpLastAccessTime == NULL && lpLastWriteTime == NULL) 94 | { 95 | return E_INVALIDARG; 96 | } 97 | 98 | HRESULT hr = QueryAttributes(); 99 | if (FAILED(hr)) return hr; 100 | 101 | if (lpCreationTime) *lpCreationTime = m_wfd.ftCreationTime; 102 | if (lpLastAccessTime) *lpLastAccessTime = m_wfd.ftLastAccessTime; 103 | if (lpLastWriteTime) *lpLastWriteTime = m_wfd.ftLastWriteTime; 104 | return hr; 105 | } 106 | 107 | HRESULT WINAPI CFileFsAttribute::SetTime( 108 | __in_opt FILETIME *lpCreationTime, 109 | __in_opt FILETIME *lpLastAccessTime, 110 | __in_opt FILETIME *lpLastWriteTime) 111 | { 112 | HRESULT hr; 113 | if (lpCreationTime == NULL && lpLastAccessTime == NULL && lpLastWriteTime == NULL) 114 | { 115 | return E_INVALIDARG; 116 | } 117 | 118 | if (m_handle == NULL || m_handle == INVALID_HANDLE_VALUE) 119 | { 120 | HANDLE hFile = CreateFileW(m_fileName.c_str(), FILE_WRITE_ATTRIBUTES, 121 | FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, 122 | NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 123 | 124 | if (hFile != INVALID_HANDLE_VALUE) 125 | { 126 | if (SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime)) 127 | hr = S_OK; 128 | else 129 | { 130 | hr = HRESULT_FROM_WIN32(GetLastError()); 131 | } 132 | CloseHandle(hFile); 133 | return hr; 134 | } 135 | return HRESULT_FROM_WIN32(GetLastError()); 136 | } 137 | else 138 | { 139 | if (SetFileTime(m_handle, lpCreationTime, lpLastAccessTime, lpLastWriteTime)) 140 | return S_OK; 141 | else 142 | return HRESULT_FROM_WIN32(GetLastError()); 143 | } 144 | } 145 | 146 | HRESULT WINAPI CFileFsAttribute::SetFilePath(__in LPCWSTR lpFilePath, __in_opt void* handle /*= NULL*/) 147 | { 148 | m_handle = handle; 149 | m_fileName = lpFilePath; 150 | return QueryAttributes(); 151 | } 152 | 153 | HRESULT WINAPI CFileFsAttribute::QueryAttributes(void) 154 | { 155 | HANDLE hFind = FindFirstFileW(m_fileName.c_str(), &m_wfd); 156 | m_bInited = (hFind != INVALID_HANDLE_VALUE); 157 | HRESULT hr = m_bInited ? S_OK : HRESULT_FROM_WIN32(GetLastError()); 158 | FindClose(hFind); 159 | return hr; 160 | } 161 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/BufferedStream.cpp: -------------------------------------------------------------------------------- 1 | #include "BufferedStream.h" 2 | 3 | CBufferedStream::CBufferedStream(void) : 4 | m_FileSize(0), 5 | m_CurrPos(0) 6 | { 7 | } 8 | 9 | CBufferedStream::~CBufferedStream(void) 10 | { 11 | } 12 | 13 | HRESULT WINAPI CBufferedStream::QueryInterface( 14 | __in REFIID riid, 15 | __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) 16 | { 17 | if (ppvObject == NULL) return E_INVALIDARG; 18 | if (IsEqualIID(riid, IID_IUnknown) || 19 | IsEqualIID(riid, __uuidof(IFsStream))) 20 | { 21 | *ppvObject = static_cast(this); 22 | AddRef(); 23 | return S_OK; 24 | } 25 | 26 | return E_NOINTERFACE; 27 | } 28 | 29 | HRESULT WINAPI CBufferedStream::Read(__out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) 30 | { 31 | if (buffer == NULL || bufferSize == 0) return E_INVALIDARG; 32 | ULONGLONG copySize; 33 | 34 | if (m_CurrPos + bufferSize > m_FileSize) 35 | copySize = (ULONGLONG)(m_FileSize - m_CurrPos); 36 | else 37 | copySize = bufferSize; 38 | 39 | if (readSize) *readSize = (ULONG)copySize; 40 | if (copySize == 0) return E_NOT_VALID_STATE; 41 | 42 | memcpy(buffer, &m_DataStream[(size_t)m_CurrPos], (size_t)copySize); 43 | m_CurrPos += copySize; 44 | 45 | return S_OK; 46 | } 47 | 48 | HRESULT WINAPI CBufferedStream::ReadAt( 49 | __in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, 50 | __out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) 51 | { 52 | HRESULT hr = Seek(NULL, offset, moveMethod); 53 | if (FAILED(hr)) return hr; 54 | return Read(buffer, bufferSize, readSize); 55 | } 56 | 57 | HRESULT WINAPI CBufferedStream::Write(__in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) 58 | { 59 | if (buffer == NULL || bufferSize == 0) return E_INVALIDARG; 60 | 61 | if (m_CurrPos == m_FileSize) 62 | { 63 | m_DataStream.insert(m_DataStream.end(), bufferSize, 0); 64 | memcpy(&m_DataStream[(size_t)m_CurrPos], buffer, bufferSize); 65 | m_FileSize = m_CurrPos = m_CurrPos + (ULONGLONG)bufferSize; 66 | if (*writtenSize) *writtenSize = bufferSize; 67 | return S_OK; 68 | } 69 | else if (m_CurrPos < m_FileSize) 70 | { 71 | if ((m_CurrPos + (ULONGLONG)bufferSize) <= m_FileSize) 72 | { 73 | memcpy(&m_DataStream[(size_t)m_CurrPos], buffer, bufferSize); 74 | m_CurrPos += (ULONGLONG)bufferSize; 75 | if (*writtenSize) *writtenSize = bufferSize; 76 | return S_OK; 77 | } 78 | else 79 | { 80 | m_DataStream.insert(m_DataStream.end(), (size_t)(m_CurrPos + (ULONGLONG)bufferSize - m_FileSize), 0); 81 | memcpy(&m_DataStream[(size_t)m_CurrPos], buffer, bufferSize); 82 | m_FileSize = m_CurrPos = m_CurrPos + (ULONGLONG)bufferSize; 83 | if (*writtenSize) *writtenSize = bufferSize; 84 | return S_OK; 85 | } 86 | } 87 | 88 | return E_NOT_VALID_STATE; 89 | } 90 | 91 | HRESULT WINAPI CBufferedStream::WriteAt( 92 | __in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, 93 | __in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) 94 | { 95 | HRESULT hr = Seek(NULL, offset, moveMethod); 96 | if (FAILED(hr)) return hr; 97 | return Write(buffer, bufferSize, writtenSize); 98 | } 99 | 100 | HRESULT WINAPI CBufferedStream::Tell(__out ULARGE_INTEGER * pos) 101 | { 102 | if (pos == NULL) return E_INVALIDARG; 103 | 104 | pos->QuadPart = m_CurrPos; 105 | return S_OK; 106 | } 107 | 108 | HRESULT WINAPI CBufferedStream::Seek(__out_opt ULARGE_INTEGER * pos, __in LARGE_INTEGER const distanceToMove, __in const FsStreamSeek MoveMethod) 109 | { 110 | ULONGLONG newPos; 111 | 112 | switch (MoveMethod) 113 | { 114 | case FsStreamBegin: 115 | newPos = distanceToMove.QuadPart; 116 | break; 117 | 118 | case FsStreamCurrent: 119 | newPos = m_CurrPos + distanceToMove.QuadPart; 120 | break; 121 | 122 | case FsStreamEnd: 123 | newPos = m_FileSize + distanceToMove.QuadPart; 124 | break; 125 | 126 | default: 127 | return E_INVALIDARG; 128 | } 129 | 130 | if (newPos > m_FileSize) return E_INVALIDARG; 131 | m_CurrPos = newPos; 132 | if (pos) 133 | pos->QuadPart = m_CurrPos; 134 | return S_OK; 135 | } 136 | 137 | void WINAPI CBufferedStream::SetFileHandle(__in void* const handle) 138 | { 139 | if ((HANDLE)handle == INVALID_HANDLE_VALUE || handle == NULL) 140 | { 141 | m_DataStream.clear(); 142 | m_FileSize = m_CurrPos = 0; 143 | } 144 | } 145 | 146 | HRESULT WINAPI CBufferedStream::Shrink(void) 147 | { 148 | m_DataStream.resize((size_t)m_CurrPos); 149 | m_FileSize = m_DataStream.size(); 150 | m_CurrPos--; 151 | return S_OK; 152 | } 153 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /TinyAvConsole/ConsoleObserver.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | #include "ConsoleObserver.h" 3 | 4 | CConsoleObserver::CConsoleObserver() 5 | { 6 | m_bRescan = FALSE; 7 | m_bVirusDetected = FALSE; 8 | m_TotalFileCnt = 0; 9 | m_TotalObjectCnt = 0; 10 | m_DetectedCnt = 0; 11 | m_RemovedCnt = 0; 12 | m_error = FALSE; 13 | } 14 | 15 | CConsoleObserver::~CConsoleObserver() 16 | { 17 | } 18 | 19 | HRESULT WINAPI CConsoleObserver::QueryInterface(__in REFIID riid, __in void **ppvObject) 20 | { 21 | if (ppvObject == NULL) return E_INVALIDARG; 22 | 23 | if (riid == IID_IUnknown || 24 | riid == __uuidof(IScanObserver)) 25 | { 26 | *ppvObject = static_cast(this); 27 | AddRef(); 28 | return S_OK; 29 | } 30 | else 31 | { 32 | *ppvObject = NULL; 33 | } 34 | return E_NOINTERFACE; 35 | } 36 | 37 | HRESULT WINAPI CConsoleObserver::OnScanStarted(__in IFsEnumContext * context) 38 | { 39 | printf("Scanning ...\n"); 40 | m_TotalFileCnt = 0; 41 | m_TotalObjectCnt = 0; 42 | m_DetectedCnt = 0; 43 | m_RemovedCnt = 0; 44 | m_FailedCnt = 0; 45 | return S_OK; 46 | } 47 | 48 | HRESULT WINAPI CConsoleObserver::OnScanPaused(__in IFsEnumContext * context) 49 | { 50 | printf("Paused\n"); 51 | return S_OK; 52 | } 53 | 54 | HRESULT WINAPI CConsoleObserver::OnScanResumed(__in IFsEnumContext * context) 55 | { 56 | printf("Resumed\n"); 57 | return S_OK; 58 | } 59 | 60 | HRESULT WINAPI CConsoleObserver::OnScanStopping(__in IFsEnumContext * context) 61 | { 62 | printf("\n=============================================\n"); 63 | printf("Scanned : %lld file(s) (%lld object(s))\n", m_TotalFileCnt, m_TotalObjectCnt); 64 | printf("Detected : %lld file(s)\n", m_DetectedCnt); 65 | printf("Removed : %lld file(s)\n", m_RemovedCnt); 66 | printf("Access denied : %lld file(s)\n", m_FailedCnt); 67 | return S_OK; 68 | } 69 | 70 | HRESULT WINAPI CConsoleObserver::OnPreScan(__in IVirtualFs * file, __in IFsEnumContext * context) 71 | { 72 | m_error = FALSE; 73 | m_TotalObjectCnt++; 74 | if (m_bRescan) return S_OK; 75 | BSTR fullPath = NULL; 76 | ULONG fsType; 77 | if (SUCCEEDED(file->GetFsType(&fsType)) && 78 | fsType == IVirtualFs::basic) 79 | { 80 | m_TotalFileCnt++; 81 | } 82 | 83 | file->GetFullPath(&fullPath); 84 | if (fullPath) 85 | { 86 | WCHAR wzDisplay[70] = {}; 87 | if (wcslen(fullPath) < _countof(wzDisplay)) 88 | { 89 | wcscpy_s(wzDisplay, _countof(wzDisplay), fullPath); 90 | } 91 | else 92 | { 93 | wcsncpy(wzDisplay, fullPath, 20); 94 | wcscat(wzDisplay, L"..."); 95 | 96 | wcscpy_s(&wzDisplay[wcslen(wzDisplay)], _countof(wzDisplay) - wcslen(wzDisplay), &fullPath[wcslen(fullPath) - (_countof(wzDisplay) - 1 - wcslen(wzDisplay))]); 97 | } 98 | wprintf(L"%-70s ", wzDisplay); 99 | SysFreeString(fullPath); 100 | } 101 | return S_OK; 102 | } 103 | 104 | HRESULT WINAPI CConsoleObserver::OnAllScanFinished(__in IVirtualFs * file, __in IFsEnumContext * context) 105 | { 106 | if (m_bVirusDetected == FALSE && !m_error) 107 | { 108 | printf("OK\n"); 109 | } 110 | m_bVirusDetected = FALSE; 111 | m_bRescan = FALSE; 112 | m_error = FALSE; 113 | return S_OK; 114 | } 115 | 116 | HRESULT WINAPI CConsoleObserver::OnPreClean(__in IVirtualFs * file, __in IFsEnumContext * context, __inout SCAN_RESULT * result) 117 | { 118 | wprintf(L"\n\t%s ", result->malwareName); 119 | result->action = KillVirus; 120 | m_bVirusDetected = TRUE; 121 | m_DetectedCnt++; 122 | return S_OK; 123 | } 124 | 125 | HRESULT WINAPI CConsoleObserver::OnPostClean(__in IVirtualFs * file, __in IFsEnumContext * context, __in SCAN_RESULT * result) 126 | { 127 | if (result && result->scanResult == VirusDetected) 128 | { 129 | switch (result->cleanResult) 130 | { 131 | case CleanVirusSucceeded: 132 | printf("Disinfected \n"); 133 | m_bRescan = TRUE; 134 | m_RemovedCnt++; 135 | break; 136 | 137 | case CleanVirusDenied: 138 | printf("Access Denied \n"); 139 | m_FailedCnt++; 140 | break; 141 | 142 | case VirusDeleted: 143 | printf("Deleted \n"); 144 | m_RemovedCnt++; 145 | break; 146 | 147 | default: 148 | printf("Unknown error \n"); 149 | m_FailedCnt++; 150 | break; 151 | } 152 | } 153 | 154 | return S_OK; 155 | } 156 | 157 | void WINAPI CConsoleObserver::OnError(__in DWORD dwErrorCode, __in_opt LPCWSTR lpMessage /*= NULL*/) 158 | { 159 | m_error = TRUE; 160 | printf("\n[!] "); 161 | if (lpMessage) 162 | { 163 | wprintf(L"%s ", lpMessage); 164 | } 165 | 166 | switch (dwErrorCode) 167 | { 168 | case IFsEnum::FsEnumAccessDenied: 169 | wprintf(L"Access denied."); 170 | m_TotalFileCnt++; 171 | m_FailedCnt++; 172 | break; 173 | case IFsEnum::FsEnumNotFound: 174 | wprintf(L"Not found."); 175 | break; 176 | 177 | case IEmulObserver::EmulatorIsNotFound: 178 | wprintf(L"unicorn.dll and its dependent dlls are needed."); 179 | break; 180 | case IEmulObserver::EmulatorIsNotRunable: 181 | wprintf(L"Internal error has occurred. Skip this file."); 182 | break; 183 | case IEmulObserver::EmulatorInternalError: 184 | wprintf(L"Emulator has internal errors. Skip this file."); 185 | break; 186 | default: 187 | break; 188 | } 189 | 190 | printf("\n"); 191 | } 192 | -------------------------------------------------------------------------------- /include/FileSystem/FsStream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | 4 | MIDL_INTERFACE("AC50DA10-6F4D-469E-9050-E716FB987AE0") 5 | IFsStream : public IUnknown 6 | { 7 | public: 8 | enum FsStreamSeek 9 | { 10 | FsStreamBegin = 1, // Beginning of stream 11 | FsStreamCurrent = 2, // Current position of the stream pointer 12 | FsStreamEnd = 3, // End of stream 13 | }; 14 | 15 | BEGIN_INTERFACE 16 | 17 | /* Set handle to the specified stream 18 | @handle: A handle of new specified stream. 19 | @return: If the function has no return value. 20 | */ 21 | virtual void WINAPI SetFileHandle(__in void* const handle) = 0; 22 | 23 | /* Read data from the specified stream. 24 | @buffer: A pointer to the buffer that receives the data. 25 | @bufferSize: The maximum number of bytes to be read. 26 | @readSize: A pointer to the variable that receives the number of bytes read. 27 | @return: If the function succeeds, the return value is S_OK. 28 | */ 29 | virtual HRESULT WINAPI Read(__out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) = 0; 30 | 31 | /* Read a specified number of bytes starting at a specified offset from the specified stream. 32 | @offset: The number of bytes to move the file pointer. A positive 33 | value moves the pointer forward in the file and a negative value moves the 34 | file pointer backward. 35 | @moveMethod: The starting point for the file pointer move. This parameter 36 | can be one of the following values: 37 | FsStreamBegin: The starting point is the beginning of the stream. 38 | FsStreamCurrent: The start point is the current value of the stream pointer. 39 | FsStreamEnd: The starting point is the current end-of-stream position. 40 | @buffer: A pointer to the buffer that receives the data. 41 | @bufferSize: The maximum number of bytes to be read. 42 | @readSize: A pointer to the variable that receives the number of bytes read. 43 | @return: If the function succeeds, the return value is S_OK. 44 | */ 45 | virtual HRESULT WINAPI ReadAt(__in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, 46 | __out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) = 0; 47 | 48 | /* Write data to the specified stream. 49 | @buffer: A pointer to the buffer containing the data to be written to stream. 50 | @bufferSize: The maximum number of bytes to be written. 51 | @writtenSize: A pointer to the variable that receives the number of bytes written. 52 | @return: If the function succeeds, the return value is S_OK. 53 | */ 54 | virtual HRESULT WINAPI Write(__in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) = 0; 55 | 56 | /* Write a specified number of bytes starting at a specified offset from the specified stream. 57 | @offset: The number of bytes to move the file pointer. A positive 58 | value moves the pointer forward in the file and a negative value moves the 59 | file pointer backward. 60 | @moveMethod: The starting point for the file pointer move. This parameter 61 | can be one of the following values: 62 | FsStreamBegin: The starting point is the beginning of the stream. 63 | FsStreamCurrent: The start point is the current value of the stream pointer. 64 | FsStreamEnd: The starting point is the current end-of-stream position. 65 | @buffer: A pointer to the buffer that receives the data. 66 | @bufferSize: The maximum number of bytes to be read. 67 | @readSize: A pointer to the variable that receives the number of bytes read. 68 | @return: If the function succeeds, the return value is S_OK. 69 | */ 70 | virtual HRESULT WINAPI WriteAt(__in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, 71 | __in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) = 0; 72 | 73 | // Get the stream pointer of the specified stream. 74 | //@pos: A pointer to a variable to receive the new file pointer. 75 | //@return: If the function succeeds, the return value is S_OK. 76 | virtual HRESULT WINAPI Tell(__out ULARGE_INTEGER * pos) = 0; 77 | 78 | /* Move the stream pointer of the specified stream. 79 | @distanceToMove: The number of bytes to move the file pointer. A positive 80 | value moves the pointer forward in the file and a negative value moves the 81 | file pointer backward. 82 | @pos: A pointer to a variable to receive the new file pointer. If this 83 | parameter is NULL, the new file pointer is not returned. 84 | @MoveMethod: The starting point for the file pointer move. This parameter 85 | can be one of the following values: 86 | FsStreamBegin : The starting point is the beginning of the stream. 87 | FsStreamCurrent: The start point is the current value of the stream pointer. 88 | FsStreamEnd : The starting point is the current end-of-stream position. 89 | @return: If the function succeeds, the return value is S_OK. 90 | */ 91 | virtual HRESULT WINAPI Seek(__out_opt ULARGE_INTEGER * pos, __in LARGE_INTEGER const distanceToMove, __in const FsStreamSeek MoveMethod) = 0; 92 | 93 | /* 94 | Shrink the size of a stream to the current position of the stream pointer. 95 | @return: If the function succeeds, the return value is S_OK. 96 | */ 97 | virtual HRESULT WINAPI Shrink(void) = 0; 98 | 99 | END_INTERFACE 100 | }; 101 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/FileFsEnumContext.cpp: -------------------------------------------------------------------------------- 1 | #include "FileFsEnumContext.h" 2 | 3 | CFileFsEnumContext::CFileFsEnumContext() 4 | { 5 | m_depth = 0; 6 | m_maxDepth = -1; 7 | m_ArchiveDepth = 0; 8 | m_maxArchiveDepth = -1; 9 | m_flags = 0; 10 | m_container = NULL; 11 | m_maxSize.QuadPart = MAX_FILE_SIZE; 12 | } 13 | 14 | CFileFsEnumContext::~CFileFsEnumContext() 15 | { 16 | if (m_container) 17 | { 18 | m_container->Release(); 19 | m_container = NULL; 20 | } 21 | } 22 | 23 | HRESULT WINAPI CFileFsEnumContext::QueryInterface( 24 | __in REFIID riid, 25 | __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) 26 | { 27 | if (ppvObject == NULL) return E_INVALIDARG; 28 | if (IsEqualIID(riid, IID_IUnknown) || 29 | IsEqualIID(riid, __uuidof(IFsEnumContext))) 30 | { 31 | *ppvObject = static_cast(this); 32 | AddRef(); 33 | return S_OK; 34 | } 35 | else 36 | { 37 | *ppvObject = NULL; 38 | } 39 | return E_NOINTERFACE; 40 | } 41 | 42 | HRESULT WINAPI CFileFsEnumContext::SetSearchContainer(__in IVirtualFs *container) 43 | { 44 | if (container == NULL) return E_INVALIDARG; 45 | 46 | if (m_container) 47 | { 48 | m_container->Release(); 49 | m_container = NULL; 50 | } 51 | 52 | container->AddRef(); 53 | m_container = container; 54 | return S_OK; 55 | } 56 | 57 | HRESULT WINAPI CFileFsEnumContext::GetSearchContainer(__out IVirtualFs **container) 58 | { 59 | if (container == NULL) return E_INVALIDARG; 60 | *container = m_container; 61 | m_container->AddRef(); 62 | return S_OK; 63 | } 64 | 65 | HRESULT WINAPI CFileFsEnumContext::SetSearchPattern(__in LPCWSTR searchPattern) 66 | { 67 | if (searchPattern == NULL) return E_INVALIDARG; 68 | m_searchPattern = searchPattern; 69 | return S_OK; 70 | } 71 | 72 | HRESULT WINAPI CFileFsEnumContext::GetSearchPattern(__out BSTR *searchPattern) 73 | { 74 | if (m_searchPattern.length() == 0) return E_NOT_SET; 75 | if (searchPattern == NULL) return E_INVALIDARG; 76 | 77 | *searchPattern = SysAllocString(m_searchPattern.c_str()); 78 | return (*searchPattern) ? S_OK : E_OUTOFMEMORY; 79 | } 80 | 81 | int WINAPI CFileFsEnumContext::GetMaxDepth(void) 82 | { 83 | return m_maxDepth; 84 | } 85 | 86 | int WINAPI CFileFsEnumContext::GetDepth(void) 87 | { 88 | return m_depth; 89 | } 90 | 91 | HRESULT WINAPI CFileFsEnumContext::SetMaxFileSize(__in ULARGE_INTEGER fileSize) 92 | { 93 | if (fileSize.QuadPart <= MAX_FILE_SIZE) 94 | { 95 | m_maxSize = fileSize; 96 | return S_OK; 97 | } 98 | else 99 | { 100 | return S_FALSE; 101 | } 102 | } 103 | 104 | HRESULT WINAPI CFileFsEnumContext::GetMaxFileSize(__in ULARGE_INTEGER *fileSize) 105 | { 106 | if (fileSize == NULL) return E_INVALIDARG; 107 | *fileSize = m_maxSize; 108 | return S_OK; 109 | } 110 | 111 | HRESULT WINAPI CFileFsEnumContext::AddIgnoreItem(__in LPCWSTR lpPath) 112 | { 113 | if (lpPath == NULL) return E_INVALIDARG; 114 | if (m_ignore.end() == std::find(m_ignore.begin(), m_ignore.end(), StringW(lpPath))) 115 | { 116 | m_ignore.push_back(lpPath); 117 | return S_OK; 118 | } 119 | return S_FALSE; 120 | } 121 | 122 | HRESULT WINAPI CFileFsEnumContext::RemoveIgnoreItem(__in LPCWSTR lpPath) 123 | { 124 | if (lpPath == NULL) return E_INVALIDARG; 125 | std::vector::iterator it = std::find(m_ignore.begin(), m_ignore.end(), StringW(lpPath)); 126 | if (m_ignore.end() == it) 127 | { 128 | return E_NOT_SET; 129 | } 130 | m_ignore.erase(it); 131 | return S_FALSE; 132 | } 133 | 134 | HRESULT WINAPI CFileFsEnumContext::GetIgnoreList(__out BSTR* lpPath, __out UINT *itemCount) 135 | { 136 | if (itemCount == NULL || lpPath == NULL) return E_INVALIDARG; 137 | *itemCount = (UINT)m_ignore.size(); 138 | if (*itemCount == 0) return S_OK; 139 | *lpPath = (BSTR)new BSTR[*itemCount]; 140 | if (*lpPath == NULL) 141 | return E_OUTOFMEMORY; 142 | ZeroMemory(*lpPath, *itemCount * sizeof(BSTR)); 143 | for (UINT i = 0; i < *itemCount; ++i) 144 | { 145 | BSTR b = SysAllocString(m_ignore[i].c_str()); 146 | if (b == NULL) 147 | { 148 | for (UINT j = 0; j < *itemCount; ++j) 149 | { 150 | if (lpPath[j]) 151 | SysFreeString(lpPath[j]); 152 | } 153 | delete[] (*lpPath); 154 | return E_OUTOFMEMORY; 155 | } 156 | 157 | lpPath[i] = b; 158 | } 159 | 160 | return S_OK; 161 | } 162 | 163 | HRESULT WINAPI CFileFsEnumContext::FreeIgnoreList(__in BSTR* lpPath, __in UINT itemCount) 164 | { 165 | for (UINT j = 0; j < itemCount; ++j) 166 | { 167 | if (lpPath[j]) 168 | SysFreeString(lpPath[j]); 169 | } 170 | delete[](*lpPath); 171 | return S_OK; 172 | } 173 | 174 | int WINAPI CFileFsEnumContext::GetMaxDepthInArchive(void) 175 | { 176 | return m_maxArchiveDepth; 177 | } 178 | 179 | int WINAPI CFileFsEnumContext::GetDepthInArchive(void) 180 | { 181 | return m_ArchiveDepth; 182 | } 183 | 184 | HRESULT WINAPI CFileFsEnumContext::SetMaxDepthInArchive(__in const int maxDepth) 185 | { 186 | m_maxArchiveDepth = maxDepth; 187 | return S_OK; 188 | } 189 | 190 | HRESULT WINAPI CFileFsEnumContext::SetDepthInArchive(__in const int depth) 191 | { 192 | m_ArchiveDepth = depth; 193 | return S_OK; 194 | } 195 | 196 | HRESULT WINAPI CFileFsEnumContext::SetMaxDepth(__in const int maxDepth) 197 | { 198 | m_maxDepth = maxDepth; 199 | return S_OK; 200 | } 201 | 202 | HRESULT WINAPI CFileFsEnumContext::SetDepth(__in const int depth) 203 | { 204 | m_depth = depth; 205 | return S_OK; 206 | } 207 | 208 | HRESULT WINAPI CFileFsEnumContext::SetFlags(__in const ULONG flags) 209 | { 210 | m_flags = flags; 211 | return S_OK; 212 | } 213 | 214 | ULONG WINAPI CFileFsEnumContext::GetFlags(void) 215 | { 216 | return m_flags; 217 | } 218 | 219 | -------------------------------------------------------------------------------- /libs/include/unicorn/mips.h: -------------------------------------------------------------------------------- 1 | #ifndef UNICORN_MIPS_H 2 | #define UNICORN_MIPS_H 3 | 4 | /* Unicorn Emulator Engine */ 5 | /* By Nguyen Anh Quynh , 2015 */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // GCC MIPS toolchain has a default macro called "mips" which breaks 12 | // compilation 13 | #undef mips 14 | 15 | #ifdef _MSC_VER 16 | #pragma warning(disable:4201) 17 | #endif 18 | 19 | //> MIPS registers 20 | typedef enum UC_MIPS_REG { 21 | UC_MIPS_REG_INVALID = 0, 22 | //> General purpose registers 23 | UC_MIPS_REG_PC, 24 | 25 | UC_MIPS_REG_0, 26 | UC_MIPS_REG_1, 27 | UC_MIPS_REG_2, 28 | UC_MIPS_REG_3, 29 | UC_MIPS_REG_4, 30 | UC_MIPS_REG_5, 31 | UC_MIPS_REG_6, 32 | UC_MIPS_REG_7, 33 | UC_MIPS_REG_8, 34 | UC_MIPS_REG_9, 35 | UC_MIPS_REG_10, 36 | UC_MIPS_REG_11, 37 | UC_MIPS_REG_12, 38 | UC_MIPS_REG_13, 39 | UC_MIPS_REG_14, 40 | UC_MIPS_REG_15, 41 | UC_MIPS_REG_16, 42 | UC_MIPS_REG_17, 43 | UC_MIPS_REG_18, 44 | UC_MIPS_REG_19, 45 | UC_MIPS_REG_20, 46 | UC_MIPS_REG_21, 47 | UC_MIPS_REG_22, 48 | UC_MIPS_REG_23, 49 | UC_MIPS_REG_24, 50 | UC_MIPS_REG_25, 51 | UC_MIPS_REG_26, 52 | UC_MIPS_REG_27, 53 | UC_MIPS_REG_28, 54 | UC_MIPS_REG_29, 55 | UC_MIPS_REG_30, 56 | UC_MIPS_REG_31, 57 | 58 | //> DSP registers 59 | UC_MIPS_REG_DSPCCOND, 60 | UC_MIPS_REG_DSPCARRY, 61 | UC_MIPS_REG_DSPEFI, 62 | UC_MIPS_REG_DSPOUTFLAG, 63 | UC_MIPS_REG_DSPOUTFLAG16_19, 64 | UC_MIPS_REG_DSPOUTFLAG20, 65 | UC_MIPS_REG_DSPOUTFLAG21, 66 | UC_MIPS_REG_DSPOUTFLAG22, 67 | UC_MIPS_REG_DSPOUTFLAG23, 68 | UC_MIPS_REG_DSPPOS, 69 | UC_MIPS_REG_DSPSCOUNT, 70 | 71 | //> ACC registers 72 | UC_MIPS_REG_AC0, 73 | UC_MIPS_REG_AC1, 74 | UC_MIPS_REG_AC2, 75 | UC_MIPS_REG_AC3, 76 | 77 | //> COP registers 78 | UC_MIPS_REG_CC0, 79 | UC_MIPS_REG_CC1, 80 | UC_MIPS_REG_CC2, 81 | UC_MIPS_REG_CC3, 82 | UC_MIPS_REG_CC4, 83 | UC_MIPS_REG_CC5, 84 | UC_MIPS_REG_CC6, 85 | UC_MIPS_REG_CC7, 86 | 87 | //> FPU registers 88 | UC_MIPS_REG_F0, 89 | UC_MIPS_REG_F1, 90 | UC_MIPS_REG_F2, 91 | UC_MIPS_REG_F3, 92 | UC_MIPS_REG_F4, 93 | UC_MIPS_REG_F5, 94 | UC_MIPS_REG_F6, 95 | UC_MIPS_REG_F7, 96 | UC_MIPS_REG_F8, 97 | UC_MIPS_REG_F9, 98 | UC_MIPS_REG_F10, 99 | UC_MIPS_REG_F11, 100 | UC_MIPS_REG_F12, 101 | UC_MIPS_REG_F13, 102 | UC_MIPS_REG_F14, 103 | UC_MIPS_REG_F15, 104 | UC_MIPS_REG_F16, 105 | UC_MIPS_REG_F17, 106 | UC_MIPS_REG_F18, 107 | UC_MIPS_REG_F19, 108 | UC_MIPS_REG_F20, 109 | UC_MIPS_REG_F21, 110 | UC_MIPS_REG_F22, 111 | UC_MIPS_REG_F23, 112 | UC_MIPS_REG_F24, 113 | UC_MIPS_REG_F25, 114 | UC_MIPS_REG_F26, 115 | UC_MIPS_REG_F27, 116 | UC_MIPS_REG_F28, 117 | UC_MIPS_REG_F29, 118 | UC_MIPS_REG_F30, 119 | UC_MIPS_REG_F31, 120 | 121 | UC_MIPS_REG_FCC0, 122 | UC_MIPS_REG_FCC1, 123 | UC_MIPS_REG_FCC2, 124 | UC_MIPS_REG_FCC3, 125 | UC_MIPS_REG_FCC4, 126 | UC_MIPS_REG_FCC5, 127 | UC_MIPS_REG_FCC6, 128 | UC_MIPS_REG_FCC7, 129 | 130 | //> AFPR128 131 | UC_MIPS_REG_W0, 132 | UC_MIPS_REG_W1, 133 | UC_MIPS_REG_W2, 134 | UC_MIPS_REG_W3, 135 | UC_MIPS_REG_W4, 136 | UC_MIPS_REG_W5, 137 | UC_MIPS_REG_W6, 138 | UC_MIPS_REG_W7, 139 | UC_MIPS_REG_W8, 140 | UC_MIPS_REG_W9, 141 | UC_MIPS_REG_W10, 142 | UC_MIPS_REG_W11, 143 | UC_MIPS_REG_W12, 144 | UC_MIPS_REG_W13, 145 | UC_MIPS_REG_W14, 146 | UC_MIPS_REG_W15, 147 | UC_MIPS_REG_W16, 148 | UC_MIPS_REG_W17, 149 | UC_MIPS_REG_W18, 150 | UC_MIPS_REG_W19, 151 | UC_MIPS_REG_W20, 152 | UC_MIPS_REG_W21, 153 | UC_MIPS_REG_W22, 154 | UC_MIPS_REG_W23, 155 | UC_MIPS_REG_W24, 156 | UC_MIPS_REG_W25, 157 | UC_MIPS_REG_W26, 158 | UC_MIPS_REG_W27, 159 | UC_MIPS_REG_W28, 160 | UC_MIPS_REG_W29, 161 | UC_MIPS_REG_W30, 162 | UC_MIPS_REG_W31, 163 | 164 | UC_MIPS_REG_HI, 165 | UC_MIPS_REG_LO, 166 | 167 | UC_MIPS_REG_P0, 168 | UC_MIPS_REG_P1, 169 | UC_MIPS_REG_P2, 170 | 171 | UC_MIPS_REG_MPL0, 172 | UC_MIPS_REG_MPL1, 173 | UC_MIPS_REG_MPL2, 174 | 175 | UC_MIPS_REG_ENDING, // <-- mark the end of the list or registers 176 | 177 | // alias registers 178 | UC_MIPS_REG_ZERO = UC_MIPS_REG_0, 179 | UC_MIPS_REG_AT = UC_MIPS_REG_1, 180 | UC_MIPS_REG_V0 = UC_MIPS_REG_2, 181 | UC_MIPS_REG_V1 = UC_MIPS_REG_3, 182 | UC_MIPS_REG_A0 = UC_MIPS_REG_4, 183 | UC_MIPS_REG_A1 = UC_MIPS_REG_5, 184 | UC_MIPS_REG_A2 = UC_MIPS_REG_6, 185 | UC_MIPS_REG_A3 = UC_MIPS_REG_7, 186 | UC_MIPS_REG_T0 = UC_MIPS_REG_8, 187 | UC_MIPS_REG_T1 = UC_MIPS_REG_9, 188 | UC_MIPS_REG_T2 = UC_MIPS_REG_10, 189 | UC_MIPS_REG_T3 = UC_MIPS_REG_11, 190 | UC_MIPS_REG_T4 = UC_MIPS_REG_12, 191 | UC_MIPS_REG_T5 = UC_MIPS_REG_13, 192 | UC_MIPS_REG_T6 = UC_MIPS_REG_14, 193 | UC_MIPS_REG_T7 = UC_MIPS_REG_15, 194 | UC_MIPS_REG_S0 = UC_MIPS_REG_16, 195 | UC_MIPS_REG_S1 = UC_MIPS_REG_17, 196 | UC_MIPS_REG_S2 = UC_MIPS_REG_18, 197 | UC_MIPS_REG_S3 = UC_MIPS_REG_19, 198 | UC_MIPS_REG_S4 = UC_MIPS_REG_20, 199 | UC_MIPS_REG_S5 = UC_MIPS_REG_21, 200 | UC_MIPS_REG_S6 = UC_MIPS_REG_22, 201 | UC_MIPS_REG_S7 = UC_MIPS_REG_23, 202 | UC_MIPS_REG_T8 = UC_MIPS_REG_24, 203 | UC_MIPS_REG_T9 = UC_MIPS_REG_25, 204 | UC_MIPS_REG_K0 = UC_MIPS_REG_26, 205 | UC_MIPS_REG_K1 = UC_MIPS_REG_27, 206 | UC_MIPS_REG_GP = UC_MIPS_REG_28, 207 | UC_MIPS_REG_SP = UC_MIPS_REG_29, 208 | UC_MIPS_REG_FP = UC_MIPS_REG_30, UC_MIPS_REG_S8 = UC_MIPS_REG_30, 209 | UC_MIPS_REG_RA = UC_MIPS_REG_31, 210 | 211 | UC_MIPS_REG_HI0 = UC_MIPS_REG_AC0, 212 | UC_MIPS_REG_HI1 = UC_MIPS_REG_AC1, 213 | UC_MIPS_REG_HI2 = UC_MIPS_REG_AC2, 214 | UC_MIPS_REG_HI3 = UC_MIPS_REG_AC3, 215 | 216 | UC_MIPS_REG_LO0 = UC_MIPS_REG_HI0, 217 | UC_MIPS_REG_LO1 = UC_MIPS_REG_HI1, 218 | UC_MIPS_REG_LO2 = UC_MIPS_REG_HI2, 219 | UC_MIPS_REG_LO3 = UC_MIPS_REG_HI3, 220 | } UC_MIPS_REG; 221 | 222 | #ifdef __cplusplus 223 | } 224 | #endif 225 | 226 | #endif 227 | -------------------------------------------------------------------------------- /TinyAvConsole/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #pragma comment(lib, "Shlwapi.lib") 6 | #include "getopt.h" 7 | #include "ConsoleObserver.h" 8 | 9 | #if defined DEBUG || defined _DEBUG 10 | #include 11 | #endif 12 | ////////////////////////////////////////////////////////////////////////// 13 | 14 | // notelemetry 15 | #ifdef __cplusplus 16 | extern "C" 17 | { 18 | #endif // __cplusplus 19 | void _cdecl __vcrt_initialize_telemetry_provider() {} 20 | void _cdecl __telemetry_main_invoke_trigger() {} 21 | void _cdecl __telemetry_main_return_trigger() {} 22 | void _cdecl __vcrt_uninitialize_telemetry_provider() {} 23 | #ifdef __cplusplus 24 | }; 25 | #endif // __cplusplus 26 | ////////////////////////////////////////////////////////////////////////// 27 | 28 | 29 | void Usage(void) 30 | { 31 | puts("Read README.md for usage\n"); 32 | exit(0); 33 | } 34 | 35 | void PrintWelcome() 36 | { 37 | puts("--------------------------------------------------------------------------"); 38 | puts("TinyAntivirus version 0.1"); 39 | puts("Copyright (C) 2016, Quang Nguyen. All rights reserved."); 40 | puts("TinyAntivirus comes with ABSOLUTELY NO WARRANTY"); 41 | puts("This is free software, and you are welcome to redistribute it under "); 42 | puts("certain conditions."); 43 | puts("Website: http://develbranch.com"); 44 | puts("--------------------------------------------------------------------------"); 45 | } 46 | 47 | int wmain(int argc, wchar_t* argv[]) 48 | { 49 | PrintWelcome(); 50 | #if defined DEBUG || defined _DEBUG 51 | { 52 | int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 53 | _CrtSetDbgFlag(flag | _CRTDBG_LEAK_CHECK_DF); 54 | //_CrtSetBreakAlloc(0x1337); 55 | } 56 | #endif 57 | HRESULT hr; 58 | WCHAR szPattern[MAX_PATH + 1] = L"*.*"; 59 | WCHAR szTargetDir[MAX_PATH + 1] = {}; 60 | WCHAR szPluginsSubDir[MAX_PATH + 1] = {}; 61 | WCHAR szPluginsDir[MAX_PATH + 1] = {}; 62 | int c; 63 | int depth = -1; 64 | int archiveDepth = -1; 65 | ULARGE_INTEGER maxFileSize = {}; 66 | int mode = 2; //kill mode 67 | maxFileSize.QuadPart = 10 * 1024 * 1024; 68 | // -p 69 | while ((c = getopt_w(argc, argv, L"e:A:D:d:p:s:m:h")) != -1) 70 | { 71 | switch (c) 72 | { 73 | case L'e': 74 | wcscpy_s((wchar_t*)szPluginsSubDir, MAX_PATH, optarg_w); 75 | break; 76 | 77 | case L'A': 78 | archiveDepth = _wtoi(optarg_w); 79 | break; 80 | 81 | case L'D': 82 | depth = _wtoi(optarg_w); 83 | break; 84 | 85 | case L'd': 86 | wcscpy_s((wchar_t*)szTargetDir, MAX_PATH, optarg_w); 87 | break; 88 | 89 | case L'p': 90 | wcscpy_s((wchar_t*)szPattern, MAX_PATH, optarg_w); 91 | break; 92 | 93 | case L's': 94 | maxFileSize.QuadPart = _wtoi(optarg_w); 95 | break; 96 | 97 | case L'm': // mode 98 | if ((optarg_w[0] & 0xdf) == L'K') // kill mode 99 | mode = 2; 100 | if ((optarg_w[0] & 0xdf) == L'S') // Scan mode 101 | mode = 1; 102 | break; 103 | 104 | case L'h': 105 | Usage(); 106 | break; 107 | default: 108 | Usage(); 109 | break; 110 | } 111 | } 112 | 113 | if (wcslen(szTargetDir) == 0) 114 | return 1; 115 | 116 | IScanObserver * consoleObserver = NULL; 117 | IScanner * scanner = NULL; 118 | IModuleManager *mgr = NULL; 119 | IFsEnumContext * enumContext = NULL; 120 | IVirtualFs *container = NULL; 121 | 122 | if (FAILED(CreateClassObject(CLSID_CModuleMgrService, 0, __uuidof(IModuleManager), (LPVOID*)&mgr)) || 123 | FAILED(CreateClassObject(CLSID_CScanService, 0, __uuidof(IScanner), (LPVOID*)&scanner)) || 124 | FAILED(CreateClassObject(CLSID_CFileFsEnumContext, 0, __uuidof(IFsEnumContext), (LPVOID*)&enumContext)) || 125 | FAILED(CreateClassObject(CLSID_CFileFs, 0, __uuidof(IVirtualFs), (LPVOID*)&container)) || 126 | ((consoleObserver = static_cast(new CConsoleObserver)) == NULL) 127 | ) 128 | { 129 | if (scanner) scanner->Release(); 130 | if (mgr) mgr->Release(); 131 | if (enumContext) enumContext->Release(); 132 | if (container) container->Release(); 133 | if (consoleObserver) consoleObserver->Release(); 134 | return 1; 135 | } 136 | 137 | GetModuleFileNameW(NULL, szPluginsDir, MAX_PATH); 138 | PathRemoveFileSpecW(szPluginsDir); 139 | if (wcslen(szPluginsSubDir) > 0) 140 | PathAppendW(szPluginsDir, szPluginsSubDir); 141 | 142 | if (SUCCEEDED(mgr->Load(szPluginsDir, NULL, 0))) 143 | { 144 | IModule **scanModule = NULL; 145 | size_t moduleCount = 0; 146 | 147 | if (SUCCEEDED(mgr->QueryModule(scanModule, moduleCount, ScanModule))) 148 | { 149 | for (size_t i = 0; i < moduleCount; ++i) 150 | { 151 | scanner->AddScanModule(dynamic_cast(scanModule[i])); 152 | scanModule[i]->Release(); 153 | } 154 | 155 | CoTaskMemFree(scanModule); 156 | } 157 | 158 | if ( 159 | SUCCEEDED(hr = scanner->AddScanObserver(consoleObserver)) && 160 | SUCCEEDED(hr = enumContext->SetSearchPattern(szPattern)) && 161 | SUCCEEDED(hr = enumContext->SetMaxDepth(depth)) && 162 | SUCCEEDED(hr = enumContext->SetMaxDepthInArchive(archiveDepth)) && 163 | SUCCEEDED(hr = enumContext->SetMaxFileSize(maxFileSize)) && 164 | SUCCEEDED(hr = enumContext->SetFlags((mode == 1) ? IFsEnumContext::DetectOnly : IFsEnumContext::Disinfect)) && 165 | SUCCEEDED(hr = container->Create(szTargetDir, 0)) && 166 | SUCCEEDED(hr = enumContext->SetSearchContainer(container)) 167 | ) 168 | { 169 | hr = scanner->Start(enumContext); 170 | scanner->Forever(); 171 | } 172 | } 173 | consoleObserver->Release(); 174 | enumContext->Release(); 175 | container->Release(); 176 | scanner->Release(); 177 | mgr->Unload(ScanModule); 178 | mgr->Release(); 179 | return 0; 180 | } -------------------------------------------------------------------------------- /include/FileSystem/FsObject.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "FsAttribute.h" 4 | #include "FsStream.h" 5 | 6 | MIDL_INTERFACE("9FC5CDB9-77CF-4D3D-802A-74BBF789F572") 7 | IVirtualFs : public IUnknown 8 | { 9 | enum IFsType { 10 | unknown = 1, 11 | basic = 1 << 1, 12 | archive = 1 << 2, 13 | }; 14 | 15 | enum IFsObjectFlags { 16 | fsRead = 1, // Read access 17 | fsWrite = 1 << 1, // Write access 18 | fsSharedRead = 1 << 2, // Enables subsequent open operations on a file to request read access. 19 | fsSharedWrite = 1 << 3, // Enables subsequent open operations on a file to request write access. 20 | fsSharedDelete = 1 << 4, // Enables subsequent open operations on a file to request delete access. 21 | fsCreateNew = 1 << 5, // Creates a new file, only if it does not already exist. 22 | fsCreateAlways = 1 << 6, // Creates a new file, always. 23 | fsOpenAlways = 1 << 7, // Opens a file, always. 24 | fsOpenExisting = 1 << 8, // Opens a file only if it exists. 25 | fsAttrNormal = 1 << 9, // The file does not have other attributes set. 26 | fsAttrReadonly = 1 << 10, // The file is read only. Applications can read the file, but cannot write to or delete it. 27 | fsAttrSystem = 1 << 11, // The file is part of or used exclusively by an operating system. 28 | fsAttrHidden = 1 << 12, // The file is hidden. Do not include it in an ordinary directory listing. 29 | fsAttrTemporary = 1 << 13, // The file is being used for temporary storage. 30 | fsAttrDeleteOnClose = 1 << 14, // The file is to be deleted immediately after all of its handles are closed. 31 | fsDeferredCreation = 1 << 15, // Defer the creation of file when creating or opening until application re-creates file. 32 | fsDeferredDeletion = 1 << 16, // Defer the deletion of file until application closes it 33 | }; 34 | 35 | BEGIN_INTERFACE 36 | 37 | public: 38 | /* Create or open file 39 | @lpFileName: The name of the file to be created or opened. 40 | @flags: The file attributes and flags. 41 | @return: HRESULT on success, or other value on failure. 42 | */ 43 | virtual HRESULT WINAPI Create(__in LPCWSTR lpFileName, __in ULONG const flags) = 0; 44 | 45 | /* Close file 46 | @return: HRESULT on success, or other value on failure. 47 | */ 48 | 49 | virtual HRESULT WINAPI Close(void) = 0; 50 | /* Close and re-create or re-open file OR set file handle to existing handle and new flags. 51 | @handle: new file handle 52 | @flags: The file attributes and flags. 53 | @return: HRESULT on success, or other value on failure. 54 | */ 55 | virtual HRESULT WINAPI ReCreate(__in_opt void* handle = NULL, __in_opt ULONG const flags = 0) = 0; 56 | 57 | /* Get current opened file handle 58 | @fileHandle: a pointer to a variable storing file handle. 59 | @return: HRESULT on success, or other value on failure. 60 | */ 61 | virtual HRESULT WINAPI GetHandle(__out LPVOID * fileHandle) = 0; 62 | 63 | /* Get object type 64 | @fsType: a pointer to a variable storing type. Type is one of these values: 65 | basic: basic file system 66 | archive: archive file system 67 | @return: HRESULT on success, or other value on failure. 68 | */ 69 | virtual HRESULT WINAPI GetFsType(__out ULONG * fsType) = 0; 70 | 71 | /* Check whether file was already opened 72 | @isOpened: a pointer to a variable storing result. 73 | @return: HRESULT on success, or other value on failure. 74 | */ 75 | virtual HRESULT WINAPI IsOpened(__out BOOL *isOpened) = 0; 76 | 77 | /* Retrieve the last-error code value. 78 | @return: return value is the last-error code. 79 | */ 80 | virtual ULONG WINAPI GetError(void) = 0; 81 | 82 | /* Sets the last-error code. 83 | @return: This function does not return a value. 84 | */ 85 | virtual void WINAPI SetError(__in const ULONG error) = 0; 86 | 87 | /* Retrieve the flags of file object. 88 | @flags: a pointer to a variable storing result. 89 | @return: HRESULT on success, or other value on failure. 90 | */ 91 | virtual HRESULT WINAPI GetFlags(__out ULONG *flags) = 0; 92 | 93 | /* Retrieve fully qualified name of file. 94 | @fullPath: a pointer to a pointer to store file name. 95 | @return: HRESULT on success, or other value on failure. 96 | */ 97 | virtual HRESULT WINAPI GetFullPath(__out BSTR *fullPath) = 0; 98 | 99 | /* Retrieve file name 100 | @fullPath: a pointer to a pointer to store file name. 101 | @return: HRESULT on success, or other value on failure. 102 | */ 103 | virtual HRESULT WINAPI GetFileName(__out BSTR *fileName) = 0; 104 | 105 | /* Retrieve file extension 106 | @fullPath: a pointer to a pointer to store extension. 107 | @return: HRESULT on success, or other value on failure. 108 | */ 109 | virtual HRESULT WINAPI GetFileExt(__out BSTR *fileExt) = 0; 110 | 111 | /* Retrieve container object 112 | @container: a pointer to a pointer to store container object. 113 | @return: HRESULT on success, or other value on failure. 114 | */ 115 | virtual HRESULT WINAPI GetContainer(__out IVirtualFs **container) = 0; 116 | 117 | /* Set container object 118 | @container: a pointer to a container object. 119 | @return: HRESULT on success, or other value on failure. 120 | */ 121 | virtual HRESULT WINAPI SetContainer(__in IVirtualFs *container) = 0; 122 | 123 | /* Delete current file 124 | @return: HRESULT on success, or other value on failure. 125 | */ 126 | virtual HRESULT WINAPI DeferredDelete(void) = 0; 127 | 128 | END_INTERFACE 129 | }; 130 | 131 | -------------------------------------------------------------------------------- /include/Emulator/Emulator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../TinyAvBase.h" 3 | #include "../FileType/PEFile.h" 4 | 5 | MIDL_INTERFACE("D5B16D11-F05D-4F5A-90CD-849EC0AE4049") 6 | IEmulObserver: public IUnknown 7 | { 8 | public: 9 | 10 | enum EmulErrorCode 11 | { 12 | EmulatorErr = EMULATOR_ERROR_CODE_BASE, 13 | EmulatorIsNotFound, 14 | EmulatorIsNotRunable, 15 | EmulatorInternalError 16 | }; 17 | 18 | BEGIN_INTERFACE 19 | 20 | // Method is called when emulator starts 21 | virtual HRESULT WINAPI OnEmulatorStarting(void) = 0; 22 | 23 | // Method is called when emulator stops 24 | virtual HRESULT WINAPI OnEmulatorStopped(void) = 0; 25 | 26 | // method is called when an error occurred. 27 | virtual void WINAPI OnError(__in DWORD const dwErrorCode) = 0; 28 | END_INTERFACE 29 | }; 30 | 31 | // IEmulator interface 32 | MIDL_INTERFACE("D6C8BC2A-2F66-4DEC-9E63-8A4DF52BE7DF") 33 | IEmulator: public IUnknown 34 | { 35 | public: 36 | enum EmulateOrigin 37 | { 38 | FromImageBase = 1, 39 | FromEntryPoint, 40 | }; 41 | 42 | BEGIN_INTERFACE 43 | 44 | /* Read register value 45 | 46 | @reg: register ID that is to be retrieved. 47 | @regValue: pointer to a variable storing the register value. 48 | 49 | @return: HRESULT on success, or other value on failure. 50 | */ 51 | virtual HRESULT WINAPI ReadRegister(__in DWORD const reg, __out DWORD_PTR *regValue) = 0; 52 | 53 | /* Write register value 54 | 55 | @reg: register ID that is to be retrieved. 56 | @regValue: variable storing the register value to write. 57 | 58 | @return: HRESULT on success, or other value on failure. 59 | */ 60 | virtual HRESULT WINAPI WriteRegister(__in DWORD const reg, __out DWORD_PTR const regValue) = 0; 61 | 62 | /* 63 | Read a range of bytes in memory. 64 | 65 | @memoryAddr: starting memory address of bytes to get. 66 | @lpBuffer: pointer to a variable containing data copied from memory. 67 | @nNumberOfBytesToRead: size of memory to read. 68 | 69 | @return: HRESULT on success, or other value on failure. 70 | */ 71 | virtual HRESULT WINAPI ReadMemory(__in DWORD_PTR memoryAddr, __out_bcount(nNumberOfBytesToRead) LPVOID lpBuffer, __in DWORD nNumberOfBytesToRead) = 0; 72 | 73 | /* 74 | Write to a range of bytes in memory. 75 | 76 | @memoryAddr: starting memory address of bytes to set. 77 | @lpBuffer: pointer to a variable containing data to be written to memory. 78 | @nNumberOfBytesToWrite: size of memory to write to. 79 | 80 | @return: HRESULT on success, or other value on failure. 81 | */ 82 | virtual HRESULT WINAPI WriteMemory(__in DWORD_PTR memoryAddr, __out_bcount(nNumberOfBytesToWrite) LPVOID lpBuffer, __in DWORD nNumberOfBytesToWrite) = 0; 83 | 84 | /* 85 | Stop emulation 86 | @return: HRESULT on success, or other value on failure. 87 | */ 88 | virtual HRESULT WINAPI StopEmulator(void) = 0; 89 | 90 | /* 91 | Emulate machine code. 92 | 93 | @lpCodeBuffer: pointer to a variable containing data to be emulated. 94 | @nSizeOfCode: size of memory to emulate. 95 | @memoryMappedAddr: address where machine code is mapped. 96 | @nSizeOfStackCommit: size of the stack in bytes. 97 | @nSizeOfStackReserve: total stack allocation in mapped memory. 98 | @addressToStart: address where emulation starts. 99 | @nNumberOfBytesToEmulate: the number of instructions to be emulated. When this value is 0, 100 | we will emulate all the code available, until the code is finished. 101 | 102 | @return: HRESULT on success, or other value on failure. 103 | */ 104 | virtual HRESULT WINAPI EmulateCode(__in_bcount(nSizeOfCode) LPBYTE lpCodeBuffer, __in DWORD nSizeOfCode, 105 | __in DWORD_PTR memoryMappedAddr, __in DWORD nSizeOfStackCommit, __in DWORD nSizeOfStackReserve, 106 | __in DWORD_PTR addressToStart, __in DWORD nNumberOfBytesToEmulate) = 0; 107 | 108 | /* 109 | Emulate PE file. 110 | 111 | @peFile: pointer to IPeFile object. 112 | @rvaToStart: address where emulation starts. 113 | @origin: Position used as reference for the rvaToStart. It is specified by one of the following constants 114 | FromImageBase: Beginning of image 115 | FromEntryPoint: from Address of entry point 116 | @nNumberOfBytesToEmulate: the number of instructions to be emulated. When this value is 0, 117 | we will emulate all the code available, until the code is finished. 118 | 119 | @return: HRESULT on success, or other value on failure. 120 | */ 121 | virtual HRESULT WINAPI EmulatePeFile(__in IPeFile *peFile, __in DWORD_PTR rvaToStart, __in int origin, __in DWORD nNumberOfBytesToEmulate = 0) = 0; 122 | 123 | //virtual HRESULT WINAPI EmulatePe64File(__in IPe64File *peFile, __in DWORD_PTR rvaToStart, __in int origin, __in DWORD nNumberOfBytesToEmulate = 0) = 0; 124 | 125 | /* 126 | Add an emulator Observer 127 | @observer: a pointer to IEmulObserver object 128 | @return: HRESULT on success, or other value on failure. 129 | */ 130 | virtual HRESULT WINAPI AddObserver(__in IEmulObserver *observer) = 0; 131 | 132 | /* 133 | Remove an emulator Observer 134 | @observer: a pointer to IEmulObserver object 135 | @return: HRESULT on success, or other value on failure. 136 | */ 137 | virtual HRESULT WINAPI RemoveObserver(__in IEmulObserver *observer) = 0; 138 | 139 | /* 140 | Register callback for a hook event. 141 | The callback will be run when the hook event is hit. 142 | 143 | @hookHandle: hook handle returned from this registration. To be used in uc_hook_del() API 144 | @type: hook type 145 | @callback: callback to be run when instruction is hit 146 | @user_data: user-defined data. This will be passed to callback function in its 147 | last argument @user_data 148 | @...: variable arguments (depending on @type) 149 | 150 | @return: HRESULT on success, or other value on failure. 151 | */ 152 | virtual HRESULT __cdecl AddHook(__out void *hookHandle, __in int type, __in void * callback, __in void *user_data, ...) = 0; 153 | 154 | /* 155 | Unregister (remove) a hook callback. 156 | This API removes the hook callback registered by AddHook() 157 | 158 | @hookHandle: handle returned by uc_hook_add() 159 | 160 | @return: HRESULT on success, or other value on failure. 161 | */ 162 | virtual HRESULT WINAPI RemoveHook(__in size_t hookHandle) = 0; 163 | 164 | END_INTERFACE 165 | }; -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/zip/UnzipHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "UnzipHelper.h" 2 | 3 | #ifdef _DEBUG 4 | #pragma comment(lib, "zlibstaticd.lib") 5 | #else 6 | #pragma comment(lib, "zlibstatic.lib") 7 | #endif // _DEBUG 8 | 9 | static void TranslateOpenMode(__in int mode, __out ULONG *creationMode) 10 | { 11 | *creationMode = 0; 12 | 13 | if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) 14 | { 15 | *creationMode = IVirtualFs::fsRead | IVirtualFs::fsOpenExisting | IVirtualFs::fsSharedRead | IVirtualFs::fsAttrNormal; 16 | } 17 | else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 18 | { 19 | *creationMode = IVirtualFs::fsRead | IVirtualFs::fsWrite | IVirtualFs::fsSharedRead | IVirtualFs::fsOpenExisting | IVirtualFs::fsAttrNormal; 20 | } 21 | else if (mode & ZLIB_FILEFUNC_MODE_CREATE) 22 | { 23 | *creationMode = IVirtualFs::fsRead | IVirtualFs::fsWrite | IVirtualFs::fsSharedRead | IVirtualFs::fsCreateAlways | IVirtualFs::fsAttrNormal; 24 | } 25 | } 26 | 27 | voidpf ZCALLBACK UHOpen(voidpf opaque, const char* filename, int mode) 28 | { 29 | return UHOpen64(opaque, (const void*)filename, mode); 30 | } 31 | 32 | uLong ZCALLBACK UHRead(voidpf opaque, voidpf stream, void* buf, uLong size) 33 | { 34 | UNREFERENCED_PARAMETER(opaque); 35 | uLong readSize = 0; 36 | 37 | IFsStream* fileStream = static_cast(stream); 38 | if (fileStream == NULL) return 0; 39 | 40 | if (!SUCCEEDED(fileStream->Read(buf, size, &readSize))) 41 | readSize = 0; 42 | 43 | return readSize; 44 | } 45 | 46 | uLong ZCALLBACK UHWrite(voidpf opaque, voidpf stream, const void* buf, uLong size) 47 | { 48 | UNREFERENCED_PARAMETER(opaque); 49 | uLong writtenSize = 0; 50 | IFsStream* fileStream = static_cast(stream); 51 | if (fileStream == NULL) return 0; 52 | if (!SUCCEEDED(fileStream->Write(buf, size, &writtenSize))) 53 | writtenSize = 0; 54 | return writtenSize; 55 | } 56 | 57 | long ZCALLBACK UHTell(voidpf opaque, voidpf stream) 58 | { 59 | return (long)UHTell64(opaque, stream); 60 | } 61 | 62 | long ZCALLBACK UHSeek(voidpf opaque, voidpf stream, uLong offset, int origin) 63 | { 64 | return UHSeek64(opaque, stream, (ZPOS64_T)offset, origin); 65 | } 66 | 67 | int ZCALLBACK UHClose(voidpf opaque, voidpf stream) 68 | { 69 | UNREFERENCED_PARAMETER(opaque); 70 | int ret = -1; 71 | IVirtualFs * file = static_cast(opaque); 72 | if (file == NULL) return 0; 73 | ret = (SUCCEEDED(file->Close())) ? 0 : -1; 74 | IFsStream* fileStream = static_cast(stream); 75 | if (fileStream) fileStream->Release(); 76 | file->Release(); 77 | return ret; 78 | } 79 | 80 | int ZCALLBACK UHError(voidpf opaque, voidpf stream) 81 | { 82 | UNREFERENCED_PARAMETER(stream); 83 | IVirtualFs * file = static_cast(opaque); 84 | if (file == NULL) return -1; 85 | return (int)file->GetError(); 86 | } 87 | 88 | voidpf ZCALLBACK UHOpen64(voidpf opaque, const void* filename, int mode) 89 | { 90 | UNREFERENCED_PARAMETER(filename); 91 | ULONG creationMode = IVirtualFs::fsRead | IVirtualFs::fsSharedRead | IVirtualFs::fsOpenExisting | IVirtualFs::fsAttrNormal; 92 | voidpf zipHandle = NULL; 93 | TranslateOpenMode(mode, &creationMode); 94 | 95 | IVirtualFs * file = static_cast(opaque); 96 | if (file == NULL) return zipHandle; 97 | 98 | ULONG fsType = 0; 99 | 100 | HRESULT hr = E_FAIL; 101 | if (SUCCEEDED(file->GetFsType(&fsType)) && fsType == IVirtualFs::archive) 102 | { 103 | void* handle; 104 | hr = file->GetHandle((LPVOID*)&handle); 105 | if (SUCCEEDED(hr)) 106 | hr = file->ReCreate(handle, creationMode); 107 | } 108 | else 109 | { 110 | hr = file->ReCreate(NULL, creationMode); 111 | } 112 | 113 | if (SUCCEEDED(hr)) 114 | { 115 | IFsStream* fileStream = NULL; 116 | if (SUCCEEDED(file->QueryInterface(__uuidof(IFsStream), (LPVOID*)&fileStream))) 117 | { 118 | file->AddRef(); 119 | zipHandle = (voidpf)fileStream; 120 | } 121 | } 122 | 123 | return zipHandle; 124 | } 125 | 126 | ZPOS64_T ZCALLBACK UHTell64(voidpf opaque, voidpf stream) 127 | { 128 | UNREFERENCED_PARAMETER(opaque); 129 | ULARGE_INTEGER pos = {}; 130 | IFsStream* fileStream = static_cast(stream); 131 | if (fileStream == NULL) return 0; 132 | if (SUCCEEDED(fileStream->Tell(&pos))) 133 | return pos.QuadPart; 134 | return 0; 135 | } 136 | 137 | long ZCALLBACK UHSeek64(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) 138 | { 139 | UNREFERENCED_PARAMETER(opaque); 140 | ULARGE_INTEGER pos = {}; 141 | LARGE_INTEGER distanceToMove = {}; 142 | long ret = -1; 143 | 144 | IFsStream::FsStreamSeek dwMoveMethod; 145 | 146 | switch (origin) 147 | { 148 | case ZLIB_FILEFUNC_SEEK_CUR: 149 | dwMoveMethod = IFsStream::FsStreamCurrent; 150 | break; 151 | case ZLIB_FILEFUNC_SEEK_END: 152 | dwMoveMethod = IFsStream::FsStreamEnd; 153 | break; 154 | case ZLIB_FILEFUNC_SEEK_SET: 155 | dwMoveMethod = IFsStream::FsStreamBegin; 156 | break; 157 | default: 158 | return -1; 159 | } 160 | 161 | distanceToMove.QuadPart = offset; 162 | 163 | IFsStream* fileStream = static_cast(stream); 164 | if (fileStream == NULL) return 0; 165 | HRESULT hr = fileStream->Seek(&pos, distanceToMove, dwMoveMethod); 166 | if (SUCCEEDED(hr)) 167 | ret = 0; 168 | else 169 | { 170 | IVirtualFs * file = static_cast(stream); 171 | if (file) file->SetError((ULONG)(hr & 0xffff)); 172 | ret = (long)hr; 173 | } 174 | 175 | return ret; 176 | } 177 | 178 | void FillFunctions64(__in voidpf opaque, __out zlib_filefunc64_def* pzlib_filefunc_def) 179 | { 180 | pzlib_filefunc_def->zopen64_file = UHOpen64; 181 | pzlib_filefunc_def->zread_file = UHRead; 182 | pzlib_filefunc_def->zwrite_file = UHWrite; 183 | pzlib_filefunc_def->ztell64_file = UHTell64; 184 | pzlib_filefunc_def->zseek64_file = UHSeek64; 185 | pzlib_filefunc_def->zclose_file = UHClose; 186 | pzlib_filefunc_def->zerror_file = UHError; 187 | pzlib_filefunc_def->opaque = opaque; 188 | } 189 | 190 | void FillFunctions(__in voidpf opaque, __out zlib_filefunc_def* pzlib_filefunc_def) 191 | { 192 | pzlib_filefunc_def->zopen_file = UHOpen; 193 | pzlib_filefunc_def->zread_file = UHRead; 194 | pzlib_filefunc_def->zwrite_file = UHWrite; 195 | pzlib_filefunc_def->ztell_file = UHTell; 196 | pzlib_filefunc_def->zseek_file = UHSeek; 197 | pzlib_filefunc_def->zclose_file = UHClose; 198 | pzlib_filefunc_def->zerror_file = UHError; 199 | pzlib_filefunc_def->opaque = opaque; 200 | } 201 | -------------------------------------------------------------------------------- /TinyAvCore/FileSystem/FileFsStream.cpp: -------------------------------------------------------------------------------- 1 | #include "FileFsStream.h" 2 | 3 | CFileFsStream::CFileFsStream() 4 | { 5 | m_hFile = INVALID_HANDLE_VALUE; 6 | ZeroMemory(&m_currentPos, sizeof(m_currentPos)); 7 | m_cacheSize = 0; 8 | m_cache = new char[DEFAULT_MAX_CACHE_SIZE]; 9 | ZeroMemory(&m_cachePos, sizeof(m_cachePos)); 10 | } 11 | 12 | CFileFsStream::~CFileFsStream() 13 | { 14 | if (m_cache) 15 | { 16 | delete[] m_cache; 17 | m_cache = NULL; 18 | } 19 | } 20 | 21 | HRESULT WINAPI CFileFsStream::QueryInterface( 22 | __in REFIID riid, 23 | __out _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) 24 | { 25 | if (ppvObject == NULL) return E_INVALIDARG; 26 | 27 | if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, __uuidof(IFsStream))) 28 | { 29 | *ppvObject = static_cast(this); 30 | AddRef(); 31 | return S_OK; 32 | } 33 | 34 | return E_NOINTERFACE; 35 | } 36 | 37 | HRESULT WINAPI CFileFsStream::Read( 38 | __out_bcount(bufferSize) LPVOID buffer, 39 | __in ULONG bufferSize, 40 | __out_opt ULONG * readSize) 41 | { 42 | ULONG r; 43 | if (m_hFile == INVALID_HANDLE_VALUE) return E_NOT_SET; 44 | if (buffer == NULL || bufferSize == 0) return E_INVALIDARG; 45 | 46 | if ((m_cachePos.QuadPart <= m_currentPos.QuadPart) && 47 | (m_currentPos.QuadPart + bufferSize < m_cachePos.QuadPart + m_cacheSize)) 48 | { 49 | memcpy(buffer, &m_cache[m_currentPos.QuadPart - m_cachePos.QuadPart], bufferSize); 50 | m_currentPos.QuadPart += bufferSize; 51 | LARGE_INTEGER distanceToMove; 52 | distanceToMove.QuadPart = m_currentPos.QuadPart; 53 | if (readSize) *readSize = bufferSize; 54 | 55 | if (FALSE == SetFilePointerEx(m_hFile, distanceToMove, (PLARGE_INTEGER)NULL, FILE_BEGIN)) 56 | { 57 | return HRESULT_FROM_WIN32(GetLastError()); 58 | } 59 | } 60 | else 61 | { 62 | if (!ReadFile(m_hFile, buffer, bufferSize, &r, NULL)) 63 | { 64 | return HRESULT_FROM_WIN32(GetLastError()); 65 | } 66 | 67 | if (r) 68 | { 69 | m_cacheSize = r < DEFAULT_MAX_CACHE_SIZE ? r : DEFAULT_MAX_CACHE_SIZE; 70 | memcpy(m_cache, buffer, m_cacheSize); 71 | } 72 | 73 | m_cachePos.QuadPart = m_currentPos.QuadPart; 74 | m_currentPos.QuadPart += r; 75 | 76 | if (readSize) *readSize = r; 77 | } 78 | 79 | return S_OK; 80 | } 81 | 82 | HRESULT WINAPI CFileFsStream::ReadAt( 83 | __in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, 84 | __out_bcount(bufferSize) LPVOID buffer, __in ULONG bufferSize, __out_opt ULONG * readSize) 85 | { 86 | HRESULT hr = Seek(NULL, offset, moveMethod); 87 | if (FAILED(hr)) return hr; 88 | return Read(buffer, bufferSize, readSize); 89 | } 90 | 91 | HRESULT WINAPI CFileFsStream::Write( 92 | __in_bcount(bufferSize) LPCVOID buffer, 93 | __in ULONG bufferSize, 94 | __out_opt ULONG * writtenSize) 95 | { 96 | ULONG w; 97 | if (m_hFile == INVALID_HANDLE_VALUE) return E_NOT_SET; 98 | if (buffer == NULL || bufferSize == 0) return E_INVALIDARG; 99 | 100 | // write to disk 101 | if (!WriteFile(m_hFile, buffer, bufferSize, &w, NULL)) 102 | { 103 | return HRESULT_FROM_WIN32(GetLastError()); 104 | } 105 | 106 | // update cache 107 | if ((m_cachePos.QuadPart < m_currentPos.QuadPart) && 108 | (m_currentPos.QuadPart + w < m_cachePos.QuadPart + m_cacheSize)) 109 | { 110 | memcpy(&m_cache[m_currentPos.QuadPart - m_cachePos.QuadPart], buffer, w); 111 | m_currentPos.QuadPart += w; 112 | } 113 | else 114 | { 115 | m_cacheSize = w < DEFAULT_MAX_CACHE_SIZE ? w : DEFAULT_MAX_CACHE_SIZE; 116 | memcpy(m_cache, buffer, m_cacheSize); 117 | m_cachePos.QuadPart = m_currentPos.QuadPart; 118 | m_currentPos.QuadPart += w; 119 | } 120 | 121 | if (writtenSize) *writtenSize = w; 122 | return S_OK; 123 | } 124 | 125 | HRESULT WINAPI CFileFsStream::WriteAt(__in LARGE_INTEGER const offset, __in const FsStreamSeek moveMethod, __in_bcount(bufferSize) LPCVOID buffer, __in ULONG bufferSize, __out_opt ULONG * writtenSize) 126 | { 127 | HRESULT hr = Seek(NULL, offset, moveMethod); 128 | if (FAILED(hr)) return hr; 129 | return Write(buffer, bufferSize, writtenSize); 130 | } 131 | 132 | HRESULT WINAPI CFileFsStream::Tell(__out ULARGE_INTEGER * pos) 133 | { 134 | if (m_hFile == INVALID_HANDLE_VALUE) return E_NOT_SET; 135 | if (pos == NULL) return E_INVALIDARG; 136 | 137 | *pos = m_currentPos; 138 | return S_OK; 139 | } 140 | 141 | HRESULT WINAPI CFileFsStream::Seek( 142 | __out_opt ULARGE_INTEGER * pos, 143 | __in LARGE_INTEGER const distanceToMove, 144 | __in const FsStreamSeek MoveMethod) 145 | { 146 | if (m_hFile == INVALID_HANDLE_VALUE) return E_NOT_SET; 147 | DWORD dwMoveMethod = 0; 148 | switch (MoveMethod) 149 | { 150 | case IFsStream::FsStreamBegin: 151 | dwMoveMethod = FILE_BEGIN; 152 | break; 153 | 154 | case IFsStream::FsStreamCurrent: 155 | dwMoveMethod = FILE_CURRENT; 156 | break; 157 | 158 | case IFsStream::FsStreamEnd: 159 | dwMoveMethod = FILE_END; 160 | break; 161 | 162 | default: 163 | return E_INVALIDARG; 164 | } 165 | 166 | HRESULT hr = S_OK; 167 | if (FALSE == SetFilePointerEx(m_hFile, distanceToMove, (PLARGE_INTEGER)&m_currentPos, dwMoveMethod)) 168 | { 169 | hr = HRESULT_FROM_WIN32(GetLastError()); 170 | } 171 | 172 | if (SUCCEEDED(hr)) 173 | { 174 | if (pos) *pos = m_currentPos; 175 | if (m_cachePos.QuadPart > m_currentPos.QuadPart || 176 | m_cachePos.QuadPart + m_cacheSize < m_currentPos.QuadPart) 177 | { 178 | m_cacheSize = 0; 179 | } 180 | } 181 | return hr; 182 | } 183 | 184 | void WINAPI CFileFsStream::SetFileHandle(__in void* const handle) 185 | { 186 | m_hFile = (HANDLE)handle; 187 | if (m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE) 188 | { 189 | // Init cache 190 | SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN); 191 | DWORD r; 192 | if (ReadFile(m_hFile, m_cache, DEFAULT_MAX_CACHE_SIZE, &r, NULL) && r > 0) 193 | { 194 | m_cacheSize = (size_t)r; 195 | } 196 | ZeroMemory(&m_cachePos, sizeof(m_cachePos)); 197 | SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN); 198 | } 199 | } 200 | 201 | HRESULT WINAPI CFileFsStream::Shrink(void) 202 | { 203 | if (m_hFile == NULL || m_hFile == INVALID_HANDLE_VALUE) return E_NOT_VALID_STATE; 204 | if (!SetEndOfFile(m_hFile)) 205 | return HRESULT_FROM_WIN32(GetLastError()); 206 | 207 | if ((m_cachePos.QuadPart <= m_currentPos.QuadPart) && 208 | (m_currentPos.QuadPart < m_cachePos.QuadPart + m_cacheSize)) 209 | m_cacheSize = (size_t)(m_currentPos.QuadPart - m_cachePos.QuadPart); 210 | else 211 | m_cacheSize = 0; 212 | return S_OK; 213 | } 214 | -------------------------------------------------------------------------------- /TinyAvConsole/getopt.c: -------------------------------------------------------------------------------- 1 | #include "getopt.h" // make sure you construct the header file as dictated above 2 | 3 | /* 4 | * Copyright (c) 1987, 1993, 1994 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgment: 17 | * This product includes software developed by the University of 18 | * California, Berkeley and its contributors. 19 | * 4. Neither the name of the University nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | int opterr = 1, /* if error message should be printed */ 40 | optind = 1, /* index into parent argv vector */ 41 | optopt, /* character checked for validity */ 42 | optreset; /* reset getopt */ 43 | char *optarg; /* argument associated with option */ 44 | wchar_t *optarg_w; /* argument associated with option */ 45 | 46 | #define BADCH (int)'?' 47 | #define BADARG (int)':' 48 | #define EMSG "" 49 | #define MINUS (int)'-' 50 | /* 51 | * getopt -- 52 | * Parse argc/argv argument vector. 53 | */ 54 | int getopt(int nargc, char * const nargv[], const char *ostr) 55 | { 56 | static char *place = EMSG; /* option letter processing */ 57 | const char *oli; /* option letter list index */ 58 | 59 | if (optreset || !*place) { /* update scanning pointer */ 60 | optreset = 0; 61 | if (optind >= nargc || *(place = nargv[optind]) != MINUS) { 62 | place = EMSG; 63 | return (-1); 64 | } 65 | if (place[1] && *++place == MINUS) { /* found "--" */ 66 | ++optind; 67 | place = EMSG; 68 | return (-1); 69 | } 70 | } /* option letter okay? */ 71 | if ((optopt = (int)*place++) == BADARG || 72 | !(oli = strchr(ostr, optopt))) { 73 | /* 74 | * if the user didn't specify '-' as an option, 75 | * assume it means -1. 76 | */ 77 | if (optopt == MINUS) 78 | return (-1); 79 | if (!*place) 80 | ++optind; 81 | if (opterr && *ostr != BADARG) 82 | (void)printf("illegal option -- %c\n", optopt); 83 | return (BADCH); 84 | } 85 | if (*++oli != BADARG) { /* don't need argument */ 86 | optarg = NULL; 87 | if (!*place) 88 | ++optind; 89 | } 90 | else { /* need an argument */ 91 | if (*place) /* no white space */ 92 | optarg = place; 93 | else if (nargc <= ++optind) { /* no arg */ 94 | place = EMSG; 95 | if (*ostr == BADARG) 96 | return (BADARG); 97 | if (opterr) 98 | (void)printf("option requires an argument -- %c\n", optopt); 99 | return (BADCH); 100 | } 101 | else /* white space */ 102 | optarg = nargv[optind]; 103 | place = EMSG; 104 | ++optind; 105 | } 106 | return (optopt); /* dump back option letter */ 107 | } 108 | 109 | 110 | #define BADCH_W (int)L'?' 111 | #define BADARG_W (int)L':' 112 | #define EMSG_W L"" 113 | #define MINUS_W (int)L'-' 114 | /* 115 | * getopt -- 116 | * Parse argc/argv argument vector. 117 | */ 118 | int getopt_w(int nargc, wchar_t * const nargv[], const wchar_t *ostr) 119 | { 120 | static wchar_t *place = EMSG_W; /* option letter processing */ 121 | const wchar_t *oli; /* option letter list index */ 122 | 123 | if (optreset || !*place) { /* update scanning pointer */ 124 | optreset = 0; 125 | if (optind >= nargc || *(place = nargv[optind]) != MINUS_W) { 126 | place = EMSG_W; 127 | return (-1); 128 | } 129 | if (place[1] && *++place == MINUS_W) { /* found "--" */ 130 | ++optind; 131 | place = EMSG_W; 132 | return (-1); 133 | } 134 | } /* option letter okay? */ 135 | if ((optopt = (int)*place++) == BADARG_W || 136 | !(oli = wcschr(ostr, optopt))) { 137 | /* 138 | * if the user didn't specify '-' as an option, 139 | * assume it means -1. 140 | */ 141 | if (optopt == MINUS_W) 142 | return (-1); 143 | if (!*place) 144 | ++optind; 145 | if (opterr && *ostr != BADARG_W) 146 | (void)wprintf(L"illegal option -- %c\n", optopt); 147 | return (BADCH_W); 148 | } 149 | if (*++oli != BADARG_W) { /* don't need argument */ 150 | optarg_w = NULL; 151 | if (!*place) 152 | ++optind; 153 | } 154 | else { /* need an argument */ 155 | if (*place) /* no white space */ 156 | optarg_w = place; 157 | else if (nargc <= ++optind) { /* no arg */ 158 | place = EMSG_W; 159 | if (*ostr == BADARG_W) 160 | return (BADARG_W); 161 | if (opterr) 162 | (void)wprintf(L"option requires an argument -- %c\n", optopt); 163 | return (BADCH_W); 164 | } 165 | else /* white space */ 166 | optarg_w = nargv[optind]; 167 | place = EMSG_W; 168 | ++optind; 169 | } 170 | return (optopt); /* dump back option letter */ 171 | } 172 | -------------------------------------------------------------------------------- /tests/Unittests/FileFsStream_unittest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../TinyAvCore/FileSystem/FileFsStream.h" 5 | 6 | extern WCHAR szTestcase[MAX_PATH]; 7 | 8 | TEST(FileFsStream, Seek) 9 | { 10 | HANDLE hFile = CreateFileW(szTestcase, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 11 | ASSERT_NE(INVALID_HANDLE_VALUE, hFile); 12 | IFsStream * fsStream; 13 | ULARGE_INTEGER pos; 14 | fsStream = new CFileFsStream(); 15 | fsStream->SetFileHandle((void*)hFile); 16 | LARGE_INTEGER offset = {}; 17 | offset.QuadPart = 200; 18 | ASSERT_HRESULT_SUCCEEDED(fsStream->Seek(&pos, offset, IFsStream::FsStreamBegin)); 19 | ASSERT_EQ(200, pos.QuadPart); 20 | offset.QuadPart = 200; 21 | ASSERT_HRESULT_SUCCEEDED(fsStream->Seek(&pos, offset, IFsStream::FsStreamCurrent)); 22 | ASSERT_EQ(400, pos.QuadPart); 23 | offset.LowPart = -100; 24 | offset.HighPart = -1; 25 | ASSERT_HRESULT_SUCCEEDED(fsStream->Seek(&pos, offset, IFsStream::FsStreamCurrent)); 26 | ASSERT_EQ(300, pos.QuadPart); 27 | ASSERT_HRESULT_SUCCEEDED(fsStream->Tell(&pos)); 28 | ASSERT_EQ(300, pos.QuadPart); 29 | offset.LowPart = -1; 30 | offset.HighPart = -1; 31 | ASSERT_HRESULT_SUCCEEDED(fsStream->Seek(&pos, offset, IFsStream::FsStreamEnd)); 32 | ASSERT_EQ(0x100000 + offset.QuadPart, pos.QuadPart); 33 | CloseHandle(hFile); 34 | fsStream->Release(); 35 | } 36 | 37 | TEST(FileFsStream, Tell) 38 | { 39 | HANDLE hFile = CreateFileW(szTestcase, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 40 | ASSERT_NE(INVALID_HANDLE_VALUE, hFile); 41 | IFsStream * fsStream; 42 | fsStream = new CFileFsStream(); 43 | fsStream->SetFileHandle((void*)hFile); 44 | LARGE_INTEGER distanceToMove = {}; 45 | distanceToMove.QuadPart = 200; 46 | ULARGE_INTEGER pos; 47 | ASSERT_HRESULT_SUCCEEDED(fsStream->Seek(&pos, distanceToMove, IFsStream::FsStreamBegin)); 48 | ASSERT_EQ(200, pos.QuadPart); 49 | ASSERT_HRESULT_SUCCEEDED(fsStream->Tell(&pos)); 50 | ASSERT_EQ(200, pos.QuadPart); 51 | ASSERT_HRESULT_SUCCEEDED(fsStream->Seek(&pos, distanceToMove, IFsStream::FsStreamCurrent)); 52 | ASSERT_EQ(400, pos.QuadPart); 53 | distanceToMove.QuadPart = -100; 54 | ASSERT_HRESULT_SUCCEEDED(fsStream->Seek(&pos, distanceToMove, IFsStream::FsStreamCurrent)); 55 | ASSERT_EQ(300, pos.QuadPart); 56 | ASSERT_HRESULT_SUCCEEDED(fsStream->Seek(&pos, distanceToMove, IFsStream::FsStreamEnd)); 57 | ASSERT_EQ(0x100000 + distanceToMove.QuadPart, pos.QuadPart); 58 | CloseHandle(hFile); 59 | fsStream->Release(); 60 | } 61 | 62 | TEST(FileFsStream, ReadAt) 63 | { 64 | HANDLE hFile = CreateFileW(szTestcase, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 65 | ASSERT_NE(INVALID_HANDLE_VALUE, hFile); 66 | IFsStream * fsStream; 67 | fsStream = new CFileFsStream(); 68 | fsStream->SetFileHandle((void*)hFile); 69 | 70 | char buffer[0x400]; 71 | ULONG readSize; 72 | 73 | unsigned char testcase1[0x40] = { 74 | 0x8D, 0x5C, 0x8D, 0xEB, 0x5D, 0xDE, 0x4B, 0xA6, 0xE1, 0x9E, 0xC3, 0x82, 0xB2, 0x93, 0x17, 0x55, 75 | 0xA1, 0xC6, 0x57, 0xD1, 0xC3, 0x57, 0x14, 0x81, 0x5F, 0x27, 0x2D, 0xDB, 0xEF, 0x1E, 0xD4, 0xDE, 76 | 0xA3, 0x38, 0x77, 0x3F, 0x44, 0x85, 0xB5, 0x35, 0x14, 0x8E, 0x71, 0x2B, 0x01, 0x50, 0x6F, 0xBD, 77 | 0x7C, 0xD8, 0xB7, 0x12, 0x03, 0x43, 0xC7, 0x35, 0x47, 0x0B, 0x8B, 0x35, 0xB1, 0x70, 0xB6, 0xC2 78 | }; 79 | 80 | LARGE_INTEGER offset = {}; 81 | 82 | // read data in cache 83 | offset.QuadPart = 0; 84 | ASSERT_HRESULT_SUCCEEDED(fsStream->ReadAt(offset, IFsStream::FsStreamBegin, buffer, sizeof(testcase1), &readSize)); 85 | ASSERT_EQ(sizeof(testcase1), readSize); 86 | ASSERT_TRUE(0 == memcmp(buffer, testcase1, sizeof(testcase1))); 87 | 88 | unsigned char testcase2[0x40] = { 89 | 0x77, 0x0A, 0xC8, 0x31, 0x90, 0x5E, 0xBB, 0x5D, 0x67, 0x14, 0x91, 0x40, 0x63, 0xFE, 0x10, 0x4F, 90 | 0xEC, 0x16, 0xDF, 0x1F, 0xBE, 0x98, 0x84, 0x3E, 0xB8, 0xB5, 0x16, 0x68, 0xEA, 0x14, 0xF8, 0x7E, 91 | 0x96, 0x17, 0x3C, 0x82, 0x86, 0x56, 0x80, 0xD2, 0x04, 0x2B, 0xCA, 0xEB, 0x84, 0xD1, 0x04, 0xB4, 92 | 0x93, 0xF4, 0x5F, 0xAF, 0xC1, 0xA2, 0x14, 0xDF, 0x85, 0x8A, 0x79, 0xDB, 0x47, 0x53, 0x73, 0x52 93 | }; 94 | 95 | // read data without cache + update cache 96 | offset.QuadPart = DEFAULT_MAX_CACHE_SIZE +0x10; 97 | ASSERT_HRESULT_SUCCEEDED(fsStream->ReadAt(offset, IFsStream::FsStreamBegin, buffer, sizeof(testcase2), &readSize)); 98 | ASSERT_EQ(sizeof(testcase2), readSize); 99 | ASSERT_TRUE(0 == memcmp(buffer, testcase2, sizeof(testcase2))); 100 | 101 | // cache hit! 102 | offset.QuadPart = DEFAULT_MAX_CACHE_SIZE + 0x20; 103 | ASSERT_HRESULT_SUCCEEDED(fsStream->ReadAt(offset, IFsStream::FsStreamBegin, buffer, 0x20, &readSize)); 104 | ASSERT_EQ(0x20, readSize); 105 | ASSERT_TRUE(0 == memcmp(buffer, testcase2 + 0x10, 0x20)); 106 | 107 | // cache not found 108 | offset.QuadPart = DEFAULT_MAX_CACHE_SIZE + 0x10; 109 | ASSERT_HRESULT_SUCCEEDED(fsStream->ReadAt(offset, IFsStream::FsStreamBegin, buffer, 0x60, &readSize)); 110 | ASSERT_EQ(0x60, readSize); 111 | ASSERT_TRUE(0 == memcmp(buffer, testcase2, sizeof(testcase2))); 112 | 113 | // cache not found, re-test testcase1 114 | offset.QuadPart = 0; 115 | ASSERT_HRESULT_SUCCEEDED(fsStream->ReadAt(offset, IFsStream::FsStreamBegin, buffer, sizeof(testcase1), &readSize)); 116 | ASSERT_EQ(sizeof(testcase1), readSize); 117 | ASSERT_TRUE(0 == memcmp(buffer, testcase1, sizeof(testcase1))); 118 | 119 | CloseHandle(hFile); 120 | fsStream->Release(); 121 | } 122 | 123 | TEST(FileFsStream, WriteAt) 124 | { 125 | HANDLE hFile = CreateFileW(szTestcase, GENERIC_WRITE| GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 126 | DWORD dw = GetLastError(); 127 | ASSERT_NE(INVALID_HANDLE_VALUE, hFile); 128 | IFsStream * fsStream; 129 | fsStream = new CFileFsStream(); 130 | fsStream->SetFileHandle((void*)hFile); 131 | LARGE_INTEGER offset = {}; 132 | ULARGE_INTEGER pos; 133 | ULONG size; 134 | unsigned char backup[10]; 135 | unsigned char buf[10]; 136 | 137 | offset.QuadPart = 0x200; 138 | ASSERT_HRESULT_SUCCEEDED(fsStream->ReadAt(offset, IFsStream::FsStreamBegin, backup, sizeof(backup), &size)); 139 | 140 | unsigned char testcase1[10] = { 141 | 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, 142 | }; 143 | offset.QuadPart = 0x200; 144 | ASSERT_HRESULT_SUCCEEDED(fsStream->WriteAt(offset, IFsStream::FsStreamBegin, testcase1, 10, &size)); 145 | ASSERT_EQ(10, size); 146 | ASSERT_HRESULT_SUCCEEDED(fsStream->Tell(&pos)); 147 | ASSERT_EQ(0x200 + 10, pos.QuadPart); 148 | offset.QuadPart = 0x200; 149 | ASSERT_HRESULT_SUCCEEDED(fsStream->ReadAt(offset, IFsStream::FsStreamBegin, buf, sizeof(buf), &size)); 150 | ASSERT_TRUE(0 == memcmp(buf, testcase1, sizeof(testcase1))); 151 | 152 | offset.QuadPart = 0x200; 153 | ASSERT_HRESULT_SUCCEEDED(fsStream->WriteAt(offset, IFsStream::FsStreamBegin, backup, sizeof(backup), &size)); 154 | ASSERT_EQ(10, size); 155 | 156 | CloseHandle(hFile); 157 | fsStream->Release(); 158 | } -------------------------------------------------------------------------------- /libs/include/unicorn/arm64.h: -------------------------------------------------------------------------------- 1 | #ifndef UNICORN_ARM64_H 2 | #define UNICORN_ARM64_H 3 | 4 | /* Unicorn Emulator Engine */ 5 | /* By Nguyen Anh Quynh , 2015 */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifdef _MSC_VER 12 | #pragma warning(disable:4201) 13 | #endif 14 | 15 | //> ARM64 registers 16 | typedef enum uc_arm64_reg { 17 | UC_ARM64_REG_INVALID = 0, 18 | 19 | UC_ARM64_REG_X29, 20 | UC_ARM64_REG_X30, 21 | UC_ARM64_REG_NZCV, 22 | UC_ARM64_REG_SP, 23 | UC_ARM64_REG_WSP, 24 | UC_ARM64_REG_WZR, 25 | UC_ARM64_REG_XZR, 26 | UC_ARM64_REG_B0, 27 | UC_ARM64_REG_B1, 28 | UC_ARM64_REG_B2, 29 | UC_ARM64_REG_B3, 30 | UC_ARM64_REG_B4, 31 | UC_ARM64_REG_B5, 32 | UC_ARM64_REG_B6, 33 | UC_ARM64_REG_B7, 34 | UC_ARM64_REG_B8, 35 | UC_ARM64_REG_B9, 36 | UC_ARM64_REG_B10, 37 | UC_ARM64_REG_B11, 38 | UC_ARM64_REG_B12, 39 | UC_ARM64_REG_B13, 40 | UC_ARM64_REG_B14, 41 | UC_ARM64_REG_B15, 42 | UC_ARM64_REG_B16, 43 | UC_ARM64_REG_B17, 44 | UC_ARM64_REG_B18, 45 | UC_ARM64_REG_B19, 46 | UC_ARM64_REG_B20, 47 | UC_ARM64_REG_B21, 48 | UC_ARM64_REG_B22, 49 | UC_ARM64_REG_B23, 50 | UC_ARM64_REG_B24, 51 | UC_ARM64_REG_B25, 52 | UC_ARM64_REG_B26, 53 | UC_ARM64_REG_B27, 54 | UC_ARM64_REG_B28, 55 | UC_ARM64_REG_B29, 56 | UC_ARM64_REG_B30, 57 | UC_ARM64_REG_B31, 58 | UC_ARM64_REG_D0, 59 | UC_ARM64_REG_D1, 60 | UC_ARM64_REG_D2, 61 | UC_ARM64_REG_D3, 62 | UC_ARM64_REG_D4, 63 | UC_ARM64_REG_D5, 64 | UC_ARM64_REG_D6, 65 | UC_ARM64_REG_D7, 66 | UC_ARM64_REG_D8, 67 | UC_ARM64_REG_D9, 68 | UC_ARM64_REG_D10, 69 | UC_ARM64_REG_D11, 70 | UC_ARM64_REG_D12, 71 | UC_ARM64_REG_D13, 72 | UC_ARM64_REG_D14, 73 | UC_ARM64_REG_D15, 74 | UC_ARM64_REG_D16, 75 | UC_ARM64_REG_D17, 76 | UC_ARM64_REG_D18, 77 | UC_ARM64_REG_D19, 78 | UC_ARM64_REG_D20, 79 | UC_ARM64_REG_D21, 80 | UC_ARM64_REG_D22, 81 | UC_ARM64_REG_D23, 82 | UC_ARM64_REG_D24, 83 | UC_ARM64_REG_D25, 84 | UC_ARM64_REG_D26, 85 | UC_ARM64_REG_D27, 86 | UC_ARM64_REG_D28, 87 | UC_ARM64_REG_D29, 88 | UC_ARM64_REG_D30, 89 | UC_ARM64_REG_D31, 90 | UC_ARM64_REG_H0, 91 | UC_ARM64_REG_H1, 92 | UC_ARM64_REG_H2, 93 | UC_ARM64_REG_H3, 94 | UC_ARM64_REG_H4, 95 | UC_ARM64_REG_H5, 96 | UC_ARM64_REG_H6, 97 | UC_ARM64_REG_H7, 98 | UC_ARM64_REG_H8, 99 | UC_ARM64_REG_H9, 100 | UC_ARM64_REG_H10, 101 | UC_ARM64_REG_H11, 102 | UC_ARM64_REG_H12, 103 | UC_ARM64_REG_H13, 104 | UC_ARM64_REG_H14, 105 | UC_ARM64_REG_H15, 106 | UC_ARM64_REG_H16, 107 | UC_ARM64_REG_H17, 108 | UC_ARM64_REG_H18, 109 | UC_ARM64_REG_H19, 110 | UC_ARM64_REG_H20, 111 | UC_ARM64_REG_H21, 112 | UC_ARM64_REG_H22, 113 | UC_ARM64_REG_H23, 114 | UC_ARM64_REG_H24, 115 | UC_ARM64_REG_H25, 116 | UC_ARM64_REG_H26, 117 | UC_ARM64_REG_H27, 118 | UC_ARM64_REG_H28, 119 | UC_ARM64_REG_H29, 120 | UC_ARM64_REG_H30, 121 | UC_ARM64_REG_H31, 122 | UC_ARM64_REG_Q0, 123 | UC_ARM64_REG_Q1, 124 | UC_ARM64_REG_Q2, 125 | UC_ARM64_REG_Q3, 126 | UC_ARM64_REG_Q4, 127 | UC_ARM64_REG_Q5, 128 | UC_ARM64_REG_Q6, 129 | UC_ARM64_REG_Q7, 130 | UC_ARM64_REG_Q8, 131 | UC_ARM64_REG_Q9, 132 | UC_ARM64_REG_Q10, 133 | UC_ARM64_REG_Q11, 134 | UC_ARM64_REG_Q12, 135 | UC_ARM64_REG_Q13, 136 | UC_ARM64_REG_Q14, 137 | UC_ARM64_REG_Q15, 138 | UC_ARM64_REG_Q16, 139 | UC_ARM64_REG_Q17, 140 | UC_ARM64_REG_Q18, 141 | UC_ARM64_REG_Q19, 142 | UC_ARM64_REG_Q20, 143 | UC_ARM64_REG_Q21, 144 | UC_ARM64_REG_Q22, 145 | UC_ARM64_REG_Q23, 146 | UC_ARM64_REG_Q24, 147 | UC_ARM64_REG_Q25, 148 | UC_ARM64_REG_Q26, 149 | UC_ARM64_REG_Q27, 150 | UC_ARM64_REG_Q28, 151 | UC_ARM64_REG_Q29, 152 | UC_ARM64_REG_Q30, 153 | UC_ARM64_REG_Q31, 154 | UC_ARM64_REG_S0, 155 | UC_ARM64_REG_S1, 156 | UC_ARM64_REG_S2, 157 | UC_ARM64_REG_S3, 158 | UC_ARM64_REG_S4, 159 | UC_ARM64_REG_S5, 160 | UC_ARM64_REG_S6, 161 | UC_ARM64_REG_S7, 162 | UC_ARM64_REG_S8, 163 | UC_ARM64_REG_S9, 164 | UC_ARM64_REG_S10, 165 | UC_ARM64_REG_S11, 166 | UC_ARM64_REG_S12, 167 | UC_ARM64_REG_S13, 168 | UC_ARM64_REG_S14, 169 | UC_ARM64_REG_S15, 170 | UC_ARM64_REG_S16, 171 | UC_ARM64_REG_S17, 172 | UC_ARM64_REG_S18, 173 | UC_ARM64_REG_S19, 174 | UC_ARM64_REG_S20, 175 | UC_ARM64_REG_S21, 176 | UC_ARM64_REG_S22, 177 | UC_ARM64_REG_S23, 178 | UC_ARM64_REG_S24, 179 | UC_ARM64_REG_S25, 180 | UC_ARM64_REG_S26, 181 | UC_ARM64_REG_S27, 182 | UC_ARM64_REG_S28, 183 | UC_ARM64_REG_S29, 184 | UC_ARM64_REG_S30, 185 | UC_ARM64_REG_S31, 186 | UC_ARM64_REG_W0, 187 | UC_ARM64_REG_W1, 188 | UC_ARM64_REG_W2, 189 | UC_ARM64_REG_W3, 190 | UC_ARM64_REG_W4, 191 | UC_ARM64_REG_W5, 192 | UC_ARM64_REG_W6, 193 | UC_ARM64_REG_W7, 194 | UC_ARM64_REG_W8, 195 | UC_ARM64_REG_W9, 196 | UC_ARM64_REG_W10, 197 | UC_ARM64_REG_W11, 198 | UC_ARM64_REG_W12, 199 | UC_ARM64_REG_W13, 200 | UC_ARM64_REG_W14, 201 | UC_ARM64_REG_W15, 202 | UC_ARM64_REG_W16, 203 | UC_ARM64_REG_W17, 204 | UC_ARM64_REG_W18, 205 | UC_ARM64_REG_W19, 206 | UC_ARM64_REG_W20, 207 | UC_ARM64_REG_W21, 208 | UC_ARM64_REG_W22, 209 | UC_ARM64_REG_W23, 210 | UC_ARM64_REG_W24, 211 | UC_ARM64_REG_W25, 212 | UC_ARM64_REG_W26, 213 | UC_ARM64_REG_W27, 214 | UC_ARM64_REG_W28, 215 | UC_ARM64_REG_W29, 216 | UC_ARM64_REG_W30, 217 | UC_ARM64_REG_X0, 218 | UC_ARM64_REG_X1, 219 | UC_ARM64_REG_X2, 220 | UC_ARM64_REG_X3, 221 | UC_ARM64_REG_X4, 222 | UC_ARM64_REG_X5, 223 | UC_ARM64_REG_X6, 224 | UC_ARM64_REG_X7, 225 | UC_ARM64_REG_X8, 226 | UC_ARM64_REG_X9, 227 | UC_ARM64_REG_X10, 228 | UC_ARM64_REG_X11, 229 | UC_ARM64_REG_X12, 230 | UC_ARM64_REG_X13, 231 | UC_ARM64_REG_X14, 232 | UC_ARM64_REG_X15, 233 | UC_ARM64_REG_X16, 234 | UC_ARM64_REG_X17, 235 | UC_ARM64_REG_X18, 236 | UC_ARM64_REG_X19, 237 | UC_ARM64_REG_X20, 238 | UC_ARM64_REG_X21, 239 | UC_ARM64_REG_X22, 240 | UC_ARM64_REG_X23, 241 | UC_ARM64_REG_X24, 242 | UC_ARM64_REG_X25, 243 | UC_ARM64_REG_X26, 244 | UC_ARM64_REG_X27, 245 | UC_ARM64_REG_X28, 246 | 247 | UC_ARM64_REG_V0, 248 | UC_ARM64_REG_V1, 249 | UC_ARM64_REG_V2, 250 | UC_ARM64_REG_V3, 251 | UC_ARM64_REG_V4, 252 | UC_ARM64_REG_V5, 253 | UC_ARM64_REG_V6, 254 | UC_ARM64_REG_V7, 255 | UC_ARM64_REG_V8, 256 | UC_ARM64_REG_V9, 257 | UC_ARM64_REG_V10, 258 | UC_ARM64_REG_V11, 259 | UC_ARM64_REG_V12, 260 | UC_ARM64_REG_V13, 261 | UC_ARM64_REG_V14, 262 | UC_ARM64_REG_V15, 263 | UC_ARM64_REG_V16, 264 | UC_ARM64_REG_V17, 265 | UC_ARM64_REG_V18, 266 | UC_ARM64_REG_V19, 267 | UC_ARM64_REG_V20, 268 | UC_ARM64_REG_V21, 269 | UC_ARM64_REG_V22, 270 | UC_ARM64_REG_V23, 271 | UC_ARM64_REG_V24, 272 | UC_ARM64_REG_V25, 273 | UC_ARM64_REG_V26, 274 | UC_ARM64_REG_V27, 275 | UC_ARM64_REG_V28, 276 | UC_ARM64_REG_V29, 277 | UC_ARM64_REG_V30, 278 | UC_ARM64_REG_V31, 279 | 280 | //> pseudo registers 281 | UC_ARM64_REG_PC, // program counter register 282 | 283 | UC_ARM64_REG_ENDING, // <-- mark the end of the list of registers 284 | 285 | //> alias registers 286 | 287 | UC_ARM64_REG_IP1 = UC_ARM64_REG_X16, 288 | UC_ARM64_REG_IP0 = UC_ARM64_REG_X17, 289 | UC_ARM64_REG_FP = UC_ARM64_REG_X29, 290 | UC_ARM64_REG_LR = UC_ARM64_REG_X30, 291 | } uc_arm64_reg; 292 | 293 | #ifdef __cplusplus 294 | } 295 | #endif 296 | 297 | #endif 298 | -------------------------------------------------------------------------------- /TinyAvCore/Module/ModuleMgrService.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleMgrService.h" 2 | #include 3 | 4 | CModuleMgrService::CModuleMgrService() 5 | { 6 | } 7 | 8 | CModuleMgrService::~CModuleMgrService() 9 | { 10 | } 11 | 12 | HRESULT WINAPI CModuleMgrService::QueryInterface(__in REFIID riid, _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) 13 | { 14 | if (ppvObject == NULL) return E_INVALIDARG; 15 | if (IsEqualIID(riid, IID_IUnknown) || 16 | IsEqualIID(riid, __uuidof(IModuleManager))) 17 | { 18 | *ppvObject = static_cast(this); 19 | AddRef(); 20 | return S_OK; 21 | } 22 | 23 | return E_NOINTERFACE; 24 | } 25 | 26 | HRESULT WINAPI CModuleMgrService::Load(__in LPCWSTR lpModuleDirectory /*= NULL*/, __in LPCWSTR lpModuleName /*= NULL*/, __in DWORD flags /*= 0*/) 27 | { 28 | StringW searchStr, searchPath; 29 | 30 | if (lpModuleDirectory) 31 | searchPath = lpModuleDirectory; 32 | else 33 | { 34 | WCHAR currentFileName[MAX_PATH + 1] = {}; 35 | GetModuleFileNameW(NULL, currentFileName, MAX_PATH); 36 | searchPath = currentFileName; 37 | } 38 | 39 | if (lpModuleName == NULL) 40 | { 41 | searchStr = searchPath + L"\\*."; 42 | searchStr += MODULE_EXTENSION; 43 | } 44 | else 45 | { 46 | searchStr = searchPath + L"\\"; 47 | searchStr += lpModuleName; 48 | } 49 | 50 | WIN32_FIND_DATAW wfd = {}; 51 | HANDLE hFind = FindFirstFileW(searchStr.c_str(), &wfd); 52 | if (hFind == INVALID_HANDLE_VALUE) 53 | { 54 | return HRESULT_FROM_WIN32(GetLastError()); 55 | } 56 | 57 | do 58 | { 59 | StringW modulePath = searchPath + L"\\" + wfd.cFileName; 60 | HMODULE handle = LoadLibraryExW(modulePath.c_str(), NULL, flags); 61 | if (handle) 62 | { 63 | CREATEMODULEOBJECT createModuleObj = (CREATEMODULEOBJECT)GetProcAddress(handle, MODULE_EP); 64 | IModule * module = NULL; 65 | if (SUCCEEDED(createModuleObj(CLSID_NULL, 0, __uuidof(IModule), (LPVOID*)&module))) 66 | { 67 | if (m_modules.end() == std::find(m_modules.begin(), m_modules.end(), module)) 68 | { 69 | m_modules.push_back(module); 70 | handle = NULL; 71 | module = NULL; 72 | } 73 | } 74 | 75 | if (module) module->Release(); 76 | } 77 | 78 | if (handle) FreeLibrary(handle); 79 | 80 | } while (FindNextFileW(hFind, &wfd)); 81 | 82 | FindClose(hFind); 83 | 84 | return (m_modules.size()) ? S_OK : E_FAIL; 85 | } 86 | 87 | HRESULT WINAPI CModuleMgrService::Load(__in LPCWSTR lpModuleDirectory /*= NULL*/, __in ModuleType moduleType /*= 0*/, __in DWORD flags /*= 0*/) 88 | { 89 | StringW searchStr, searchPath; 90 | 91 | if (lpModuleDirectory) 92 | searchPath = lpModuleDirectory; 93 | else 94 | { 95 | WCHAR currentFileName[MAX_PATH + 1] = {}; 96 | GetModuleFileNameW(NULL, currentFileName, MAX_PATH); 97 | searchPath = currentFileName; 98 | } 99 | 100 | searchStr = searchPath + L"\\*."; 101 | searchStr += MODULE_EXTENSION; 102 | 103 | WIN32_FIND_DATAW wfd = {}; 104 | HANDLE hFind = FindFirstFileW(searchStr.c_str(), &wfd); 105 | if (hFind == INVALID_HANDLE_VALUE) 106 | { 107 | return HRESULT_FROM_WIN32(GetLastError()); 108 | } 109 | 110 | do 111 | { 112 | StringW modulePath = searchPath + L"\\" + wfd.cFileName; 113 | HMODULE handle = LoadLibraryExW(modulePath.c_str(), NULL, flags); 114 | if (handle) 115 | { 116 | CREATEMODULEOBJECT createclsObj = (CREATEMODULEOBJECT)GetProcAddress(handle, MODULE_EP); 117 | IModule * module = NULL; 118 | if (SUCCEEDED(createclsObj(CLSID_NULL, 0, __uuidof(IModule), (LPVOID*)&module))) 119 | { 120 | if (module->GetType() == moduleType) 121 | { 122 | if (m_modules.end() == std::find(m_modules.begin(), m_modules.end(), module)) 123 | { 124 | m_modules.push_back(module); 125 | handle = NULL; 126 | module = NULL; 127 | } 128 | } 129 | } 130 | 131 | if (module) module->Release(); 132 | } 133 | 134 | if (handle) FreeLibrary(handle); 135 | 136 | } while (FindNextFileW(hFind, &wfd)); 137 | 138 | FindClose(hFind); 139 | return (m_modules.size()) ? S_OK : E_FAIL; 140 | } 141 | 142 | HRESULT WINAPI CModuleMgrService::Unload(__in LPCWSTR lpModuleName /*= NULL*/) 143 | { 144 | if (lpModuleName == NULL) 145 | { 146 | for (MODULE_ARRAY::iterator it = m_modules.begin(); it != m_modules.end(); ) 147 | { 148 | MODULE_INFO info; 149 | if (SUCCEEDED((*it)->GetModuleInfo(&info))) 150 | { 151 | (*it)->Release(); 152 | FreeLibrary(info.handle); 153 | it = m_modules.erase(it); 154 | } 155 | } 156 | return S_OK; 157 | } 158 | else 159 | { 160 | BSTR name; 161 | for (MODULE_ARRAY::iterator it = m_modules.begin(); it != m_modules.end(); ++it) 162 | { 163 | name = NULL; 164 | if (SUCCEEDED((*it)->GetName(&name))) 165 | { 166 | if (0 == _wcsnicmp((wchar_t const*)name, lpModuleName, MAX_NAME)) 167 | { 168 | MODULE_INFO info; 169 | if (SUCCEEDED((*it)->GetModuleInfo(&info))) 170 | { 171 | (*it)->Release(); 172 | FreeLibrary(info.handle); 173 | m_modules.erase(it); 174 | SysFreeString(name); 175 | return S_OK; 176 | } 177 | } 178 | SysFreeString(name); 179 | } 180 | } 181 | } 182 | 183 | return E_NOT_SET; 184 | } 185 | 186 | HRESULT WINAPI CModuleMgrService::Unload(__in ModuleType moduleType /*= DefaultModuleType*/) 187 | { 188 | BOOL bFound = FALSE; 189 | for (MODULE_ARRAY::iterator it = m_modules.begin(); it != m_modules.end();) 190 | { 191 | if (moduleType == DefaultModuleType || (*it)->GetType() == moduleType) 192 | { 193 | MODULE_INFO info; 194 | if (SUCCEEDED((*it)->GetModuleInfo(&info))) 195 | { 196 | (*it)->Release(); 197 | FreeLibrary(info.handle); 198 | it = m_modules.erase(it); 199 | bFound = TRUE; 200 | } 201 | else 202 | { 203 | it++; 204 | } 205 | } 206 | } 207 | 208 | return bFound ? S_OK : E_NOT_SET; 209 | } 210 | 211 | HRESULT WINAPI CModuleMgrService::QueryModule(__out IModule **&module, __out size_t& moduleCount, __in LPCWSTR lpModuleName /*= NULL*/) 212 | { 213 | MODULE_ARRAY a; 214 | 215 | if (lpModuleName == NULL) 216 | { 217 | a = m_modules; 218 | } 219 | else 220 | { 221 | for (MODULE_ARRAY::iterator it = m_modules.begin(); it != m_modules.end(); ++it) 222 | { 223 | BSTR name = NULL; 224 | if (SUCCEEDED((*it)->GetName(&name)) && 225 | (0 == _wcsnicmp((wchar_t const*)name, lpModuleName, MAX_NAME))) 226 | { 227 | a.push_back((*it)); 228 | } 229 | 230 | if (name) 231 | SysFreeString(name); 232 | } 233 | } 234 | 235 | if (a.size() == 0) return E_NOT_SET; 236 | moduleCount = a.size(); 237 | 238 | module = (IModule **)CoTaskMemAlloc(a.size() * sizeof(IModule*)); 239 | if (module == NULL) 240 | { 241 | return E_OUTOFMEMORY; 242 | } 243 | for (size_t i = 0; i < moduleCount; ++i) 244 | { 245 | module[i] = a[i]; 246 | a[i]->AddRef(); 247 | } 248 | return S_OK; 249 | } 250 | 251 | HRESULT WINAPI CModuleMgrService::QueryModule(__out IModule **&module, __out size_t& moduleCount, __in ModuleType moduleType /*= DefaultModuleType*/) 252 | { 253 | MODULE_ARRAY a; 254 | 255 | if (moduleType == DefaultModuleType) 256 | { 257 | a = m_modules; 258 | } 259 | else 260 | { 261 | for (MODULE_ARRAY::iterator it = m_modules.begin(); it != m_modules.end(); ++it) 262 | { 263 | if ((*it)->GetType() == moduleType) 264 | { 265 | a.push_back((*it)); 266 | } 267 | } 268 | } 269 | 270 | if (a.size() == 0) return E_NOT_SET; 271 | moduleCount = a.size(); 272 | 273 | module = (IModule **)CoTaskMemAlloc(a.size() * sizeof(IModule*)); 274 | if (module == NULL) 275 | { 276 | return E_OUTOFMEMORY; 277 | } 278 | for (size_t i = 0; i < moduleCount; ++i) 279 | { 280 | module[i] = a[i]; 281 | a[i]->AddRef(); 282 | } 283 | return S_OK; 284 | } 285 | -------------------------------------------------------------------------------- /include/FileType/PEFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../TinyAvBase.h" 4 | #include "FileType.h" 5 | 6 | #define MAX_SECTION_COUNT (96) 7 | #define MAX_PE_HEADER_SIZE (4096) 8 | 9 | // ----------------------------- 10 | // Interface for 32-bit PE file 11 | // ----------------------------- 12 | MIDL_INTERFACE("34D42F84-0224-4195-AD90-57767B4E855F") 13 | IPeFile : public IFileType 14 | { 15 | BEGIN_INTERFACE 16 | 17 | public: 18 | 19 | /* Retrieve DOS header 20 | @dosHeader: a pointer to an variable storing IMAGE_DOS_HEADER header 21 | @return: HRESULT on success, or other value on failure. 22 | */ 23 | virtual HRESULT WINAPI GetDosHeader(__out_bcount(sizeof(IMAGE_DOS_HEADER)) IMAGE_DOS_HEADER *dosHeader) = 0; 24 | 25 | /* Retrieve PE header 26 | @dosHeader: a pointer to an variable storing IMAGE_NT_HEADERS32 header 27 | @return: HRESULT on success, or other value on failure. 28 | */ 29 | virtual HRESULT WINAPI GetPEHeader(__out_bcount(sizeof(IMAGE_NT_HEADERS32)) IMAGE_NT_HEADERS32 *peHeader) = 0; 30 | 31 | /* Retrieve section header 32 | @sectionIndex: section index 33 | @sectionHeader: a pointer to an variable storing IMAGE_SECTION_HEADER header 34 | @return: HRESULT on success, or other value on failure. 35 | */ 36 | virtual HRESULT WINAPI GetSectionHeader(__in UINT sectionIndex, __out_bcount(IMAGE_SIZEOF_SECTION_HEADER) IMAGE_SECTION_HEADER *sectionHeader) = 0; 37 | 38 | // Retrieve the number of section in header 39 | //@return: number of section. 40 | virtual UINT WINAPI GetSectionCount(void) = 0; 41 | 42 | /* Convert RVA to file offset 43 | @rva: relative virtual address 44 | @fileOffset: a pointer to an variable storing file offset 45 | @return: HRESULT on success, or other value on failure. 46 | */ 47 | virtual HRESULT WINAPI RvaToFileOffset(__in UINT rva, __out UINT *fileOffset) = 0; 48 | 49 | /* Convert VA to file offset 50 | @va: virtual address 51 | @fileOffset: a pointer to an variable storing file offset 52 | @return: HRESULT on success, or other value on failure. 53 | */ 54 | virtual HRESULT WINAPI VaToFileOffset(__in UINT va, __out UINT *fileOffset) = 0; 55 | 56 | /* Convert file offset to RVA 57 | @fileOffset: an address is offset in file 58 | @rva: a pointer to an variable storing relative virtual address 59 | @return: HRESULT on success, or other value on failure. 60 | */ 61 | virtual HRESULT WINAPI FileOffsetToRva(__in UINT fileOffset, __out UINT *rva) = 0; 62 | 63 | /* Convert file offset to VA 64 | @fileOffset: an address is offset in file 65 | @va: a pointer to an variable storing virtual address 66 | @return: HRESULT on success, or other value on failure. 67 | */ 68 | virtual HRESULT WINAPI FileOffsetToVa(__in UINT fileOffset, __out UINT *va) = 0; 69 | 70 | /* Read raw data of the given section 71 | @sectionIndex: section number 72 | @buffer: pointer to a variable containing data copied from file. 73 | @maxReadSize: size of data to copy. 74 | @bytesRead: a pointer to an variable storing byte read 75 | @return: HRESULT on success, or other value on failure. 76 | */ 77 | virtual HRESULT WINAPI ReadSectionData(__in UINT sectionIndex, __out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) = 0; 78 | 79 | /* Read raw data of the section containing Entry-Point 80 | @buffer: pointer to a variable containing data copied from file. 81 | @maxReadSize: size of data to copy. 82 | @bytesRead: a pointer to an variable storing byte read 83 | @return: HRESULT on success, or other value on failure. 84 | */ 85 | virtual HRESULT WINAPI ReadEPSectionData(__out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) = 0; 86 | 87 | /* Find section containing the given RVA 88 | @rva: relative virtual address 89 | @sectionIndex: a pointer to an variable storing section index 90 | @return: HRESULT on success, or other value on failure. 91 | */ 92 | virtual HRESULT WINAPI FindSectionByRva(__in UINT rva, __out UINT *sectionIndex) = 0; 93 | 94 | /* Find section containing the given VA 95 | @va: virtual address 96 | @sectionIndex: a pointer to an variable storing section index 97 | @return: HRESULT on success, or other value on failure. 98 | */ 99 | virtual HRESULT WINAPI FindSectionByVa(__in UINT va, __out UINT *sectionIndex) = 0; 100 | 101 | /* Find section containing the given raw file offset 102 | @fileOffset: file offset 103 | @sectionIndex: a pointer to an variable storing section index 104 | @return: HRESULT on success, or other value on failure. 105 | */ 106 | virtual HRESULT WINAPI FindSectionByFileOffset(__in UINT fileOffset, __out UINT *sectionIndex) = 0; 107 | 108 | /* Read buffer starting at the Entry-Point 109 | @buffer: pointer to a variable containing data copied from file. 110 | @maxReadSize: size of data to copy. 111 | @bytesRead: a pointer to an variable storing byte read 112 | @return: HRESULT on success, or other value on failure. 113 | */ 114 | virtual HRESULT WINAPI ReadEntryPointData(__out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) = 0; 115 | 116 | /* Set new Address of Entry Point 117 | @va: Address of new entry point. 118 | @return: HRESULT on success, or other value on failure. 119 | */ 120 | virtual HRESULT WINAPI SetVaToEntryPoint(__in UINT va) = 0; 121 | 122 | /* Set new Address of Entry Point 123 | @rva: relative address of Address of new entry point. 124 | @return: HRESULT on success, or other value on failure. 125 | */ 126 | virtual HRESULT WINAPI SetRvaToEntryPoint(__in UINT rva) = 0; 127 | 128 | /* shrink file from current section to end of file 129 | @sectionIndex: relative address of Address of new entry point. 130 | @return: HRESULT on success, or other value on failure. 131 | */ 132 | virtual HRESULT WINAPI TruncateSectionUntilEndOfFile(__in UINT sectionIndex) = 0; 133 | 134 | /* shrink file to end of file or patch file with 0xC3 135 | @va: virtual address 136 | @padding: Indicates whether to shrink or patch file. 137 | @return: HRESULT on success, or other value on failure. 138 | */ 139 | virtual HRESULT WINAPI Truncate(__in UINT va, __in_opt BOOL padding = FALSE) = 0; 140 | 141 | // 142 | virtual void WINAPI ReleaseCurrentFile(void) =0; 143 | 144 | END_INTERFACE 145 | }; 146 | 147 | 148 | // ----------------------------- 149 | // Interface for 64-bit PE file 150 | // ----------------------------- 151 | MIDL_INTERFACE("80EABAE2-34D4-448F-BF92-235C62A7151A") 152 | IPe64File : public IFileType 153 | { 154 | BEGIN_INTERFACE 155 | 156 | public: 157 | 158 | // Get DOS header 159 | virtual HRESULT WINAPI GetDosHeader(__out IMAGE_DOS_HEADER *dosHeader) = 0; 160 | // Get PE header 161 | virtual HRESULT WINAPI GetPEHeader(__out IMAGE_NT_HEADERS64 *peHeader) = 0; 162 | // Get section header 163 | virtual HRESULT WINAPI GetSectionHeader(__in UINT sectionIndex, __out IMAGE_SECTION_HEADER *sectionHeader) = 0; 164 | // Get section count 165 | virtual HRESULT WINAPI GetSectionCount(__out UINT64 *sectionCount) = 0; 166 | // Convert RVA to file offset 167 | virtual HRESULT WINAPI RvaToFileOffset(__in UINT64 rva, __out UINT *fileOffset) = 0; 168 | // Convert VA to file offset 169 | virtual HRESULT WINAPI VaToFileOffset(__in UINT64 va, __out UINT *fileOffset) = 0; 170 | // Convert file offset to RVA 171 | virtual HRESULT WINAPI FileOffsetToRva(__in UINT fileOffset, __out UINT64 *rva) = 0; 172 | // Convert file offset to VA 173 | virtual HRESULT WINAPI FileOffsetToVa(__in UINT fileOffset, __out UINT64 *va) = 0; 174 | // Read raw data of the given section 175 | virtual HRESULT WINAPI ReadSectionData(__in UINT sectionIndex, __out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) = 0; 176 | // Read raw data of the section containing Entry-Point 177 | virtual HRESULT WINAPI ReadEPSectionData(__out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) = 0; 178 | // Find section containing the given RVA 179 | virtual HRESULT WINAPI FindSectionByRva(__in UINT64 rva, __out UINT *sectionIndex) = 0; 180 | // Find section containing the given VA 181 | virtual HRESULT WINAPI FindSectionByVa(__in UINT64 va, __out UINT *sectionIndex) = 0; 182 | // Find section containing the given raw file offset 183 | virtual HRESULT WINAPI FindSectionByFileOffset(__in UINT fileOffset, __out UINT *sectionIndex) = 0; 184 | // Read buffer starting at the Entry-Point 185 | virtual HRESULT WINAPI ReadEntryPointData(__out_bcount(maxReadSize) LPVOID buffer, __in ULONG maxReadSize, __out_opt ULONG *bytesRead) = 0; 186 | 187 | virtual HRESULT WINAPI SetVaToEntryPoint(__in UINT64 va) = 0; 188 | virtual HRESULT WINAPI SetRvaToEntryPoint(__in UINT64 rva) = 0; 189 | virtual HRESULT WINAPI TruncateSectionUntilEndOfFile(__in UINT sectionIndex) = 0; 190 | virtual HRESULT WINAPI Truncate(__in UINT64 va, __in_opt BOOL padding = FALSE) = 0; 191 | virtual void WINAPI ReleaseCurrentFile(void) = 0; 192 | 193 | END_INTERFACE 194 | }; 195 | -------------------------------------------------------------------------------- /TinyAvCore/TinyAvCore.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {05de0bfa-a52e-4b61-8964-1dcf31b541fe} 18 | 19 | 20 | {714d22ee-b7e6-42ca-9ee3-f8b0400b0316} 21 | 22 | 23 | {7982db47-8a71-456f-900a-00bf82ca215d} 24 | 25 | 26 | {808377b8-44b8-41f6-8fa2-deb7c3e0f4e2} 27 | 28 | 29 | {aa2d6fe5-915c-4311-962c-de410e0d8ea0} 30 | 31 | 32 | {21a42af8-d5ee-4fdf-b882-7c094c2573e9} 33 | 34 | 35 | {b5431c20-bc66-4451-a958-488b46482dad} 36 | 37 | 38 | {35f34e88-22ed-4cd1-aeb2-8bfadeebc284} 39 | 40 | 41 | {4beaa95b-fbc2-478a-924b-a8145ec00819} 42 | 43 | 44 | {9838e715-dd7a-4540-a887-4808cc101828} 45 | 46 | 47 | {44409023-71b1-4745-b36a-2183e9b580bf} 48 | 49 | 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files\Emulator 62 | 63 | 64 | Header Files\FileSystem 65 | 66 | 67 | Header Files\FileSystem 68 | 69 | 70 | Header Files\FileSystem 71 | 72 | 73 | Header Files\FileSystem 74 | 75 | 76 | Header Files\FileSystem 77 | 78 | 79 | Header Files\FileType 80 | 81 | 82 | Header Files\FileType 83 | 84 | 85 | Header Files\Emulator 86 | 87 | 88 | Header Files\Emulator 89 | 90 | 91 | Header Files\FileSystem\zip 92 | 93 | 94 | Header Files\FileSystem\zip 95 | 96 | 97 | Header Files\FileSystem\zip 98 | 99 | 100 | Header Files\FileSystem\zip 101 | 102 | 103 | Header Files\FileSystem 104 | 105 | 106 | Header Files\FileSystem 107 | 108 | 109 | Header Files\FileSystem 110 | 111 | 112 | Header Files\FileSystem 113 | 114 | 115 | Header Files\FileSystem 116 | 117 | 118 | Header Files\FileSystem 119 | 120 | 121 | Header Files\Module 122 | 123 | 124 | Header Files\Module 125 | 126 | 127 | Header Files\Scanner 128 | 129 | 130 | Header Files\Scanner 131 | 132 | 133 | Header Files\Scanner 134 | 135 | 136 | Header Files\Scanner 137 | 138 | 139 | Header Files\FileType 140 | 141 | 142 | Header Files\Module 143 | 144 | 145 | Header Files 146 | 147 | 148 | Header Files 149 | 150 | 151 | Header Files\FileSystem 152 | 153 | 154 | 155 | 156 | Source Files\Emulator 157 | 158 | 159 | Source Files\Emulator 160 | 161 | 162 | Source Files\FileSystem\zip 163 | 164 | 165 | Source Files\FileSystem\zip 166 | 167 | 168 | Source Files\FileSystem\zip 169 | 170 | 171 | Source Files\FileSystem\zip 172 | 173 | 174 | Source Files\FileSystem 175 | 176 | 177 | Source Files\FileSystem 178 | 179 | 180 | Source Files\FileSystem 181 | 182 | 183 | Source Files\FileSystem 184 | 185 | 186 | Source Files\FileSystem 187 | 188 | 189 | Source Files\FileSystem 190 | 191 | 192 | Source Files\FileType 193 | 194 | 195 | Source Files\Module 196 | 197 | 198 | Source Files 199 | 200 | 201 | Source Files 202 | 203 | 204 | Source Files\FileSystem\zip 205 | 206 | 207 | Source Files\FileSystem\zip 208 | 209 | 210 | --------------------------------------------------------------------------------