聚合Vip网络社区 集合 HK共享吧 合购VIP等精品教程

 找回密码
 立即注册

QQ登录

只需一步,快速开始

关闭
聚合Vip社区
欢迎QQ或来电咨询
工作时间:周一至周五
AM9:00-PM22:00
淘宝店铺 淘宝皇冠店铺
论坛邀请码
查看: 1312|回复: 55

这两天对某P双机调试的学习及成果

  [复制链接]

1930

主题

22

听众

8875

积分

管理员

Rank: 9Rank: 9Rank: 9

  • TA的每日心情
    慵懒
    2015-8-3 14:17
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2015-8-18 16:49:17 |显示全部楼层

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    立即注册 已有账号?点击登录 或者 用QQ帐号登录

    x
    免责声明:以下资源由聚合VIP资源网整理提供,本资源来源于网络仅供用户学习交流之用,版权归资源方所有,本网站不承担任何法律风险,请自觉在下载学习后24小时内删除,不得用作商业用途;如果喜欢请购买正版资源。谢谢

    资料名称:这两天对某P双机调试的学习及成果

    此资料包含以下内容:
    首先感谢15PB各位老师给予我学习的帮助,通过在15PB的学习我也感觉到了自己的进步,算是打个广告,嘿嘿

    下面进入正题,新手首次发这种帖子,忘大神高抬贵手~

    关于*P双机调试的学习

    一:相关基础知识:

    根据软件调试这本书上说的,Windows启动过程如下图:


       系统一共调用了两次KdInitSystem()函数。

    第一次调用KdInitSystem会初始化一下全局变量:

    1.KdPitchDebugger:布尔类型,用来表示是否显式抑制内核调试。当启动选项中包含/DEBUG选项时,这个变量会被设置为真。
    2.KdDeBuggerEnable:布尔类型,用来表示内核调试是否被启用。当启动选项中包含/DEBUG或者/DEBUGPORT 而且不包含/NODEBUG时,这个变量会被设置为真。
    3.KiDebugRoutine:函数指针类型,用来记录内核调试引擎的异常处理回调函数,当内核调试引擎活动时,只想KdpTrap函数,否则指向KdpStub函数。
    4.KdpBreakpointTable:结构数组类型,用来记录代码断点,每一个元素为BREAKPOINT_ENTRY结构,用来描述一个断点,包括断点地址。
    5.
    可见KdDebuggerNotPresent也是一个判断是否是内核调试状态的标志。

    6.根据先前大牛写的这个帖子http://bbs.pediy.com/showthread.php?t=186091
    讲过KdEnteredDebugger也是一个判断是否为内核调试状态的标志。

    7.如果是内核调试状态,KiDebugRoutine指向KdpTrap函数,如果不是内核调试状态则指向KdpStub函数。

    综合上述,上述7点中的任何一点可以判断是否处于内核调试状态。

    二:接下来看一下*P对内核做的手脚。

    1.解决*P加载蓝屏的方法:

    根据上面提到的帖子上有给出解决方案,因为*P会访问KdEnteredDebugger的内容所以Hook IoAllocMdl,当访问KdEnteredDebugger的时候让他去访问其他始终为0的地址。具体可以看上面帖子的地址。

    2.解决完1之后,在虚拟机启动*P就不会蓝屏了,*P会有两个IAT Hook 两个通讯函数:KdSendPacket 和KdReceivePacket,反汇编一下这两个函数:



    解决方案:
    解析内核文件的PE结构,获取两个发送函数的地址,得到地之后把地址赋值给自己驱动的全局变量,然后用全局变量替换这两个jmp的地址。详见源码。
    3.众所周知,*P是调用KdDisableDebugger函数来禁止内核调试的。所以下断KdDisableDebugger。并将KdDisableDebugger的头部改成ret:



    运行*P后,Tp执行到KdDisableDebugger时就会断下来,单步走两步,发现了*P的第一个调用KdDisableDebugger的函数:

    直接jmp 到958aea2e

    这里的[edi] = 8416cd2c  ==> KdDebuggerEnabled

    这是上面7条中之一,检测是否是内核调试的标志。

    我尝试着将比较的0改为1,然后G~

    4.接下来进入了第二个调用KdDisableDebugger的地方:



    根据分析查看[958E4278h]这里存放的是KiDebugRoutine函数地址,

    [958E427Ch]存放的是KdpStub地址

    ,根据汇编可知:
    *P取出KiDebugRoutine地址,然后将KdpStub赋值给KiDebugRoutine,之后返回。

    解决方案:
    修改[958E427Ch]中的内容为KdpTrap地址

    Go起来~

    5.来到了第三处调用KdDisableDebugger的地方:


    这里这个CALL貌似是IAT HOOK 两个通讯函数的过程,因为push 的两个地址内容是


    正是IAT HOOK *P自己实现的函数。

    三:综合一下整个过程。重新整理一下所有解决方案。就是替换上述基础知识中的7个内核变量。

    首先打开IDA,搜索全部KdDeBuggerEnable和KdPitchDebugger调用:分别有下面几处:

    代码:
    //1. KeUpdateSystemTime////nt!KeUpdateSystemTime + 0x417://84096d65 33c9            xor     ecx, ecx//84096d67 8d542420        lea     edx, [esp + 20h]////nt!KeUpdateSystemTime + 0x41d ://84096d6b 803d2c1d188400  cmp     byte ptr[nt!KdDebuggerEnabled(84181d2c)], 0    <--ul_KdDebuggerEnabled_1//84096d72 7464            je      nt!KeUpdateSystemTime + 0x48a (84096dd8)//////2. KeUpdateRunTime////nt!KeUpdateRunTime + 0x149://840970c2 803d2c1d188400  cmp     byte ptr[nt!KdDebuggerEnabled(84181d2c)], 0    <--ul_KdDebuggerEnabled_2//840970c9 7412            je      nt!KeUpdateRunTime + 0x164 (840970dd)////3. KdCheckForDebugBreak////kd > uf kdcheckfordebugbreak//nt!KdCheckForDebugBreak://840970e9 803d275d148400  cmp     byte ptr[nt!KdPitchDebugger(84145d27)], 0    <--ul_KdPitchDebugger_1//840970f0 7519            jne     nt!KdCheckForDebugBreak + 0x22 (8409710b)////nt!KdCheckForDebugBreak + 0x9 ://840970f2 803d2c1d188400  cmp     byte ptr[nt!KdDebuggerEnabled(84181d2c)], 0    <--ul_KdDebuggerEnabled_3//840970f9 7410            je      nt!KdCheckForDebugBreak + 0x22 (8409710b)//////4. KdPollBreakIn////kd > uf KdPollBreakIn//nt!KdPollBreakIn://8409711f 8bff            mov     edi, edi//84097121 55              push    ebp//84097122 8bec            mov     ebp, esp//84097124 51              push    ecx//84097125 53              push    ebx//84097126 33db            xor     ebx, ebx//84097128 381d275d1484    cmp     byte ptr[nt!KdPitchDebugger(84145d27)], bl    <--ul_KdPitchDebugger_2//8409712e 7407            je      nt!KdPollBreakIn + 0x18 (84097137)////nt!KdPollBreakIn + 0x11://84097130 32c0            xor     al, al//84097132 e9d2000000      jmp     nt!KdPollBreakIn + 0xea (84097209)////nt!KdPollBreakIn + 0x18 ://84097137 885dff          mov     byte ptr[ebp - 1], bl//8409713a 381d2c1d1884    cmp     byte ptr[nt!KdDebuggerEnabled(84181d2c)], bl    <--ul_KdDebuggerEnabled_4//84097140 0f84c0000000    je      nt!KdPollBreakIn + 0xe7 (84097206)

    将几处分别替换成我们驱动中定义的全局变量就OK。详见源码~

    上述几处修改完毕之后,双机调试就可以正常下断了~

    最后说说此次更新后的*P,TesSafe.sys并不是真正的驱动,而是一个加载工具,它NEW出来一片新的内存,新内存才是真正功能函数。那么如何寻找真正的*P驱动呢,我用的方法是找到*P HOOK 的NtReadVirtualMemory 地址,然后向上搜索PE特征~



    补充一下获取*P真正基址的方法: HOOK KdDisableDebugger
    代码:
    __asm    {      push eax;      push ebx;      mov  eax, [ebp + 4];      add  eax, 4;      mov  ebx, [eax];      mov  ul_ret, ebx;      pop  ebx;      pop  eax;    }ul_TP_RelBaseAddress = ul_ret - 0x47277;DbgPrint("Tp 真正加载地址:%p\n", ul_TP_RelBaseAddress);

    因为KdDisableDebugger 不止一次会被调用,所以要做好处理~


    回复

    使用道具 举报

    14

    主题

    0

    听众

    549

    积分

    高级会员

    Rank: 4

    该用户从未签到

    发表于 2015-8-18 16:49:22 |显示全部楼层
    又抢到前排了。哈,不用怀疑,不用惊讶,你也没有看错!
    回复

    使用道具 举报

    14

    主题

    0

    听众

    453

    积分

    中级会员

    Rank: 3Rank: 3

    该用户从未签到

    发表于 2015-8-18 22:40:25 |显示全部楼层
    有空一起交流一下
    回复

    使用道具 举报

    21

    主题

    0

    听众

    552

    积分

    高级会员

    Rank: 4

    该用户从未签到

    发表于 2015-8-18 23:00:53 |显示全部楼层
    有空一起交流一下
    回复

    使用道具 举报

    19

    主题

    0

    听众

    506

    积分

    高级会员

    Rank: 4

    该用户从未签到

    发表于 2015-8-19 12:11:44 |显示全部楼层
    发发呆,回回帖,工作结束~
    回复

    使用道具 举报

    10

    主题

    0

    听众

    458

    积分

    中级会员

    Rank: 3Rank: 3

    该用户从未签到

    发表于 2015-8-19 14:15:49 |显示全部楼层
    我了个去,顶了
    回复

    使用道具 举报

    13

    主题

    0

    听众

    614

    积分

    高级会员

    Rank: 4

    该用户从未签到

    发表于 2015-8-19 23:12:54 |显示全部楼层
    众里寻他千百度,蓦然回首在这里!
    回复

    使用道具 举报

    12

    主题

    0

    听众

    551

    积分

    高级会员

    Rank: 4

    该用户从未签到

    发表于 2015-8-20 01:04:14 |显示全部楼层
    为了三千积分!
    回复

    使用道具 举报

    18

    主题

    0

    听众

    446

    积分

    中级会员

    Rank: 3Rank: 3

    该用户从未签到

    发表于 2015-8-20 02:51:00 |显示全部楼层
    顶起顶起顶起
    回复

    使用道具 举报

    12

    主题

    0

    听众

    484

    积分

    中级会员

    Rank: 3Rank: 3

    该用户从未签到

    发表于 2015-8-20 07:03:43 |显示全部楼层
    呵呵。。。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    回帖奖励

    [详情]

  • * 每天自己主题被回复3次可获得额外2金钱奖励。
  • * 每天回复他人主题5次可获得额外3贡献的奖励。
  • * 奖励每天都可领取,一定要多参与论坛讨论哦。
  • * 同一主题的重复回复不计。
  • 手机版|Archiver|聚合Vip网络社区 ( 鲁ICP备14030129号-2 )Discuz超级管家   

    GMT+8, 2018-6-24 11:00 , Processed in 0.251510 second(s), 57 queries .

    Powered by Discuz! X2.5

    © 2001-2012 Comsenz Inc. Template by A3cn

    回顶部