驱动之路_SSDT表hook

#include <ntddk.h>

//定义数据内存空间段

#define PAGECODE code_seg("PAGE")//可以用于虚拟内存
#define INITCODE code_seg("INIT")//代码运行在这块内存上,运行一次就释放

typedef struct _ServiceDescriptorTable {
    PVOID ServiceTableBase; //System Service Dispatch Table 的基地址 
    PVOID ServiceCounterTable;
    //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
    unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。 
    PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
}*PServiceDescriptorTable; 
extern PServiceDescriptorTable KeServiceDescriptorTable;

VOID WPOFF()
{
    __asm
    {
        cli
            mov eax, cr0
            and eax, not 10000h
            mov cr0, eax
    }
}


VOID WPON()
{
    __asm
    {
        mov eax, cr0
            or eax, 10000h
            mov cr0, eax
            sti
    }
}

typedef NTSTATUS (__stdcall *ZWOPENPROCESS)(OUT PHANDLE ProcessHandle,
                                            IN ACCESS_MASK DesiredAccess,
                                            IN POBJECT_ATTRIBUTES ObjectAttributes,
                                            IN PCLIENT_ID ClientId
                                            );

ZWOPENPROCESS RealZwOpenProcess;//声明了一个函数指针


NTSTATUS NewZwOPENPROCESS(OUT PHANDLE ProcessHandle,
                                  IN ACCESS_MASK DesiredAccess,
                                  IN POBJECT_ATTRIBUTES ObjectAttributes,
                                  IN PCLIENT_ID ClientId
                                  )
{

    return RealZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);

}



VOID Cr0SSDTHook()
{
    //保存原始地址
    //(int*)KeServiceDescriptorTable->ServiceTableBase)   得到base地址
    //+122*4相当于得到某个函数的变量地址
    
    int addr = (int)(((int*)KeServiceDescriptorTable->ServiceTableBase) + 122);
    
    DbgPrint("原始地址:%x\r\n",(*((int*)addr)));

    DbgPrint("原始地址:%x\r\n",*(((int*)KeServiceDescriptorTable->ServiceTableBase)+122));

    
    //把他转换成指针,然后在用*访问
    //保存下原来的函数
    RealZwOpenProcess = (ZWOPENPROCESS)(*((int*)addr));//原始函数地址

    //关闭页面保护
    WPOFF();

    //在替换成我们的函数
    *((int*)addr) = (int)NewZwOPENPROCESS;
    

    DbgPrint("现在地址:%x\r\n",(*((int*)addr)));

    //开启页面保护
    WPON();
}

#pragma PAGECODE
VOID DriverUnLoad(IN PDRIVER_OBJECT DriverObject)
{
        int addr;
        DbgPrint("卸载成功");
        addr = (int)(((int*)KeServiceDescriptorTable->ServiceTableBase) + 122);
        
        //关闭页面保护
        WPOFF();
        *((int*)addr) = (int)RealZwOpenProcess;
        //开启页面保护
        WPON();

}


#pragma INITCODE
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING regStr)
{
    DbgPrint("加载成功");
    //添加卸载函数
    pDriverObject->DriverUnload=DriverUnLoad;
    //下面进行NTOPENPROCESS的HOOK,也就是说修改表
    Cr0SSDTHook();//进行HOOK
    return (1);
}

 

posted @ 2013-09-15 10:40  宝贝,我永远都在  阅读(126)  评论(0)    收藏  举报