栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

有关C语言中字符串入栈的理解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

有关C语言中字符串入栈的理解

C语言中字符串的入栈

写在前面
对于C语言中变量入栈的顺序实际上需要具体情况具体分析,不同操作系统下的编译器可能对此有不同的解释,即使对于同一个C的编译器而言,参数设定的不同也会导致编译器调整局部变量的入栈顺序,例如一种栈溢出的防护方案下,int类型的变量可能始终是最后入栈的。

本次实践利用的编译器版本是Windows下的64位编译器: x86_64-pc-cygwin-version 11.2.0

我们在test.c中编写如下代码,申请一个局部的字符数组,然后退出。

#include 
int main() {
    char str[5] = "abcdef";
    return 0;
}

在命令行编译输出汇编代码:

gcc -S test.c -o test.asm

得到如下的汇编代码(AT&T)

	.file	"test.c"
	.text
	.def	__main;	.scl	2;	.type	32;	.endef
	.globl	main
	.def	main;	.scl	2;	.type	32;	.endef
	.seh_proc	main
main:
	pushq	%rbp
	.seh_pushreg	%rbp
	movq	%rsp, %rbp
	.seh_setframe	%rbp, 0
	subq	$48, %rsp
	.seh_stackalloc	48
	.seh_endprologue
	call	__main
	movl	$1684234849, -7(%rbp)
	movw	$26213, -3(%rbp)
	movb	$0, -1(%rbp)
	movl	$0, %eax
	addq	$48, %rsp
	popq	%rbp
	ret
	.seh_endproc
	.ident	"GCC: (GNU) 11.2.0"

代码分析:

main之前的内容在说明函数入口与文件信息,暂时不讨论

.seh_*相关的伪指令是Windows提供的一套结构异常化处理的例程,可以暂时不讨论。

不过从指令名字上我们其实也能简单地了解它们在做什么,例如seh_stackalloc 48就是为堆栈段分配了48字节的空间。

详情可以查阅:https://sourceware.org/legacy-ml/binutils/2009-08/msg00193.html

抛开上述影响因素后,我们来看我们关心的部分,call __main指令之后的内容:

movl $1684234849, -5(%rbp)

转16进制后,左边立即数为 6463 6261H,即“abcd”的端序

movw $26213, -3(%rbp)

转16进制后,左边立即数为66 65H,即“ef”的端序

movb $0, -1(%rbp)

将‘’压入栈

因此我们的栈空间为

总结一下:将字符串压栈时,连续储存,开头的字符对应低地址,结尾字符对应高地址。

从这个原理上我们再理解一下熟知的缓冲区溢出攻击,如果攻击者输入的字符串大于申请的缓冲区长度,末尾多出来的字符串在栈内会向高地址延伸,覆盖掉栈中原有的数据。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/347661.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号