- 论坛徽章:
- 0
|
最近在做下载模块,遇到一个问题,需要把待下载的文件信息(文件名,文件类型等)带在文件中用于下载传输时解析。
具体详细设计不在这里讲了,我只把遇到的问题贴下来。有2种解决方案:
1. 写一个fileConf文件记录所有的信息,用mktail工具把下载文件和fileconf文件合并在一起。下载到目标机上之后把fileconf解析出来。
2. linux可执行文件和*.so文件是linux elf文件,需要编译的时候把appInfo编译到elf的section中。
以上2种方法各有好处,基于应用的考虑,我们选择更好的第二种但是这样就需要解析elf文件。elf文件的格式不在此垒述,网上有很多文章,我把我的实验过程记录了下来:
1. 编辑一个test.c文件:
#include
int helloworld()
{
printf("hello world\n");
return 0;
}
int main()
{
helloworld();
return 0;
}
2. make编译生成elf可执行文件test
3. #arm-linux-readelf -a test > a.txt
a.txt中就可以直观的查看test这个elf文件的格式
4. #arm-linux-objdump -d test
把elf文件用反汇编查看其运行的汇编代码,其中:
0000837c :
837c: e92d4800 push {fp, lr}
8380: e28db004 add fp, sp, #4 ; 0x4
8384: e59f0014 ldr r0, [pc, #20] ; 83a0
8388: ebffffcb bl 82bc
838c: e3a03000 mov r3, #0 ; 0x0
8390: e1a00003 mov r0, r3
8394: e24bd004 sub sp, fp, #4 ; 0x4
8398: e8bd4800 pop {fp, lr}
839c: e12fff1e bx lr
83a0: 0000844c .word 0x0000844c
就是int helloworld()的反汇编出来的指令。
我们看到83a0:这行, 这行提供了word存放的地址,也就是hello world这条打印语句存放的地址是44c
5. 用二进制编辑器打开test,查找到地址0x0000044c刚好存放的就是hello world打印语句。
因此我们可以通过这样的方式把信息存为一条打印语句,且也能被解析出来。
如果在文件中加入全局变量,如:char *pString="abcdefghi";
那么abcdefghi是存放在.rodata这个section里面的,也可以找到其对应的地址,并查看解析。
我们也可以自己添加一个section,方法在这篇博客中:
http://www.lupaworld.com/?uid-151392-action-viewspace-itemid-128306
遗留问题:
1. 对应与动态连接库,我们就没有办法解析了,如果不加-fpic编译选项还可以,加上这个opt的话,.world的地址是不确定的
编译方式如下,读者可以自行研究:
#arm-linux-gcc -g -c -fPIC -o test.o test.c
#arm-linux-gcc -shared -o testso.so test.o
#arm-linux-readelf -a testso.so > a.txt
#arm-linux-objdump -d testso.so
2. 对于全局变量,这种方法也不可靠,在一个大型工程里面,全局变量存放的值可能被打断为几段存放,这个就是不可靠因素。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/99283/showart_2055312.html |
|