找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 16169|回复: 27

【紫水晶首发】VB小子玩转驱动程序(4):HOOK

 火... [复制链接]

6

主题

196

回帖

0

精华

铜牌会员

菜鸟

积分
52
发表于 2010-1-24 17:58:49 | 显示全部楼层 |阅读模式
本帖最后由 xiaoly99 于 2014-7-10 20:41 编辑

  

VB小子玩转驱动程序(4):HOOK
   


作者:0.0



0.0 导论

Ring3:

Private Sub Command1_Click()
    On Error Resume Next
    Dim TID As Long
    TID = CLng(Text1.Text)
    With DrvController
        Call .IoControl(.CTL_CODE_GEN(&H801), VarPtr(TID), 4, 0, 0)'这句代码将TID以&H801的IOCTL代码传入Ring0 以SysEnter进入
    End With                                                                                                                                                                                      
    Command1.Enabled =  False                                                                                                                                                      
End Sub                                                                                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------
Ring0:                                                                                                                                                                                             
DispatchIoctl----------Switch(IOCTLCode)----------Case(StartProt)
memcpy(&mytid,pIoBuffer,sizeof(mytid)); //将Ring3传来的TID的地址写入mytid变量
PsLookupThreadByThreadId((HANDLE)mytid,&myet)) //得到EThread
myep=IoThreadToProcess(myet); //得到EProcess

*(PULONG)((ULONG)myep+0x248)=0x4; //设置进程已退出
*(PULONG)((ULONG)myet+0x248)=0x10; //设置线程为系统线程
HookMmIsAddressValid(); //Hook函数
HookKeAttachProcess() //Hook函数
这里特别讲一下两个函数
第一个函数的作用是判断一个地址是否有效 而冰刃是也是用MmIsAddressValid来判断地址有效性
小知识1:冰刃还Hook了KeBugCheckEx确保结束DKOM了BreakOnTermination标志的进程不会蓝屏 不过Hook KeBugCheck2会更好些 但是KeBugCheck2是未导出函数 所以要搜索函数或者暴搜内核 这个下篇讲
第二个函数的作用是进入进程 ReadProcessMemory和WriteProcessMemory都是依靠KeAttachProcess
但是没有Hook KeStackAttachProcess这个函数,所以可以通过某些YY方法PspExitProcess
最好是Hook KiAttachProcess+0x5 这样好一些
-----------------------------------------------------------
现在讲如何Hook
先关内存写保护 就是对cr0寄存器的操作

在计算jmp偏移量
偏移量的计算公式是 : 跳转地址 - 当前地址 - 5
然后RtlCopyMemory把偏移Copy到一个数组中
还未Hook前的Byte数组是这样的 0xE9,0,0,0,0
填入后提高IQRL到DPC级别 注意:DPC不是一个级别 而是指和DPC一样的优先级
再获取函数地址 用RtlCopyMemory把Byte数组Copy到函数中
再降低IQRL到Passive级
关内存写保护
两个实例 inlineNtOpenProcess.rar (79.6 KB, 下载次数: 8250) inlineObReferenceObjectByHandle.rar (157.26 KB, 下载次数: 8037)


1.1 准备
获取未导出函数的准备是WinDbg和适用于系统的符号包,可以根据下列表格下载 :下载的统一为Xp x86版本,其它版本请自行搜索

XPSP0[149MB]http://msdl.microsoft.com/download/symbols/packages/windowsxp/windowsxp.x86.fre.rtm.symbols.exe
XPSP1[172MB]http://msdl.microsoft.com/download/symbols/packages/windowsxp/xpsp1sym_x86.exe

XPSP2[195MB]http://msdl.microsoft.com/download/symbols/packages/windowsxp/WindowsXP-KB835935-SP2-slp-Symbols.exe

WinDbg[17M]http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.11.1.404.msi

1.2 查找特征码
假设符号包安装在d:\Symbol,那么打开Windbg,"lkd>"命令行后输入命令:

