linux 反编译 elf,带你认识Linux中的ELF文件

本文介绍了Linux下的ELF文件格式,包括可执行文件、可重定位文件和共享目标文件的特性。通过readelf和objdump工具展示了如何查看ELF文件的头部信息和反汇编内容,探讨了PIE在安全防护中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Linux系统使用过程中,我们经常会看到elf32-i386、ELF 64-bit LSB等字样。那么究竟ELF是什么呢?

几种常见的ELF文件

在Linux下,我们经gcc编译之后生成的可执行文件属于ELF文件:

97578aeddd629dd236422ce4ee0bd80a.png

ELF是一类文件类型,而不是特指某一后缀的文件。ELF(Executable and Linkable Format,可执行与可链接格式)文件格式,在Linux下主要有如下三种文件:

可执行文件(.out):Executable File,包含代码和数据,是可以直接运行的程序。其代码和数据都有固定的地址 (或相对于基地址的偏移 ),系统可根据这些地址信息把程序加载到内存执行。

可重定位文件(.o文件):Relocatable File,包含基础代码和数据,但它的代码及数据都没有指定绝对地址,因此它适合于与其他目标文件链接来创建可执行文件或者共享目标文件。

共享目标文件(.so):Shared Object File,也称动态库文件,包含了代码和数据,这些数据是在链接时被链接器(ld)和运行时动态链接器(ld.so.l、libc.so.l、ld-linux.so.l)使用的。

ELF格式可结构大致为:

45605869529307276b41ce641670cb29.png

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。

实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。

readelf工具的使用

在Linux下,我们可以使用readelf 命令工具可以查看ELF格式文件的一些信息。下面我们先准备一个动态链接相关的demo:

60db60ad506927770f4f9a0874d0fd7d.png

文件1(main.c):

include "test.h"

int main(void)

{

print_hello();

return 0;

}

文件2(test.c):

include "test.h"

void print_hello(void)

{

printf("hello world\n");

}

文件3(test.h):

ifndef __TEST_H

#define __TEST_H

#include

void print_hello(void);

#endif

执行相关命令生成相关文件:.out文件、.o文件、.so文件。如:

7dbd57bd72cb31143ff1bd561b635693.png

下面我们使用readelf命令来查看这三类文件的一些信息。readelf命令格式为:

readelf elf-file(s)

查看可执行文件头部信息:

38522accda0e0252161152b80ffe26fd.png

查看可执行文件头部信息是,我们发现这样一个问题,头部信息中的类型竟然是共享库文件,而我们查看的是可执行文件,自相矛盾?

查了一些资料发现:gcc编译默认加了--enable-default-pie选项:

99fcedef09fe45dc0a866c21a7c2ad92.png

Position-Independent-Executable是Binutils,glibc和gcc的一个功能,能用来创建介于共享库和通常可执行代码之间的代码–能像共享库一样可重分配地址的程序,这种程序必须连接到Scrt1.o。标准的可执行程序需要固定的地址,并且只有被装载到这个地址时,程序才能正确执行。PIE能使程序像共享库一样在主存任何位置装载,这需要将程序编译成位置无关,并链接为ELF共享对象。

引入PIE的原因是让程序能装载在随机的地址,通常情况下,内核都在固定的地址运行,如果能改用位置无关,那攻击者就很难借助系统中的可执行码实施攻击了。类似缓冲区溢出之类的攻击将无法实施。而且这种安全提升的代价很小。

也就是说,pie这是一种保护我们可执行程序的一种手段。这里我们只是做实验,我们可以加-no-pie参数先把pie给关掉:

735b660579a9b2c97b31833def8db87b.png

可以看到,类型终于对得上了。ELF头部信息还包含有Entry point address(入口地址)、Start of program headers(程序头的起始字节)、Start of section headers(节头的起始字节)等信息。

查看可重定位文件头部信息:

9cbafa42460eb156a740a9112ff80ea7.png

查看共享目标文件头部信息:

c5e8671f24876abd2a7a83e59f740928.png

同样的,readelf 搭配其它参数可以查看ELF文件的其它信息:

34824fb66678d7451419af73252bdde1.png

objdump工具的使用

objdump工具用于显示一个或多个目标文件的信息。objdump命令格式:

objdump

可执行文件、可重定位文件与共享目标文件都属于目标文件,所以都可以使用这个命令来查看一些信息。

查看可重定位文件反汇编信息:

d86fc542aeed4ac1fdc9798c5a975024.png

查看可执行文件反汇编信息:

1e13653695b4265b0a7a46bca3307234.png

查看共享目标文件反汇编信息:

fa926f7b736204cb5ec99cadb953639e.png

总结

以上就是本次的分享。简单地介绍了ELF文件的一些信息,同时介绍了分析ELF文件的两个工具。ELF文件的内容很多,并且比较抽象,详细分析起来是个深坑。我们大致先进行一个简单的了解,我现在还没有这个能力或者说还没有这个需求去学习、分析这些底层的东西,之后如果深入学习时再做另外的分享。有兴趣的同学可以跟我一起学

1 . 把apk拷到apktool根目录下,执行:./apktool d xxx.apk,会生成xxx目录,里面有res目录(各种资源文件),smali目录(类似src目录,里面文件的语法不一样)及AndroidManifest.xml。 [*.apk->*.jar: sh ./dex2jar/dex2jar.sh xxx.apk,生成xxx_dex2jar.jar通过jd-linux看源码] 2 . 什么apk汉化啊,就到res/values里string.xml里修改字符串,或者拷贝一份values目录改为values-zh-rCN,再去里面修改string.xml里英文字符串改为中文,所谓的汉化就是这么简单。另外,有些图片里不是中文的得去改图片,那得用Photoshop了,图片也不能乱改,格式,图片大小(尺寸)得原来的。 3 . 修改smali文件,这个有些难度。比如有些apk安装了后要积分什么的,比如大于100才可以用的,其实这个值是用SharedPreference存放的,也就是存在xml里,,位置:/data/data/[包名]/shared_prefs的某个xml里,文件不多肯定是可以找到的。另外一种方法就是修改.smali文件也可以达到这目的,软件实现肯定是读取积分那个值给它修改一下就可以了,例如 const/16 v0 100 (其实就是 v0 = 100)这个语法有点像汇编,觉得还是比汇编简单,v0 v1 ...是寄存器,之前会跟变量关联的。具体的还是自己看看smali语法。 4 . 打包生成apk,执行:./apktool b xxx,会在xxx里面生成,一个dist目录,里面就是xxx.apk,但不能安装滴,提示(Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]),没有给这个apk签名, 5 . 签名,执行:sh ./dex2jar/d2j-apk-sign.sh ./xxx/dist/xxx.apk 就是给刚才那个apk签名,生成的文件还是xxx.apk在apktool根目录下。这样就大功告成啦。 [请看:http://blog.youkuaiyun.com/zhouyuanjing/article/details/7446988]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值