首页
社区
课程
招聘
[旧帖] [求助]各位朋友好,诚请你们帮我一个理解一下几句inline hook的代码,不胜感激. 0.00雪花
发表于: 2012-4-11 12:07 1352

[旧帖] [求助]各位朋友好,诚请你们帮我一个理解一下几句inline hook的代码,不胜感激. 0.00雪花

2012-4-11 12:07
1352
我原本不想问的(不敢),毕竟,我是一名小菜鸟,但是,我在苦苦挣扎了半天以后,确实没则了,故请你们那位朋友帮我理解一下下面的几句代码,感激不尽.
  对于你们这些大牛来说,一定非常简单,请不要笑话我哈.

  我先上全部代码.

;Inline Hook NtOpenFile 简单实现保护指定路径文件

.386
.model flat,stdcall
option casemap:none

;头文件声明;
include    \masm32\include\w2k\ntstatus.inc 
include    \masm32\include\w2k\ntddk.inc 
include    \masm32\include\w2k\hal.inc
include    \masm32\include\w2k\ntoskrnl.inc 
includelib \masm32\lib\w2k\ntoskrnl.lib 
includelib \masm32\lib\w2k\hal.lib
include    \masm32\Macros\Strings.mac

;数据段;
.data

OldNtOpenFile proto :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD   ;声明函数体;
NtOpenFile_Addr dd ?                                            ;保存NtOpenFile的真实地址;
oldIrql dd ?                                                    ;保存IRQL;
szName UNICODE_STRING <?>                                       ;文件名(UNICODE);
uCmdPathName dw '\','?','?','\','C',':','\','W','I','N','D','O','W','S','\','S','Y','S','T','E','M','3','2','\','c','m','d','.','e','x','e',0  ;欲保护文件的绝对路径(此CMD为例);

;代码段;
.code

DriverUnload proc pDriverObject:PDRIVER_OBJECT                   ;驱动卸载函数(start);

      pushad   
      
      cli             
      mov eax, cr0                  ;将CR0的WP(Write Protect)写保护置0->关闭写保护;
      and eax,0fffeffffh            
      mov cr0, eax                  
      
      invoke KeRaiseIrqlToDpcLevel  ;提升中断级,返回值:KeRaiseIrqlToDpcLevel returns the IRQL at which the call occurred;
      mov oldIrql,eax               ;将返回值保存在oldIrpl中;
      
      mov ecx,5
      mov edi,NtOpenFile_Addr
      mov esi,offset OldNtOpenFile
      rep movsb
      
      invoke KeLowerIrql,oldIrql    ;降低中断级;
      
      mov eax, cr0                  ;恢复只读页写保护;
      or eax,10000h
      mov cr0, eax 
      sti                           
      
      popad                         
 
      ret                           

DriverUnload endp                                                 

OldNtOpenFile proc FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions

      nop                             
      nop
      mov eax,NtOpenFile_Addr
      add eax,5
      jmp eax

OldNtOpenFile endp

MyNtOpenFile proc FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions
      
      mov eax,ObjectAttributes
      assume eax:ptr OBJECT_ATTRIBUTES
      
      invoke RtlCompareUnicodeString ,[eax].ObjectName,offset szName,TRUE  ;比较字符串(UNICODE);
         
      .if eax == 0                                                          
            mov       eax,STATUS_ACCESS_DENIED
            ret                                                             
      .endif
      
      assume eax:nothing                                                     
      
      invoke OldNtOpenFile,FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions  
      ret                                                                                                   

MyNtOpenFile endp

