为什么堆栈中还有另一个字节不是由局部变量分配的?

Why there is another bytes in stack which not allocated by local variables?

我尝试编写我的第一个 CTF 程序,它应该可以被缓冲区溢出利用。 为此,我执行了以下简单步骤:

  1. 创建了一个 main 函数
  2. 初始化了两个局部变量 - is_authorized(大小为 1 的字符)和 password(大小为 128 的数组)
  3. 禁用调试运行时检查 - 堆栈中不应有金丝雀

所以 main 看起来像这样:

int main()
{
    char is_authorized = 't';
    char password[128] = { 0 };

    return 0;
}

理论上变量应该是一个接一个入栈的,但真正发生的很奇怪的是,我在这两个局部变量之间多了三个奇怪的字节
这是我调试这个程序时的内存快照

0x0019FE70  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ...........................................
0x0019FE9B  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ...........................................
0x0019FEC6  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc  ..........................................ü
0x0019FEF1  fe 19 74 14 ff 19 00 63 23 41 00 01 00 00 00 70 4b 94 00 60 4e 94 00 01 00 00 00 70 4b 94 00 60 4e 94 00 70 ff 19 00 b7 21 41 00  þ.t.ÿ..c#A.....pK”.`N”.....pK”.`N”.pÿ..·!A.

正如您在快照中看到的,变量之间的堆栈上多了三个字节 - fc fe 19,因此我无法完成缓冲区溢出。 这些奇怪的字节是什么?我脑子里只想到保护机制,但是我禁用了这个,那还能是什么?

编辑: 对于它的价值,这里是反汇编:

int main()
{
004116D0  push        ebp  
004116D1  mov         ebp,esp  
004116D3  sub         esp,0C4h  
004116D9  push        ebx  
004116DA  push        esi  
004116DB  push        edi  
004116DC  mov         ecx,offset _CC196ACA_main@c (041B000h)  
004116E1  call        @__CheckForDebuggerJustMyCode@4 (04111FEh)  
    char is_authorized = 't';
004116E6  mov         byte ptr [is_authorized],74h  
    char password[128];
    return 0;
004116EA  xor         eax,eax  
}
004116EC  pop         edi  
004116ED  pop         esi  
004116EE  pop         ebx  
}
004116EF  mov         esp,ebp  
004116F1  pop         ebp  
004116F2  ret  

the variables should be one after another on the stack

不,没有这样的规定。只要副作用存在,编译器就应该做任何事情。一个好的优化编译器应该从你的代码中删除这两个变量。

What are these weird bytes? The only thought I have in mind is the protection mechanism, but I disabled this, then what else it could be?

堆栈上分配的变量之间的填充。您的非优化编译器分配与可被 4 整除的地址对齐的堆栈变量。因此在下一个 char 变量之间填充 3 个字节。字节的值很可能是程序初始化例程留在堆栈上的剩余垃圾。