首页
社区
课程
招聘
[原创]inline hook ObReferenceObjectByHandle() 实现拒绝指定进程执行
发表于: 2009-7-18 15:42 11767

[原创]inline hook ObReferenceObjectByHandle() 实现拒绝指定进程执行

2009-7-18 15:42
11767
标 题: inline hook ObReferenceObjectByHandle() 实现拒绝指定进程执行
作 者: emc
时 间: 2009-07-18
链 接: hi.baidu.com/mc0066_

此代码借鉴了sysnap早期代码,并且我从中学到了很多东西。本来我打算使用新的程序架构和流程来实现此功能,可惜由于本人是初学者,最后还是放弃了,改用sysnap早期的代码流程与架构。

在调试本程序的过程中,受到了部分网友的关注,再次向他们的崇高精神表示感谢:
flowercode
iceboy
轩辕小聪
...

参考文献: http://bbs.pediy.com/showthread.php?t=65731

#include <ntddk.h>
#include <string.h>

extern POBJECT_TYPE *PsProcessType;

//mov edi,edi
//push ebp
//mov ebp,esp
unsigned char routine_head[5] = {0x8b,0xff,0x55,0x8b,0xec};       

//jmp address
unsigned char jmp_code[5] = {0xe9,0x00,0x00,0x00,0x00};

void close_write_protected()
{
        //cancel write protected
        __asm
        {
                CLI           
                MOV eax, CR0     
                AND eax, NOT 10000H
                MOV CR0, eax
        }
}

void open_write_protected()
{
        __asm
        {
                MOV eax, CR0
                OR eax, 10000H
                MOV CR0, eax
                STI
        }       
}

//this routine unload current driver
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
        KIRQL irql;

        irql = KeRaiseIrqlToDpcLevel();
        close_write_protected();
       
        //unload inline hook
        RtlCopyMemory(ObReferenceObjectByHandle,routine_head,5);
       
        open_write_protected();
        KeLowerIrql(irql);

        DbgPrint("inline hook success unload.");

        return;
}

//this routine return 0 success run ObReferenceObjectByHandle()
//this routine return 1 failed run ObReferenceObjectByHandle()
int call_failed(
                                IN HANDLE Handle,
                                IN ACCESS_MASK DesiredAccess,
                                IN POBJECT_TYPE ObjectType,
                                IN KPROCESSOR_MODE AccessMode,
                                OUT PVOID *Object,
                                OUT POBJECT_HANDLE_INFORMATION HandleInfo
                                )
{       
        PEPROCESS process;
        KIRQL irql;               

        //this object is a process
        if(ObjectType == *PsProcessType)
        {               
                irql = KeRaiseIrqlToDpcLevel();
                close_write_protected();

                //Unload inline hook in ObReferenceObjectByHandle()
                RtlCopyMemory(ObReferenceObjectByHandle,routine_head,5);

                //run the kernel routine
                if(ObReferenceObjectByHandle(Handle,DesiredAccess,ObjectType,AccessMode,&process,NULL) == STATUS_SUCCESS)
                {
                        //this request point to notepad.exe               
                        if(_stricmp((char *)((char *)process+0x174),"notepad.exe") == 0)
                        {                               
                                //install inline hook to ObReferenceObjectByHandle()
                                RtlCopyMemory(ObReferenceObjectByHandle,jmp_code,5);               

                                open_write_protected();
                                KeLowerIrql(irql);               
                       
                                return 1;
                        }
                        else
                        {
                                //install inline hook to ObReferenceObjectByHandle()
                                RtlCopyMemory(ObReferenceObjectByHandle,jmp_code,5);               

                                open_write_protected();
                                KeLowerIrql(irql);               

                                return 0;
                        }
                }
                else
                {
                        //install inline hook to ObReferenceObjectByHandle()
                        RtlCopyMemory(ObReferenceObjectByHandle,jmp_code,5);               

                        open_write_protected();
                        KeLowerIrql(irql);               
       
                        return 0;
                }

        }
        else  //this object not a process
        {
                return 0;
        }       
}

