以下是我对代码的作用以及我想如何解决它的理解:首先,我需要找到一个字符串,然后根据我找到的 16 字节查找表对该字符串进行逆向工程。我确实知道这些“偏移量”的值加起来必须达到 60,请参见第 <+53> 行。
我尝试使用 x/s 0x4011fe 和其他检查命令(x/6c 等)找到这个 6 个字符的字符串,但我没有得到任何接近正确的结果。我可以改变一些东西来获得正确的输出,以便我可以继续消除这个阶段吗?
一旦找到这个字符串,我的想法是查看这个所需的输出字符串,然后找出获得预期输出所需的输入字符串。我在想 - 查看每个字符的十六进制值,将它们与我的表(最低顺序)进行比较,然后使用 ascii 表找到相应的字符。我只是想知道这是否是正确的方法,谢谢。
查表:
(gdb) x/16xw 0x402780
<array.3600>: 0x00000002 0x0000000a 0x00000006 0x00000001
<array.3600>: 0x0000000c 0x00000010 0x00000009 0x00000003
<array.3600>: 0x00000004 0x00000007 0x0000000e 0x00000005
<array.3600>: 0x0000000b 0x00000008 0x0000000f 0x0000000d
phase_5拆解:
0x00000000004011bf <+0>: push %rbx
0x00000000004011c0 <+1>: mov %rdi,%rbx
0x00000000004011c3 <+4>: callq 0x401414 <string_length>
0x00000000004011c8 <+9>: cmp $0x6,%eax //6 letter string!
0x00000000004011cb <+12>: je 0x4011d2 <phase_5+19> //if 6, jump over the explode
0x00000000004011cd <+14>: callq 0x401706 <explode_bomb>
0x00000000004011d2 <+19>: mov %rbx,%rax
0x00000000004011d5 <+22>: lea 0x6(%rbx),%rdi
0x00000000004011d9 <+26>: mov $0x0,%ecx
0x00000000004011de <+31>: movzbl (%rax),%edx
0x00000000004011e1 <+34>: and $0xf,%edx //”and” each letter
0x00000000004011e4 <+37>: add 0x402780(,%rdx,4),%ecx
0x00000000004011eb <+44>: add $0x1,%rax
0x00000000004011ef <+48>: cmp %rdi,%rax //compare, and then loop again.
0x00000000004011f2 <+51>: jne 0x4011de <phase_5+31> //loop!
0x00000000004011f4 <+53>: cmp $0x3c,%ecx //final compare, and then done! (0x3c = 60)
0x00000000004011f7 <+56>: je 0x4011fe <phase_5+63> //jump over explode, and finish!
0x00000000004011f9 <+58>: callq 0x401706 <explode_bomb>
0x00000000004011fe <+63>: pop %rbx
0x00000000004011ff <+64>: retq
End of assembler dump.
经过深思熟虑,我成功找到了答案。结果发现没有字符串可供比较,只有 0x3c 的值。在阅读汇编代码时,过度思考似乎是我的常见问题。
本质上,我需要从数组中挑选 6 个总和为 0x3c 的数字。然后选择 6 个可打印字符或数字,它们具有适当的索引作为低 4 位。因此,最简单的选择是 0xa,它的索引为 1(0xa = 10,因此获得 6 个值很简单)。
谢谢大家的评论。