.sympath SRV*d:\Symbol*http://msdl.microsoft.com/download/symbols
!sym noisy
!lmi nt
.reload /f nt
现在可以用u 函数名获得未导出函数地址了,但是在我们的驱动函数中不可以直接调用或Hook未导出函数,我们加载好符号先测试一下,输入命令"u KeBugCheck2"
lkd> u KeBugCheck2 l 5
nt!KeBugCheck2:
804f9226 8bff            mov     edi,edi
804f9228 55              push    ebp
804f9229 8bec            mov     ebp,esp
804f922b 81ecc8030000    sub     esp,3C8h
804f9231 a1c0be5480      mov     eax,dword ptr [nt!__security_cookie (8054bec0)]
在本机上,KeBugCheck2的地址为804f9226,但在驱动中怎么获取这个地址呢?可以搜索导出函数KeBugCheckEx
lkd> u kebugcheckex  l 10
nt!KeBugCheckEx:
804f9caa 8bff            mov     edi,edi
804f9cac 55              push    ebp
804f9cad 8bec            mov     ebp,esp
804f9caf 6a00            push    0
804f9cb1 ff7518          push    dword ptr [ebp+18h]
804f9cb4 ff7514          push    dword ptr [ebp+14h]
804f9cb7 ff7510          push    dword ptr [ebp+10h]
804f9cba ff750c          push    dword ptr [ebp+0Ch]
804f9cbd ff7508          push    dword ptr [ebp+8]
804f9cc0 e861f5ffff      call    nt!KeBugCheck2 (804f9226)
804f9cc5 5d              pop     ebp
804f9cc6 c21400          ret     14h
804f9cc0的位置调用了KeBugCheck2,从中我们可以知道特征码是e8########5d
这里是61f5ffff,为什么不是804f9226?因为它是一个偏移值,我们先把它以ULONG的形式读出:fffff561,这里用到一个公式:当前地址+偏移量+5=Call地址
804f9cc0 + fffff561 + 5 = 804f9226 = KeBugCheck2
------------------------------------------------------------------------------------


2.1 驱动搜索

#include "LDasm.h"

PVOIDGetFunctionAddr(IN PCWSTR FunctionName){UNICODE_STRINGUniCodeFunctionName;RtlInitUnicodeString(&UniCodeFunctionName,FunctionName);returnMmGetSystemRoutineAddress(&UniCodeFunctionName);}
VOID GetKeBugCheck2()

{


UCHAR *cPtr, *pOpcode;


ULONG Length;


for (cPtr =(PUCHAR)GetFunctionAddr(L"KeBugCheckEx");cPtr <(PUCHAR)GetFunctionAddr(L"KeInsertQueueApc") + 32;cPtr += Length)


{



Length = SizeOfCode(cPtr, &pOpcode);



if (!Length) break;



if (*pOpcode == 0xE8 && *(PUSHORT)(pOpcode + 5) == 0x5D)



{




KeBugCheck2 =  (KEBUGCHECK2)(*(PULONG)(pOpcode+1)+(ULONG)cPtr + 5);//注意 为什么有两个KeBugCheck2?因为C是大小写敏感的




break;



}


}

}//此段代码选自IceFreak->Kill.h

2.2 动态调用未导出函数

先声明类型(typedef):typedef VOID (*KEBUGCHECK2)(
IN ULONGBugCheckCode,
    IN ULONG_PTR  BugCheckParameter1,
    IN ULONG_PTR  BugCheckParameter2,
    IN ULONG_PTR  BugCheckParameter3,
    IN ULONG_PTR  BugCheckParameter4,
    IN ULONG_PTR  BugCheckParameterNew
    );
再声明函数:KEBUGCHECK2 KeBugCheck2 = NULL;
这样就可以调用了,不过在调用之前先Call一次GetKeBugCheck2函数,以便获得KeBugCheck2的地址
2.3 Hook
知道地址后就可以向普通的函数一样Hook,注意:HookFastCall类型的函数是,要注意堆栈平衡,最好不要直接在其内部调用外部函数和全局变量,代码如下:
pushfd
pushad
call MyFuction
popad
popfd

评分

参与人数 4水晶币 +80 +22 收起 理由
syfy + 2 第2个例子 inline hook KeInserQueueAPC
阿杰 + 20
HoviDelphic + 40
ok100fen + 20 + 20 原来这么多高手~

查看全部评分

90

主题

473

回帖

2

精华

钻石会员

积分
3261
发表于 2010-1-24 19:03:17 | 显示全部楼层
这里的氛围很好
希望继续

38

主题

199

回帖

2

精华

钻石会员

积分
3408
发表于 2010-1-25 02:06:27 | 显示全部楼层
本帖最后由 HoviDelphic 于 2010-1-25 02:08 编辑
第一个函数的作用是判断一个地址是否有效 而冰刃是用Hook KeBugCheckEx来判断地址有效性 如果在Ring0中读或写非法地址就会调用KeBugCheck蓝屏
xiaoly99 发表于 2010-1-24 17:58


是么?貌似冰刃hook KeBugCheckEx只是为了防止在杀标志为BreakOnTermination的进/线程时蓝屏。
如果附件无法下载,请点击这里

6

主题

196

回帖

0

精华

铜牌会员

菜鸟

积分
52
 楼主| 发表于 2010-1-25 09:25:36 | 显示全部楼层
是么?貌似冰刃hook KeBugCheckEx只是为了防止在杀标志为BreakOnTermination的进/线程时蓝屏。
HoviDelphic 发表于 2010-1-25 02:06

