phase_5(edition 1)

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
0x40109d <phase_5>      push   %rbx                             
0x40109e <phase_5+1> sub $0x10,%rsp
0x4010a2 <phase_5+5> mov %rdi,%rbx
0x4010a5 <phase_5+8> callq 0x4012f1 <string_length>
0x4010aa <phase_5+13> cmp $0x6,%eax
0x4010ad <phase_5+16> je 0x4010f2 <phase_5+85>
0x4010af <phase_5+18> callq 0x4015b9 <explode_bomb>
0x4010b4 <phase_5+23> jmp 0x4010f2 <phase_5+85>
0x4010b6 <phase_5+25> movzbl (%rbx,%rax,1),%edx
0x4010ba <phase_5+29> and $0xf,%edx
0x4010bd <phase_5+32> movzbl 0x4025c0(%rdx),%edx
0x4010c4 <phase_5+39> mov %dl,(%rsp,%rax,1)
0x4010c7 <phase_5+42> add $0x1,%rax
0x4010cb <phase_5+46> cmp $0x6,%rax
0x4010cf <phase_5+50> jne 0x4010b6 <phase_5+25>
0x4010d1 <phase_5+52> movb $0x0,0x6(%rsp)
0x4010d6 <phase_5+57> mov $0x40256e,%esi
0x4010db <phase_5+62> mov %rsp,%rdi
0x4010de <phase_5+65> callq 0x40130e <strings_not_equal>
0x4010e3 <phase_5+70> test %eax,%eax
0x4010e5 <phase_5+72> je 0x4010f9 <phase_5+92>
0x4010e7 <phase_5+74> callq 0x4015b9 <explode_bomb>
0x4010ec <phase_5+79> nopl 0x0(%rax)
0x4010f0 <phase_5+83> jmp 0x4010f9 <phase_5+92>
0x4010f2 <phase_5+85> mov $0x0,%eax
0x4010f7 <phase_5+90> jmp 0x4010b6 <phase_5+25>
0x4010f9 <phase_5+92> add $0x10,%rsp
0x4010fd <phase_5+96> pop %rbx
0x4010fe <phase_5+97> retq

Part 1

1
2
3
4
5
6
7
0x40109d <phase_5>      push   %rbx                             
0x40109e <phase_5+1> sub $0x10,%rsp
0x4010a2 <phase_5+5> mov %rdi,%rbx
0x4010a5 <phase_5+8> callq 0x4012f1 <string_length>
0x4010aa <phase_5+13> cmp $0x6,%eax
0x4010ad <phase_5+16> je 0x4010f2 <phase_5+85>
0x4010af <phase_5+18> callq 0x4015b9 <explode_bomb>
  • 调用了 ,并把其返回值(即字符串的长度)与6比较,如果不相等就boom
  • 所以可以知道这关我们的输入是一个长度为6的字符串

Part 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0x4010ad <phase_5+16>   je     0x4010f2 <phase_5+85> //字符串长度符合,跳到+85       
0x4010af <phase_5+18> callq 0x4015b9 <explode_bomb>
0x4010b4 <phase_5+23> jmp 0x4010f2 <phase_5+85>
0x4010b6 <phase_5+25> movzbl (%rbx,%rax,1),%edx
0x4010ba <phase_5+29> and $0xf,%edx
0x4010bd <phase_5+32> movzbl 0x4025c0(%rdx),%edx
0x4010c4 <phase_5+39> mov %dl,(%rsp,%rax,1)
0x4010c7 <phase_5+42> add $0x1,%rax
0x4010cb <phase_5+46> cmp $0x6,%rax
0x4010cf <phase_5+50> jne 0x4010b6 <phase_5+25>
0x4010d1 <phase_5+52> movb $0x0,0x6(%rsp)
0x4010d6 <phase_5+57> mov $0x40256e,%esi
0x4010db <phase_5+62> mov %rsp,%rdi
0x4010de <phase_5+65> callq 0x40130e <strings_not_equal>
0x4010e3 <phase_5+70> test %eax,%eax
0x4010e5 <phase_5+72> je 0x4010f9 <phase_5+92>
0x4010e7 <phase_5+74> callq 0x4015b9 <explode_bomb>
0x4010ec <phase_5+79> nopl 0x0(%rax)
0x4010f0 <phase_5+83> jmp 0x4010f9 <phase_5+92>
0x4010f2 <phase_5+85> mov $0x0,%eax
0x4010f7 <phase_5+90> jmp 0x4010b6 <phase_5+25>
  1. 跳到<phase_5+85>后,首先把 0 move 到 %eax中 之后再跳到 <phase_5+25>

  2. <phase_5+25> movzbl (%rbx,%rax,1),%edx

    • 这句的含义是把%rbx的地址每次加上%rax * 1处的内容移动到%edx
    • 1到是char类型的长度
    • 联系上文可以知道%rbx是我们输入的string的首地址
  3. 0x4010c7 <phase_5+42> add $0x1,%rax
    0x4010cb <phase_5+46> cmp $0x6,%rax
    0x4010cf <phase_5+50> jne 0x4010b6 <phase_5+25>

  • 这几句代码可以看出是一个循环,联系2中的分析可以知道,实际上实现了如下功能:
