学习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)的时候,系统提示无法终止进程,如下图所示。
![](http://img.blog.csdn.net/20130522231803500)
好了,可以去试试了。
//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;
}
我在看雪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;
}
相关文章推荐
- inline hook NtOpenProcess学习资料以及总结问题
- 驱动学习---RootKits--inline hook 小插曲(
- 2017/4/22inlinehook学习
- Inline Hook IofCallDriver 截获所有IRP
- rootkit应用之[三] inline hook
- SSDT Hook的妙用-对抗ring0 inline hook
- ARM汇编基础知识汇总与Inline Hook
- css学习之路(5)--display:inline、block、inline-block的区别及inline-block兼容
- Android inline hook
- HOOK钩子技术5 SSDT Inline Hook
- 小试X64 inline HOOK,hook explorer.exe--->CreateProcessInternalW监视进程创建
- Arm Inline hook的简易原理图
- inline hook IofCallDriver 调用ntfs时保护文件访问
- 【日常学习】【模拟双向链表】【疑问】Uva12657 - Boxes in a Line题解
- 实现kernel-mode inline function hook的简单方法
- C++ Inline Hook 代码
- 【原创】详谈内核三步走Inline Hook实现
- Windows内核API HOOK 之 Inline Hook
- Inline Hook 之(监视任意函数)
- Android Arm Inline Hook