SlideShare une entreprise Scribd logo
1  sur  23
Télécharger pour lire hors ligne
BitVisorに「移植」する
東京農工大学 市川 遼
2017/12/05 BitVisor Summit 6
自己紹介
● 東京農工大学 工学府情報工学専攻1年
● twitter: @icchyr
● CTF: TokyoWesterns
● 研究: OS, セキュリティ
本日お話しすること
● LVisorについて
● LVisorの実装上の課題
○ BitVisorのどの部分で動かすのか
○ どうやって呼び出すのか
○ エラーが起きたらどうするのか
○ 依存ライブラリはどうするのか
○ etc.
● これらを解決する方法を検討
○ BitVisorに外部のプログラムを移植した例は多くあるが,
ソースコードが公開されているものは少ない
○ 初期実装ではひたすらアドホックに試した → 後に限界が見えてきた
■ なるべくソースコードを改変する必要がない方法を模索
○ 実装する上での具体的な手順について共有
LVisorの背景
● VMMに汎用スクリプト言語を組み込むモチベーション
○ 比較的簡単に複雑な処理を記述可能
○ eval相当の機能がある場合は動的にプログラムを追加可能
○ 通常VMMに動的に機能を追加するのは難しい
● BitVisorにVMI (Virtual Machine Introspection) があるとうれしい
○ ゲストOSから不可視
■ マルウェア解析環境として適している
○ 他のVMMに比べてパフォーマンスが優れている
■ 解析効率の向上
● BitVisorにLuaとLibVMIを組み込んだ
○ 普通のBitVisorでは処理を追加するために Cで直接VMMを書き換える必要がある
○ スクリプト言語でBitVisorを使いたい
○ LibVMI+シンボル情報でゲスト OS解析の補助
○ Luaのプログラムをルールとしてプロセスやネットワークを監視
Luaを選んだ理由
● Luaの特徴
○ (比較的) 早い
○ バイナリが小さい,依存ライブラリが少ない (最低限libc, libmのみ)
○ 記述方法が多様
■ 手続き型
■ プロトタイプベース
■ など
○ インターフェースとして有用
● BitVisorの特徴
○ 早い
○ VMMが小さい
○ 拡張のハードルが高い
■ processなどを書いてビルドし直す必要がある
● BitVisorに組み込む上でLuaは比較的相性が良い
インターフェースとしてのLua
● LuaをインターフェースとするAPIを提供
○ システムコールフック
○ 仮想メモリアクセス
○ ネットワークパケットフィルタ
● オブジェクト指向でデータにアクセス
○ フックするイベントに対して処理を登録
○ イベントハンドラにフック対象に関わるオブジェクトが渡される
● Luaはプロトタイプベースなので記述しやすい
○ メソッドに対して動的に処理を追加できる
○ 関数の動作を上書きすることが可能なため用途に合わせてフレームワーク的に扱える
LVisorの例
● 使用例
○ /tmp/ で始まるバイナリが起動 (execve) された時に全てのネットワーク通信を遮断
○ 現状プロセス単位の通信は制御できない
denyall = function(eth)
return DROP
end
execve_hook = function(args)
filename = args[0] -- execveの第一引数 (filename) へのポインタを取得
filename_s = pmem.read(filename, 0x100) -- filenameを文字列で取得
-- /tmp/で始まるバイナリの場合全てのネットワーク通信を遮断
if string.match(filename_s, “^/tmp/”) ~= nil then
net.eth.hooks.add(“*”, “*”, “denyall”, denyall)
end
end
syscall.hooks.add(“netproc”, execve_hook)
LVisorの実装方法
BitVisorに機能を追加する方法
● BitVisorで処理を走らせる手段
○ 一回のみ
■ INITFUNC
○ 定期的
■ thread
○ dbgshから任意のタイミング
■ process
○ ゲストOSから任意のタイミング
■ vmmcall
● BitVisorの実装 (vpn, storageなど)
○ BitVisorの機能が必要な部分のみ msgbufで呼び出し,それ以外は保護ドメインで処理
○ 必要な時のみしかRing 0で動作させない方針
LVisorの実装方針
● Ring 0で動かすのは得策ではない
○ 移植するプログラムが巨大であるため
● 基本的にvpnやstorage等と同じ方針をとる
○ 必要な部分だけmsgbufでやりとりする
○ Lua,LibVMIは保護ドメインで動作させる
● まずLuaのインタプリタを組み込み,次にLibVMIを移植
● 環境
○ Lua: 5.3.3
○ LibVMI: 2016年9月時点でのGitHubの版
BitVisorのビルドシステムおさらい
● makeをベースとしたビルドシステム
○ 下の階層をビルドした結果を上の階層にリンク
○ オブジェクト (.o) を作る場合は subdirs-1 に追加
○ 静的ライブラリ (.a) を作る場合は asubdirs-1 に追加
○ objs-1 にオブジェクトファイルを追加することでビルド対象を決定
○ CFLAGSを書き換えることでコンパイルオプションを調節
○ 基本的にカレントディレクトリは一番上 (bitvisor/) になることに注意
● processのビルド
○ $(name)-objs にオブジェクトファイルを追加
○ $(name)-libs に依存ライブラリ (.a) を追加
○ bins-1 にprocessとして登録する名前を追加
リンクについて
● BitVisorは基本的にstatic link
○ dynamic linkがサポートされていない
○ そもそもサポートする必要がない (再利用されるコードが極めて小さいため )
○ バイナリのローダは存在するがライブラリのローダは存在しない
● Ring 0の部分は最終的に全て同じ階層でリンクされる
○ どこかにシンボルが存在していればよい
○ processからリンクしたい場合は process-dependsに加える必要がある
ソースコードの配置場所
● 全てprocess配下に置くのが正しいか?
○ vpnやstorageはそうではない
■ dbgshから呼び出すことを想定していない
● 例: vpn
○ vpn/lib/user.c に処理を書き,process/vpn.c ではexternのようにして呼び出す
○ この構成のメリット
■ process/Makefileを汚さない
■ process/ 以外からもリンクすることができる
● musl, LibVMIは一番上の階層に置く
移植に必要な手順
● 静的ライブラリまたはオブジェクトを作成する
○ BitVisorのビルドシステムに組み込む
■ findコマンドなどである程度自動化 , コンパイルオプションに注意
○ プロジェクトのMakefileを直接叩く
■ カレントディレクトリに注意
● 必要なプログラムの依存関係に加える
○ processであれば$(name)-libs
○ それ以外であればasubdirs-1 (or subdirs-1)
● 標準的なOSの機能を使う部分は修正する必要がある
○ 標準入出力, メモリ管理は特にBitVisorに合わせる必要がある
Luaの組み込み方法
● Luaは比較的移植がしやすい
○ 依存ライブラリが少ない
○ 全てのソースコードが同じ階層に存在し,コンパイルしたオブジェクトをリンクするだけ
■ ビルドシステムへの負担が少ない
○ 静的ライブラリ (.a) を作成できればよい
● BitVisorのビルドシステムに組み込む
○ BitVisorのビルドシステムを理解する
○ process/ 以下にluaのソースコードを丸ごとコピー
○ LuaのMakefileをBitVisor向けに編集 (objs-1にLuaのプログラムを追加していくだけ )
○ process/MakefileにLuaに関わる部分を追記
● これだけでは動かない
○ libcが必要
○ BitVisorは部分的にしかlibcの関数をサポートしていない
libcの組み込み方法
● 必要なlibcを移植するのは大変 → 既存のlibcを移植する
● どのlibcを使うか?
○ eglibc
○ uClibc
○ newlib
○ musl libc
○ etc.
○ 比較的サイズが小さくビルドも簡単な musl libcを採用
● BitVisorに合わせた変更が必要
○ ファイルシステムおよび fdの概念が存在しない
○ BitVisorのprocess/libでサポートしている関数に注目
■ 標準出力 (printf)
■ 標準入力 (lineinput)
■ メモリ管理 (alloc/free)
○ 最低限これらの機能と接続しないと動作しない
libcの組み込み方法
● muslの関数を編集
○ 標準出力
■ __fwritexでputcharを使う (process/lib/lib_putchar.c)
■ muslのprintfを使えるようにするため
● BitVisorのprintfは浮動小数点系のフォーマット指定子に対応していない
○ 標準入力
■ libc側で対応せずにprocessの入力を受け取るところで対処
○ メモリ管理
■ malloc
● process/lib/lib_mm.c:alloc を使うように修正
■ free
● process/lib/lib_mm.c:free を使うように修正
■ realloc
● size == 0の時のバグを修正
■ 確保可能な領域は各 processでheap, heaplenを定義して調整
libcの組み込み方法
● ビルドシステムの修正
○ muslのMakefileをBitVisorに対応させるのは困難
○ BitVisorのmake中にmuslのmakeを走らせるようにする
■ cleanを回避する場合は ifndef clean_p の中に書く (clean時に定義される変数の一つ )
● リンク方法の検討
○ プロジェクトの.aを直接リンクする (ビルド時に生成された .aを指定)
○ BitVisorのビルドシステムで.aを作る (ビルド時に生成された .oを集める) ← こちらを採用
● 例: include makefiles/musl.mak
ifndef clean_p
$(info building musl...)
$(info $(shell cd $(musl_dir) && make -j4 && cd - >/dev/null))
objs-1 += $(musl_o)
endif
Luaの組み込み方法 (続き)
● Luaのインタプリタを用意する
○ lua.cをprocess向けに編集
○ lua_writelineマクロとlua_readlineマクロをそれぞれ編集
■ printfとlineinputを使うように修正
○ main関数を修正
■ setlimitを呼び出して大きくスタックを確保するように修正
● 標準ではスタックが足りなくてクラッシュする
■ pushcfunction~reportまで削除し,代わりに doREPLを呼び出す
● argc, argvが存在しないためpushcfunctionが使えない
■ exitprocessで終了
● 浮動小数点レジスタのサポート
○ VMM起動時にCR0を操作して有効化しておく (一時的な措置)
● debugshのprocessからLuaインタプリタが使用可能に
LibVMIの組み込み方法
● LibVMIはlibcの他にGlib, json-cに依存
○ libcと同様の方法でビルドシステムに組み込む
● LibVMIのBitVisor対応
○ XenをベースにBitVisor用のdriverを作成
■ ゲストOSのCPUの読み書き
■ ゲストOSの物理メモリの読み書き
■ ゲストOSの電源操作 (pause, resume, halt)
■ メモリサイズの取得
○ CPUレジスタ操作,メモリ操作があれば理論上は動作する
○ rekallのprofileを用意
■ 現状はファイルシステムが無いのでバイナリの dataセクションに埋め込む
■ objcopyでJSONを変換
■ サイズが非常に大きい (Linuxで約3.3M) ため改善の必要あり
LibVMIの組み込み方法
● ビルドシステムの修正
○ LibVMIのビルドシステムはKVM, Xenなどの本来対応する VMM用のライブラリに深く依存
○ BitVisor用のdriverをビルドするようにMakefileを作成
■ libvmi/およびその下のarch, driver, os以下
● 例: include makefiles/libvmi.mak
CFLAGS += $(libvmi_INCLUDE)
curdir = $(libvmi_dir)/driver
subdirs-1 += bitvisor
obj = $(subst .c,.o,$(shell find $(curdir) -maxdepth 1 -name "*.c"))
objs-1 += $(obj:$(curdir)/%=%)
近況
● Luaはほぼ完全に動作
○ muslのprint系が壊れていて変な出力が出るものの特に影響はない
● LibVMIが完全に動いていない
○ 動きはするがオフセットがずれている
● ネットワーク監視が完全に動いていない
○ netapiの使い方が把握しきれていない
● 全てのAPIに対応できていない
まとめ
● BitVisorへの移植は比較的容易な手順で実現可能
○ 一番上の階層にプロジェクト用のディレクトリを切り分ける
○ プロジェクトをそのままコピーする
○ Makefile内でプロジェクトのビルドを行う
○ 生成された.oファイルを検索してobjs-1に追加
● libc, GLibcが移植できたため大抵のプログラムは移植可能
○ OSの機能を必要とするものは移植できない
○ BitVisorを拡張するのが容易に

