OSDN Git Service

Fix installers.
[ffftp/ffftp.git] / protectprocess.c
index b5a271e..edd3acc 100644 (file)
@@ -26,9 +26,6 @@
 #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
 #endif\r
 \r
 #ifdef USE_CODE_HOOK\r
-#if defined(_X86_)\r
+#if defined(_M_IX86)\r
 #define HOOK_JUMP_CODE_LENGTH 5\r
-#elif defined(_AMD64_)\r
+#elif defined(_M_AMD64)\r
 #define HOOK_JUMP_CODE_LENGTH 14\r
 #endif\r
+typedef struct\r
+{\r
+       void* pCode;\r
+       size_t CodeLength;\r
+       BYTE PatchCode[HOOK_JUMP_CODE_LENGTH];\r
+       BYTE BackupCode[HOOK_JUMP_CODE_LENGTH];\r
+} HOOK_JUMP_CODE_PATCH;\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
+BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatch, BOOL bRestore);\r
 #endif\r
 #ifdef USE_IAT_HOOK\r
 BOOL HookFunctionInIAT(void* pOriginal, void* pNew);\r
@@ -63,7 +67,7 @@ BOOL IsModuleTrusted(LPCWSTR Filename);
 \r
 // 変数の宣言\r
 #ifdef USE_CODE_HOOK\r
-#define HOOK_FUNCTION_VAR(name) _##name p_##name;BYTE c_##name[HOOK_JUMP_CODE_LENGTH * 2];\r
+#define HOOK_FUNCTION_VAR(name) _##name p_##name;HOOK_JUMP_CODE_PATCH c_##name;\r
 #endif\r
 #ifdef USE_IAT_HOOK\r
 #define HOOK_FUNCTION_VAR(name) _##name p_##name;\r
@@ -75,7 +79,7 @@ BOOL IsModuleTrusted(LPCWSTR Filename);
 // フック対象を呼び出す前に対象のコードを復元\r
 #define BEGIN_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, TRUE)\r
 // フック対象を呼び出した後に対象のコードを置換\r
-#define END_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, NULL, FALSE)\r
+#define END_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE)\r
 \r
 HOOK_FUNCTION_VAR(LoadLibraryA)\r
 HOOK_FUNCTION_VAR(LoadLibraryW)\r
@@ -94,12 +98,12 @@ _CryptCATAdminCalcHashFromFileHandle p_CryptCATAdminCalcHashFromFileHandle;
 \r
 #define MAX_LOCKED_THREAD 16\r
 #define MAX_TRUSTED_FILENAME_TABLE 16\r
-#define MAX_TRUSTED_MD5_HASH_TABLE 16\r
+#define MAX_TRUSTED_SHA1_HASH_TABLE 16\r
 \r
 DWORD g_ProcessProtectionLevel;\r
 DWORD g_LockedThread[MAX_LOCKED_THREAD];\r
 WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE];\r
-BYTE g_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][20];\r
+BYTE g_TrustedSHA1HashTable[MAX_TRUSTED_SHA1_HASH_TABLE][20];\r
 WNDPROC g_PasswordEditControlProc;\r
 \r
 // 以下フック関数\r
@@ -245,63 +249,120 @@ BOOL UnlockThreadLock()
 }\r
 \r
 #ifdef USE_CODE_HOOK\r
-BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore)\r
+BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatch, BOOL bRestore)\r
 {\r
        BOOL bResult;\r
        bResult = FALSE;\r
-#if defined(_X86_)\r
+#if defined(_M_IX86)\r
        {\r
-               BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xe9, 0x00, 0x00, 0x00, 0x00};\r
-               size_t Relative;\r
                DWORD Protect;\r
-               Relative = (size_t)pNew - (size_t)pOriginal - HOOK_JUMP_CODE_LENGTH;\r
-               memcpy(&JumpCode[1], &Relative, 4);\r
+               BYTE* pCode;\r
+               CHAR c;\r
+               LONG l;\r
+               bResult = FALSE;\r
                if(bRestore)\r
                {\r
-                       if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
+                       if(VirtualProtect(pPatch->pCode, pPatch->CodeLength, PAGE_EXECUTE_READWRITE, &Protect))\r
                        {\r
-                               memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH);\r
-                               VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
+                               memcpy(pPatch->pCode, &pPatch->BackupCode, pPatch->CodeLength);\r
+                               VirtualProtect(pPatch->pCode, pPatch->CodeLength, 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
+                       if(!pPatch->pCode)\r
+                       {\r
+                               pCode = (BYTE*)pOriginal;\r
+                               while(pCode[0] == 0xeb)\r
+                               {\r
+                                       memcpy(&c, pCode + 1, 1);\r
+                                       pCode = pCode + 2 + c;\r
+                               }\r
+                               if(pCode[0] == 0xe9)\r
+                               {\r
+                                       pPatch->pCode = pCode + 1;\r
+                                       pPatch->CodeLength = 4;\r
+                                       memcpy(&pPatch->BackupCode, pPatch->pCode, pPatch->CodeLength);\r
+                                       l = (long)pNew - ((long)pCode + 5);\r
+                                       memcpy(&pPatch->PatchCode[0], &l, 4);\r
+                               }\r
+                               else\r
+                               {\r
+                                       pPatch->pCode = pCode;\r
+                                       pPatch->CodeLength = 5;\r
+                                       memcpy(&pPatch->BackupCode, pPatch->pCode, pPatch->CodeLength);\r
+                                       pPatch->PatchCode[0] = 0xe9;\r
+                                       l = (long)pNew - ((long)pCode + 5);\r
+                                       memcpy(&pPatch->PatchCode[1], &l, 4);\r
+                               }\r
+                       }\r
+                       if(VirtualProtect(pPatch->pCode, pPatch->CodeLength, PAGE_EXECUTE_READWRITE, &Protect))\r
                        {\r
-                               memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH);\r
-                               VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
+                               memcpy(pPatch->pCode, &pPatch->PatchCode, pPatch->CodeLength);\r
+                               VirtualProtect(pPatch->pCode, pPatch->CodeLength, Protect, &Protect);\r
                                bResult = TRUE;\r
                        }\r
                }\r
        }\r
