OSDN Git Service

Fix bugs process protection.
[ffftp/ffftp.git] / protectprocess.c
index 1492bc6..6865912 100644 (file)
@@ -16,8 +16,6 @@
 // \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
 
-#define _WIN32_WINNT 0x0600
-
 #include <tchar.h>
 #include <windows.h>
 #include <ntsecapi.h>
@@ -26,8 +24,9 @@
 #include <softpub.h>
 #include <aclapi.h>
 #include <sfc.h>
-#ifdef USE_IAT_HOOK
 #include <tlhelp32.h>
+#include <imagehlp.h>
+#ifdef USE_IAT_HOOK
 #include <dbghelp.h>
 #endif
 
 #endif
 #endif
 
+BOOL LockThreadLock();
+BOOL UnlockThreadLock();
+#ifdef USE_CODE_HOOK
 BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore);
+#endif
+#ifdef USE_IAT_HOOK
+BOOL HookFunctionInIAT(void* pOriginal, void* pNew);
+#endif
+HANDLE LockExistingFile(LPCWSTR Filename);
+BOOL FindTrustedModuleMD5Hash(void* pHash);
+BOOL VerifyFileSignature(LPCWSTR Filename);
+BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename);
+BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash);
+BOOL IsModuleTrusted(LPCWSTR Filename);
 
 // \95Ï\90\94\82Ì\90é\8c¾
 #ifdef USE_CODE_HOOK
@@ -70,21 +82,23 @@ HOOK_FUNCTION_VAR(LoadLibraryW)
 HOOK_FUNCTION_VAR(LoadLibraryExA)
 HOOK_FUNCTION_VAR(LoadLibraryExW)
 
-// \83h\83L\83\85\83\81\83\93\83g\82ª\96³\82¢\82½\82ß\8c´\88ö\82Í\95s\96¾\82¾\82ª\91æ2\88ø\90\94\82Í\83|\83C\83\93\83^\82Å\82È\82¢\82Æ\83G\83\89\81[\82É\82È\82é\8fê\8d\87\82ª\82 \82é
-//typedef NTSTATUS (WINAPI* _LdrLoadDll)(LPCWSTR, DWORD, UNICODE_STRING*, HMODULE*);
-typedef NTSTATUS (WINAPI* _LdrLoadDll)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*);
-// \83h\83L\83\85\83\81\83\93\83g\82ª\96³\82¢\82½\82ß\8c´\88ö\82Í\95s\96¾\82¾\82ª\91æ2\88ø\90\94\82Í\83|\83C\83\93\83^\82Å\82È\82¢\82Æ\83G\83\89\81[\82É\82È\82é\8fê\8d\87\82ª\82 \82é
-//typedef NTSTATUS (WINAPI* _LdrGetDllHandle)(LPCWSTR, DWORD, UNICODE_STRING*, HMODULE*);
-typedef NTSTATUS (WINAPI* _LdrGetDllHandle)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*);
-typedef NTSTATUS (WINAPI* _LdrAddRefDll)(DWORD, HMODULE);
+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;
-_LdrAddRefDll p_LdrAddRefDll;
+_RtlImageNtHeader p_RtlImageNtHeader;
+_CryptCATAdminCalcHashFromFileHandle p_CryptCATAdminCalcHashFromFileHandle;
 
-#define MAX_MD5_HASH_TABLE 16
+#define MAX_LOCKED_THREAD 16
+#define MAX_TRUSTED_FILENAME_TABLE 16
+#define MAX_TRUSTED_MD5_HASH_TABLE 16
 
-BYTE g_MD5HashTable[MAX_MD5_HASH_TABLE][16];
+DWORD g_LockedThread[MAX_LOCKED_THREAD];
+WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE];
+BYTE g_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][16];
 
 // \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é
