《深入理解计算机系统》bomb lab第五个字符串

《深入理解计算机系统》bomb lab第五个字符串

首先看下phase_5的反汇编代码

   0x0000000000401062 <+0>:     push   rbx
   0x0000000000401063 <+1>:     sub    rsp,0x20
   0x0000000000401067 <+5>:     mov    rbx,rdi
   0x000000000040106a <+8>:     mov    rax,QWORD PTR fs:0x28
   0x0000000000401073 <+17>:    mov    QWORD PTR [rsp+0x18],rax
   0x0000000000401078 <+22>:    xor    eax,eax
   0x000000000040107a <+24>:    call   0x40131b <string_length>
   0x000000000040107f <+29>:    cmp    eax,0x6                      # 比较字符串长度,可见字符串长度不等于6会触发爆炸
   0x0000000000401082 <+32>:    je     0x4010d2 <phase_5+112>
   0x0000000000401084 <+34>:    call   0x40143a <explode_bomb>
   0x0000000000401089 <+39>:    jmp    0x4010d2 <phase_5+112>
   0x000000000040108b <+41>:    movzx  ecx,BYTE PTR [rbx+rax*1]     # 将我们输入的第rax个字符放到ecx中
   0x000000000040108f <+45>:    mov    BYTE PTR [rsp],cl
   0x0000000000401092 <+48>:    mov    rdx,QWORD PTR [rsp]
   0x0000000000401096 <+52>:    and    edx,0xf                      # 与0b1111与操作,即取最低4位
   0x0000000000401099 <+55>:    movzx  edx,BYTE PTR [rdx+0x4024b0]  
   # 最关键的一步,将rdx+0x4024b0地址中的字符放入edx,再放入rsp+rax*1+0x10中。
     在之后的代码中可以看到这个地方就是我们要拿来比较的两个字符串之一,
     意思是我们要构造这个字符串与另一个字符串相同,这样就可以通过了。
   0x00000000004010a0 <+62>:    mov    BYTE PTR [rsp+rax*1+0x10],dl
   0x00000000004010a4 <+66>:    add    rax,0x1
   0x00000000004010a8 <+70>:    cmp    rax,0x6
   0x00000000004010ac <+74>:    jne    0x40108b <phase_5+41>        # 循环6次,每次eax+1
   0x00000000004010ae <+76>:    mov    BYTE PTR [rsp+0x16],0x0
   0x00000000004010b3 <+81>:    mov    esi,0x40245e                 # 0x40245e地址中保存的是我们要比较的另一个字符串之一。使用 x/s查看可知其为'flyers'
   0x00000000004010b8 <+86>:    lea    rdi,[rsp+0x10]
   0x00000000004010bd <+91>:    call   0x401338 <strings_not_equal>
   0x00000000004010c2 <+96>:    test   eax,eax
   0x00000000004010c4 <+98>:    je     0x4010d9 <phase_5+119>
   0x00000000004010c6 <+100>:   call   0x40143a <explode_bomb>
   0x00000000004010cb <+105>:   nop    DWORD PTR [rax+rax*1+0x0]
   0x00000000004010d0 <+110>:   jmp    0x4010d9 <phase_5+119>
   0x00000000004010d2 <+112>:   mov    eax,0x0
   0x00000000004010d7 <+117>:   jmp    0x40108b <phase_5+41>
   0x00000000004010d9 <+119>:   mov    rax,QWORD PTR [rsp+0x18]
   0x00000000004010de <+124>:   xor    rax,QWORD PTR fs:0x28
   0x00000000004010e7 <+133>:   je     0x4010ee <phase_5+140>
   0x00000000004010e9 <+135>:   call   0x400b30 <__stack_chk_fail@plt>
   0x00000000004010ee <+140>:   add    rsp,0x20
   0x00000000004010f2 <+144>:   pop    rbx
   0x00000000004010f3 <+145>:   ret

大致看一下反汇编代码,就知道这个又是一个字符串比较的,我们需要通过输入6个字符,构造出与地址0x40245e中的字符串相等的字符串(‘flyers’),构造的方法是取输入6个字符的低4位加上某个地址0x4024b0得到一个新地址,这个新地址中的字符就是构造后的字符,我们需要其分别为f、l、y、e、r、s。

先看一下地址0x40245e中的内容是啥:

(gdb) x /s 6305984
0x6038c0 <input_strings+320>:   "flyers"

再看一下0x4024b0中的内容是啥:

(gdb) x /s 0x4024b0
0x4024b0 <array.3449>:  "maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?"

不难看出,在0x4024b0中序号为9,15,14,5,6,7的字符分别为f,l,y,e,r,s。这就是我们要找的。但是这几个数字对应的ascii码都是不可打印的,咋办??我们看到反汇编代码中有一句:

0x0000000000401096 <+52>:    and    edx,0xf                      # 与0b1111与操作,即取最低4位

这意味着,我们输入的字符只要最后4位的值为9,15,14,5,6,7即可,于是我们可以将其值加上64得到73,79,78,69,70,71,再通过查找ascii码表,我们可以得到输入的字符串为:

IONEFG

输入后即可通过…

猜你喜欢

转载自blog.csdn.net/qq_38600065/article/details/108868328