news 2026/7/23 21:00:55

【2020-01-02】linux strip readelf nm 简单应用和安全分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【2020-01-02】linux strip readelf nm 简单应用和安全分析

[历史归档]本文原发布于 cstriker1407.info 个人博客,内容为历史存档,仅供参考。
发布时间:2020-01-02| 标题:linux strip readelf nm 简单应用和安全分析分类:操作系统 / linux / 安全 |标签:linux·常用命令·nm·安全·readelf·strip·逆向·cutter


linux strip readelf nm 简单应用和安全分析

    • strip
    • nm
    • readelf
    • strip -s VS strip
    • org VS strip-s
    • org VS strip -g
    • org VS strip -x
    • org VS strip -X
    • cutter安全分析

最近在搞编译优化和安全优化,话不多说,这里简单的笔记下使用记录吧,免得以后又忘了。

strip

strip - Discard symbols from object files.

$ strip-h用法:strip<选项>输入文件 从文件中删除符号和节 选项为:-I--input-target=<bfdname>Assume inputfileisinformat<bfdname>-O--output-target=<bfdname>Create an outputfileinformat<bfdname>-F--target=<bfdname>Set both input and outputformatto<bfdname>-p--preserve-dates Copy modified/access timestamps to the output-D--enable-deterministic-archives Produce deterministic output when stripping archives(default)-U--disable-deterministic-archives Disable-Dbehavior-R--remove-section=<name>Also remove section<name>from the output --remove-relocations<name>Remove relocations from section<name>-s--strip-all Remove all symbol and relocation information-g-S-d--strip-debug Remove all debugging symbols&sections --strip-dwo Remove all DWO sections --strip-unneeded Remove all symbols not needed by relocations --only-keep-debug Strip everything but the debug information-M--merge-notes Remove redundant entriesinnote sections(default)--no-merge-notes Do not attempt to remove redundant notes-N--strip-symbol=<name>Do not copy symbol<name>-K--keep-symbol=<name>Do not strip symbol<name>--keep-file-symbols Do not stripfilesymbol(s)-w--wildcardPermit wildcardinsymbol comparison-x--discard-all Remove all non-global symbols-X--discard-locals Remove any compiler-generated symbols-v--verboseList all object files modified-V--versionDisplay this program's version number-h--helpDisplay this output--infoList object formats&architectures supported-o<file>Place stripped output into<file>strip:支持的目标: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 plugin srec symbolsrec verilog tekhex binary ihex 将 bug 报告到<http://www.sourceware.org/bugzilla/>

nm

nm - list symbols from object files.

