$ readelf -l main1... Section to Segment mapping:Segment Sections...0001.interp02.interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame03.init_array .fini_array .dynamic .got .got.plt .data .bss04.dynamic05.note.ABI-tag .note.gnu.build-id06.eh_frame_hdr0708.init_array .fini_array .dynamic .got在 Section to Segment mapping 中可以看到这些段的内容是跟对应section的内容重叠的,虽然一个segment可能对应多个section,但是可以根据内存的读写属性、内存特征以及对应段的一般顺序进行区分 。
如果程序中有比较详细的日志函数,我们还可以通过反编译工具的脚本拓展去修改 .symtab/.strtab 段来批量还原ELF文件的符号 , 从而高效地辅助动态调试 。
Binary Fuzzing考虑这么一种场景,我们在分析某个IoT设备时发现了一个定制的ELF网络程序,类似于httpd,其中有个静态函数负责处理输入数据 。现在想要单独对这个函数进行fuzz应该怎么做?直接从网络请求中进行变异是一种方法,但是网络请求的效率太低 , 而且触达该函数的程序逻辑也可能太长 。
既然我们已经了解了ELF , 那就可以有更好的办法将该函数抽取出来进行独立调用 。在介绍ELF类型的时候其实有提到,可执行文件可以有两种类型,即可执行类型( ET_EXEC )和共享对象( ET_DYN ),一个动态链接的可执行程序默认是共享对象类型的:
$ gcc hello.c -o hello$ readelf -h hello | grep TypeType:DYN (Shared object file)而动态库(.so)本身也是共享对象类型,他们之间的本质区别在于前者链接了libc并且定义了main函数 。对于动态库,我们可以通过 dlopen/dlsym 获取对应的符号进行调用,因此对于上面的场景,一个解决方式就是修改目标ELF文件 , 并且将对应的静态函数导出添加到dynamic section中,并修复对应的ELF头 。
这个思想其实很早就已经有人实现了,比如lief的 bin2lib。通过该方法,我们就能将目标程序任意的函数抽取出来执行 , 比如hugsy就用这个方式复现了Exim中的溢出漏洞(CVE-2018-6789) , 详见 Fuzzing arbitrary functions in ELF binaries ( 中文翻译 ) 。
总结本文主要介绍了32位环境下ELF文件的格式和布局 , 然后从内核空间和用户空间两个方向分析了ELF程序的加载过程,最后列举了几个依赖于ELF文件特性的案例进行具体分析,包括dynamic linker的滥用、程序加固和反加固以及在二进制fuzzing中的应用 。
ELF文件本身并不复杂,只有三个关键部分,只不过在section和segment的类型上保留了极大的拓展性 。操作系统可以根据自己的需求在不同字段上实现和拓展自己的功能,比如Linux中通过dymamic类型实现动态加载 。但这不是必须的,例如在Android中就通过ELF格式封装了特有的 .odex 、 .oat 文件来保存优化后的dex 。另外对于64位环境,大部分字段含义都是类似的,只是字段大小稍有变化(Elf32->Elf64),并不影响文中的结论 。
【elf是什么意思 elf是什么意思英语】作者:PansLabyrinth
推荐阅读
- ox是什么意思 ox是什么意思英语
- 梦到佛庙 梦到佛庙是什么征兆佛庙
- 梦到死去的陌生人 梦到死去的陌生人是什么意思
- 梦到水潭没水 梦到水潭没水什么意思
- 梦到水潭里好多鱼 梦到水潭里好多鱼什么意思
- 翡翠梅花的寓意是什么,翡翠花的寓意和象征
- 梦到水潭里洗衣服 梦到水潭里洗衣服什么意思
- 睡觉梦到鬼 睡觉梦到鬼是什么预兆
- 梦到在水潭里走动 梦到在水潭里走动什么意思
- 梦到水潭玩水 梦到水潭玩水什么意思