@@ -92,84 +106,142 @@ BYTE g_MD5HashTable[MAX_MD5_HASH_TABLE][16];
 HMODULE WINAPI h_LoadLibraryA(LPCSTR lpLibFileName)
 {
        HMODULE r = NULL;
-       if(GetModuleHandleA(lpLibFileName) || IsModuleTrustedA(lpLibFileName))
-       {
-               wchar_t* pw0 = NULL;
-               pw0 = DuplicateAtoW(lpLibFileName, -1);
-               r = System_LoadLibrary(pw0, NULL, 0);
-               FreeDuplicatedString(pw0);
-       }
+       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;
-       if(GetModuleHandleW(lpLibFileName) || IsModuleTrustedW(lpLibFileName))
-               r = System_LoadLibrary(lpLibFileName, NULL, 0);
+       r = LoadLibraryExW(lpLibFileName, NULL, 0);
        return r;
 }
 
 HMODULE WINAPI h_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
 {
        HMODULE r = NULL;
-       if(GetModuleHandleA(lpLibFileName) || IsModuleTrustedA(lpLibFileName))
-       {
-               wchar_t* pw0 = NULL;
-               pw0 = DuplicateAtoW(lpLibFileName, -1);
-               r = System_LoadLibrary(pw0, hFile, dwFlags);
-               FreeDuplicatedString(pw0);
-       }
+       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;
-       if(GetModuleHandleW(lpLibFileName) || IsModuleTrustedW(lpLibFileName))
+       BOOL bTrusted;
+       wchar_t* pw0;
+       HANDLE hLock;
+       HMODULE hModule;
+       DWORD Length;
+       bTrusted = FALSE;
+       pw0 = NULL;
+       hLock = NULL;
+//     if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))
+       if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | 0x00000020 | 0x00000040))
+               bTrusted = TRUE;
+       if(!bTrusted)
+       {
+               if(hModule = System_LoadLibrary(lpLibFileName, NULL, DONT_RESOLVE_DLL_REFERENCES))
+               {
+                       Length = MAX_PATH;
+                       if(pw0 = AllocateStringW(Length))
+                       {
+                               if(GetModuleFileNameW(hModule, pw0, Length) > 0)
+                               {
+                                       while(pw0)
+                                       {
+                                               if(GetModuleFileNameW(hModule, pw0, Length) + 1 <= Length)
+                                               {
+                                                       lpLibFileName = pw0;
+                                                       break;
+                                               }
+                                               Length = Length * 2;
+                                               FreeDuplicatedString(pw0);
+                                               pw0 = AllocateStringW(Length);
+                                       }
+                               }
+                       }
+                       hLock = LockExistingFile(lpLibFileName);
+                       FreeLibrary(hModule);
+               }
+               if(GetModuleHandleW(lpLibFileName))
+                       bTrusted = TRUE;
+       }
+       if(!bTrusted)
+       {
+               if(LockThreadLock())
+               {
+                       if(hLock)
+                       {
+                               if(IsModuleTrusted(lpLibFileName))
+                                       bTrusted = TRUE;
+                       }
+                       UnlockThreadLock();
+               }
+       }
+       if(bTrusted)
                r = System_LoadLibrary(lpLibFileName, hFile, dwFlags);
+       FreeDuplicatedString(pw0);
+       if(hLock)
+               CloseHandle(hLock);
        return r;
 }
 
 // \88È\89º\83w\83\8b\83p\81[\8aÖ\90\94
 
-BOOL GetMD5HashOfFile(LPCWSTR Filename, void* pHash)
+BOOL LockThreadLock()
 {
        BOOL bResult;
-       HCRYPTPROV hProv;
-       HCRYPTHASH hHash;
-       HANDLE hFile;
-       DWORD Size;
-       void* pData;
-       DWORD dw;
+       DWORD ThreadId;
+       DWORD i;
        bResult = FALSE;
-       if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+       ThreadId = GetCurrentThreadId();
+       i = 0;
+       while(i < MAX_LOCKED_THREAD)
        {
-               if(CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
+               if(g_LockedThread[i] == ThreadId)
+                       break;
+               i++;
+       }
+       if(i >= MAX_LOCKED_THREAD)
+       {
+               i = 0;
+               while(i < MAX_LOCKED_THREAD)
                {
-                       if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
+                       if(g_LockedThread[i] == 0)
                        {
-                               Size = GetFileSize(hFile, NULL);
-                               if(pData = VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE))
-                               {
-                                       VirtualLock(pData, Size);
-                                       if(ReadFile(hFile, pData, Size, &dw, NULL))
-                                       {
-                                               if(CryptHashData(hHash, (BYTE*)pData, Size, 0))
-                                               {
-                                                       dw = 16;
-                                                       if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))
-                                                               bResult = TRUE;
-                                               }
-                                       }
-                                       VirtualUnlock(pData, Size);
-                                       VirtualFree(pData, Size, MEM_DECOMMIT);
-                               }
-                               CloseHandle(hFile);
+                               g_LockedThread[i] = ThreadId;
+                               bResult = TRUE;
+                               break;
                        }
-                       CryptDestroyHash(hHash);
+                       i++;
                }
-               CryptReleaseContext(hProv, 0);
+       }
+       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;
 }
@@ -287,43 +359,378 @@ BOOL HookFunctionInIAT(void* pOriginal, void* pNew)
 }
 #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 FindTrustedModuleMD5Hash(void* pHash)
