做的是coursera上面这个 The Hardware/Software Interface 这个课程的课后作业, 也就是CSAPP这本书上很有名的bonm实验. 感觉非常有意思, 对汇编和GDB的熟悉认真做完都能有很大的提高

答案在我的github上有, 不过推荐自己做下来.
几个非常有用的GDB操作

  1. info registers 查看所有的register信息

  2. info frame 查看当前的栈信息, 非常的有用

  3. display /10i $pc 这样就可以在nexti 执行以后, 显示当前10行的汇编代码

  4. layout asm 线上汇编代码, 加当前指令的布局. 调试起来非常方便

  5. print $eax 是显示某一个寄存器里面的内容
    x/w $eax 是检查保存在寄存器里面的地址的内容, 也就是检查寄存器存的内容的内容

思路:

首先objdump -d bomb > bomb.s 得到汇编代码, 然后就可以gdb了

bomb 1: 可以看到有一个 callq strings_not_equal, 然后进去就可以获得一个字符串, 然后出来是比较 %eax. 因此可以判断这里是要输入一个相应的字符串

bomb 2: 可以看到 read_six_numbers, 主要考察的是loops操作

bomb 3: 可以看到这里有一个 jmpq *0x401b60(,%rax,8), 可以断定这是一个switch的case, 看汇编可以知道, 只有走到任意一个case, 就可以解这个bomb. 通过 x/7 0x401b60 就可以找到这个switch语句对应的跳转的表

bomb 4: 这个bomb主要考察的是递归, 最后结果是一个斐波那契数

0x400f92 <func4+14>     mov    %edi,%ebx # 将%edi赋值给$ebx
0x400f94 <func4+16>     mov    $0x1,%eax
0x400f99 <func4+21>     cmp    $0x1,%edi # 判断%edi是否比1小
0x400f9c <func4+24>     jle    0x400fb2 <func4+46> # 比1小就退出
0x400f9e <func4+26>     lea    -0x1(%rbx),%edi # 其实这里 %edi = %rbx - 1 = %ebx - 1 = %edi - 1
0x400fa1 <func4+29>     callq  0x400f84 <func4>
0x400fa6 <func4+34>     mov    %eax,%ebp
0x400fa8 <func4+36>     lea    -0x2(%rbx),%edi # 这里就是 %edi = %edi - 2
0x400fab <func4+39>     callq  0x400f84 <func4>
0x400fb0 <func4+44>     add    %ebp,%eax
0x400fb2 <func4+46>     mov    0x8(%rsp),%rbx
0x400fb7 <func4+51>     mov    0x10(%rsp),%rbp
0x400fbc <func4+56>     add    $0x18,%rsp
0x400fc0 <func4+60>     retq

bomb 5: 这里是对一个数组的不断跳转, 然后正好跳转12次, value是15. 数据的内容可以通过

(gdb) x/16wd 0x401ba0
0x401ba0 <array.3014>:  10      2       14      7
0x401bb0 <array.3014+16>:       8       12      15      11
0x401bc0 <array.3014+32>:       0       4       1       13
0x401bd0 <array.3014+48>:       3       9       6       5

这样就可以获得这个数据的内容, 那么接下来就很容易了


<
Previous Post
Paxos introduction
>
Next Post
Mario(a pipe line library)