歡迎您光臨本站 註冊首頁

linux下ELF文件和動態庫,靜態庫分析

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

  本文使用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 指定需要查看的節區.


[火星人 ] linux下ELF文件和動態庫,靜態庫分析已經有402次圍觀

http://coctec.com/docs/linux/show-post-50639.html