滴水逆向软件调试

一、调试对象

在这里插入图片描述
在这里插入图片描述
分为两种:创建进程和附加进程
创建进程为将未运行的程序创建进程
附加进程为将运行中的进程附加
在这里插入图片描述
对调试器做的事
DebugActiveProcess调用了DbgUiConnectToDbg,然后调用了ntdll.dll模块中的DbgUiConnectToDbg
在这里插入图片描述
DbgUiConnectToDbg调用ZwCreateDebugObject,进入0环,创建_DEBUG_OBJECT
在这里插入图片描述
在这里插入图片描述
_ZwCreateDebugObject第一个参数为输出,由于是在3环,所以是一个句柄,存在当前线程TEB(0XF24)中
在这里插入图片描述

对被调试进程做的事
DebugActiveProcess函数,成功创建调试对象后和调试器进程创建连接后。调用ProcessIdToHandle,将进程ID转换成进程句柄。然后将进程句柄做为参数调用DbgUiDebugActiveProcess
在这里插入图片描述
DbgUiDebugActiveProcess调用ntdll.dll模块中的DbgUiDebugActiveProcess函数
在这里插入图片描述
DbgUiDebugActiveProcess中调用_NtDebugActiveProcess,参数一为上面传下来的被调试进程的句柄,参数二为TEB+0XF24,当前线程的调试对象
在这里插入图片描述
_ntDebugActiveProcess进入0环
在这里插入图片描述
NtDebugActiveProcess中两个传下来的参数,因为是3环传下来的,所以是句柄。ObReferenceObjectByHandle函数为根据句柄获得对象,参数一为进程句柄,获得EPROCESS地址放到参数5,参数5被占用,函数调用完后参数5为EPROCESS地址
在这里插入图片描述
获取当前线程所处进程,如果是当前进程或者是PsInitialSystemProcess,结束
在这里插入图片描述
再次调用ObReferenceObjectByHandle,这次获取调试对象的地址
在这里插入图片描述
然后调用DbgKpSetProcessDebugObject函数将调试对象和被调试进程关联起来,参数一为被调试进程的EPROCESS,参数二为调试对象的地址
在这里插入图片描述
判断EPROCESS+0BCh,也就是DebugPort是不是为0
在这里插入图片描述
如果DebugPort是0,将DEBUG_OBJECT存储到被调试进程EPROCESS的DebugPort中
在这里插入图片描述
_DEBUG_OBJECT的本质:桥
在这里插入图片描述

二、调试事件的采集

只有几个关键的调试事件种类才会记录到调试事件
在这里插入图片描述
谁替被调试进程生成调试事件,装入调试事件链表中。在函数调用的必经之路中有一组Dbgk开头的函数,先判断DebugPort是否为0,不为0才调用Dbgk函数
在这里插入图片描述
每一种事件要求描述的信息不同,需要封装不同的结构体,所以需要不同的调试事件采集函数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、调试事件的处理

调试器进程循环判断DEBUG_OBJECT链表中是否有数据
WaitForDebugEvent函数为判断DEBUG_OBJECT中是否有调试事件,如果有就把调试事件取出,放到DEBUG_EVENT中
在这里插入图片描述
ContinueDebugEvent告诉被调试进程继续执行
在这里插入图片描述
在这里插入图片描述

四、异常的处理流程

在这里插入图片描述
在这里插入图片描述
第二次异常分发由UnhandledExceptionFilter分发
在这里插入图片描述

五、软件断点

调试的本质是异常的处理
在调试器中按下一个F2时会生成一个断点,将这个地方的代码改成int 3,硬编码为CC
反调试中CRC可以用来检测软件断点
在这里插入图片描述

六、内存断点

内存读或写断点 ,Memory,on access 或Memory,on write
设置内存断点要修改内存的页的属性,如果要设置访问断点将内存页属性设置为不可访问。如果要设置内存写断点要将内存页属性设置为可读可执行不可写
反调试可以写一个程序使当前代码内存页属于永远可以访问
在这里插入图片描述
在这里插入图片描述

七、硬件断点

硬件断点最多只有四个,调试寄存器只有四个,Dr0-Dr3
Dr0-Dr3存储线性地址,每个线程都有上下文context,当目标线程的值被装入寄存器时才起作用
当想要调试寄存器Dr0到Dr3有作用,Dr7中的对应的Lx~Gx必须有一个为1
硬件断点类型可以分为访问,写入和执行
反调试可以写一个线程可以将调试寄存器不停清0,反反调试可以找到清0的线程处理掉
在这里插入图片描述
CPU检测到调试寄存器中的值和当前正在读的值是相同的,触发单步异常,IDT表01号中断处理函数
在这里插入图片描述
CPU的eflag中的TF位置1也是触发单步异常
在这里插入图片描述
查看Dr6中的B0-B3是否有值,如果没有为eflag中的TF位为1导致

九、单步步过

在这里插入图片描述
判断当前指令是否为CALL指令,如果为call,在下一行设置硬件断点,将当前指令给反汇编引擎,计算当前指令长度,下一行指令开始位置

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值