-#elif defined(_AMD64_)\r
+#elif defined(_M_AMD64)\r
        {\r
-               BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
-               size_t Absolute;\r
                DWORD Protect;\r
-               Absolute = (size_t)pNew;\r
-               memcpy(&JumpCode[6], &Absolute, 8);\r
+               BYTE* pCode;\r
+               CHAR c;\r
+               LONG l;\r
                bResult = FALSE;\r
                if(bRestore)\r
                {\r
-                       if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
+                       if(VirtualProtect(pPatch->pCode, pPatch->CodeLength, PAGE_EXECUTE_READWRITE, &Protect))\r
                        {\r
-                               memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH);\r
-                               VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
+                               memcpy(pPatch->pCode, &pPatch->BackupCode, pPatch->CodeLength);\r
+                               VirtualProtect(pPatch->pCode, pPatch->CodeLength, 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
+                       if(!pPatch->pCode)\r
+                       {\r
+                               pCode = (BYTE*)pOriginal;\r
+                               while(pCode[0] == 0xeb || pCode[0] == 0xe9)\r
+                               {\r
+                                       if(pCode[0] == 0xeb)\r
+                                       {\r
+                                               memcpy(&c, pCode + 1, 1);\r
+                                               pCode = pCode + 2 + c;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               memcpy(&l, pCode + 1, 4);\r
+                                               pCode = pCode + 5 + l;\r
+                                       }\r
+                               }\r
+                               if(pCode[0] == 0xff && pCode[1] == 0x25)\r
+                               {\r
+                                       memcpy(&l, pCode + 2, 4);\r
+                                       pPatch->pCode = pCode + 6 + l;\r
+                                       pPatch->CodeLength = 8;\r
+                                       memcpy(&pPatch->BackupCode, pPatch->pCode, pPatch->CodeLength);\r
+                                       memcpy(&pPatch->PatchCode[0], &pNew, 8);\r
+                               }\r
+                               else\r
+                               {\r
+                                       pPatch->pCode = pCode;\r
+                                       pPatch->CodeLength = 14;\r
+                                       memcpy(&pPatch->BackupCode, pPatch->pCode, pPatch->CodeLength);\r
+                                       pPatch->PatchCode[0] = 0xff;\r
+                                       pPatch->PatchCode[1] = 0x25;\r
+                                       l = 0;\r
+                                       memcpy(&pPatch->PatchCode[2], &l, 4);\r
+                                       memcpy(&pPatch->PatchCode[6], &pNew, 8);\r
+                               }\r
+                       }\r
+                       if(VirtualProtect(pPatch->pCode, pPatch->CodeLength, PAGE_EXECUTE_READWRITE, &Protect))\r
                        {\r
-                               memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH);\r
-                               VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
+                               memcpy(pPatch->pCode, &pPatch->PatchCode, pPatch->CodeLength);\r
+                               VirtualProtect(pPatch->pCode, pPatch->CodeLength, Protect, &Protect);\r
                                bResult = TRUE;\r
                        }\r
                }\r
@@ -379,9 +440,9 @@ BOOL FindTrustedModuleSHA1Hash(void* pHash)
        int i;\r
        bResult = FALSE;\r
        i = 0;\r
-       while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
+       while(i < MAX_TRUSTED_SHA1_HASH_TABLE)\r
        {\r
-               if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0)\r
+               if(memcmp(&g_TrustedSHA1HashTable[i], pHash, 20) == 0)\r
                {\r
                        bResult = TRUE;\r
                        break;\r
@@ -705,12 +766,12 @@ BOOL IsModuleTrusted(LPCWSTR Filename)
                }\r
                if(!bResult)\r
                {\r
-                       if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SIDE_BY_SIDE) && IsSxsModuleTrusted(Filename))\r
+                       if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SYSTEM_FILE) && SfcIsFileProtected(NULL, Filename))\r
                                bResult = TRUE;\r
                }\r
                if(!bResult)\r
                {\r
-                       if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SYSTEM_FILE) && SfcIsFileProtected(NULL, Filename))\r
+                       if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SIDE_BY_SIDE) && IsSxsModuleTrusted(Filename))\r
                                bResult = TRUE;\r
                }\r
                UnlockThreadLock();\r
