我一直在研究Binary Bomb for school,我在第5阶段绝对迷失。作业的目的是拆解代码并找到一个字符串,我发现它是“传单”和反向工程它具有与“传单”相同的数值。但是,我花了最后3-4个小时试图找出如何做到这一点?你不必给出答案,但请帮助我理解我需要做什么。这是使用gdb的反汇编代码:
Dump of assembler code for function phase_5:
0x08048d88 <+0>: push %ebx
0x08048d89 <+1>: sub $0x28,%esp
0x08048d8c <+4>: mov 0x30(%esp),%ebx
0x08048d90 <+8>: mov %gs:0x14,%eax
0x08048d96 <+14>: mov %eax,0x1c(%esp)
0x08048d9a <+18>: xor %eax,%eax
0x08048d9c <+20>: mov %ebx,(%esp)
0x08048d9f <+23>: call 0x804902b <string_length>
0x08048da4 <+28>: cmp $0x6,%eax
0x08048da7 <+31>: je 0x8048dae <phase_5+38>
0x08048da9 <+33>: call 0x804934c <explode_bomb>
0x08048dae <+38>: mov $0x0,%eax
0x08048db3 <+43>: movsbl (%ebx,%eax,1),%edx
0x08048db7 <+47>: and $0xf,%edx
0x08048dba <+50>: movzbl 0x804a4b8(%edx),%edx
0x08048dc1 <+57>: mov %dl,0x15(%esp,%eax,1)
0x08048dc5 <+61>: add $0x1,%eax
0x08048dc8 <+64>: cmp $0x6,%eax
0x08048dcb <+67>: jne 0x8048db3 <phase_5+43>
0x08048dcd <+69>: movb $0x0,0x1b(%esp)
0x08048dd2 <+74>: movl $0x804a48e,0x4(%esp)
0x08048dda <+82>: lea 0x15(%esp),%eax
0x08048dde <+86>: mov %eax,(%esp)
0x08048de1 <+89>: call 0x8049044 <strings_not_equal>
0x08048de6 <+94>: test %eax,%eax
0x08048de8 <+96>: je 0x8048def <phase_5+103>
0x08048dea <+98>: call 0x804934c <explode_bomb>
0x08048def <+103>: mov 0x1c(%esp),%eax
0x08048df3 <+107>: xor %gs:0x14,%eax
0x08048dfa <+114>: je 0x8048e05 <phase_5+125>
0x08048dfc <+116>: lea 0x0(%esi,%eiz,1),%esi
0x08048e00 <+120>: call 0x8048810 <__stack_chk_fail@plt>
0x08048e05 <+125>: add $0x28,%esp
0x08048e08 <+128>: pop %ebx
0x08048e09 <+129>: ret
End of assembler dump.
答案 0 :(得分:1)
目前尚不清楚flyers
是什么,我认为这是一个正确的输入,你必须找到其他人。
重要的部分是<+47>
和<+50>
。它使用16字节的查找表来转换输入字符串。代码基本上是这样做的:
for(int i = 0; i != 6; i += 1) output[i] = table[input[i] & 0xf];
很明显,任何共享低4位的字符都会产生相同的输出(即使查找表中的值是唯一的)。例如,第一个字符f
具有ascii代码0x66,因此它由表条目0x06映射。这同样适用于0x06为低4位的任何字符,例如&
(0x26),6
(0x36),F
(0x46),V
(0x56) ,v
(0x76)。您可以将f
替换为其中任何一个(为简洁起见,省略了不可打印和完整的8位值)。您可以类似地计算出其他字母的等价性。
如果flyers
是必需的输出,那么你必须检查地址0x804a4b8
的查找表的内容,并为输入字符串提供映射到预期输出的正确字母。