Hook ObReferenceObjectByHandle的另一种框架

2009-8-7 Nie.Meining Coding

看到过几次hook ObReferenceObjectByHandle的代码,总感觉过程非常纠结,不停hook了又恢复,恢复了又hook,在几个函数间来回跳。
今天下午尝试写了个不那么纠结的框架,跟大家分享:

#include <ntddk.h>

//Hook ObReferenceObjectByHandle

//by Fypher

//http://hi.baidu.com/nmn714

unsigned char OriginalBytes[5]={0};

unsigned char JmpAddress[5]={0xE9,0,0,0,0};

extern POBJECT_TYPE *PsProcessType;

//唯一的fake函数,不恢复hook

_declspec (naked) void FakeReferenceObjectByHandle(){

    _asm{

        push [esp+0x18]            //参数压栈

        push [esp+0x18]

        push [esp+0x18]

        push [esp+0x18]

        push [esp+0x18]

        push [esp+0x18]

        push fakeeip               //压入假的返回地址

            mov edi,edi                //ObReferenceObjectByHandle的前5个字节

            push ebp

            mov ebp,esp

            mov eax,ObReferenceObjectByHandle

            add eax,5

            jmp eax                    //跳到ObReferenceObjectByHandle去执行

 

fakeeip:

        push eax                   //现在的eax是返回值,所以需要压栈保留

            mov eax,[esp+0x10]         //3个参数,判断是不是进程

        mov ecx,PsProcessType;   

        mov ecx,[ecx];

        cmp eax,ecx;

        jnz pass;                  //不是进程就pass

        mov eax,[esp+0x18];        //5个参数,即返回的EPROCESS

        mov eax,[eax];

        add eax,0x174;

        mov eax,[eax];

        cmp al,'n';                //判断进程名是否以“n”开头,可用notepad测试

        jnz pass                   //如果不是则pass

            pop eax

            mov eax,[esp+0x14]         //5个参数,即返回的EPROCESS,填0

        mov dword ptr [eax],0

            push 0xC0000022L           //STATUS_ACCESS_DENIED

 

pass:

        pop eax;

        retn 0x18;

    }

}

//没有新意的hook函数

void HookObReferenceObjectByHandle(){

    RtlCopyMemory(OriginalBytes,(unsigned char*)ObReferenceObjectByHandle,5);

    *(ULONG *)(JmpAddress+1)=(ULONG)FakeReferenceObjectByHandle-((ULONG)ObReferenceObjectByHandle+5);

    _asm{

        cli

            mov eax, cr0

            and eax, not 0x10000

            mov cr0, eax

    }

    RtlCopyMemory((unsigned char *)ObReferenceObjectByHandle,JmpAddress,5);

    _asm{

        mov eax, cr0

            or eax,0x10000

            mov cr0,eax

            sti

    }

}

//unhook函数

void UnHookObReferenceObjectByHandle(){

    _asm{

        cli

            mov eax, cr0

            and eax, not 0x10000

            mov cr0, eax

    }

    RtlCopyMemory((unsigned char*)ObReferenceObjectByHandle,OriginalBytes,5);

    __asm{

        mov eax, cr0

            or eax,0x10000

            mov cr0,eax

            sti

    }

}

VOID OnUnload(IN PDRIVER_OBJECT o){

    UnHookObReferenceObjectByHandle();

    return;

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath){

    DriverObject->DriverUnload=OnUnload;

    HookObReferenceObjectByHandle();

    return STATUS_SUCCESS;

}

 

发表评论:

Powered by emlog