用户层 UnHook(x86)

大部分Windows API都会在ntdll找调用号进入内核,所以杀软3环钩子一般在ntdll

通过覆盖来清除杀软钩子(同理修改为user32.dll就可以去除上面x86的hook),例:

  • 1.从磁盘加载干净的ntdll

  • 2.获取从内存加载的ntdll

  • 3.找到代码段进行覆盖

#include <iostream>
#include <windows.h>
#include <psapi.h>

VOID UnHookNtdll() {
    // 从磁盘加载干净的ntdll
    HANDLE ntdllFile = CreateFile(L"C:\\windows\\system32\\ntdll.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); // ntdll文件句柄
    HANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL); // 将ntdll映射到进程内存
    LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0); // 指向起始地址的指针
    CloseHandle(ntdllMapping); // 关闭句柄
    CloseHandle(ntdllFile);

    // 从内存加载的ntdll可能被杀软hook
    HMODULE ntdllModule = GetModuleHandle(L"ntdll.dll"); // 加载ntdll
    /*
    * MODULEINFO结构体用于存储模块信息
    * GetModuleInformation 是 Windows API,用于获取模块信息
    * 参数1:进程句柄,HANDLE(-1)为当前进程句柄
    * 参数2:模块句柄
    * 参数3:MODULEINFO结构体的指针
    * 参数4:MODULEINFO结构体大小
    */
    MODULEINFO mi = {};
    GetModuleInformation(HANDLE(-1), ntdllModule, &mi, sizeof(mi)); // 获取ntdll模块信息
    LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll; // 获取ntdll基址
    PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase; // 获取DOS头
    PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew); // 偏移到NT头
    FreeLibrary(ntdllModule); // 释放DLL空间

    for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) { // 遍历PE文件每个节(Section)(代码段、数据段等),WORD是因为NumberOfSections是16位无符号整数
        /*
        * IMAGE_FIRST_SECTION(hookedNtHeader)为第一个节的地址
        * IMAGE_SIZEOF_SECTION_HEADER为一个节的大小
        * DWORD_PTR为无符号整数,便于在指针加法中进行偏移量计算
        * 加起来就是当前节
        */
        PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));

        if (!strcmp((char*)hookedSectionHeader->Name, (char*)".text")) { // 是代码段
            DWORD oldProtection = NULL; // 用于接收修改前的访问权限
            // 代码段改为可读可写可执行权限
            VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
            // 用ntdll原本的代码段进行覆盖
            memcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);
            // 代码段改回原权限
            VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
        }
    }
}

int main() {
    // InlineHook(); // 要将UnHookNtdll改为user32.dll
    UnHookNtdll();
    MessageBox(0, L"1", L"1", MB_OK);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值