+{
+       BOOL bResult;
+       int i;
+       bResult = FALSE;
+       i = 0;
+       while(i < MAX_TRUSTED_MD5_HASH_TABLE)
+       {
+               if(memcmp(&g_TrustedMD5HashTable[i], pHash, 16) == 0)
+               {
+                       bResult = TRUE;
+                       break;
+               }
+               i++;
+       }
+       return bResult;
+}
+
+// \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;
+       bResult = FALSE;
+       ZeroMemory(&wfi, sizeof(WINTRUST_FILE_INFO));
+       wfi.cbStruct = sizeof(WINTRUST_FILE_INFO);
+       wfi.pcwszFilePath = Filename;
+       ZeroMemory(&wd, sizeof(WINTRUST_DATA));
+       wd.cbStruct = sizeof(WINTRUST_DATA);
+       wd.dwUIChoice = WTD_UI_NONE;
+       wd.dwUnionChoice = WTD_CHOICE_FILE;
+       wd.pFile = &wfi;
+       if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS)
+               bResult = TRUE;
+       return bResult;
+}
+
+// \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
+// \83n\83b\83V\83\85\82ª\93o\98^\82³\82ê\82Ä\82¢\82é\81AAuthenticode\8f\90\96¼\82ª\82³\82ê\82Ä\82¢\82é\81A\82Ü\82½\82ÍWFP\82É\82æ\82é\95Û\8cì\89º\82É\82 \82é\82±\82Æ\82ð\8am\94F
+BOOL IsModuleTrusted(LPCWSTR Filename)
+{
+       BOOL bResult;
+       BYTE Hash[16];
+       bResult = FALSE;
+       if(GetMD5HashOfFile(Filename, &Hash))
+       {
+               if(FindTrustedModuleMD5Hash(&Hash))
+                       bResult = TRUE;
+       }
+       if(!bResult)
+       {
+               if(VerifyFileSignature(Filename))
+                       bResult = TRUE;
+       }
+       if(!bResult)
+       {
+               if(IsSxsModuleTrusted(Filename))
+                       bResult = TRUE;
+       }
+       if(!bResult)
+       {
+               if(SfcIsFileProtected(NULL, Filename))
+                       bResult = TRUE;
+       }
+       return bResult;
+}
+
 // kernel32.dll\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)
+//     if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))
+       if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040))
        {
-//             if(p_LdrGetDllHandle(NULL, dwFlags, &us, &r) == 0)
-               if(p_LdrGetDllHandle(NULL, &dwFlags, &us, &r) == 0)
+//             if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == STATUS_SUCCESS)
+               if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == 0)
                {
-                       if(p_LdrAddRefDll)
-                               p_LdrAddRefDll(0, r);
+//                     dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);
+                       dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040);
+                       dwFlags |= DONT_RESOLVE_DLL_REFERENCES;
                }
                else
                {
-                       dwFlags |= DONT_RESOLVE_DLL_REFERENCES;
-//                     if(p_LdrLoadDll(NULL, dwFlags, &us, &r) == 0)
-                       if(p_LdrLoadDll(NULL, &dwFlags, &us, &r) == 0)
+//                     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
-                               r = NULL;
+                       {
+//                             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 | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)))
+       if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040)))
        {
-//             if(p_LdrGetDllHandle(NULL, dwFlags, &us, &r) == 0)
-               if(p_LdrGetDllHandle(NULL, &dwFlags, &us, &r) == 0)
-               {
-                       if(p_LdrAddRefDll)
-                               p_LdrAddRefDll(0, r);
-               }
-//             else if(p_LdrLoadDll(NULL, dwFlags, &us, &r) == 0)
-               else if(p_LdrLoadDll(NULL, &dwFlags, &us, &r) == 0)
+               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
@@ -332,23 +739,65 @@ HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
        return r;
 }
 
+// \83t\83@\83C\83\8b\82ÌMD5\83n\83b\83V\83\85\82ð\8eæ\93¾
+BOOL GetMD5HashOfFile(LPCWSTR Filename, void* pHash)
+{
+       BOOL bResult;
+       HCRYPTPROV hProv;
+       HCRYPTHASH hHash;
+       HANDLE hFile;
+       DWORD Size;
+       void* pData;
+       DWORD dw;
+       bResult = FALSE;
+       if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+       {
+               if(CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
+               {
+                       if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
+                       {
+                               Size = GetFileSize(hFile, NULL);
+                               if(pData = VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE))
+                               {
+                                       VirtualLock(pData, Size);
+                                       if(ReadFile(hFile, pData, Size, &dw, NULL))
+                                       {
+                                               if(CryptHashData(hHash, (BYTE*)pData, Size, 0))
+                                               {
+                                                       dw = 16;
+                                                       if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))
+                                                               bResult = TRUE;
+                                               }
+                                       }
+                                       VirtualUnlock(pData, Size);
+                                       VirtualFree(pData, Size, MEM_DECOMMIT);
+                               }
+                               CloseHandle(hFile);
+                       }
+                       CryptDestroyHash(hHash);
+               }
+               CryptReleaseContext(hProv, 0);
+       }
+       return bResult;
+}
+
 // DLL\82Ì\83n\83b\83V\83\85\82ð\93o\98^
