Linux ELF文件格式分析---objcopy命令的使用
2017-06-27 12:10
344 查看
Linux ELF文件格式分析—objcopy命令的使用
最近在看《程序员的自我修养—链接、装载与库》一书,对书中提到的一个小问题,自己做了个试验验证一番,然后记录之。其具体问题如下:如果我们将一个二进制文件,比如图片,MP3音乐,词典一类的东西作为目标文件的一段,该怎么做?
可以使用objcopy工具,比如我们有一个图片文件”image.jpg” 大小为8846Bytes :
[james_xie@james-desk testforobjcopy]$ ls -al image.jpg -rw-rw-r-- 1 james_xie james_xie 8846 Jun 21 12:51 image.jpg [james_xie@james-desk testforobjcopy]$ objcopy -I binary -O elf64-x86-64 -B i386 image.jpg image.o [james_xie@james-desk testforobjcopy]$ objdump -ht image.o image.o: file format elf64-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .data 0000228e 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, ALLOC, LOAD, DATA SYMBOL TABLE: 0000000000000000 l d .data 0000000000000000 .data 0000000000000000 g .data 0000000000000000 _binary_test_jpg_start 000000000000228e g .data 0000000000000000 _binary_test_jpg_end 000000000000228e g *ABS* 0000000000000000 _binary_test_jpg_size
符号“_binary_test_jpg_start”,“ _binary_test_jpg_end”和“_binary_test_jpg_size”分别表示该图片文件在内存中的起始地址,结束地址和大小,我们可以在程序里面直接声明并使用它们。
下面结合一个简单的例子来尝试,新建一个文件名为test.c的文件:
#include <stdio.h> extern char _binary_test_jpg_start; extern char _binary_test_jpg_end; extern char _binary_test_jpg_size; int main() { int i = 0; unsigned char *p = NULL; printf("_binary_test_jpg_start 0x%lx\n",(unsigned long)&_binary_test_jpg_start); printf("_binary_test_jpg_end 0x%lx\n",(unsigned long)&_binary_test_jpg_end); printf("_binary_test_jpg_size %ld\n",(unsigned long)&_binary_test_jpg_size); p = (unsigned char *)(unsigned long)&_binary_test_jpg_start; printf("First 8 bytes of the Image : \n"); for(i=0;i<8;++i){ printf("0x%02x ",*p++); } printf("\n"); return 0; }
首先把该文件编译成目标文件(.o文件):
gcc -c test.c
链接生成最后的可执行文件:
gcc test.o image.o -o test
运行结果如下:
[james_xie@james-desk testforobjcopy]$ ./test _binary_test_jpg_start 0x601044 _binary_test_jpg_end 0x6032d2 _binary_test_jpg_size 8846 First 8 bytes of the Image : 0xff 0xd8 0xff 0xe0 0x00 0x10 0x4a 0x46
代码非常简单,没什么值得深入分析的,但是还有个小小的疑问,符号的值(即symbol’s value),通常可通过如下命令去查看:
[james_xie@james-desk testforobjcopy]$ objdump -t test test: file format elf64-x86-64 SYMBOL TABLE: ...... 0000000000601044 g .data 0000000000000000 _binary_test_jpg_start ...... 000000000000228e g *ABS* 0000000000000000 _binary_test_jpg_size 00000000006032d2 g .data 0000000000000000 _binary_test_jpg_end ......
为了更加直观,其他的符号表的输出结果被删除,其结果中第一列就是我所说的符号的值(即symbol’s value),按照我的理解这个值应该是该符号(symbol)的虚拟内存地址,为了验证我这个想法,我上面的例子代码中尝试去打印_binary_test_jpg_start开始位置的连续8个字节的值,跟我直接通过hexdump命令查看图片文件的值一样:
[james_xie@james-desk testforobjcopy]$ hexdump -C image.jpg 00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 |......JFIF......| 00000010 00 01 00 00 ff db 00 43 00 0f 0f 0f 0f 0f 0f 0f |.......C........| 00000020 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| *
这说明我的理解是对的,但是我还有个疑问就是这个符号“_binary_test_jpg_size”,这个符号的值(即symbol’s value)是000000000000228e,转换位十进制刚好是8846,即为我们图片文件的大小,这很明显应该不是一个地址,但是我上面的代码中,确确实实是通过
printf("_binary_test_jpg_size %ld\n",(unsigned long)&_binary_test_jpg_size);
地址取操作符&来访问的,而且如果我要是去掉这个地址操作符,如下方操作的话:
printf("_binary_test_jpg_size %ld\n",(unsigned long)_binary_test_jpg_size);
会直接出现:Segmentation fault (core dumped),即我们常碰到的段错误,这时我就有点方了,为了验证这个问题,我绝对去研究下objcopy的代码,看看它里面定义绝对符号(Absolute Symbol)表是具体怎么操作的,将在下一篇文章中来进行分析,未完待续。
相关文章推荐
- ArcGIS 切片缓存紧凑文件格式分析与使用
- OBJ文件格式分析工具: objdump, nm,ar
- Linux使用tcpdump命令抓包保存pcap文件wireshark分析
- ArcGIS 切片缓存紧凑文件格式分析与使用
- 文件加密的一种方法——如何使用Copy命令把文件和图片“复制”在一起
- ubuntu 文件权限命令详解使用格式和方法
- OBJ文件格式分析工具: objdump, nm,ar
- ubuntu 文件权限命令详解使用格式和方法
- ubuntu 文件权限命令详解使用格式和方法
- OBJ文件格式分析工具: objdump, nm,ar
- OBJ文件格式分析工具: objdump, nm,ar -- 转帖
- OBJ文件格式分析工具: objdump, nm,ar
- window下面使用copy命令把其它文件隐藏到图片中且图片能正常使用
- ubuntu 文件权限命令详解使用格式和方法
- OBJ材质文件MTL格式分析
- lib文件格式分析,以及从lib文件提取obj的思路和源码
- 使用 objcopy把图片文件转换为 ELF格式的 obj 文件
- 文件加密的一种方法——如何使用Copy命令把文件和图片“复制”在一起
- ELF格式文件符号表全解析及readelf命令使用方法