1
2
3
for(int i = 0; i < 6; i++){
//这里对str[i]进行一些阴暗的操作
}
  1. 0x4010b6 <phase_5+25> movzbl (%rbx,%rax,1),%edx
    0x4010ba <phase_5+29> and $0xf,%edx 取第四位的值
    0x4010bd <phase_5+32> movzbl 0x4025c0(%rdx),%edx 访问神秘地址
    0x4010c4 <phase_5+39> mov %dl,(%rsp,%rax,1) 访问结果替换原有字符
    这些就是对字符串中的阴暗操作,首先取每个字符的低4位,用低四位的数值作为指针,加到0x4025c0这个地址上,从这里获取新值替换原有字符

phase_5e1

  1. 打印这个神秘地址的内容:“maduiersnfotvbyl”获得神秘字符串

p5e1addr.png

part 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
0x4010d1 <phase_5+52>   movb   $0x0,0x6(%rsp)                      
0x4010d6 <phase_5+57> mov $0x40256e,%esi
0x4010db <phase_5+62> mov %rsp,%rdi
0x4010de <phase_5+65> callq 0x40130e <strings_not_equal>
0x4010e3 <phase_5+70> test %eax,%eax
0x4010e5 <phase_5+72> je 0x4010f9 <phase_5+92>
0x4010e7 <phase_5+74> callq 0x4015b9 <explode_bomb>
0x4010ec <phase_5+79> nopl 0x0(%rax)
0x4010f0 <phase_5+83> jmp 0x4010f9 <phase_5+92>
0x4010f2 <phase_5+85> mov $0x0,%eax
0x4010f7 <phase_5+90> jmp 0x4010b6 <phase_5+25>
0x4010f9 <phase_5+92> add $0x10,%rsp
0x4010fd <phase_5+96> pop %rbx
0x4010fe <phase_5+97> retq

这里是在跳出循环后,可以看出最后一步就是比较字符串是否相等,如果相等,这关就解决了
0x4010d6 <phase_5+57> mov $0x40256e,%esi 注意到这里是和$0x40256e的字符串的比较,打印此处的信息,出现结果“flames”,OK到这里这题的含义就明晰了。

结论

我们需要输入一个6个字符的字符串,其中每个字符的低四位的值需要按顺序对应着“maduiersnfotvbyl”中”f“、”l”、“a”、”m”、”e”、”s”的下标,从而使字符串经过替换后可以变成所需的flames

phase_5(edition 2)

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
0000000000401139 <phase_5>:
401139: 53 push %rbx
40113a: 48 89 fb mov %rdi,%rbx
40113d: e8 4f 02 00 00 callq 401391 <string_length>
401142: 83 f8 06 cmp $0x6,%eax
401145: 74 05 je 40114c <phase_5+0x13>
401147: e8 0d 05 00 00 callq 401659 <explode_bomb>
40114c: b8 00 00 00 00 mov $0x0,%eax
401151: ba 00 00 00 00 mov $0x0,%edx
401156: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx
40115a: 83 e1 0f and $0xf,%ecx
40115d: 03 14 8d 80 26 40 00 add 0x402680(,%rcx,4),%edx
401164: 48 83 c0 01 add $0x1,%rax
401168: 48 83 f8 06 cmp $0x6,%rax
40116c: 75 e8 jne 401156 <phase_5+0x1d>
40116e: 83 fa 1f cmp $0x1f,%edx
401171: 74 05 je 401178 <phase_5+0x3f>
401173: e8 e1 04 00 00 callq 401659 <explode_bomb>
401178: 5b pop %rbx
401179: c3 retq

part 1

1
2
3
4
5
6
401139:	53                   	push   %rbx
40113a: 48 89 fb mov %rdi,%rbx
40113d: e8 4f 02 00 00 callq 401391 <string_length>
401142: 83 f8 06 cmp $0x6,%eax
401145: 74 05 je 40114c <phase_5+0x13>
401147: e8 0d 05 00 00 callq 401659 <explode_bomb>

类似的,首先判断字符串长度是否为6

part 2

1
2
3
4
5
6
7
8
40114c:	b8 00 00 00 00       	mov    $0x0,%eax
401151: ba 00 00 00 00 mov $0x0,%edx
401156: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx
40115a: 83 e1 0f and $0xf,%ecx
40115d: 03 14 8d 80 26 40 00 add 0x402680(,%rcx,4),%edx
401164: 48 83 c0 01 add $0x1,%rax
401168: 48 83 f8 06 cmp $0x6,%rax
40116c: 75 e8 jne 401156 <phase_5+0x1d>
  • 类似的,一个循环,对字符串每个字符取第四位,然后用来访问magic address :0x402680
  • 计算时用到了4,猜测是int类型的顺序存储
  • 打印一下这个地址的位置 发现确实有很多数字
  • 字符串中的字符用来参与地址运算,从而把数组对应位置的数值加到%edx中
    p5e2print

part 3

1
2
3
4
5
40116e:	83 fa 1f             	cmp    $0x1f,%edx
401171: 74 05 je 401178 <phase_5+0x3f>
401173: e8 e1 04 00 00 callq 401659 <explode_bomb>
401178: 5b pop %rbx
401179: c3 retq
  • 比较%edx和0x1f的大小关系,相等则通过,不等则爆炸

结论

  • 我们需要输入一个字符串,其中的每个字符用来参与地址计算,访问数组的某个元素,最终需要用数组中的6个元素求和得到31
  • 我的答案:322222(1 + 6 +6 + 6 + 6 + 6)

To be continued……