DriverEntry proc pDriverObject:PDRIVER_OBJECT,pRegistryPath:PUNICODE_STRING  ;多么熟悉,驱动的入口函数,相当于win32的main;

      pushad                                                                  
      invoke RtlInitUnicodeString,offset szName,offset uCmdPathName           ;初始化UNICODE字符;

      cli 
      mov eax, cr0                                                            ;去掉只读页写保护;
      and eax,0fffeffffh
      mov cr0, eax 
      
      invoke KeRaiseIrqlToDpcLevel                                            ;提升中断级;
      mov oldIrql,eax
      
      invoke MmGetSystemRoutineAddress,$CCOUNTED_UNICODE_STRING("NtOpenFile") ;直接调用MmGetSystemRoutineAddress获取已经导出的内核函数地址;

      mov NtOpenFile_Addr,eax       
      mov ecx,5                                                               ;计数寄存器置5(传送5个字节);
      mov esi,eax                                                        
      mov edi,offset OldNtOpenFile                                          
      rep movsb
      mov edx,offset MyNtOpenFile
      sub edx,eax
      sub edx,5
      mov byte ptr [eax],0e9h
      xchg [eax+1],edx
      
      invoke KeLowerIrql,oldIrql                                               ;恢复中断级;
      
      mov eax, cr0                                                             ;去掉只读页写保护;
      or eax,10000h
      mov cr0, eax 
      sti 
      
      mov eax,pDriverObject
      assume eax:ptr DRIVER_OBJECT
      mov [eax].DriverUnload,offset DriverUnload                               
      assume eax:nothing                                                       

      popad                                                                    
      mov eax,STATUS_SUCCESS                                                   
      ret

DriverEntry endp
end DriverEntry

  以上就是全部代码了.

  那么,那位朋友帮助我解释一下下面几句代码呢?谢谢.

在获取NtOpenFile的地址后:
      mov NtOpenFile_Addr,eax                                              
      mov ecx,5                                                              
      mov esi,eax                                                            
      mov edi,offset OldNtOpenFile                                          
      rep movsb
      mov edx,offset MyNtOpenFile
      sub edx,eax
      sub edx,5
      mov byte ptr [eax],0e9h
      xchg [eax+1],edx

  谢谢哈,我在线等.一定要帮我哈.

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 245
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我说的不一定对啊,感觉像是:
    在NtOpenFile原函数开始5字节处放置一个jmp,跳到MyNtOpenFile(),MyNtOpenFile()检查一下路径,如果可过的话,就要跳到OldNtOpenFile().OldNtOpenFile()就会去调用原来的ori NtOpenFile_Addr.但原来的NtOpenFile_addr(真实openfile地址头5字节被放置了jmp)所以需要把这5字节先执行了,再跳到NtOpenFile剩余5字节以后的地方继续执行。
   
   

     mov NtOpenFile_Addr,eax                                             
      mov ecx,5                                                              
      mov esi,eax                                                            
      mov edi,offset OldNtOpenFile                                          
      rep movsb     //这几句是保存原来NtOpenFile()的头5字节到OldNtOpenFile中去
      mov edx,offset MyNtOpenFile
      sub edx,eax
      sub edx,5     //这几句在计算原函数地址到MyNtOpenFile的距离
      mov byte ptr [eax],0e9h//放jmp
      xchg [eax+1],edx//偏移一字节开始放置需要跳的距离,(在真正的函数入口放个jmp,跳到MyNtOpenFile)
2012-4-11 14:44
0
雪    币: 64
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
mov NtOpenFile_Addr,eax      ;保存NtOpenFile的原地址
mov ecx,5                              
mov esi,eax                           
mov edi,offset OldNtOpenFile
rep movsb                              
从esi指向的内存中拷贝5个字节到edi指向的内存中。由于esi指向NtOpenFile原地址,edi指向OldNtOpenFile首地址,所以这四句的意思为把原NtOpenFile的前5个字节拷贝到OldNtOpenFile前5个字节中。
     
      mov edx,offset MyNtOpenFile
      sub edx,eax                          
      sub edx,5                             
      mov byte ptr [eax],0e9h      
      xchg [eax+1],edx                  
这五句是在原NtOpenFile的首地址处构造一个jmp MyNtOpenFile。0E9h为jmp的二进制编码,0E9h后面的四个字节的值为:目标地址- 本jmp指令的下一条指令的地址;jmp MyNtOpenFile这条指令占5个字节。

这就是所谓的inline hook
2012-4-11 14:50
0
游客
登录 | 注册 方可回帖
返回
//