AntiPlug

反插件工程

  1 #pragma once
  2 
  3 #ifndef __ENHANFUNC_H__
  4 #define __ENHANFUNC_H__
  5 
  6 #include <iostream>
  7 #include <string>
  8 #include <windows.h>
  9 #include <psapi.h>
 10 #include <tlhelp32.h>
 11 #include "CApiHook.h"
 12 using namespace std;
 13 
 14 #pragma region 预编译指令
 15 
 16 //    引用静态连接库
 17 #pragma comment(lib,"psapi.lib")
 18 #pragma comment(lib,"version.lib")
 19 
 20 //    关闭非法数组访问部分的编译警告
 21 #pragma warning(disable: 4146)
 22 #pragma warning(disable: 4838)
 23 
 24 //    关闭string函数的不安全的编译警告
 25 #pragma warning(disable: 4996)
 26 
 27 //    关闭有无符号不匹配的编译警告
 28 #pragma warning(disable: 4018)
 29 
 30 #pragma endregion
 31 
 32 #pragma region 结构体
 33 
 34 typedef struct UNICODE_STRING
 35 {
 36     USHORT Length;
 37     USHORT MaximumLength;
 38     PWSTR  Buffer;
 39 } *PUNICODE_STRING;
 40 
 41 struct LANGANDCODEPAGE
 42 {
 43     WORD wLanguage;
 44     WORD wCodePage;
 45 };
 46 
 47 #pragma endregion
 48 
 49 #pragma region 函数原型
 50 
 51 //    LdrLoadDll
 52 typedef NTSTATUS(WINAPI *pLdrLoadDll)
 53 (
 54     IN    PWCHAR            PathToFile        OPTIONAL,
 55     IN    ULONG            Flags            OPTIONAL,
 56     IN    PUNICODE_STRING    ModuleFileName,
 57     OUT    PHANDLE            ModuleHandle
 58 );
 59 
 60 //    RtlInitUnicodeString
 61 typedef VOID(WINAPI *pRtlInitUnicodeString)
 62 (
 63     PUNICODE_STRING    DestinationString,
 64     PCWSTR            SourceString
 65 );
 66 
 67 #pragma endregion
 68 
 69 #pragma region 全局变量
 70 
 71 extern BOOL bShowError;    //    错误信息框是否在显示
 72 
 73 extern HMODULE hNtdll;    //    Ntdll.dll模块句柄
 74 extern pLdrLoadDll _LdrLoadDll;    //    LdrLoadDll函数地址
 75 extern pRtlInitUnicodeString RtlInitUnicodeString;    //RtlInitUnicodeString函数地址
 76 
 77 extern CHAR szNtdllPath[MAX_PATH];    //    Ntdll.dll文件路径
 78 extern CHAR szWindir[MAX_PATH], szWindir64[MAX_PATH];    //    系统目录, 64位系统目录
 79 extern CHAR szMSCompanyName[MAX_PATH], szMSLegalCopyright[MAX_PATH];    //    微软公司名称, 微软版权信息
 80 
 81 extern CApiHook HookLdrLoadDll;    //    LdrLoadDll钩子
 82 
 83 #pragma endregion
 84 
 85 #pragma region 错误提示宏
 86 
 87 //
 88 
 89 #pragma endregion
 90 
 91 #pragma region 函数声明
 92 
 93 void TmntCrtPrcs();    //    结束当前进程
 94 void TmntCrtPrcsTimeOut();    //    延时结束当前进程
 95 void ErrorMessageBox(LPCSTR lpText);    //    显示错误提示框并结束自身
 96 
 97 BOOL EnablePrivileges(LPCSTR lpPrivilegeName, BOOL bEnabled);    //    打开进程权限
 98 BOOL GetFileVerInfo(LPCSTR lpFileName, LPCSTR lpType, LPSTR lpBuf);    //    获取文件信息
 99 BOOL DevicePathToWinPath(LPCSTR lpDeviceFileName, LPSTR lpBuf);    //    设备路径转为逻辑路径
