在 gcc 编译器编译 C 语言代码时 , 如果添加了 -Wl,-z,nostackprotector
选项 , 就是构建一个没有 堆栈保护 的 ELF 格式的 共享对象 ( SO 文件 ) ;
堆栈保护 指的是 栈溢出保护 , Canary 值 ;
执行 readelf -sW example.so
命令 , 可以查询动态库是否启用了 堆栈保护 ;
-fstack-protector
是 gcc 编译器 的 增强 堆栈保护的 选项 , 该选项可以增强程序的安全性 , 特别是对抗堆栈缓冲区溢出攻击 ;
" 堆栈保护 " 选项 -fstack-protector
的工作原理是在编译代码时插入一些保护代码 , 检测是否有堆栈溢出的发生 :
在交叉编译动态库时 , 设置 -fstack-protector
参数 ;
这样编译出来的动态库 利用堆栈缓冲区溢出 的难度会增加 ;
在 Android.mk 脚本中配置
LOCAL_CFLAGS := -Wall -O2 -U_FORTIFY_SOURCE -fstack-protector-all
参数 ,
-Wall
: 开启所有警告 ;-O2
: 使用优化级别 2 , 进行代码优化 ;-U_FORTIFY_SOURCE
: 取消 _FORTIFY_SOURCE 的定义 , 这是用于增强安全性的宏定义 ;-fstack-protector-all
: 启用所有 堆栈保护 措施 ;完整配置示例如下 :
# Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 编译选项
LOCAL_CFLAGS := -Wall -O2 -U_FORTIFY_SOURCE -fstack-protector-all
# 指定源文件
LOCAL_SRC_FILES := example.c
# 设置 .got.plt 的只读属性
LOCAL_LDFLAGS := -Wl,-z,relro,-z,now
# 指定生成的共享对象名称
LOCAL_MODULE := libexample
include $(BUILD_SHARED_LIBRARY)
在 CMakeLists.txt 中配置如下编译选项 :
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O2 -U_FORTIFY_SOURCE -fstack-protector-all")
-Wall
: 开启警告 ;-O2
: 启用优化级别 2 ;-U_FORTIFY_SOURCE
: 取消 _FORTIFY_SOURCE 的定义 , 这是用于增强安全性的宏定义 ;-fstack-protector-all
: 启用所有 堆栈保护 措施 ;完整配置示例如下 :
cmake_minimum_required(VERSION 3.0)
project(example_project C)
# 设置编译选项
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O2 -U_FORTIFY_SOURCE -fstack-protector-all")
# 添加可执行文件或共享对象
add_executable(example_executable example.c)
# 设置链接选项
target_link_options(example_executable PRIVATE -Wl,-z,relro,-z,now)