Android(8)で実行されているaarch64プロセスのファイルを調べている間、/proc/<PID>/maps
次のセクションが見つかりました。
726048e000-7260564000 r-xp 00000000 103:00 5402 /system/lib64/libc++.so
7260564000-7260565000 ---p 00000000 00:00 0
7260565000-726056d000 r--p 000d6000 103:00 5402 /system/lib64/libc++.so
726056d000-726056e000 rw-p 000de000 103:00 5402 /system/lib64/libc++.so
726056e000-7260571000 rw-p 00000000 00:00 0 [anon:.bss]
72605b3000-72605b5000 r-xp 00000000 103:00 5641 /system/lib64/libpackagelistparser.so
これはプログラムヘッダーテーブルですlibc++.so
。
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000009040 0x0000000000009040 0x0001c0 0x0001c0 R 0x8
LOAD 0x000000 0x0000000000009000 0x0000000000009000 0x0d58fc 0x0d58fc R E 0x1000
LOAD 0x0d68e0 0x00000000000e08e0 0x00000000000e08e0 0x007770 0x00aea8 RW 0x1000
DYNAMIC 0x0dbb40 0x00000000000e5b40 0x00000000000e5b40 0x000220 0x000220 RW 0x8
NOTE 0x000200 0x0000000000009200 0x0000000000009200 0x000038 0x000038 R 0x4
GNU_EH_FRAME 0x0d3058 0x00000000000dc058 0x00000000000dc058 0x0028a4 0x0028a4 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0
GNU_RELRO 0x0d68e0 0x00000000000e08e0 0x00000000000e08e0 0x007720 0x007720 RW 0x10
0xe08e0
2番目のセグメントのアドレスを取得し、LOAD
ベースを追加する0x726048e000
となります0x726056e8e0
。ただし、上記のマッピングファイルに示すように、マッピングされたセグメントはありません。正しいその住所から。代わりに[anon:.bss]
セグメントと重なります。0xaea8
エンドアドレスはサイズが大きいため、セグメントに完全には含まれません0x7260579788
。
答え1
印刷されたプログラムヘッダーテーブルの最後の列は、定義されたセグメントのソート要件を定義するヘッダーのメンバーreadelf
です。p_align
Linuxのマニュアルページからelf(5)
:
このメンバーは、メモリーとファイル内のセグメントのソートを維持します。ロード可能なプロセスセグメントのp_vaddrとp_offsetは、一貫した値(モジュロページサイズ)を持つ必要があります。値 0 と 1 は、ソートが不要であることを示します。それ以外の場合、p_alignは2の正の整数の二乗でなければならず、p_vaddrはp_alignモジュールでp_offsetと等しくなければなりません。
ソート値によって初期化された読み取り専用データセグメントは、オフセット(丸め)とサイズ(丸め)0x1000
とともにメモリマップに含まれます。これはファイルが表示するのとまったく同じです(4番目のフィールドはファイルオフセットです)。マップの長さは、終了アドレスと開始アドレスを減算して計算できます。以下の2つのマップは同じソートを持ち、保護フラグを使用して初期化されたデータセグメント()と初期化されていないデータセグメント()に対応することを推測できます。0x0d6000
0x0d68e0
0x008000
0x007770
maps
0x726056d000 - 0x7260565000 = 0x8000
.data
.bss