已经改正了

3

主题

50

回帖

0

精华

银牌会员

积分
444
发表于 2010-1-25 11:49:53 | 显示全部楼层
学习学习,再学习...
我是晶晶

9

主题

210

回帖

0

精华

初来乍到

积分
904
发表于 2010-1-26 10:51:05 | 显示全部楼层
LZ怎么水晶狂飚啊!!?!?!?!:funk:
本网站最菜的人 该用户已被删除
发表于 2010-1-29 21:03:55 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
本网站最菜的人 该用户已被删除
发表于 2010-1-29 21:05:50 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
本网站最菜的人 该用户已被删除
发表于 2010-1-29 21:06:42 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

38

主题

199

回帖

2

精华

钻石会员

积分
3408
发表于 2010-1-29 21:49:54 | 显示全部楼层
我用很通俗的语言解释了ssdt/sssdt hook。
如果附件无法下载,请点击这里

0

主题

12

回帖

0

精华

初来乍到

积分
5
发表于 2010-1-30 22:22:29 | 显示全部楼层
收藏下,慢慢看!

0

主题

12

回帖

0

精华

初来乍到

积分
5
发表于 2010-1-30 22:22:59 | 显示全部楼层
收藏下,慢慢看!
本网站最菜的人 该用户已被删除
发表于 2010-2-4 20:48:41 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

0

主题

9

回帖

0

精华

铜牌会员

积分
60
发表于 2010-2-13 16:06:07 | 显示全部楼层
本帖最后由 syfy 于 2010-2-13 17:48 编辑

你的顺序是不是反了,为什么不是先从导出的函数开始寻址呢

38

主题

199

回帖

2

精华

钻石会员

积分
3408
发表于 2010-2-14 04:17:57 | 显示全部楼层
你的顺序是不是反了,为什么不是先从导出的函数开始寻址呢
syfy 发表于 2010-2-13 16:06


你说谁的顺序反了?
另外syfy=syf吗?
如果附件无法下载,请点击这里

0

主题

9

回帖

0

精华

铜牌会员

积分
60
发表于 2010-2-14 12:12:19 | 显示全部楼层
不等不等,我可不是syf大牛,我是新手

38

主题

199

回帖

2

精华

钻石会员

积分
3408
发表于 2010-2-14 13:38:29 | 显示全部楼层
哦,原来syf是大牛啊,一同膜拜大牛。“syf大牛”在此网站的账号是“本网站最菜的人”。
如果附件无法下载,请点击这里
本网站最菜的人 该用户已被删除
发表于 2010-2-15 21:01:16 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2010-2-16 13:46:50 | 显示全部楼层
新年快乐!

支持一下.
我就是嗷嗷叫的老马了......

9

主题

210

回帖

0

精华

初来乍到

积分
904
发表于 2010-2-17 14:28:16 | 显示全部楼层

9

主题

210

回帖

0

精华

初来乍到

积分
904
发表于 2010-2-17 14:32:13 | 显示全部楼层
我觉得应该先说下普通的APIHOOK,
首先说下用PB写DLL用VB写注入 如何HOOKAPI
起飞就是驱动级HOOK了。
不说了  回学校整去!

0

主题

9

回帖

0

精华

铜牌会员

积分
60
发表于 2010-2-19 18:24:20 | 显示全部楼层
dll注入确实是最有效率和最安全的方法,ssdt hook已经老掉牙了

6

主题

196

回帖

0

精华

铜牌会员

菜鸟

积分
52
 楼主| 发表于 2010-2-28 12:21:51 | 显示全部楼层
dll注入确实是最有效率和最安全的方法,ssdt hook已经老掉牙了
syfy 发表于 2010-2-19 18:24


ssdt hook在内核层是稳定的方法 还没有老掉牙呢
dll注入的话在Ring0 Hook OBORH就可以让你不能注入了

0

主题

7

回帖

0

精华

初来乍到

积分
12
发表于 2010-3-2 13:20:16 | 显示全部楼层
ssdt hook在内核层是稳定的方法

0

主题

8

回帖

0

精华

铜牌会员

积分
54
发表于 2011-3-21 23:43:41 | 显示全部楼层
确实不错,学习了,谢谢了

9

主题

39

回帖

0

精华

铜牌会员

积分
67
发表于 2011-5-17 17:59:01 | 显示全部楼层
学习

0

主题

4

回帖

0

精华

初来乍到

积分
16
发表于 2012-3-20 17:02:46 | 显示全部楼层
刚刚来学习了,

1

主题

48

回帖

0

精华

金牌会员

积分
978
发表于 2012-6-23 18:11:23 | 显示全部楼层
好文章{:soso_e102:}学习一下
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表