试图拆解

时间:2015-02-07 22:36:42

标签: assembly reverse-engineering x86-64 att

该任务是解释一些汇编代码,以找到一个不会调用"爆炸炸弹"运行的短语。我正在使用gdb来反汇编当前阶段。我被困了,对于我是否朝着正确的方向前进的任何建议都会非常感激。

0x0000000000400fb5 <+0>:    sub    $0x18,%rsp           
0x0000000000400fb9 <+4>:    lea    0x8(%rsp),%r8
0x0000000000400fbe <+9>:    lea    0xf(%rsp),%rcx
0x0000000000400fc3 <+14>:   lea    0x4(%rsp),%rdx

我相信发生的事情是我们正在查看%rsp中的短语(基指针指向的内容)。我认为它在内存中保存了四个东西,分别是(%rsp),0x4(%rsp),0x8(%rsp)和0xf(%rsp),我认为它是三个整数和其他东西,但是我不确定是什么。

0x0000000000400fc8 <+19>:   mov    $0x4028f6,%esi           

地址$ 0x4028f6的值为“%d%c%d”。我知道它被移动到注册%esi,但我不确定如何使用它。

0x0000000000400fcd <+24>:   mov    $0x0,%eax            
0x0000000000400fd2 <+29>:   callq  0x400c80 <__isoc99_sscanf@plt>

不确定这里发生了什么。我查看了0x400c80,发现了以下内容:

0x0000000000400c80 <+0>:    jmpq   *0x20340a(%rip)          
0x0000000000400c86 <+6>:    pushq  $0x12
0x0000000000400c8b <+11>:   jmpq   0x400b50

我没有看到%rip被用作注册,因此我不太确定该做什么或在哪里看。我认为它将0x12放在%eax中,但是我不知道它在哪里跳跃,因为0x400b50不是有效地址。无论如何,回到原来的功能:

0x0000000000400fd7 <+34>:   cmp    $0x2,%eax            
0x0000000000400fda <+37>:   jg     0x400fe1 <phase_3+44>
0x0000000000400fdc <+39>:   callq  0x401719 <explode_bomb>

我认为我们只是在%eax上推了0x18,所以它肯定会大于0x2并且程序将跳过&#34;爆炸炸弹&#34;。我只是想知道在那之前我搞砸了。

2 个答案:

答案 0 :(得分:0)

不幸的是,您似乎缺少关键知识。你应该重温一下你可能拥有的任何材料,否则你会对其余的任务感到非常幸运,这实际上会涉及一些不那么简单的代码。

也就是说,到目前为止您引用的块只执行以下操作:

int x, y;
char c;
if (sscanf(foo, "%d %c %d", &x, &c, &y) <= 2) explode_bomb();

第一个块分配3个局部变量,并将每个变量的地址加载到相应sscanf参数的相应寄存器中。请注意,x86-64调用约定使用寄存器rdirsircxrdxr8r9作为前六个参数(假设它们是合适的)并且值在rax中返回。

您不需要查看0x400c80,您只能找到最终跳转到sscanf的PLT条目。我们已经从符号名称中了解了sscanf

答案 1 :(得分:0)

如果你自己弄清楚这会更有趣,所以我只是给出提示

  • 从堆栈指针中减去是一种在输入函数时为局部范围变量分配空间的相当标准的方法

  • google for intel opcodes,例如&#34; lea&#34;就像&#34;加载有效地址&#34;。它不加载数据

  • 谷歌sscanf,它是一个标准的C库函数,有一个C99 C语言标准。它从字符串中读取数据,并获取数据字符串,带有%-escaped转换说明符的格式字符串,以及指向放置扫描和转换数据的变量的指针。无需追踪sscanf的内部,但要查找其返回值

  • C函数最常返回%eax中的结果。 %eax在通话前被清除,并在通话后进行测试,并根据结果有条件地避免(或不通过)

这应该足以让你弄清楚。玩得开心!

相关问题