liang's profile阿斯提亚神殿——梦幻天子's skyPhotosBlogLists Tools Help
    September 18

    如何对抗硬件断点之一---调试寄存器(转载)

    1.前言

    在我跨入ollydbg的门的时候,就对ollydbg里面的各种断点充满了疑问,以前我总是不明白普通断点,内存断点,硬件断点有什么区别,他们为什么有些时候不能混用,他们的原理是什么,在学习了前辈们的文章以后,终于明白了一些东西。希望这篇文章能让你对硬件断点的原理和使用有一些帮助

    2.正文
    --------------------------------------------------
    i.硬件断点的原理

    在寄存器中,有这么一些寄存器,它们用于调试。人们把他们称为调试寄存器,调试寄存器一共有8个名字分别从Dr0-Dr7。所以我们也把调试寄存器简单的称为Drx。

    对于Dr0-Dr3的四个调试寄存器,他们的作用是存放中断的地址,例如:401000
    对于Dr4,Dr5这两个寄存器我们一般不使用他们,保留
    对于Dr6,Dr7这两个寄存器的作用是用来记录你在Dr0-Dr3中下断的地址的属性,比如:对这个401000是硬件读还是写,或者是执行;是对字节还是对字,或者是双字。

    好了,从这里你可能明白一些东西。

    1. 为什么在OD里面只能下4个硬件断点?
    2. 为什么下硬件断点有byte,word,dword只分?
    3. 为什么下硬件断点有读,写,执行只分?

    ii.关于F4,F8,F7,F2的区别

    在ollydbug的help里面只是提到如何使用F7和F8的使用,并没说明他们的实现原理

    现在我们来做一个实验

    实验一(F4的原理)

    1.随便找一个程序,载入OD,构造一个死循环

    就象这样:

    00400154 > 90 nop //EP停在这里
    00400155 90 nop
    00400156 90 nop
    00400157 90 nop
    00400158 ^ EB FA jmp short 天2国际. //构造一个死循环
    0040015A 61 popad
    0040015B 94 xchg eax,esp

    2.对0040015A这一行按下F4,由于死循环,程序一直运行

    3.调试器的窗口里,右键--查看调试寄存器

    结果在Drx里面显示:

    DR0 0040015A //地址
    DR1 00000000
    DR2 00000000
    DR3 00000000
    DR6 FFFF0FF0 //断点属性
    DR7 00000401

    实验二(F8原理)

    1.随便找一个程序,载入OD,构造一个子程序的死循环

    就像这样

    00400154 t> E8 0100D03F call 4010015A //EP,停在这里
    00400159 90 nop
    0040015A 90 nop
    0040015B 90 nop
    0040015C 90 nop //对这里下F2断点
    0040015D C3 retn // 返回

    2.按下F8,由于INT3断点,程序中断在0040015C

    3.调试器的窗口里,右键--查看调试寄存器

    结果在Drx里面显示:

    DR0 00400159 //call的返回地址
    DR1 00000000
    DR2 00000000
    DR3 00000000
    DR6 FFFF4FF1 //断点属性
    DR7 00000401


    实验三(F7原理)

    1.随便找一个程序,载入OD

    2.双击调试器的窗口里的T标志,将TF从原来的0变成1

    3.F9运行

    结果程序断在了下面的一行

    实验四(F2的原理)

    1.用98的notepad吧,载入OD,构造一个死循环

    004010CC N> 90 nop //EP,挺在这里
    004010CD 90 nop
    004010CE ^ EB FC jmp short NOTEPAD. //死循环
    004010D0 90 nop //在这里按下F2,普通断点
    004010D1 90 nop

    2.按下F9,由于死循环,程序一直运行着

    3.使用LordPE(不要用ollydump)将这个程序dump下来

    4.重新载入OD

    来看看成什么样子了

    004010CC d> $ 90 nop
    004010CD . 90 nop
    004010CE .^ EB FC jmp short dumped.
    004010D0 CC int3 //这里变成了CC了
    004010D1 90 nop

    --------------------------------------------------

    3.总结

    从实验一和实验二我们能清楚的看到,F4是直接将该行的地址放入drx里面,F8是将下一行的地址放入到drx里面,他们都使用了调试寄存器。从实验三中我们知道对于F7来说很可能使用的是将TF置一的办法,也就是说当我们按下F7的时候OD把TF置一。对于F2来说他是将,第一个字节悄悄的修改成了CC,虽然并没有显示给我看到这个是一个CC,当我们按下F2的时候,OD还没有运行,只是把这个表示记录下来,当运行的时候他就把所有标记的字节修改了,尽管还是显示原来的代码,当然当他一暂停下来就又修改回来了。

    上面的是实验中,F7的原理只是猜测,还没有很好的办法能证明他就是使用TF,下面我继续猜测一下内存断点的原理

    1.将设置的内存断点的地址记录下来

    2.对这个地址的内存页面修改其属性

    如果是内存写断点,就修改为RE(可读,可执行)
    如果是内存访问断点,就修改为NO ACCESS(不可访问)

    3.只要访问到这个页面就会产生相应的异常,然后由OD来判断是否与记录的断点一致,从而是否中断下来

    --------------------------------------------------
    4.后话

    对于上面的F7和内存断点的原理,我还没想出什么好的办法去找出OD的原理,或许去调试一下ollydbg.exe是一个不错的建议。如果有哪位兄弟知道有什么好办法,希望能告诉我。当然也很欢迎各位和我讨论。 
     
    September 16

    沙加与佛的对话(转载)

    佛说:沙加,沙加,有什么事情让你如此悲伤?只有六岁的你,为什么每天这么坐着?
           什么事情让你如此有心忡忡?
    沙加:今天又看到冈底斯河中浮着好几具尸体,在河岸上有好多来自印度各地的巡礼者在那里沐浴,
           看他们的样子,与其说是求生,不如说是希望求死一样。我所降生的这个国家,为什么会这么贫穷?
           难道人们就是为了受苦受难而来到这个世界的吗?
    佛说:沙加,这就是你悲伤的原因吗?
    沙加:当然了,谁会希望致意个只有痛苦的人生呢?
    佛说:那是不对的...
           因为有痛苦,所以快乐也一定相应的存在,反过来一样...
           美丽的花开了,可它也有一天会凋谢,在这个世界上,生命一瞬也不会停止的,它一直在动着,变着,这就是无常...
           人的一生也是这样...
    沙加:但是,最后还是只有一死... ...
           这难道不可以说,人生还是被悲伤所支配着吗?
           活着的时候,无论是克服痛苦还是追求爱,追求喜悦...
           最终死亡还是把一切都化为虚无...
           那,人是为什么而生?想要和死亡这种永恒的东西对抗根本就是不可能...
    佛说:沙加,你忘记了?
    沙加:忘记了?
    佛说:那是... ...
    沙加:沙罗双树的花...也凋谢了吗...
    佛说:沙加啊,你忘记了吧?
    沙加:忘记了?
    佛说:死并不是一切的终结,即使是死也只不过是变化的一种...

    佛说:沙加,沙加,你一定不能忘记啊!死亡决不是最后...
           曾经活在这个世上的圣人们,都超越了死的境界!
           沙加啊!如果你也能领悟这一点的话,那你也就成为了人类中最接近神的人!
    沙加:花开了,然后又会凋零,星星市璀璨的,可那光芒也会消失!
           这个地球,太阳,这整个银河系,甚至连这个宇宙,也会有死亡 的时候。
           人的一生,和这些东西相比,简直就象是刹那间的事情...
           在这样的一个瞬间,人降生了,笑着,哭着,战斗,伤害,喜悦,悲伤,憎恶,爱情,一切都知识刹那间的邂逅,而最后都要归入死的永眠!
    September 02

    [汇编]条件条状与PSW(转载)

    一、状态寄存器

    PSW(Program Flag)程序状态字寄存器,是一个16位寄存器,由条件码标志(flag)和控制标志构成,如下所示:

    15
    14
    13
    12
    11
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    0
     
     
     
     
    OF
    DF
    IF
    TF
    SF
    ZF
     
    AF
     
    PF
     
    CF


    条件码:
    ①OF(Overflow Flag)溢出标志。溢出时为1,否则置0。
    ②SF(Sign Flag)符号标志。结果为负时置1,否则置0.
    ③ZF(Zero Flag)零标志,运算结果为0时ZF位置1,否则置0.
    ④CF(Carry Flag)进位标志,进位时置1,否则置0.
    ⑤AF(Auxiliary carry Flag)辅助进位标志,记录运算时第3位(半个字节)产生的进位置。有进位时1,否则置0.
    ⑥PF(Parity Flag)奇偶标志。结果操作数中1的个数为偶数时置1,否则置0.

    控制标志位:
    ⑦DF(Direction Flag)方向标志,在串处理指令中控制信息的方向。

    ⑧IF(Interrupt Flag)中断标志。
    ⑨TF(Trap Flag)陷井标志。

    二、 直接标志转移(8位寻址)

    指令格式
    机器码
    测试条件
    如...则转移
     
     
    指令格式
    机器码
    测试条件
    如...则转移
    JC
    72
    C=1
    有进位
    JNS
    79
    S=0
    正号
    JNC
    73
    C=0
    无进位
    JO
    70
    O=1
    有溢出
    JZ/JE
    74
    Z=1
    零/等于
    JNO
    71
    O=0
    无溢出
    JNZ/JNE
    75
    Z=0
    不为零/不等于
    JP/JPE
    7A
    P=1
    奇偶位为偶
    JS
    78
    S=1
    负号
    JNP/IPO
    7B
    P=0
    奇偶位为奇

    三、间接标志转移(8位寻址)

    指令格式
    机器码
    测试格式
    如...则转移
    JA/JNBE(比较无符号数)
    77
    C或Z=0
    >  高于/不低于或等于
    JAE/JNB(比较无符号数)
    73
    C=0
    >=  高于或等于/不低于
    JB/JNAE(比较无符号数)
    72
    C=1
    <  低于/不高于或等于
    JBE/JNA(比较无符号数)
    76
    C或Z=1
    <=  低于或等于/不高于
    JG/JNLE(比较带符号数)
    7F
    (S异或O)或Z=0
    >  大于/不小于或等于
    JGE/JNL(比较带符号数)
    7D
    S异或O=0
    >=  大于或等于/不小于
    JL/JNGE(比较带符号数)
    7C
    S异或O=1
    <  小于/不大于或等于
    JLE/JNG(比较带符号数)
    7E
    (S异或O)或Z=1
    <=  小于或等于/不大于