- 1 readelfコマンドとは?
- 2 検証環境
- 3 オプション一覧
- 4 事前準備
- 5 ELFヘッダを表示する方法(-h)
- 6 セクション一覧を表示する方法(-S)
- 7 80文字以上を表示する方法(-W)
- 8 セクションヘッダの中身を情報を表示する方法
- 9 シンボルテーブルを表示する方法(-s)
- 10 プログラムヘッダを表示する方法(-l)
- Z 参考情報
1 readelfコマンドとは?
ELF(Executable and Linkable Format)ファイルの情報を表示するコマンドです。
ELFファイルかどうかはfileコマンドで確認することができます。
カーネルモジュールに対してfileコマンドを実行してみます。ELFファイルであることがわかります。
[root@server ~]# file -z /lib/modules/3.10.0-1160.el7.x86_64/kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko.xz /lib/modules/3.10.0-1160.el7.x86_64/kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko.xz: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV) (XZ compressed data)
次に実行ファイルに対して、readelfコマンドを実行してみます。ELFファイルであることがわかります。
[root@server ~]# file /usr/bin/bc /usr/bin/bc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=60e314fae84e986e67cc4b61986bdbfc108a1f86, stripped
最後に共有ライブラリに対して、readelfコマンドを実行してみます。ELFファイルであることがわかります。
[root@server ~]# file /lib64/libc-2.17.so /lib64/libc-2.17.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), BuildID[sha1]=f9fafde281e0e0e2af45911ad0fa115b64c2cea8, for GNU/Linux 2.6.32, not stripped
2 検証環境
CentOS版数は以下のとおりです。仮想マシンは最小構成で作成しました。
[root@server ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)
カーネル版数は以下のとおりです。
[root@server ~]# uname -r 3.10.0-1160.el7.x86_64
readelfコマンドの版数は以下のとおりです。
[root@server ~]# readelf -v GNU readelf version 2.27-44.base.el7 Copyright (C) 2016 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or (at your option) any later version. This program has absolutely no warranty.
3 オプション一覧
[root@server ~]# readelf -h readelf: 警告: 行なうべき事はありません。 使用法: readelf <option(s)> elf-file(s) ELF 形式のファイルの内容に関する情報を表示します Options are: -a --all Equivalent to: -h -l -S -s -r -d -V -A -I -h --file-header Display the ELF file header -l --program-headers Display the program headers --segments An alias for --program-headers -S --section-headers Display the sections' header --sections An alias for --section-headers -g --section-groups Display the section groups -t --section-details Display the section details -e --headers Equivalent to: -h -l -S -s --syms Display the symbol table --symbols An alias for --syms --dyn-syms Display the dynamic symbol table -n --notes Display the core notes (if present) -r --relocs Display the relocations (if present) -u --unwind Display the unwind info (if present) -d --dynamic Display the dynamic section (if present) -V --version-info Display the version sections (if present) -A --arch-specific Display architecture specific information (if any) -c --archive-index Display the symbol/file index in an archive -D --use-dynamic Use the dynamic section info when displaying symbols -x --hex-dump=<number|name> Dump the contents of section <number|name> as bytes -p --string-dump=<number|name> Dump the contents of section <number|name> as strings -R --relocated-dump=<number|name> Dump the contents of section <number|name> as relocated bytes -z --decompress Decompress section before dumping it -w[lLiaprmfFsoRt] or --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames, =frames-interp,=str,=loc,=Ranges,=pubtypes, =gdb_index,=trace_info,=trace_abbrev,=trace_aranges, =addr,=cu_index] Display the contents of DWARF2 debug sections --dwarf-depth=N N 以上の深さの DIE を表示しない --dwarf-start=N N 以上の深さの DIE を表示する -I --histogram Display histogram of bucket list lengths -W --wide 出力幅が 80 文字を超えることを許可する @<file> オプションを <file> から読み込む -H --help この情報を表示する -v --version readelf のバージョン番号を表示する
4 事前準備
readelfの動作確認のため、nf_conntrack_ipv4.koモジュールを使ってみます。/lib/modules配下から、カレントディレクトリにカーネルモジュールをコピーします。
[root@server ~]# cp /lib/modules/3.10.0-1160.el7.x86_64/kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko.xz .
カーネルモジュールを解凍します。
[root@server ~]# xz -d nf_conntrack_ipv4.ko.xz
解凍したカーネルモジュールを確認します。
[root@server ~]# ls -l nf_conntrack_ipv4.ko -rw-r--r--. 1 root root 28973 4月 9 19:38 nf_conntrack_ipv4.ko
5 ELFヘッダを表示する方法(-h)
-hはELFヘッダを表示するオプションです。-hを使ってnf_conntrack_ipv4.koのELFヘッダを表示してみます。
[root@server ~]# readelf -h nf_conntrack_ipv4.ko ELF ヘッダ: マジック: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 クラス: ELF64 データ: 2 の補数、リトルエンディアン バージョン: 1 (current) OS/ABI: UNIX - System V ABI バージョン: 0 型: REL (再配置可能ファイル) マシン: Advanced Micro Devices X86-64 バージョン: 0x1 エントリポイントアドレス: 0x0 プログラムの開始ヘッダ: 0 (バイト) セクションヘッダ始点: 26128 (バイト) フラグ: 0x0 このヘッダのサイズ: 64 (バイト) プログラムヘッダサイズ: 0 (バイト) プログラムヘッダ数: 0 セクションヘッダ: 64 (バイト) セクションヘッダサイズ: 37 セクションヘッダ文字列表索引: 36
6 セクション一覧を表示する方法(-S)
-Sはセクション一覧を表示するオプションです。nf_conntrack_ipv4.koのセクション一覧を表示してみます。nf_conntrack_ipv4.koは、37個のセクションから構成されていることがわかります。
[root@server ~]# readelf -S nf_conntrack_ipv4.ko 37 個のセクションヘッダ、始点オフセット 0x6610: セクションヘッダ: [番] 名前 タイプ アドレス オフセット サイズ EntSize フラグ Link 情報 整列 [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .note.gnu.build-i NOTE 0000000000000000 00000040 0000000000000024 0000000000000000 A 0 0 4 [ 2] .text PROGBITS 0000000000000000 00000070 0000000000000fa2 0000000000000000 AX 0 0 16 [ 3] .rela.text RELA 0000000000000000 00001018 0000000000000cc0 0000000000000018 I 33 2 8 [ 4] .init.text PROGBITS 0000000000000000 00001cd8 00000000000000f8 0000000000000000 AX 0 0 1 [ 5] .rela.init.text RELA 0000000000000000 00001dd0 00000000000002a0 0000000000000018 I 33 4 8 [ 6] .exit.text PROGBITS 0000000000000000 00002070 0000000000000051 0000000000000000 AX 0 0 1 [ 7] .rela.exit.text RELA 0000000000000000 000020c8 0000000000000108 0000000000000018 I 33 6 8 [ 8] __ksymtab_gpl PROGBITS 0000000000000000 000021d0 0000000000000010 0000000000000000 A 0 0 16 [ 9] .rela__ksymtab_gp RELA 0000000000000000 000021e0 0000000000000030 0000000000000018 I 33 8 8 [10] __kcrctab_gpl PROGBITS 0000000000000000 00002210 0000000000000008 0000000000000000 A 0 0 8 [11] .rela__kcrctab_gp RELA 0000000000000000 00002218 0000000000000018 0000000000000018 I 33 10 8 [12] .rodata PROGBITS 0000000000000000 00002240 00000000000001d3 0000000000000000 A 0 0 32 [13] .rodata.str1.1 PROGBITS 0000000000000000 00002413 00000000000000c4 0000000000000001 AMS 0 0 1 [14] .rodata.str1.8 PROGBITS 0000000000000000 000024d8 00000000000002cd 0000000000000001 AMS 0 0 8 [15] .smp_locks PROGBITS 0000000000000000 000027a8 0000000000000004 0000000000000000 A 0 0 4 [16] .rela.smp_locks RELA 0000000000000000 000027b0 0000000000000018 0000000000000018 I 33 15 8 [17] __ksymtab_strings PROGBITS 0000000000000000 000027c8 0000000000000014 0000000000000000 A 0 0 1 [18] .modinfo PROGBITS 0000000000000000 000027e0 00000000000000e9 0000000000000000 A 0 0 32 [19] __param PROGBITS 0000000000000000 000028d0 0000000000000020 0000000000000000 A 0 0 8 [20] .rela__param RELA 0000000000000000 000028f0 0000000000000048 0000000000000018 I 33 19 8 [21] __mcount_loc PROGBITS 0000000000000000 00002938 00000000000000f0 0000000000000000 A 0 0 8 [22] .rela__mcount_loc RELA 0000000000000000 00002a28 00000000000002d0 0000000000000018 I 33 21 8 [23] __versions PROGBITS 0000000000000000 00002d00 0000000000000d80 0000000000000000 A 0 0 32 [24] .data PROGBITS 0000000000000000 00003a80 0000000000000180 0000000000000000 WA 0 0 32 [25] .rela.data RELA 0000000000000000 00003c00 0000000000000150 0000000000000018 I 33 24 8 [26] __verbose PROGBITS 0000000000000000 00003d50 0000000000000168 0000000000000000 WA 0 0 8 [27] .rela__verbose RELA 0000000000000000 00003eb8 0000000000000360 0000000000000018 I 33 26 8 [28] .data..read_mostl PROGBITS 0000000000000000 00004220 00000000000003a4 0000000000000000 WA 0 0 32 [29] .rela.data..read_ RELA 0000000000000000 000045c8 00000000000003c0 0000000000000018 I 33 28 8 [30] .gnu.linkonce.thi PROGBITS 0000000000000000 000049a0 0000000000000238 0000000000000000 WA 0 0 32 [31] .rela.gnu.linkonc RELA 0000000000000000 00004bd8 0000000000000030 0000000000000018 I 33 30 8 [32] .bss NOBITS 0000000000000000 00004c08 0000000000000000 0000000000000000 WA 0 0 1 [33] .symtab SYMTAB 0000000000000000 00004c08 0000000000000e88 0000000000000018 34 95 8 [34] .strtab STRTAB 0000000000000000 00005a90 00000000000009fe 0000000000000000 0 0 1 [35] .gnu_debuglink PROGBITS 0000000000000000 00006490 0000000000000020 0000000000000000 0 0 4 [36] .shstrtab STRTAB 0000000000000000 000064b0 000000000000015f 0000000000000000 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), l (large), p (processor specific)
セクション | 意味 |
---|---|
.text | 実行コードを格納するセクションです |
.data | 初期化済データを格納するセクションです |
.bss | 未初期化の変数を格納するセクションです |
.nodata | リードオンリーのセクションで、書き込みはできません。定数か固定文字列を格納するセクションです |
7 80文字以上を表示する方法(-W)
-Wは1行に表示する文字数を指定するオプションです。デフォルトは80文字までしか表示しません。 -Wを使うことで、80文字以上の文字を表示することができます。
[root@server ~]# readelf -S -W nf_conntrack_ipv4.ko 37 個のセクションヘッダ、始点オフセット 0x6610: セクションヘッダ: [番] 名前 型 アドレス Off サイズ ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .note.gnu.build-id NOTE 0000000000000000 000040 000024 00 A 0 0 4 [ 2] .text PROGBITS 0000000000000000 000070 000fa2 00 AX 0 0 16 [ 3] .rela.text RELA 0000000000000000 001018 000cc0 18 I 33 2 8 [ 4] .init.text PROGBITS 0000000000000000 001cd8 0000f8 00 AX 0 0 1 [ 5] .rela.init.text RELA 0000000000000000 001dd0 0002a0 18 I 33 4 8 [ 6] .exit.text PROGBITS 0000000000000000 002070 000051 00 AX 0 0 1 [ 7] .rela.exit.text RELA 0000000000000000 0020c8 000108 18 I 33 6 8 [ 8] __ksymtab_gpl PROGBITS 0000000000000000 0021d0 000010 00 A 0 0 16 [ 9] .rela__ksymtab_gpl RELA 0000000000000000 0021e0 000030 18 I 33 8 8 [10] __kcrctab_gpl PROGBITS 0000000000000000 002210 000008 00 A 0 0 8 [11] .rela__kcrctab_gpl RELA 0000000000000000 002218 000018 18 I 33 10 8 [12] .rodata PROGBITS 0000000000000000 002240 0001d3 00 A 0 0 32 [13] .rodata.str1.1 PROGBITS 0000000000000000 002413 0000c4 01 AMS 0 0 1 [14] .rodata.str1.8 PROGBITS 0000000000000000 0024d8 0002cd 01 AMS 0 0 8 [15] .smp_locks PROGBITS 0000000000000000 0027a8 000004 00 A 0 0 4 [16] .rela.smp_locks RELA 0000000000000000 0027b0 000018 18 I 33 15 8 [17] __ksymtab_strings PROGBITS 0000000000000000 0027c8 000014 00 A 0 0 1 [18] .modinfo PROGBITS 0000000000000000 0027e0 0000e9 00 A 0 0 32 [19] __param PROGBITS 0000000000000000 0028d0 000020 00 A 0 0 8 [20] .rela__param RELA 0000000000000000 0028f0 000048 18 I 33 19 8 [21] __mcount_loc PROGBITS 0000000000000000 002938 0000f0 00 A 0 0 8 [22] .rela__mcount_loc RELA 0000000000000000 002a28 0002d0 18 I 33 21 8 [23] __versions PROGBITS 0000000000000000 002d00 000d80 00 A 0 0 32 [24] .data PROGBITS 0000000000000000 003a80 000180 00 WA 0 0 32 [25] .rela.data RELA 0000000000000000 003c00 000150 18 I 33 24 8 [26] __verbose PROGBITS 0000000000000000 003d50 000168 00 WA 0 0 8 [27] .rela__verbose RELA 0000000000000000 003eb8 000360 18 I 33 26 8 [28] .data..read_mostly PROGBITS 0000000000000000 004220 0003a4 00 WA 0 0 32 [29] .rela.data..read_mostly RELA 0000000000000000 0045c8 0003c0 18 I 33 28 8 [30] .gnu.linkonce.this_module PROGBITS 0000000000000000 0049a0 000238 00 WA 0 0 32 [31] .rela.gnu.linkonce.this_module RELA 0000000000000000 004bd8 000030 18 I 33 30 8 [32] .bss NOBITS 0000000000000000 004c08 000000 00 WA 0 0 1 [33] .symtab SYMTAB 0000000000000000 004c08 000e88 18 34 95 8 [34] .strtab STRTAB 0000000000000000 005a90 0009fe 00 0 0 1 [35] .gnu_debuglink PROGBITS 0000000000000000 006490 000020 00 0 0 4 [36] .shstrtab STRTAB 0000000000000000 0064b0 00015f 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), l (large), p (processor specific)
8 セクションヘッダの中身を情報を表示する方法
8.1 HEXで表示する方法(-x)
nf_conntrack_ipv4.koには全部で37個のセクションがありました。その中に、modinfoというセクションがあります。ここでは、modinfoセクションの中身を表示してみます。
[root@server ~]# readelf -S nf_conntrack_ipv4.ko|grep modinfo [18] .modinfo PROGBITS 0000000000000000 000027e0
-xオプションに18を指定して、modinfoセクションの情報を表示します。
[root@server ~]# readelf -x 18 nf_conntrack_ipv4.ko セクション '.modinfo' の 十六進数ダンプ: 0x00000000 6c696365 6e73653d 47504c00 616c6961 license=GPL.alia 0x00000010 733d6970 5f636f6e 6e747261 636b0061 s=ip_conntrack.a 0x00000020 6c696173 3d6e665f 636f6e6e 74726163 lias=nf_conntrac 0x00000030 6b2d3200 00000000 00000000 00000000 k-2............. 0x00000040 72657470 6f6c696e 653d5900 7268656c retpoline=Y.rhel 0x00000050 76657273 696f6e3d 372e3900 73726376 version=7.9.srcv 0x00000060 65727369 6f6e3d31 41354537 44414634 ersion=1A5E7DAF4 0x00000070 41413144 41363546 33353838 30320000 AA1DA65F358802.. 0x00000080 64657065 6e64733d 6e665f63 6f6e6e74 depends=nf_connt 0x00000090 7261636b 2c6e665f 64656672 61675f69 rack,nf_defrag_i 0x000000a0 70763400 696e7472 65653d59 00766572 pv4.intree=Y.ver 0x000000b0 6d616769 633d332e 31302e30 2d313136 magic=3.10.0-116 0x000000c0 302e656c 372e7838 365f3634 20534d50 0.el7.x86_64 SMP 0x000000d0 206d6f64 5f756e6c 6f616420 6d6f6476 mod_unload modv 0x000000e0 65727369 6f6e7320 00 ersions .
8.2 文字列で表示する方法(-p)
-pはセクションの情報を文字列で表示するオプションです。セクション番号18を指定して、modinfoセクションの情報を表示します。modinfoのセクション情報が文字列で表示されたことがわかります。
[root@server ~]# readelf -p 18 nf_conntrack_ipv4.ko セクション '.modinfo' の文字列ダンプ: [ 0] license=GPL [ c] alias=ip_conntrack [ 1f] alias=nf_conntrack-2 [ 40] retpoline=Y [ 4c] rhelversion=7.9 [ 5c] srcversion=1A5E7DAF4AA1DA65F358802 [ 80] depends=nf_conntrack,nf_defrag_ipv4 [ a4] intree=Y [ ad] vermagic=3.10.0-1160.el7.x86_64 SMP mod_unload modversions
-pオプションで表示した情報は、modinfoコマンドで表示したものと同じであることがわかります。
[root@server ~]# modinfo nf_conntrack_ipv4.ko filename: /root/nf_conntrack_ipv4.ko license: GPL alias: ip_conntrack alias: nf_conntrack-2 retpoline: Y rhelversion: 7.9 srcversion: 1A5E7DAF4AA1DA65F358802 depends: nf_conntrack,nf_defrag_ipv4 intree: Y vermagic: 3.10.0-1160.el7.x86_64 SMP mod_unload modversions signer: CentOS Linux kernel signing key sig_key: E1:FD:B0:E2:A7:E8:61:A1:D1:CA:80:A2:3D:CF:0D:BA:3A:A4:AD:F5 sig_hashalgo: sha256
9 シンボルテーブルを表示する方法(-s)
-sはシンボルテーブルを表示するオプションです。シンボルテーブルは、変数名、関数名、ファイル名を含んだセクションになります。以下の実行結果では、FUNCは関数名、OBJECTは変数名、FILE はファイル名を表しています。
[root@server ~]# readelf -s nf_conntrack_ipv4.ko シンボルテーブル '.symtab' は 155 個のエントリから構成されています: 番号: 値 サイズ タイプ Bind Vis 索引名 -snip- 26: 0000000000000110 28 FUNC LOCAL DEFAULT 2 ipv4_nlattr_tuple_size 27: 0000000000000040 80 OBJECT LOCAL DEFAULT 12 ipv4_nla_policy 28: 0000000000000130 140 FUNC LOCAL DEFAULT 2 ipv4_tuple_to_nlattr -snip- 60: 0000000000000000 0 FILE LOCAL DEFAULT ABS nf_conntrack_proto_icmp.c -snip-
10 プログラムヘッダを表示する方法(-l)
-lはプログラムヘッダを表示するオプションです。ここでは、tcpdumpコマンドのプログラムヘッダを表示してみます。
[root@server ~]# readelf -l /usr/sbin/tcpdump Elf ファイルタイプは EXEC (実行可能ファイル) です エントリポイント 0x406f65 9 個のプログラムヘッダ、始点オフセット 64 プログラムヘッダ: タイプ オフセット 仮想Addr 物理Addr ファイルサイズ メモリサイズ フラグ 整列 PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040 0x00000000000001f8 0x00000000000001f8 R E 8 INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238 0x000000000000001c 0x000000000000001c R 1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x00000000000dfa74 0x00000000000dfa74 R E 200000 LOAD 0x00000000000dfde0 0x00000000006dfde0 0x00000000006dfde0 0x0000000000003cb8 0x0000000000162bf0 RW 200000 DYNAMIC 0x00000000000dfdf8 0x00000000006dfdf8 0x00000000006dfdf8 0x0000000000000200 0x0000000000000200 RW 8 NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254 0x0000000000000044 0x0000000000000044 R 4 GNU_EH_FRAME 0x00000000000d2d08 0x00000000004d2d08 0x00000000004d2d08 0x000000000000135c 0x000000000000135c R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10 GNU_RELRO 0x00000000000dfde0 0x00000000006dfde0 0x00000000006dfde0 0x0000000000000220 0x0000000000000220 R 1 セグメントマッピングへのセクション: セグメントセクション... 00 01 .interp 02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag .note.gnu.build-id 06 .eh_frame_hdr 07 08 .init_array .fini_array .jcr .dynamic .got
Z 参考情報
私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ
https://docs.oracle.com/cd/E19253-01/819-0391/chapter6-79797/index.html