OSDN Git Service

Add support for retaining time stamps on uploading files.
[ffftp/ffftp.git] / protectprocess.c
index 7c7c60f..f0669a8 100644 (file)
-// 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;
-       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;
-}
-
-// \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;
-       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);
-}
-
-// \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 START_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_MD5_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_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][20];\r
+WNDPROC g_PasswordEditControlProc;\r
+\r
+// 以下フック関数\r
+// フック対象を呼び出す場合は前後でSTART_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
+       DWORD Protect;\r
+#if defined(_X86_)\r
+       BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xe9, 0x00, 0x00, 0x00, 0x00};\r
+       size_t Relative;\r
+       Relative = (size_t)pNew - (size_t)pOriginal - HOOK_JUMP_CODE_LENGTH;\r
+       memcpy(&JumpCode[1], &Relative, 4);\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
+#elif defined(_AMD64_)\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
+       Absolute = (size_t)pOriginal;\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
+#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_MD5_HASH_TABLE)\r
+       {\r
+               if(memcmp(&g_TrustedMD5HashTable[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_SIDE_BY_SIDE) && IsSxsModuleTrusted(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
+               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 GetSHA1HashOfFile(LPCWSTR Filename, void* pHash)\r
+{\r
+       BOOL bResult;\r
+       HCRYPTPROV hProv;\r
+       HCRYPTHASH hHash;\r
+       HANDLE hFile;\r
+       DWORD Size;\r
+       void* pData;\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
+                               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(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
+                                       }\r
+                                       VirtualUnlock(pData, Size);\r
+                                       VirtualFree(pData, Size, MEM_DECOMMIT);\r
+                               }\r
+                               CloseHandle(hFile);\r
+                       }\r
+                       CryptDestroyHash(hHash);\r
+               }\r
+               CryptReleaseContext(hProv, 0);\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_MD5_HASH_TABLE)\r
+               {\r
+                       if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 20) == 0)\r
+                       {\r
+                               memcpy(&g_TrustedMD5HashTable[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_MD5_HASH_TABLE)\r
+       {\r
+               if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0)\r
+               {\r
+                       memcpy(&g_TrustedMD5HashTable[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
+       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(!END_HOOK_FUNCTION(LoadLibraryA))\r
+                       bResult = FALSE;\r
+               if(!END_HOOK_FUNCTION(LoadLibraryW))\r
+                       bResult = FALSE;\r
+               if(!END_HOOK_FUNCTION(LoadLibraryExA))\r
+                       bResult = FALSE;\r
+               if(!END_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