首页
社区
课程
招聘
[求助]竹君,你的这句代码是什么意思?
发表于: 2010-9-24 20:46 5592

[求助]竹君,你的这句代码是什么意思?

2010-9-24 20:46
5592
看了好几遍了,就是不理解这句代码:

status=OriginalObReferenceObjectByHandle(Handle,DesiredAccess,ObjectType,AccessMode,Object,HandleInformation);
  
  if((status==STATUS_SUCCESS)&&(DesiredAccess==1))
   
为什么要调用原函数呢?请解释一下~~
谢谢!

//=======================================inline HOOK ObReferenceObjectByHandle===========================

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

//字节型数据  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
      
  }
}

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 1
支持
分享
最新回复 (14)
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
就是里面红色的那句
2010-9-24 20:48
0
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
scm
3
不调用原函数,怎么做判断?这代码很通用哦,很多HOOK都这么写的。
2010-9-24 21:13
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
ls的兄弟,调用原函数返回一个状态值有什么用呢?
这跟判断有什么关系?
实在不明白,希望能详细解释一下,谢谢
2010-9-24 21:41
0
雪    币: 998
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
因为你首先需要让这个函数调用能实现原来的功能,这个是最基本的要求。根据原函数完成后的状态,再判断是否应该做些手脚。
2010-9-24 22:53
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
明白了,谢谢楼上兄弟

再次感谢~~
2010-9-24 23:44
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
7


调用原来函数是要获取对象类型,判断这个函数调用成功了,基本上对象也就获取到了,当然有特殊情况是函数调用成功了,对象却没有获取到。。
2010-9-25 03:29
0
雪    币: 34
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
仔细看这句:
if( _stricmp((char *)((ULONG)(*Object)+0x174),"notepad.exe")==0)
这函数判断是否放过的方法是比较进程名是否为"notepad.exe",而获取进程名就需要获取EPROCESS,于是先通过ObRefObjectByHandle来获得EPROCESS,继而通过EPROCESS来获取ImageFileName(0x174偏移).

另外:
if(ObjectType== *PsProcessType)  这句是有点问题的.
IN POBJECT_TYPE  ObjectType  OPTIONAL, 是个可选的参数,
设置为NULL也是可以调用的.
ObReferenceObjectByHandle(....., NULL, .....); 这样调用就绕过这个hook了.
2010-9-25 03:58
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
本来我还以为理解了呢
经过ls这么一说,我发现自己还没理解.
ls的朋友,如果我想通过pid来判断是否过滤,是不是就可以不用调用这个原函数了?
2010-9-25 13:53
0
雪    币: 34
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
问题是,你如何获得pid?
获取pid还是得先得到EPROCESS,然后再从EPROCESS中获取pid,这样子还是得先调用ObReferenceObjectByHandle来获取EPROCESS.
2010-9-25 14:39
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
为什么还要加上这个代码?
_asm
               
        {   
               
           mov edi,edi
                        push ebp
                        mov ebp,esp
                        mov eax,ObReferenceObjectByHandle
                        add eax,5
                        jmp eax               
                       
        }
2010-9-25 19:41
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
是不是把已经被hook的函数复原?
2010-9-25 20:31
0
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
scm
13
这是调用原始函数~~
2010-9-26 21:00
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
mov edi,edi

这句代码好像一点用都没有啊~

去掉之后能怎么样?
2010-9-27 00:24
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
sd老师悲剧了
2010-9-27 00:31
0
游客
登录 | 注册 方可回帖
返回
//