如何根据汇编指令识别此数组的长度?

逆向工程 数据库 缓冲区溢出
2021-06-30 02:13:03

在此处输入图片说明

在源代码中,我可以清楚地看到名为“buf”的数组长度为 32 字节,因为 1 个字符 = 1 个字节我假设该数组从地址 [rbp-0x30] 开始,并且 argv[ ] 存储在寄存器 rsi 和移到第 22 行的堆栈上。 以下是问题:

  • 首先,为什么是QWORD PTR?Qword 是 8 字节,当一个字符只有 1 字节时,这有什么意义
  • 我在哪里可以识别汇编代码中 buf 数组的 32 字节长度?
2个回答

我认为可以使用main+0x04is指令来估计局部变量的长度sub rsp, 0x30,即函数在堆栈上为局部变量分配的空间。在您的情况下,它是 (0x30) 48 个字节,所以我们现在知道局部变量都是 48 个字节或更少。 argcmain()通过edi寄存器提供给函数的,正如我们在 上看到的那样main+0x08,它被移动到偏移量 -0x24 处的分配堆栈空间中。

argc由于movat 指令,我们知道4 个字节的长度main+0x08,所以我想堆栈现在对齐如下:

  • From -0x30to -0x28=**argv指针,8 字节。
  • -0x24-0x20= argc,4 个字节。
  • -0x20下到存储的RBPqword = buf,32 个字节。


在此处输入图片说明

  1. 数组不以 @ 开头-30这其中的argv指针存储,即通知包含RSI的移动堆栈@ 22还通知指令26,其中8被添加到该指针,这样就可以访问argv[1]strcpy
  2. 数组存储在 @ 中-20数组必须从 -32 到 1(即从 -20h)存储。但是如果不分析完整的堆栈并预测其他变量的大小和位置,就无法知道这一点(假设您没有符号或不知道源代码)(这是一个非常小的程序,因此您可以以某种方式预测查看代码)。并且随着更多的优化,预测该数组的存在将变得非常困难。
  3. buff 的类型信息编译后丢失。这是类型恢复中非常常见的问题。
  4. 解决方法 - 如果您有源代码,则使用gcc -g标志编译此代码然后使用类似的东西检查符号表readelf
  5. 解决方法 - 一个简单的反编译器会将类型检测为 char 或 int 大小的标量,而像 ida pro 这样的专业反编译器将能够猜测正确的类型信息。