OSDN Git Service

Modify documents.
[ffftp/ffftp.git] / protectprocess.c
1 // protectprocess.c\r
2 // Copyright (C) 2011 Suguru Kawamoto\r
3 // プロセスの保護\r
4 \r
5 // 次の中から1個のみ有効にする\r
6 // フック先の関数のコードを書き換える\r
7 // 全ての呼び出しをフック可能だが原理的に二重呼び出しに対応できない\r
8 #define USE_CODE_HOOK\r
9 // フック先の関数のインポートアドレステーブルを書き換える\r
10 // 二重呼び出しが可能だが呼び出し方法によってはフックを回避される\r
11 //#define USE_IAT_HOOK\r
12 \r
13 // フック対象の関数名 %s\r
14 // フック対象の型 _%s\r
15 // フック対象のポインタ p_%s\r
16 // フック用の関数名 h_%s\r
17 // フック対象のコードのバックアップ c_%s\r
18 \r
19 #include <tchar.h>\r
20 #include <windows.h>\r
21 #include <ntsecapi.h>\r
22 #include <wincrypt.h>\r
23 #include <wintrust.h>\r
24 #include <softpub.h>\r
25 #include <aclapi.h>\r
26 #include <sfc.h>\r
27 #include <tlhelp32.h>\r
28 #include <imagehlp.h>\r
29 #ifdef USE_IAT_HOOK\r
30 #include <dbghelp.h>\r
31 #endif\r
32 \r
33 #define DO_NOT_REPLACE\r
34 #include "protectprocess.h"\r
35 #include "mbswrapper.h"\r
36 \r
37 #ifdef USE_IAT_HOOK\r
38 #pragma comment(lib, "dbghelp.lib")\r
39 #endif\r
40 \r
41 #ifdef USE_CODE_HOOK\r
42 #if defined(_X86_)\r
43 #define HOOK_JUMP_CODE_LENGTH 5\r
44 #elif defined(_AMD64_)\r
45 #define HOOK_JUMP_CODE_LENGTH 14\r
46 #endif\r
47 #endif\r
48 \r
49 BOOL LockThreadLock();\r
50 BOOL UnlockThreadLock();\r
51 #ifdef USE_CODE_HOOK\r
52 BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore);\r
53 #endif\r
54 #ifdef USE_IAT_HOOK\r
55 BOOL HookFunctionInIAT(void* pOriginal, void* pNew);\r
56 #endif\r
57 HANDLE LockExistingFile(LPCWSTR Filename);\r
58 BOOL FindTrustedModuleSHA1Hash(void* pHash);\r
59 BOOL VerifyFileSignature(LPCWSTR Filename);\r
60 BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename);\r
61 BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash);\r
62 BOOL IsModuleTrusted(LPCWSTR Filename);\r
63 \r
64 // 変数の宣言\r
65 #ifdef USE_CODE_HOOK\r
66 #define HOOK_FUNCTION_VAR(name) _##name p_##name;BYTE c_##name[HOOK_JUMP_CODE_LENGTH * 2];\r
67 #endif\r
68 #ifdef USE_IAT_HOOK\r
69 #define HOOK_FUNCTION_VAR(name) _##name p_##name;\r
70 #endif\r
71 // 関数ポインタを取得\r
72 #define GET_FUNCTION(h, name) p_##name = (_##name)GetProcAddress(h, #name)\r
73 // フック対象のコードを置換してフックを開始\r
74 #define SET_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE)\r
75 // フック対象を呼び出す前に対象のコードを復元\r
76 #define START_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, TRUE)\r
77 // フック対象を呼び出した後に対象のコードを置換\r
78 #define END_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, NULL, FALSE)\r
79 \r
80 HOOK_FUNCTION_VAR(LoadLibraryA)\r
81 HOOK_FUNCTION_VAR(LoadLibraryW)\r
82 HOOK_FUNCTION_VAR(LoadLibraryExA)\r
83 HOOK_FUNCTION_VAR(LoadLibraryExW)\r
84 \r
85 typedef NTSTATUS (NTAPI* _LdrLoadDll)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*);\r
86 typedef NTSTATUS (NTAPI* _LdrGetDllHandle)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*);\r
87 typedef PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)(PVOID);\r
88 typedef BOOL (WINAPI* _CryptCATAdminCalcHashFromFileHandle)(HANDLE, DWORD*, BYTE*, DWORD);\r
89 \r
90 _LdrLoadDll p_LdrLoadDll;\r
91 _LdrGetDllHandle p_LdrGetDllHandle;\r
92 _RtlImageNtHeader p_RtlImageNtHeader;\r
93 _CryptCATAdminCalcHashFromFileHandle p_CryptCATAdminCalcHashFromFileHandle;\r
94 \r
95 #define MAX_LOCKED_THREAD 16\r
96 #define MAX_TRUSTED_FILENAME_TABLE 16\r
97 #define MAX_TRUSTED_MD5_HASH_TABLE 16\r
98 \r
99 DWORD g_ProcessProtectionLevel;\r
100 DWORD g_LockedThread[MAX_LOCKED_THREAD];\r
101 WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE];\r
102 BYTE g_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][20];\r
103 WNDPROC g_PasswordEditControlProc;\r
104 \r
105 // 以下フック関数\r
106 // フック対象を呼び出す場合は前後でSTART_HOOK_FUNCTIONとEND_HOOK_FUNCTIONを実行する必要がある\r
107 \r
108 HMODULE WINAPI h_LoadLibraryA(LPCSTR lpLibFileName)\r
109 {\r
110         HMODULE r = NULL;\r
111         wchar_t* pw0 = NULL;\r
112         if(pw0 = DuplicateAtoW(lpLibFileName, -1))\r
113                 r = LoadLibraryExW(pw0, NULL, 0);\r
114         FreeDuplicatedString(pw0);\r
115         return r;\r
116 }\r
117 \r
118 HMODULE WINAPI h_LoadLibraryW(LPCWSTR lpLibFileName)\r
119 {\r
120         HMODULE r = NULL;\r
121         r = LoadLibraryExW(lpLibFileName, NULL, 0);\r
122         return r;\r
123 }\r
124 \r
125 HMODULE WINAPI h_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
126 {\r
127         HMODULE r = NULL;\r
128         wchar_t* pw0 = NULL;\r
129         if(pw0 = DuplicateAtoW(lpLibFileName, -1))\r
130                 r = LoadLibraryExW(pw0, hFile, dwFlags);\r
131         FreeDuplicatedString(pw0);\r
132         return r;\r
133 }\r
134 \r
135 HMODULE WINAPI h_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
136 {\r
137         HMODULE r = NULL;\r
138         BOOL bTrusted;\r
139         wchar_t* pw0;\r
140         HANDLE hLock;\r
141         HMODULE hModule;\r
142         DWORD Length;\r
143         bTrusted = FALSE;\r
144         pw0 = NULL;\r
145         hLock = NULL;\r
146 //      if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))\r
147         if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | 0x00000020 | 0x00000040))\r
148                 bTrusted = TRUE;\r
149         if(!bTrusted)\r
150         {\r
151                 if(hModule = System_LoadLibrary(lpLibFileName, NULL, DONT_RESOLVE_DLL_REFERENCES))\r
152                 {\r
153                         Length = MAX_PATH;\r
154                         if(pw0 = AllocateStringW(Length))\r
155                         {\r
156                                 if(GetModuleFileNameW(hModule, pw0, Length) > 0)\r
157                                 {\r
158                                         while(pw0)\r
159                                         {\r
160                                                 if(GetModuleFileNameW(hModule, pw0, Length) + 1 <= Length)\r
161                                                 {\r
162                                                         lpLibFileName = pw0;\r
163                                                         break;\r
164                                                 }\r
165                                                 Length = Length * 2;\r
166                                                 FreeDuplicatedString(pw0);\r
167                                                 pw0 = AllocateStringW(Length);\r
168                                         }\r
169                                 }\r
170                         }\r
171                         hLock = LockExistingFile(lpLibFileName);\r
172                         FreeLibrary(hModule);\r
173                 }\r
174                 if((g_ProcessProtectionLevel & PROCESS_PROTECTION_LOADED) && GetModuleHandleW(lpLibFileName))\r
175                         bTrusted = TRUE;\r
176         }\r
177         if(!bTrusted)\r
178         {\r
179                 if(hLock)\r
180                 {\r
181                         if(IsModuleTrusted(lpLibFileName))\r
182                                 bTrusted = TRUE;\r
183                 }\r
184         }\r
185         if(bTrusted)\r
186                 r = System_LoadLibrary(lpLibFileName, hFile, dwFlags);\r
187         FreeDuplicatedString(pw0);\r
188         if(hLock)\r
189                 CloseHandle(hLock);\r
190         return r;\r
191 }\r
192 \r
193 // 以下ヘルパー関数\r
194 \r
195 BOOL LockThreadLock()\r
196 {\r
197         BOOL bResult;\r
198         DWORD ThreadId;\r
199         DWORD i;\r
200         bResult = FALSE;\r
201         ThreadId = GetCurrentThreadId();\r
202         i = 0;\r
203         while(i < MAX_LOCKED_THREAD)\r
204         {\r
205                 if(g_LockedThread[i] == ThreadId)\r
206                         break;\r
207                 i++;\r
208         }\r
209         if(i >= MAX_LOCKED_THREAD)\r
210         {\r
211                 i = 0;\r
212                 while(i < MAX_LOCKED_THREAD)\r
213                 {\r
214                         if(g_LockedThread[i] == 0)\r
215                         {\r
216                                 g_LockedThread[i] = ThreadId;\r
217                                 bResult = TRUE;\r
218                                 break;\r
219                         }\r
220                         i++;\r
221                 }\r
222         }\r
223         return bResult;\r
224 }\r
225 \r
226 BOOL UnlockThreadLock()\r
227 {\r
228         BOOL bResult;\r
229         DWORD ThreadId;\r
230         DWORD i;\r
231         bResult = FALSE;\r
232         ThreadId = GetCurrentThreadId();\r
233         i = 0;\r
234         while(i < MAX_LOCKED_THREAD)\r
235         {\r
236                 if(g_LockedThread[i] == ThreadId)\r
237                 {\r
238                         g_LockedThread[i] = 0;\r
239                         bResult = TRUE;\r
240                         break;\r
241                 }\r
242                 i++;\r
243         }\r
244         return bResult;\r
245 }\r
246 \r
247 #ifdef USE_CODE_HOOK\r
248 BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore)\r
249 {\r
250         BOOL bResult;\r
251         DWORD Protect;\r
252 #if defined(_X86_)\r
253         BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xe9, 0x00, 0x00, 0x00, 0x00};\r
254         size_t Relative;\r
255         Relative = (size_t)pNew - (size_t)pOriginal - HOOK_JUMP_CODE_LENGTH;\r
256         memcpy(&JumpCode[1], &Relative, 4);\r
257         bResult = FALSE;\r
258         if(bRestore)\r
259         {\r
260                 if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
261                 {\r
262                         memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH);\r
263                         VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
264                         bResult = TRUE;\r
265                 }\r
266         }\r
267         else\r
268         {\r
269                 if(pBackupCode)\r
270                         memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH);\r
271                 if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
272                 {\r
273                         memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH);\r
274                         VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
275                         bResult = TRUE;\r
276                 }\r
277         }\r
278 #elif defined(_AMD64_)\r
279         BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
280         size_t Absolute;\r
281         Absolute = (size_t)pOriginal;\r
282         memcpy(&JumpCode[6], &Absolute, 8);\r
283         bResult = FALSE;\r
284         if(bRestore)\r
285         {\r
286                 if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
287                 {\r
288                         memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH);\r
289                         VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
290                         bResult = TRUE;\r
291                 }\r
292         }\r
293         else\r
294         {\r
295                 if(pBackupCode)\r
296                         memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH);\r
297                 if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
298                 {\r
299                         memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH);\r
300                         VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
301                         bResult = TRUE;\r
302                 }\r
303         }\r
304 #endif\r
305         return bResult;\r
306 }\r
307 #endif\r
308 \r
309 #ifdef USE_IAT_HOOK\r
310 BOOL HookFunctionInIAT(void* pOriginal, void* pNew)\r
311 {\r
312         BOOL bResult;\r
313         HANDLE hSnapshot;\r
314         MODULEENTRY32 me;\r
315         BOOL bFound;\r
316         IMAGE_IMPORT_DESCRIPTOR* piid;\r
317         ULONG Size;\r
318         IMAGE_THUNK_DATA* pitd;\r
319         DWORD Protect;\r
320         bResult = FALSE;\r
321         if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE)\r
322         {\r
323                 me.dwSize = sizeof(MODULEENTRY32);\r
324                 if(Module32First(hSnapshot, &me))\r
325                 {\r
326                         bFound = FALSE;\r
327                         do\r
328                         {\r
329                                 if(piid = (IMAGE_IMPORT_DESCRIPTOR*)ImageDirectoryEntryToData(me.hModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size))\r
330                                 {\r
331                                         while(!bFound && piid->Name != 0)\r
332                                         {\r
333                                                 pitd = (IMAGE_THUNK_DATA*)((BYTE*)me.hModule + piid->FirstThunk);\r
334                                                 while(!bFound && pitd->u1.Function != 0)\r
335                                                 {\r
336                                                         if((void*)pitd->u1.Function == pOriginal)\r
337                                                         {\r
338                                                                 bFound = TRUE;\r
339                                                                 if(VirtualProtect(&pitd->u1.Function, sizeof(void*), PAGE_EXECUTE_READWRITE, &Protect))\r
340                                                                 {\r
341                                                                         memcpy(&pitd->u1.Function, &pNew, sizeof(void*));\r
342                                                                         VirtualProtect(&pitd->u1.Function, sizeof(void*), Protect, &Protect);\r
343                                                                         bResult = TRUE;\r
344                                                                 }\r
345                                                         }\r
346                                                         pitd++;\r
347                                                 }\r
348                                                 piid++;\r
349                                         }\r
350                                 }\r
351                         }\r
352                         while(!bFound && Module32Next(hSnapshot, &me));\r
353                 }\r
354                 CloseHandle(hSnapshot);\r
355         }\r
356         return bResult;\r
357 }\r
358 #endif\r
359 \r
360 // ファイルを変更不能に設定\r
361 HANDLE LockExistingFile(LPCWSTR Filename)\r
362 {\r
363         HANDLE hResult;\r
364         hResult = NULL;\r
365         if((hResult = CreateFileW(Filename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)) == INVALID_HANDLE_VALUE)\r
366                 hResult = NULL;\r
367         return hResult;\r
368 }\r
369 \r
370 // DLLのハッシュを検索\r
371 BOOL FindTrustedModuleSHA1Hash(void* pHash)\r
372 {\r
373         BOOL bResult;\r
374         int i;\r
375         bResult = FALSE;\r
376         i = 0;\r
377         while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
378         {\r
379                 if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0)\r
380                 {\r
381                         bResult = TRUE;\r
382                         break;\r
383                 }\r
384                 i++;\r
385         }\r
386         return bResult;\r
387 }\r
388 \r
389 BOOL VerifyFileSignature_Function(LPCWSTR Filename)\r
390 {\r
391         BOOL bResult;\r
392         HCERTSTORE hStore;\r
393         PCCERT_CONTEXT pcc;\r
394         CERT_CHAIN_PARA ccp;\r
395         CERT_CHAIN_CONTEXT* pccc;\r
396         CERT_CHAIN_POLICY_PARA ccpp;\r
397         CERT_CHAIN_POLICY_STATUS ccps;\r
398         bResult = FALSE;\r
399         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
400         {\r
401                 pcc = NULL;\r
402                 while(!bResult && (pcc = CertEnumCertificatesInStore(hStore, pcc)))\r
403                 {\r
404                         ZeroMemory(&ccp, sizeof(CERT_CHAIN_PARA));\r
405                         ccp.cbSize = sizeof(CERT_CHAIN_PARA);\r
406                         if(CertGetCertificateChain(NULL, pcc, NULL, NULL, &ccp, 0, NULL, &pccc))\r
407                         {\r
408                                 ZeroMemory(&ccpp, sizeof(CERT_CHAIN_POLICY_PARA));\r
409                                 ccpp.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);\r
410                                 if(g_ProcessProtectionLevel & PROCESS_PROTECTION_EXPIRED)\r
411                                         ccpp.dwFlags |= CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG;\r
412                                 else if(g_ProcessProtectionLevel & PROCESS_PROTECTION_UNAUTHORIZED)\r
413                                         ccpp.dwFlags |= CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;\r
414                                 ZeroMemory(&ccps, sizeof(CERT_CHAIN_POLICY_STATUS));\r
415                                 ccps.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);\r
416                                 if(CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, pccc, &ccpp, &ccps))\r
417                                 {\r
418                                         if(ccps.dwError == ERROR_SUCCESS)\r
419                                         {\r
420                                                 bResult = TRUE;\r
421                                                 break;\r
422                                         }\r
423                                 }\r
424                                 CertFreeCertificateChain(pccc);\r
425                         }\r
426                 }\r
427                 while(pcc = CertEnumCertificatesInStore(hStore, pcc))\r
428                 {\r
429                 }\r
430                 CertCloseStore(hStore, 0);\r
431         }\r
432         return bResult;\r
433 }\r
434 \r
435 // ファイルの署名を確認\r
436 BOOL VerifyFileSignature(LPCWSTR Filename)\r
437 {\r
438         BOOL bResult;\r
439         GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;\r
440         WINTRUST_FILE_INFO wfi;\r
441         WINTRUST_DATA wd;\r
442         bResult = FALSE;\r
443         ZeroMemory(&wfi, sizeof(WINTRUST_FILE_INFO));\r
444         wfi.cbStruct = sizeof(WINTRUST_FILE_INFO);\r
445         wfi.pcwszFilePath = Filename;\r
446         ZeroMemory(&wd, sizeof(WINTRUST_DATA));\r
447         wd.cbStruct = sizeof(WINTRUST_DATA);\r
448         wd.dwUIChoice = WTD_UI_NONE;\r
449         wd.dwUnionChoice = WTD_CHOICE_FILE;\r
450         wd.pFile = &wfi;\r
451         if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS)\r
452                 bResult = TRUE;\r
453         else\r
454                 bResult = VerifyFileSignature_Function(Filename);\r
455         return bResult;\r
456 }\r
457 \r
458 // ファイルの署名をカタログファイルで確認\r
459 BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename)\r
460 {\r
461         BOOL bResult;\r
462         GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;\r
463         WINTRUST_CATALOG_INFO wci;\r
464         WINTRUST_DATA wd;\r
465         bResult = FALSE;\r
466         if(VerifyFileSignature(Catalog))\r
467         {\r
468                 ZeroMemory(&wci, sizeof(WINTRUST_CATALOG_INFO));\r
469                 wci.cbStruct = sizeof(WINTRUST_CATALOG_INFO);\r
470                 wci.pcwszCatalogFilePath = Catalog;\r
471                 wci.pcwszMemberFilePath = Filename;\r
472                 if((wci.hMemberFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
473                 {\r
474                         p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, NULL, 0);\r
475                         if(wci.pbCalculatedFileHash = (BYTE*)malloc(wci.cbCalculatedFileHash))\r
476                         {\r
477                                 if(p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, wci.pbCalculatedFileHash, 0))\r
478                                 {\r
479                                         ZeroMemory(&wd, sizeof(WINTRUST_DATA));\r
480                                         wd.cbStruct = sizeof(WINTRUST_DATA);\r
481                                         wd.dwUIChoice = WTD_UI_NONE;\r
482                                         wd.dwUnionChoice = WTD_CHOICE_CATALOG;\r
483                                         wd.pCatalog = &wci;\r
484                                         if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS)\r
485                                                 bResult = TRUE;\r
486                                 }\r
487                                 free(wci.pbCalculatedFileHash);\r
488                         }\r
489                         CloseHandle(wci.hMemberFile);\r
490                 }\r
491         }\r
492         return bResult;\r
493 }\r
494 \r
495 BOOL WINAPI GetSHA1HashOfModule_Function(DIGEST_HANDLE refdata, PBYTE pData, DWORD dwLength)\r
496 {\r
497         return CryptHashData(*(HCRYPTHASH*)refdata, pData, dwLength, 0);\r
498 }\r
499 \r
500 // モジュールのSHA1ハッシュを取得\r
501 // マニフェストファイルのfile要素のhash属性は実行可能ファイルの場合にImageGetDigestStreamで算出される\r
502 BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash)\r
503 {\r
504         BOOL bResult;\r
505         HCRYPTPROV hProv;\r
506         HCRYPTHASH hHash;\r
507         HANDLE hFile;\r
508         DWORD dw;\r
509         bResult = FALSE;\r
510         if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))\r
511         {\r
512                 if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))\r
513                 {\r
514                         if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
515                         {\r
516                                 if(ImageGetDigestStream(hFile, CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO, GetSHA1HashOfModule_Function, (DIGEST_HANDLE)&hHash))\r
517                                 {\r
518                                         dw = 20;\r
519                                         if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))\r
520                                                 bResult = TRUE;\r
521                                 }\r
522                                 CloseHandle(hFile);\r
523                         }\r
524                         CryptDestroyHash(hHash);\r
525                 }\r
526                 CryptReleaseContext(hProv, 0);\r
527         }\r
528         return bResult;\r
529 }\r
530 \r
531 BOOL IsSxsModuleTrusted_Function(LPCWSTR Catalog, LPCWSTR Manifest, LPCWSTR Module)\r
532 {\r
533         BOOL bResult;\r
534         HANDLE hLock0;\r
535         HANDLE hLock1;\r
536         BYTE Hash[20];\r
537         int i;\r
538         static char HexTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};\r
539         char HashHex[41];\r
540         HANDLE hFile;\r
541         DWORD Size;\r
542         char* pData;\r
543         DWORD dw;\r
544         bResult = FALSE;\r
545         if(hLock0 = LockExistingFile(Catalog))\r
546         {\r
547                 if(hLock1 = LockExistingFile(Manifest))\r
548                 {\r
549                         if(VerifyFileSignatureInCatalog(Catalog, Manifest))\r
550                         {\r
551                                 if(GetSHA1HashOfModule(Module, &Hash))\r
552                                 {\r
553                                         for(i = 0; i < 20; i++)\r
554                                         {\r
555                                                 HashHex[i * 2] = HexTable[(Hash[i] >> 4) & 0x0f];\r
556                                                 HashHex[i * 2 + 1] = HexTable[Hash[i] & 0x0f];\r
557                                         }\r
558                                         HashHex[i * 2] = '\0';\r
559                                         if((hFile = CreateFileW(Manifest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
560                                         {\r
561                                                 Size = GetFileSize(hFile, NULL);\r
562                                                 if(pData = (char*)VirtualAlloc(NULL, Size + 1, MEM_COMMIT, PAGE_READWRITE))\r
563                                                 {\r
564                                                         VirtualLock(pData, Size + 1);\r
565                                                         if(ReadFile(hFile, pData, Size, &dw, NULL))\r
566                                                         {\r
567                                                                 pData[dw] = '\0';\r
568                                                                 if(strstr(pData, HashHex))\r
569                                                                         bResult = TRUE;\r
570                                                         }\r
571                                                         VirtualUnlock(pData, Size + 1);\r
572                                                         VirtualFree(pData, Size + 1, MEM_DECOMMIT);\r
573                                                 }\r
574                                                 CloseHandle(hFile);\r
575                                         }\r
576                                 }\r
577                         }\r
578                         CloseHandle(hLock1);\r
579                 }\r
580                 CloseHandle(hLock0);\r
581         }\r
582         return bResult;\r
583 }\r
584 \r
585 // サイドバイサイドDLLを確認\r
586 // パスは"%SystemRoot%\WinSxS"以下を想定\r
587 // 以下のファイルが存在するものとする\r
588 // "\xxx\yyy.dll"、"\manifests\xxx.cat"、"\manifests\xxx.manifest"のセット(XPの全てのDLL、Vista以降の一部のDLL)\r
589 // "\xxx\yyy.dll"、"\catalogs\zzz.cat"、"\manifests\xxx.manifest"のセット(Vista以降のほとんどのDLL)\r
590 // 署名されたカタログファイルを用いてマニフェストファイルが改竄されていないことを確認\r
591 // ハッシュ値は   マニフェストファイルのfile要素のhash属性に記述されているものを用いる\r
592 // マニフェストファイル内にSHA1ハッシュ値の16進数表記を直接検索しているが確率的に問題なし\r
593 BOOL IsSxsModuleTrusted(LPCWSTR Filename)\r
594 {\r
595         BOOL bResult;\r
596         wchar_t* pw0;\r
597         wchar_t* pw1;\r
598         wchar_t* pw2;\r
599         wchar_t* pw3;\r
600         wchar_t* pw4;\r
601         wchar_t* pw5;\r
602         wchar_t* p;\r
603         HANDLE hFind;\r
604         WIN32_FIND_DATAW wfd;\r
605         bResult = FALSE;\r
606         if(pw0 = AllocateStringW(wcslen(Filename) + 1))\r
607         {\r
608                 wcscpy(pw0, Filename);\r
609                 if(p = wcsrchr(pw0, L'\\'))\r
610                 {\r
611                         wcscpy(p, L"");\r
612                         if(p = wcsrchr(pw0, L'\\'))\r
613                         {\r
614                                 p++;\r
615                                 if(pw1 = AllocateStringW(wcslen(p) + 1))\r
616                                 {\r
617                                         wcscpy(pw1, p);\r
618                                         wcscpy(p, L"");\r
619                                         if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".cat") + 1))\r
620                                         {\r
621                                                 wcscpy(pw2, pw0);\r
622                                                 wcscat(pw2, L"manifests\\");\r
623                                                 wcscat(pw2, pw1);\r
624                                                 if(pw3 = AllocateStringW(wcslen(pw2) + wcslen(L".manifest") + 1))\r
625                                                 {\r
626                                                         wcscpy(pw3, pw2);\r
627                                                         wcscat(pw3, L".manifest");\r
628                                                         wcscat(pw2, L".cat");\r
629                                                         if(IsSxsModuleTrusted_Function(pw2, pw3, Filename))\r
630                                                                 bResult = TRUE;\r
631                                                         FreeDuplicatedString(pw3);\r
632                                                 }\r
633                                                 FreeDuplicatedString(pw2);\r
634                                         }\r
635                                         if(!bResult)\r
636                                         {\r
637                                                 if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"catalogs\\") + 1))\r
638                                                 {\r
639                                                         if(pw3 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".manifest") + 1))\r
640                                                         {\r
641                                                                 wcscpy(pw2, pw0);\r
642                                                                 wcscat(pw2, L"catalogs\\");\r
643                                                                 wcscpy(pw3, pw0);\r
644                                                                 wcscat(pw3, L"manifests\\");\r
645                                                                 wcscat(pw3, pw1);\r
646                                                                 wcscat(pw3, L".manifest");\r
647                                                                 if(pw4 = AllocateStringW(wcslen(pw2) + wcslen(L"*.cat") + 1))\r
648                                                                 {\r
649                                                                         wcscpy(pw4, pw2);\r
650                                                                         wcscat(pw4, L"*.cat");\r
651                                                                         if((hFind = FindFirstFileW(pw4, &wfd)) != INVALID_HANDLE_VALUE)\r
652                                                                         {\r
653                                                                                 do\r
654                                                                                 {\r
655                                                                                         if(pw5 = AllocateStringW(wcslen(pw2) + wcslen(wfd.cFileName) + 1))\r
656                                                                                         {\r
657                                                                                                 wcscpy(pw5, pw2);\r
658                                                                                                 wcscat(pw5, wfd.cFileName);\r
659                                                                                                 if(IsSxsModuleTrusted_Function(pw5, pw3, Filename))\r
660                                                                                                         bResult = TRUE;\r
661                                                                                                 FreeDuplicatedString(pw5);\r
662                                                                                         }\r
663                                                                                 }\r
664                                                                                 while(!bResult && FindNextFileW(hFind, &wfd));\r
665                                                                                 FindClose(hFind);\r
666                                                                         }\r
667                                                                         FreeDuplicatedString(pw4);\r
668                                                                 }\r
669                                                                 FreeDuplicatedString(pw3);\r
670                                                         }\r
671                                                         FreeDuplicatedString(pw2);\r
672                                                 }\r
673                                         }\r
674                                         FreeDuplicatedString(pw1);\r
675                                 }\r
676                         }\r
677                 }\r
678                 FreeDuplicatedString(pw0);\r
679         }\r
680         return bResult;\r
681 }\r
682 \r
683 // DLLを確認\r
684 BOOL IsModuleTrusted(LPCWSTR Filename)\r
685 {\r
686         BOOL bResult;\r
687         BYTE Hash[20];\r
688         bResult = FALSE;\r
689         if(LockThreadLock())\r
690         {\r
691                 if(GetSHA1HashOfFile(Filename, &Hash))\r
692                 {\r
693                         if(FindTrustedModuleSHA1Hash(&Hash))\r
694                                 bResult = TRUE;\r
695                 }\r
696                 if(!bResult)\r
697                 {\r
698                         if((g_ProcessProtectionLevel & PROCESS_PROTECTION_BUILTIN) && VerifyFileSignature(Filename))\r
699                                 bResult = TRUE;\r
700                 }\r
701                 if(!bResult)\r
702                 {\r
703                         if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SIDE_BY_SIDE) && IsSxsModuleTrusted(Filename))\r
704                                 bResult = TRUE;\r
705                 }\r
706                 if(!bResult)\r
707                 {\r
708                         if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SYSTEM_FILE) && SfcIsFileProtected(NULL, Filename))\r
709                                 bResult = TRUE;\r
710                 }\r
711                 UnlockThreadLock();\r
712         }\r
713         return bResult;\r
714 }\r
715 \r
716 // kernel32.dllのLoadLibraryExW相当の関数\r
717 // ドキュメントが無いため詳細は不明\r
718 // 一部のウィルス対策ソフト(Avast!等)がLdrLoadDllをフックしているためLdrLoadDllを書き換えるべきではない\r
719 // カーネルモードのコードに対しては効果なし\r
720 // SeDebugPrivilegeが使用可能なユーザーに対しては効果なし\r
721 HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
722 {\r
723         HMODULE r = NULL;\r
724         UNICODE_STRING us;\r
725         HANDLE hDataFile;\r
726         HANDLE hMapping;\r
727         DWORD DllFlags;\r
728         us.Length = sizeof(wchar_t) * wcslen(lpLibFileName);\r
729         us.MaximumLength = sizeof(wchar_t) * (wcslen(lpLibFileName) + 1);\r
730         us.Buffer = (PWSTR)lpLibFileName;\r
731 //      if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))\r
732         if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040))\r
733         {\r
734 //              if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == STATUS_SUCCESS)\r
735                 if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == 0)\r
736                 {\r
737 //                      dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);\r
738                         dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040);\r
739                         dwFlags |= DONT_RESOLVE_DLL_REFERENCES;\r
740                 }\r
741                 else\r
742                 {\r
743 //                      if(dwFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)\r
744                         if(dwFlags & 0x00000040)\r
745                                 hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\r
746                         else\r
747                                 hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);\r
748                         if(hDataFile != INVALID_HANDLE_VALUE)\r
749                         {\r
750                                 if(hMapping = CreateFileMappingW(hDataFile, NULL, PAGE_READONLY, 0, 0, NULL))\r
751                                 {\r
752                                         if(r = (HMODULE)MapViewOfFileEx(hMapping, FILE_MAP_READ, 0, 0, 0, NULL))\r
753                                         {\r
754                                                 if(p_RtlImageNtHeader(r))\r
755                                                         r = (HMODULE)((size_t)r | 1);\r
756                                                 else\r
757                                                 {\r
758                                                         UnmapViewOfFile(r);\r
759                                                         r = NULL;\r
760                                                 }\r
761                                         }\r
762                                         CloseHandle(hMapping);\r
763                                 }\r
764                                 CloseHandle(hDataFile);\r
765                         }\r
766                         else\r
767                         {\r
768 //                              dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);\r
769                                 dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040);\r
770                                 dwFlags |= DONT_RESOLVE_DLL_REFERENCES;\r
771                         }\r
772                 }\r
773         }\r
774 //      if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)))\r
775         if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040)))\r
776         {\r
777                 DllFlags = 0;\r
778 //              if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_IMAGE_RESOURCE))\r
779                 if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | 0x00000020))\r
780                         DllFlags |= 0x00000002;\r
781 //              if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == STATUS_SUCCESS)\r
782                 if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == 0)\r
783                 {\r
784                 }\r
785                 else\r
786                         r = NULL;\r
787         }\r
788         return r;\r
789 }\r
790 \r
791 void SetProcessProtectionLevel(DWORD Level)\r
792 {\r
793         g_ProcessProtectionLevel = Level;\r
794 }\r
795 \r
796 // ファイルのSHA1ハッシュを取得\r
797 BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash)\r
798 {\r
799         BOOL bResult;\r
800         HCRYPTPROV hProv;\r
801         HCRYPTHASH hHash;\r
802         HANDLE hFile;\r
803         DWORD Size;\r
804         void* pData;\r
805         DWORD dw;\r
806         bResult = FALSE;\r
807         if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))\r
808         {\r
809                 if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))\r
810                 {\r
811                         if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
812                         {\r
813                                 Size = GetFileSize(hFile, NULL);\r
814                                 if(pData = VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE))\r
815                                 {\r
816                                         VirtualLock(pData, Size);\r
817                                         if(ReadFile(hFile, pData, Size, &dw, NULL))\r
818                                         {\r
819                                                 if(CryptHashData(hHash, (BYTE*)pData, Size, 0))\r
820                                                 {\r
821                                                         dw = 20;\r
822                                                         if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))\r
823                                                                 bResult = TRUE;\r
824                                                 }\r
825                                         }\r
826                                         VirtualUnlock(pData, Size);\r
827                                         VirtualFree(pData, Size, MEM_DECOMMIT);\r
828                                 }\r
829                                 CloseHandle(hFile);\r
830                         }\r
831                         CryptDestroyHash(hHash);\r
832                 }\r
833                 CryptReleaseContext(hProv, 0);\r
834         }\r
835         return bResult;\r
836 }\r
837 \r
838 // DLLのハッシュを登録\r
839 BOOL RegisterTrustedModuleSHA1Hash(void* pHash)\r
840 {\r
841         BOOL bResult;\r
842         BYTE NullHash[20] = {0};\r
843         int i;\r
844         bResult = FALSE;\r
845         if(FindTrustedModuleSHA1Hash(pHash))\r
846                 bResult = TRUE;\r
847         else\r
848         {\r
849                 i = 0;\r
850                 while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
851                 {\r
852                         if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 20) == 0)\r
853                         {\r
854                                 memcpy(&g_TrustedMD5HashTable[i], pHash, 20);\r
855                                 bResult = TRUE;\r
856                                 break;\r
857                         }\r
858                         i++;\r
859                 }\r
860         }\r
861         return bResult;\r
862 }\r
863 \r
864 // DLLのハッシュの登録を解除\r
865 BOOL UnregisterTrustedModuleSHA1Hash(void* pHash)\r
866 {\r
867         BOOL bResult;\r
868         BYTE NullHash[20] = {0};\r
869         int i;\r
870         bResult = FALSE;\r
871         i = 0;\r
872         while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
873         {\r
874                 if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0)\r
875                 {\r
876                         memcpy(&g_TrustedMD5HashTable[i], &NullHash, 20);\r
877                         bResult = TRUE;\r
878                         break;\r
879                 }\r
880                 i++;\r
881         }\r
882         return bResult;\r
883 }\r
884 \r
885 // 信頼できないDLLをアンロード\r
886 BOOL UnloadUntrustedModule()\r
887 {\r
888         BOOL bResult;\r
889         wchar_t* pw0;\r
890         HANDLE hSnapshot;\r
891         MODULEENTRY32 me;\r
892         DWORD Length;\r
893         bResult = FALSE;\r
894         pw0 = NULL;\r
895         if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE)\r
896         {\r
897                 bResult = TRUE;\r
898                 me.dwSize = sizeof(MODULEENTRY32);\r
899                 if(Module32First(hSnapshot, &me))\r
900                 {\r
901                         do\r
902                         {\r
903                                 Length = MAX_PATH;\r
904                                 FreeDuplicatedString(pw0);\r
905                                 if(pw0 = AllocateStringW(Length))\r
906                                 {\r
907                                         if(GetModuleFileNameW(me.hModule, pw0, Length) > 0)\r
908                                         {\r
909                                                 while(pw0)\r
910                                                 {\r
911                                                         if(GetModuleFileNameW(me.hModule, pw0, Length) + 1 <= Length)\r
912                                                                 break;\r
913                                                         Length = Length * 2;\r
914                                                         FreeDuplicatedString(pw0);\r
915                                                         pw0 = AllocateStringW(Length);\r
916                                                 }\r
917                                         }\r
918                                 }\r
919                                 if(pw0)\r
920                                 {\r
921                                         if(!IsModuleTrusted(pw0))\r
922                                         {\r
923                                                 if(me.hModule != GetModuleHandleW(NULL))\r
924                                                 {\r
925                                                         while(FreeLibrary(me.hModule))\r
926                                                         {\r
927                                                         }\r
928                                                         if(GetModuleFileNameW(me.hModule, pw0, Length) > 0)\r
929                                                         {\r
930                                                                 bResult = FALSE;\r
931                                                                 break;\r
932                                                         }\r
933                                                 }\r
934                                         }\r
935                                 }\r
936                                 else\r
937                                 {\r
938                                         bResult = FALSE;\r
939                                         break;\r
940                                 }\r
941                         }\r
942                         while(Module32Next(hSnapshot, &me));\r
943                 }\r
944                 CloseHandle(hSnapshot);\r
945         }\r
946         FreeDuplicatedString(pw0);\r
947         return bResult;\r
948 }\r
949 \r
950 // 関数ポインタを使用可能な状態に初期化\r
951 BOOL InitializeLoadLibraryHook()\r
952 {\r
953         BOOL bResult;\r
954         HMODULE hModule;\r
955         bResult = TRUE;\r
956         if(!(hModule = GetModuleHandleW(L"kernel32.dll")))\r
957                 bResult = FALSE;\r
958         if(!(GET_FUNCTION(hModule, LoadLibraryA)))\r
959                 bResult = FALSE;\r
960         if(!(GET_FUNCTION(hModule, LoadLibraryW)))\r
961                 bResult = FALSE;\r
962         if(!(GET_FUNCTION(hModule, LoadLibraryExA)))\r
963                 bResult = FALSE;\r
964         if(!(GET_FUNCTION(hModule, LoadLibraryExW)))\r
965                 bResult = FALSE;\r
966         if(!(hModule = GetModuleHandleW(L"ntdll.dll")))\r
967                 bResult = FALSE;\r
968         if(!(GET_FUNCTION(hModule, LdrLoadDll)))\r
969                 bResult = FALSE;\r
970         if(!(GET_FUNCTION(hModule, LdrGetDllHandle)))\r
971                 bResult = FALSE;\r
972         if(!(GET_FUNCTION(hModule, RtlImageNtHeader)))\r
973                 bResult = FALSE;\r
974         if(!(hModule = LoadLibraryW(L"wintrust.dll")))\r
975                 bResult = FALSE;\r
976         if(!(GET_FUNCTION(hModule, CryptCATAdminCalcHashFromFileHandle)))\r
977                 bResult = FALSE;\r
978         return bResult;\r
979 }\r
980 \r
981 // SetWindowsHookEx対策\r
982 // DLL Injectionされた場合は上のh_LoadLibrary系関数でトラップ可能\r
983 BOOL EnableLoadLibraryHook(BOOL bEnable)\r
984 {\r
985         BOOL bResult;\r
986         bResult = FALSE;\r
987         if(bEnable)\r
988         {\r
989                 bResult = TRUE;\r
990 #ifdef USE_CODE_HOOK\r
991                 if(!SET_HOOK_FUNCTION(LoadLibraryA))\r
992                         bResult = FALSE;\r
993                 if(!SET_HOOK_FUNCTION(LoadLibraryW))\r
994                         bResult = FALSE;\r
995                 if(!SET_HOOK_FUNCTION(LoadLibraryExA))\r
996                         bResult = FALSE;\r
997                 if(!SET_HOOK_FUNCTION(LoadLibraryExW))\r
998                         bResult = FALSE;\r
999 #endif\r
1000 #ifdef USE_IAT_HOOK\r
1001                 if(!HookFunctionInIAT(p_LoadLibraryA, h_LoadLibraryA))\r
1002                         bResult = FALSE;\r
1003                 if(!HookFunctionInIAT(p_LoadLibraryW, h_LoadLibraryW))\r
1004                         bResult = FALSE;\r
1005                 if(!HookFunctionInIAT(p_LoadLibraryExA, h_LoadLibraryExA))\r
1006                         bResult = FALSE;\r
1007                 if(!HookFunctionInIAT(p_LoadLibraryExW, h_LoadLibraryExW))\r
1008                         bResult = FALSE;\r
1009 #endif\r
1010         }\r
1011         else\r
1012         {\r
1013                 bResult = TRUE;\r
1014 #ifdef USE_CODE_HOOK\r
1015                 if(!END_HOOK_FUNCTION(LoadLibraryA))\r
1016                         bResult = FALSE;\r
1017                 if(!END_HOOK_FUNCTION(LoadLibraryW))\r
1018                         bResult = FALSE;\r
1019                 if(!END_HOOK_FUNCTION(LoadLibraryExA))\r
1020                         bResult = FALSE;\r
1021                 if(!END_HOOK_FUNCTION(LoadLibraryExW))\r
1022                         bResult = FALSE;\r
1023 #endif\r
1024 #ifdef USE_IAT_HOOK\r
1025                 if(!HookFunctionInIAT(h_LoadLibraryA, p_LoadLibraryA))\r
1026                         bResult = FALSE;\r
1027                 if(!HookFunctionInIAT(h_LoadLibraryW, p_LoadLibraryW))\r
1028                         bResult = FALSE;\r
1029                 if(!HookFunctionInIAT(h_LoadLibraryExA, p_LoadLibraryExA))\r
1030                         bResult = FALSE;\r
1031                 if(!HookFunctionInIAT(h_LoadLibraryExW, p_LoadLibraryExW))\r
1032                         bResult = FALSE;\r
1033 #endif\r
1034         }\r
1035         return bResult;\r
1036 }\r
1037 \r
1038 // ReadProcessMemory、WriteProcessMemory、CreateRemoteThread対策\r
1039 // TerminateProcessのみ許可\r
1040 BOOL RestartProtectedProcess(LPCTSTR Keyword)\r
1041 {\r
1042         BOOL bResult;\r
1043         ACL* pACL;\r
1044         SID_IDENTIFIER_AUTHORITY sia = SECURITY_WORLD_SID_AUTHORITY;\r
1045         PSID pSID;\r
1046         SECURITY_DESCRIPTOR sd;\r
1047         TCHAR* CommandLine;\r
1048         SECURITY_ATTRIBUTES sa;\r
1049         STARTUPINFO si;\r
1050         PROCESS_INFORMATION pi;\r
1051         bResult = FALSE;\r
1052         if(_tcslen(GetCommandLine()) >= _tcslen(Keyword) && _tcscmp(GetCommandLine() + _tcslen(GetCommandLine()) - _tcslen(Keyword), Keyword) == 0)\r
1053                 return FALSE;\r
1054         if(pACL = (ACL*)malloc(sizeof(ACL) + 1024))\r
1055         {\r
1056                 if(InitializeAcl(pACL, sizeof(ACL) + 1024, ACL_REVISION))\r
1057                 {\r
1058                         if(AllocateAndInitializeSid(&sia, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSID))\r
1059                         {\r
1060                                 if(AddAccessAllowedAce(pACL, ACL_REVISION, PROCESS_TERMINATE, pSID))\r
1061                                 {\r
1062                                         if(InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))\r
1063                                         {\r
1064                                                 if(SetSecurityDescriptorDacl(&sd, TRUE, pACL, FALSE))\r
1065                                                 {\r
1066                                                         if(CommandLine = (TCHAR*)malloc(sizeof(TCHAR) * (_tcslen(GetCommandLine()) + _tcslen(Keyword) + 1)))\r
1067                                                         {\r
1068                                                                 _tcscpy(CommandLine, GetCommandLine());\r
1069                                                                 _tcscat(CommandLine, Keyword);\r
1070                                                                 sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
1071                                                                 sa.lpSecurityDescriptor = &sd;\r
1072                                                                 sa.bInheritHandle = FALSE;\r
1073                                                                 GetStartupInfo(&si);\r
1074                                                                 if(CreateProcess(NULL, CommandLine, &sa, NULL, FALSE, 0, NULL, NULL, &si, &pi))\r
1075                                                                 {\r
1076                                                                         CloseHandle(pi.hThread);\r
1077                                                                         CloseHandle(pi.hProcess);\r
1078                                                                         bResult = TRUE;\r
1079                                                                 }\r
1080                                                                 free(CommandLine);\r
1081                                                         }\r
1082                                                 }\r
1083                                         }\r
1084                                 }\r
1085                                 FreeSid(pSID);\r
1086                         }\r
1087                 }\r
1088                 free(pACL);\r
1089         }\r
1090         return bResult;\r
1091 }\r
1092 \r
1093 INT_PTR CALLBACK PasswordEditControlWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
1094 {\r
1095         switch(Msg)\r
1096         {\r
1097         case EM_GETPASSWORDCHAR:\r
1098                 break;\r
1099         case EM_SETPASSWORDCHAR:\r
1100                 break;\r
1101         default:\r
1102                 return CallWindowProcW(g_PasswordEditControlProc, hWnd, Msg, wParam, lParam);\r
1103         }\r
1104         return 0;\r
1105 }\r
1106 \r
1107 BOOL ProtectPasswordEditControl(HWND hWnd)\r
1108 {\r
1109         BOOL bResult;\r
1110         WCHAR ClassName[MAX_PATH];\r
1111         WNDPROC Proc;\r
1112         bResult = FALSE;\r
1113         if(g_ProcessProtectionLevel & PROCESS_PROTECTION_PASSWORD_EDIT)\r
1114         {\r
1115                 if(GetClassNameW(hWnd, ClassName, MAX_PATH) > 0)\r
1116                 {\r
1117                         if(_wcsicmp(ClassName, WC_EDITW) == 0)\r
1118                         {\r
1119                                 Proc = (WNDPROC)GetWindowLongPtrW(hWnd, GWLP_WNDPROC);\r
1120                                 if(Proc != (WNDPROC)PasswordEditControlWndProc)\r
1121                                 {\r
1122                                         g_PasswordEditControlProc = Proc;\r
1123                                         SetWindowLongPtrW(hWnd, GWLP_WNDPROC, (LONG_PTR)PasswordEditControlWndProc);\r
1124                                         bResult = TRUE;\r
1125                                 }\r
1126                         }\r
1127                 }\r
1128         }\r
1129         return bResult;\r
1130 }\r
1131 \r
1132 BOOL CALLBACK ProtectAllEditControlsEnumChildProc(HWND hwnd , LPARAM lParam)\r
1133 {\r
1134         ProtectPasswordEditControl(hwnd);\r
1135         return TRUE;\r
1136 }\r
1137 \r
1138 BOOL ProtectAllEditControls(HWND hWnd)\r
1139 {\r
1140         if(g_ProcessProtectionLevel & PROCESS_PROTECTION_PASSWORD_EDIT)\r
1141                 EnumChildWindows(hWnd, ProtectAllEditControlsEnumChildProc, 0);\r
1142         return TRUE;\r
1143 }\r
1144 \r