@@ -730,8 +791,8 @@ HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
        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.Length = sizeof(wchar_t) * (USHORT)wcslen(lpLibFileName);\r
+       us.MaximumLength = sizeof(wchar_t) * ((USHORT)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
@@ -798,40 +859,23 @@ void SetProcessProtectionLevel(DWORD Level)
        g_ProcessProtectionLevel = Level;\r
 }\r
 \r
-// ファイルのSHA1ハッシュを取得\r
-BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash)\r
+//     メモリのSHA1ハッシュを取得\r
+BOOL GetSHA1HashOfMemory(const void* pData, DWORD Size, 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
+                       if(CryptHashData(hHash, (BYTE*)pData, Size, 0))\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
+                               dw = 20;\r
+                               if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))\r
+                                       bResult = TRUE;\r
                        }\r
                        CryptDestroyHash(hHash);\r
                }\r
@@ -840,6 +884,34 @@ BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash)
        return bResult;\r
 }\r
 \r
+// ファイルのSHA1ハッシュを取得\r
+BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash)\r
+{\r
+       BOOL bResult;\r
+       HANDLE hFile;\r
+       DWORD Size;\r
+       void* pData;\r
+       DWORD dw;\r
+       bResult = FALSE;\r
+       if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
+       {\r
+               Size = GetFileSize(hFile, NULL);\r
+               if(pData = VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE))\r
+               {\r
+                       VirtualLock(pData, Size);\r
+                       if(ReadFile(hFile, pData, Size, &dw, NULL))\r
+                       {\r
+                               if(GetSHA1HashOfMemory(pData, Size, pHash))\r
+                                       bResult = TRUE;\r
+                       }\r
+                       VirtualUnlock(pData, Size);\r
+                       VirtualFree(pData, Size, MEM_DECOMMIT);\r
+               }\r
+               CloseHandle(hFile);\r
+       }\r
+       return bResult;\r
+}\r
+\r
 // DLLのハッシュを登録\r
 BOOL RegisterTrustedModuleSHA1Hash(void* pHash)\r
 {\r
@@ -852,11 +924,11 @@ BOOL RegisterTrustedModuleSHA1Hash(void* pHash)
        else\r
        {\r
                i = 0;\r
-               while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
+               while(i < MAX_TRUSTED_SHA1_HASH_TABLE)\r
                {\r
-                       if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 20) == 0)\r
+                       if(memcmp(&g_TrustedSHA1HashTable[i], &NullHash, 20) == 0)\r
                        {\r
-                               memcpy(&g_TrustedMD5HashTable[i], pHash, 20);\r
+                               memcpy(&g_TrustedSHA1HashTable[i], pHash, 20);\r
                                bResult = TRUE;\r
                                break;\r
                        }\r
@@ -874,11 +946,11 @@ BOOL UnregisterTrustedModuleSHA1Hash(void* pHash)
        int i;\r
        bResult = FALSE;\r
        i = 0;\r
-       while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
+       while(i < MAX_TRUSTED_SHA1_HASH_TABLE)\r
        {\r
-               if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0)\r
+               if(memcmp(&g_TrustedSHA1HashTable[i], pHash, 20) == 0)\r
                {\r
-                       memcpy(&g_TrustedMD5HashTable[i], &NullHash, 20);\r
+                       memcpy(&g_TrustedSHA1HashTable[i], &NullHash, 20);\r
                        bResult = TRUE;\r
                        break;\r
                }\r
@@ -980,6 +1052,8 @@ BOOL InitializeLoadLibraryHook()
                bResult = FALSE;\r
        if(!(GET_FUNCTION(hModule, CryptCATAdminCalcHashFromFileHandle)))\r
                bResult = FALSE;\r
+       // バグ対策\r
+       ImageGetDigestStream(NULL, 0, NULL, NULL);\r
        return bResult;\r
 }\r
 \r