这里小结一下Linux二进制分析相关的环境与工具的基础知识。

Linux工具

Linux自带了很多常用的binutils工具,这些工具可在以下的URL中找到,其中包含许多用于二进制分析和破解的工具:http://www.gnu.org/software/binutils/

GDB

GNU Debuger,具体的不用多说。

GNU binutils中的objdump

object dump是一种对代码进行快速反编译的简介方案,在反编译简单的、未被篡改的二进制文件时较为有用,可以读取常用的ELF类型文件,但对于如恶意软件等较为复杂的反编译任务则显得局限。

主要缺点是需要依赖ELF节头,并且不会进行控制流分析。

一些常见用例:

查看ELF文件中所有节的数据或代码:

objdump -D \

只查看ELF文件中的程序代码:

objdump -d \

查看所有符号:

objdump -tf \

GNU binutils中的objcopy

object copy将目标文件的一部分或者全部内容拷贝到另外一个目标文件中,或者实现目标文件的格式转换。其可以分析和修改任意类型的ELF文件,修改ELF节,复制ELF节到ELF二进制中或反之。

要将.data节从一个ELF文件复制到另一个文件中可用以下命令:

objcopy -only-section=.data \ \

strace

system call trace系统调用追踪,是基于ptrace(2)系统调用的工具,通过在一个循环中使用PTRACE_SYSCALL请求来显示运行中程序的系统调用syscalls活动相关的信息以及程序执行中捕获到的信号量。

跟踪程序:

strace /bin/ls -o ls.out

附加到一个现存的进程上:

strace -p \ -o daemon.out

原始输出将会显示每个系统调用的文件描述编号,系统调用会将文件描述符作为参数,如下:

SYS_read(3, buf, sizeof(buf));

若想查看读入到文件描述符3中的所有数据,可执行如下命令:

strace -e read=3 /bin/ls

也可以使用-e write=fd命令查看写入的数据。

ltrace

library trace库追踪,与strace类似,用于解析共享库即一个程序的链接信息,并打印出用到的库函数。还可以使用-S参数查看系统调用。该命令通过解析可执行文件的动态段,并打印出共享库和静态库的实际符号和函数来提供更详细的信息。

ltrace \ -o program.out

ftrace

function trace函数追踪,与ltrace类似,另外还可以查看二进制文件本身的函数调用,可以在以下URL下载:https://github.com/elfmaster/ftrace

readelf

readelf是用于解析ELF二进制文件的工具。在进行反编译之前,需要手机目标文件相关的信息,该命令可以提供收集信息所需要的特定的ELF的所有数据。

查询节头表:readelf -S \

查询程序头表:readelf -l \

查询符号表:readelf -s \

查询ELF文件头数据:readelf -e \

查询重定位入口:readelf -r \

查询动态段:readelf -d \

ERESI——ELF反编译系统接口

ERESI工程包含了许多Linux二进制工具,具体查看http://www.eresi-project.org

设备和文件

/proc/<pid>/maps

/proc/\/maps文件保存了一个进程镜像的布局,通过展现每个内存映射来实现,展现的内容包括可执行文件、共享库、栈、堆和VDSO等。对于快速解析一个进程的地址空间分布十分有用。

/proc/kcore

/proc/kcore是proc文件系统的一项,是Linux内核的动态核心文件,是以ELF核心文件的形式所展现出来的原生内存转储。GDB可以使用/proc/kcore来对内核进行调试分析。

/boot/System.map

该文件几乎存在于所有的Linux版本中,包含了整个内核的所有符号。

/proc/kallsyms

/proc/kallsyms与/boot/System.map类似,/proc/kallsyms包含了内核中绝大部分的符号(若在CONFIG_KALLSYMS_ALL内核配置中指明则可以包含内核中全部的符号),区别是kallsyms是内核所属的/proc的一个入口并且可以动态更新。假如安装了新的LKM(Linux Kernel Module),符号会自动添加到/proc/kallsyms中。

/proc/iomem

/proc/iomem是一个proc入口,与/proc/\/maps类似,不过其是跟系统内存相关的。

例如,查询内核的text段所映射的物理内存位置,通过搜索Kernel便可以查看code/text段、data段和bss段的内容:

ECFS

Extended Core File Snapshot扩展核心文件快照,是一种核心转储技术,专门为进程镜像的高级取证分析所设计。可从该URL下载:https://github.com/elfmaster/ecfs

链接器相关环境指针

LD_PRELOAD环境变量

LD_PRELOAD环境变量可以设置成一个指定库的路径,动态链接时较其他库有着更高的优先级,允许预加载指定库中的函数和符号覆盖掉后续链接的库中的函数和符号。即可以通过重定向共享库函数来进行运行时修复。这项技术可用于绕过反调试代码,也可以用作用户机rootkit。

CTF中有示例参考HITB Binary 100。

LD_SHOW_AUXV环境变量

LD_SHOW_AUXV环境变量能够通知程序加载器来展示程序运行时的辅助向量。辅助向量是放在程序栈上的信息(通过内核的ELF常规加载方式),附带了传递给动态链接器的程序相关的特定信息。

链接器脚本

链接器脚本由链接器解释,把程序划分为节、内存和符号。gcc通过使用-T参数来指定链接器脚本。默认的链接器脚本可以使用ld –verbose命令查看: