[历史归档]本文原发布于 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安全分析
- org
- strip\_dbg
- strip\_all
最近在搞编译优化和安全优化,话不多说,这里简单的笔记下使用记录吧,免得以后又忘了。
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§ions --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 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*,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全部裁剪掉。