zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    性能计数器
    SpringBoot_数据访问-整合JPA
    SpringBoot_数据访问-整合MyBatis(二)-注解版MyBatis
    SpringBoot_数据访问-整合Druid&配置数据源监控
    SpringBoot_数据访问-JDBC&自动配置原理
    八字克妻口诀
    没想到,我能这么细心地看算法
    辰戌丑未,四库
    The jar of divisors
    分布式系统阅读笔记(十六)-----事务和并发控制
  • 原文地址:https://www.cnblogs.com/gwsbhqt/p/5042252.html
Copyright © 2011-2022 走看看