一个纯汇编写的Hook API的例子!!!这里只列出驱动程序,控制程序这里不列出了! 
有不好的地方,还请各位多见谅!也希望大家有好的建议能提出来! 
纯汇编写的,还望大家多多支持哦!

.386
.model flat,stdcall
option casemap:none
include ntstatus.inc
include ntddk.inc
include w2kundoc.inc
include hal.inc
include ntoskrnl.inc
includelib hal.lib
includelib ntoskrnl.lib
.const
szdevicename dw '\','D','e','v','i','c','e','\','z','h','t','j','i','a',0
szconnect dw '\','?','?','\','l','s','z','h',0
.data?
sz1 UNICODE_STRING <?>
sz2 UNICODE_STRING <?>
scr0 dd ?
old dd ?
padd dd ?
.code
func proc p1,p2,p3,p4,p5,p6,p7,p8,p9
  xor eax,eax
  ret
func endp

workit proc
  pushad
  cli
  mov eax,cr0
  mov scr0,eax
  and eax,0fffeffffh
  mov cr0,eax
  mov eax,KeServiceDescriptorTable
  mov eax,[eax]
  mov eax,[eax]
  add eax,30h*4h
  mov padd,eax
  mov ecx,[eax]
  mov old,ecx
  lea ecx,func
  mov [eax],ecx
  mov eax,scr0
  mov cr0,eax
  sti
  cld
  stosd
  popad
  mov eax,1000h
  ret
workit endp
makeit proc pdevice,pirp
  local status,dwbytesret
  pushad
  and dwbytesret,0
  mov esi,pirp
  mov edi,[esi+60h]
  mov ecx,[edi+0ch]
  sub ecx,22e000h
  or ecx,ecx
  jnz @1
  mov ecx,[edi+4h]
  sub ecx,1000h
  or ecx,ecx
  jnz @2
  mov ecx,[edi+8h]
  sub ecx,1000h
  or ecx,ecx
  jnz @2
  mov edi,[esi+0ch]
  invoke workit
  mov dwbytesret,eax
  and status,0
  jmp @3
@2:
  mov status,STATUS_BUFFER_TOO_SMALL
@1:
  mov status,STATUS_INVALID_DEVICE_REQUEST
@3:
  push status
  pop [esi+18h]
  push dwbytesret
  pop [esi+1ch]
  invoke IoCompleteRequest,pirp,IO_NO_INCREMENT
  popad
  mov eax,status
  ret
makeit endp
createclose proc pdevice,pirp
  mov eax,pirp
  xor ecx,ecx
  mov [eax][18h],ecx
  mov [eax][1ch],ecx
  invoke IoCompleteRequest,pirp,IO_NO_INCREMENT
  xor eax,eax
  ret
createclose endp

driverunload proc pdri
  cli
  mov eax,cr0
  mov scr0,eax
  and eax,0fffeffffh
  mov cr0,eax
  mov edi,padd
  mov eax,old
  cld
  stosd
  mov eax,scr0
  mov cr0,eax
  sti
  invoke IoDeleteSymbolicLink,offset sz2
  mov eax,pdri
  invoke IoDeleteDevice,[eax+04h]
  ret
driverunload endp
driverentry proc pdri,pregpath
  local pdevice,status
  mov status,STATUS_DEVICE_CONFIGURATION_ERROR
  invoke RtlInitUnicodeString,offset sz1,offset szdevicename
  invoke RtlInitUnicodeString,offset sz2,offset szconnect
  invoke IoCreateDevice,pdri,0,offset sz1,FILE_DEVICE_UNKNOWN,0,0,addr pdevice
  .if !eax
    invoke IoCreateSymbolicLink,offset sz2,offset sz1
    .if !eax
      mov eax,pdri
      mov [eax][38h+4h*IRP_MJ_CREATE],offset createclose
      mov [eax][38h+4h*IRP_MJ_CLOSE],offset createclose
      mov [eax][38h+4h*IRP_MJ_DEVICE_CONTROL],offset makeit
      mov [eax][34h],offset driverunload
      and status,0
    .else
      invoke IoDeleteDevice,pdevice
    .endif
  .endif
  mov eax,status
  ret
driverentry endp
end driverentry

  • 标 题:答复
  • 作 者:炉子
  • 时 间:2007-11-02 20:02

最近刚好在学ASM  试着注释下。。

引用:

.386
;扁平模式(使用线性地址),StdCall
.model flat,stdcall
option casemap:none
include 
ntstatus.inc
include ntddk.inc
include w2kundoc.inc
include hal.inc
include ntoskrnl.inc
includelib hal.lib
includelib ntoskrnl.lib
.const
;szdevicename=\Device\zhtjia\0
szdevicename dw 
'\','D','e','v','i','c','e','\','z','h','t','j','i','a',0
;szconnect=\??\lszh\0
szconnect dw 
'\','?','?','\','l','s','z','h',0
.data?
;一些变量
sz1 UNICODE_STRING <?>
sz2 UNICODE_STRING <?>
scr0 dd ?
old dd ?
padd dd ?
.code
;这函数啥都没做。。
func proc p1,p2,p3,p4,p5,p6,p7,p8,p9
;清理犯罪现场
  
xor eax,eax
;ret了
  
ret
func endp
;改SDT的
workit proc
  
;保存所有寄存器
  
pushad 
  
