学习InlineHOOK

其实InlineHook 不像想象的那么复杂。如果你慢慢的学习研究还是很好理解的。

我在看雪http://bbs.pediy.com/showthread.php?t=98493 看了这篇文章,做了一下修改。这里说说我的心得体会吧!

我们看到很多文章都说是修改前五个字节,其实这是不完全正确的说法,如果你熟悉InlineHook的话,可以换成这个函数地址范围内的任意五个字节,

但是要确保这个五个字节的格式为{E9,xx,xx,xx,xx} 其中XX表示地址。

下面的代码我会注释,写上我的理解。

整个代码的效果就是——当你使用任务管理器结束一个记事本进程(notepad.exe)的时候,系统提示无法终止进程,如下图所示。

学习InlineHOOK_第1张图片


好了,可以去试试了。

//HookObReferenceObjectByHandle------DetourMyObReferenceObjectByHa ndle----------UnHookObReferenceObjectByHandle

//完整代码分析如下:
//=======================================inline HOOK ObReferenceObjectByHandle===========================
//ObReferenceObjectByHandle是ntoskrnl.exe导出函数,采用HOOK前五个字节的方式

#include "ntddk.h"
//关闭内存保护
#define DisableMemProtect()\
    {\
 __asm cli\
 __asm mov eax,cr0\
 __asm push eax\
 __asm and eax,(~0x10000)\
 __asm mov cr0,eax\
}

//恢复内存保护
#define RecoverMemProtect()\
{\
 __asm pop eax\
 __asm or eax,0x10000\
 __asm mov cr0,eax\
 __asm sti\
}

//全局变量
unsigned char  OriginalBytes[5]={0};             //保存原始函数前五个字节           
unsigned char JmpAddress[5]={0xE9,0,0,0,0};       //跳转到HOOK函数的地址 E9 是JMP的机器码
extern POBJECT_TYPE *PsProcessType;

NTKERNELAPI NTSTATUS ObReferenceObjectByHandle(
                                     IN HANDLE  Handle,
                                     IN ACCESS_MASK  DesiredAccess,
                                     IN POBJECT_TYPE  ObjectType  OPTIONAL,
                                     IN KPROCESSOR_MODE  AccessMode,
                                     OUT PVOID  *Object,
                                     OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL);

//HOOK函数 这个函数功能就是,在系统调用ObReferenceObjectByHandle函数时

//进行其他操作,具体操作看下文的定义

NTSTATUS DetourMyObReferenceObjectByHandle(
                                   IN HANDLE  Handle,           
                                   IN ACCESS_MASK  DesiredAccess,
                                   IN POBJECT_TYPE  ObjectType  OPTIONAL,
                                   IN KPROCESSOR_MODE  AccessMode,
                                   OUT PVOID  *Object,
                                   OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL);


void  HookObReferenceObjectByHandle()
{
    //赋值前面定义的数组
    KIRQL Irql;
    KdPrint(("\n[ObReferenceObjectByHandle] :0x%x",ObReferenceObjectByHandle));  //地址验证

    //保存函数前五个字节内容
    RtlCopyMemory(OriginalBytes,(unsigned char *)ObReferenceObjectByHandle,5);

    //保存新函数五个字节之后偏移
    //Jmp[0]= E9
    //Jmp[1..4]  其实就是一个地址
    *(ULONG *)(JmpAddress+1)=(ULONG)DetourMyObReferenceObjectByHandle-((ULONG)ObReferenceObjectByHandle+5);
    KdPrint(("\n[JmpAddress] :0x%x",
        (ULONG)DetourMyObReferenceObjectByHandle-((ULONG)ObReferenceObjectByHandle+5)));  //地址验证
    //开始inline hook
    DisableMemProtect();  //关闭内存写保护
    Irql=KeRaiseIrqlToDpcLevel();//提升IRQL中断级
    //函数开头五个字节写JMP
    RtlCopyMemory((unsigned char *)ObReferenceObjectByHandle,JmpAddress,5);
    KeLowerIrql(Irql); //恢复Irql中断级别
    RecoverMemProtect();  //恢复内存写保护
 
}
_declspec (naked) NTSTATUS OriginalObReferenceObjectByHandle(
                                                   IN HANDLE  Handle,
                                                   IN ACCESS_MASK  DesiredAccess,
                                                   IN POBJECT_TYPE  ObjectType  OPTIONAL,
                                                   IN KPROCESSOR_MODE  AccessMode,
                                                   OUT PVOID  *Object,
                                                   OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL)
                               
{
    _asm
    {   
          mov edi,edi
          push ebp
          mov ebp,esp
          mov eax,ObReferenceObjectByHandle
          add eax,5
          jmp eax
    }
}


NTSTATUS DetourMyObReferenceObjectByHandle(
                               IN HANDLE  Handle,
                               IN ACCESS_MASK  DesiredAccess,
                               IN POBJECT_TYPE  ObjectType  OPTIONAL,
                               IN KPROCESSOR_MODE  AccessMode,
                               OUT PVOID  *Object,
                               OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL)
                       
{
    NTSTATUS status;
    //调用原函数
    status=OriginalObReferenceObjectByHandle(Handle,
                                            DesiredAccess,
                                            ObjectType,
                                            AccessMode,
                                            Object,
                                            HandleInformation);
    if((status==STATUS_SUCCESS)&&(DesiredAccess==1))
    {   
        if(ObjectType== *PsProcessType)
        {
            // 0x174 ImageFileName XP
            //0x16c ImageFileName Win7
            //if( _stricmp((char *)((ULONG)(*Object)+0x174),"notepad.exe")==0)//XP
            if( _stricmp((char *)((ULONG)(*Object)+0x16c),"notepad.exe")==0)//WIN7 注释掉这一句 回复上一句 就可以在XP 使用
            {   
                ObDereferenceObject(*Object);
                return STATUS_INVALID_HANDLE;
            }
        }
    }
   return status;
}

//取消HOOK
void UnHookObReferenceObjectByHandle()
{
    //把五个字节再写回到原函数
    KIRQL Irql;
    DisableMemProtect();  //关闭内存写保护
    Irql=KeRaiseIrqlToDpcLevel();    //提升IRQL到Dpc
    RtlCopyMemory((unsigned char *)ObReferenceObjectByHandle,OriginalBytes,5);
    KeLowerIrql(Irql);    //恢复到原来的中断级别
    RecoverMemProtect();   //恢复内存保护
}

//卸载驱动
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
   UnHookObReferenceObjectByHandle();
   DbgPrint("inline hook success unload.\n");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING InlineHook)
{
    NTSTATUS  status = 0;
    UNICODE_STRING DriverNameString;
    PDRIVER_OBJECT pDriverObject;
    HookObReferenceObjectByHandle();
    DriverObject->DriverUnload = DriverUnload;
    return     STATUS_SUCCESS;
}

你可能感兴趣的:(内核,InlineHooK)