//jmp this routine
__declspec(naked) my_routine(
                                                        IN HANDLE  Handle,
                                                        IN ACCESS_MASK  DesiredAccess,
                                                        IN POBJECT_TYPE  ObjectType,
                                                        IN KPROCESSOR_MODE  AccessMode,
                                                        OUT PVOID  *Object,
                                                        OUT POBJECT_HANDLE_INFORMATION  HandleInfor
                                                        )
{
        __asm
        {               
                mov edi,edi
               
                //create next stack for sub routine using       
                push ebp
                mov ebp,esp

                //parameter enter the stack
                push [ebp+0x1c]
                push [ebp+0x18]
                push [ebp+0x14]
                push [ebp+0x10]
                push [ebp+0xc]
                push [ebp+8]

                //enter the routine
                call call_failed
                cmp eax,1
                jz start_new

                mov eax,ObReferenceObjectByHandle
                add eax,5
                jmp eax

start_new:
                mov [ebp+8],-1
                mov eax,ObReferenceObjectByHandle
                add eax,5
                jmp eax
        }
}

//in this routine install inline hook
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
        //this is offset of jmp to my routine
        int jmp_offset;
       
        KIRQL irql;       

        //set current driver unload routine
        DriverObject->DriverUnload = DriverUnload;

        irql = KeRaiseIrqlToDpcLevel();
        close_write_protected();
       
        //count and get to my_routine offset
        jmp_offset = (char *)my_routine - (char *)ObReferenceObjectByHandle - 5;
       
        //create the jmp offset to jmp_offset
        RtlCopyMemory(jmp_code+1,&jmp_offset,4);       

        //inline hook ObReferenceObjectByHandle routine
        RtlCopyMemory(ObReferenceObjectByHandle,jmp_code,5);

        open_write_protected();
        KeLowerIrql(irql);
       
        DbgPrint("install inline hook success.");

        return STATUS_SUCCESS;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
2
顶一下,不过入门阶段实在不建议学这个…
2009-7-18 19:47
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
emc
3
to achillis:

那该怎么学呀~教主兄,告诉我学习的方法和步骤,加我QQ呀~ 我给你发消息了。
2009-7-18 20:11
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
没人顶,我帮你恶魔城。哈哈
2009-8-3 21:58
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
繁琐  而且不是很好
2009-8-9 19:05
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
/字节型数据  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;
        KdPrint(("[ObReferenceObjectByHandle] :0x%x",ObReferenceObjectByHandle));  //地址验证
        //保存函数前五个字节内容
        RtlCopyMemory(OriginalBytes,(BYTE *)ObReferenceObjectByHandle,5);
        //保存新函数五个字节之后偏移
        *(ULONG *)(JmpAddress+1)=(ULONG)DetourMyObReferenceObjectByHandle-((ULONG)ObReferenceObjectByHandle+5);
        //开始inline hook
        //关闭内存写保护
        _asm
        {
                push eax
                        mov eax, cr0
                        mov CR0VALUE, eax
                        and eax, 0fffeffffh  
                        mov cr0, eax
                        pop eax
        }
        //提升IRQL中断级
        Irql=KeRaiseIrqlToDpcLevel();
        //函数开头五个字节写JMP
        RtlCopyMemory((BYTE *)ObReferenceObjectByHandle,JmpAddress,5);
        //恢复Irql
        KeLowerIrql(Irql);
        //开启内存写保护
        __asm
        {      
                push eax
                        mov eax, CR0VALUE
                        mov cr0, eax
                        pop eax
        }
}

_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)
                {
                   if( _stricmp((char *)((ULONG)(*Object)+0x174),"notepad.exe")==0)
                   {   
                           ObDereferenceObject(*Object);
                           return STATUS_INVALID_HANDLE;
                   }
                }
        }
        return status;
}

void UnHookObReferenceObjectByHandle()
{
        //把五个字节再写回到原函数
        KIRQL Irql;
    //关闭写保护
        _asm
        {
                push eax
                        mov eax, cr0
                        mov CR0VALUE, eax
                        and eax, 0fffeffffh  
                        mov cr0, eax
                        pop eax
        }
    //提升IRQL到Dpc
    Irql=KeRaiseIrqlToDpcLevel();
        RtlCopyMemory((BYTE *)ObReferenceObjectByHandle,OriginalBytes,5);
        KeLowerIrql(Irql);
    //开启写保护
        __asm
        {      
                push eax
                        mov eax, CR0VALUE
                        mov cr0, eax
                        pop eax
        }
}
2009-8-9 19:06
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
emc
7
谢谢,希望我以后可以写出更好的 inline hook
2009-8-9 22:25
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
8
采用我这三步走就差不多了
2009-8-10 23:54
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
9
你看看你那过程无比繁琐,耗资源
2009-8-10 23:55
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
emc
10
竹君: 我一开始就想改流程和框架了,可惜没改成。现在我研究object hook,inline hook之后还研究,到时候就先copy你的code.

ps:你是sysdog ?
2009-8-11 09:17
0
游客
登录 | 注册 方可回帖
返回
//