反插件工程
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__
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 }
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 }