-z execstack对.so编译运行的影响及加载程序无执行栈时的运行表现
问题1:编译共享对象(.so)时使用
-z execstack参数的影响 编译阶段影响
- 该参数是传递给GNU链接器(ld)的标记,不会改变代码本身的编译生成逻辑,只会在最终生成的.so的ELF程序头中修改
PT_GNU_STACK段的权限标记,新增可执行(X)权限。 - 可通过命令验证标记是否生效:
- 执行
readelf -l your_lib.so | grep GNU_STACK,未加该参数时输出权限为RW,加参数后为RWE - 执行
execstack -q your_lib.so,输出标记为X即表示该库要求可执行栈
- 执行
执行阶段影响
- 加载该.so时,动态链接器会识别
PT_GNU_STACK的可执行标记,调整进程栈的内存权限。 - 会大幅降低进程安全防护能力:栈可执行后,攻击者可以直接执行注入到栈上的Shellcode,绕过NX(栈不可执行)防护机制。
问题2:主程序未设置可执行栈时该参数的生效逻辑
该参数不会被忽略,最终整个进程的所有线程栈都会具备可执行权限,原因如下:
- 栈属于进程全局的内存资源,不存在单个.so专属的栈帧权限,所有库的代码执行时共用当前线程的栈空间。
- Linux系统默认动态链接器(ld.so)的处理逻辑为:只要加载的任意ELF对象(主程序、任意动态链接库)的
PT_GNU_STACK标记要求可执行权限,就会将整个进程的栈内存设置为可执行,不会仅以主程序的标记为准。
注意:如果系统内核开启了强制栈不可执行的加固规则(如部分带PaX补丁的自定义内核),该标记可能会被内核强制覆盖,栈仍然不可执行,但常规发行版默认内核不会做该限制。
内容的提问来源于stack exchange,提问作者Aaa Bbb
相关产品推荐
相关产品推荐

