December 10, 2006

自我印列 ELF 簽名

[Jollen] 兄最近寫了不少 ELF 相關的文件,相當受益,作為「深入淺出 Hello World」系列演講的延伸資料相當合適,下次我會補進去。

在之前的演講提到 Linux Address space,我做了一張 slide: (click to enlarge)

當然,這是針對 IA32,我們可以看到 0x08048000 位址以上有兩個 segment,是 exec image 映射於記憶體空間的區域。hexdump 這個工具指定自訂印列格式,所以我寫了簡單的格式檔:
$ cat format 
"%04.4_ax  " 32/1 "%_p" "\n"
這個格式表示法為前面十六進位位址與 32 字元為一欄長度的可印列文字。然後隨便挑選一個 ELF 格式的執行檔,進行分析:
$ hexdump -f format elf | head
0000  .ELF........................4...
0020  0.......4. ...(.#. .....4...4...
0040  4...............................
0060  ................................
0080  ....@...@...............@...@...
00a0  @.......................T...T...
00c0  T.......................(...(...
00e0  (... ... ...........Q.td........
0100  ..................../lib/ld-linu
0120  x.so.2..............GNU.........
很明顯看到檔頭與 ELF 簽名字串,又我們可得知 exec image 0x0001 開始的三個 bytes 為 "ELF",那我們能否在執行時期印列呢?於是我寫了以下小程式:
#include <unistd.h>

int main()
{
        write(1, 0x08048001, 3);
        return 0;
}
這裡要提的是 0x08048001,其算法就是 0x08048000 基底位址加上 0x0001。於是我們可見執行結果:
$ ./elf 
ELF
另一種方式是直接讀取 /proc/self/mem,在之前的 slides 展示過用 dd 直接輸出 linux-gate.so.1 的方式,不過剛剛發現在 Ubuntu feisty 上竟然失敗了:
$ uname -a
Linux venux 2.6.19-7-lowlatency #2 SMP Mon Dec 4 16:48:22 UTC 2006 i686 GNU/Linux
$ dd if=/proc/self/mem of=MEM bs=4096
dd: 正在讀取 「/proc/self/mem」: 輸入/輸出錯誤
0+0 records in
0+0 records out
頗詭異,有哪位好心的朋友能指點迷津呢?謝謝!
由 jserv 發表於 December 10, 2006 12:23 PM
迴響

未知核心版本為何?
http://www.google.com.tw/search?num=100&hl=zh-TW&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&hs=V86&q=proc%2Fself%2Fmem%3A+Input%2Foutput+error&btnG=%E6%90%9C%E5%B0%8B&meta=

Roytam1 發表於 December 11, 2006 01:18 AM

page 0, NULL address ? So, it is not mapped.

Thinker 發表於 December 14, 2006 03:55 AM
發表迴響









記住我的資訊?