100 BOOL IsMicrosoftFile(LPCSTR lpFileName);    //    文件是否属于微软
101 BOOL IsExistWindir(LPCSTR lpFileName);        //    文件是否存在系统目录
102 BOOL GetPrcsFilePath(DWORD dwPid, LPSTR lpBuf);    //    获取目标进程的文件路径
103 BOOL GetApiHookStatus(LPCSTR lpModuleName, LPCSTR lpProcName);    //    获取目标函数的钩子状态
104 
105 void InitInfo();    //    初始化信息
106 void CheckParent();    //    检测父进程
107 
108 //    Hook LdrLoadDll指向的函数
109 NTSTATUS WINAPI NewLdrLoadDll(PWCHAR PathToFile, ULONG Flags, PUNICODE_STRING ModuleFileName, PHANDLE ModuleHandle);
110 HMODULE MyLdrLoadDll(LPCSTR lpFileName);    //    LdrLoadDll的封装调用
111 BOOL InitAntiInject();    //    初始化反注入
112 
113 void CheckDllModule();    //    检测DLL模块
114 void Check();        //    检测
115 
116 #pragma endregion
117 
118 #endif    //    __ENHANFUNC_H__
EnhanFunc.h
  1 #include "EnhanFunc.h"
  2 
  3 #pragma region 全局变量
  4 
  5 BOOL bShowError;    //    错误信息框是否在显示
  6 
  7 HMODULE hNtdll = NULL;    //    Ntdll.dll模块句柄
  8 pLdrLoadDll LdrLoadDll = NULL;    //    LdrLoadDll函数地址
  9 pRtlInitUnicodeString RtlInitUnicodeString = NULL;    //RtlInitUnicodeString函数地址
 10 
 11 CHAR szNtdllPath[MAX_PATH] = "";    //    Ntdll.dll文件路径
 12 CHAR szWindir[MAX_PATH] = "", szWindir64[MAX_PATH] = "";    //    系统目录, 64位系统目录
 13 CHAR szMSCompanyName[MAX_PATH] = "", szMSLegalCopyright[MAX_PATH] = "";    //    微软公司名称, 微软版权信息
 14 
 15 CApiHook HookLdrLoadDll;    //    LdrLoadDll钩子
 16 
 17 #pragma endregion
 18 
 19 //    结束当前进程
 20 void TmntCrtPrcs()
 21 {
 22     while (true)
 23     {
 24         //    API结束进程
 25         TerminateProcess(GetCurrentProcess(), NULL);
 26     
 27         //    清空模块内存
 28         HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, NULL);    //    创建当前进程模块信息快照
 29         if (hSnapshot != INVALID_HANDLE_VALUE)
 30         {
 31             MODULEENTRY32 me32 = {};
 32             me32.dwSize = sizeof(me32);
 33 
 34             //    枚举模块信息
 35             BOOL ret = Module32First(hSnapshot, &me32);
 36             while (ret)
 37             {
 38                 //    修改模块基地址的保护属性
 39                 DWORD dwOldProtect = NULL;
 40                 VirtualProtectEx(GetCurrentProcess(), me32.modBaseAddr, me32.modBaseSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
 41 
 42                 //    将空白缓冲区写入到模块基地址
 43                 LPVOID lpBuffer = new byte[me32.modBaseSize];
 44                 WriteProcessMemory(GetCurrentProcess(), me32.modBaseAddr, lpBuffer, me32.modBaseSize, NULL);
 45 
 46                 ret = Module32Next(hSnapshot, &me32);
 47             }
 48         }
 49 
 50         //    创建并访问非法的数组
 51         int arraySize[MAX_LANA] = { -1, -1024, -65536, -2147483648, 2147483647 };    //    非法的数组大小
 52         for (int i = 0; i < MAX_LANA; i++)
 53         {
 54             //    创建非法数组
 55             int *arr = new int[arraySize[i]];
 56 
 57             //    访问非法数组
 58             for (int j = 0; j < MAX_LANA; j++)
 59                 arr[arraySize[i]] = arraySize[i] / (int)(1 / arraySize[i]);
 60         }
 61     }
 62 }
 63 
 64 //    延时结束当前进程
 65 void TmntCrtPrcsTimeOut()
 66 {
 67     //    延时以给消息框显示时间
 68     Sleep(2000);
 69 
 70     //    循环结束当前进程
 71     while (true)
 72         TmntCrtPrcs();
 73 }
 74 
 75 //    显示错误提示框并结束自身
 76 void ErrorMessageBox(LPCSTR lpText)
 77 {
 78     //    创建结束自身进程的线程
 79     for (int i = 0; i < MAX_LANA; i++)
 80         CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TmntCrtPrcsTimeOut, NULL, 0, NULL);
 81 
 82     //    显示错误信息
 83     if (bShowError)    //    如果有错误信息框正在显示则等待
 84         Sleep(2000);
 85     else
 86     {    //    如果没有错误信息框正在显示则显示并标记
 87         bShowError = true;
 88         HookLdrLoadDll.Suspend();    //    防止崩溃
 89         MessageBoxA(NULL, lpText, "错误", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
 90         HookLdrLoadDll.Resume();
 91     }        
 92 
 93     //    循环结束自身进程
 94     while (true)
 95         TmntCrtPrcs();
 96 }
 97 
 98 //    打开进程权限
 99 BOOL EnablePrivileges(LPCSTR lpPrivilegeName, BOOL bEnabled)
