Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

はりぼて OS で ELF なアプリを起動してみた

はりぼて OS を改造して ELF バイナリを起動します。
ELF の内部構造や、好きな ELF 構造を生成するためのリンカスクリプトの書き方を説明し、はりぼて OS のどこを改造すればよいか示します。

  • Be the first to comment

はりぼて OS で ELF なアプリを起動してみた

  1. 1. はりぼて OS で ELF な アプリを起動してみた @uchan_nos 2016/11/26 第4回自作OSもくもく会
  2. 2. はりぼてOSによるアプリ起動 • デモ
  3. 3. はりぼてOSによるアプリ起動 • コンソールにコマンドを打ち込むと起動する • 裏では: • カーネルが.hrbファイルをメモリに配置 • アプリ用のデータ領域確保やESP設定 • エントリポイントにジャンプ
  4. 4. hrb ファイルフォーマット(p.460) off 意味 0x00 stack+.data+heap の大きさ 0x04 “Hari” 0x08 mmarea の大きさ 0x0C ESPの初期値(= .data の転送先) 0x10 .data のサイズ 0x14 .data の初期値のファイル内オフセット 0x18 0xE9000000 0x1C エントリアドレス-0x20 0x20 heap 領域開始アドレス ヘッダ .text .data
  5. 5. Segm 1 Segm 2 ロード後のメモリ配置 stack .data .bss heap .text .data ヘッダ .hrbファイル そのまま ESP初期値
  6. 6. はりぼてOSのプログラムローダ(ELF化前) console.c
  7. 7. 実行可能形式いろいろ • COM • 実行時のメモリイメージそのままの形式 • PE • Windowsの標準 • a.out • Unix最初期の形式。TEXT, DATA, BSSだけをもつ • COFF • オブジェクトファイル形式として有名 • ELF • Executable and Linking Format
  8. 8. ELF : Executable and Linking Format • 現在の Unix, Linux での標準 • オブジェクトファイル、実行可能ファイルどちらもOK • ツールチェーンで良くサポートされている • a.out や COFF に比べ柔軟。新しい言語にも対応できる • →これは ELF に対応するしかないでしょ!
  9. 9. ELF ファイルフォーマット • ELFヘッダ、SHT 、PHT 、セクション群からなる • SHT:セクション・ヘッダ・テーブル • PHT:プログラム・ヘッダ・テーブル • セクション群:.text, .data, .bss, .shstrtab など • 詳しくは 『リンカ・ローダ実践開発テクニック』坂井弘亮, 2010 ELFヘッダ PHT SHT セクション
  10. 10. ELF32ヘッダフォーマット off field 意味 0x00 e_ident 先頭4バイトは 0x7f, ‘E’, ‘L’, ‘F’ 0x10 e_type ファイルタイプ ET_EXEC, ET_REL など 0x12 e_machine EM_386 など 0x14 e_version ファイルバージョン 0x18 e_entry エントリポイントのアドレス 0x1C e_phoff プログラムヘッダテーブルのファイル位置 0x20 e_shoff セクションヘッダテーブルのファイル位置 0x24 e_flags 未使用 0x28 e_ehsize ELF ヘッダサイズ 0x2A … 0x32 e_shstrndx セクション名格納用セクションの番号 ELFヘッダ PHT SHT セクション
  11. 11. セクション・ヘッダ • .text、.data、.bss などのセクションを管理するヘッダ • コンパイラが出力したセクションをリンカがまとめる • セクション名 • セクションの属性(書き込み、実行) • セクションのロード先仮想アドレス • セクションデータのファイル位置とサイズ
  12. 12. プログラム・ヘッダ • ローダが利用するセグメントを記述する • PHTは実行可能ファイルにしかない • セグメントのタイプ • セグメントのロード先仮想アドレス • セグメントデータのファイル位置とサイズ • セグメントのメモリ上のサイズ • セグメント属性(読み書き実行)
  13. 13. ロードの仕様を考える • はりぼてOSでは、スタッ ク領域は.dataの前に置く • メモリ上では .text, .stack の先頭アドレスが両方と も 0 になって欲しい • .stack, .bss, .malloc はファイル上は0バイト .text .stack .malloc 欲しい ELFファイル EXEC RW .text .data .bss ELFヘッダ PHT SHT 欲しい メモリ配置 .stack .data 0番地 0番地 .bss .malloc
  14. 14. ELF用リンカ スクリプト ENTRY(_HariMain) INCLUDE ld_variables.lds SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } "file offset of data" = .; . = 0; .stack : AT("file offset of data") { . = STACK; } .data : { *(.rodata*) *(.data) } .bss : { *(.bss) } .malloc : { . += MALLOC; } } EXECセグメントに ロードされる部分 RWセグメントに ロードされる部分
  15. 15. 生成されるヘッダ構造 セクション タイプ ロード先 Offset Size .text PROGBITS 00000094 000094 000188 .stack NOBITS 00000000 00021c 000400 .data PROGBITS 00000400 00021c 000088 .bss NOBITS 00000488 0002a4 000100 .malloc NOBITS 00000588 0002a4 00c000 セグメント Offset 仮想アドレス File Size Mem Size Flag LOAD 000094 00000094 000188 000188 R E LOAD 00021c 00000000 000000 000400 RW LOAD 00021c 00000400 000088 00c188 RW ※これらは readelf -a hoge.elf で表示できるよ!
  16. 16. ローダの改造1 .elfファイルを探す console.c
  17. 17. ローダの改造2 ELFのマジックナンバーを確認する …
  18. 18. ローダの改造3 espの初期値を計算する
  19. 19. calc_elf_esp .stackセクションがあれば、そのサイズを返す →.stackセクションが0番地から配置されることを暗に仮定している
  20. 20. ローダの改造4 .dataのコピーとアプリ起動 EXEC 0*8+4 RW 1*8+4 ELF ファイル 全体 .data .bss .stack p q appsiz segsiz .malloc esp
  21. 21. calc_elf_datasize
  22. 22. copy_elf_data
  23. 23. ELFアプリ起動 デモ
  24. 24. リンカスクリプト豆知識 location counter と virtual memory address (VMA) load memory address (LMA) の関係 参考:https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html
  25. 25. Location counter is . (dot) SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } "file offset of data" = .; • VMA, LMA の現在値を保持するもの • 値が加算されていくので「カウンタ」 • "file offset of data" はシンボル
  26. 26. Virtual memory address (VMA) • VMAはそのセクションが配置されるメモリの仮想アドレス • 上記の例では “.text” の VMA は SIZEOF_HEADERS SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } "file offset of data" = .; SIZEOF_HEADERS ファイルのヘッダの バイト数を返す リンカの組み込み変数
  27. 27. Virtual memory address (VMA) ヘッダ .text SIZEOF_HEADERS (= ELFヘッダ+PHT) バイト "file offset of data" .data SHT
  28. 28. Load memory address (LMA) • VMA はファイル実行時のアドレス • 対して、LMA はファイルが読み込まれるアドレス • 今回、これを「ファイル内のオフセット」として使っている • 上記の例では “.stack” の VMA は 0、LMA は “.text” の直後 . = 0; .stack : AT("file offset of data") { . = STACK; }
  29. 29. . = 0; .stack : AT("file offset of data") { . = STACK; } .data : { *(.rodata*) *(.data) } .bss : { *(.bss) } Sect VMA LMA .stack 0 “file offset of data” .data STACK “file offset of data” .bss STACK+sizeof(.data) “file offset of data”+sizeof(.data) ATを指定しなければ、LMAに関して直前のATの効果が続く
  30. 30. 参考文献など • ELF化したはりぼてOSのソースコード https://github.com/osdev-jp/elf_haribote • 『リンカ・ローダ実践開発テクニック』坂井 弘亮, 2010 • ELFの仕様書 http://www.skyfree.org/linux/references/ELF_Format.pdf • LDのドキュメント https://sourceware.org/binutils/docs/ld/ • 3.1 Basic Linker Script Concepts • 3.6.8.2 Output Section LMA • はりぼてOSサポートページ内 “tools/obj2bim” http://hrb.osask.jp/wiki/?tools/obj2bim

    Be the first to comment

    Login to see the comments

  • ssuser5fb663

    Mar. 16, 2019
  • DaichiTsuzuki

    Mar. 1, 2021

はりぼて OS を改造して ELF バイナリを起動します。 ELF の内部構造や、好きな ELF 構造を生成するためのリンカスクリプトの書き方を説明し、はりぼて OS のどこを改造すればよいか示します。

Views

Total views

1,954

On Slideshare

0

From embeds

0

Number of embeds

33

Actions

Downloads

11

Shares

0

Comments

0

Likes

2

×