- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我得到了一个最初用 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。我的理论是必须将字符串保存到 %edi/%edx/%eax 的第 80485db/de/e2 行,但我不明白这些字符串将如何存储在那里,而不是如何获取它们。我非常感谢更有经验的编码人员的任何帮助,因为这让我困惑了好几天。
最佳答案
您已经正确识别了 80485db
附近的临界区。让我们从 strcmp
调用开始倒退。比较需要两个操作数,它们在前两行从寄存器%eax
和%edx
入栈。我们可以看到%eax
是fgets
的返回值,也就是输入的文本。 %edx
由 mov (%edi,%ebx,4),%edx
加载,不幸的是它依赖于另外两个寄存器。 %edi
比较简单,它由mov $0x80498e4,%edi
设置为一个常量地址。 %ebx
在 804859d
处初始化为 1
,然后在 80485f3
处递增并与 5
进行比较> 稍后。因此我们可以看到它是循环计数器,显示我们正在处理的输入。将这些放在一起意味着 %edx
是从包含预期字符串的数组中加载的。第一个字符串将位于 0x80498e4+4
,因为 ebx 从 1 开始。因此,gdb 中的 x/5s *0x80498e8
应该会向您显示拆除炸弹所需的输入.
关于c - 了解有关 C 'bomb' 的 x86 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28816917/
在此处回答的另一个问题中,我发现了以下 JavaScript代码: function _dom_trackActiveElement(evt) { if (evt && evt.target)
if (A == 0) OR (B == 0) 怎么说? 最佳答案 只是为了讽刺: if (A === 0 || B === 0) 关于语法,我们在Stack Overflow上找到一个类似的问题:
var ret = [] ,xresult = document.evaluate(exp, rootEl, null, X
我一直在寻找一些类似于下例的 JavaScript。有人可以解释一下吗,因为我以前从未见过这样编写的 JavaScript。 “SomethingHere”和冒号代表什么?我习惯于看到函数 myFun
这是我的程序: delimiter // drop procedure if exists migContactToActor; create procedure migContactToActor(
我遇到了一个问题。我一直在使用 gcc 编译/汇编我的 C 代码一段时间,并且习惯了阅读 Intel 汇编语法。我在生成程序集文件时使用了 -masm=intel 标志。 但是最近因为公司迁移,拿到了
自上而下和自下而上语法有什么区别?举个例子就太好了。 最佳答案 首先,语法本身不是自上而下或自下而上的,解析器是(尽管有些语法可以被其中一个解析,但不能被另一个解析)。 从实践的角度来看,主要区别在于
我知道这是草率的代码,但它是: display dialog ("Start Screensaver. Please type: matrix, coffee, waffles, star, wate
这个问题已经有答案了: Giving name to a loop (6 个回答) 已关闭 8 年前。 我见过这个字符在 C# 中使用,就像 Java 中的扩展一样,但最近我在代码中发现了这个 loo
我正在尝试编写一个函数来检查字符串是否为回文,但我认为在使用字符串指针时存在一些错误。这段代码有什么问题? #include #include #define MAX 1000 int IsPalin
所以在this question我询问了一些 Javascript 是如何被压缩的。问题已得到解答,但以下片段让我非常困惑,以至于我不得不问另一个问题。在这里: for (Y = 0; $ = 'zx
假设我有一个接受这些参数的函数。 int create(Ptr * p,void * (*insert)(void *, void *)) { //return something later } 结
这个问题已经有答案了: Bitwise '&' operator (6 个回答) 已关闭 5 年前。 我在代码中找到了这个,但我从未遇到过像 & 这样的事情,仅 && if ((code & 1) =
我在处理继承类及其中的构造函数和方法的语法时遇到了问题。 我想实现一个类日期和一个子类 date_ISO,它们将按特定顺序设置给定的日、月、年,并通过一种方法将其写入字符串。我觉得我的基类日期工作正常
我正在尝试通过存储过程填充表,如下所示: SET @resultsCount = (SELECT COUNT(*) FROM tableA); SET @i = 0; WHILE @i THEN
谁能解释一下下面代码中的“<<”? mysql test<
刚刚开始学习 MySQL,这是一个菜鸟问题,也是我在 StackOverflow 上的第一个问题。 假设我有 12 个订单状态,我想从其中的 5 个中选择总计。我会使用: SELECT SUM(tot
我的编程背景是在学校学过一点Java。由于某些原因,JavaScript 语法往往让我感到困惑。下面的 JavaScript 代码是一种我不知道如何构成的语法模式: foo.ready = funct
我正在阅读 javascript 源代码,并且我以前没有编写过 javascript。我对它的一些语法感到困惑。 $(function () { window.onload=function
我什至不知道如何命名我想要的东西。那么让我举个例子来解释一下。 虽然火狐使用textContent,但其他浏览器支持innerText属性。顺便说一句,如果我使用了错误的术语,请纠正我。无论如何,到目
我是一名优秀的程序员,十分优秀!