assembly - 为什么buf的地址是0x12而不是10?
问题描述
我的代码如下:
#include <stdlib.h>
#include <unistd.h>
void myread () {
char s[10];
read(0, s, 100);
}
void getshell ()
{
system("/bin/bash");
}
int main ()
{
myread();
return 0;
}
我编译代码并使用ida pro打开二进制文件(gcc版本为5.4.0,操作系统为ubuntu 16.04,编译命令为“gcc -m32 -no-pie -fno-stack-protector stack_overflow.c - o stack_overflow "),我发现反汇编代码显示缓冲区s的地址是ebp - 12h,我只是想知道为什么不是ebp - 10?
ssize_t myread()
{
char buf; // [esp+6h] [ebp-12h]
return read(0, &buf, 0x64u);
}
myread()的反汇编代码如下:
.text:0804843B
.text:0804843B ; Attributes: bp-based frame
.text:0804843B
.text:0804843B public myread
.text:0804843B myread proc near ; CODE XREF: main+11↓p
.text:0804843B
.text:0804843B buf = byte ptr -12h
.text:0804843B
.text:0804843B ; __unwind {
.text:0804843B push ebp
.text:0804843C mov ebp, esp
.text:0804843E sub esp, 18h
.text:08048441 sub esp, 4
.text:08048444 push 64h ; nbytes
.text:08048446 lea eax, [ebp+buf]
.text:08048449 push eax ; buf
.text:0804844A push 0 ; fd
.text:0804844C call _read
.text:08048451 add esp, 10h
.text:08048454 nop
.text:08048455 leave
.text:08048456 retn
.text:08048456 ; } // starts at 804843B
.text:08048456 myread endp
myread()的栈如下,好像和栈保护机制无关
-00000018 ; D/A/* : change type (data/ascii/array)
-00000018 ; N : rename
-00000018 ; U : undefine
-00000018 ; Use data definition commands to create local variables and function arguments.
-00000018 ; Two special fields " r" and " s" represent return address and saved registers.
-00000018 ; Frame size: 18; Saved regs: 4; Purge: 0
-00000018 ;
-00000018
-00000018 db ? ; undefined
-00000017 db ? ; undefined
-00000016 db ? ; undefined
-00000015 db ? ; undefined
-00000014 db ? ; undefined
-00000013 db ? ; undefined
-00000012 buf db ?
-00000011 db ? ; undefined
-00000010 db ? ; undefined
-0000000F db ? ; undefined
-0000000E db ? ; undefined
-0000000D db ? ; undefined
-0000000C db ? ; undefined
-0000000B db ? ; undefined
-0000000A db ? ; undefined
-00000009 db ? ; undefined
-00000008 db ? ; undefined
-00000007 db ? ; undefined
-00000006 db ? ; undefined
-00000005 db ? ; undefined
-00000004 db ? ; undefined
-00000003 db ? ; undefined
-00000002 db ? ; undefined
-00000001 db ? ; undefined
+00000000 s db 4 dup(?)
+00000004 r db 4 dup(?)
+00000008
+00000008 ; end of stack variables
解决方案
为堆栈保护变量分配了额外的空间 - 我用红色突出显示了这个地方(我的代码编译为 x64 - 这不会改变本质)。如果你的缓冲区溢出,安全变量将被损坏,___stack_chk_fail 将被调用。
Hex-rays 反编译器在输出中隐藏了这个变量:
ssize_t myread()
{
char v1[10]; // [rsp+Eh] [rbp-12h] BYREF
return read(0, v1, 0x64uLL);
}
小提示:如果你想分析堆栈变量 - 双击反汇编器或反编译器输出中的任何变量 - 堆栈窗口将打开:
-0000000000000020 var_20 dq ?
-0000000000000018 db ? ; undefined
-0000000000000017 db ? ; undefined
-0000000000000016 db ? ; undefined
-0000000000000015 db ? ; undefined
-0000000000000014 db ? ; undefined
-0000000000000013 db ? ; undefined
-0000000000000012 s db 10 dup(?)
-0000000000000008 stack_protection dq ?
+0000000000000000 s db 8 dup(?)
+0000000000000008 r db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variables
推荐阅读
- php - PHP preg_match:带有+或*修饰符的多个组匹配不会出现在结果中?
- azure - 将消息从 Azure 事件中心路由到 Azure 服务总线
- javascript - 条不出现
- python - 通过与其他数据框列映射更改数据框列名称,Python 3.6
- c - 将生成的程序集重写为 GCC 内联程序集
- javascript - 当图像将在 Json 数据中时在 Array.map 中显示图像
- python - 获取所有动态和二级导入的名称
- sql - 具有开始和结束日期以及数据透视表的历史表
- php - 如何在 Eloquent 模型中创建复杂的虚拟列?
- s4sdk - 无法导入机器学习依赖项