Contenu connexe

Similaire à how to port * to BitVisor

Similaire à how to port * to BitVisor (20)

how to port * to BitVisor (2)
how to port * to BitVisor (2)how to port * to BitVisor (2)
how to port * to BitVisor (2)
 
今さら聞けない人のためのGit超入門 2020/12/19
今さら聞けない人のためのGit超入門 2020/12/19今さら聞けない人のためのGit超入門 2020/12/19
今さら聞けない人のためのGit超入門 2020/12/19
 
Docker 再入門 2016 update
Docker 再入門 2016 updateDocker 再入門 2016 update
Docker 再入門 2016 update
 
OpenStack + MidoNet を動かしてみた - 2015/2/16 MidoNetコミュニティ発足会
OpenStack + MidoNet を動かしてみた - 2015/2/16 MidoNetコミュニティ発足会OpenStack + MidoNet を動かしてみた - 2015/2/16 MidoNetコミュニティ発足会
OpenStack + MidoNet を動かしてみた - 2015/2/16 MidoNetコミュニティ発足会
 
OpenStack + MidoNet を動かしてみた - 2015/2/16 MidoNetコミュニティ発足会
OpenStack + MidoNet を動かしてみた - 2015/2/16 MidoNetコミュニティ発足会OpenStack + MidoNet を動かしてみた - 2015/2/16 MidoNetコミュニティ発足会
OpenStack + MidoNet を動かしてみた - 2015/2/16 MidoNetコミュニティ発足会
 
