局部变量在堆栈上的顺序是什么?

时间:2018-08-14 21:28:15

标签: variables gcc c buffer stack

我目前正在尝试对缓冲区溢出漏洞进行一些测试。 这是易受攻击的代码

void win()
  {
      printf("code flow successfully changed\n");
  }

int main(int argc, char **argv)
  {
      volatile int (*fp)();
      char buffer[64];

      fp = 0;

      gets(buffer);

      if(fp) {
           printf("calling function pointer, jumping to 0x%08x\n", fp);
           fp();
             }
   }

该漏洞利用非常简单且非常基础:我在这里所需要的只是溢出缓冲区并覆盖fp值以使其持有win()函数的地址。 在尝试调试程序时,我发现fb放在缓冲区下方(即内存中的地址较低),因此我无法修改其值。 我以为,一旦我们在 y 之前声明了局部变量 x x 的内存就会更高(即在堆栈的底部),因此如果 x 超出其边界,则可以覆盖 y (此处不是这种情况)。 我正在使用gcc gcc版本5.2.1编译程序,没有特殊标志(仅已测试-O0)

有任何线索吗?

2 个答案:

答案 0 :(得分:2)

局部变量在堆栈上的顺序未定义。

在不同的编译器,不同的版本或不同的优化选项之间可能会有所不同。它甚至可能取决于变量的名称或其他看似无关的东西。

答案 1 :(得分:0)

直到编译/链接(构建)时间,才定义堆栈上局部变量的顺序。我当然不是专家,但是我认为您必须进行某种“十六进制转储”,或者也许在调试器环境中运行代码以找出分配位置。而且我还猜想这将是一个相对地址,而不是绝对地址。

正如@RalfFriedl在他的回答中指出的那样,在为不同平台等调用的任意数量的编译器选项下,位置可能会改变。

但是我们确实知道有可能发生缓冲区溢出。尽管由于防御措施(例如地址空间布局随机化(ASLR)),您现在对它们的了解有所减少,但它们仍然存在,并为我猜到的人付款。当然,有很多关于该主题的在线文章。这是一个看起来很新的https://www.synopsys.com/blogs/software-security/detect-prevent-and-mitigate-buffer-overflow-attacks/

祝您好运(您甚至应该对正在练习缓冲区溢出攻击的人说)?无论如何,我希望您能学到一些东西,并将其永久使用:)