zoukankan      html  css  js  c++  java
  • 4断点和单步执行

    4.12在调试器中设置断点

    当我们在调试器中设置断点,调试器会先把这里的本来指令的第一个字节保存起来,然后写入int3指令,


    4.13断点命中

    对于window这种保护模式下的多任务操作系统,INT3异常的处理函数是操作系统的内核函数(KiTrap03),因此执行INT3会导致CPU执行nt!kitrap03函数,KiTrap03对X86 CPU的断点异常会有一个特殊的处理,会将程序指针寄存器的值减1

    出于上面的原因,我们在调试器中看到的程序指针指向的仍是INT3指令的位置,而不是它的下一条指令,这下做目的有以下两点:

    1.调试器在使用INT3断点时,总是只替换一个字节,因此,如果程序指针指向下一个指令的位置,那么指向的可能是原来多字节指令的第二个字节,不是一条完整的指令,

    2.因为在断点位置那条指令没有被执行,所以必须倒退一个字节,指向原来指令的起始地址.


    4.14恢复执行

    当断点命中中断到调试器时,调试器会把所有的断点处的INT3指令恢复成本的内容,那么在用户发出了恢复执行命断点后,调试器在通知系统执行程序前,调试器需要把断点列表的所有断点再落实一遍,但刚才命中的断点需要特别对待,为什么呢,把它设置为INT3,那么程序一执行便又触发断点,如果不替换,那么这个断点便没有被落实,程序下次执行到这里时就不会触发断点

    对于上面的问题,大多数调试器的做法是先单步执行一次,也就是说,先设置单步执行标志,然后恢复执行,把断点所在位置的指令执行完,因为设置了单步标志,所以,CPU执行完断点位置的这条指令后会立即中断到调试器, 这次调试器不会通知用户,会做一些内部操作后便立即恢复程序执行,把所有的断点都落实,当然,如果用户在恢复程序执行前,已经取消了当前的断点,那么就不需要先单步执行一次了。


    4.15特别用途

    为了辅助调试,编译器在编译调试版本时会用OXCC来填充刚刚分配的缓冲区,如果是中文环境下,因为OXCCCC恰恰好是汉字烫字的简码,所以会观察到很多

    烫烫...


    4.17系统对INT3的优待

    系统会把INT n对应的机器码是oxcd后跟1字节n值,如INT 23会被编译为oxcd23,但INT3为单字节的OXCC,虽然没有哪个编译器会把INT 3编译成OXCD03,但可以直接在程序中插入OXCD03,但会出错,因为kitrap03会把程序指针减1,而不是减2,这使得异常后EIP指向了OXCD03的第二个字节了

    如图:我们可以看到反汇编程序也将OXCD03反汇编成INT3指令:


    这使得异常后EIP指向了OXCD03的第二个字节了:


    0:000> dd 401038
    00401038  909003cd 


    4.21调试寄存器概览

    IA-32处理器定义了8个调试寄存器,分别称为DR0-DR7

    首先,DR4和DR5是保留的,当调试扩展功能被启用时(CR4的DE位设置为1),那何对DR4和DR5的引用都会导致一个非法指令异常(#UD),当此功能被禁止时,DR4和DR5分别是DR6和DR7的别名寄存器,即等价于访问后者.

    DR0-DR3用来指定断点的内存或I/O地址,DR7用来进一步定义断点的中断条件,可以最多设置4个断点.


    4.23调试控制寄存器

    读/写内存中的数据时中断:这种断点又被称为数据访问断点,利用数据访问断点,可以监控对全局变量或局部变量的读写操作,如ba w4 00401200

    对于数据和I/O访问断点,有两点需要注意:

    1.只要断点区域中的任一字节在被访问的范围内,都会触发该断点

    2.4字节区域必须安双字(doubleword)边界对齐,8字节区域必须按4字边界对齐,也就是说,CPU在检查断点匹配时会自动去掉相应娄量的低位

    对2举个例子,如windbg输入:

    0:005> ba w4 777c410c
    0:005> ba w4 777c410d
    Data breakpoint must be aligned
                        ^ Syntax error in 'ba w4 777c410d'
    
    可以看到,后面提示数据为点必须对齐,因为777c410d不是4位对齐的

    再比如强制把DR0设为0XA003,四字节对齐,那么CPU在检查地址匹配时,会自动把0xA003的低四位屏蔽掉,只是匹配0xA000,而OXA004,0xA005,0xA006屏蔽低2位后都是0xA004,所以无法触发断点.

    数据访问异常同样属于陷阱类异常


    4.31单步执行标志(TF)

    调试器的标志寄存器中有一个陷阱标志位,名为Trap Flag,简称TF,当TF位为1时,CPU每执行完一条指令便会产生一个调试异常,中断到调试异常处理程序,调试器的单步执行功能大多依靠这一机制来实现的,

    因为CPU在进入异常处理例程前会自动清除TF标志,因此,当CPU中断到调试器中再观察TF标志,它的值总是0

    此异常的向量号为1,但只能在内核模式下才能执行INT 1指问,也就是,用户模式下应用程序没有权利使用INT 1指令,一旦使用,就会报访问违例错误.



  • 相关阅读:
    分页系统
    ORM-数据处理
    Django的用法
    登录cookie写法
    MySQL数据库的安装创建
    前端弹框编写
    ADB常用指令
    Appium环境配置
    Jmeter中传递cookie值
    Jmeter从文件中读取参数值
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693431.html
Copyright © 2011-2022 走看看