Inside pixiv's infrastructure〜application cluster side〜
Inside pixiv's infrastructure〜application cluster side〜Inside pixiv's infrastructure〜application cluster side〜
Inside pixiv's infrastructure〜application cluster side〜
 
今さら聞けない人のためのGit超入門 OSC2018広島版
今さら聞けない人のためのGit超入門 OSC2018広島版今さら聞けない人のためのGit超入門 OSC2018広島版
今さら聞けない人のためのGit超入門 OSC2018広島版
 
今さら聞けない人のためのGit超入門 2019/11/21
今さら聞けない人のためのGit超入門 2019/11/21今さら聞けない人のためのGit超入門 2019/11/21
今さら聞けない人のためのGit超入門 2019/11/21
 
私とOSSの25年
私とOSSの25年私とOSSの25年
私とOSSの25年
 
今さら聞けない人のためのGit超入門 GitLab 13対応版
今さら聞けない人のためのGit超入門 GitLab 13対応版今さら聞けない人のためのGit超入門 GitLab 13対応版
今さら聞けない人のためのGit超入門 GitLab 13対応版
 
今さら聞けない人のためのgit超入門
今さら聞けない人のためのgit超入門今さら聞けない人のためのgit超入門
今さら聞けない人のためのgit超入門
 
今さら聞けない人のためのGit超入門
今さら聞けない人のためのGit超入門今さら聞けない人のためのGit超入門
今さら聞けない人のためのGit超入門
 
