【问题标题】:Overwriting of stack static array when the other static array overflows [closed]当另一个静态数组溢出时覆盖堆栈静态数组[关闭]
【发布时间】:2016-07-03 13:17:14
【问题描述】:
#include<stdio.h>

int main(){
  char A[10];
  char B[10];
  sprintf(A,"Hello");
  sprintf(B,"AAAAAAAAAABBBBBBBBBBCCCCCCCCCC");
  printf("%s:%s\n",A,B);
  return(0);
}

(gdb) p &A
$1 = (char (*)[10]) 0x7fffffffe450
(gdb) p &B
$2 = (char (*)[10]) 0x7fffffffe440
(gdb) step
2: B = "AAAAAAAAAA"
1: A = "BBBBCCCCCC"
printf o/p- BBBBCCCCCCCCCC:AAAAAAAAAABBBBBBBBBBCCCCCCCCCC

问题-

A 在堆栈帧中首先出现,B 在后面。如果 B 覆盖 A,那么所有 "BBBBBBBBBB" 都应该进入 A 为什么 A 从 "BBBBCCCCCCCCCC" 开始?

另外我想知道如果我覆盖BP,程序会终止吗?

【问题讨论】:

  • 因为堆栈向上增长,这就是为什么 A 从 BBBBCCCCCCCCCC 盯着看
  • 你们为什么对未定义的行为如此着迷?没有人说编译器必须以特定方式将这些自动变量放在内存中。他们甚至不需要在内存中! C 中不需要有栈!
  • 但是A应该从“BBBBBBBBBB....”开始
  • '在我的系统和环境中解释你没有的 UB'。 DCV:(
  • @AnttiHaapala 这可能是家庭作业。教授/助教在学期开始时设置了这样的作业,看看谁在作弊 - 'AAAAAAAAAABBBBBBBBBBCCCCCCCCCC' 字符串很容易被脚本在线发现,而且误报很少。

标签: c stack


【解决方案1】:

当然B 在堆栈中“在”A 之后出现,但是堆栈(通常,并且假设在您的平台上基于打印输出)会增长向下。注意B的地址小于A的地址。

所以B 的覆盖进入A

另外我认为 gdb 很聪明,只打印来自 B 的 10 个字符,因为它打印 10 A's 并且没有终止。

您不能使用流氓字符串格式覆盖处理器寄存器,寄存器不在内存中(通常,当然不在您可能使用的 x86 上)。

请注意,您的代码会调用未定义的行为,因此它可能会因此而终止。

【讨论】:

  • BP 是基指针,在 B 变量中写入 10 个 A 后,编译器实际上应该开始覆盖 A 变量,A 应该以 10 B 的“BBBBBBBBBB...”开头。
  • @SahilChodhary 你不能对这样的未定义行为进行推理。它是未定义的。没有定义。当然,您只需阅读编译器生成的实际机器代码,就可以更详细地了解您的实现发生了什么。
猜你喜欢
  • 2014-03-28
  • 2011-05-08
  • 1970-01-01
  • 2011-04-25
  • 2014-01-31
  • 2019-05-09
  • 1970-01-01
  • 2014-11-23
  • 2011-06-18
相关资源
最近更新 更多