《深入理解计算机系统》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
输入后即可通过…