为什么堆栈中还有另一个字节不是由局部变量分配的?
Why there is another bytes in stack which not allocated by local variables?
我尝试编写我的第一个 CTF 程序,它应该可以被缓冲区溢出利用。
为此,我执行了以下简单步骤:
- 创建了一个
main
函数
- 初始化了两个局部变量 -
is_authorized
(大小为 1 的字符)和 password
(大小为 128 的数组)
- 禁用调试运行时检查 - 堆栈中不应有金丝雀
所以 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 个字节。字节的值很可能是程序初始化例程留在堆栈上的剩余垃圾。
我尝试编写我的第一个 CTF 程序,它应该可以被缓冲区溢出利用。 为此,我执行了以下简单步骤:
- 创建了一个
main
函数 - 初始化了两个局部变量 -
is_authorized
(大小为 1 的字符)和password
(大小为 128 的数组) - 禁用调试运行时检查 - 堆栈中不应有金丝雀
所以 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 个字节。字节的值很可能是程序初始化例程留在堆栈上的剩余垃圾。