试图拆卸
trying to disassemble
作业是解释一些汇编代码以找到一个将 运行 而无需调用 "explode bomb" 的短语。我正在使用 gdb 反汇编当前阶段。我被困住了,非常感谢任何关于我是否朝着正确方向前进的建议。
0x0000000000400fb5 <+0>: sub [=10=]x18,%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 [=11=]x4028f6,%esi
地址$0x4028f6 的值为“%d %c %d”。我知道它正在被转移到注册 %esi,但我不确定它是如何被使用的。
0x0000000000400fcd <+24>: mov [=12=]x0,%eax
0x0000000000400fd2 <+29>: callq 0x400c80 <__isoc99_sscanf@plt>
不确定这里发生了什么。我查看了 0x400c80 并发现了以下内容:
0x0000000000400c80 <+0>: jmpq *0x20340a(%rip)
0x0000000000400c86 <+6>: pushq [=13=]x12
0x0000000000400c8b <+11>: jmpq 0x400b50
我没有看到 %rip 被用作寄存器,所以我不太确定该做什么或去哪里找。我认为它将 0x12 放入 %eax,但我不确定它跳到哪里,因为 0x400b50 不是有效地址。无论如何,回到原来的功能:
0x0000000000400fd7 <+34>: cmp [=14=]x2,%eax
0x0000000000400fda <+37>: jg 0x400fe1 <phase_3+44>
0x0000000000400fdc <+39>: callq 0x401719 <explode_bomb>
我想我们只是将 0x18 推到 %eax 上,所以它肯定会大于 0x2,程序将跳过 "explode bomb"。我只想知道在那之前我在哪里搞砸了。
很遗憾,您似乎缺少关键知识。你应该重新审视你可能拥有的任何 material 否则你将不会对剩下的作业有太多的运气,这实际上将涉及一些不那么琐碎的代码。
也就是说,到目前为止您引用的块仅执行以下操作:
int x, y;
char c;
if (sscanf(foo, "%d %c %d", &x, &c, &y) <= 2) explode_bomb();
第一个块分配 3 个局部变量,并将每个变量的地址加载到相应 sscanf
参数的适当寄存器中。请注意,x86-64 调用约定使用寄存器 rdi
、rsi
、rcx
、rdx
、r8
和 r9
作为前六个参数(假设它们是合适的)并且值在 rax
.
中返回
你不需要看0x400c80
,你只需要找到最终跳转到sscanf
本身的PLT条目。我们已经从符号名称中知道它是 sscanf
。
如果你自己想出来会更有趣,所以我只是给出提示
从堆栈指针中减去是在进入函数时为局部范围变量分配 space 的一种相当标准的方法
google 用于 intel 操作码,例如 "lea" 类似于 "load effective address"。它不加载数据
google sscanf,一个标准的C库函数,有C99 C语言标准。它从字符串中读取数据,并获取一个数据字符串、一个带有 % 转义转换说明符的格式字符串,以及指向放置扫描和转换数据的变量的指针。无需追踪 sscanf 的内部结构,但请查看其 return 值
C 函数最常 return 它们的结果在 %eax 中。调用前清除%eax,调用后测试,根据结果有条件地避免(或不)炸弹
这应该足以让您弄明白。玩得开心!
作业是解释一些汇编代码以找到一个将 运行 而无需调用 "explode bomb" 的短语。我正在使用 gdb 反汇编当前阶段。我被困住了,非常感谢任何关于我是否朝着正确方向前进的建议。
0x0000000000400fb5 <+0>: sub [=10=]x18,%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 [=11=]x4028f6,%esi
地址$0x4028f6 的值为“%d %c %d”。我知道它正在被转移到注册 %esi,但我不确定它是如何被使用的。
0x0000000000400fcd <+24>: mov [=12=]x0,%eax
0x0000000000400fd2 <+29>: callq 0x400c80 <__isoc99_sscanf@plt>
不确定这里发生了什么。我查看了 0x400c80 并发现了以下内容:
0x0000000000400c80 <+0>: jmpq *0x20340a(%rip)
0x0000000000400c86 <+6>: pushq [=13=]x12
0x0000000000400c8b <+11>: jmpq 0x400b50
我没有看到 %rip 被用作寄存器,所以我不太确定该做什么或去哪里找。我认为它将 0x12 放入 %eax,但我不确定它跳到哪里,因为 0x400b50 不是有效地址。无论如何,回到原来的功能:
0x0000000000400fd7 <+34>: cmp [=14=]x2,%eax
0x0000000000400fda <+37>: jg 0x400fe1 <phase_3+44>
0x0000000000400fdc <+39>: callq 0x401719 <explode_bomb>
我想我们只是将 0x18 推到 %eax 上,所以它肯定会大于 0x2,程序将跳过 "explode bomb"。我只想知道在那之前我在哪里搞砸了。
很遗憾,您似乎缺少关键知识。你应该重新审视你可能拥有的任何 material 否则你将不会对剩下的作业有太多的运气,这实际上将涉及一些不那么琐碎的代码。
也就是说,到目前为止您引用的块仅执行以下操作:
int x, y;
char c;
if (sscanf(foo, "%d %c %d", &x, &c, &y) <= 2) explode_bomb();
第一个块分配 3 个局部变量,并将每个变量的地址加载到相应 sscanf
参数的适当寄存器中。请注意,x86-64 调用约定使用寄存器 rdi
、rsi
、rcx
、rdx
、r8
和 r9
作为前六个参数(假设它们是合适的)并且值在 rax
.
你不需要看0x400c80
,你只需要找到最终跳转到sscanf
本身的PLT条目。我们已经从符号名称中知道它是 sscanf
。
如果你自己想出来会更有趣,所以我只是给出提示
从堆栈指针中减去是在进入函数时为局部范围变量分配 space 的一种相当标准的方法
google 用于 intel 操作码,例如 "lea" 类似于 "load effective address"。它不加载数据
google sscanf,一个标准的C库函数,有C99 C语言标准。它从字符串中读取数据,并获取一个数据字符串、一个带有 % 转义转换说明符的格式字符串,以及指向放置扫描和转换数据的变量的指针。无需追踪 sscanf 的内部结构,但请查看其 return 值
C 函数最常 return 它们的结果在 %eax 中。调用前清除%eax,调用后测试,根据结果有条件地避免(或不)炸弹
这应该足以让您弄明白。玩得开心!