【错误记录】Android 应用漏洞修复处理 ( 无堆栈保护的 ELF 构建 SO 文件 | lib/armeabi-v7a/libijkffmpeg.so 安全检测出现问题 )

2024-06-24 10:59:17 浏览数 (2)

一、堆栈保护


在 gcc 编译器编译 C 语言代码时 , 如果添加了 -Wl,-z,nostackprotector 选项 , 就是构建一个没有 堆栈保护 的 ELF 格式的 共享对象 ( SO 文件 ) ;

堆栈保护 指的是 栈溢出保护 , Canary 值 ;

执行 readelf -sW example.so 命令 , 可以查询动态库是否启用了 堆栈保护 ;

二、gcc 编译选项 -fstack-protector


-fstack-protector 是 gcc 编译器 的 增强 堆栈保护的 选项 , 该选项可以增强程序的安全性 , 特别是对抗堆栈缓冲区溢出攻击 ;

" 堆栈保护 " 选项 -fstack-protector 的工作原理是在编译代码时插入一些保护代码 , 检测是否有堆栈溢出的发生 :

  • Canary 值 : 在函数的 栈帧 中插入一个特殊的 Canary 值 , 该值 放置在 函数的局部变量 和 控制数据 之间 , 用于检测堆栈缓冲区溢出 ;
  • 栈帧检查 : 函数返回之前 , 检查 Canary 值是否被修改 , 如果被修改 , 说明发生了堆栈溢出 , 直接终止程序 ;

三、解决方案


1、交叉编译动态库时设置 -fstack-protector 参数

在交叉编译动态库时 , 设置 -fstack-protector 参数 ;

这样编译出来的动态库 利用堆栈缓冲区溢出 的难度会增加 ;

2、Android.mk 配置

在 Android.mk 脚本中配置

代码语言:javascript复制
LOCAL_CFLAGS := -Wall -O2 -U_FORTIFY_SOURCE -fstack-protector-all

参数 ,

  • -Wall : 开启所有警告 ;
  • -O2 : 使用优化级别 2 , 进行代码优化 ;
  • -U_FORTIFY_SOURCE : 取消 _FORTIFY_SOURCE 的定义 , 这是用于增强安全性的宏定义 ;
  • -fstack-protector-all : 启用所有 堆栈保护 措施 ;

完整配置示例如下 :

代码语言:javascript复制
# 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)

3、CMakeLists.txt 配置

在 CMakeLists.txt 中配置如下编译选项 :

代码语言:javascript复制
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 : 启用所有 堆栈保护 措施 ;

完整配置示例如下 :

代码语言:javascript复制
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)

0 人点赞