今さら聞けない人のためのGit超入門 GitLab 14対応版
今さら聞けない人のためのGit超入門 GitLab 14対応版今さら聞けない人のためのGit超入門 GitLab 14対応版
今さら聞けない人のためのGit超入門 GitLab 14対応版
 
20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux
 
仮想化環境の設計手法 〜プロのテクニック教えます〜
仮想化環境の設計手法 〜プロのテクニック教えます〜仮想化環境の設計手法 〜プロのテクニック教えます〜
仮想化環境の設計手法 〜プロのテクニック教えます〜
 
CI/CDパイプラインを定着させる闘い @九州インフラ交流勉強会(Kixs) Vol.006
CI/CDパイプラインを定着させる闘い @九州インフラ交流勉強会(Kixs) Vol.006CI/CDパイプラインを定着させる闘い @九州インフラ交流勉強会(Kixs) Vol.006
CI/CDパイプラインを定着させる闘い @九州インフラ交流勉強会(Kixs) Vol.006
 
ビットキーのIoT基盤におけるAWS IoT Rule Action 活用
ビットキーのIoT基盤におけるAWS IoT Rule Action 活用ビットキーのIoT基盤におけるAWS IoT Rule Action 活用
ビットキーのIoT基盤におけるAWS IoT Rule Action 活用
 
Firefox 3.1 In Depth (?)
Firefox 3.1 In Depth (?)Firefox 3.1 In Depth (?)
Firefox 3.1 In Depth (?)
 
【de:code 2020】 Azure Kubernetes Service と Azure DevOps による GitOps の実践
【de:code 2020】 Azure Kubernetes Service と Azure DevOps による GitOps の実践【de:code 2020】 Azure Kubernetes Service と Azure DevOps による GitOps の実践
【de:code 2020】 Azure Kubernetes Service と Azure DevOps による GitOps の実践
 
