码迷,mamicode.com
首页 > 其他好文 > 详细

HOOK KiFastCallEntry

时间:2015-11-16 22:53:09      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:

#include <ntddk.h>
#include <windef.h>
#include <stdlib.h>


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



VOID UnHOOKNtOpenProcess();

ULONG Old_NtOpProAddress;
ULONG New_NtOpProAddress;

ULONG Address_KiFastCallEntry;
ULONG OldJmpKeFastCallEntry;
typedef NTSTATUS  (*NTOPENPROCESS)(
    OUT PHANDLE ProcessHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN PCLIENT_ID ClientId OPTIONAL
    );

VOID OutPut()
{
    DbgPrint("Success\n");
}

VOID UnHookKiFastCallEntry()
{
    // 2B E1 C1 E9 02

    UCHAR HookKiFastMyAddress[5] = {0x2B,0xE1,0xC1,0xE9,0x02};
    _asm
    {
            cli
            mov eax,cr0
            and eax,not 10000h
            mov cr0,eax
    }


    RtlCopyMemory((PVOID)(OldJmpKeFastCallEntry-5),HookKiFastMyAddress,5);

    _asm
    {
            mov eax,cr0
            or  eax,10000h
            mov cr0,eax
            sti
    }
}



_declspec(naked)VOID MyKiFaseCallEntry()
{
    _asm
    {
        pushad //一定要保存这个
        pushfd
        call OutPut
        popfd
        popad
        sub     esp,ecx
        shr     ecx,2
        jmp     OldJmpKeFastCallEntry
    }
}

VOID HOOKMYKIFASTCALLENTRY(ULONG Address)
{
    ULONG HOOKFUNTIONADDRESS = (ULONG)MyKiFaseCallEntry;
    UCHAR HOOKADDRESS[5] = {0xe9,0,0,0,0};
    ULONG NTHOOKADDRESS_KIFASTCALLENTRY = HOOKFUNTIONADDRESS - Address - 5;
    *(ULONG*)&HOOKADDRESS[1] = NTHOOKADDRESS_KIFASTCALLENTRY;
    OldJmpKeFastCallEntry = (Address+5);
    _asm
    {
        cli
            mov eax,cr0
            and eax,not 10000h
            mov cr0,eax
    }

    RtlCopyMemory((PVOID)Address,HOOKADDRESS,5);

    _asm
    {
        mov eax,cr0
            or  eax,10000h
            mov cr0,eax
            sti
    }
}


ULONG HookKiFastCallEntry(ULONG KiFastCallEntryAddress)
{
    KiFastCallEntryAddress-=50;
    BYTE* P;
    for (ULONG i=0;i<50;i++)
    {
        // 2B E1 C1 E9 02
        P = (BYTE*)(KiFastCallEntryAddress+i);
        if (*P==0x2b && *(P+1)== 0xe1 && *(P+2)==0xc1 && *(P+3)== 0xE9 && *(P+4)==0x02)
        {
            //============================================
        
            DbgPrint("OldJmpKeFastCallEntry:%X\n",P);
            UnHOOKNtOpenProcess();
            //============================================
            return (ULONG)P;
            break;
        }
    }
    return 0;
}

NTSTATUS  MyNtOpenProcess(
    OUT PHANDLE ProcessHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN PCLIENT_ID ClientId OPTIONAL
    )
{
    //获取调用 KiFastCallEntry 中代码的地址
    _asm
    {
        pushfd 
        mov  eax,[ebp+4]
        mov  Address_KiFastCallEntry,eax
        popfd
    }
    ULONG Address = HookKiFastCallEntry(Address_KiFastCallEntry);
    if (Address != 0)
    {
        HOOKMYKIFASTCALLENTRY(Address);
    }
    return ((NTOPENPROCESS)Old_NtOpProAddress)(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
}



VOID HOOKNtOpenProcess()
{

    _asm
    {
            push ebx
            push eax
            push ecx
            mov  ebx,122
            mov  eax,KeServiceDescriptorTable
            mov  eax,[eax]
            mov  ecx,[eax+ebx*4]
            mov  Old_NtOpProAddress,ecx
            pop  ecx
            pop  eax
            pop  ebx
    }


    New_NtOpProAddress = (ULONG)MyNtOpenProcess;
    

    _asm //关闭保护
    {
        cli
            mov eax,CR0
            and  eax,not 10000h
            mov CR0,eax
    }


    _asm
    {
        push ebx
            push eax
            push ecx

            mov  ebx,122
            mov  eax,KeServiceDescriptorTable
            mov  eax,[eax]
            mov  ecx,MyNtOpenProcess
            mov  [eax+ebx*4],ecx

            pop  ecx
            pop  eax
            pop  ebx
    }

    _asm //开启保护
    {
        mov eax,CR0
            or  eax,10000h
            mov CR0,eax
            sti
    }
}

VOID UnHOOKNtOpenProcess()
{
    _asm //关闭保护
    {
        cli
            mov eax,CR0
            and  eax,not 10000h
            mov CR0,eax
    }


    _asm
    {
        push ebx
            push eax
            push ecx

            mov  ebx,122
            mov  eax,KeServiceDescriptorTable
            mov  eax,[eax]
            mov  ecx,Old_NtOpProAddress
            mov  [eax+ebx*4],ecx

            pop  ecx
            pop  eax
            pop  ebx
    }

    _asm //开启保护
    {
        mov eax,CR0
            or  eax,10000h
            mov CR0,eax
            sti
    }
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{    
    UnHookKiFastCallEntry();
    
    DbgPrint("++++驱动卸载++++\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
    pDriverObj->DriverUnload = DriverUnload;
    DbgPrint("++++驱动加载++++\n");
    HOOKNtOpenProcess();
    return STATUS_SUCCESS;
}

 

HOOK KiFastCallEntry

标签:

原文地址:http://www.cnblogs.com/cxys/p/4970235.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!