-BOOL RegisterModuleMD5Hash(void* pHash)
+BOOL RegisterTrustedModuleMD5Hash(void* pHash)
 {
        BOOL bResult;
        BYTE NullHash[16] = {0};
        int i;
        bResult = FALSE;
-       if(FindModuleMD5Hash(pHash))
+       if(FindTrustedModuleMD5Hash(pHash))
                bResult = TRUE;
        else
        {
                i = 0;
-               while(i < MAX_MD5_HASH_TABLE)
+               while(i < MAX_TRUSTED_MD5_HASH_TABLE)
                {
-                       if(memcmp(&g_MD5HashTable[i], &NullHash, 16) == 0)
+                       if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 16) == 0)
                        {
-                               memcpy(&g_MD5HashTable[i], pHash, 16);
+                               memcpy(&g_TrustedMD5HashTable[i], pHash, 16);
                                bResult = TRUE;
                                break;
                        }
@@ -359,18 +808,18 @@ BOOL RegisterModuleMD5Hash(void* pHash)
 }
 
 // DLL\82Ì\83n\83b\83V\83\85\82Ì\93o\98^\82ð\89ð\8f\9c
-BOOL UnregisterModuleMD5Hash(void* pHash)
+BOOL UnregisterTrustedModuleMD5Hash(void* pHash)
 {
        BOOL bResult;
        BYTE NullHash[16] = {0};
        int i;
        bResult = FALSE;
        i = 0;
-       while(i < MAX_MD5_HASH_TABLE)
+       while(i < MAX_TRUSTED_MD5_HASH_TABLE)
        {
-               if(memcmp(&g_MD5HashTable[i], pHash, 16) == 0)
+               if(memcmp(&g_TrustedMD5HashTable[i], pHash, 16) == 0)
                {
-                       memcpy(&g_MD5HashTable[i], &NullHash, 16);
+                       memcpy(&g_TrustedMD5HashTable[i], &NullHash, 16);
                        bResult = TRUE;
                        break;
                }
@@ -379,144 +828,157 @@ BOOL UnregisterModuleMD5Hash(void* pHash)
        return bResult;
 }
 
-// DLL\82Ì\83n\83b\83V\83\85\82ð\8c\9f\8dõ
-BOOL FindModuleMD5Hash(void* pHash)
+// \90M\97\8a\82Å\82«\82È\82¢DLL\82ð\83A\83\93\83\8d\81[\83h
+BOOL UnloadUntrustedModule()
 {
        BOOL bResult;
-       int i;
+       wchar_t* pw0;
+       HANDLE hSnapshot;
+       MODULEENTRY32 me;
+       DWORD Length;
        bResult = FALSE;
-       i = 0;
-       while(i < MAX_MD5_HASH_TABLE)
+       pw0 = NULL;
+       if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE)
        {
-               if(memcmp(&g_MD5HashTable[i], pHash, 16) == 0)
+               bResult = TRUE;
+               me.dwSize = sizeof(MODULEENTRY32);
+               if(Module32First(hSnapshot, &me))
                {
-                       bResult = TRUE;
-                       break;
+                       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));
                }
-               i++;
+               CloseHandle(hSnapshot);
        }
-       return bResult;
-}
-
-// DLL\82ð\8am\94F
-// \83n\83b\83V\83\85\82ª\93o\98^\82³\82ê\82Ä\82¢\82é\81AAuthenticode\8f\90\96¼\82ª\82³\82ê\82Ä\82¢\82é\81A\82Ü\82½\82ÍWFP\82É\82æ\82é\95Û\8cì\89º\82É\82 \82é\82±\82Æ\82ð\8am\94F
-BOOL IsModuleTrustedA(LPCSTR Filename)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-       pw0 = DuplicateAtoW(Filename, -1);
-       r = IsModuleTrustedW(pw0);
        FreeDuplicatedString(pw0);
