当前位置: 代码迷 >> 综合 >> Inline hook ObReferenceObjectByHandle,附加问题笔记做记录
  详细解决方案

Inline hook ObReferenceObjectByHandle,附加问题笔记做记录

热度:33   发布时间:2023-12-21 08:00:43.0

//禁止记事本结束 inline hook成功,原来的抄袭代码似乎有问题,不知道是不是环境问题:xp sp3+VM+双核CPU

 

//ObReferenceObjectByHandle是ntoskrnl.exe导出函数,采用HOOK前五个字节的方式

#include <ntddk.h>

#define dprintf DbgPrint

#include <windef.h> 

#include <ntstatus.h>

//字节型数据  unsigned char

ULONG  CR0VALUE;

BYTE  OriginalBytes[5]={0};             //保存原始函数前五个字节           

BYTE JmpAddress[5]={0xE9,0,0,0,0};       //跳转到HOOK函数的地址

 

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函数

 

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

 

//

 

//hook流程 HookObReferenceObjectByHandle---DetourMyObReferenceObjectByHandle---UnHookObReferenceObjectByHandle

 

void  HookObReferenceObjectByHandle()

 

{

 

//赋值前面定义的数组

KIRQL Irql;

// DbgPrint("[ObReferenceObjectByHandle] :%08x/n",ObReferenceObjectByHandle);  //地址验证

//保存函数前五个字节内容

RtlCopyMemory(OriginalBytes,(BYTE *)ObReferenceObjectByHandle,5);

//保存新函数五个字节之后偏移

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

//开始inline hook

 

__asm{//去掉内存保护

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

 

//提升IRQL中断级

Irql=KeRaiseIrqlToDpcLevel();

//函数开头五个字节写JMP 

RtlCopyMemory((BYTE *)ObReferenceObjectByHandle,JmpAddress,5);

//恢复Irql

KeLowerIrql(Irql);

//开启内存写保护

 

__asm{//恢复内存保护 

mov eax,cr0

or eax,10000h

mov cr0,eax

sti

}

 

}

 

_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   status;

char* ProtectName = "notepad.exe";

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)

 

{

//调用原函数

status=-1;

status=OriginalObReferenceObjectByHandle(Handle,DesiredAccess,ObjectType,AccessMode,Object,HandleInformation);

if((DesiredAccess==0x1)&&(ObjectType== *PsProcessType))

{

 

if(( _stricmp((char *)((ULONG)(*Object)+0x174),ProtectName)==0))//&&(status=STATUS_SUCCESS))加入蓝屏见图一反汇编代码,原因不知,—。—,太菜,结束进程记事本,出现应用程序出错,进程没结束,但会耗死CPU。


{   

ObDereferenceObject(*Object);//??? 去除也可以 不蓝屏或出错

 

return STATUS_ACCESS_DENIED;

}

 

}

return status;

}

 

 

 

void UnHookObReferenceObjectByHandle()

 

{

 

//把五个字节再写回到原函数

 

KIRQL Irql;

 

//关闭写保护

 

__asm{//去掉内存保护

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

 

//提升IRQL到Dpc

 

Irql=KeRaiseIrqlToDpcLevel();

 

RtlCopyMemory((BYTE *)ObReferenceObjectByHandle,OriginalBytes,5)