首页
社区
课程
招聘
[原创]某驱动的内核调试检测学习内核调试引擎加载机制
发表于: 2014-3-29 02:13 74530

[原创]某驱动的内核调试检测学习内核调试引擎加载机制

2014-3-29 02:13
74530

作者:Tiany
QQ:304400230

如果大家调试过某驱动 就知道新版本的驱动已经改了很多 很主要的一点就是只要我们在boot.ini 里加入
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows 2003  - debug" /fastdetect /noguiboot /debug /debugport=com1 /baudrate=115200 
启动游戏的时候就会导致蓝屏 



这次测试 我只是加入了 /debug /debugport=com1    并没有开启 windbg 也产生了 系统错误 0x99999999
可以得出一个结论 就是某驱动对我们的启动模式有检测(地球人都知道)
首先我们来了解一下 加入了 /debug /debugport=com1 对系统启动的时候做了些什么操作


所有命令详情请查看微软官方说明
http://msdn.microsoft.com/en-us/library/windows/hardware/ff556253(v=vs.85).aspx

实际上在windows 内核初始化会对CPU做必要的初始化工作 包括16位实模式切换到32位保护模式 启动分页机制等 然后通过启动配置信息(Boot.ini 或 BCD)得到windows系统的系统目录并加装系统内核文件 而我们加入了 /debug ...这些 就是告诉了系统要初始化内核调试引擎

上图表示了windows的初始化逻辑图

而内核调试引擎初始化 主要在 KdInitSystem 这个函数里 
  第一次调用KdInitSystem
  从图18-10可以看到,系统在启动过程中会两次调用内核调试引擎的初始化函数,KdInitSystem。第一次是在系统内核开始执行后由入口函数KiSystemStartup调用。
  调用时,KdInitSystem会执行以下动作。
  初始化调试器数据链表,使用变量KdpDebuggerDataListHead指向这个链表。
  初始化KdDebuggerDataBlock数据结构,该结构包含了内核基地址、模块链表指针、调试器数据链表指针等重要数据,调试器需要读取这些信息以了解目标系统。
  根据参数指针指向的LOADER_PARAMETER_BLOCK结构寻找调试有关的选项,然后保存到变量中(见下文)。
  对于XP之后的系统,调用KdDebuggerInitialize0来对通信扩展模块进行阶段0初始化。对于XP之前的版本,调用KdPortInitialize来初始化COM端口。如果使用的是串行通信方式,那么KDCOM中的KdDebuggerInitialize0函数会调用模块内的KdCompInitialize函数来初始化串行口。不论是KdPortInitialize还是KdCompInitialize函数,成功初始化COM口后,都会设置HAL模块中所定义的KdComPortInUse全局变量,记录下已被内核调试使用的COM端口,此后的串行口驱动程序(serial.sys)会检查这个变量,并跳过用于调试用途的串行端口,因此,在目标系统的设备管理器中我们看不到用于内核调试的串行端口。
  此外,KdInitSystem会初始化以下全局变量:
  KdPitchDebugger:布尔类型,用来标识是否显式抑制内核调试。当启动选项中包含/NODEBUG选项时,这个变量会被设置为真。
  KdDebuggerEnabled:布尔类型,用来标识内核调试是否被启用。当启动选项中包含/DEBUG或/DEBUGPORT而且不包含/NODEBUG时,这个变量会被设置为真。
  KiDebugRoutine:函数指针类型,用来记录内核调试引擎的异常处理回调函数,当内核调试引擎活动时,它指向KdpTrap函数,否则指向KdpStub函数。
  KdpBreakpointTable:结构数组类型,用来记录代码断点,每个元素为一个BREAKPOINT_ENTRY结构,用来描述一个断点,包括断点地址。
  对于Windows XP之前的版本,还会初始化如下变量。
  KdpNextPacketIdToSend:整数类型,用来标识下一个要发送的数据包ID,KdInitSystem将这个变量初始化为0x80800000 | 0x800,即INITIAL_PACKET_ID(初始包)或SYNC_PACKET_ID(同步包)。
  KdpPacketIdExpected:整数类型,用来标识期待收到的下一个数据包ID ,初始化为0x80800000,即INITIAL_PACKET_ID。
  对于XP和之后的系统,当使用串行通信方式时,在KDCOM.DLL中定义了两个同样用途的变量KdCompNextPacketIdToSend和KdCompPacketIdExpected。
  对于Windows Vista,会初始化如下变量。
  KdAutoEnableOnEvent:布尔类型,如果调试设置中的启动策略为AUTOENABLE,则设为真。
  KdIgnoreUmExceptions:布尔类型,代表了处理用户态异常的方式,如果调试设置中的启动策略包含/noumex,则设为真,含义是忽略用户态异常。
关于KdInitSystem第一次被调用,还有如下两点值得说明。第一,只有当0号CPU执行KiSystemStartup函数时才会调用KdInitSystem,所以它不会被KiSystemStartup多次调用。第二,不管系统是否启用内核调试,调用都会发生。

当我们启动/debug模式启动时候 
KdPitchDebugger = FALSE;
KdDebuggerEnabled = TRUE;
KiDebugRoutine = KdpTrap;

0: kd> dd KdPitchDebugger
808948a8  00000000 00000000 00000000 00000000
0: kd> dd KdDebuggerEnabled
808a5b90  00000001 00000000 00000014 00000000