nm-h用法:nm[选项][文件]列举[文件]中的符号(默认为 a.out)。 The options are: -a, --debug-syms Display debugger-only symbols -A, --print-file-name Print name of the inputfilebefore every symbol-BSame as--format=bsd -C, --demangle[=STYLE]Decode low-level symbol names into user-level names The STYLE,ifspecified, can be`auto'(the default),`gnu', `lucid',`arm',`hp', `edg',`gnu-v3',`java' or `gnat'--no-demangle Do not demangle low-level symbol names -D,--dynamicDisplay dynamic symbols instead of normal symbols --defined-only Display only defined symbols-e(ignored)-f,--format=FORMAT Use the outputformatFORMAT. FORMAT can be`bsd',`sysv' or `posix'.The default is `bsd' -g, --extern-only Display only external symbols -l, --line-numbers Use debugging information to find a filename and line number for each symbol -n, --numeric-sort Sort symbols numerically by address -o Same as -A -p, --no-sort Do not sort the symbols -P, --portability Same as --format=posix -r, --reverse-sort Reverse the sense of the sort --plugin NAME Load the specified plugin -S, --print-size Print size of defined symbols -s, --print-armap Include index for symbols from archive members --size-sort Sort symbols by size --special-syms Include special symbols in the output --synthetic Display synthetic symbols as well -t, --radix=RADIX Use RADIX for printing symbol values --target=BFDNAME Specify the target object format as BFDNAME -u, --undefined-only Display only undefined symbols --with-symbol-versions Display version strings after symbol names -X 32_64 (ignored) @FILE Read options from FILE -h, --help Display this information -V, --version Display this program's version number nm:支持的目标: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 plugin srec symbolsrec verilog tekhex binary ihex 将 bug 报告到<http://www.sourceware.org/bugzilla/>

readelf

readelf - Displays information about ELF files.

$ readelf-H用法:readelf<选项>elf-文件 显示关于 ELF 格式文件内容的信息 Options are:-a--allEquivalent to:-h-l-S-s-r-d-V-A-I-h--file-header Display the ELFfileheader-l--program-headers Display the program headers--segmentsAnaliasfor--program-headers-S--section-headers Display the sections' header--sectionsAnaliasfor--section-headers-g--section-groups Display the sectiongroups-t--section-details Display the section details-e--headersEquivalent to:-h-l-S-s--symsDisplay the symbol table--symbolsAnaliasfor--syms--dyn-syms Display the dynamic symbol table-n--notesDisplay the core notes(if present)-r--relocsDisplay the relocations(if present)-u--unwindDisplay the unwind info(if present)-d--dynamicDisplay the dynamic section(if present)-V--version-info Display the version sections(if present)-A--arch-specific Display architecture specific information(if any)-c--archive-index Display the symbol/file indexinan archive-D--use-dynamic Use the dynamic section info when displaying symbols-x--hex-dump=<number|name>Dump the contents of section<number|name>as bytes-p--string-dump=<number|name>Dump the contents of section<number|name>as strings-R--relocated-dump=<number|name>Dump the contents of section<number|name>as relocated bytes-z--decompressDecompress section before dumping it-wor --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=gdb_index,=trace_info,=trace_abbrev,=trace_aranges,=addr,=cu_index,=links,=follow-links]Display the contents of DWARF debug sections --dwarf-depth=N Do not display DIEs at depth N or greater --dwarf-start=N Display DIEs starting with N, at the same depth or deeper-I--histogramDisplay histogram of bucket list lengths-W--wideAllow output width to exceed80characters @<file>Read options from<file>-H--helpDisplay this information-v--versionDisplay the version number of readelf 将 bug 报告到<http://www.sourceware.org/bugzilla/>

可以看出,strip是用来裁剪符号表的,nm和readelf是用来解析符号表的。这里具体分析下,首先建立几个对比文件,命令如下:

# 假定org是 -g 编译链接的一个可执行文件# 对org进行分析$ readelf-a-g-t--dyn-syms org>org.elf $ nm-lorg>org.nm# 使用strip默认参数进行裁剪$cporg default_strip $ strip default_strip $ readelf-a-g-t--dyn-syms default_strip>default_strip.elf $ nm-ldefault_strip>default_strip.nm#使用strip -s进行裁剪$cporg strip_all $ strip-sstrip_all $ readelf-a-g-t--dyn-syms strip_all>strip_all.elf $ nm strip_all>strip_all.nm#使用strip -g进行裁剪$cporg strip_dbg $ strip-gstrip_dbg $ readelf-a-g-t--dyn-syms strip_dbg>strip_dbg.elf $ nm strip_dbg>strip_dbg.nm#使用strip -x进行裁剪$cporg strip_x $ strip-xstrip_x $ nm strip_x>strip_x.nm $ readelf-a-g-t--dyn-syms strip_x>strip_x.elf#使用strip -X进行裁剪$cporg strip_X $ readelf-a-g-t--dyn-syms strip_X>strip_X.elf $ nm strip_X>strip_X.nm $ls-l#打印文件类型$fileorg org: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID=972680aa8cffbf12e21466a284eb6141d334ea12, with debug_info, not stripped $filedefault_strip default_strip: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID=972680aa8cffbf12e21466a284eb6141d334ea12, stripped $filestrip_all strip_all: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID=972680aa8cffbf12e21466a284eb6141d334ea12, stripped $filestrip_dbg strip_dbg: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID=972680aa8cffbf12e21466a284eb6141d334ea12, not stripped $filestrip_x strip_x: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID=972680aa8cffbf12e21466a284eb6141d334ea12, not stripped $filestrip_X strip_X: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID=972680aa8cffbf12e21466a284eb6141d334ea12, with debug_info, not stripped#打印文件大小$ls-l总用量90676-rwxr-xr-x1cstriker1407 cstriker14078371601217:28 default_strip -rw-r--r--1cstriker1407 cstriker1407588081217:28 default_strip.elf -rw-r--r--1cstriker1407 cstriker140701217:37 default_strip.nm -rwxr-xr-x1cstriker1407 cstriker140716262721217:13 org -rw-r--r--1cstriker1407 cstriker14072653521217:26 org.elf -rw-r--r--1cstriker1407 cstriker14072764221217:27 org.nm -rwxr-xr-x1cstriker1407 cstriker14078371601217:39 strip_all -rw-r--r--1cstriker1407 cstriker1407588081217:39 strip_all.elf -rw-r--r--1cstriker1407 cstriker140701217:39 strip_all.nm -rwxr-xr-x1cstriker1407 cstriker14079458801217:40 strip_dbg -rw-r--r--1cstriker1407 cstriker14072572651217:40 strip_dbg.elf -rw-r--r--1cstriker1407 cstriker1407970711217:40 strip_dbg.nm -rwxr-xr-x1cstriker1407 cstriker14078996881217:40 strip_x -rw-r--r--1cstriker1407 cstriker14071710521217:41 strip_x.elf -rw-r--r--1cstriker1407 cstriker1407529201217:41 strip_x.nm -rwxr-xr-x1cstriker1407 cstriker140716262721217:41 strip_X -rw-r--r--1cstriker1407 cstriker14072653521217:41 strip_X.elf -rw-r--r--1cstriker1407 cstriker1407970711217:41 strip_X.nm

下面来详细分析下。

strip -s VS strip

通过文件大小和二进制对比,可以看出两个是一致的。因此可以认为strip默认选项即为 strip -s

org VS strip-s

对比下elf文件,我们可以发现,strip -s 才减掉了debug*,symtab和strtab,由于将symtab全部才裁剪掉了,因此nm也没有输出。

org VS strip -g

对比下elf文件,我们可以发现,strip -g 才减掉了debug*,symtab,strtab还存在,因此因此nm还是有输出的。但是对比nm输出文件可以看到,函数位置已经没有了。

org VS strip -x

对比下elf文件,我们可以发现,strip -x 才减掉了debug*,symtab进行了大量删减,只保留了很少一部分内容,因此还是有nm输出。

org VS strip -X

作者测试发现没有任何变动,就暂时不深究了。

cutter安全分析

我们使用strip对输出文件进行裁剪不仅仅是为了减小文件大小,还有一个很重要的原因是安全考虑。这里我们使用cutter对几个输出进行简单的分析,看下各个文件反汇编和定位核心函数的成本。

org

org包含了debug*,symtab,strtab,对org文件进行分析,可以非常直观的看到各个函数的名称,所在的符号表等,如下图所示:

通过函数搜索,就可以很容易的找到核心函数,然后尝试反编译,如下图:

可以看到,可以非常容易的看到函数执行流程,在汇编TAB页甚至可以看到函数所在的源文件的位置。

strip_dbg

strip_dbg去掉了debug*,包含了symtab,strtab,对strip_dbg文件进行分析,可以非常直观的看到各个函数的名称,所在的符号表等,如下图所示:

由于symtab存在,我们也可以很容易的通过函数搜索来定位到核心函数,进而看到函数执行流程。

strip_all

strip_all去掉了debug*,symtab,strtab,对strip_all文件进行分析,如下图所示:

可以看到,虽然函数流程依然被反汇编了,但是由于symtab被裁剪,反汇编后的函数可读性已经非常差了,定位核心函数就会变得比较困难。
综上,考虑到和文件大小和安全,作者这里建议使用strip默认参数,也就是strip -s,将debug*和symtab全部裁剪掉

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/23 20:58:42

linux的rename命令详解

Linux rename 命令超详细详解rename 是 Linux 系统中批量重命名文件 / 目录的专用命令&#xff0c;相比 mv 配合循环的写法更简洁高效。但它有两个语法完全不兼容的主流实现&#xff0c;这是绝大多数用户踩坑的根源&#xff1a;Perl 版 rename&#xff08;prename&#xff09;&…

作者头像 李华
网站建设 2026/7/23 20:54:51

AI原生应用中的函数调用技术解析与实践

1. AI原生应用中的函数调用革命去年我在开发一个智能客服系统时&#xff0c;第一次真正体会到AI原生应用的威力。传统开发中&#xff0c;我们需要为每个业务场景编写大量if-else逻辑&#xff0c;而采用函数调用机制后&#xff0c;大模型能够自主判断何时调用哪些API&#xff0c…

作者头像 李华
网站建设 2026/7/23 20:54:25

TI EtherCAT从站调试实战:从硬件排查到PDO映射优化

1. 项目概述&#xff1a;当EtherCAT从站“罢工”时&#xff0c;我们如何让它重新“跑”起来 在工业自动化产线上&#xff0c;一个EtherCAT从站节点的通信异常&#xff0c;可能导致整条产线停机&#xff0c;每分钟的损失都可能以万计。我经历过太多次这样的深夜紧急支援&#xf…

作者头像 李华
网站建设 2026/7/23 20:51:16

Django毕业设计-基于 Django 的高校学生综合素质考评管理系统 大学生德智体综测评分信息化管理系统(源码+LW+部署文档+全bao+远程调试+代码讲解等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/23 20:49:47

指纹浏览器时区与地理一致性:IP、GPS、WebRTC与语言环境的交叉验证对抗

更多内容请见: 《指纹浏览器开发实战》 - 专栏介绍和目录 在指纹浏览器与风控系统的无声战役中,当开发者们将防御精力倾注于 Canvas 噪声注入、BoringSSL 字节级定制、以及 V8 引擎底层的物理级 Hook 时,往往会在一个极其基础却又极其致命的维度上遭遇毁灭性的降维打击。 这…

作者头像 李华