您的位置:首页 > 其它

学习InlineHOOK

2013-05-22 23:18 429 查看
其实InlineHook 不像想象的那么复杂。如果你慢慢的学习研究还是很好理解的。

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

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

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

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

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



好了,可以去试试了。

//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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: