-// protectprocess.c
-// Copyright (C) 2011 Suguru Kawamoto
-// \83v\83\8d\83Z\83X\82Ì\95Û\8cì
-
-// \8e\9f\82Ì\92\86\82©\82ç1\8cÂ\82Ì\82Ý\97L\8cø\82É\82·\82é
-// \83t\83b\83N\90æ\82Ì\8aÖ\90\94\82Ì\83R\81[\83h\82ð\8f\91\82«\8a·\82¦\82é
-// \91S\82Ä\82Ì\8cÄ\82Ñ\8fo\82µ\82ð\83t\83b\83N\89Â\94\\82¾\82ª\8c´\97\9d\93I\82É\93ñ\8fd\8cÄ\82Ñ\8fo\82µ\82É\91Î\89\9e\82Å\82«\82È\82¢
-#define USE_CODE_HOOK
-// \83t\83b\83N\90æ\82Ì\8aÖ\90\94\82Ì\83C\83\93\83|\81[\83g\83A\83h\83\8c\83X\83e\81[\83u\83\8b\82ð\8f\91\82«\8a·\82¦\82é
-// \93ñ\8fd\8cÄ\82Ñ\8fo\82µ\82ª\89Â\94\\82¾\82ª\8cÄ\82Ñ\8fo\82µ\95û\96@\82É\82æ\82Á\82Ä\82Í\83t\83b\83N\82ð\89ñ\94ð\82³\82ê\82é
-//#define USE_IAT_HOOK
-
-// \83t\83b\83N\91Î\8fÛ\82Ì\8aÖ\90\94\96¼ %s
-// \83t\83b\83N\91Î\8fÛ\82Ì\8c^ _%s
-// \83t\83b\83N\91Î\8fÛ\82Ì\83|\83C\83\93\83^ p_%s
-// \83t\83b\83N\97p\82Ì\8aÖ\90\94\96¼ h_%s
-// \83t\83b\83N\91Î\8fÛ\82Ì\83R\81[\83h\82Ì\83o\83b\83N\83A\83b\83v c_%s
-
-#include <tchar.h>
-#include <windows.h>
-#include <ntsecapi.h>
-#include <wincrypt.h>
-#include <wintrust.h>
-#include <softpub.h>
-#include <aclapi.h>
-#include <sfc.h>
-#include <tlhelp32.h>
-#include <imagehlp.h>
-#ifdef USE_IAT_HOOK
-#include <dbghelp.h>
-#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);
-
-// \95Ï\90\94\82Ì\90é\8c¾
-#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
-// \8aÖ\90\94\83|\83C\83\93\83^\82ð\8eæ\93¾
-#define GET_FUNCTION(h, name) p_##name = (_##name)GetProcAddress(h, #name)
-// \83t\83b\83N\91Î\8fÛ\82Ì\83R\81[\83h\82ð\92u\8a·\82µ\82Ä\83t\83b\83N\82ð\8aJ\8en
-#define SET_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE)
-// \83t\83b\83N\91Î\8fÛ\82ð\8cÄ\82Ñ\8fo\82·\91O\82É\91Î\8fÛ\82Ì\83R\81[\83h\82ð\95\9c\8c³
-#define START_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, TRUE)
-// \83t\83b\83N\91Î\8fÛ\82ð\8cÄ\82Ñ\8fo\82µ\82½\8cã\82É\91Î\8fÛ\82Ì\83R\81[\83h\82ð\92u\8a·
-#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];
-
-// \88È\89º\83t\83b\83N\8aÖ\90\94
-// \83t\83b\83N\91Î\8fÛ\82ð\8cÄ\82Ñ\8fo\82·\8fê\8d\87\82Í\91O\8cã\82ÅSTART_HOOK_FUNCTION\82ÆEND_HOOK_FUNCTION\82ð\8eÀ\8ds\82·\82é\95K\97v\82ª\82 \82é
-
-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;
-}
-
-// \88È\89º\83w\83\8b\83p\81[\8aÖ\90\94
-
-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
-
-// \83t\83@\83C\83\8b\82ð\95Ï\8dX\95s\94\\82É\90Ý\92è
-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\82Ì\83n\83b\83V\83\85\82ð\8c\9f\8dõ
-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;
-}
-
-// \83t\83@\83C\83\8b\82Ì\8f\90\96¼\82ð\8am\94F
-BOOL VerifyFileSignature(LPCWSTR Filename)
-{
- BOOL bResult;
- GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;
- WINTRUST_FILE_INFO wfi;
- WINTRUST_DATA wd;
- LONG Error;
- 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;
- Error = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd);
- if(Error == ERROR_SUCCESS)
- bResult = TRUE;
- else if((g_ProcessProtectionLevel & PROCESS_PROTECTION_EXPIRED) && Error == CERT_E_EXPIRED)
- bResult = TRUE;
- else if((g_ProcessProtectionLevel & PROCESS_PROTECTION_UNAUTHORIZED) && (Error == CERT_E_UNTRUSTEDROOT || Error == CERT_E_UNTRUSTEDCA))
- bResult = TRUE;
- return bResult;
-}
-
-// \83t\83@\83C\83\8b\82Ì\8f\90\96¼\82ð\83J\83^\83\8d\83O\83t\83@\83C\83\8b\82Å\8am\94F
-BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename)
-{
- BOOL bResult;
- GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;
- WINTRUST_CATALOG_INFO wci;
- WINTRUST_DATA wd;
- LONG Error;
- 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;
- Error = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd);
- if(Error == ERROR_SUCCESS)
- bResult = TRUE;
- else if((g_ProcessProtectionLevel & PROCESS_PROTECTION_EXPIRED) && Error == CERT_E_EXPIRED)
- bResult = TRUE;
- else if((g_ProcessProtectionLevel & PROCESS_PROTECTION_UNAUTHORIZED) && (Error == CERT_E_UNTRUSTEDROOT || Error == CERT_E_UNTRUSTEDCA))
- 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);
-}
-
-// \83\82\83W\83\85\81[\83\8b\82ÌSHA1\83n\83b\83V\83\85\82ð\8eæ\93¾
-// \83}\83j\83t\83F\83X\83g\83t\83@\83C\83\8b\82Ìfile\97v\91f\82Ìhash\91®\90«\82Í\8eÀ\8ds\89Â\94\\83t\83@\83C\83\8b\82Ì\8fê\8d\87\82ÉImageGetDigestStream\82Å\8eZ\8fo\82³\82ê\82é
-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;
-}
-
-// \83T\83C\83h\83o\83C\83T\83C\83hDLL\82ð\8am\94F
-// \83p\83X\82Í"%SystemRoot%\WinSxS"\88È\89º\82ð\91z\92è
-// \88È\89º\82Ì\83t\83@\83C\83\8b\82ª\91¶\8dÝ\82·\82é\82à\82Ì\82Æ\82·\82é
-// "\xxx\yyy.dll"\81A"\manifests\xxx.cat"\81A"\manifests\xxx.manifest"\82Ì\83Z\83b\83g\81iXP\82Ì\91S\82Ä\82ÌDLL\81AVista\88È\8d~\82Ì\88ê\95\94\82ÌDLL\81j
-// "\xxx\yyy.dll"\81A"\catalogs\zzz.cat"\81A"\manifests\xxx.manifest"\82Ì\83Z\83b\83g\81iVista\88È\8d~\82Ì\82Ù\82Æ\82ñ\82Ç\82ÌDLL\81j
-// \8f\90\96¼\82³\82ê\82½\83J\83^\83\8d\83O\83t\83@\83C\83\8b\82ð\97p\82¢\82Ä\83}\83j\83t\83F\83X\83g\83t\83@\83C\83\8b\82ª\89üâ\82\82³\82ê\82Ä\82¢\82È\82¢\82±\82Æ\82ð\8am\94F
-// \83n\83b\83V\83\85\92l\82Í \83}\83j\83t\83F\83X\83g\83t\83@\83C\83\8b\82Ìfile\97v\91f\82Ìhash\91®\90«\82É\8bL\8fq\82³\82ê\82Ä\82¢\82é\82à\82Ì\82ð\97p\82¢\82é
-// \83}\83j\83t\83F\83X\83g\83t\83@\83C\83\8b\93à\82ÉSHA1\83n\83b\83V\83\85\92l\82Ì16\90i\90\94\95\\8bL\82ð\92¼\90Ú\8c\9f\8dõ\82µ\82Ä\82¢\82é\82ª\8am\97¦\93I\82É\96â\91è\82È\82µ
-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\82ð\8am\94F
-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\82ÌLoadLibraryExW\91\8a\93\96\82Ì\8aÖ\90\94
-// \83h\83L\83\85\83\81\83\93\83g\82ª\96³\82¢\82½\82ß\8fÚ\8d×\82Í\95s\96¾
-// \88ê\95\94\82Ì\83E\83B\83\8b\83X\91Î\8dô\83\\83t\83g\81iAvast!\93\99\81j\82ªLdrLoadDll\82ð\83t\83b\83N\82µ\82Ä\82¢\82é\82½\82ßLdrLoadDll\82ð\8f\91\82«\8a·\82¦\82é\82×\82«\82Å\82Í\82È\82¢
-// \83J\81[\83l\83\8b\83\82\81[\83h\82Ì\83R\81[\83h\82É\91Î\82µ\82Ä\82Í\8cø\89Ê\82È\82µ
-// SeDebugPrivilege\82ª\8eg\97p\89Â\94\\82È\83\86\81[\83U\81[\82É\91Î\82µ\82Ä\82Í\8cø\89Ê\82È\82µ
-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;
-}
-
-// \83t\83@\83C\83\8b\82ÌSHA1\83n\83b\83V\83\85\82ð\8eæ\93¾
-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\82Ì\83n\83b\83V\83\85\82ð\93o\98^
-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\82Ì\83n\83b\83V\83\85\82Ì\93o\98^\82ð\89ð\8f\9c
-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;
-}
-
-// \90M\97\8a\82Å\82«\82È\82¢DLL\82ð\83A\83\93\83\8d\81[\83h
-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;
-}
-
-// \8aÖ\90\94\83|\83C\83\93\83^\82ð\8eg\97p\89Â\94\\82È\8fó\91Ô\82É\8f\89\8aú\89»
-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\91Î\8dô
-// DLL Injection\82³\82ê\82½\8fê\8d\87\82Í\8fã\82Ìh_LoadLibrary\8cn\8aÖ\90\94\82Å\83g\83\89\83b\83v\89Â\94\
-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\81AWriteProcessMemory\81ACreateRemoteThread\91Î\8dô
-// TerminateProcess\82Ì\82Ý\8b\96\89Â
-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\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// プロセスの保護\r
+\r
+// 次の中から1個のみ有効にする\r
+// フック先の関数のコードを書き換える\r
+// 全ての呼び出しをフック可能だが原理的に二重呼び出しに対応できない\r
+#define USE_CODE_HOOK\r
+// フック先の関数のインポートアドレステーブルを書き換える\r
+// 二重呼び出しが可能だが呼び出し方法によってはフックを回避される\r
+//#define USE_IAT_HOOK\r
+\r
+// フック対象の関数名 %s\r
+// フック対象の型 _%s\r
+// フック対象のポインタ p_%s\r
+// フック用の関数名 h_%s\r
+// フック対象のコードのバックアップ c_%s\r
+\r
+#include <tchar.h>\r
+#include <windows.h>\r
+#include <ntsecapi.h>\r
+#include <wincrypt.h>\r
+#include <wintrust.h>\r
+#include <softpub.h>\r
+#include <aclapi.h>\r
+#include <sfc.h>\r
+#include <tlhelp32.h>\r
+#include <imagehlp.h>\r
+#ifdef USE_IAT_HOOK\r
+#include <dbghelp.h>\r
+#endif\r
+\r
+#define DO_NOT_REPLACE\r
+#include "protectprocess.h"\r
+#include "mbswrapper.h"\r
+\r
+#ifdef USE_IAT_HOOK\r
+#pragma comment(lib, "dbghelp.lib")\r
+#endif\r
+\r
+#ifdef USE_CODE_HOOK\r
+#if defined(_X86_)\r
+#define HOOK_JUMP_CODE_LENGTH 5\r
+#elif defined(_AMD64_)\r
+#define HOOK_JUMP_CODE_LENGTH 14\r
+#endif\r
+#endif\r
+\r
+BOOL LockThreadLock();\r
+BOOL UnlockThreadLock();\r
+#ifdef USE_CODE_HOOK\r
+BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore);\r
+#endif\r
+#ifdef USE_IAT_HOOK\r
+BOOL HookFunctionInIAT(void* pOriginal, void* pNew);\r
+#endif\r
+HANDLE LockExistingFile(LPCWSTR Filename);\r
+BOOL FindTrustedModuleSHA1Hash(void* pHash);\r
+BOOL VerifyFileSignature(LPCWSTR Filename);\r
+BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename);\r
+BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash);\r
+BOOL IsModuleTrusted(LPCWSTR Filename);\r
+\r
+// 変数の宣言\r
+#ifdef USE_CODE_HOOK\r
+#define HOOK_FUNCTION_VAR(name) _##name p_##name;BYTE c_##name[HOOK_JUMP_CODE_LENGTH * 2];\r
+#endif\r
+#ifdef USE_IAT_HOOK\r
+#define HOOK_FUNCTION_VAR(name) _##name p_##name;\r
+#endif\r
+// 関数ポインタを取得\r
+#define GET_FUNCTION(h, name) p_##name = (_##name)GetProcAddress(h, #name)\r
+// フック対象のコードを置換してフックを開始\r
+#define SET_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE)\r
+// フック対象を呼び出す前に対象のコードを復元\r
+#define BEGIN_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, TRUE)\r
+// フック対象を呼び出した後に対象のコードを置換\r
+#define END_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, NULL, FALSE)\r
+\r
+HOOK_FUNCTION_VAR(LoadLibraryA)\r
+HOOK_FUNCTION_VAR(LoadLibraryW)\r
+HOOK_FUNCTION_VAR(LoadLibraryExA)\r
+HOOK_FUNCTION_VAR(LoadLibraryExW)\r
+\r
+typedef NTSTATUS (NTAPI* _LdrLoadDll)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*);\r
+typedef NTSTATUS (NTAPI* _LdrGetDllHandle)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*);\r
+typedef PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)(PVOID);\r
+typedef BOOL (WINAPI* _CryptCATAdminCalcHashFromFileHandle)(HANDLE, DWORD*, BYTE*, DWORD);\r
+\r
+_LdrLoadDll p_LdrLoadDll;\r
+_LdrGetDllHandle p_LdrGetDllHandle;\r
+_RtlImageNtHeader p_RtlImageNtHeader;\r
+_CryptCATAdminCalcHashFromFileHandle p_CryptCATAdminCalcHashFromFileHandle;\r
+\r
+#define MAX_LOCKED_THREAD 16\r
+#define MAX_TRUSTED_FILENAME_TABLE 16\r
+#define MAX_TRUSTED_SHA1_HASH_TABLE 16\r
+\r
+DWORD g_ProcessProtectionLevel;\r
+DWORD g_LockedThread[MAX_LOCKED_THREAD];\r
+WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE];\r
+BYTE g_TrustedSHA1HashTable[MAX_TRUSTED_SHA1_HASH_TABLE][20];\r
+WNDPROC g_PasswordEditControlProc;\r
+\r
+// 以下フック関数\r
+// フック対象を呼び出す場合は前後でBEGIN_HOOK_FUNCTIONとEND_HOOK_FUNCTIONを実行する必要がある\r
+\r
+HMODULE WINAPI h_LoadLibraryA(LPCSTR lpLibFileName)\r
+{\r
+ HMODULE r = NULL;\r
+ wchar_t* pw0 = NULL;\r
+ if(pw0 = DuplicateAtoW(lpLibFileName, -1))\r
+ r = LoadLibraryExW(pw0, NULL, 0);\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+HMODULE WINAPI h_LoadLibraryW(LPCWSTR lpLibFileName)\r
+{\r
+ HMODULE r = NULL;\r
+ r = LoadLibraryExW(lpLibFileName, NULL, 0);\r
+ return r;\r
+}\r
+\r
+HMODULE WINAPI h_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
+{\r
+ HMODULE r = NULL;\r
+ wchar_t* pw0 = NULL;\r
+ if(pw0 = DuplicateAtoW(lpLibFileName, -1))\r
+ r = LoadLibraryExW(pw0, hFile, dwFlags);\r
+ FreeDuplicatedString(pw0);\r
+ return r;\r
+}\r
+\r
+HMODULE WINAPI h_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
+{\r
+ HMODULE r = NULL;\r
+ BOOL bTrusted;\r
+ wchar_t* pw0;\r
+ HANDLE hLock;\r
+ HMODULE hModule;\r
+ DWORD Length;\r
+ bTrusted = FALSE;\r
+ pw0 = NULL;\r
+ hLock = NULL;\r
+// if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))\r
+ if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | 0x00000020 | 0x00000040))\r
+ bTrusted = TRUE;\r
+ if(!bTrusted)\r
+ {\r
+ if(hModule = System_LoadLibrary(lpLibFileName, NULL, DONT_RESOLVE_DLL_REFERENCES))\r
+ {\r
+ Length = MAX_PATH;\r
+ if(pw0 = AllocateStringW(Length))\r
+ {\r
+ if(GetModuleFileNameW(hModule, pw0, Length) > 0)\r
+ {\r
+ while(pw0)\r
+ {\r
+ if(GetModuleFileNameW(hModule, pw0, Length) + 1 <= Length)\r
+ {\r
+ lpLibFileName = pw0;\r
+ break;\r
+ }\r
+ Length = Length * 2;\r
+ FreeDuplicatedString(pw0);\r
+ pw0 = AllocateStringW(Length);\r
+ }\r
+ }\r
+ }\r
+ hLock = LockExistingFile(lpLibFileName);\r
+ FreeLibrary(hModule);\r
+ }\r
+ if((g_ProcessProtectionLevel & PROCESS_PROTECTION_LOADED) && GetModuleHandleW(lpLibFileName))\r
+ bTrusted = TRUE;\r
+ }\r
+ if(!bTrusted)\r
+ {\r
+ if(hLock)\r
+ {\r
+ if(IsModuleTrusted(lpLibFileName))\r
+ bTrusted = TRUE;\r
+ }\r
+ }\r
+ if(bTrusted)\r
+ r = System_LoadLibrary(lpLibFileName, hFile, dwFlags);\r
+ FreeDuplicatedString(pw0);\r
+ if(hLock)\r
+ CloseHandle(hLock);\r
+ return r;\r
+}\r
+\r
+// 以下ヘルパー関数\r
+\r
+BOOL LockThreadLock()\r
+{\r
+ BOOL bResult;\r
+ DWORD ThreadId;\r
+ DWORD i;\r
+ bResult = FALSE;\r
+ ThreadId = GetCurrentThreadId();\r
+ i = 0;\r
+ while(i < MAX_LOCKED_THREAD)\r
+ {\r
+ if(g_LockedThread[i] == ThreadId)\r
+ break;\r
+ i++;\r
+ }\r
+ if(i >= MAX_LOCKED_THREAD)\r
+ {\r
+ i = 0;\r
+ while(i < MAX_LOCKED_THREAD)\r
+ {\r
+ if(g_LockedThread[i] == 0)\r
+ {\r
+ g_LockedThread[i] = ThreadId;\r
+ bResult = TRUE;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ }\r
+ return bResult;\r
+}\r
+\r
+BOOL UnlockThreadLock()\r
+{\r
+ BOOL bResult;\r
+ DWORD ThreadId;\r
+ DWORD i;\r
+ bResult = FALSE;\r
+ ThreadId = GetCurrentThreadId();\r
+ i = 0;\r
+ while(i < MAX_LOCKED_THREAD)\r
+ {\r
+ if(g_LockedThread[i] == ThreadId)\r
+ {\r
+ g_LockedThread[i] = 0;\r
+ bResult = TRUE;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ return bResult;\r
+}\r
+\r
+#ifdef USE_CODE_HOOK\r
+BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore)\r
+{\r
+ BOOL bResult;\r
+ bResult = FALSE;\r
+#if defined(_X86_)\r
+ {\r
+ BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xe9, 0x00, 0x00, 0x00, 0x00};\r
+ size_t Relative;\r
+ DWORD Protect;\r
+ Relative = (size_t)pNew - (size_t)pOriginal - HOOK_JUMP_CODE_LENGTH;\r
+ memcpy(&JumpCode[1], &Relative, 4);\r
+ if(bRestore)\r
+ {\r
+ if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
+ {\r
+ memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH);\r
+ VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if(pBackupCode)\r
+ memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH);\r
+ if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
+ {\r
+ memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH);\r
+ VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ }\r
+#elif defined(_AMD64_)\r
+ {\r
+ BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
+ size_t Absolute;\r
+ DWORD Protect;\r
+ Absolute = (size_t)pNew;\r
+ memcpy(&JumpCode[6], &Absolute, 8);\r
+ bResult = FALSE;\r
+ if(bRestore)\r
+ {\r
+ if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
+ {\r
+ memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH);\r
+ VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if(pBackupCode)\r
+ memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH);\r
+ if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
+ {\r
+ memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH);\r
+ VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ }\r
+#endif\r
+ return bResult;\r
+}\r
+#endif\r
+\r
+#ifdef USE_IAT_HOOK\r
+BOOL HookFunctionInIAT(void* pOriginal, void* pNew)\r
+{\r
+ BOOL bResult;\r
+ HANDLE hSnapshot;\r
+ MODULEENTRY32 me;\r
+ BOOL bFound;\r
+ IMAGE_IMPORT_DESCRIPTOR* piid;\r
+ ULONG Size;\r
+ IMAGE_THUNK_DATA* pitd;\r
+ DWORD Protect;\r
+ bResult = FALSE;\r
+ if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE)\r
+ {\r
+ me.dwSize = sizeof(MODULEENTRY32);\r
+ if(Module32First(hSnapshot, &me))\r
+ {\r
+ bFound = FALSE;\r
+ do\r
+ {\r
+ if(piid = (IMAGE_IMPORT_DESCRIPTOR*)ImageDirectoryEntryToData(me.hModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size))\r
+ {\r
+ while(!bFound && piid->Name != 0)\r
+ {\r
+ pitd = (IMAGE_THUNK_DATA*)((BYTE*)me.hModule + piid->FirstThunk);\r
+ while(!bFound && pitd->u1.Function != 0)\r
+ {\r
+ if((void*)pitd->u1.Function == pOriginal)\r
+ {\r
+ bFound = TRUE;\r
+ if(VirtualProtect(&pitd->u1.Function, sizeof(void*), PAGE_EXECUTE_READWRITE, &Protect))\r
+ {\r
+ memcpy(&pitd->u1.Function, &pNew, sizeof(void*));\r
+ VirtualProtect(&pitd->u1.Function, sizeof(void*), Protect, &Protect);\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ pitd++;\r
+ }\r
+ piid++;\r
+ }\r
+ }\r
+ }\r
+ while(!bFound && Module32Next(hSnapshot, &me));\r
+ }\r
+ CloseHandle(hSnapshot);\r
+ }\r
+ return bResult;\r
+}\r
+#endif\r
+\r
+// ファイルを変更不能に設定\r
+HANDLE LockExistingFile(LPCWSTR Filename)\r
+{\r
+ HANDLE hResult;\r
+ hResult = NULL;\r
+ if((hResult = CreateFileW(Filename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)) == INVALID_HANDLE_VALUE)\r
+ hResult = NULL;\r
+ return hResult;\r
+}\r
+\r
+// DLLのハッシュを検索\r
+BOOL FindTrustedModuleSHA1Hash(void* pHash)\r
+{\r
+ BOOL bResult;\r
+ int i;\r
+ bResult = FALSE;\r
+ i = 0;\r
+ while(i < MAX_TRUSTED_SHA1_HASH_TABLE)\r
+ {\r
+ if(memcmp(&g_TrustedSHA1HashTable[i], pHash, 20) == 0)\r
+ {\r
+ bResult = TRUE;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ return bResult;\r
+}\r
+\r
+BOOL VerifyFileSignature_Function(LPCWSTR Filename)\r
+{\r
+ BOOL bResult;\r
+ HCERTSTORE hStore;\r
+ PCCERT_CONTEXT pcc;\r
+ CERT_CHAIN_PARA ccp;\r
+ CERT_CHAIN_CONTEXT* pccc;\r
+ CERT_CHAIN_POLICY_PARA ccpp;\r
+ CERT_CHAIN_POLICY_STATUS ccps;\r
+ bResult = FALSE;\r
+ if(CryptQueryObject(CERT_QUERY_OBJECT_FILE, Filename, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL, NULL, &hStore, NULL, NULL))\r
+ {\r
+ pcc = NULL;\r
+ while(!bResult && (pcc = CertEnumCertificatesInStore(hStore, pcc)))\r
+ {\r
+ ZeroMemory(&ccp, sizeof(CERT_CHAIN_PARA));\r
+ ccp.cbSize = sizeof(CERT_CHAIN_PARA);\r
+ if(CertGetCertificateChain(NULL, pcc, NULL, NULL, &ccp, 0, NULL, &pccc))\r
+ {\r
+ ZeroMemory(&ccpp, sizeof(CERT_CHAIN_POLICY_PARA));\r
+ ccpp.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);\r
+ if(g_ProcessProtectionLevel & PROCESS_PROTECTION_EXPIRED)\r
+ ccpp.dwFlags |= CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG;\r
+ else if(g_ProcessProtectionLevel & PROCESS_PROTECTION_UNAUTHORIZED)\r
+ ccpp.dwFlags |= CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;\r
+ ZeroMemory(&ccps, sizeof(CERT_CHAIN_POLICY_STATUS));\r
+ ccps.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);\r
+ if(CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, pccc, &ccpp, &ccps))\r
+ {\r
+ if(ccps.dwError == ERROR_SUCCESS)\r
+ {\r
+ bResult = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ CertFreeCertificateChain(pccc);\r
+ }\r
+ }\r
+ while(pcc = CertEnumCertificatesInStore(hStore, pcc))\r
+ {\r
+ }\r
+ CertCloseStore(hStore, 0);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// ファイルの署名を確認\r
+BOOL VerifyFileSignature(LPCWSTR Filename)\r
+{\r
+ BOOL bResult;\r
+ GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;\r
+ WINTRUST_FILE_INFO wfi;\r
+ WINTRUST_DATA wd;\r
+ bResult = FALSE;\r
+ ZeroMemory(&wfi, sizeof(WINTRUST_FILE_INFO));\r
+ wfi.cbStruct = sizeof(WINTRUST_FILE_INFO);\r
+ wfi.pcwszFilePath = Filename;\r
+ ZeroMemory(&wd, sizeof(WINTRUST_DATA));\r
+ wd.cbStruct = sizeof(WINTRUST_DATA);\r
+ wd.dwUIChoice = WTD_UI_NONE;\r
+ wd.dwUnionChoice = WTD_CHOICE_FILE;\r
+ wd.pFile = &wfi;\r
+ if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS)\r
+ bResult = TRUE;\r
+ else\r
+ bResult = VerifyFileSignature_Function(Filename);\r
+ return bResult;\r
+}\r
+\r
+// ファイルの署名をカタログファイルで確認\r
+BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename)\r
+{\r
+ BOOL bResult;\r
+ GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;\r
+ WINTRUST_CATALOG_INFO wci;\r
+ WINTRUST_DATA wd;\r
+ bResult = FALSE;\r
+ if(VerifyFileSignature(Catalog))\r
+ {\r
+ ZeroMemory(&wci, sizeof(WINTRUST_CATALOG_INFO));\r
+ wci.cbStruct = sizeof(WINTRUST_CATALOG_INFO);\r
+ wci.pcwszCatalogFilePath = Catalog;\r
+ wci.pcwszMemberFilePath = Filename;\r
+ if((wci.hMemberFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
+ {\r
+ p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, NULL, 0);\r
+ if(wci.pbCalculatedFileHash = (BYTE*)malloc(wci.cbCalculatedFileHash))\r
+ {\r
+ if(p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, wci.pbCalculatedFileHash, 0))\r
+ {\r
+ ZeroMemory(&wd, sizeof(WINTRUST_DATA));\r
+ wd.cbStruct = sizeof(WINTRUST_DATA);\r
+ wd.dwUIChoice = WTD_UI_NONE;\r
+ wd.dwUnionChoice = WTD_CHOICE_CATALOG;\r
+ wd.pCatalog = &wci;\r
+ if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS)\r
+ bResult = TRUE;\r
+ }\r
+ free(wci.pbCalculatedFileHash);\r
+ }\r
+ CloseHandle(wci.hMemberFile);\r
+ }\r
+ }\r
+ return bResult;\r
+}\r
+\r
+BOOL WINAPI GetSHA1HashOfModule_Function(DIGEST_HANDLE refdata, PBYTE pData, DWORD dwLength)\r
+{\r
+ return CryptHashData(*(HCRYPTHASH*)refdata, pData, dwLength, 0);\r
+}\r
+\r
+// モジュールのSHA1ハッシュを取得\r
+// マニフェストファイルのfile要素のhash属性は実行可能ファイルの場合にImageGetDigestStreamで算出される\r
+BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash)\r
+{\r
+ BOOL bResult;\r
+ HCRYPTPROV hProv;\r
+ HCRYPTHASH hHash;\r
+ HANDLE hFile;\r
+ DWORD dw;\r
+ bResult = FALSE;\r
+ if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))\r
+ {\r
+ if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))\r
+ {\r
+ if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
+ {\r
+ if(ImageGetDigestStream(hFile, CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO, GetSHA1HashOfModule_Function, (DIGEST_HANDLE)&hHash))\r
+ {\r
+ dw = 20;\r
+ if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))\r
+ bResult = TRUE;\r
+ }\r
+ CloseHandle(hFile);\r
+ }\r
+ CryptDestroyHash(hHash);\r
+ }\r
+ CryptReleaseContext(hProv, 0);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+BOOL IsSxsModuleTrusted_Function(LPCWSTR Catalog, LPCWSTR Manifest, LPCWSTR Module)\r
+{\r
+ BOOL bResult;\r
+ HANDLE hLock0;\r
+ HANDLE hLock1;\r
+ BYTE Hash[20];\r
+ int i;\r
+ static char HexTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};\r
+ char HashHex[41];\r
+ HANDLE hFile;\r
+ DWORD Size;\r
+ char* pData;\r
+ DWORD dw;\r
+ bResult = FALSE;\r
+ if(hLock0 = LockExistingFile(Catalog))\r
+ {\r
+ if(hLock1 = LockExistingFile(Manifest))\r
+ {\r
+ if(VerifyFileSignatureInCatalog(Catalog, Manifest))\r
+ {\r
+ if(GetSHA1HashOfModule(Module, &Hash))\r
+ {\r
+ for(i = 0; i < 20; i++)\r
+ {\r
+ HashHex[i * 2] = HexTable[(Hash[i] >> 4) & 0x0f];\r
+ HashHex[i * 2 + 1] = HexTable[Hash[i] & 0x0f];\r
+ }\r
+ HashHex[i * 2] = '\0';\r
+ if((hFile = CreateFileW(Manifest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
+ {\r
+ Size = GetFileSize(hFile, NULL);\r
+ if(pData = (char*)VirtualAlloc(NULL, Size + 1, MEM_COMMIT, PAGE_READWRITE))\r
+ {\r
+ VirtualLock(pData, Size + 1);\r
+ if(ReadFile(hFile, pData, Size, &dw, NULL))\r
+ {\r
+ pData[dw] = '\0';\r
+ if(strstr(pData, HashHex))\r
+ bResult = TRUE;\r
+ }\r
+ VirtualUnlock(pData, Size + 1);\r
+ VirtualFree(pData, Size + 1, MEM_DECOMMIT);\r
+ }\r
+ CloseHandle(hFile);\r
+ }\r
+ }\r
+ }\r
+ CloseHandle(hLock1);\r
+ }\r
+ CloseHandle(hLock0);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// サイドバイサイドDLLを確認\r
+// パスは"%SystemRoot%\WinSxS"以下を想定\r
+// 以下のファイルが存在するものとする\r
+// "\xxx\yyy.dll"、"\manifests\xxx.cat"、"\manifests\xxx.manifest"のセット(XPの全てのDLL、Vista以降の一部のDLL)\r
+// "\xxx\yyy.dll"、"\catalogs\zzz.cat"、"\manifests\xxx.manifest"のセット(Vista以降のほとんどのDLL)\r
+// 署名されたカタログファイルを用いてマニフェストファイルが改竄されていないことを確認\r
+// ハッシュ値は マニフェストファイルのfile要素のhash属性に記述されているものを用いる\r
+// マニフェストファイル内にSHA1ハッシュ値の16進数表記を直接検索しているが確率的に問題なし\r
+BOOL IsSxsModuleTrusted(LPCWSTR Filename)\r
+{\r
+ BOOL bResult;\r
+ wchar_t* pw0;\r
+ wchar_t* pw1;\r
+ wchar_t* pw2;\r
+ wchar_t* pw3;\r
+ wchar_t* pw4;\r
+ wchar_t* pw5;\r
+ wchar_t* p;\r
+ HANDLE hFind;\r
+ WIN32_FIND_DATAW wfd;\r
+ bResult = FALSE;\r
+ if(pw0 = AllocateStringW(wcslen(Filename) + 1))\r
+ {\r
+ wcscpy(pw0, Filename);\r
+ if(p = wcsrchr(pw0, L'\\'))\r
+ {\r
+ wcscpy(p, L"");\r
+ if(p = wcsrchr(pw0, L'\\'))\r
+ {\r
+ p++;\r
+ if(pw1 = AllocateStringW(wcslen(p) + 1))\r
+ {\r
+ wcscpy(pw1, p);\r
+ wcscpy(p, L"");\r
+ if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".cat") + 1))\r
+ {\r
+ wcscpy(pw2, pw0);\r
+ wcscat(pw2, L"manifests\\");\r
+ wcscat(pw2, pw1);\r
+ if(pw3 = AllocateStringW(wcslen(pw2) + wcslen(L".manifest") + 1))\r
+ {\r
+ wcscpy(pw3, pw2);\r
+ wcscat(pw3, L".manifest");\r
+ wcscat(pw2, L".cat");\r
+ if(IsSxsModuleTrusted_Function(pw2, pw3, Filename))\r
+ bResult = TRUE;\r
+ FreeDuplicatedString(pw3);\r
+ }\r
+ FreeDuplicatedString(pw2);\r
+ }\r
+ if(!bResult)\r
+ {\r
+ if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"catalogs\\") + 1))\r
+ {\r
+ if(pw3 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".manifest") + 1))\r
+ {\r
+ wcscpy(pw2, pw0);\r
+ wcscat(pw2, L"catalogs\\");\r
+ wcscpy(pw3, pw0);\r
+ wcscat(pw3, L"manifests\\");\r
+ wcscat(pw3, pw1);\r
+ wcscat(pw3, L".manifest");\r
+ if(pw4 = AllocateStringW(wcslen(pw2) + wcslen(L"*.cat") + 1))\r
+ {\r
+ wcscpy(pw4, pw2);\r
+ wcscat(pw4, L"*.cat");\r
+ if((hFind = FindFirstFileW(pw4, &wfd)) != INVALID_HANDLE_VALUE)\r
+ {\r
+ do\r
+ {\r
+ if(pw5 = AllocateStringW(wcslen(pw2) + wcslen(wfd.cFileName) + 1))\r
+ {\r
+ wcscpy(pw5, pw2);\r
+ wcscat(pw5, wfd.cFileName);\r
+ if(IsSxsModuleTrusted_Function(pw5, pw3, Filename))\r
+ bResult = TRUE;\r
+ FreeDuplicatedString(pw5);\r
+ }\r
+ }\r
+ while(!bResult && FindNextFileW(hFind, &wfd));\r
+ FindClose(hFind);\r
+ }\r
+ FreeDuplicatedString(pw4);\r
+ }\r
+ FreeDuplicatedString(pw3);\r
+ }\r
+ FreeDuplicatedString(pw2);\r
+ }\r
+ }\r
+ FreeDuplicatedString(pw1);\r
+ }\r
+ }\r
+ }\r
+ FreeDuplicatedString(pw0);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// DLLを確認\r
+BOOL IsModuleTrusted(LPCWSTR Filename)\r
+{\r
+ BOOL bResult;\r
+ BYTE Hash[20];\r
+ bResult = FALSE;\r
+ if(LockThreadLock())\r
+ {\r
+ if(GetSHA1HashOfFile(Filename, &Hash))\r
+ {\r
+ if(FindTrustedModuleSHA1Hash(&Hash))\r
+ bResult = TRUE;\r
+ }\r
+ if(!bResult)\r
+ {\r
+ if((g_ProcessProtectionLevel & PROCESS_PROTECTION_BUILTIN) && VerifyFileSignature(Filename))\r
+ bResult = TRUE;\r
+ }\r
+ if(!bResult)\r
+ {\r
+ if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SYSTEM_FILE) && SfcIsFileProtected(NULL, Filename))\r
+ bResult = TRUE;\r
+ }\r
+ if(!bResult)\r
+ {\r
+ if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SIDE_BY_SIDE) && IsSxsModuleTrusted(Filename))\r
+ bResult = TRUE;\r
+ }\r
+ UnlockThreadLock();\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// kernel32.dllのLoadLibraryExW相当の関数\r
+// ドキュメントが無いため詳細は不明\r
+// 一部のウィルス対策ソフト(Avast!等)がLdrLoadDllをフックしているためLdrLoadDllを書き換えるべきではない\r
+// カーネルモードのコードに対しては効果なし\r
+// SeDebugPrivilegeが使用可能なユーザーに対しては効果なし\r
+HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
+{\r
+ HMODULE r = NULL;\r
+ UNICODE_STRING us;\r
+ HANDLE hDataFile;\r
+ HANDLE hMapping;\r
+ DWORD DllFlags;\r
+ us.Length = sizeof(wchar_t) * wcslen(lpLibFileName);\r
+ us.MaximumLength = sizeof(wchar_t) * (wcslen(lpLibFileName) + 1);\r
+ us.Buffer = (PWSTR)lpLibFileName;\r
+// if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))\r
+ if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040))\r
+ {\r
+// if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == STATUS_SUCCESS)\r
+ if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == 0)\r
+ {\r
+// dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);\r
+ dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040);\r
+ dwFlags |= DONT_RESOLVE_DLL_REFERENCES;\r
+ }\r
+ else\r
+ {\r
+// if(dwFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)\r
+ if(dwFlags & 0x00000040)\r
+ hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\r
+ else\r
+ hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);\r
+ if(hDataFile != INVALID_HANDLE_VALUE)\r
+ {\r
+ if(hMapping = CreateFileMappingW(hDataFile, NULL, PAGE_READONLY, 0, 0, NULL))\r
+ {\r
+ if(r = (HMODULE)MapViewOfFileEx(hMapping, FILE_MAP_READ, 0, 0, 0, NULL))\r
+ {\r
+ if(p_RtlImageNtHeader(r))\r
+ r = (HMODULE)((size_t)r | 1);\r
+ else\r
+ {\r
+ UnmapViewOfFile(r);\r
+ r = NULL;\r
+ }\r
+ }\r
+ CloseHandle(hMapping);\r
+ }\r
+ CloseHandle(hDataFile);\r
+ }\r
+ else\r
+ {\r
+// dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);\r
+ dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040);\r
+ dwFlags |= DONT_RESOLVE_DLL_REFERENCES;\r
+ }\r
+ }\r
+ }\r
+// if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)))\r
+ if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040)))\r
+ {\r
+ DllFlags = 0;\r
+// if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_IMAGE_RESOURCE))\r
+ if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | 0x00000020))\r
+ DllFlags |= 0x00000002;\r
+// if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == STATUS_SUCCESS)\r
+ if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == 0)\r
+ {\r
+ }\r
+ else\r
+ r = NULL;\r
+ }\r
+ return r;\r
+}\r
+\r
+void SetProcessProtectionLevel(DWORD Level)\r
+{\r
+ g_ProcessProtectionLevel = Level;\r
+}\r
+\r
+// メモリのSHA1ハッシュを取得\r
+BOOL GetSHA1HashOfMemory(const void* pData, DWORD Size, void* pHash)\r
+{\r
+ BOOL bResult;\r
+ HCRYPTPROV hProv;\r
+ HCRYPTHASH hHash;\r
+ DWORD dw;\r
+ bResult = FALSE;\r
+ if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))\r
+ {\r
+ if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))\r
+ {\r
+ if(CryptHashData(hHash, (BYTE*)pData, Size, 0))\r
+ {\r
+ dw = 20;\r
+ if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))\r
+ bResult = TRUE;\r
+ }\r
+ CryptDestroyHash(hHash);\r
+ }\r
+ CryptReleaseContext(hProv, 0);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// ファイルのSHA1ハッシュを取得\r
+BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash)\r
+{\r
+ BOOL bResult;\r
+ HANDLE hFile;\r
+ DWORD Size;\r
+ void* pData;\r
+ DWORD dw;\r
+ bResult = FALSE;\r
+ if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
+ {\r
+ Size = GetFileSize(hFile, NULL);\r
+ if(pData = VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE))\r
+ {\r
+ VirtualLock(pData, Size);\r
+ if(ReadFile(hFile, pData, Size, &dw, NULL))\r
+ {\r
+ if(GetSHA1HashOfMemory(pData, Size, pHash))\r
+ bResult = TRUE;\r
+ }\r
+ VirtualUnlock(pData, Size);\r
+ VirtualFree(pData, Size, MEM_DECOMMIT);\r
+ }\r
+ CloseHandle(hFile);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// DLLのハッシュを登録\r
+BOOL RegisterTrustedModuleSHA1Hash(void* pHash)\r
+{\r
+ BOOL bResult;\r
+ BYTE NullHash[20] = {0};\r
+ int i;\r
+ bResult = FALSE;\r
+ if(FindTrustedModuleSHA1Hash(pHash))\r
+ bResult = TRUE;\r
+ else\r
+ {\r
+ i = 0;\r
+ while(i < MAX_TRUSTED_SHA1_HASH_TABLE)\r
+ {\r
+ if(memcmp(&g_TrustedSHA1HashTable[i], &NullHash, 20) == 0)\r
+ {\r
+ memcpy(&g_TrustedSHA1HashTable[i], pHash, 20);\r
+ bResult = TRUE;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// DLLのハッシュの登録を解除\r
+BOOL UnregisterTrustedModuleSHA1Hash(void* pHash)\r
+{\r
+ BOOL bResult;\r
+ BYTE NullHash[20] = {0};\r
+ int i;\r
+ bResult = FALSE;\r
+ i = 0;\r
+ while(i < MAX_TRUSTED_SHA1_HASH_TABLE)\r
+ {\r
+ if(memcmp(&g_TrustedSHA1HashTable[i], pHash, 20) == 0)\r
+ {\r
+ memcpy(&g_TrustedSHA1HashTable[i], &NullHash, 20);\r
+ bResult = TRUE;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// 信頼できないDLLをアンロード\r
+BOOL UnloadUntrustedModule()\r
+{\r
+ BOOL bResult;\r
+ wchar_t* pw0;\r
+ HANDLE hSnapshot;\r
+ MODULEENTRY32 me;\r
+ DWORD Length;\r
+ bResult = FALSE;\r
+ pw0 = NULL;\r
+ if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE)\r
+ {\r
+ bResult = TRUE;\r
+ me.dwSize = sizeof(MODULEENTRY32);\r
+ if(Module32First(hSnapshot, &me))\r
+ {\r
+ do\r
+ {\r
+ Length = MAX_PATH;\r
+ FreeDuplicatedString(pw0);\r
+ if(pw0 = AllocateStringW(Length))\r
+ {\r
+ if(GetModuleFileNameW(me.hModule, pw0, Length) > 0)\r
+ {\r
+ while(pw0)\r
+ {\r
+ if(GetModuleFileNameW(me.hModule, pw0, Length) + 1 <= Length)\r
+ break;\r
+ Length = Length * 2;\r
+ FreeDuplicatedString(pw0);\r
+ pw0 = AllocateStringW(Length);\r
+ }\r
+ }\r
+ }\r
+ if(pw0)\r
+ {\r
+ if(!IsModuleTrusted(pw0))\r
+ {\r
+ if(me.hModule != GetModuleHandleW(NULL))\r
+ {\r
+ while(FreeLibrary(me.hModule))\r
+ {\r
+ }\r
+ if(GetModuleFileNameW(me.hModule, pw0, Length) > 0)\r
+ {\r
+ bResult = FALSE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ bResult = FALSE;\r
+ break;\r
+ }\r
+ }\r
+ while(Module32Next(hSnapshot, &me));\r
+ }\r
+ CloseHandle(hSnapshot);\r
+ }\r
+ FreeDuplicatedString(pw0);\r
+ return bResult;\r
+}\r
+\r
+// 関数ポインタを使用可能な状態に初期化\r
+BOOL InitializeLoadLibraryHook()\r
+{\r
+ BOOL bResult;\r
+ HMODULE hModule;\r
+ bResult = TRUE;\r
+ if(!(hModule = GetModuleHandleW(L"kernel32.dll")))\r
+ bResult = FALSE;\r
+ if(!(GET_FUNCTION(hModule, LoadLibraryA)))\r
+ bResult = FALSE;\r
+ if(!(GET_FUNCTION(hModule, LoadLibraryW)))\r
+ bResult = FALSE;\r
+ if(!(GET_FUNCTION(hModule, LoadLibraryExA)))\r
+ bResult = FALSE;\r
+ if(!(GET_FUNCTION(hModule, LoadLibraryExW)))\r
+ bResult = FALSE;\r
+ if(!(hModule = GetModuleHandleW(L"ntdll.dll")))\r
+ bResult = FALSE;\r
+ if(!(GET_FUNCTION(hModule, LdrLoadDll)))\r
+ bResult = FALSE;\r
+ if(!(GET_FUNCTION(hModule, LdrGetDllHandle)))\r
+ bResult = FALSE;\r
+ if(!(GET_FUNCTION(hModule, RtlImageNtHeader)))\r
+ bResult = FALSE;\r
+ if(!(hModule = LoadLibraryW(L"wintrust.dll")))\r
+ bResult = FALSE;\r
+ if(!(GET_FUNCTION(hModule, CryptCATAdminCalcHashFromFileHandle)))\r
+ bResult = FALSE;\r
+ // バグ対策\r
+ ImageGetDigestStream(NULL, 0, NULL, NULL);\r
+ return bResult;\r
+}\r
+\r
+// SetWindowsHookEx対策\r
+// DLL Injectionされた場合は上のh_LoadLibrary系関数でトラップ可能\r
+BOOL EnableLoadLibraryHook(BOOL bEnable)\r
+{\r
+ BOOL bResult;\r
+ bResult = FALSE;\r
+ if(bEnable)\r
+ {\r
+ bResult = TRUE;\r
+#ifdef USE_CODE_HOOK\r
+ if(!SET_HOOK_FUNCTION(LoadLibraryA))\r
+ bResult = FALSE;\r
+ if(!SET_HOOK_FUNCTION(LoadLibraryW))\r
+ bResult = FALSE;\r
+ if(!SET_HOOK_FUNCTION(LoadLibraryExA))\r
+ bResult = FALSE;\r
+ if(!SET_HOOK_FUNCTION(LoadLibraryExW))\r
+ bResult = FALSE;\r
+#endif\r
+#ifdef USE_IAT_HOOK\r
+ if(!HookFunctionInIAT(p_LoadLibraryA, h_LoadLibraryA))\r
+ bResult = FALSE;\r
+ if(!HookFunctionInIAT(p_LoadLibraryW, h_LoadLibraryW))\r
+ bResult = FALSE;\r
+ if(!HookFunctionInIAT(p_LoadLibraryExA, h_LoadLibraryExA))\r
+ bResult = FALSE;\r
+ if(!HookFunctionInIAT(p_LoadLibraryExW, h_LoadLibraryExW))\r
+ bResult = FALSE;\r
+#endif\r
+ }\r
+ else\r
+ {\r
+ bResult = TRUE;\r
+#ifdef USE_CODE_HOOK\r
+ if(!BEGIN_HOOK_FUNCTION(LoadLibraryA))\r
+ bResult = FALSE;\r
+ if(!BEGIN_HOOK_FUNCTION(LoadLibraryW))\r
+ bResult = FALSE;\r
+ if(!BEGIN_HOOK_FUNCTION(LoadLibraryExA))\r
+ bResult = FALSE;\r
+ if(!BEGIN_HOOK_FUNCTION(LoadLibraryExW))\r
+ bResult = FALSE;\r
+#endif\r
+#ifdef USE_IAT_HOOK\r
+ if(!HookFunctionInIAT(h_LoadLibraryA, p_LoadLibraryA))\r
+ bResult = FALSE;\r
+ if(!HookFunctionInIAT(h_LoadLibraryW, p_LoadLibraryW))\r
+ bResult = FALSE;\r
+ if(!HookFunctionInIAT(h_LoadLibraryExA, p_LoadLibraryExA))\r
+ bResult = FALSE;\r
+ if(!HookFunctionInIAT(h_LoadLibraryExW, p_LoadLibraryExW))\r
+ bResult = FALSE;\r
+#endif\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// ReadProcessMemory、WriteProcessMemory、CreateRemoteThread対策\r
+// TerminateProcessのみ許可\r
+BOOL RestartProtectedProcess(LPCTSTR Keyword)\r
+{\r
+ BOOL bResult;\r
+ ACL* pACL;\r
+ SID_IDENTIFIER_AUTHORITY sia = SECURITY_WORLD_SID_AUTHORITY;\r
+ PSID pSID;\r
+ SECURITY_DESCRIPTOR sd;\r
+ TCHAR* CommandLine;\r
+ SECURITY_ATTRIBUTES sa;\r
+ STARTUPINFO si;\r
+ PROCESS_INFORMATION pi;\r
+ bResult = FALSE;\r
+ if(_tcslen(GetCommandLine()) >= _tcslen(Keyword) && _tcscmp(GetCommandLine() + _tcslen(GetCommandLine()) - _tcslen(Keyword), Keyword) == 0)\r
+ return FALSE;\r
+ if(pACL = (ACL*)malloc(sizeof(ACL) + 1024))\r
+ {\r
+ if(InitializeAcl(pACL, sizeof(ACL) + 1024, ACL_REVISION))\r
+ {\r
+ if(AllocateAndInitializeSid(&sia, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSID))\r
+ {\r
+ if(AddAccessAllowedAce(pACL, ACL_REVISION, PROCESS_TERMINATE, pSID))\r
+ {\r
+ if(InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))\r
+ {\r
+ if(SetSecurityDescriptorDacl(&sd, TRUE, pACL, FALSE))\r
+ {\r
+ if(CommandLine = (TCHAR*)malloc(sizeof(TCHAR) * (_tcslen(GetCommandLine()) + _tcslen(Keyword) + 1)))\r
+ {\r
+ _tcscpy(CommandLine, GetCommandLine());\r
+ _tcscat(CommandLine, Keyword);\r
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
+ sa.lpSecurityDescriptor = &sd;\r
+ sa.bInheritHandle = FALSE;\r
+ GetStartupInfo(&si);\r
+ if(CreateProcess(NULL, CommandLine, &sa, NULL, FALSE, 0, NULL, NULL, &si, &pi))\r
+ {\r
+ CloseHandle(pi.hThread);\r
+ CloseHandle(pi.hProcess);\r
+ bResult = TRUE;\r
+ }\r
+ free(CommandLine);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ FreeSid(pSID);\r
+ }\r
+ }\r
+ free(pACL);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+INT_PTR CALLBACK PasswordEditControlWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+ switch(Msg)\r
+ {\r
+ case EM_GETPASSWORDCHAR:\r
+ break;\r
+ case EM_SETPASSWORDCHAR:\r
+ break;\r
+ default:\r
+ return CallWindowProcW(g_PasswordEditControlProc, hWnd, Msg, wParam, lParam);\r
+ }\r
+ return 0;\r
+}\r
+\r
+BOOL ProtectPasswordEditControl(HWND hWnd)\r
+{\r
+ BOOL bResult;\r
+ WCHAR ClassName[MAX_PATH];\r
+ WNDPROC Proc;\r
+ bResult = FALSE;\r
+ if(g_ProcessProtectionLevel & PROCESS_PROTECTION_PASSWORD_EDIT)\r
+ {\r
+ if(GetClassNameW(hWnd, ClassName, MAX_PATH) > 0)\r
+ {\r
+ if(_wcsicmp(ClassName, WC_EDITW) == 0)\r
+ {\r
+ Proc = (WNDPROC)GetWindowLongPtrW(hWnd, GWLP_WNDPROC);\r
+ if(Proc != (WNDPROC)PasswordEditControlWndProc)\r
+ {\r
+ g_PasswordEditControlProc = Proc;\r
+ SetWindowLongPtrW(hWnd, GWLP_WNDPROC, (LONG_PTR)PasswordEditControlWndProc);\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return bResult;\r
+}\r
+\r
+BOOL CALLBACK ProtectAllEditControlsEnumChildProc(HWND hwnd , LPARAM lParam)\r
+{\r
+ ProtectPasswordEditControl(hwnd);\r
+ return TRUE;\r
+}\r
+\r
+BOOL ProtectAllEditControls(HWND hWnd)\r
+{\r
+ if(g_ProcessProtectionLevel & PROCESS_PROTECTION_PASSWORD_EDIT)\r
+ EnumChildWindows(hWnd, ProtectAllEditControlsEnumChildProc, 0);\r
+ return TRUE;\r
+}\r
+\r