file
它的作用:帮助确定文件类型。
这将是你进行二进制分析的起点。我们每天都在与文件打交道,并非所有的文件都是可执行类型,除此之外还有各种各样的文件类型。在你开始之前,你需要了解要分析的文件类型。是二进制文件、库文件、ASCII 文本文件、视频文件、图片文件、PDF、数据文件等文件吗?
file 命令将帮助你确定你所处理的文件类型。
- $ file /bin/ls
- /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=94943a89d17e9d373b2794dcb1f7e38c95b66c86, stripped
- $
- $ file /etc/passwd
- /etc/passwd: ASCII text
- $
ldd
它的作用:打印共享对象依赖关系。
如果你已经在一个可执行的二进制文件上使用了上面的 file 命令,你肯定会看到输出中的“动态链接dynamically linked”信息。它是什么意思呢?
在开发软件的时候,我们尽量不要重造轮子。有一组常见的任务是大多数软件程序需要的,比如打印输出或从标准输入/打开的文件中读取等。所有这些常见的任务都被抽象成一组通用的函数,然后每个人都可以使用,而不是写出自己的变体。这些常用的函数被放在一个叫 libc 或 glibc 的库中。
如何找到可执行程序所依赖的库?这就是 ldd 命令的作用了。对动态链接的二进制文件运行该命令会显示出所有依赖库和它们的路径。
- $ ldd /bin/ls
- linux-vdso.so.1 => (0x00007ffef5ba1000)
- libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fea9f854000)
- libcap.so.2 => /lib64/libcap.so.2 (0x00007fea9f64f000)
- libacl.so.1 => /lib64/libacl.so.1 (0x00007fea9f446000)
- libc.so.6 => /lib64/libc.so.6 (0x00007fea9f079000)
- libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fea9ee17000)
- libdl.so.2 => /lib64/libdl.so.2 (0x00007fea9ec13000)
- /lib64/ld-linux-x86-64.so.2 (0x00007fea9fa7b000)
- libattr.so.1 => /lib64/libattr.so.1 (0x00007fea9ea0e000)
- libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fea9e7f2000)
- $
ltrace
它的作用:库调用跟踪器。
我们现在知道如何使用 ldd 命令找到一个可执行程序所依赖的库。然而,一个库可以包含数百个函数。在这几百个函数中,哪些是我们的二进制程序正在使用的实际函数?
ltrace 命令可以显示运行时从库中调用的所有函数。在下面的例子中,你可以看到被调用的函数名称,以及传递给该函数的参数。你也可以在输出的最右边看到这些函数返回的内容。