0: kd> dd KiDebugRoutine 
8089aa8c  809cf27a fffff000 0000000f fffff000

0: kd> u 809cf27a 
nt!KdpTrap:
809cf27a 8bff            mov     edi,edi
809cf27c 55              push    ebp
809cf27d 8bec            mov     ebp,esp
0: kd> ed KdPitchDebugger 1
0: kd> dd KdPitchDebugger
808948a8  00000001 00000000 00000000 00000000
//恢复KiDebugRoutine  = KdpStub
0: kd> u KdpStub
nt!KdpStub:
80824e88 8bff            mov     edi,edi
80824e8a 55              push    ebp
80824e8b 8bec            mov     ebp,esp
//得到KdpStub 的地址 0x80824e88 然后修改
0: kd> ed KiDebugRoutine 80824e88
//查看新的KiDebugRoutine  地址
0: kd> dd KiDebugRoutine
8089aa8c  80824e88 fffff000 0000000f fffff000
8089aa9c  0000000f ffffffff ffffffef ffffffff
0: kd> u 80824e88
nt!KdpStub:
80824e88 8bff            mov     edi,edi
80824e8a 55              push    ebp
80824e8b 8bec            mov     ebp,esp
0: kd> ed KdDebuggerEnabled 0
0: kd> dd KdDebuggerEnabled 
808a5b90  00000000 00000000 00000014 00000000
808a5ba0  00000000 00000000 00000000 00000000

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
  • 1.jpg (84.70kb,39次下载)
  • 2.jpg (167.49kb,346次下载)
  • 3.jpg (123.09kb,153次下载)
  • 4.jpg (108.86kb,107次下载)
  • 5.jpg (117.59kb,62次下载)
  • 6.jpg (278.22kb,57次下载)
  • 7.jpg (71.34kb,12次下载)
  • 8.jpg (151.22kb,124次下载)
  • 9.jpg (408.75kb,41次下载)
  • 10.jpg (157.71kb,233次下载)
收藏
免费 7
支持
分享
最新回复 (111)
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
0x99999999 哎
2014-3-29 02:43
0
雪    币: 257
活跃值: (67)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
谢谢分享,占个座
2014-3-29 05:01
0
雪    币: 371
活跃值: (72)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
0x99999999~
2014-3-29 05:53
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
5
不错,我要学习下,谢谢分享
2014-3-29 08:43
0
雪    币: 506
活跃值: (318)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
强大,膜拜+学习
2014-3-29 10:03
0
雪    币: 124
活跃值: (461)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
非常好,感谢。、
2014-3-29 10:08
0
雪    币: 135
活跃值: (76)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好文+膜拜。
2014-3-29 10:13
0
雪    币: 265
活跃值: (74)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
搞内核调试的都是专家!膜拜
2014-3-29 12:46
0
雪    币: 623
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
mark
2014-3-29 13:07
0
雪    币: 9941
活跃值: (2143)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
直接从操作系统入手解决

楼主天赋异禀,将来必成器
2014-3-29 13:17
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
我靠,我就是搞这个破东西搞了个半死啊,lz牛B,吊炸天啊
2014-3-29 14:49
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
很不错的分析帖子
2014-3-29 16:46
0
雪    币: 199
活跃值: (64)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
高手啊 膜拜ing
2014-3-29 19:14
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
15
tp已更新 ╮(╯▽╰)╭
2014-3-29 19:23
0
雪    币: 346
活跃值: (129)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
16
我菜鸟一枚  看雪上真正的大牛多啊
2014-3-29 19:24
0
雪    币: 346
活跃值: (129)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
17
....... 不知道等我老了 会成器么 哈哈
2014-3-29 19:26
0
雪    币: 199
活跃值: (64)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
能 问下 为什么要 hook这个 IoAllocateMdl 函数吗  求指教
2014-3-29 20:38
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
大牛是怎样炼成的?
2014-3-29 21:02
0
雪    币: 346
活跃值: (129)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
20
文章上写清楚了啊  定位到某驱动的代码关键位置后 发现他后面的流程是 是获取到 KdEnteredDebugger 地址 然后创建MDL   然后判断用MDL返回的指针 来判断 KdEnteredDebugger 的值
判断部分已经VM了 不好跟
2014-3-29 21:11
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
呵呵,楼主分析很到位!!!辛苦了!
2014-3-29 22:27
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
呵呵,看了下楼主的分析,我估计下次企鹅会自己模拟KD_PACKET包,来判断有没有调试器接收,这可能行很大,希望那帮2B就会这样做。。。。。。
2014-3-29 22:49
0
雪    币: 346
活跃值: (129)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
23
KD_PACKET 包 我想他也会先检查调试引擎开启了没
或者我们开启了调试引擎 不开windbg 呢? 这样也可以慢慢排除一些他检测的地方

反正每次开源 都会给下次分析带来更大的难度
2014-3-29 23:13
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
等那天哥心血来潮,搞个硬件调试器来玩玩,看看企鹅怎么检测。。。。
2014-3-29 23:17
0
雪    币: 199
活跃值: (64)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
恩 是我没看仔细  ,再问一下楼主 你的 KdEnteredDebugger 断点是怎么下的   

ba r1 KdEnteredDebugger 断不下来  直接蓝屏了
2014-3-29 23:21
0
游客
登录 | 注册 方可回帖
返回
//