【2020-01-02】linux strip readelf nm 简单应用和安全分析
[历史归档]本文原发布于 cstriker1407.info 个人博客内容为历史存档仅供参考。发布时间2020-01-02 标题linux strip readelf nm 简单应用和安全分析分类操作系统 / linux / 安全 标签linux·常用命令·nm·安全·readelf·strip·逆向·cutterlinux strip readelf nm 简单应用和安全分析stripnmreadelfstrip -s VS striporg VS strip-sorg VS strip -gorg VS strip -xorg VS strip -Xcutter安全分析orgstrip\_dbgstrip\_all最近在搞编译优化和安全优化话不多说这里简单的笔记下使用记录吧免得以后又忘了。stripstrip - Discard symbols from object files.$ strip-h用法strip选项输入文件 从文件中删除符号和节 选项为-I--input-targetbfdnameAssume inputfileisinformatbfdname-O--output-targetbfdnameCreate an outputfileinformatbfdname-F--targetbfdnameSet both input and outputformattobfdname-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-sectionnameAlso remove sectionnamefrom the output --remove-relocationsnameRemove relocations from sectionname-s--strip-all Remove all symbol and relocation information-g-S-d--strip-debug Remove all debugging symbolssections --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-symbolnameDo not copy symbolname-K--keep-symbolnameDo not strip symbolname--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 programs version number-h--helpDisplay this output--infoList object formatsarchitectures supported-ofilePlace stripped output intofilestrip支持的目标 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/nmnm - 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--formatbsd -C, --demangle[STYLE]Decode low-level symbol names into user-level names The STYLE,ifspecified, can beauto(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,--formatFORMAT Use the outputformatFORMAT. FORMAT can bebsd,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 --formatposix -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, --radixRADIX Use RADIX for printing symbol values --targetBFDNAME 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 programs 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/。readelfreadelf - 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-dumpnumber|nameDump the contents of sectionnumber|nameas bytes-p--string-dumpnumber|nameDump the contents of sectionnumber|nameas strings-R--relocated-dumpnumber|nameDump the contents of sectionnumber|nameas 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-depthN Do not display DIEs at depth N or greater --dwarf-startN Display DIEs starting with N, at the same depth or deeper-I--histogramDisplay histogram of bucket list lengths-W--wideAllow output width to exceed80characters fileRead options fromfile-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 orgorg.elf $ nm-lorgorg.nm# 使用strip默认参数进行裁剪$cporg default_strip $ strip default_strip $ readelf-a-g-t--dyn-syms default_stripdefault_strip.elf $ nm-ldefault_stripdefault_strip.nm#使用strip -s进行裁剪$cporg strip_all $ strip-sstrip_all $ readelf-a-g-t--dyn-syms strip_allstrip_all.elf $ nm strip_allstrip_all.nm#使用strip -g进行裁剪$cporg strip_dbg $ strip-gstrip_dbg $ readelf-a-g-t--dyn-syms strip_dbgstrip_dbg.elf $ nm strip_dbgstrip_dbg.nm#使用strip -x进行裁剪$cporg strip_x $ strip-xstrip_x $ nm strip_xstrip_x.nm $ readelf-a-g-t--dyn-syms strip_xstrip_x.elf#使用strip -X进行裁剪$cporg strip_X $ readelf-a-g-t--dyn-syms strip_Xstrip_X.elf $ nm strip_Xstrip_X.nm $ls-l#打印文件类型$fileorg org: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID972680aa8cffbf12e21466a284eb6141d334ea12, 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,BuildID972680aa8cffbf12e21466a284eb6141d334ea12, stripped $filestrip_all strip_all: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID972680aa8cffbf12e21466a284eb6141d334ea12, stripped $filestrip_dbg strip_dbg: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID972680aa8cffbf12e21466a284eb6141d334ea12, not stripped $filestrip_x strip_x: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID972680aa8cffbf12e21466a284eb6141d334ea12, not stripped $filestrip_X strip_X: ELF64-bit LSB shared object, x86-64, version1(SYSV), dynamically linked, interpreter /lib64/l,forGNU/Linux3.2.0,BuildID972680aa8cffbf12e21466a284eb6141d334ea12, with debug_info, not stripped#打印文件大小$ls-l总用量90676-rwxr-xr-x1cstriker1407 cstriker14078371601月217:28 default_strip -rw-r--r--1cstriker1407 cstriker1407588081月217:28 default_strip.elf -rw-r--r--1cstriker1407 cstriker140701月217:37 default_strip.nm -rwxr-xr-x1cstriker1407 cstriker140716262721月217:13 org -rw-r--r--1cstriker1407 cstriker14072653521月217:26 org.elf -rw-r--r--1cstriker1407 cstriker14072764221月217:27 org.nm -rwxr-xr-x1cstriker1407 cstriker14078371601月217:39 strip_all -rw-r--r--1cstriker1407 cstriker1407588081月217:39 strip_all.elf -rw-r--r--1cstriker1407 cstriker140701月217:39 strip_all.nm -rwxr-xr-x1cstriker1407 cstriker14079458801月217:40 strip_dbg -rw-r--r--1cstriker1407 cstriker14072572651月217:40 strip_dbg.elf -rw-r--r--1cstriker1407 cstriker1407970711月217:40 strip_dbg.nm -rwxr-xr-x1cstriker1407 cstriker14078996881月217:40 strip_x -rw-r--r--1cstriker1407 cstriker14071710521月217:41 strip_x.elf -rw-r--r--1cstriker1407 cstriker1407529201月217:41 strip_x.nm -rwxr-xr-x1cstriker1407 cstriker140716262721月217:41 strip_X -rw-r--r--1cstriker1407 cstriker14072653521月217:41 strip_X.elf -rw-r--r--1cstriker1407 cstriker1407970711月217: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*symtabstrtab还存在因此因此nm还是有输出的。但是对比nm输出文件可以看到函数位置已经没有了。org VS strip -x对比下elf文件我们可以发现strip -x 才减掉了debug*symtab进行了大量删减只保留了很少一部分内容因此还是有nm输出。org VS strip -X作者测试发现没有任何变动就暂时不深究了。cutter安全分析我们使用strip对输出文件进行裁剪不仅仅是为了减小文件大小还有一个很重要的原因是安全考虑。这里我们使用cutter对几个输出进行简单的分析看下各个文件反汇编和定位核心函数的成本。orgorg包含了debug*symtabstrtab对org文件进行分析可以非常直观的看到各个函数的名称所在的符号表等如下图所示通过函数搜索就可以很容易的找到核心函数然后尝试反编译如下图可以看到可以非常容易的看到函数执行流程在汇编TAB页甚至可以看到函数所在的源文件的位置。strip_dbgstrip_dbg去掉了debug*包含了symtabstrtab对strip_dbg文件进行分析可以非常直观的看到各个函数的名称所在的符号表等如下图所示由于symtab存在我们也可以很容易的通过函数搜索来定位到核心函数进而看到函数执行流程。strip_allstrip_all去掉了debug*symtabstrtab对strip_all文件进行分析如下图所示可以看到虽然函数流程依然被反汇编了但是由于symtab被裁剪反汇编后的函数可读性已经非常差了定位核心函数就会变得比较困难。综上考虑到和文件大小和安全作者这里建议使用strip默认参数也就是strip -s将debug*和symtab全部裁剪掉。