phase 5
0000000000401062 <phase_5>:
401062: 53 push %rbx
401063: 48 83 ec 20 sub $0x20,%rsp
401067: 48 89 fb mov %rdi,%rbx
40106a: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
401071: 00 00
401073: 48 89 44 24 18 mov %rax,0x18(%rsp)
401078: 31 c0 xor %eax,%eax
40107a: e8 9c 02 00 00 callq 40131b <string_length>
40107f: 83 f8 06 cmp $0x6,%eax
401082: 74 4e je 4010d2 <phase_5+0x70>
401084: e8 b1 03 00 00 callq 40143a <explode_bomb>
401089: eb 47 jmp 4010d2 <phase_5+0x70>
40108b: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx
40108f: 88 0c 24 mov %cl,(%rsp)
401092: 48 8b 14 24 mov (%rsp),%rdx
401096: 83 e2 0f and $0xf,%edx
401099: 0f b6 92 b0 24 40 00 movzbl 0x4024b0(%rdx),%edx
4010a0: 88 54 04 10 mov %dl,0x10(%rsp,%rax,1)
4010a4: 48 83 c0 01 add $0x1,%rax
4010a8: 48 83 f8 06 cmp $0x6,%rax
4010ac: 75 dd jne 40108b <phase_5+0x29>
4010ae: c6 44 24 16 00 movb $0x0,0x16(%rsp)
4010b3: be 5e 24 40 00 mov $0x40245e,%esi
4010b8: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi
4010bd: e8 76 02 00 00 callq 401338 <strings_not_equal>
4010c2: 85 c0 test %eax,%eax
4010c4: 74 13 je 4010d9 <phase_5+0x77>
4010c6: e8 6f 03 00 00 callq 40143a <explode_bomb>
4010cb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
4010d0: eb 07 jmp 4010d9 <phase_5+0x77>
4010d2: b8 00 00 00 00 mov $0x0,%eax
4010d7: eb b2 jmp 40108b <phase_5+0x29>
4010d9: 48 8b 44 24 18 mov 0x18(%rsp),%rax
4010de: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
4010e5: 00 00
4010e7: 74 05 je 4010ee <phase_5+0x8c>
4010e9: e8 42 fa ff ff callq 400b30 <__stack_chk_fail@plt>
4010ee: 48 83 c4 20 add $0x20,%rsp
4010f2: 5b pop %rbx
4010f3: c3 retq
phase 5还算比较简单,首先是存储rbx,以及一个%fs:0x28,据说是检测栈是否溢出的,对解题无影响。
接下来调用string_length,判断字符串长度是否为6,若不是则爆炸。
然后是循环,%eax从0到5,也就是输入字符串的每一个字符char x
先0拓展到32位存入%ecx中,取低8位%el存储到栈上(%rsp)
再取栈上(%rsp) 到 %rdx中,注意这里取的是64位,也就是有7个未知字节。
%edx与0xf做按位与,注意当传送或者产生32位寄存器值时,寄存器的高32位也会被置为0(可见调试过程)
(gdb) x/x 0x7fffffffdc80 //%rsp
0x7fffffffdc80: 0x00402239 //(%rsp)
(gdb) watch $rdx
Watchpoint 2: $rdx
(gdb) step
Single stepping until exit from function phase_5,
which has no line number information.
Watchpoint 2: $rdx
Old value = 6305990
New value = 4203065
0x0000000000401096 in phase_5 () //after mov (%rsp),%rdx
(gdb) print/x $rdx
$4 = 0x402239
(gdb) step
Single stepping until exit from function phase_5,
which has no line number information.
Watchpoint 2: $rdx
Old value = 4203065
New value = 9
0x0000000000401099 in phase_5 () //after and $0xf,%edx
(gdb) step
Single stepping until exit from function phase_5,
which has no line number information.
Watchpoint 2: $rdx
Old value = 9
New value = 102
0x00000000004010a0 in phase_5 ()
(gdb) print/c $rdx
$5 = 102 'f'
所以%rdx变为0x0000 000x,x是char x的16进制表示
将地址为0x4024b0(%rdx)的字符通过0拓展方式放到%edx中,取低8位也就是char x存储到栈上
循环完成后在字符串末尾加上'\0',调用strings_not_equal判断是否相等