100 {
101     /*
102     lpPrivilegeName        目标权限名称
103 
104     SeDebugPrivilege    调试权限
105     */
106 
107     //    打开进程令牌
108     HANDLE hToken;
109     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
110         return FALSE;
111 
112     //    查询目标权限的令牌值
113     LUID luid = {};
114     if (!LookupPrivilegeValueA(NULL, lpPrivilegeName, &luid))
115         return FALSE;
116 
117     //    打开目标权限
118     TOKEN_PRIVILEGES tp = {};
119     tp.PrivilegeCount = 1;
120     tp.Privileges[0].Luid = luid;
121     tp.Privileges[0].Attributes = bEnabled ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;
122     if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL))
123         return FALSE;
124 
125     CloseHandle(hToken);
126     return TRUE;
127 }
128 
129 //    获取文件信息
130 BOOL GetFileVerInfo(LPCSTR lpFileName, LPCSTR lpType, LPSTR lpBuf)
131 {
132     /*
133     lpType 目标信息类型 可以为以下值:
134 
135     Comments            评论
136     InternalName        内部名称
137     ProductName            产品名称
138     CompanyName            公司名称
139     LegalCopyright        法律版权
140     ProductVersion        产品版本
141     FileDescription        文件描述
142     LegalTrademarks        法律商标
143     PrivateBuild        私有构建
144     FileVersion            文件版本
145     OriginalFilename    原始文件名
146     SpecialBuild        特别构建
147     */
148 
149     //    获取缓冲区大小
150     DWORD dwSize = GetFileVersionInfoSizeA(lpFileName, NULL);
151     if (dwSize == 0)
152         return FALSE;
153 
154     //    获取缓冲区信息
155     LPSTR lpData = new CHAR[dwSize + 1];
156     if (!GetFileVersionInfoA(lpFileName, NULL, dwSize + 1, (LPVOID)lpData))
157         return FALSE;
158 
159     //    获取语言编码
160     UINT cbTranslate = NULL;
161     LANGANDCODEPAGE *lpTranslate = NULL;
162     if (!VerQueryValueA(lpData, "\VarFileInfo\Translation", (LPVOID *)&lpTranslate, &cbTranslate))
163         return FALSE;
164 
165     //    构造获取目标信息的格式参数
166     CHAR szSubBlock[MAX_LANA] = "";
167     CHAR szFormat[MAX_LANA] = "\StringFileInfo\%04x%04x\";
168     strcat(szFormat, lpType);
169     sprintf(szSubBlock, szFormat, lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);
170 
171     //    查询目标信息
172     LPSTR lplpBuf = new CHAR[MAX_LANA];
173     if (!VerQueryValueA(lpData, szSubBlock, (LPVOID *)&lplpBuf, NULL))
174         return FALSE;
175 
176     strcpy(lpBuf, lplpBuf);
177 
178     //    如果目标为版权信息
179     if (strcmp(lpType, "LegalCopyright") == 0)
180     {
181         //    修正版权信息里的特殊符号
182         for (int i = 0; i < strlen(lplpBuf); i++)
183             if (lplpBuf[i] == 'M')    //    Microsoft Corporation. All rights reserved.
184             {
185                 strcpy(lpBuf, &lplpBuf[i]);
186                 break;
187             }
188     }
189 
190     return TRUE;
191 }
192 
193 //    设备路径转为逻辑路径
194 BOOL DevicePathToWinPath(LPCSTR lpDeviceFileName, LPSTR lpBuf)
195 {
196     //    枚举反查法取设备路径对应的逻辑路径
197     for (int i = 0; i < 26; i++)
198     {
199         //    构造逻辑盘符
200         CHAR szDeviceName[MAX_PATH] = "";
201         szDeviceName[0] = 'A' + i;
202         szDeviceName[1] = ':';
203 
204         //    查询逻辑盘符对应的设备路径
205         CHAR szTargetPath[MAX_PATH] = "";
206         if (QueryDosDeviceA(szDeviceName, szTargetPath, MAX_PATH) == 0)
207             continue;
208 
209         //    匹配查询到的设备路径和目标设备路径
210         bool bStatus = true;
211         for (int j = 0; j < strlen(szTargetPath); j++)
212             if (szTargetPath[j] != lpDeviceFileName[j])
213             {
214                 bStatus = false;
215                 break;
216             }
217 
218         //    如果匹配成功则构造逻辑盘符路径
219         if (bStatus)
220         {
221             strcpy(lpBuf, szDeviceName);
222             strcpy(&lpBuf[2], &lpDeviceFileName[strlen(szTargetPath)]);
223             return TRUE;
224         }
225     }
226 
227     return FALSE;
228 }
229 
230 //    是否是微软文件
231 BOOL IsMicrosoftFile(LPCSTR lpFileName)
232 {
233     //    检测信息初始化是否已成功
234     if (strlen(szMSCompanyName) == 0 || strlen(szMSLegalCopyright) == 0)
235         TmntCrtPrcs();
236         //ErrorMessageBox("运行时错误!");
237 
238     //    获取当前文件公司名称和版权信息
239     CHAR szCompanyName[MAX_PATH] = "", szLegalCopyright[MAX_PATH] = "";
240     if (!GetFileVerInfo(lpFileName, "CompanyName", szCompanyName) || strlen(szCompanyName) == 0 || 
241         !GetFileVerInfo(lpFileName, "LegalCopyright", szLegalCopyright) || strlen(szLegalCopyright) == 0)
242         return FALSE;
243 
244     //    对比微软公司名称和版权信息
245     return strcmp(szCompanyName, szMSCompanyName) == 0 && strcmp(szLegalCopyright, szMSLegalCopyright) == 0;
246 }
247 
248 //    文件是否存在系统目录
249 BOOL IsExistWindir(LPCSTR lpFileName)
250 {
251     //    检测信息初始化是否已成功
252     if (strlen(szWindir) == 0 || strlen(szWindir64) == 0)
253         TmntCrtPrcs();
254         //ErrorMessageBox("运行时错误!");
255 
256     //    分割文件路径
257     CHAR szPath[MAX_PATH] = "", drive[MAX_PATH] = "", dir[MAX_PATH] = "";
258     _splitpath(lpFileName, drive, dir, NULL, NULL);
259     strcpy(szPath, drive);
260     strcat(szPath, dir);            //    构造路径
261 
262     //    文件路径和系统目录是否匹配
263     return stricmp(szPath, szWindir) == 0 || stricmp(szPath, szWindir64) == 0;
264 }
265 
266 //    获取目标进程的文件路径
267 BOOL GetPrcsFilePath(DWORD dwPid, LPSTR lpBuf)
268 {
269     //    打开进程调试权限
270     if (!EnablePrivileges("SeDebugPrivilege", TRUE))
271         return FALSE;
272 
273     //    打开目标进程
274     HANDLE hParentProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
275     if (hParentProc == NULL)
276         return FALSE;
277 
278     //    关闭进程调试权限
279     EnablePrivileges("SeDebugPrivilege", FALSE);
280 
281     //    获取目标进程的设备路径
282     CHAR szImageFileName[MAX_PATH] = "";
283     if (GetProcessImageFileNameA(hParentProc, szImageFileName, MAX_PATH) == 0 || strlen(szImageFileName) == 0)
284         return FALSE;
285 
286     //    将设备路径转为逻辑路径
287     if (!DevicePathToWinPath(szImageFileName, lpBuf) || strlen(lpBuf) == 0)
288         return FALSE;
289 
290     return TRUE;
291 }
292 
293 //    获取目标函数的钩子状态
294 //    该函数暂仅对在WinXPx86/Win7x86/Win7x64/Win8.1x64下的ntdll.dll/kernel32.dll/user32.dll负责
295 BOOL GetApiHookStatus(LPCSTR lpModuleName, LPCSTR lpProcName)
296 {
297     //    获取目标函数所在的动态链接库的句柄
298     HMODULE hModule = GetModuleHandleA(lpModuleName);
299     if (hModule == NULL)
300         hModule = LoadLibraryA(lpModuleName);
301     if (hModule == NULL)
302         return ERROR;
303 
304     //    获取目标函数的地址
305     FARPROC fpProc = GetProcAddress(hModule, lpProcName);
306     if (fpProc == NULL)
307         return ERROR;
308 
309     //    获取目标函数地址的前16字节
310     BYTE buf[16] = {};
311     if (!ReadProcessMemory(GetCurrentProcess(), fpProc, &buf, 16, NULL))
312         return ERROR;
313 
314     /*
315     E9
316     XX ... XX FF E0
317 
318     例外
319     E9 XX XX XX 00
320     E9 XX XX XX FA
321     E9 XX XX XX FC
322     E9 XX XX XX FF
323     E9 XX XX XX XX 90
324     */
325 
326     //   判断前1字节是否存在JMP指令并排除例外
327     if (buf[0] == 0xE9 && buf[4] != 0x00 && buf[4] != 0xFA && buf[4] != 0xFC && buf[4] != 0xFF && buf[5] != 0x90)
328         return TRUE;
329 
330     //     判断前16字节是否存在JMP EAX指令
331     for (int i = 0; i < 16 - 1; i++)
332         if (buf[i] == 0xFF && buf[i + 1] == 0xE0)
333             return TRUE;
334 
335     return FALSE;
336 }
337 
338 //    初始化信息
339 void InitInfo()
340 {
341     //    获取Ntdll.dll模块句柄
342     hNtdll = GetModuleHandleA("Ntdll.dll");
343     if (hNtdll == NULL)
344         hNtdll = LoadLibraryA("Ntdll.dll");
345     if (hNtdll == NULL)
346         ErrorMessageBox("程序初始化失败!");
347 
348     //    获取LdrLoadDll函数地址
349     LdrLoadDll = (pLdrLoadDll)GetProcAddress(hNtdll, "LdrLoadDll");
350     if (LdrLoadDll == NULL)
351         ErrorMessageBox("程序初始化失败!");
352 
353     //    获取RtlInitUnicodeString函数地址
354     RtlInitUnicodeString = (pRtlInitUnicodeString)GetProcAddress(hNtdll, "RtlInitUnicodeString");
355     if (RtlInitUnicodeString == NULL)
356         ErrorMessageBox("程序初始化失败!");
357 
358     //    获取系统目录
359     GetSystemDirectoryA(szWindir, MAX_PATH);
360     strcat(szWindir, "\");
361     if (strlen(szWindir) != 20 && stricmp(&szWindir[14], "tem32\") != 0)
362         ErrorMessageBox("程序初始化失败!");
363 
364     //    获取64位系统目录
365     strcpy(szWindir64, szWindir);
366     strcpy(&szWindir64[14], "wow64\");
367 
368     //    获取Ntdll.dll文件路径
369     strcpy(szNtdllPath, szWindir);
370     strcat(szNtdllPath, "Ntdll.dll");
371 
372     //    获取微软公司名称和版权信息
373     if (!GetFileVerInfo(szNtdllPath, "CompanyName", szMSCompanyName) || strlen(szMSCompanyName) == 0 ||
374         !GetFileVerInfo(szNtdllPath, "LegalCopyright", szMSLegalCopyright) || strlen(szMSLegalCopyright) == 0)
375         ErrorMessageBox("程序初始化失败!");
376 }
377 
378 //    检测父进程
379 void CheckParent()
380 {
381     //    创建进程信息快照
382     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
383     if (hSnapshot == INVALID_HANDLE_VALUE)
384         ErrorMessageBox("程序初始化失败!");
385 
386     PROCESSENTRY32 pe32 = {};
387     pe32.dwSize = sizeof(pe32);
388 
389     DWORD dwParentId = NULL;    //    父进程PID
390 
391     //    枚举进程信息
392     BOOL ret = Process32First(hSnapshot, &pe32);
393     while (ret)
394     {
395         //    获取自身进程的父进程ID
396         if (pe32.th32ProcessID == GetCurrentProcessId())
397         {
398             dwParentId = pe32.th32ParentProcessID;
399             break;
400         }
401         ret = Process32Next(hSnapshot, &pe32);
402     }
403     CloseHandle(hSnapshot);
404 
405     if (dwParentId == NULL)
406         ErrorMessageBox("程序初始化失败!");
407 
408     CHAR szParentFileName[MAX_PATH] = "";
409     if (!GetPrcsFilePath(dwParentId, szParentFileName) || strlen(szParentFileName) == 0)
410         ErrorMessageBox("程序初始化失败!");
411 
412     //    分割文件路径
413     CHAR szExeName[MAX_PATH] = "", fileName[MAX_PATH] = "", ext[MAX_PATH] = "";
414     _splitpath(szParentFileName, NULL, NULL, fileName, ext);
415     strcpy(szExeName, fileName);
416     strcat(szExeName, ext);            //    构造文件名
417 
418     //    如果父进程名不为"explorer.exe", 或父进程不为微软文件
419     if (stricmp(szExeName, "explorer.exe") != 0 || !IsMicrosoftFile(szParentFileName))
420         ErrorMessageBox("程序初始化失败!");
421 }
422 
423 //    Hook LdrLoadDll指向的函数
424 NTSTATUS WINAPI NewLdrLoadDll(PWCHAR PathToFile, ULONG Flags, PUNICODE_STRING ModuleFileName, PHANDLE ModuleHandle)
425 {
426     //    将UNICODE STRING转为WSTR
427     WCHAR wszFileName[MAX_PATH] = L"";
428     wcscpy(wszFileName, ModuleFileName->Buffer);
429 
430     //    将WSTR转为STR
431     CHAR szFileName[MAX_PATH] = "";
432     wcstombs(szFileName, wszFileName, MAX_PATH);
433 
434     //    获取目标文件的后缀
435     CHAR ext[MAX_PATH] = "";
436     _splitpath(szFileName, NULL, NULL, NULL, ext);
437 
438     //    如果目标文件为DLL, 存在系统目录, 是微软文件 则允许加载
439     HMODULE ret = NULL;
440     if (stricmp(ext, ".dll") == 0 && IsExistWindir(szFileName)/* && IsMicrosoftFile(szFileName)*/)
441     {
442         //    暂停Hook LdrLoadDll
443         HookLdrLoadDll.Suspend();
444 
445         //    调用封装LdrLoadDll并获得返回值
446         ret = MyLdrLoadDll(szFileName);
447 
448         //    恢复Hook LdrLoadDll
449         HookLdrLoadDll.Resume();
450     }
451 
452     //    成功返回真实句柄 失败则返回Ntdll.dll的句柄
453     *ModuleHandle = (HANDLE)(ret != NULL ? ret : hNtdll);
454 
455     return ERROR_SUCCESS;
456 }
457 
458 //    LdrLoadDll的封装调用
459 HMODULE MyLdrLoadDll(LPCSTR lpFileName)
460 {
461     //    检测信息初始化是否已成功
462     if (LdrLoadDll == NULL || RtlInitUnicodeString == NULL)
463         TmntCrtPrcs();
464         //ErrorMessageBox("运行时错误!");
465 
466     //    将STR转为WSTR
467     WCHAR wszFileName[MAX_PATH] = L"";
468     mbstowcs(wszFileName, lpFileName, MAX_PATH);
469 
470     //    将WSTR转为UNICODE STRING
471     UNICODE_STRING usFileName;
472     RtlInitUnicodeString(&usFileName, wszFileName);
473 
474     //    调用LdrLoadDll函数
475     HANDLE hModule;
476     LdrLoadDll(NULL, NULL, &usFileName, &hModule);
477 
478     return (HMODULE)hModule;
479 }
480 
481 //    初始化反注入
482 BOOL InitAntiInject()
483 {
484     if (HookLdrLoadDll.GetHookStatus())
485         return TRUE;
486 
487     //    Hook LdrLoadDll
488     HookLdrLoadDll.Uninstall();
489     return HookLdrLoadDll.Install("ntdll.dll", "LdrLoadDll", (FARPROC)NewLdrLoadDll);
490 }
491 
492 //    检测DLL模块
493 void CheckDllModule()
494 {
495     //    创建模块信息快照
496     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, NULL);
497     if (hSnapshot == INVALID_HANDLE_VALUE)
498         TmntCrtPrcs();
499         //ErrorMessageBox("运行时错误!");
500 
501     MODULEENTRY32W me32 = {};
502     me32.dwSize = sizeof(me32);
503 
504     //    枚举模块信息
505     BOOL ret = Module32First(hSnapshot, &me32), bStatus = false;
506     ret = Module32Next(hSnapshot, &me32);    //    直接忽略第一个自身exe文件模块
507     while (ret)
508     {
509         //    标记已经枚举模块成功
510         bStatus = true;
511 
512         //    获取STR文件路径
513         CHAR szFileName[MAX_PATH] = "";
514         wcstombs(szFileName, me32.szExePath, MAX_PATH);
515 
516         //    分割文件路径
517         CHAR szExeName[MAX_PATH] = "", fileName[MAX_PATH] = "", ext[MAX_PATH] = "";
518         _splitpath(szFileName, NULL, NULL, fileName, ext);
519         strcpy(szExeName, fileName);
520         strcat(szExeName, ext);        //    构造文件名
521 
522         //    匹配模块是否合法
523         if (stricmp(ext, ".dll") != 0 || !IsExistWindir(szFileName) || !IsMicrosoftFile(szFileName))
524         {
525             int tmp = 0;
526             while (FreeModule(me32.hModule))
527                 if (tmp++ >= MAX_LANA)
528                     ErrorMessageBox("检测到非法注入!");
529 
530             if (GetModuleHandleA(szExeName))
531                 ErrorMessageBox("检测到非法注入!");
532         }
533 
534         ret = Module32Next(hSnapshot, &me32);
535     }
536 
537     CloseHandle(hSnapshot);
538 
539     if (!bStatus)
540         TmntCrtPrcs();
541         //ErrorMessageBox("运行时错误!");
542 }
543 
544 //    检测
545 void Check()
546 {
547     //    在检测线程里循环检测
548     while (true)
549     {
550         //    获取系统时间间隔
551         FILETIME fts = {}, fte = {};
552         GetSystemTimeAsFileTime(&fts);    //    获取开始时间
553 
554         CheckDllModule();
555         InitAntiInject();
556         Sleep(2000);
557 
558         GetSystemTimeAsFileTime(&fte);    //    获取结束时间
559         DWORD dwMillisecond = (fte.dwLowDateTime - fts.dwLowDateTime) / 10000;    //    获取时间间隔
560         if (dwMillisecond > 3000)    //    如果时间间隔远大于Sleep的时间
561             TmntCrtPrcs();
562             //ErrorMessageBox("运行时错误!");
563     }
564 }
EnhanFunc.cpp
 1 #include <iostream>
 2 #include <string>
 3 #include <windows.h>
 4 #include "EnhanFunc.h"
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     InitInfo();
10     CheckParent();
11 
12     if (CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Check, NULL, NULL, NULL) == NULL)
13         ErrorMessageBox("程序初始化失败!");
14 
15     int crt = 0;
16     while (true)
17     {
18         //    获取系统时间间隔
19         FILETIME fts = {}, fte = {};
20         GetSystemTimeAsFileTime(&fts);    //    获取开始时间
21 
22         printf("safety running %d second
", crt++);
23         Sleep(1000);
24 
25         GetSystemTimeAsFileTime(&fte);    //    获取结束时间
26         DWORD dwMillisecond = (fte.dwLowDateTime - fts.dwLowDateTime) / 10000;    //    获取时间间隔
27         if (dwMillisecond > 2000)    //    如果时间间隔远大于Sleep的时间
28             TmntCrtPrcs();
29             //ErrorMessageBox("运行时错误!");
30     }
31 
32     return 0;
33 }
main.cpp
原文地址:https://www.cnblogs.com/gwsbhqt/p/5042252.html