【发布时间】:2015-05-03 05:24:45
【问题描述】:
我收到了一个最初用 C 语言编写的可执行文件,用于玩猜谜游戏。我作为玩家应该猜 5 个数字,如果我猜对了,炸弹就不会爆炸。然而,一旦我错过了一个,我就输了,炸弹爆炸了。到目前为止,我解决这个问题的方法是反汇编可执行文件并尝试从那里读取解决方案。我知道在某些时候会调用 strcmp 函数,这意味着我的猜测与键值将在此之前存储到寄存器中。我迷失的是在哪里找到它,以及如何访问存储该数字的正确字符串。
这是我得到的汇编代码:
0804856a <main>:
804856a: 55 push %ebp
804856b: 89 e5 mov %esp,%ebp
804856d: 83 e4 f0 and $0xfffffff0,%esp
8048570: 57 push %edi
8048571: 56 push %esi
8048572: 53 push %ebx
8048573: 81 ec 14 02 00 00 sub $0x214,%esp //prologue code ends
8048579: 8b 35 fc 98 04 08 mov 0x80498fc,%esi
804857f: 83 7d 08 02 cmpl $0x2,0x8(%ebp)
8048583: 75 18 jne 804859d <main+0x33>
8048585: c7 44 24 04 fb 86 04 movl $0x80486fb,0x4(%esp)
804858c: 08
804858d: 8b 45 0c mov 0xc(%ebp),%eax
8048590: 8b 40 04 mov 0x4(%eax),%eax
8048593: 89 04 24 mov %eax,(%esp)
8048596: e8 65 fe ff ff call 8048400 <fopen@plt>
804859b: 89 c6 mov %eax,%esi
804859d: bb 01 00 00 00 mov $0x1,%ebx
80485a2: bf e4 98 04 08 mov $0x80498e4,%edi
80485a7: 3b 35 fc 98 04 08 cmp 0x80498fc,%esi
80485ad: 75 10 jne 80485bf <main+0x55>
80485af: 89 5c 24 04 mov %ebx,0x4(%esp)
80485b3: c7 04 24 fd 86 04 08 movl $0x80486fd,(%esp)
80485ba: e8 51 fe ff ff call 8048410 <printf@plt>
80485bf: 89 74 24 08 mov %esi,0x8(%esp)
80485c3: c7 44 24 04 00 02 00 movl $0x200,0x4(%esp)
80485ca: 00
80485cb: 8d 44 24 10 lea 0x10(%esp),%eax
80485cf: 89 04 24 mov %eax,(%esp)
80485d2: e8 09 fe ff ff call 80483e0 <fgets@plt>
80485d7: 85 c0 test %eax,%eax
80485d9: 74 22 je 80485fd <main+0x93>
80485db: 8b 14 9f mov (%edi,%ebx,4),%edx
80485de: 89 54 24 04 mov %edx,0x4(%esp)
80485e2: 89 04 24 mov %eax,(%esp)
80485e5: e8 56 fe ff ff call 8048440 <strcmp@plt> //call to strcmp, so the two parameters (my guess vs. key) must be stored before it.
80485ea: 85 c0 test %eax,%eax
80485ec: 74 05 break<main+0x89>
80485ee: e8 4d ff ff ff call 8048540 <bomb>
80485f3: 83 c3 01 add $0x1,%ebx
80485f6: 83 fb 05 cmp $0x5,%ebx
80485f9: 7e ac jle 80485a7 <main+0x3d>
80485fb: eb 05 jmp 8048602 <main+0x98>
80485fd: 83 fb 05 cmp $0x5,%ebx
8048600: 7e a5 jle 80485a7 <main+0x3d>
8048602: e8 19 ff ff ff call 8048520 <success>
8048607: b8 00 00 00 00 mov $0x0,%eax
804860c: 81 c4 14 02 00 00 add $0x214,%esp //epilogue code begins
8048612: 5b pop %ebx
8048613: 5e pop %esi
8048614: 5f pop %edi
8048615: 89 ec mov %ebp,%esp
8048617: 5d pop %ebp
8048618: c3 ret
到目前为止,在这个项目中,我一直在使用 GNU 调试器来尝试破解程序。但是,我似乎无法理解它。这是我第一次接触 x86 asm。我的理论是必须将字符串保存到 80485db/de/e2 行的 %edi/%edx/%eax 中,但我不明白这些字符串将如何存储在那里,而不是如何获取它们。我非常感谢更有经验的编码人员提供的任何帮助,因为这让我困惑了好几天。
【问题讨论】:
-
您没有明确提出问题 - 您是在尝试找出正确的数字序列,还是修补用户输入检查代码以使其始终通过?
-
可能没有存储正确数字的字符串。
-
在炸弹(监控你的击键)爆炸之前尝试逆向工程代码是一个更好的游戏;-)
-
在 Apple ][ Dracula's Castle 游戏中,如果您使用反汇编器或制表器查看代码,您会看到大量包含提示的字符串,这些提示都是红鲱鱼 -真实的东西不是那么容易看到的。
-
如果它确实是对硬编码字符串进行简单比较,您可以尝试在您的可执行文件上运行程序strings。即
strings <exename>
标签: c assembly x86 parameter-passing reverse-engineering