X-Git-Url: http://git.sourceforge.jp/view?p=ffftp%2Fffftp.git;a=blobdiff_plain;f=protectprocess.c;h=a37fab26c7f98d1c1d28e73b00c2e325086f4a36;hp=6865912ee1a8b967a395eab526a8602a123c3b7f;hb=91e53f38be77b8d53a9509b748273a9aefce84b7;hpb=c30cc851b60a7c4006cd02b4718d9738a6c4049a diff --git a/protectprocess.c b/protectprocess.c index 6865912..a37fab2 100644 --- a/protectprocess.c +++ b/protectprocess.c @@ -1,1038 +1,1091 @@ -// protectprocess.c -// Copyright (C) 2011 Suguru Kawamoto -// ƒvƒƒZƒX‚Ì•ÛŒì - -// ŽŸ‚Ì’†‚©‚ç1ŒÂ‚Ì‚Ý—LŒø‚É‚·‚é -// ƒtƒbƒNæ‚̊֐”‚̃R[ƒh‚ð‘‚«Š·‚¦‚é -// ‘S‚Ă̌Ăяo‚µ‚ðƒtƒbƒN‰Â”\‚¾‚ªŒ´—“I‚É“ñdŒÄ‚яo‚µ‚ɑΉž‚Å‚«‚È‚¢ -#define USE_CODE_HOOK -// ƒtƒbƒNæ‚̊֐”‚̃Cƒ“ƒ|[ƒgƒAƒhƒŒƒXƒe[ƒuƒ‹‚ð‘‚«Š·‚¦‚é -// “ñdŒÄ‚яo‚µ‚ª‰Â”\‚¾‚ªŒÄ‚яo‚µ•û–@‚É‚æ‚Á‚Ă̓tƒbƒN‚ð‰ñ”ð‚³‚ê‚é -//#define USE_IAT_HOOK - -// ƒtƒbƒN‘Ώۂ̊֐”–¼ %s -// ƒtƒbƒN‘Ώۂ̌^ _%s -// ƒtƒbƒN‘Ώۂ̃|ƒCƒ“ƒ^ p_%s -// ƒtƒbƒN—p‚̊֐”–¼ h_%s -// ƒtƒbƒN‘Ώۂ̃R[ƒh‚̃oƒbƒNƒAƒbƒv c_%s - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_IAT_HOOK -#include -#endif - -#define DO_NOT_REPLACE -#include "protectprocess.h" -#include "mbswrapper.h" - -#ifdef USE_IAT_HOOK -#pragma comment(lib, "dbghelp.lib") -#endif - -#ifdef USE_CODE_HOOK -#if defined(_X86_) -#define HOOK_JUMP_CODE_LENGTH 5 -#elif defined(_AMD64_) -#define HOOK_JUMP_CODE_LENGTH 14 -#endif -#endif - -BOOL LockThreadLock(); -BOOL UnlockThreadLock(); -#ifdef USE_CODE_HOOK -BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore); -#endif -#ifdef USE_IAT_HOOK -BOOL HookFunctionInIAT(void* pOriginal, void* pNew); -#endif -HANDLE LockExistingFile(LPCWSTR Filename); -BOOL FindTrustedModuleMD5Hash(void* pHash); -BOOL VerifyFileSignature(LPCWSTR Filename); -BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename); -BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash); -BOOL IsModuleTrusted(LPCWSTR Filename); - -// •Ï”‚̐錾 -#ifdef USE_CODE_HOOK -#define HOOK_FUNCTION_VAR(name) _##name p_##name;BYTE c_##name[HOOK_JUMP_CODE_LENGTH * 2]; -#endif -#ifdef USE_IAT_HOOK -#define HOOK_FUNCTION_VAR(name) _##name p_##name; -#endif -// ŠÖ”ƒ|ƒCƒ“ƒ^‚ðŽæ“¾ -#define GET_FUNCTION(h, name) p_##name = (_##name)GetProcAddress(h, #name) -// ƒtƒbƒN‘Ώۂ̃R[ƒh‚ð’uŠ·‚µ‚ătƒbƒN‚ðŠJŽn -#define SET_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE) -// ƒtƒbƒN‘ΏۂðŒÄ‚яo‚·‘O‚ɑΏۂ̃R[ƒh‚𕜌³ -#define START_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, TRUE) -// ƒtƒbƒN‘ΏۂðŒÄ‚яo‚µ‚½Œã‚ɑΏۂ̃R[ƒh‚ð’uŠ· -#define END_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, NULL, FALSE) - -HOOK_FUNCTION_VAR(LoadLibraryA) -HOOK_FUNCTION_VAR(LoadLibraryW) -HOOK_FUNCTION_VAR(LoadLibraryExA) -HOOK_FUNCTION_VAR(LoadLibraryExW) - -typedef NTSTATUS (NTAPI* _LdrLoadDll)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*); -typedef NTSTATUS (NTAPI* _LdrGetDllHandle)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*); -typedef PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)(PVOID); -typedef BOOL (WINAPI* _CryptCATAdminCalcHashFromFileHandle)(HANDLE, DWORD*, BYTE*, DWORD); - -_LdrLoadDll p_LdrLoadDll; -_LdrGetDllHandle p_LdrGetDllHandle; -_RtlImageNtHeader p_RtlImageNtHeader; -_CryptCATAdminCalcHashFromFileHandle p_CryptCATAdminCalcHashFromFileHandle; - -#define MAX_LOCKED_THREAD 16 -#define MAX_TRUSTED_FILENAME_TABLE 16 -#define MAX_TRUSTED_MD5_HASH_TABLE 16 - -DWORD g_LockedThread[MAX_LOCKED_THREAD]; -WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE]; -BYTE g_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][16]; - -// ˆÈ‰ºƒtƒbƒNŠÖ” -// ƒtƒbƒN‘ΏۂðŒÄ‚яo‚·ê‡‚Í‘OŒã‚ÅSTART_HOOK_FUNCTION‚ÆEND_HOOK_FUNCTION‚ðŽÀs‚·‚é•K—v‚ª‚ ‚é - -HMODULE WINAPI h_LoadLibraryA(LPCSTR lpLibFileName) -{ - HMODULE r = NULL; - wchar_t* pw0 = NULL; - if(pw0 = DuplicateAtoW(lpLibFileName, -1)) - r = LoadLibraryExW(pw0, NULL, 0); - FreeDuplicatedString(pw0); - return r; -} - -HMODULE WINAPI h_LoadLibraryW(LPCWSTR lpLibFileName) -{ - HMODULE r = NULL; - r = LoadLibraryExW(lpLibFileName, NULL, 0); - return r; -} - -HMODULE WINAPI h_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -{ - HMODULE r = NULL; - wchar_t* pw0 = NULL; - if(pw0 = DuplicateAtoW(lpLibFileName, -1)) - r = LoadLibraryExW(pw0, hFile, dwFlags); - FreeDuplicatedString(pw0); - return r; -} - -HMODULE WINAPI h_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -{ - HMODULE r = NULL; - BOOL bTrusted; - wchar_t* pw0; - HANDLE hLock; - HMODULE hModule; - DWORD Length; - bTrusted = FALSE; - pw0 = NULL; - hLock = NULL; -// if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) - if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | 0x00000020 | 0x00000040)) - bTrusted = TRUE; - if(!bTrusted) - { - if(hModule = System_LoadLibrary(lpLibFileName, NULL, DONT_RESOLVE_DLL_REFERENCES)) - { - Length = MAX_PATH; - if(pw0 = AllocateStringW(Length)) - { - if(GetModuleFileNameW(hModule, pw0, Length) > 0) - { - while(pw0) - { - if(GetModuleFileNameW(hModule, pw0, Length) + 1 <= Length) - { - lpLibFileName = pw0; - break; - } - Length = Length * 2; - FreeDuplicatedString(pw0); - pw0 = AllocateStringW(Length); - } - } - } - hLock = LockExistingFile(lpLibFileName); - FreeLibrary(hModule); - } - if(GetModuleHandleW(lpLibFileName)) - bTrusted = TRUE; - } - if(!bTrusted) - { - if(LockThreadLock()) - { - if(hLock) - { - if(IsModuleTrusted(lpLibFileName)) - bTrusted = TRUE; - } - UnlockThreadLock(); - } - } - if(bTrusted) - r = System_LoadLibrary(lpLibFileName, hFile, dwFlags); - FreeDuplicatedString(pw0); - if(hLock) - CloseHandle(hLock); - return r; -} - -// ˆÈ‰ºƒwƒ‹ƒp[ŠÖ” - -BOOL LockThreadLock() -{ - BOOL bResult; - DWORD ThreadId; - DWORD i; - bResult = FALSE; - ThreadId = GetCurrentThreadId(); - i = 0; - while(i < MAX_LOCKED_THREAD) - { - if(g_LockedThread[i] == ThreadId) - break; - i++; - } - if(i >= MAX_LOCKED_THREAD) - { - i = 0; - while(i < MAX_LOCKED_THREAD) - { - if(g_LockedThread[i] == 0) - { - g_LockedThread[i] = ThreadId; - bResult = TRUE; - break; - } - i++; - } - } - return bResult; -} - -BOOL UnlockThreadLock() -{ - BOOL bResult; - DWORD ThreadId; - DWORD i; - bResult = FALSE; - ThreadId = GetCurrentThreadId(); - i = 0; - while(i < MAX_LOCKED_THREAD) - { - if(g_LockedThread[i] == ThreadId) - { - g_LockedThread[i] = 0; - bResult = TRUE; - break; - } - i++; - } - return bResult; -} - -#ifdef USE_CODE_HOOK -BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore) -{ - BOOL bResult; - DWORD Protect; -#if defined(_X86_) - BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xe9, 0x00, 0x00, 0x00, 0x00}; - size_t Relative; - Relative = (size_t)pNew - (size_t)pOriginal - HOOK_JUMP_CODE_LENGTH; - memcpy(&JumpCode[1], &Relative, 4); - bResult = FALSE; - if(bRestore) - { - if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect)) - { - memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH); - VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect); - bResult = TRUE; - } - } - else - { - if(pBackupCode) - memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH); - if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect)) - { - memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH); - VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect); - bResult = TRUE; - } - } -#elif defined(_AMD64_) - BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - size_t Absolute; - Absolute = (size_t)pOriginal; - memcpy(&JumpCode[6], &Absolute, 8); - bResult = FALSE; - if(bRestore) - { - if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect)) - { - memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH); - VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect); - bResult = TRUE; - } - } - else - { - if(pBackupCode) - memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH); - if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect)) - { - memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH); - VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect); - bResult = TRUE; - } - } -#endif - return bResult; -} -#endif - -#ifdef USE_IAT_HOOK -BOOL HookFunctionInIAT(void* pOriginal, void* pNew) -{ - BOOL bResult; - HANDLE hSnapshot; - MODULEENTRY32 me; - BOOL bFound; - IMAGE_IMPORT_DESCRIPTOR* piid; - ULONG Size; - IMAGE_THUNK_DATA* pitd; - DWORD Protect; - bResult = FALSE; - if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE) - { - me.dwSize = sizeof(MODULEENTRY32); - if(Module32First(hSnapshot, &me)) - { - bFound = FALSE; - do - { - if(piid = (IMAGE_IMPORT_DESCRIPTOR*)ImageDirectoryEntryToData(me.hModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size)) - { - while(!bFound && piid->Name != 0) - { - pitd = (IMAGE_THUNK_DATA*)((BYTE*)me.hModule + piid->FirstThunk); - while(!bFound && pitd->u1.Function != 0) - { - if((void*)pitd->u1.Function == pOriginal) - { - bFound = TRUE; - if(VirtualProtect(&pitd->u1.Function, sizeof(void*), PAGE_EXECUTE_READWRITE, &Protect)) - { - memcpy(&pitd->u1.Function, &pNew, sizeof(void*)); - VirtualProtect(&pitd->u1.Function, sizeof(void*), Protect, &Protect); - bResult = TRUE; - } - } - pitd++; - } - piid++; - } - } - } - while(!bFound && Module32Next(hSnapshot, &me)); - } - CloseHandle(hSnapshot); - } - return bResult; -} -#endif - -// ƒtƒ@ƒCƒ‹‚ð•ÏX•s”\‚ɐݒè -HANDLE LockExistingFile(LPCWSTR Filename) -{ - HANDLE hResult; - hResult = NULL; - if((hResult = CreateFileW(Filename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)) == INVALID_HANDLE_VALUE) - hResult = NULL; - return hResult; -} - -// DLL‚̃nƒbƒVƒ…‚ðŒŸõ -BOOL FindTrustedModuleMD5Hash(void* pHash) -{ - BOOL bResult; - int i; - bResult = FALSE; - i = 0; - while(i < MAX_TRUSTED_MD5_HASH_TABLE) - { - if(memcmp(&g_TrustedMD5HashTable[i], pHash, 16) == 0) - { - bResult = TRUE; - break; - } - i++; - } - return bResult; -} - -// ƒtƒ@ƒCƒ‹‚̏–¼‚ðŠm”F -BOOL VerifyFileSignature(LPCWSTR Filename) -{ - BOOL bResult; - GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2; - WINTRUST_FILE_INFO wfi; - WINTRUST_DATA wd; - bResult = FALSE; - ZeroMemory(&wfi, sizeof(WINTRUST_FILE_INFO)); - wfi.cbStruct = sizeof(WINTRUST_FILE_INFO); - wfi.pcwszFilePath = Filename; - ZeroMemory(&wd, sizeof(WINTRUST_DATA)); - wd.cbStruct = sizeof(WINTRUST_DATA); - wd.dwUIChoice = WTD_UI_NONE; - wd.dwUnionChoice = WTD_CHOICE_FILE; - wd.pFile = &wfi; - if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS) - bResult = TRUE; - return bResult; -} - -// ƒtƒ@ƒCƒ‹‚̏–¼‚ðƒJƒ^ƒƒOƒtƒ@ƒCƒ‹‚ÅŠm”F -BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename) -{ - BOOL bResult; - GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2; - WINTRUST_CATALOG_INFO wci; - WINTRUST_DATA wd; - bResult = FALSE; - if(VerifyFileSignature(Catalog)) - { - ZeroMemory(&wci, sizeof(WINTRUST_CATALOG_INFO)); - wci.cbStruct = sizeof(WINTRUST_CATALOG_INFO); - wci.pcwszCatalogFilePath = Catalog; - wci.pcwszMemberFilePath = Filename; - if((wci.hMemberFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) - { - p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, NULL, 0); - if(wci.pbCalculatedFileHash = (BYTE*)malloc(wci.cbCalculatedFileHash)) - { - if(p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, wci.pbCalculatedFileHash, 0)) - { - ZeroMemory(&wd, sizeof(WINTRUST_DATA)); - wd.cbStruct = sizeof(WINTRUST_DATA); - wd.dwUIChoice = WTD_UI_NONE; - wd.dwUnionChoice = WTD_CHOICE_CATALOG; - wd.pCatalog = &wci; - if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS) - bResult = TRUE; - } - free(wci.pbCalculatedFileHash); - } - CloseHandle(wci.hMemberFile); - } - } - return bResult; -} - -BOOL WINAPI GetSHA1HashOfModule_Function(DIGEST_HANDLE refdata, PBYTE pData, DWORD dwLength) -{ - return CryptHashData(*(HCRYPTHASH*)refdata, pData, dwLength, 0); -} - -// ƒ‚ƒWƒ…[ƒ‹‚ÌSHA1ƒnƒbƒVƒ…‚ðŽæ“¾ -// ƒ}ƒjƒtƒFƒXƒgƒtƒ@ƒCƒ‹‚Ìfile—v‘f‚Ìhash‘®«‚ÍŽÀs‰Â”\ƒtƒ@ƒCƒ‹‚̏ꍇ‚ÉImageGetDigestStream‚ÅŽZo‚³‚ê‚é -BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash) -{ - BOOL bResult; - HCRYPTPROV hProv; - HCRYPTHASH hHash; - HANDLE hFile; - DWORD dw; - bResult = FALSE; - if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) - { - if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) - { - if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) - { - if(ImageGetDigestStream(hFile, CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO, GetSHA1HashOfModule_Function, (DIGEST_HANDLE)&hHash)) - { - dw = 20; - if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0)) - bResult = TRUE; - } - CloseHandle(hFile); - } - CryptDestroyHash(hHash); - } - CryptReleaseContext(hProv, 0); - } - return bResult; -} - -BOOL IsSxsModuleTrusted_Function(LPCWSTR Catalog, LPCWSTR Manifest, LPCWSTR Module) -{ - BOOL bResult; - HANDLE hLock0; - HANDLE hLock1; - BYTE Hash[20]; - int i; - static char HexTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - char HashHex[41]; - HANDLE hFile; - DWORD Size; - char* pData; - DWORD dw; - bResult = FALSE; - if(hLock0 = LockExistingFile(Catalog)) - { - if(hLock1 = LockExistingFile(Manifest)) - { - if(VerifyFileSignatureInCatalog(Catalog, Manifest)) - { - if(GetSHA1HashOfModule(Module, &Hash)) - { - for(i = 0; i < 20; i++) - { - HashHex[i * 2] = HexTable[(Hash[i] >> 4) & 0x0f]; - HashHex[i * 2 + 1] = HexTable[Hash[i] & 0x0f]; - } - HashHex[i * 2] = '\0'; - if((hFile = CreateFileW(Manifest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) - { - Size = GetFileSize(hFile, NULL); - if(pData = (char*)VirtualAlloc(NULL, Size + 1, MEM_COMMIT, PAGE_READWRITE)) - { - VirtualLock(pData, Size + 1); - if(ReadFile(hFile, pData, Size, &dw, NULL)) - { - pData[dw] = '\0'; - if(strstr(pData, HashHex)) - bResult = TRUE; - } - VirtualUnlock(pData, Size + 1); - VirtualFree(pData, Size + 1, MEM_DECOMMIT); - } - CloseHandle(hFile); - } - } - } - CloseHandle(hLock1); - } - CloseHandle(hLock0); - } - return bResult; -} - -// ƒTƒCƒhƒoƒCƒTƒCƒhDLL‚ðŠm”F -// ƒpƒX‚Í"%SystemRoot%\WinSxS"ˆÈ‰º‚ð‘z’è -// ˆÈ‰º‚̃tƒ@ƒCƒ‹‚ª‘¶Ý‚·‚é‚à‚Ì‚Æ‚·‚é -// "\xxx\yyy.dll"A"\manifests\xxx.cat"A"\manifests\xxx.manifest"‚̃ZƒbƒgiXP‚Ì‘S‚Ä‚ÌDLLAVistaˆÈ~‚̈ꕔ‚ÌDLLj -// "\xxx\yyy.dll"A"\catalogs\zzz.cat"A"\manifests\xxx.manifest"‚̃ZƒbƒgiVistaˆÈ~‚Ì‚Ù‚Æ‚ñ‚Ç‚ÌDLLj -// –¼‚³‚ꂽƒJƒ^ƒƒOƒtƒ@ƒCƒ‹‚ð—p‚¢‚ă}ƒjƒtƒFƒXƒgƒtƒ@ƒCƒ‹‚ª‰ü₂³‚ê‚Ä‚¢‚È‚¢‚±‚Æ‚ðŠm”F -// ƒnƒbƒVƒ…’l‚Í ƒ}ƒjƒtƒFƒXƒgƒtƒ@ƒCƒ‹‚Ìfile—v‘f‚Ìhash‘®«‚É‹Lq‚³‚ê‚Ä‚¢‚é‚à‚Ì‚ð—p‚¢‚é -// ƒ}ƒjƒtƒFƒXƒgƒtƒ@ƒCƒ‹“à‚ÉSHA1ƒnƒbƒVƒ…’l‚Ì16i”•\‹L‚𒼐ڌŸõ‚µ‚Ä‚¢‚邪Šm—¦“I‚É–â‘è‚È‚µ -BOOL IsSxsModuleTrusted(LPCWSTR Filename) -{ - BOOL bResult; - wchar_t* pw0; - wchar_t* pw1; - wchar_t* pw2; - wchar_t* pw3; - wchar_t* pw4; - wchar_t* pw5; - wchar_t* p; - HANDLE hFind; - WIN32_FIND_DATAW wfd; - bResult = FALSE; - if(pw0 = AllocateStringW(wcslen(Filename) + 1)) - { - wcscpy(pw0, Filename); - if(p = wcsrchr(pw0, L'\\')) - { - wcscpy(p, L""); - if(p = wcsrchr(pw0, L'\\')) - { - p++; - if(pw1 = AllocateStringW(wcslen(p) + 1)) - { - wcscpy(pw1, p); - wcscpy(p, L""); - if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".cat") + 1)) - { - wcscpy(pw2, pw0); - wcscat(pw2, L"manifests\\"); - wcscat(pw2, pw1); - if(pw3 = AllocateStringW(wcslen(pw2) + wcslen(L".manifest") + 1)) - { - wcscpy(pw3, pw2); - wcscat(pw3, L".manifest"); - wcscat(pw2, L".cat"); - if(IsSxsModuleTrusted_Function(pw2, pw3, Filename)) - bResult = TRUE; - FreeDuplicatedString(pw3); - } - FreeDuplicatedString(pw2); - } - if(!bResult) - { - if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"catalogs\\") + 1)) - { - if(pw3 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".manifest") + 1)) - { - wcscpy(pw2, pw0); - wcscat(pw2, L"catalogs\\"); - wcscpy(pw3, pw0); - wcscat(pw3, L"manifests\\"); - wcscat(pw3, pw1); - wcscat(pw3, L".manifest"); - if(pw4 = AllocateStringW(wcslen(pw2) + wcslen(L"*.cat") + 1)) - { - wcscpy(pw4, pw2); - wcscat(pw4, L"*.cat"); - if((hFind = FindFirstFileW(pw4, &wfd)) != INVALID_HANDLE_VALUE) - { - do - { - if(pw5 = AllocateStringW(wcslen(pw2) + wcslen(wfd.cFileName) + 1)) - { - wcscpy(pw5, pw2); - wcscat(pw5, wfd.cFileName); - if(IsSxsModuleTrusted_Function(pw5, pw3, Filename)) - bResult = TRUE; - FreeDuplicatedString(pw5); - } - } - while(!bResult && FindNextFileW(hFind, &wfd)); - FindClose(hFind); - } - FreeDuplicatedString(pw4); - } - FreeDuplicatedString(pw3); - } - FreeDuplicatedString(pw2); - } - } - FreeDuplicatedString(pw1); - } - } - } - FreeDuplicatedString(pw0); - } - return bResult; -} - -// DLL‚ðŠm”F -// ƒnƒbƒVƒ…‚ª“o˜^‚³‚ê‚Ä‚¢‚éAAuthenticode–¼‚ª‚³‚ê‚Ä‚¢‚éA‚Ü‚½‚ÍWFP‚É‚æ‚é•ÛŒì‰º‚É‚ ‚邱‚Æ‚ðŠm”F -BOOL IsModuleTrusted(LPCWSTR Filename) -{ - BOOL bResult; - BYTE Hash[16]; - bResult = FALSE; - if(GetMD5HashOfFile(Filename, &Hash)) - { - if(FindTrustedModuleMD5Hash(&Hash)) - bResult = TRUE; - } - if(!bResult) - { - if(VerifyFileSignature(Filename)) - bResult = TRUE; - } - if(!bResult) - { - if(IsSxsModuleTrusted(Filename)) - bResult = TRUE; - } - if(!bResult) - { - if(SfcIsFileProtected(NULL, Filename)) - bResult = TRUE; - } - return bResult; -} - -// kernel32.dll‚ÌLoadLibraryExW‘Š“–‚̊֐” -// ƒhƒLƒ…ƒƒ“ƒg‚ª–³‚¢‚½‚ߏڍׂ͕s–¾ -// ˆê•”‚̃EƒBƒ‹ƒX‘΍ôƒ\ƒtƒgiAvast!“™j‚ªLdrLoadDll‚ðƒtƒbƒN‚µ‚Ä‚¢‚邽‚ßLdrLoadDll‚ð‘‚«Š·‚¦‚é‚ׂ«‚Å‚Í‚È‚¢ -// ƒJ[ƒlƒ‹ƒ‚[ƒh‚̃R[ƒh‚ɑ΂µ‚Ä‚ÍŒø‰Ê‚È‚µ -// SeDebugPrivilege‚ªŽg—p‰Â”\‚ȃ†[ƒU[‚ɑ΂µ‚Ä‚ÍŒø‰Ê‚È‚µ -HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) -{ - HMODULE r = NULL; - UNICODE_STRING us; - HANDLE hDataFile; - HANDLE hMapping; - DWORD DllFlags; - us.Length = sizeof(wchar_t) * wcslen(lpLibFileName); - us.MaximumLength = sizeof(wchar_t) * (wcslen(lpLibFileName) + 1); - us.Buffer = (PWSTR)lpLibFileName; -// if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) - if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040)) - { -// if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == STATUS_SUCCESS) - if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == 0) - { -// dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); - dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040); - dwFlags |= DONT_RESOLVE_DLL_REFERENCES; - } - else - { -// if(dwFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE) - if(dwFlags & 0x00000040) - hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - else - hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); - if(hDataFile != INVALID_HANDLE_VALUE) - { - if(hMapping = CreateFileMappingW(hDataFile, NULL, PAGE_READONLY, 0, 0, NULL)) - { - if(r = (HMODULE)MapViewOfFileEx(hMapping, FILE_MAP_READ, 0, 0, 0, NULL)) - { - if(p_RtlImageNtHeader(r)) - r = (HMODULE)((size_t)r | 1); - else - { - UnmapViewOfFile(r); - r = NULL; - } - } - CloseHandle(hMapping); - } - CloseHandle(hDataFile); - } - else - { -// dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); - dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040); - dwFlags |= DONT_RESOLVE_DLL_REFERENCES; - } - } - } -// if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))) - if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040))) - { - DllFlags = 0; -// if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) - if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | 0x00000020)) - DllFlags |= 0x00000002; -// if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == STATUS_SUCCESS) - if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == 0) - { - } - else - r = NULL; - } - return r; -} - -// ƒtƒ@ƒCƒ‹‚ÌMD5ƒnƒbƒVƒ…‚ðŽæ“¾ -BOOL GetMD5HashOfFile(LPCWSTR Filename, void* pHash) -{ - BOOL bResult; - HCRYPTPROV hProv; - HCRYPTHASH hHash; - HANDLE hFile; - DWORD Size; - void* pData; - DWORD dw; - bResult = FALSE; - if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) - { - if(CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) - { - if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) - { - Size = GetFileSize(hFile, NULL); - if(pData = VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE)) - { - VirtualLock(pData, Size); - if(ReadFile(hFile, pData, Size, &dw, NULL)) - { - if(CryptHashData(hHash, (BYTE*)pData, Size, 0)) - { - dw = 16; - if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0)) - bResult = TRUE; - } - } - VirtualUnlock(pData, Size); - VirtualFree(pData, Size, MEM_DECOMMIT); - } - CloseHandle(hFile); - } - CryptDestroyHash(hHash); - } - CryptReleaseContext(hProv, 0); - } - return bResult; -} - -// DLL‚̃nƒbƒVƒ…‚ð“o˜^ -BOOL RegisterTrustedModuleMD5Hash(void* pHash) -{ - BOOL bResult; - BYTE NullHash[16] = {0}; - int i; - bResult = FALSE; - if(FindTrustedModuleMD5Hash(pHash)) - bResult = TRUE; - else - { - i = 0; - while(i < MAX_TRUSTED_MD5_HASH_TABLE) - { - if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 16) == 0) - { - memcpy(&g_TrustedMD5HashTable[i], pHash, 16); - bResult = TRUE; - break; - } - i++; - } - } - return bResult; -} - -// DLL‚̃nƒbƒVƒ…‚Ì“o˜^‚ð‰ðœ -BOOL UnregisterTrustedModuleMD5Hash(void* pHash) -{ - BOOL bResult; - BYTE NullHash[16] = {0}; - int i; - bResult = FALSE; - i = 0; - while(i < MAX_TRUSTED_MD5_HASH_TABLE) - { - if(memcmp(&g_TrustedMD5HashTable[i], pHash, 16) == 0) - { - memcpy(&g_TrustedMD5HashTable[i], &NullHash, 16); - bResult = TRUE; - break; - } - i++; - } - return bResult; -} - -// M—Š‚Å‚«‚È‚¢DLL‚ðƒAƒ“ƒ[ƒh -BOOL UnloadUntrustedModule() -{ - BOOL bResult; - wchar_t* pw0; - HANDLE hSnapshot; - MODULEENTRY32 me; - DWORD Length; - bResult = FALSE; - pw0 = NULL; - if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE) - { - bResult = TRUE; - me.dwSize = sizeof(MODULEENTRY32); - if(Module32First(hSnapshot, &me)) - { - do - { - Length = MAX_PATH; - FreeDuplicatedString(pw0); - if(pw0 = AllocateStringW(Length)) - { - if(GetModuleFileNameW(me.hModule, pw0, Length) > 0) - { - while(pw0) - { - if(GetModuleFileNameW(me.hModule, pw0, Length) + 1 <= Length) - break; - Length = Length * 2; - FreeDuplicatedString(pw0); - pw0 = AllocateStringW(Length); - } - } - } - if(pw0) - { - if(!IsModuleTrusted(pw0)) - { - if(me.hModule != GetModuleHandleW(NULL)) - { - while(FreeLibrary(me.hModule)) - { - } - if(GetModuleFileNameW(me.hModule, pw0, Length) > 0) - { - bResult = FALSE; - break; - } - } - } - } - else - { - bResult = FALSE; - break; - } - } - while(Module32Next(hSnapshot, &me)); - } - CloseHandle(hSnapshot); - } - FreeDuplicatedString(pw0); - return bResult; -} - -// ŠÖ”ƒ|ƒCƒ“ƒ^‚ðŽg—p‰Â”\‚ȏó‘Ԃɏ‰Šú‰» -BOOL InitializeLoadLibraryHook() -{ - BOOL bResult; - HMODULE hModule; - bResult = TRUE; - if(!(hModule = GetModuleHandleW(L"kernel32.dll"))) - bResult = FALSE; - if(!(GET_FUNCTION(hModule, LoadLibraryA))) - bResult = FALSE; - if(!(GET_FUNCTION(hModule, LoadLibraryW))) - bResult = FALSE; - if(!(GET_FUNCTION(hModule, LoadLibraryExA))) - bResult = FALSE; - if(!(GET_FUNCTION(hModule, LoadLibraryExW))) - bResult = FALSE; - if(!(hModule = GetModuleHandleW(L"ntdll.dll"))) - bResult = FALSE; - if(!(GET_FUNCTION(hModule, LdrLoadDll))) - bResult = FALSE; - if(!(GET_FUNCTION(hModule, LdrGetDllHandle))) - bResult = FALSE; - if(!(GET_FUNCTION(hModule, RtlImageNtHeader))) - bResult = FALSE; - if(!(hModule = LoadLibraryW(L"wintrust.dll"))) - bResult = FALSE; - if(!(GET_FUNCTION(hModule, CryptCATAdminCalcHashFromFileHandle))) - bResult = FALSE; - return bResult; -} - -// SetWindowsHookEx‘΍ô -// DLL Injection‚³‚ꂽê‡‚͏ã‚Ìh_LoadLibraryŒnŠÖ”‚Ńgƒ‰ƒbƒv‰Â”\ -BOOL EnableLoadLibraryHook(BOOL bEnable) -{ - BOOL bResult; - bResult = FALSE; - if(bEnable) - { - bResult = TRUE; -#ifdef USE_CODE_HOOK - if(!SET_HOOK_FUNCTION(LoadLibraryA)) - bResult = FALSE; - if(!SET_HOOK_FUNCTION(LoadLibraryW)) - bResult = FALSE; - if(!SET_HOOK_FUNCTION(LoadLibraryExA)) - bResult = FALSE; - if(!SET_HOOK_FUNCTION(LoadLibraryExW)) - bResult = FALSE; -#endif -#ifdef USE_IAT_HOOK - if(!HookFunctionInIAT(p_LoadLibraryA, h_LoadLibraryA)) - bResult = FALSE; - if(!HookFunctionInIAT(p_LoadLibraryW, h_LoadLibraryW)) - bResult = FALSE; - if(!HookFunctionInIAT(p_LoadLibraryExA, h_LoadLibraryExA)) - bResult = FALSE; - if(!HookFunctionInIAT(p_LoadLibraryExW, h_LoadLibraryExW)) - bResult = FALSE; -#endif - } - else - { - bResult = TRUE; -#ifdef USE_CODE_HOOK - if(!END_HOOK_FUNCTION(LoadLibraryA)) - bResult = FALSE; - if(!END_HOOK_FUNCTION(LoadLibraryW)) - bResult = FALSE; - if(!END_HOOK_FUNCTION(LoadLibraryExA)) - bResult = FALSE; - if(!END_HOOK_FUNCTION(LoadLibraryExW)) - bResult = FALSE; -#endif -#ifdef USE_IAT_HOOK - if(!HookFunctionInIAT(h_LoadLibraryA, p_LoadLibraryA)) - bResult = FALSE; - if(!HookFunctionInIAT(h_LoadLibraryW, p_LoadLibraryW)) - bResult = FALSE; - if(!HookFunctionInIAT(h_LoadLibraryExA, p_LoadLibraryExA)) - bResult = FALSE; - if(!HookFunctionInIAT(h_LoadLibraryExW, p_LoadLibraryExW)) - bResult = FALSE; -#endif - } - return bResult; -} - -// ReadProcessMemoryAWriteProcessMemoryACreateRemoteThread‘΍ô -// TerminateProcess‚Ì‚Ý‹–‰Â -BOOL RestartProtectedProcess(LPCTSTR Keyword) -{ - BOOL bResult; - ACL* pACL; - SID_IDENTIFIER_AUTHORITY sia = SECURITY_WORLD_SID_AUTHORITY; - PSID pSID; - SECURITY_DESCRIPTOR sd; - TCHAR* CommandLine; - SECURITY_ATTRIBUTES sa; - STARTUPINFO si; - PROCESS_INFORMATION pi; - bResult = FALSE; - if(_tcslen(GetCommandLine()) >= _tcslen(Keyword) && _tcscmp(GetCommandLine() + _tcslen(GetCommandLine()) - _tcslen(Keyword), Keyword) == 0) - return FALSE; - if(pACL = (ACL*)malloc(sizeof(ACL) + 1024)) - { - if(InitializeAcl(pACL, sizeof(ACL) + 1024, ACL_REVISION)) - { - if(AllocateAndInitializeSid(&sia, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSID)) - { - if(AddAccessAllowedAce(pACL, ACL_REVISION, PROCESS_TERMINATE, pSID)) - { - if(InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) - { - if(SetSecurityDescriptorDacl(&sd, TRUE, pACL, FALSE)) - { - if(CommandLine = (TCHAR*)malloc(sizeof(TCHAR) * (_tcslen(GetCommandLine()) + _tcslen(Keyword) + 1))) - { - _tcscpy(CommandLine, GetCommandLine()); - _tcscat(CommandLine, Keyword); - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.lpSecurityDescriptor = &sd; - sa.bInheritHandle = FALSE; - GetStartupInfo(&si); - if(CreateProcess(NULL, CommandLine, &sa, NULL, FALSE, 0, NULL, NULL, &si, &pi)) - { - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - bResult = TRUE; - } - free(CommandLine); - } - } - } - } - FreeSid(pSID); - } - } - free(pACL); - } - return bResult; -} - +// protectprocess.c +// Copyright (C) 2011 Suguru Kawamoto +// プロセスの保護 + +// 次の中から1個のみ有効にする +// フック先の関数のコードを書き換える +// 全ての呼び出しをフック可能だが原理的に二重呼び出しに対応できない +#define USE_CODE_HOOK +// フック先の関数のインポートアドレステーブルを書き換える +// 二重呼び出しが可能だが呼び出し方法によってはフックを回避される +//#define USE_IAT_HOOK + +// フック対象の関数名 %s +// フック対象の型 _%s +// フック対象のポインタ p_%s +// フック用の関数名 h_%s +// フック対象のコードのバックアップ c_%s + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef USE_IAT_HOOK +#include +#endif + +#define DO_NOT_REPLACE +#include "protectprocess.h" +#include "mbswrapper.h" + +#ifdef USE_IAT_HOOK +#pragma comment(lib, "dbghelp.lib") +#endif + +#ifdef USE_CODE_HOOK +#if defined(_X86_) +#define HOOK_JUMP_CODE_LENGTH 5 +#elif defined(_AMD64_) +#define HOOK_JUMP_CODE_LENGTH 14 +#endif +#endif + +BOOL LockThreadLock(); +BOOL UnlockThreadLock(); +#ifdef USE_CODE_HOOK +BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore); +#endif +#ifdef USE_IAT_HOOK +BOOL HookFunctionInIAT(void* pOriginal, void* pNew); +#endif +HANDLE LockExistingFile(LPCWSTR Filename); +BOOL FindTrustedModuleSHA1Hash(void* pHash); +BOOL VerifyFileSignature(LPCWSTR Filename); +BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename); +BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash); +BOOL IsModuleTrusted(LPCWSTR Filename); + +// 変数の宣言 +#ifdef USE_CODE_HOOK +#define HOOK_FUNCTION_VAR(name) _##name p_##name;BYTE c_##name[HOOK_JUMP_CODE_LENGTH * 2]; +#endif +#ifdef USE_IAT_HOOK +#define HOOK_FUNCTION_VAR(name) _##name p_##name; +#endif +// 関数ポインタを取得 +#define GET_FUNCTION(h, name) p_##name = (_##name)GetProcAddress(h, #name) +// フック対象のコードを置換してフックを開始 +#define SET_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE) +// フック対象を呼び出す前に対象のコードを復元 +#define START_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, TRUE) +// フック対象を呼び出した後に対象のコードを置換 +#define END_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, NULL, FALSE) + +HOOK_FUNCTION_VAR(LoadLibraryA) +HOOK_FUNCTION_VAR(LoadLibraryW) +HOOK_FUNCTION_VAR(LoadLibraryExA) +HOOK_FUNCTION_VAR(LoadLibraryExW) + +typedef NTSTATUS (NTAPI* _LdrLoadDll)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*); +typedef NTSTATUS (NTAPI* _LdrGetDllHandle)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*); +typedef PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)(PVOID); +typedef BOOL (WINAPI* _CryptCATAdminCalcHashFromFileHandle)(HANDLE, DWORD*, BYTE*, DWORD); + +_LdrLoadDll p_LdrLoadDll; +_LdrGetDllHandle p_LdrGetDllHandle; +_RtlImageNtHeader p_RtlImageNtHeader; +_CryptCATAdminCalcHashFromFileHandle p_CryptCATAdminCalcHashFromFileHandle; + +#define MAX_LOCKED_THREAD 16 +#define MAX_TRUSTED_FILENAME_TABLE 16 +#define MAX_TRUSTED_MD5_HASH_TABLE 16 + +DWORD g_ProcessProtectionLevel; +DWORD g_LockedThread[MAX_LOCKED_THREAD]; +WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE]; +BYTE g_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][20]; + +// 以下フック関数 +// フック対象を呼び出す場合は前後でSTART_HOOK_FUNCTIONとEND_HOOK_FUNCTIONを実行する必要がある + +HMODULE WINAPI h_LoadLibraryA(LPCSTR lpLibFileName) +{ + HMODULE r = NULL; + wchar_t* pw0 = NULL; + if(pw0 = DuplicateAtoW(lpLibFileName, -1)) + r = LoadLibraryExW(pw0, NULL, 0); + FreeDuplicatedString(pw0); + return r; +} + +HMODULE WINAPI h_LoadLibraryW(LPCWSTR lpLibFileName) +{ + HMODULE r = NULL; + r = LoadLibraryExW(lpLibFileName, NULL, 0); + return r; +} + +HMODULE WINAPI h_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE r = NULL; + wchar_t* pw0 = NULL; + if(pw0 = DuplicateAtoW(lpLibFileName, -1)) + r = LoadLibraryExW(pw0, hFile, dwFlags); + FreeDuplicatedString(pw0); + return r; +} + +HMODULE WINAPI h_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE r = NULL; + BOOL bTrusted; + wchar_t* pw0; + HANDLE hLock; + HMODULE hModule; + DWORD Length; + bTrusted = FALSE; + pw0 = NULL; + hLock = NULL; +// if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) + if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | 0x00000020 | 0x00000040)) + bTrusted = TRUE; + if(!bTrusted) + { + if(hModule = System_LoadLibrary(lpLibFileName, NULL, DONT_RESOLVE_DLL_REFERENCES)) + { + Length = MAX_PATH; + if(pw0 = AllocateStringW(Length)) + { + if(GetModuleFileNameW(hModule, pw0, Length) > 0) + { + while(pw0) + { + if(GetModuleFileNameW(hModule, pw0, Length) + 1 <= Length) + { + lpLibFileName = pw0; + break; + } + Length = Length * 2; + FreeDuplicatedString(pw0); + pw0 = AllocateStringW(Length); + } + } + } + hLock = LockExistingFile(lpLibFileName); + FreeLibrary(hModule); + } + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_LOADED) && GetModuleHandleW(lpLibFileName)) + bTrusted = TRUE; + } + if(!bTrusted) + { + if(hLock) + { + if(IsModuleTrusted(lpLibFileName)) + bTrusted = TRUE; + } + } + if(bTrusted) + r = System_LoadLibrary(lpLibFileName, hFile, dwFlags); + FreeDuplicatedString(pw0); + if(hLock) + CloseHandle(hLock); + return r; +} + +// 以下ヘルパー関数 + +BOOL LockThreadLock() +{ + BOOL bResult; + DWORD ThreadId; + DWORD i; + bResult = FALSE; + ThreadId = GetCurrentThreadId(); + i = 0; + while(i < MAX_LOCKED_THREAD) + { + if(g_LockedThread[i] == ThreadId) + break; + i++; + } + if(i >= MAX_LOCKED_THREAD) + { + i = 0; + while(i < MAX_LOCKED_THREAD) + { + if(g_LockedThread[i] == 0) + { + g_LockedThread[i] = ThreadId; + bResult = TRUE; + break; + } + i++; + } + } + return bResult; +} + +BOOL UnlockThreadLock() +{ + BOOL bResult; + DWORD ThreadId; + DWORD i; + bResult = FALSE; + ThreadId = GetCurrentThreadId(); + i = 0; + while(i < MAX_LOCKED_THREAD) + { + if(g_LockedThread[i] == ThreadId) + { + g_LockedThread[i] = 0; + bResult = TRUE; + break; + } + i++; + } + return bResult; +} + +#ifdef USE_CODE_HOOK +BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore) +{ + BOOL bResult; + DWORD Protect; +#if defined(_X86_) + BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xe9, 0x00, 0x00, 0x00, 0x00}; + size_t Relative; + Relative = (size_t)pNew - (size_t)pOriginal - HOOK_JUMP_CODE_LENGTH; + memcpy(&JumpCode[1], &Relative, 4); + bResult = FALSE; + if(bRestore) + { + if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect)) + { + memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH); + VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect); + bResult = TRUE; + } + } + else + { + if(pBackupCode) + memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH); + if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect)) + { + memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH); + VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect); + bResult = TRUE; + } + } +#elif defined(_AMD64_) + BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + size_t Absolute; + Absolute = (size_t)pOriginal; + memcpy(&JumpCode[6], &Absolute, 8); + bResult = FALSE; + if(bRestore) + { + if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect)) + { + memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH); + VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect); + bResult = TRUE; + } + } + else + { + if(pBackupCode) + memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH); + if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect)) + { + memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH); + VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect); + bResult = TRUE; + } + } +#endif + return bResult; +} +#endif + +#ifdef USE_IAT_HOOK +BOOL HookFunctionInIAT(void* pOriginal, void* pNew) +{ + BOOL bResult; + HANDLE hSnapshot; + MODULEENTRY32 me; + BOOL bFound; + IMAGE_IMPORT_DESCRIPTOR* piid; + ULONG Size; + IMAGE_THUNK_DATA* pitd; + DWORD Protect; + bResult = FALSE; + if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE) + { + me.dwSize = sizeof(MODULEENTRY32); + if(Module32First(hSnapshot, &me)) + { + bFound = FALSE; + do + { + if(piid = (IMAGE_IMPORT_DESCRIPTOR*)ImageDirectoryEntryToData(me.hModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size)) + { + while(!bFound && piid->Name != 0) + { + pitd = (IMAGE_THUNK_DATA*)((BYTE*)me.hModule + piid->FirstThunk); + while(!bFound && pitd->u1.Function != 0) + { + if((void*)pitd->u1.Function == pOriginal) + { + bFound = TRUE; + if(VirtualProtect(&pitd->u1.Function, sizeof(void*), PAGE_EXECUTE_READWRITE, &Protect)) + { + memcpy(&pitd->u1.Function, &pNew, sizeof(void*)); + VirtualProtect(&pitd->u1.Function, sizeof(void*), Protect, &Protect); + bResult = TRUE; + } + } + pitd++; + } + piid++; + } + } + } + while(!bFound && Module32Next(hSnapshot, &me)); + } + CloseHandle(hSnapshot); + } + return bResult; +} +#endif + +// ファイルを変更不能に設定 +HANDLE LockExistingFile(LPCWSTR Filename) +{ + HANDLE hResult; + hResult = NULL; + if((hResult = CreateFileW(Filename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)) == INVALID_HANDLE_VALUE) + hResult = NULL; + return hResult; +} + +// DLLのハッシュを検索 +BOOL FindTrustedModuleSHA1Hash(void* pHash) +{ + BOOL bResult; + int i; + bResult = FALSE; + i = 0; + while(i < MAX_TRUSTED_MD5_HASH_TABLE) + { + if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0) + { + bResult = TRUE; + break; + } + i++; + } + return bResult; +} + +BOOL VerifyFileSignature_Function(LPCWSTR Filename) +{ + BOOL bResult; + HCERTSTORE hStore; + PCCERT_CONTEXT pcc; + CERT_CHAIN_PARA ccp; + CERT_CHAIN_CONTEXT* pccc; + CERT_CHAIN_POLICY_PARA ccpp; + CERT_CHAIN_POLICY_STATUS ccps; + bResult = FALSE; + if(CryptQueryObject(CERT_QUERY_OBJECT_FILE, Filename, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL, NULL, &hStore, NULL, NULL)) + { + pcc = NULL; + while(!bResult && (pcc = CertEnumCertificatesInStore(hStore, pcc))) + { + ZeroMemory(&ccp, sizeof(CERT_CHAIN_PARA)); + ccp.cbSize = sizeof(CERT_CHAIN_PARA); + if(CertGetCertificateChain(NULL, pcc, NULL, NULL, &ccp, 0, NULL, &pccc)) + { + ZeroMemory(&ccpp, sizeof(CERT_CHAIN_POLICY_PARA)); + ccpp.cbSize = sizeof(CERT_CHAIN_POLICY_PARA); + if(g_ProcessProtectionLevel & PROCESS_PROTECTION_EXPIRED) + ccpp.dwFlags |= CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG; + else if(g_ProcessProtectionLevel & PROCESS_PROTECTION_UNAUTHORIZED) + ccpp.dwFlags |= CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG; + ZeroMemory(&ccps, sizeof(CERT_CHAIN_POLICY_STATUS)); + ccps.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS); + if(CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, pccc, &ccpp, &ccps)) + { + if(ccps.dwError == ERROR_SUCCESS) + { + bResult = TRUE; + break; + } + } + CertFreeCertificateChain(pccc); + } + } + while(pcc = CertEnumCertificatesInStore(hStore, pcc)) + { + } + CertCloseStore(hStore, 0); + } + return bResult; +} + +// ファイルの署名を確認 +BOOL VerifyFileSignature(LPCWSTR Filename) +{ + BOOL bResult; + GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2; + WINTRUST_FILE_INFO wfi; + WINTRUST_DATA wd; + bResult = FALSE; + ZeroMemory(&wfi, sizeof(WINTRUST_FILE_INFO)); + wfi.cbStruct = sizeof(WINTRUST_FILE_INFO); + wfi.pcwszFilePath = Filename; + ZeroMemory(&wd, sizeof(WINTRUST_DATA)); + wd.cbStruct = sizeof(WINTRUST_DATA); + wd.dwUIChoice = WTD_UI_NONE; + wd.dwUnionChoice = WTD_CHOICE_FILE; + wd.pFile = &wfi; + if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS) + bResult = TRUE; + else + bResult = VerifyFileSignature_Function(Filename); + return bResult; +} + +// ファイルの署名をカタログファイルで確認 +BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename) +{ + BOOL bResult; + GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2; + WINTRUST_CATALOG_INFO wci; + WINTRUST_DATA wd; + bResult = FALSE; + if(VerifyFileSignature(Catalog)) + { + ZeroMemory(&wci, sizeof(WINTRUST_CATALOG_INFO)); + wci.cbStruct = sizeof(WINTRUST_CATALOG_INFO); + wci.pcwszCatalogFilePath = Catalog; + wci.pcwszMemberFilePath = Filename; + if((wci.hMemberFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) + { + p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, NULL, 0); + if(wci.pbCalculatedFileHash = (BYTE*)malloc(wci.cbCalculatedFileHash)) + { + if(p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, wci.pbCalculatedFileHash, 0)) + { + ZeroMemory(&wd, sizeof(WINTRUST_DATA)); + wd.cbStruct = sizeof(WINTRUST_DATA); + wd.dwUIChoice = WTD_UI_NONE; + wd.dwUnionChoice = WTD_CHOICE_CATALOG; + wd.pCatalog = &wci; + if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS) + bResult = TRUE; + } + free(wci.pbCalculatedFileHash); + } + CloseHandle(wci.hMemberFile); + } + } + return bResult; +} + +BOOL WINAPI GetSHA1HashOfModule_Function(DIGEST_HANDLE refdata, PBYTE pData, DWORD dwLength) +{ + return CryptHashData(*(HCRYPTHASH*)refdata, pData, dwLength, 0); +} + +// モジュールのSHA1ハッシュを取得 +// マニフェストファイルのfile要素のhash属性は実行可能ファイルの場合にImageGetDigestStreamで算出される +BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash) +{ + BOOL bResult; + HCRYPTPROV hProv; + HCRYPTHASH hHash; + HANDLE hFile; + DWORD dw; + bResult = FALSE; + if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) + { + if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) + { + if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) + { + if(ImageGetDigestStream(hFile, CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO, GetSHA1HashOfModule_Function, (DIGEST_HANDLE)&hHash)) + { + dw = 20; + if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0)) + bResult = TRUE; + } + CloseHandle(hFile); + } + CryptDestroyHash(hHash); + } + CryptReleaseContext(hProv, 0); + } + return bResult; +} + +BOOL IsSxsModuleTrusted_Function(LPCWSTR Catalog, LPCWSTR Manifest, LPCWSTR Module) +{ + BOOL bResult; + HANDLE hLock0; + HANDLE hLock1; + BYTE Hash[20]; + int i; + static char HexTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + char HashHex[41]; + HANDLE hFile; + DWORD Size; + char* pData; + DWORD dw; + bResult = FALSE; + if(hLock0 = LockExistingFile(Catalog)) + { + if(hLock1 = LockExistingFile(Manifest)) + { + if(VerifyFileSignatureInCatalog(Catalog, Manifest)) + { + if(GetSHA1HashOfModule(Module, &Hash)) + { + for(i = 0; i < 20; i++) + { + HashHex[i * 2] = HexTable[(Hash[i] >> 4) & 0x0f]; + HashHex[i * 2 + 1] = HexTable[Hash[i] & 0x0f]; + } + HashHex[i * 2] = '\0'; + if((hFile = CreateFileW(Manifest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) + { + Size = GetFileSize(hFile, NULL); + if(pData = (char*)VirtualAlloc(NULL, Size + 1, MEM_COMMIT, PAGE_READWRITE)) + { + VirtualLock(pData, Size + 1); + if(ReadFile(hFile, pData, Size, &dw, NULL)) + { + pData[dw] = '\0'; + if(strstr(pData, HashHex)) + bResult = TRUE; + } + VirtualUnlock(pData, Size + 1); + VirtualFree(pData, Size + 1, MEM_DECOMMIT); + } + CloseHandle(hFile); + } + } + } + CloseHandle(hLock1); + } + CloseHandle(hLock0); + } + return bResult; +} + +// サイドバイサイドDLLを確認 +// パスは"%SystemRoot%\WinSxS"以下を想定 +// 以下のファイルが存在するものとする +// "\xxx\yyy.dll"、"\manifests\xxx.cat"、"\manifests\xxx.manifest"のセット(XPの全てのDLL、Vista以降の一部のDLL) +// "\xxx\yyy.dll"、"\catalogs\zzz.cat"、"\manifests\xxx.manifest"のセット(Vista以降のほとんどのDLL) +// 署名されたカタログファイルを用いてマニフェストファイルが改竄されていないことを確認 +// ハッシュ値は マニフェストファイルのfile要素のhash属性に記述されているものを用いる +// マニフェストファイル内にSHA1ハッシュ値の16進数表記を直接検索しているが確率的に問題なし +BOOL IsSxsModuleTrusted(LPCWSTR Filename) +{ + BOOL bResult; + wchar_t* pw0; + wchar_t* pw1; + wchar_t* pw2; + wchar_t* pw3; + wchar_t* pw4; + wchar_t* pw5; + wchar_t* p; + HANDLE hFind; + WIN32_FIND_DATAW wfd; + bResult = FALSE; + if(pw0 = AllocateStringW(wcslen(Filename) + 1)) + { + wcscpy(pw0, Filename); + if(p = wcsrchr(pw0, L'\\')) + { + wcscpy(p, L""); + if(p = wcsrchr(pw0, L'\\')) + { + p++; + if(pw1 = AllocateStringW(wcslen(p) + 1)) + { + wcscpy(pw1, p); + wcscpy(p, L""); + if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".cat") + 1)) + { + wcscpy(pw2, pw0); + wcscat(pw2, L"manifests\\"); + wcscat(pw2, pw1); + if(pw3 = AllocateStringW(wcslen(pw2) + wcslen(L".manifest") + 1)) + { + wcscpy(pw3, pw2); + wcscat(pw3, L".manifest"); + wcscat(pw2, L".cat"); + if(IsSxsModuleTrusted_Function(pw2, pw3, Filename)) + bResult = TRUE; + FreeDuplicatedString(pw3); + } + FreeDuplicatedString(pw2); + } + if(!bResult) + { + if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"catalogs\\") + 1)) + { + if(pw3 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".manifest") + 1)) + { + wcscpy(pw2, pw0); + wcscat(pw2, L"catalogs\\"); + wcscpy(pw3, pw0); + wcscat(pw3, L"manifests\\"); + wcscat(pw3, pw1); + wcscat(pw3, L".manifest"); + if(pw4 = AllocateStringW(wcslen(pw2) + wcslen(L"*.cat") + 1)) + { + wcscpy(pw4, pw2); + wcscat(pw4, L"*.cat"); + if((hFind = FindFirstFileW(pw4, &wfd)) != INVALID_HANDLE_VALUE) + { + do + { + if(pw5 = AllocateStringW(wcslen(pw2) + wcslen(wfd.cFileName) + 1)) + { + wcscpy(pw5, pw2); + wcscat(pw5, wfd.cFileName); + if(IsSxsModuleTrusted_Function(pw5, pw3, Filename)) + bResult = TRUE; + FreeDuplicatedString(pw5); + } + } + while(!bResult && FindNextFileW(hFind, &wfd)); + FindClose(hFind); + } + FreeDuplicatedString(pw4); + } + FreeDuplicatedString(pw3); + } + FreeDuplicatedString(pw2); + } + } + FreeDuplicatedString(pw1); + } + } + } + FreeDuplicatedString(pw0); + } + return bResult; +} + +// DLLを確認 +BOOL IsModuleTrusted(LPCWSTR Filename) +{ + BOOL bResult; + BYTE Hash[20]; + bResult = FALSE; + if(LockThreadLock()) + { + if(GetSHA1HashOfFile(Filename, &Hash)) + { + if(FindTrustedModuleSHA1Hash(&Hash)) + bResult = TRUE; + } + if(!bResult) + { + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_BUILTIN) && VerifyFileSignature(Filename)) + bResult = TRUE; + } + if(!bResult) + { + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SIDE_BY_SIDE) && IsSxsModuleTrusted(Filename)) + bResult = TRUE; + } + if(!bResult) + { + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SYSTEM_FILE) && SfcIsFileProtected(NULL, Filename)) + bResult = TRUE; + } + UnlockThreadLock(); + } + return bResult; +} + +// kernel32.dllのLoadLibraryExW相当の関数 +// ドキュメントが無いため詳細は不明 +// 一部のウィルス対策ソフト(Avast!等)がLdrLoadDllをフックしているためLdrLoadDllを書き換えるべきではない +// カーネルモードのコードに対しては効果なし +// SeDebugPrivilegeが使用可能なユーザーに対しては効果なし +HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE r = NULL; + UNICODE_STRING us; + HANDLE hDataFile; + HANDLE hMapping; + DWORD DllFlags; + us.Length = sizeof(wchar_t) * wcslen(lpLibFileName); + us.MaximumLength = sizeof(wchar_t) * (wcslen(lpLibFileName) + 1); + us.Buffer = (PWSTR)lpLibFileName; +// if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) + if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040)) + { +// if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == STATUS_SUCCESS) + if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == 0) + { +// dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); + dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040); + dwFlags |= DONT_RESOLVE_DLL_REFERENCES; + } + else + { +// if(dwFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE) + if(dwFlags & 0x00000040) + hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + else + hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); + if(hDataFile != INVALID_HANDLE_VALUE) + { + if(hMapping = CreateFileMappingW(hDataFile, NULL, PAGE_READONLY, 0, 0, NULL)) + { + if(r = (HMODULE)MapViewOfFileEx(hMapping, FILE_MAP_READ, 0, 0, 0, NULL)) + { + if(p_RtlImageNtHeader(r)) + r = (HMODULE)((size_t)r | 1); + else + { + UnmapViewOfFile(r); + r = NULL; + } + } + CloseHandle(hMapping); + } + CloseHandle(hDataFile); + } + else + { +// dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); + dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040); + dwFlags |= DONT_RESOLVE_DLL_REFERENCES; + } + } + } +// if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))) + if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040))) + { + DllFlags = 0; +// if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) + if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | 0x00000020)) + DllFlags |= 0x00000002; +// if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == STATUS_SUCCESS) + if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == 0) + { + } + else + r = NULL; + } + return r; +} + +void SetProcessProtectionLevel(DWORD Level) +{ + g_ProcessProtectionLevel = Level; +} + +// ファイルのSHA1ハッシュを取得 +BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash) +{ + BOOL bResult; + HCRYPTPROV hProv; + HCRYPTHASH hHash; + HANDLE hFile; + DWORD Size; + void* pData; + DWORD dw; + bResult = FALSE; + if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) + { + if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) + { + if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) + { + Size = GetFileSize(hFile, NULL); + if(pData = VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE)) + { + VirtualLock(pData, Size); + if(ReadFile(hFile, pData, Size, &dw, NULL)) + { + if(CryptHashData(hHash, (BYTE*)pData, Size, 0)) + { + dw = 20; + if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0)) + bResult = TRUE; + } + } + VirtualUnlock(pData, Size); + VirtualFree(pData, Size, MEM_DECOMMIT); + } + CloseHandle(hFile); + } + CryptDestroyHash(hHash); + } + CryptReleaseContext(hProv, 0); + } + return bResult; +} + +// DLLのハッシュを登録 +BOOL RegisterTrustedModuleSHA1Hash(void* pHash) +{ + BOOL bResult; + BYTE NullHash[20] = {0}; + int i; + bResult = FALSE; + if(FindTrustedModuleSHA1Hash(pHash)) + bResult = TRUE; + else + { + i = 0; + while(i < MAX_TRUSTED_MD5_HASH_TABLE) + { + if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 20) == 0) + { + memcpy(&g_TrustedMD5HashTable[i], pHash, 20); + bResult = TRUE; + break; + } + i++; + } + } + return bResult; +} + +// DLLのハッシュの登録を解除 +BOOL UnregisterTrustedModuleSHA1Hash(void* pHash) +{ + BOOL bResult; + BYTE NullHash[20] = {0}; + int i; + bResult = FALSE; + i = 0; + while(i < MAX_TRUSTED_MD5_HASH_TABLE) + { + if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0) + { + memcpy(&g_TrustedMD5HashTable[i], &NullHash, 20); + bResult = TRUE; + break; + } + i++; + } + return bResult; +} + +// 信頼できないDLLをアンロード +BOOL UnloadUntrustedModule() +{ + BOOL bResult; + wchar_t* pw0; + HANDLE hSnapshot; + MODULEENTRY32 me; + DWORD Length; + bResult = FALSE; + pw0 = NULL; + if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE) + { + bResult = TRUE; + me.dwSize = sizeof(MODULEENTRY32); + if(Module32First(hSnapshot, &me)) + { + do + { + Length = MAX_PATH; + FreeDuplicatedString(pw0); + if(pw0 = AllocateStringW(Length)) + { + if(GetModuleFileNameW(me.hModule, pw0, Length) > 0) + { + while(pw0) + { + if(GetModuleFileNameW(me.hModule, pw0, Length) + 1 <= Length) + break; + Length = Length * 2; + FreeDuplicatedString(pw0); + pw0 = AllocateStringW(Length); + } + } + } + if(pw0) + { + if(!IsModuleTrusted(pw0)) + { + if(me.hModule != GetModuleHandleW(NULL)) + { + while(FreeLibrary(me.hModule)) + { + } + if(GetModuleFileNameW(me.hModule, pw0, Length) > 0) + { + bResult = FALSE; + break; + } + } + } + } + else + { + bResult = FALSE; + break; + } + } + while(Module32Next(hSnapshot, &me)); + } + CloseHandle(hSnapshot); + } + FreeDuplicatedString(pw0); + return bResult; +} + +// 関数ポインタを使用可能な状態に初期化 +BOOL InitializeLoadLibraryHook() +{ + BOOL bResult; + HMODULE hModule; + bResult = TRUE; + if(!(hModule = GetModuleHandleW(L"kernel32.dll"))) + bResult = FALSE; + if(!(GET_FUNCTION(hModule, LoadLibraryA))) + bResult = FALSE; + if(!(GET_FUNCTION(hModule, LoadLibraryW))) + bResult = FALSE; + if(!(GET_FUNCTION(hModule, LoadLibraryExA))) + bResult = FALSE; + if(!(GET_FUNCTION(hModule, LoadLibraryExW))) + bResult = FALSE; + if(!(hModule = GetModuleHandleW(L"ntdll.dll"))) + bResult = FALSE; + if(!(GET_FUNCTION(hModule, LdrLoadDll))) + bResult = FALSE; + if(!(GET_FUNCTION(hModule, LdrGetDllHandle))) + bResult = FALSE; + if(!(GET_FUNCTION(hModule, RtlImageNtHeader))) + bResult = FALSE; + if(!(hModule = LoadLibraryW(L"wintrust.dll"))) + bResult = FALSE; + if(!(GET_FUNCTION(hModule, CryptCATAdminCalcHashFromFileHandle))) + bResult = FALSE; + return bResult; +} + +// SetWindowsHookEx対策 +// DLL Injectionされた場合は上のh_LoadLibrary系関数でトラップ可能 +BOOL EnableLoadLibraryHook(BOOL bEnable) +{ + BOOL bResult; + bResult = FALSE; + if(bEnable) + { + bResult = TRUE; +#ifdef USE_CODE_HOOK + if(!SET_HOOK_FUNCTION(LoadLibraryA)) + bResult = FALSE; + if(!SET_HOOK_FUNCTION(LoadLibraryW)) + bResult = FALSE; + if(!SET_HOOK_FUNCTION(LoadLibraryExA)) + bResult = FALSE; + if(!SET_HOOK_FUNCTION(LoadLibraryExW)) + bResult = FALSE; +#endif +#ifdef USE_IAT_HOOK + if(!HookFunctionInIAT(p_LoadLibraryA, h_LoadLibraryA)) + bResult = FALSE; + if(!HookFunctionInIAT(p_LoadLibraryW, h_LoadLibraryW)) + bResult = FALSE; + if(!HookFunctionInIAT(p_LoadLibraryExA, h_LoadLibraryExA)) + bResult = FALSE; + if(!HookFunctionInIAT(p_LoadLibraryExW, h_LoadLibraryExW)) + bResult = FALSE; +#endif + } + else + { + bResult = TRUE; +#ifdef USE_CODE_HOOK + if(!END_HOOK_FUNCTION(LoadLibraryA)) + bResult = FALSE; + if(!END_HOOK_FUNCTION(LoadLibraryW)) + bResult = FALSE; + if(!END_HOOK_FUNCTION(LoadLibraryExA)) + bResult = FALSE; + if(!END_HOOK_FUNCTION(LoadLibraryExW)) + bResult = FALSE; +#endif +#ifdef USE_IAT_HOOK + if(!HookFunctionInIAT(h_LoadLibraryA, p_LoadLibraryA)) + bResult = FALSE; + if(!HookFunctionInIAT(h_LoadLibraryW, p_LoadLibraryW)) + bResult = FALSE; + if(!HookFunctionInIAT(h_LoadLibraryExA, p_LoadLibraryExA)) + bResult = FALSE; + if(!HookFunctionInIAT(h_LoadLibraryExW, p_LoadLibraryExW)) + bResult = FALSE; +#endif + } + return bResult; +} + +// ReadProcessMemory、WriteProcessMemory、CreateRemoteThread対策 +// TerminateProcessのみ許可 +BOOL RestartProtectedProcess(LPCTSTR Keyword) +{ + BOOL bResult; + ACL* pACL; + SID_IDENTIFIER_AUTHORITY sia = SECURITY_WORLD_SID_AUTHORITY; + PSID pSID; + SECURITY_DESCRIPTOR sd; + TCHAR* CommandLine; + SECURITY_ATTRIBUTES sa; + STARTUPINFO si; + PROCESS_INFORMATION pi; + bResult = FALSE; + if(_tcslen(GetCommandLine()) >= _tcslen(Keyword) && _tcscmp(GetCommandLine() + _tcslen(GetCommandLine()) - _tcslen(Keyword), Keyword) == 0) + return FALSE; + if(pACL = (ACL*)malloc(sizeof(ACL) + 1024)) + { + if(InitializeAcl(pACL, sizeof(ACL) + 1024, ACL_REVISION)) + { + if(AllocateAndInitializeSid(&sia, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSID)) + { + if(AddAccessAllowedAce(pACL, ACL_REVISION, PROCESS_TERMINATE, pSID)) + { + if(InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) + { + if(SetSecurityDescriptorDacl(&sd, TRUE, pACL, FALSE)) + { + if(CommandLine = (TCHAR*)malloc(sizeof(TCHAR) * (_tcslen(GetCommandLine()) + _tcslen(Keyword) + 1))) + { + _tcscpy(CommandLine, GetCommandLine()); + _tcscat(CommandLine, Keyword); + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = &sd; + sa.bInheritHandle = FALSE; + GetStartupInfo(&si); + if(CreateProcess(NULL, CommandLine, &sa, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + bResult = TRUE; + } + free(CommandLine); + } + } + } + } + FreeSid(pSID); + } + } + free(pACL); + } + return bResult; +} +