-       return r;
-}
-
-// DLL\82ð\8am\94F
-// \83n\83b\83V\83\85\82ª\93o\98^\82³\82ê\82Ä\82¢\82é\81AAuthenticode\8f\90\96¼\82ª\82³\82ê\82Ä\82¢\82é\81A\82Ü\82½\82ÍWFP\82É\82æ\82é\95Û\8cì\89º\82É\82 \82é\82±\82Æ\82ð\8am\94F
-BOOL IsModuleTrustedW(LPCWSTR Filename)
-{
-       BOOL bResult;
-       WCHAR Path[MAX_PATH];
-       LPWSTR p;
-       BYTE Hash[16];
-       GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;
-       WINTRUST_FILE_INFO wfi;
-       WINTRUST_DATA wd;
-       bResult = FALSE;
-       if(wcsrchr(Filename, '.') > wcsrchr(Filename, '\\'))
-       {
-               if(SearchPathW(NULL, Filename, NULL, MAX_PATH, Path, &p) > 0)
-                       Filename = Path;
-       }
-       else
-       {
-               if(SearchPathW(NULL, Filename, L".dll", MAX_PATH, Path, &p) > 0)
-                       Filename = Path;
-       }
-       if(GetMD5HashOfFile(Filename, &Hash))
-       {
-               if(FindModuleMD5Hash(&Hash))
-                       bResult = TRUE;
-       }
-       if(!bResult)
-       {
-               ZeroMemory(&wfi, sizeof(WINTRUST_FILE_INFO));
-               wfi.cbStruct = sizeof(WINTRUST_FILE_INFO);
-               wfi.pcwszFilePath = Filename;
-               ZeroMemory(&wd, sizeof(WINTRUST_DATA));
-               wd.cbStruct = sizeof(WINTRUST_DATA);
-               wd.dwUIChoice = WTD_UI_NONE;
-               wd.dwUnionChoice = WTD_CHOICE_FILE;
-               wd.pFile = &wfi;
-               if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS)
-                       bResult = TRUE;
-       }
-       if(!bResult)
-       {
-               if(SfcIsFileProtected(NULL, Filename))
-                       bResult = TRUE;
-       }
-//     if(!bResult)
-//     {
-//             WCHAR Temp[MAX_PATH + 128];
-//             _swprintf(Temp, L"Untrusted module was detected! \"%s\"\n", Filename);
-//             OutputDebugStringW(Temp);
-//     }
        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;
-       hModule = GetModuleHandleW(L"kernel32.dll");
-       GET_FUNCTION(hModule, LoadLibraryA);
-       GET_FUNCTION(hModule, LoadLibraryW);
-       GET_FUNCTION(hModule, LoadLibraryExA);
-       GET_FUNCTION(hModule, LoadLibraryExW);
-       hModule = GetModuleHandleW(L"ntdll.dll");
-       GET_FUNCTION(hModule, LdrLoadDll);
-       GET_FUNCTION(hModule, LdrGetDllHandle);
-       GET_FUNCTION(hModule, LdrAddRefDll);
-       return TRUE;
+       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)
        {
-               // \8c\9f\8fØ\82É\95K\97v\82ÈDLL\82Ì\92x\89\84\93Ç\82Ý\8d\9e\82Ý\89ñ\94ð
-               IsModuleTrustedA("");
+               bResult = TRUE;
 #ifdef USE_CODE_HOOK
-               SET_HOOK_FUNCTION(LoadLibraryA);
-               SET_HOOK_FUNCTION(LoadLibraryW);
-               SET_HOOK_FUNCTION(LoadLibraryExA);
-               SET_HOOK_FUNCTION(LoadLibraryExW);
+               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
-               HookFunctionInIAT(p_LoadLibraryA, h_LoadLibraryA);
-               HookFunctionInIAT(p_LoadLibraryW, h_LoadLibraryW);
-               HookFunctionInIAT(p_LoadLibraryExA, h_LoadLibraryExA);
-               HookFunctionInIAT(p_LoadLibraryExW, h_LoadLibraryExW);
+               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
-               END_HOOK_FUNCTION(LoadLibraryA);
-               END_HOOK_FUNCTION(LoadLibraryW);
-               END_HOOK_FUNCTION(LoadLibraryExA);
-               END_HOOK_FUNCTION(LoadLibraryExW);
+               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
-               HookFunctionInIAT(h_LoadLibraryA, p_LoadLibraryA);
-               HookFunctionInIAT(h_LoadLibraryW, p_LoadLibraryW);
-               HookFunctionInIAT(h_LoadLibraryExA, p_LoadLibraryExA);
-               HookFunctionInIAT(h_LoadLibraryExW, p_LoadLibraryExW);
+               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 TRUE;
+       return bResult;
 }
 
 // ReadProcessMemory\81AWriteProcessMemory\81ACreateRemoteThread\91Î\8dô