一、相关工具集
在Linux的实际开发中,与库相关的命令工具有很多,这些工具在前面也介绍了一部分,现在做一个相对全面的介绍,掌握了这些命令工具,会在实际开发中大大减少解决问题的思路,提高开发的效率。在查找和定位问题时,起到事半功倍的效果。
二、查看和分析工具
1、file
这个命令可以用来查看几乎所有类型的文件的详细信息
file [ -bchikLnNprsvz ] [ -f namefile ] [ -F separator ] [ -m magicfiles ] file ...
-b
只显示执行结果,不显示文件名
-c
这个是显示执行过程,在Linux命令中基本差不多
-f
显示文件中文件名的文件类型
-F
指定分隔符号替换输出文件名后的默认的“:”分隔符。
-i
输出mime类型的字符串
-L
显示相关软链接对应文件的文件类型
-z
尝试显示压缩文件的内容
看一下执行效果:
machine:~/dlltest$ file -b testdll.cpp
C source, ASCII text
machine:~/dlltest$ file testdll.cpp
testdll.cpp: C source, ASCII text
machine:~/dlltest$ file -c testdll.cpp
cont offset type opcode mask value desc
machine:~/dlltest$ file -f testdll.cpp
#include <iostream>: cannot open `#include <iostream>' (No such file or directory)
: cannot open `' (No such file or directory)
int Compare(int a,int b);: cannot open `int Compare(int a,int b);' (No such file or directory)
: cannot open `' (No such file or directory)
int main(): cannot open `int main()' (No such file or directory)
{: cannot open `{' (No such file or directory)
int a = 100;: cannot open `\011int a = 100;' (No such file or directory)
int b = 200;: cannot open `\011int b = 200;' (No such file or directory)
: cannot open `' (No such file or directory)
int max = Compare(a,b);: cannot open `\011int max = Compare(a,b);' (No such file or directory)
std::cout<<"max is :"<< max<< std::endl;: cannot open `\011std::cout<<"max is :"<< max<< std::endl;' (No such file or directory)
: cannot open `' (No such file or directory)
return 0;: cannot open `\011return 0;' (No such file or directory)
}: cannot open `}' (No such file or directory)
2、size
可以用来查看输入文件的段大小和总大小:
size [parms] [file]
参数:
size [-A|-B|--format=compatibility] 控制输出格式
[--help]
[-d|-o|-x|--radix=number] 输出的数据进制
[--common] 打印common symbols大小
[-t|--totals] 列出所有文件的总大小
[--target=bfdname] [-V|--version]
[objfile...]
默认是以十进制显示数据的。看一下执行命令:
machine:~/dlltest$ size dtest
text data bss dec hex filename
2483 704 280 3467 d8b dtest
machine:~/dlltest$ size -x dtest
text data bss dec hex filename
0x9b3 0x2c0 0x118 3467 d8b dtest
machine:~/dlltest$ size dc dtest
text data bss dec hex filename
3323 712 280 4315 10db dc
2483 704 280 3467 d8b dtest
3、strings
这个命令用来在二进制文件中查找可打印的字符串:
strings [ -a ] [ - ] [ -o ] [ -t Format ] [ -n Number ] [ -Number ] [file ... ]
-a --all:扫描整个文件
-f –print-file-name:显示文件名
-n –bytes=[number]:找到并输出终止符
- :设置显示字节数,默认4个
-t --radix={o,d,x} :输出字符的位置,基于八进制,十进制或者十六进制
-o :八进制 等于--radix=o
-T --target= :指定目标文件格式
最常用的是如果库的版本不对,会报编译错误缺少XXX函数,那么就可以用这个命令来试一下目前库是否版本低
machine:/usr/local/lib64$ strings libstdc++.so |grep GLIBCXX*
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_3.4.26
4、ldd
这个命令是用来查看文件依赖的,如果缺少库,可以用他来看:
ldd [option] [parms]
参数:
--version:显示版本
-v:显示详细信息
-u:显示未应用用直接依赖
-d:执行重定位并显示不存在的依赖
-r:执行数据对象和函数的重定位,并显示不存在的依赖
执行一下:
machine:~/dlltest$ ldd dtest
linux-vdso.so.1 (0x00007ffdb39f7000)
libdisplay.so => not found
libcompare.so => not found
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fea0eb7d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fea0e7df000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fea0e5c7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fea0e1d6000)
/lib64/ld-linux-x86-64.so.2 (0x00007fea0ef0b000)
不过ldd命令无法识别通过动态加载的动态库,最重要的是,这个命令可能会引起安全问题,因为一些版本的ldd可能会尝试执行程序来获得依赖信息,这就给病毒木马提供了机会,所以可以使用以下的两个命令来替换:
machine:~/dlltest$ objdump -p dtest|grep NEEDED
NEEDED libdisplay.so
NEEDED libcompare.so
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
machine:~/dlltest$ readelf -d dtest|grep NEEDED
0x0000000000000001 (NEEDED) 共享库:[libdisplay.so]
0x0000000000000001 (NEEDED) 共享库:[libcompare.so]
0x0000000000000001 (NEEDED) 共享库:[libstdc++.so.6]
0x0000000000000001 (NEEDED) 共享库:[libm.so.6]
0x0000000000000001 (NEEDED) 共享库:[libgcc_s.so.1]
0x0000000000000001 (NEEDED) 共享库:[libc.so.6]
5、nm
显示目标文件的符号表:
nm [option] [parms]
-A:显示文件名
-D:显示动态符号
-g:只显示外部符号
-r:逆序显示符号表
执行一下命令:
machine:~/dlltest$ nm -g libcompare.so
0000000000201038 B __bss_start
U __cxa_atexit@@GLIBC_2.2.5
w __cxa_finalize@@GLIBC_2.2.5
U Display
0000000000201038 D _edata
0000000000201040 B _end
00000000000007d8 T _fini
w __gmon_start__
0000000000000620 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000000745 T _Z7Compareii
U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4
U _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4
6、objdump
这个命令非常强大,强大到可以在WIN和LINUX上同时使用。它不但支持ELF,更是支持几十种其它格式的文件,提供了大量的针对二进制文件的分析信息。
其下命令最后都要跟目标文件地址和名称。
objdump -f:获得头信息
objdump -h:列出所有节
objdump -t(T) :列出所有符号(动态符号)
objdump -p:列查看动态节
objdump -R:查看重定位
objdump -s -j(节名称):查看节的数据
objdump -d -M intel:以intel方式查看汇编,前提是编译期提供了-g选项。
前边讲过这个,不再举例
7、readelf
这个命令只能看ELF文件。主要的用法有以下几个:
其下命令最后都要跟目标文件地址和名称。
readelf -h :用于获取目标头文件信息,比如上面的头就是用这个命令得到的。
readelf -S:是大写的S,是获得节的信息
readelf --symbols:用于得到文件内的符号。注意这里是两个-
readelf --dyn-syms:列出动态符号
readelf -d:只看动态节信息
readelf -r:查看重定位信息
readelf -x:查看指定节的信息
其它更多的可以用man命令或者查找相关资料。看一下执行查看指定节的命令。
三、部署工具
1、chrpath
这个工具可以改变rpath的路径,也就是可以修改依赖库的路径,好东西啊。
chrpath [-v|-d|-c|-r <path>] <program> [<program> ...]
参数:
-v|--version 显示版本号
-d|--delete 删除当前rpath/runpath设置
-c|--convert 覆盖上述设置
-r <path>|--replace <path> 用给定的路径覆盖上述路径
-l|--list 显示上述路径
看一下执行情况:
machine:~/dlltest$ ldd dtest
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8996e19000)
machine:~/dlltest$ chrpath -r "/usr/local/lib/" dtest
machine:~/dlltest$ ldd dtest
libstdc++.so.6 => /usr/local/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8996e19000)
如果没有这个命令,需要安装一下。
2、patchelf
这个功能和上面的类似也是修改runpath的路径。
patchelf --set-rpath [one or more paths] [executable]
执行命令:
machine:~/dlltest$ patchelf --set-rpath /usr/local/lib/ dtest
machine:~/dlltest$ readelf -d dtest
Dynamic section at offset 0x270 contains 31 entries:
标记 类型 名称/值
0x000000000000001d (RUNPATH) Library runpath: [/usr/local/lib/]
0x0000000000000001 (NEEDED) 共享库:[libdisplay.so]
0x0000000000000001 (NEEDED) 共享库:[libcompare.so]
0x0000000000000001 (NEEDED) 共享库:[libstdc++.so.6]
3、ldconfig
这个命令的重要性在于,如果在/etc/ld.so.conf中包含的目录中修改了依赖库文件,可以使用这个命令将其更新到/etc/ld.so.cache文件中,从而使路径生效。但是这个命令需要root权限。
四、运行分析工具
1、strace
追踪进程调用
strace [option] [file]
参数:
-tt 在每行输出的前面,显示毫秒级别的时间
-T 显示每次系统调用所花费的时间
-v 对于某些相关调用,把完整的环境变量,文件stat结构等打出来。
-f 跟踪目标进程,以及目标进程创建的所有子进程
-e 控制要跟踪的事件和跟踪行为,比如指定要跟踪的系统调用名称
-o 把strace的输出单独写到指定的文件
-s 当系统调用的某个参数是字符串时,最多输出指定长度的内容,默认是32个字节
-p 指定要跟踪的进程pid, 要同时跟踪多个pid, 重复多次-p选项即可。
执行一下:
machine:~/dlltest$ strace -tt ./dtest -o 1.log
18:20:27.732059 writev(2, [{iov_base="./dtest", iov_len=7}, {iov_base=": ", iov_len=2}, {iov_base="error while loading shared libra"..., iov_len=36}, {iov_base=": ", iov_len=2}, {iov_base="libdisplay.so", iov_len=13}, {iov_base=": ", iov_len=2}, {iov_base="cannot open shared object file", iov_len=30}, {iov_base=": ", iov_len=2}, {iov_base="No such file or directory", iov_len=25}, {iov_base="\n", iov_len=1}], 10./dtest: error while loading shared libraries: libdisplay.so: cannot open shared object file: No such file or directory
) = 120
18:20:27.732185 exit_group(127) = ?
18:20:27.732317 +++ exited with 127 +++
//如果跟踪某个进程可以:
strace -tt -T -v -f -e trace=file -o ./data.log -s 1024 -p 9879
跟踪某个执行文件启动调用:
strace -tt -T -f -e trace=file -o ./data.log -s 1024 ./exefilename
2、addr2line
这个可以通过崩溃的地址来回退到指定文件的位置,不过前提是要加上调试符号 -g.
addr2line [-b bfdname|--target=bfdname] [-C|--demangle[=style]] [-e filename|--exe=filename] [-f|--functions] [-s|--basename] [-i|--inlines] [-j|--section=name] [-H|--help] [-V|--version] [addr addr ...]
参数:
-b
指定目标文件的目标代码格式为bfdname。
-C
将低级符号名称解码(demangle)为用户级名称。去除c++改名机制产生的代码。
-e
指定应为其转换地址的可执行文件的名称。默认文件是a.out。
-f
显示函数名以及文件和行号信息。
-s
只显示每个文件名而不显示相关路径
-i
如果地址属于内联函数,则打印全部代码
-j
读取相对于指定节而不是绝对地址的偏移量。
假如taddr.cpp第6行做一个除0的动作,编译后执行,崩溃转储,使用gdb exe core得到地址就可以使用如下命令来操作:
machine:~/dlltest$ addr2line -C -f -e taddr 0x00000000004007c7
main
/dlltest/taddr.cpp:6
3、gdb
这个工具实在是太强大,请移步专门的分析篇章。
五、实例
使用上面的命令,看一个个体的例子的分析过程(例子使用前面创建的dtest):
1、确定文件类型
machine:~/dlltest$ file dtest
dtest: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped
machine:~/dlltest$ readelf -h dtest |grep 类型
类型: EXEC (可执行文件)
2、确定可执行文件入口
machine:~/dlltest$ objdump -f dtest|grep 起始
起始地址 0x0000000000400850
machine:~/dlltest$ readelf -h dtest |grep 入口
入口点地址: 0x400850
3、列出符号表
machine:~/dlltest$ readelf --dyn-syms dtest 动态链接符号
Symbol table '.dynsym' contains 17 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _Z7Compareii
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@GLIBC_2.2.5 (3)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcE@GLIBCXX_3.4 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNSolsEPFRSoS_E@GLIBCXX_3.4 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitC1Ev@GLIBCXX_3.4 (2)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNSolsEi@GLIBCXX_3.4 (2)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (3)
8: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
9: 0000000000601068 0 NOTYPE GLOBAL DEFAULT 23 _edata
10: 0000000000601198 0 NOTYPE GLOBAL DEFAULT 24 _end
11: 00000000004007d0 0 FUNC GLOBAL DEFAULT UND _ZSt4endlIcSt11char_trait@GLIBCXX_3.4 (2)
12: 00000000004007a8 0 FUNC GLOBAL DEFAULT 12 _init
13: 0000000000601068 0 NOTYPE GLOBAL DEFAULT 24 __bss_start
14: 0000000000400a54 0 FUNC GLOBAL DEFAULT 15 _fini
15: 0000000000601080 272 OBJECT GLOBAL DEFAULT 24 _ZSt4cout@GLIBCXX_3.4 (2)
16: 0000000000400840 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4 (2)
machine:~/dlltest$ objdump -t dtest 获取外部可见符号
dtest: 文件格式 elf64-x86-64
SYMBOL TABLE:
00000000003ff888 l d .interp 0000000000000000 .interp
00000000003ff8a8 l d .note.ABI-tag 0000000000000000 .note.ABI-tag
00000000003ff830 l d .hash 0000000000000000 .hash
00000000003ff7e8 l d .gnu.hash 0000000000000000 .gnu.hash
00000000003ff650 l d .dynsym 0000000000000000 .dynsym
00000000003ff4b0 l d .dynstr 0000000000000000 .dynstr
000000000040063e l d .gnu.version 0000000000000000 .gnu.version
0000000000400660 l d .gnu.version_r 0000000000000000 .gnu.version_r
00000000004006a0 l d .rela.dyn 0000000000000000 .rela.dyn
00000000004006e8 l d .rela.plt 0000000000000000 .rela.plt
00000000004007a8 l d .init 0000000000000000 .init
00000000004007c0 l d .plt 0000000000000000 .plt
0000000000400850 l d .text 0000000000000000 .text
0000000000400a54 l d .fini 0000000000000000 .fini
0000000000400a60 l d .rodata 0000000000000000 .rodata
0000000000400a70 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr
0000000000400ac0 l d .eh_frame 0000000000000000 .eh_frame
0000000000600da8 l d .init_array 0000000000000000 .init_array
0000000000600db8 l d .fini_array 0000000000000000 .fini_array
00000000003ff270 l d .dynamic 0000000000000000 .dynamic
0000000000600ff0 l d .got 0000000000000000 .got
0000000000601000 l d .got.plt 0000000000000000 .got.plt
0000000000601058 l d .data 0000000000000000 .data
0000000000601080 l d .bss 0000000000000000 .bss
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000400890 l F .text 0000000000000000 deregister_tm_clones
00000000004008c0 l F .text 0000000000000000 register_tm_clones
0000000000400900 l F .text 0000000000000000 __do_global_dtors_aux
0000000000601190 l O .bss 0000000000000001 completed.7409
0000000000600db8 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry
0000000000400930 l F .text 0000000000000000 frame_dummy
0000000000600da8 l O .init_array 0000000000000000 __frame_dummy_init_array_entry
0000000000000000 l df *ABS* 0000000000000000 testdll.cpp
0000000000400a64 l O .rodata 0000000000000001 _ZStL19piecewise_construct
0000000000601191 l O .bss 0000000000000001 _ZStL8__ioinit
000000000040098d l F .text 000000000000003e _Z41__static_initialization_and_destruction_0ii
00000000004009cb l F .text 0000000000000015 _GLOBAL__sub_I_main
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000400bfc l O .eh_frame 0000000000000000 __FRAME_END__
0000000000000000 l df *ABS* 0000000000000000
0000000000400a70 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR
0000000000600dc0 l O .dynamic 0000000000000000 _DYNAMIC
0000000000600db8 l .init_array 0000000000000000 __init_array_end
0000000000600da8 l .init_array 0000000000000000 __init_array_start
0000000000601000 l O .got.plt 0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000601068 g .data 0000000000000000 _edata
0000000000601058 w .data 0000000000000000 data_start
0000000000400a60 g O .rodata 0000000000000004 _IO_stdin_used
0000000000400932 g F .text 000000000000005b main
00000000004007d0 F *UND* 0000000000000000 _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4
0000000000601060 g O .data 0000000000000000 .hidden __dso_handle
0000000000400a54 g F .fini 0000000000000000 _fini
0000000000400880 g F .text 0000000000000002 .hidden _dl_relocate_static_pie
0000000000000000 F *UND* 0000000000000000 _Z7Compareii
0000000000000000 F *UND* 0000000000000000 __cxa_atexit@@GLIBC_2.2.5
0000000000400850 g F .text 000000000000002b _start
0000000000000000 F *UND* 0000000000000000 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4
0000000000000000 F *UND* 0000000000000000 _ZNSolsEPFRSoS_E@@GLIBCXX_3.4
00000000004007a8 g F .init 0000000000000000 _init
0000000000601068 g O .data 0000000000000000 .hidden __TMC_END__
0000000000601080 g O .bss 0000000000000110 _ZSt4cout@@GLIBCXX_3.4
0000000000601058 g .data 0000000000000000 __data_start
0000000000601198 g .bss 0000000000000000 _end
0000000000601068 g .bss 0000000000000000 __bss_start
0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4
00000000004009e0 g F .text 0000000000000065 __libc_csu_init
0000000000000000 F *UND* 0000000000000000 _ZNSolsEi@@GLIBCXX_3.4
0000000000400a50 g F .text 0000000000000002 __libc_csu_fini
0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.5
0000000000000000 w *UND* 0000000000000000 __gmon_start__
0000000000400840 F *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4
4、查看节的信息
machine:~/dlltest$ readelf -s dtest
Symbol table '.dynsym' contains 17 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _Z7Compareii
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@GLIBC_2.2.5 (3)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcE@GLIBCXX_3.4 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNSolsEPFRSoS_E@GLIBCXX_3.4 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitC1Ev@GLIBCXX_3.4 (2)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZNSolsEi@GLIBCXX_3.4 (2)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (3)
8: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
9: 0000000000601068 0 NOTYPE GLOBAL DEFAULT 23 _edata
10: 0000000000601198 0 NOTYPE GLOBAL DEFAULT 24 _end
11: 00000000004007d0 0 FUNC GLOBAL DEFAULT UND _ZSt4endlIcSt11char_trait@GLIBCXX_3.4 (2)
12: 00000000004007a8 0 FUNC GLOBAL DEFAULT 12 _init
13: 0000000000601068 0 NOTYPE GLOBAL DEFAULT 24 __bss_start
14: 0000000000400a54 0 FUNC GLOBAL DEFAULT 15 _fini
15: 0000000000601080 272 OBJECT GLOBAL DEFAULT 24 _ZSt4cout@GLIBCXX_3.4 (2)
16: 0000000000400840 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4 (2)
Symbol table '.symtab' contains 73 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000003ff888 0 SECTION LOCAL DEFAULT 6
2: 00000000003ff8a8 0 SECTION LOCAL DEFAULT 7
3: 00000000003ff830 0 SECTION LOCAL DEFAULT 5
5、查看段的信息
machine:~/dlltest$ objdump -p dtest
dtest: 文件格式 elf64-x86-64
程序头:
PHDR off 0x0000000000000040 vaddr 0x00000000003ff040 paddr 0x00000000003ff040 align 2**3
filesz 0x0000000000000230 memsz 0x0000000000000230 flags r--
STACK off 0x0000000000001000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
LOAD off 0x0000000000000000 vaddr 0x00000000003ff000 paddr 0x00000000003ff000 align 2**12
filesz 0x0000000000001000 memsz 0x0000000000001000 flags rw-
DYNAMIC off 0x0000000000000270 vaddr 0x00000000003ff270 paddr 0x00000000003ff270 align 2**3
filesz 0x0000000000000240 memsz 0x0000000000000240 flags rw-
INTERP off 0x0000000000000888 vaddr 0x00000000003ff888 paddr 0x00000000003ff888 align 2**0
filesz 0x000000000000001c memsz 0x000000000000001c flags r--
LOAD off 0x0000000000001000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**12
filesz 0x0000000000000c00 memsz 0x0000000000000c00 flags r-x
NOTE off 0x0000000000001254 vaddr 0x0000000000400254 paddr 0x0000000000400254 align 2**2
filesz 0x0000000000000020 memsz 0x0000000000000020 flags r--
EH_FRAME off 0x0000000000001a70 vaddr 0x0000000000400a70 paddr 0x0000000000400a70 align 2**2
filesz 0x000000000000004c memsz 0x000000000000004c flags r--
LOAD off 0x0000000000001da8 vaddr 0x0000000000600da8 paddr 0x0000000000600da8 align 2**12
filesz 0x00000000000002c0 memsz 0x00000000000003f0 flags rw-
RELRO off 0x0000000000001da8 vaddr 0x0000000000600da8 paddr 0x0000000000600da8 align 2**0
filesz 0x0000000000000258 memsz 0x0000000000000258 flags r--
动态节:
RUNPATH /usr/local/lib/
NEEDED libdisplay.so
NEEDED libcompare.so
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
INIT 0x00000000004007a8
FINI 0x0000000000400a54
INIT_ARRAY 0x0000000000600da8
INIT_ARRAYSZ 0x0000000000000010
FINI_ARRAY 0x0000000000600db8
FINI_ARRAYSZ 0x0000000000000008
HASH 0x00000000003ff830
GNU_HASH 0x00000000003ff7e8
STRTAB 0x00000000003ff4b0
SYMTAB 0x00000000003ff650
STRSZ 0x000000000000019d
SYMENT 0x0000000000000018
DEBUG 0x0000000000000000
PLTGOT 0x0000000000601000
PLTRELSZ 0x00000000000000c0
PLTREL 0x0000000000000007
JMPREL 0x00000000004006e8
RELA 0x00000000004006a0
RELASZ 0x0000000000000048
RELAENT 0x0000000000000018
VERNEED 0x0000000000400660
VERNEEDNUM 0x0000000000000002
VERSYM 0x000000000040063e
版本引用:
required from libc.so.6:
0x09691a75 0x00 03 GLIBC_2.2.5
required from libstdc++.so.6:
0x08922974 0x00 02 GLIBCXX_3.4
6、反汇编
machine:~/dlltest$ objdump -d -M intel dtest
dtest: 文件格式 elf64-x86-64
Disassembly of section .init:
00000000004007a8 <_init>:
4007a8: 48 83 ec 08 sub rsp,0x8
4007ac: 48 8b 05 45 08 20 00 mov rax,QWORD PTR [rip+0x200845] # 600ff8 <__gmon_start__>
4007b3: 48 85 c0 test rax,rax
4007b6: 74 02 je 4007ba <_init+0x12>
4007b8: ff d0 call rax
4007ba: 48 83 c4 08 add rsp,0x8
4007be: c3 ret
Disassembly of section .plt:
00000000004007c0 <.plt>:
4007c0: ff 35 42 08 20 00 push QWORD PTR [rip+0x200842] # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
4007c6: ff 25 44 08 20 00 jmp QWORD PTR [rip+0x200844] # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
4007cc: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
00000000004007d0 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@plt>:
4007d0: ff 25 42 08 20 00 jmp QWORD PTR [rip+0x200842] # 601018 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GLIBCXX_3.4>
4007d6: 68 00 00 00 00 push 0x0
4007db: e9 e0 ff ff ff jmp 4007c0 <.plt>
00000000004007e0 <_Z7Compareii@plt>:
4007e0: ff 25 3a 08 20 00 jmp QWORD PTR [rip+0x20083a] # 601020 <_Z7Compareii>
4007e6: 68 01 00 00 00 push 0x1
4007eb: e9 d0 ff ff ff jmp 4007c0 <.plt>
00000000004007f0 <__cxa_atexit@plt>:
4007f0: ff 25 32 08 20 00 jmp QWORD PTR [rip+0x200832] # 601028 <__cxa_atexit@GLIBC_2.2.5>
4007f6: 68 02 00 00 00 push 0x2
4007fb: e9 c0 ff ff ff jmp 4007c0 <.plt>
0000000000400800 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>:
400800: ff 25 2a 08 20 00 jmp QWORD PTR [rip+0x20082a] # 601030 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@GLIBCXX_3.4>
400806: 68 03 00 00 00 push 0x3
40080b: e9 b0 ff ff ff jmp 4007c0 <.plt>
0000000000400810 <_ZNSolsEPFRSoS_E@plt>:
400810: ff 25 22 08 20 00 jmp QWORD PTR [rip+0x200822] # 601038 <_ZNSolsEPFRSoS_E@GLIBCXX_3.4>
400816: 68 04 00 00 00 push 0x4
40081b: e9 a0 ff ff ff jmp 4007c0 <.plt>
7 、判断是否Debug
machine:~/dlltest$ readelf --debug-dump=line taddr
.debug_line 节的调试内容转储:
偏移: 0x0
长度: 1061
DWARF 版本: 2
导言长度: 993
最小指令长度: 1
“is_stmt”的初始值: 1
行基数: -5
行范围: 14
操作码基数: 13
操作码:
Opcode 1 has 0 args
Opcode 2 has 1 arg
Opcode 3 has 1 arg
Opcode 4 has 1 arg
Opcode 5 has 1 arg
Opcode 6 has 0 args
Opcode 7 has 0 args
Opcode 8 has 0 args
Opcode 9 has 1 arg
Opcode 10 has 0 args
Opcode 11 has 0 args
Opcode 12 has 1 arg
目录表 (偏移 0x1b):
1 /usr/local/include/c++/9.1.0
2 /usr/local/include/c++/9.1.0/bits
3 /usr/local/include/c++/9.1.0/x86_64-pc-linux-gnu/bits
4 /usr/local/include/c++/9.1.0/debug
5 /usr/local/include/c++/9.1.0/ext
6 /usr/local/lib/gcc/x86_64-pc-linux-gnu/9.1.0/include
7 /usr/include/x86_64-linux-gnu/bits/types
8 /usr/include/x86_64-linux-gnu/bits
9 /usr/include
文件名表 (偏移 0x163):
条目 目录 时间 大小 名称
1 0 0 0 taddr.cpp
2 1 0 0 iostream
8 、查看应用依赖项
machine:~/dlltest$ ldd dtest
linux-vdso.so.1 (0x00007ffd18f90000)
libdisplay.so => not found
libcompare.so => not found
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8941397000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8940ff9000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8940de1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f89409f0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8941725000)
或者特定的加载库
machine:~/dlltest$ ldconfig -p|grep display
//此处没有找到
9、使用strace追踪加载的动态库
这个已经介绍并运行了实例,此处不再赘述。
10、lsof显示当前打开的文件
//显示某个进程使用的文件
# lsof -c MeetingServer
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
MeetingSe 9032 root cwd DIR 253,1 4096 1186984 /root/projects/MeetingServer/build
MeetingSe 9032 root rtd DIR 253,1 4096 2 /
MeetingSe 9032 root txt REG 253,1 2446712 1187072 /root/projects/MeetingServer/build/MeetingServer
MeetingSe 9032 root mem REG 253,1 2151672 265443 /usr/lib64/libc-2.17.so
MeetingSe 9032 root mem REG 253,1 141968 265470 /usr/lib64/libpthread-2.17.so
MeetingSe 9032 root mem REG 253,1 88720 266411 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
MeetingSe 9032 root mem REG 253,1 1137024 265452 /usr/lib64/libm-2.17.so
MeetingSe 9032 root mem REG 253,1 995840 266421 /usr/lib64/libstdc++.so.6.0.19
MeetingSe 9032 root mem REG 253,1 163400 265153 /usr/lib64/ld-2.17.so
MeetingSe 9032 root 0w CHR 1,3 0t0 1028 /dev/null
MeetingSe 9032 root 1w REG 253,1 1285955 1187006 /root/projects/MeetingServer/build/1.log
MeetingSe 9032 root 2w REG 253,1 1285955 1187006 /root/projects/MeetingServer/build/1.log
MeetingSe 9032 root 3u IPv4 222350 0t0 TCP *:38888 (LISTEN)
MeetingSe 9032 root 4u a_inode 0,10 0 6487 [eventpoll]
MeetingSe 9032 root 5u a_inode 0,10 0 6487 [timerfd]
[root@iZj6c8dmrj7zr49bx5dnooZ ~]# lsof -c -p 9032
lsof: missing -c option value
lsof 4.87
latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
usage: [-?abhKlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-f[gG]] [+|-e s]
[-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+m [m]] [+|-M] [-o [o]] [-p s]
[+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]
Use the ``-h'' option to get more help information.
[root@iZj6c8dmrj7zr49bx5dnooZ ~]# lsof -p 9032
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
MeetingSe 9032 root cwd DIR 253,1 4096 1186984 /root/projects/MeetingServer/build
MeetingSe 9032 root rtd DIR 253,1 4096 2 /
MeetingSe 9032 root txt REG 253,1 2446712 1187072 /root/projects/MeetingServer/build/MeetingServer
MeetingSe 9032 root mem REG 253,1 2151672 265443 /usr/lib64/libc-2.17.so
MeetingSe 9032 root mem REG 253,1 141968 265470 /usr/lib64/libpthread-2.17.so
MeetingSe 9032 root mem REG 253,1 88720 266411 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
MeetingSe 9032 root mem REG 253,1 1137024 265452 /usr/lib64/libm-2.17.so
MeetingSe 9032 root mem REG 253,1 995840 266421 /usr/lib64/libstdc++.so.6.0.19
MeetingSe 9032 root mem REG 253,1 163400 265153 /usr/lib64/ld-2.17.so
MeetingSe 9032 root 0w CHR 1,3 0t0 1028 /dev/null
MeetingSe 9032 root 1w REG 253,1 1285955 1187006 /root/projects/MeetingServer/build/1.log
MeetingSe 9032 root 2w REG 253,1 1285955 1187006 /root/projects/MeetingServer/build/1.log
MeetingSe 9032 root 3u IPv4 222350 0t0 TCP *:38888 (LISTEN)
MeetingSe 9032 root 4u a_inode 0,10 0 6487 [eventpoll]
MeetingSe 9032 root 5u a_inode 0,10 0 6487 [timerfd]
lsof还可以恢复删除的文件,这里不介绍。此命令非常强大,可心查询相关资料。
六、总结
工欲善其事,必先利其器。