linux下ELF文件和动态库,静态库分析

本文使用readelf和objdump工具,对PPC处理器下的ELF可执行文件进行分析.
首先展示一下我们将要分析的对象:
[ygliu@publicPC-6 home]$ cat test.c
#include <stdio.h>

int main(void)
{
        myprintf();
        return 0;
}
[ygliu@publicPC-6 home]$ cat myprintf.c
#include <stdio.h>

void myprintf(void)
{
        printf("hello,ferrysnow!\n");
}

编译如下:
[ygliu@publicPC-6 home]$ ppc_85xx-gcc -c test.c
[ygliu@publicPC-6 home]$ ppc_85xx-gcc -c myprintf.c

查看生成的目标代码:
[ygliu@publicPC-6 home]$ ppc_85xx-readelf -h test.o | grep Type
Type:                              REL (可重定位文件)
[ygliu@publicPC-6 home]$ ppc_85xx-readelf -h myprintf.o | grep Type
Type:                              REL (可重定位文件)

将目标代码生成可执行文件:
[ygliu@publicPC-6 home]$ ppc_85xx-gcc -o test test.o myprintf.o
[ygliu@publicPC-6 home]$ ppc_85xx-readelf -h test | grep Type
Type:                              EXEC (可执行文件)
root@ppc:/home# ./test
hello,ferrysnow!

创建静态链接库:
[ygliu@publicPC-6 home]$ ppc_85xx-ar rcsv libmyprintf.a myprintf.o
a - myprintf.o
[ygliu@publicPC-6 home]$ ppc_85xx-readelf -h libmyprintf.a | grep Type
Type:                              REL (可重定位文件)
可以看出,静态链接库也是可重定位文件,它实际上是多个可重定位文件的集合.
使用静态链接库:
[ygliu@publicPC-6 home]$ ppc_85xx-gcc -o test test.o libmyprintf.a
root@ppc:/home# ./test
hello,ferrysnow!

创建动态链接库:
[ygliu@publicPC-6 home]$ ppc_85xx-gcc myprintf.o -shared -fPIC -o libmyprintf.so
[ygliu@publicPC-6 home]$ ppc_85xx-readelf -h libmyprintf.so | grep Type      
   Type:                              DYN (共享目标文件)
使用动态链接库:
[ygliu@publicPC-6 home]$ ppc_85xx-gcc -o testdyn test.o -lmyprintf -L./
root@ppc:/home# LD_LIBRARY_PATH=./ ./testdyn
hello,ferrysnow!
其中LD_LIBRARY_PATH用于指定动态链接库的搜索路径.

小结:
静态链接库和动态链接库由可重定位文件链接而成.
静态链接库由多个可重定位文件组成,并且在链接时加到可执行文件中去.
动态链接库在链接时,库文件本身并没有加到可执行文件中去,只是在可执行文件中加入了该库的名字等信息,以便在可执行文件运行过程中引用库中的函数时,由动态链接器去查找相关函数的地址,并调用它们.


ELF文件具有很大的灵活性,它通过文件头组织整个文件的总体结构,通过节区表 (Section Headers Table)和程序头(Program Headers Table或者叫段表)来分别描述可重定位文件和可执行文件。但不管是哪种类型,它们都需要它们的主体,即各种节区。在可重定位文件中,节区 表描述的就是各种节区本身;而在可执行文件中,程序头描述的是由各个节区组成的段(Segment),以便程序运行时动态装载器知道如何对它们进行内存映 像,从而方便程序加载和运行。先来看看 一些常见的节区.
[ygliu@publicPC-6 home]$ ppc_85xx-readelf -S myprintf.o
共有11 个节头,从偏移量 0x114开始:

节头:
[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
[ 0]                   NULL            00000000 000000 000000 00      0   0 0
[ 1] .text             PROGBITS        00000000 000034 000038 00 AX 0   0 4
[ 2] .rela.text        RELA            00000000 000388 000024 0c      9   1 4
[ 3] .data             PROGBITS        00000000 00006c 000000 00 WA 0   0 1
[ 4] .bss              NOBITS          00000000 00006c 000000 00 WA 0   0 1
[ 5] .rodata           PROGBITS        00000000 00006c 000014 00   A 0   0 4
[ 6] .note.GNU-stack   PROGBITS        00000000 000080 000000 00      0   0 1
[ 7] .comment          PROGBITS        00000000 000080 000040 00      0   0 1
[ 8] .shstrtab         STRTAB          00000000 0000c0 000052 00      0   0 1
[ 9] .symtab           SYMTAB          00000000 0002cc 0000a0 10     10   8 4
[10] .strtab           STRTAB          00000000 00036c 00001c 00      0   0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
[ygliu@publicPC-6 home]$ ppc_85xx-objdump -d -j .text myprintf.o

myprintf:文件格式 elf32-powerpc

反汇编 .text 节:

00000000 <myprintf>:
   0:   94 21 ff f0     stwu    r1,-16(r1)
   4:   7c 08 02 a6     mflr    r0
   8:   93 e1 00 0c     stw     r31,12(r1)
   c:   90 01 00 14     stw     r0,20(r1)
10:   7c 3f 0b 78     mr      r31,r1
14:   3d 20 00 00     lis     r9,0
18:   38 69 00 00     addi    r3,r9,0
1c:   48 00 00 01     bl      1c <myprintf+0x1c>
20:   81 61 00 00     lwz     r11,0(r1)
24:   80 0b 00 04     lwz     r0,4(r11)
28:   7c 08 03 a6     mtlr    r0
2c:   83 eb ff fc     lwz     r31,-4(r11)
30:   7d 61 5b 78     mr      r1,r11
34:   4e 80 00 20     blr
其中-d可以看到反汇编结果 -j 指定需要查看的节区.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值