;filename:shadow_ssdt_hook_2.asm
;made by correy
;QQ:112426112
;Email:leguanyuan at 126 dot com
;HomePage:http://correy.webs.com
;不足之处敬请指点
;顺便说一下编译方式:
;rc me.rc >error.txt ;这个可有可无。
;ml /nologo /c /coff /Zp4 shadow_ssdt_hook_2.asm >>error.txt
;link /nologo /driver /base:0x10000 /align:16 /out:sys.sys /subsystem:native /section:.text,rw /MERGE:.rdata=.text shadow_ssdt_hook_2.obj me.res>>error.txt
;如果想得到调试信息,在ml命令行中加入,/Cp /Zi,在link中加入 /DEBUG /DEBUGTYPE:CV.不过本人,不喜欢这两个参数。很少使用。
;出错信息在error.txt中查看。
.386
.model flat,stdcall
option casemap:none
include ntstatus.inc
include ntddk.inc
include ntoskrnl.inc
includelib ntoskrnl.lib
.code
GetServiceDescriptorTableShadowAddress proc uses esi edi ebx
;本函数摘自kmdkit。本人加一些注释,及自己的理解。
local dwThreadId:DWORD
xor ebx, ebx ; = NULL. Assume ServiceDescriptorTableShadow will be not found
mov eax, KeServiceDescriptorTable
mov esi, [eax]
; Find KTHREAD.ServiceTable field
; For non-GUI threads this field == KeServiceDescriptorTable
; and it points to ServiceDescriptorTable
; For GUI threads
; ServiceDescriptorTableShadow
invoke KeGetCurrentThread ;得到KTHREAD的结构。
mov edi, 200h-4;1;200h-4 ;为什么是这个数呢?换成1,inc edi呢?
.while edi
.break .if dword ptr [eax][edi] == esi ;经查资料0x0e0 ServiceTable : Ptr32 Void。
dec edi;inc edi;dec edi
.endw
.if edi != 0
; edi = offset to ServiceTable field in KTHREAD structure
mov dwThreadId, 080h ;为什么是这个数呢?
.while dwThreadId < 400h ;为什么是这个数呢?
push eax ; reserve DWORD on stack
invoke PsLookupThreadByThreadId, dwThreadId, esp
pop ecx ; -> ETHREAD/KTHREAD
.if eax == STATUS_SUCCESS
push dword ptr [ecx][edi] ;这就是那个表,ssdt或者shadow.
fastcall ObfDereferenceObject, ecx
pop eax ;这儿就应该是返回值。
.if eax != esi ;如果这是一个GUI线程。就返回结束吧!
mov edx, MmSystemRangeStart ;这三行,得到的数是80000000,特殊的可能是c0000000h.
mov edx, [edx]
mov edx, [edx]
.if eax > edx ; some stupid error checking 真是!这里的判断太多余。
mov ebx, eax
;invoke DbgPrint, $CTA0("FindShadowTable: Found in thread with ID: %X\n"), dwThreadId
.break
.endif
.endif
.endif
add dwThreadId, 4 ;为什么加4呢?
.endw
.endif
mov eax, ebx
ret
GetServiceDescriptorTableShadowAddress endp
y dd 0
szNtUserFindWindowEx db "NtUserFindWindowEx is called!",0
myhookapi proc x1,x2,x3,x4,x5
;要hook的是NtUserFindWindowEx
;要加啥功能,就在这里设置吧!
;本人只显示一个信息。
invoke DbgPrint,addr szNtUserFindWindowEx
push x5
push x4
push x3
push x2
push x1
call y
ret
myhookapi endp
szcsrss db "csrss.exe",0
DriverEntry proc pDriverObject: PDRIVER_OBJECT,pRegistryPath: PUNICODE_STRING
local temp:dword
local x:dword
pushad
invoke IoGetCurrentProcess ;其实这段代码还可以再优化。那就交给看官你吧!
lea eax,[eax+0b8h] ;windwos 7-32下用0b8h,widnows xp-32下用88h
mov esi,dword ptr [eax]
.while esi != 0
lea edi,[esi-0b8h] ;windwos 7-32下用0b8h,widnows xp-32下用88h
mov x, edi
lea eax,[edi+16ch] ;windwos 7-32下用16ch,widnows xp-32下用174h
invoke _strnicmp,eax, addr szcsrss,9
.if eax == 0
.break
.endif
mov esi,dword ptr [esi]
.endw
invoke KeAttachProcess,x
invoke GetServiceDescriptorTableShadowAddress
mov eax, [eax+16]
add eax,18ch*4 ;要挂钩的函数是:NtUserFindWindowEx,windwos 7-32下用18ch,widnows xp-32下用17ah。
;无法用MmGetSystemRoutineAddress函数获得。
;找不到相关的资料,只能调试反汇编了,但还得有办法。
mov esi, [eax]
mov y, esi
push eax
cli
mov eax,cr0
mov temp,eax
and eax,0fffeffffh
mov cr0,eax
pop eax
mov dword ptr[eax],offset myhookapi
push eax
mov eax,temp
mov cr0,eax
sti
pop eax
invoke KeDetachProcess
popad
mov eax,0
ret
DriverEntry endp
end DriverEntry
;made at 2011.06.30
;没有卸载函数,你自己找工具卸载吧!或者手动卸载(下次起效)。
没有评论:
发表评论