;filename:shadow_ssdt_hook.asm
;made by correy
;QQ:112426112
;Email:leguanyuan at 126 dot com
;HomePage:http://correy.webs.com
;不足之处敬请指点
;在实机上有时候会蓝屏,可能是AttachProcess引起的吧!
;但这是极个别的情况下,打开anti-rootlit-tools时。
;更有趣的是有些工具,却发现不了这个hook.
;顺便说一下编译方式:
;rc me.rc >error.txt ;这个可有可无。
;ml /nologo /c /coff /Zp4 shadow_ssdt_hook.asm >>error.txt
;link /nologo /driver /base:0x10000 /align:16 /out:sys.sys /subsystem:native /section:.text,rw /MERGE:.rdata=.text shadow_ssdt_hook.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
include Strings.mac
.code
y dd 0
prs db 18 dup (0) ;KAPC_STATE STRUCT
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, 1;200h-4 ;为什么是这个数呢?换成1,inc edi呢?
.while edi
.break .if dword ptr [eax][edi] == esi ;经查资料0x0e0 ServiceTable : Ptr32 Void。
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
szeax db "eax == %x",0
szNtUserFindWindowEx db "NtUserFindWindowEx is called",0
myhookfun proc x1,x2,x3,x4,x5
;这个函数是:NtUserFindWindowEx。
;要获取与附加一些功能,就在这里设置吧!
;我就在这里打印一个信息吧!
invoke DbgPrint,addr szNtUserFindWindowEx
push x5
push x4
push x3
push x2
push x1
call y
push eax ;此三行是检测,可以不要。
invoke DbgPrint,addr szeax,eax
pop eax
ret
myhookfun endp
correy db "ok",0
szcsrss db "csrss.exe",0
DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
local tem:dword
local e:dword
local z:dword
local x:dword
push eax;另一种办法是mdl,甚么的。
;cli
mov eax, cr0;
mov tem, eax;
and eax, 0FFFEFFFFh;
mov cr0, eax;
pop eax;
;int 3
invoke PsGetCurrentProcess
mov edx,[eax+88h] ;跳过自身,也就是第一个。可以确定这个不是?是system?还有一个是smss.exe
.while edx!=0
mov e,edx
mov esi,edx
add esi,0ech;174h
mov z,edx
invoke _strnicmp,esi, addr szcsrss,9 ;这个函数的调用方式像c/c++.
.if eax == 0
mov edx,z
sub edx,88h
invoke KeAttachProcess,edx
;invoke KeStackAttachProcess,edx,addr prs ;微软推荐用这个函数。
invoke DbgPrint,addr correy ;检测信息,多余的。
;int 3
mov edx,z ;这个变量是多余的,主要用来是查看值的。
.break ;这一句其实是个调转指令。jmp.
.endif
mov edx,dword ptr [e]
mov edx,[edx]
.endw
;以上的代码是确保下面的代码正确运行。有好多多余的变量,与垃圾的指令,下面也是。
invoke GetServiceDescriptorTableShadowAddress
mov eax,[eax+16]
add eax,17ah*4 ;无法用MmGetSystemRoutineAddress函数获得。 hook的是NtUserFindWindowEx。
;找不到相关的资料,只能调试反汇编了,但还得有办法。
;int 3
mov esi,dword ptr [eax] ;此句运行失败。
mov x,esi ;这两行多余不?只为下面一行运行正确。
mov ecx,x
mov y,ecx;esi ;存储要hook的函数的原始的地址。他妈的,这一句也会运行失败。
mov dword ptr [eax],offset myhookfun
push eax; 不用说了吧!
mov eax,tem
mov cr0, eax;
pop eax;
;sti
mov eax, 0
ret
DriverEntry endp
end DriverEntry
;made at 2011.06.25
;没有卸载函数,你找工具卸载吧!
没有评论:
发表评论