elf 文件信息的用途

--------------------------------------------------------------------------------
author:       hjjdebug
date:         2023年 10月 10日 星期二 15:11:53 CST
description:  elf 文件信息,
--------------------------------------------------------------------------------

目录:

1. 检查程序头, 判定重定位信息是否是只读的.                                                     

 $readelf -l ${1} | grep 'GNU_RELRO'

2. 检查是否存在符号表

$readelf -s ${1} |grep '.symtab'

3. canary 检测(金丝雀检测), 检查符号表中是否存在__stack_chk_fail函数调用

$readelf -s ${1} | grep '__stack_chk_fail'

4. 查看执行文件中有多少个函数调用了libc中的函数

参考下面详述.

1. 检查程序头, 判定重定位信息是否是只读的.
Program headers 信息
readelf -l ${1} | grep 'GNU_RELRO'  // 重定位信息只读后要继续查询:
readelf -d ${1} | grep 'BIND_NOW'  // 动态节中有'BIND_NOW'字符串 为"Full RELRO", 无该字串为"Partial RELRO"
readelf -l ${1} | grep 'GNU_STACK' |grep 'RWE'  //存在RWE 表示堆栈上有可执行权限


2. 检查是否存在符号表
readelf -s ${1} |grep '.symtab'
存在就是没有去除, 不存在就是去除了. 例如:
$readelf -s /bin/ls |grep '.symtab'  确认其没有符号表, /bin/ls 只有'.dynsym'
而我自己的一个程序, 则有符号表
$readelf -s multiview |grep '.symtab' |cut -d' ' -f5 可以获取符号个数.

$readelf -s multiview 输出详细的符号信息
$readelf -s multiview | grep '.symtab' 输出一行信息,如下:
Symbol table '.symtab' contains 28697 entries:
$readelf -s multiview |grep '.symtab' |cut -d' ' -f5 输出符号个数,如下:
28697

3. canary 检测(金丝雀检测), 检查符号表中是否存在__stack_chk_fail函数调用
$readelf -s "${1}" | grep '__stack_chk_fail'  // 符号表中存在__stack_chk_fail函数,表示有canary 保护,该函数是动态符号表中函数


综合测试:
4. 查看执行文件中有多少个函数调用了libc中的函数
步骤:
4.1. 查看执行文件的对外连接符号(动态连接符号), 用--dyn-syms
$readelf --dyn-syms multiview

4.2. 将输出净化, 只保留外部调用的函数名称
$readelf --dyn-syms multiview | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d'

查看libc 对外提供的函数
4.3. libc 中的符号信息, 以i386-linux-gnu 目录下libc 为例
$ readelf -s /usr/lib/i386-linux-gnu/libc.so.6

4.4. libc对外提供的函数名称一类是带 _chk 字符串的, 我们去掉修饰,只打印名称
$ readelf -s /usr/lib/i386-linux-gnu/libc.so.6 | sed -ne 's/.*__\(.*_chk\)@@.*/\1/p
另一类是不带_chk字符串的. 见后边sprintf 举例
把_chk去掉就是不带_chk 的函数名
用脚本可以这样写: 把输出送给变量保存
  FS_chk_func_libc="$(${readelf} -s $FS_libc 2>/dev/null | sed -ne 's/.*__\(.*_chk\)@@.*/\1/p')"
  FS_func_libc="$(echo "${FS_chk_func_libc}" | sed 's/_chk$//')"

举例, 以sprintf 为例, 去掉无关输出, 发现有sprintf(GLIBC_2.0引入), 同时也有 __sprintf_chk(GLIBC_2.3.4引入)
$ readelf -s /usr/lib/i386-linux-gnu/libc.so.6 | grep  sprintf
   178: 00050300    36 FUNC    GLOBAL DEFAULT   15 sprintf@@GLIBC_2.0
  2187: 00112b80    63 FUNC    GLOBAL DEFAULT   15 __sprintf_chk@@GLIBC_2.3.4


 4.5. 外部调用函数列表以及libc函数列表都已经准备好了, 现在我们来查询一下: 外部调用函数表中有多少个是libc的
 fgrep -xf <libc_file> f_file
 其中fgrep 就是 grep -F 的意思, 就是搜索固定的字符串
 -x 需要匹配整行才输出
 -f 指明后边的参数是一个文件,文件中包含了要搜索的字符串

 参考:

 以上知识来源于对 checksec "检查安全性"的shell源码分析, 确实有收获!
 要想脚本过硬, bash下的命令含义也要过硬!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值