;改SDT之前的一系列常规操作
  
cli
  mov 
eax,cr0
  
mov scr0,eax
  
and eax,0fffeffffh
  
mov cr0,eax
  
;把KSDT放到eax中
  
mov eax,KeServiceDescriptorTable
  
;取eax指向的数值
  
mov eax,[eax]
  
;继续取
  
mov eax,[eax]
  
;现在eax是KiServiceTable了,30是系统服务的序号
  
add eax,30h*4h
  
;保存指针(做的有点废物),感觉没多大必要
  
mov padd,eax
  
;取旧的地址到ecx
  
mov ecx,[eax]
  
;保存旧的地址
  
mov old,ecx
  
;把func的地址放到ecx中???
  
lea ecx,func
  
;抹表~
  
mov [eax],ecx
  
;改SDT之后的一系列常规操作
  
mov eax,scr0
  
mov cr0,eax
  
sti
  
;DF = 0
  
cld
  
;mov es:[di],eax
  ;add es:[di],4
  ;????
  
stosd
  
;清理作案现场  恢复生态环境
  
popad
  
;return 1000??  乱七八糟。。
  
mov eax,1000h
  
ret
workit endp
;IRP_MJ_DEVICE_CONTROL
makeit proc pdevice,pirp
  
local status,dwbytesret
  
;保存所有寄存器
  
pushad
  
;没看出有什么意义
  
and dwbytesret,0
  
;从pirp中取东西。。偶就不查irp的结构了 -。-
  ;乱七八糟的偏移量。。。pass了。。
  
mov esi,pirp
  
mov edi,[esi+60h]
  mov 
ecx,[edi+0ch]
  sub 
ecx,22e000h
  
or ecx,ecx
  
jnz @1
  
mov ecx,[edi+4h]
  sub 
ecx,1000h
  
or ecx,ecx
  
jnz @2
  
mov ecx,[edi+8h]
  sub 
ecx,1000h
  
or ecx,ecx
  
jnz @2
  
mov edi,[esi+0ch]
  
;改SDT
  
invoke workit
  
mov dwbytesret,eax
  
;status = 0;
  
and status,0
  
jmp @3
@2
:
  mov 
status,STATUS_BUFFER_TOO_SMALL
@1
:
  mov 
status,STATUS_INVALID_DEVICE_REQUEST
@3
:
  
;?????压进去弹出来到底想干嘛-。-
  
push status
  
pop [esi+18h]
  push 
dwbytesret
  
pop [esi+1ch]
  invoke 
IoCompleteRequest,pirp,IO_NO_INCREMENT
  
;清理作案现场
  
popad
  
;return STATUS_SUCCESS; (STATUS_SUCCESS = 0)
  
mov eax,status
  
ret
makeit endp
;IRP_MJ_CREATE & IRP_MJ_CLOSE
createclose proc pdevice,pirp
  
;啥都没做 直接return
  
mov eax,pirp
  
xor ecx,ecx
  
mov [eax][18h],ecx
  
mov [eax][1ch],ecx
  
invoke IoCompleteRequest,pirp,IO_NO_INCREMENT
  
xor eax,eax
  
ret
createclose endp
;DriverUnload
driverunload proc pdri
  
cli
  
;改SDT之前的一系列常规操作
  
mov eax,cr0
  
mov scr0,eax
  
and eax,0fffeffffh
  
mov cr0,eax
  
;之前保存的指针
  
mov edi,padd
  
;旧的地址
  
mov eax,old
  
;????? 
  ;mov edi,eax ??? where is "mov edi,eax"????
  ;DF = 0
  
cld
  
;把eax扔到es:[di] 然后给es:[di]+=4
  ;不知道是干什么用的-。-
  
stosd
  
;常规操作
  
mov eax,scr0
  
mov cr0,eax
  
sti
  
;清理作案遗迹
  
invoke IoDeleteSymbolicLink,offset sz2
  
mov eax,pdri
  
invoke IoDeleteDevice,[eax+04h]
  
;ret了
  
ret
driverunload endp
;DriverEntry
driverentry proc pdri,pregpath
  
local pdevice,status
  
mov status,STATUS_DEVICE_CONFIGURATION_ERROR
  
;初始化Unicode_String
  
invoke RtlInitUnicodeString,offset sz1,offset szdevicename
  
invoke RtlInitUnicodeString,offset sz2,offset szconnect
  
;创建设备
  
invoke IoCreateDevice,pdri,0,offset sz1,FILE_DEVICE_UNKNOWN,0,0,addr pdevice
  
.if !eax 
    
;创建成功
    ;创建符号链接
    
invoke IoCreateSymbolicLink,offset sz2,offset sz1
    
.if !eax
      
;创建成功
      
mov eax,pdri
      
;设置派遣函数
      
mov [eax][38h+4h*IRP_MJ_CREATE],offset createclose
      
mov [eax][38h+4h*IRP_MJ_CLOSE],offset createclose
      
mov [eax][38h+4h*IRP_MJ_DEVICE_CONTROL],offset makeit
      
mov [eax][34h],offset driverunload
      
;status = 0
      
and status,0
    
.else
      
;创建失败
      ;删除之前创建的设备
      
invoke IoDeleteDevice,pdevice
    
.endif
  .endif
  mov 
eax,status
  
;return STATUS_SUCCESS;
  
ret
driverentry endp
end 
driverentry