"Continuous Publication" with Python: Another Approach
"Continuous Publication" with Python: Another Approach"Continuous Publication" with Python: Another Approach
"Continuous Publication" with Python: Another Approach
 

Dernier

Dernier (7)

LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 

how to port * to BitVisor

  • 2. 自己紹介 ● 東京農工大学 工学府情報工学専攻1年 ● twitter: @icchyr ● CTF: TokyoWesterns ● 研究: OS, セキュリティ
  • 3. 本日お話しすること ● LVisorについて ● LVisorの実装上の課題 ○ BitVisorのどの部分で動かすのか ○ どうやって呼び出すのか ○ エラーが起きたらどうするのか ○ 依存ライブラリはどうするのか ○ etc. ● これらを解決する方法を検討 ○ BitVisorに外部のプログラムを移植した例は多くあるが, ソースコードが公開されているものは少ない ○ 初期実装ではひたすらアドホックに試した → 後に限界が見えてきた ■ なるべくソースコードを改変する必要がない方法を模索 ○ 実装する上での具体的な手順について共有
  • 4. LVisorの背景 ● VMMに汎用スクリプト言語を組み込むモチベーション ○ 比較的簡単に複雑な処理を記述可能 ○ eval相当の機能がある場合は動的にプログラムを追加可能 ○ 通常VMMに動的に機能を追加するのは難しい ● BitVisorにVMI (Virtual Machine Introspection) があるとうれしい ○ ゲストOSから不可視 ■ マルウェア解析環境として適している ○ 他のVMMに比べてパフォーマンスが優れている ■ 解析効率の向上 ● BitVisorにLuaとLibVMIを組み込んだ ○ 普通のBitVisorでは処理を追加するために Cで直接VMMを書き換える必要がある ○ スクリプト言語でBitVisorを使いたい ○ LibVMI+シンボル情報でゲスト OS解析の補助 ○ Luaのプログラムをルールとしてプロセスやネットワークを監視
  • 5. Luaを選んだ理由 ● Luaの特徴 ○ (比較的) 早い ○ バイナリが小さい,依存ライブラリが少ない (最低限libc, libmのみ) ○ 記述方法が多様 ■ 手続き型 ■ プロトタイプベース ■ など ○ インターフェースとして有用 ● BitVisorの特徴 ○ 早い ○ VMMが小さい ○ 拡張のハードルが高い ■ processなどを書いてビルドし直す必要がある ● BitVisorに組み込む上でLuaは比較的相性が良い
  • 6. インターフェースとしてのLua ● LuaをインターフェースとするAPIを提供 ○ システムコールフック ○ 仮想メモリアクセス ○ ネットワークパケットフィルタ ● オブジェクト指向でデータにアクセス ○ フックするイベントに対して処理を登録 ○ イベントハンドラにフック対象に関わるオブジェクトが渡される ● Luaはプロトタイプベースなので記述しやすい ○ メソッドに対して動的に処理を追加できる ○ 関数の動作を上書きすることが可能なため用途に合わせてフレームワーク的に扱える
  • 7. LVisorの例 ● 使用例 ○ /tmp/ で始まるバイナリが起動 (execve) された時に全てのネットワーク通信を遮断 ○ 現状プロセス単位の通信は制御できない denyall = function(eth) return DROP end execve_hook = function(args) filename = args[0] -- execveの第一引数 (filename) へのポインタを取得 filename_s = pmem.read(filename, 0x100) -- filenameを文字列で取得 -- /tmp/で始まるバイナリの場合全てのネットワーク通信を遮断 if string.match(filename_s, “^/tmp/”) ~= nil then net.eth.hooks.add(“*”, “*”, “denyall”, denyall) end end syscall.hooks.add(“netproc”, execve_hook)
  • 9. BitVisorに機能を追加する方法 ● BitVisorで処理を走らせる手段 ○ 一回のみ ■ INITFUNC ○ 定期的 ■ thread ○ dbgshから任意のタイミング ■ process ○ ゲストOSから任意のタイミング ■ vmmcall ● BitVisorの実装 (vpn, storageなど) ○ BitVisorの機能が必要な部分のみ msgbufで呼び出し,それ以外は保護ドメインで処理 ○ 必要な時のみしかRing 0で動作させない方針
  • 10. LVisorの実装方針 ● Ring 0で動かすのは得策ではない ○ 移植するプログラムが巨大であるため ● 基本的にvpnやstorage等と同じ方針をとる ○ 必要な部分だけmsgbufでやりとりする ○ Lua,LibVMIは保護ドメインで動作させる ● まずLuaのインタプリタを組み込み,次にLibVMIを移植 ● 環境 ○ Lua: 5.3.3 ○ LibVMI: 2016年9月時点でのGitHubの版
  • 11. BitVisorのビルドシステムおさらい ● makeをベースとしたビルドシステム ○ 下の階層をビルドした結果を上の階層にリンク ○ オブジェクト (.o) を作る場合は subdirs-1 に追加 ○ 静的ライブラリ (.a) を作る場合は asubdirs-1 に追加 ○ objs-1 にオブジェクトファイルを追加することでビルド対象を決定 ○ CFLAGSを書き換えることでコンパイルオプションを調節 ○ 基本的にカレントディレクトリは一番上 (bitvisor/) になることに注意 ● processのビルド ○ $(name)-objs にオブジェクトファイルを追加 ○ $(name)-libs に依存ライブラリ (.a) を追加 ○ bins-1 にprocessとして登録する名前を追加
  • 12. リンクについて ● BitVisorは基本的にstatic link ○ dynamic linkがサポートされていない ○ そもそもサポートする必要がない (再利用されるコードが極めて小さいため ) ○ バイナリのローダは存在するがライブラリのローダは存在しない ● Ring 0の部分は最終的に全て同じ階層でリンクされる ○ どこかにシンボルが存在していればよい ○ processからリンクしたい場合は process-dependsに加える必要がある
  • 13. ソースコードの配置場所 ● 全てprocess配下に置くのが正しいか? ○ vpnやstorageはそうではない ■ dbgshから呼び出すことを想定していない ● 例: vpn ○ vpn/lib/user.c に処理を書き,process/vpn.c ではexternのようにして呼び出す ○ この構成のメリット ■ process/Makefileを汚さない ■ process/ 以外からもリンクすることができる ● musl, LibVMIは一番上の階層に置く
  • 14. 移植に必要な手順 ● 静的ライブラリまたはオブジェクトを作成する ○ BitVisorのビルドシステムに組み込む ■ findコマンドなどである程度自動化 , コンパイルオプションに注意 ○ プロジェクトのMakefileを直接叩く ■ カレントディレクトリに注意 ● 必要なプログラムの依存関係に加える ○ processであれば$(name)-libs ○ それ以外であればasubdirs-1 (or subdirs-1) ● 標準的なOSの機能を使う部分は修正する必要がある ○ 標準入出力, メモリ管理は特にBitVisorに合わせる必要がある
  • 15. Luaの組み込み方法 ● Luaは比較的移植がしやすい ○ 依存ライブラリが少ない ○ 全てのソースコードが同じ階層に存在し,コンパイルしたオブジェクトをリンクするだけ ■ ビルドシステムへの負担が少ない ○ 静的ライブラリ (.a) を作成できればよい ● BitVisorのビルドシステムに組み込む ○ BitVisorのビルドシステムを理解する ○ process/ 以下にluaのソースコードを丸ごとコピー ○ LuaのMakefileをBitVisor向けに編集 (objs-1にLuaのプログラムを追加していくだけ ) ○ process/MakefileにLuaに関わる部分を追記 ● これだけでは動かない ○ libcが必要 ○ BitVisorは部分的にしかlibcの関数をサポートしていない
  • 16. libcの組み込み方法 ● 必要なlibcを移植するのは大変 → 既存のlibcを移植する ● どのlibcを使うか? ○ eglibc ○ uClibc ○ newlib ○ musl libc ○ etc. ○ 比較的サイズが小さくビルドも簡単な musl libcを採用 ● BitVisorに合わせた変更が必要 ○ ファイルシステムおよび fdの概念が存在しない ○ BitVisorのprocess/libでサポートしている関数に注目 ■ 標準出力 (printf) ■ 標準入力 (lineinput) ■ メモリ管理 (alloc/free) ○ 最低限これらの機能と接続しないと動作しない
  • 17. libcの組み込み方法 ● muslの関数を編集 ○ 標準出力 ■ __fwritexでputcharを使う (process/lib/lib_putchar.c) ■ muslのprintfを使えるようにするため ● BitVisorのprintfは浮動小数点系のフォーマット指定子に対応していない ○ 標準入力 ■ libc側で対応せずにprocessの入力を受け取るところで対処 ○ メモリ管理 ■ malloc ● process/lib/lib_mm.c:alloc を使うように修正 ■ free ● process/lib/lib_mm.c:free を使うように修正 ■ realloc ● size == 0の時のバグを修正 ■ 確保可能な領域は各 processでheap, heaplenを定義して調整
  • 18. libcの組み込み方法 ● ビルドシステムの修正 ○ muslのMakefileをBitVisorに対応させるのは困難 ○ BitVisorのmake中にmuslのmakeを走らせるようにする ■ cleanを回避する場合は ifndef clean_p の中に書く (clean時に定義される変数の一つ ) ● リンク方法の検討 ○ プロジェクトの.aを直接リンクする (ビルド時に生成された .aを指定) ○ BitVisorのビルドシステムで.aを作る (ビルド時に生成された .oを集める) ← こちらを採用 ● 例: include makefiles/musl.mak ifndef clean_p $(info building musl...) $(info $(shell cd $(musl_dir) && make -j4 && cd - >/dev/null)) objs-1 += $(musl_o) endif
  • 19. Luaの組み込み方法 (続き) ● Luaのインタプリタを用意する ○ lua.cをprocess向けに編集 ○ lua_writelineマクロとlua_readlineマクロをそれぞれ編集 ■ printfとlineinputを使うように修正 ○ main関数を修正 ■ setlimitを呼び出して大きくスタックを確保するように修正 ● 標準ではスタックが足りなくてクラッシュする ■ pushcfunction~reportまで削除し,代わりに doREPLを呼び出す ● argc, argvが存在しないためpushcfunctionが使えない ■ exitprocessで終了 ● 浮動小数点レジスタのサポート ○ VMM起動時にCR0を操作して有効化しておく (一時的な措置) ● debugshのprocessからLuaインタプリタが使用可能に
  • 20. LibVMIの組み込み方法 ● LibVMIはlibcの他にGlib, json-cに依存 ○ libcと同様の方法でビルドシステムに組み込む ● LibVMIのBitVisor対応 ○ XenをベースにBitVisor用のdriverを作成 ■ ゲストOSのCPUの読み書き ■ ゲストOSの物理メモリの読み書き ■ ゲストOSの電源操作 (pause, resume, halt) ■ メモリサイズの取得 ○ CPUレジスタ操作,メモリ操作があれば理論上は動作する ○ rekallのprofileを用意 ■ 現状はファイルシステムが無いのでバイナリの dataセクションに埋め込む ■ objcopyでJSONを変換 ■ サイズが非常に大きい (Linuxで約3.3M) ため改善の必要あり
  • 21. LibVMIの組み込み方法 ● ビルドシステムの修正 ○ LibVMIのビルドシステムはKVM, Xenなどの本来対応する VMM用のライブラリに深く依存 ○ BitVisor用のdriverをビルドするようにMakefileを作成 ■ libvmi/およびその下のarch, driver, os以下 ● 例: include makefiles/libvmi.mak CFLAGS += $(libvmi_INCLUDE) curdir = $(libvmi_dir)/driver subdirs-1 += bitvisor obj = $(subst .c,.o,$(shell find $(curdir) -maxdepth 1 -name "*.c")) objs-1 += $(obj:$(curdir)/%=%)
  • 22. 近況 ● Luaはほぼ完全に動作 ○ muslのprint系が壊れていて変な出力が出るものの特に影響はない ● LibVMIが完全に動いていない ○ 動きはするがオフセットがずれている ● ネットワーク監視が完全に動いていない ○ netapiの使い方が把握しきれていない ● 全てのAPIに対応できていない
  • 23. まとめ ● BitVisorへの移植は比較的容易な手順で実現可能 ○ 一番上の階層にプロジェクト用のディレクトリを切り分ける ○ プロジェクトをそのままコピーする ○ Makefile内でプロジェクトのビルドを行う ○ 生成された.oファイルを検索してobjs-1に追加 ● libc, GLibcが移植できたため大抵のプログラムは移植可能 ○ OSの機能を必要とするものは移植できない ○ BitVisorを拡張するのが容易に