2013-12-25
■[ruby][BHyVe]任意のアセンブリコードを仮想マシンで実行しちゃうRuby gemを作ってみた
このブログエントリはカーネル/VM Advent Calendar 2013 25日目の記事です。
前回、カーネル/VM探検隊で「バインディングさえあればスクリプト言語でもゲストOSローダを実装出来る」という話をちらっとしました(資料)。
今回の記事では、ゲストOSローダではなくてもっと実験的な、簡単なアセンブリコードをRubyスクリプトからハイパーバイザへ投入する仕組みを実装したのでこれを紹介します。
ruby-virtualmachine
ruby-virtualmachineというgemを作成しました。
これを用いて、任意のアセンブリコードをアセンブル・ロード・VM上で実行、までの一連の処理をわずかな行数のRubyスクリプトで行えます。
インストール
BHyVeが正常動作するFreeBSD 10.0以降の環境が必要です。
$ gem install virtualmachine
サンプルプログラム
以下に、引数で渡された文字を指定回数だけ仮想マシンのシリアルポート(ポート3F8h)へ表示するプログラムの例を示します。
VMの終了には未実装IOポートへのアクセスを利用しています(ポート10h)。
require 'virtualmachine' if ARGV.size < 2 puts "sample1.rb [char] [repeat]" exit 1 end puts "[args]" puts "char:#{ARGV[0]}" puts "repeat:#{ARGV[1]}" puts vm0 = VirtualMachine.new('vm0', 128) vm0.rax = ARGV[0].bytes.to_a[0] vm0.rcx = ARGV[1].to_i vm0.load_asm(<<EOS) mov dx, 3F8h loop: out dx, al dec cx cmp cx, 0 jne loop mov al, 0ah out dx, al mov dx, 10h mov al, 0h out dx, al EOS puts "[registers]" puts "rax:#{vm0.rax}" puts "rbx:#{vm0.rbx}" puts "rcx:#{vm0.rcx}" puts "rdx:#{vm0.rdx}" puts "rip:#{vm0.rip}" puts puts "[run vm]" vm0.run puts puts "[registers]" puts "rax:#{vm0.rax}" puts "rbx:#{vm0.rbx}" puts "rcx:#{vm0.rcx}" puts "rdx:#{vm0.rdx}" puts "rip:#{vm0.rip}"
簡単な使い方としては、vm = VirtualMachine.new(VM名, メモリサイズ)でインスタンスを作成、vm.load_asm(アセンブリコード)で0x10000にアセンブリコードをロード、vm.runで実行です。
vm.raxなどとレジスタ名を指定することにより、レジスタの読み書きが可能です。
実行例
以下が実行結果です。
ここでは、表示する文字に*を、リピート回数に30回を指定しています。
$ sudo ruby sample1.rb '*' 30 [args] char:* repeat:30 [registers] rax:42 rbx:0 rcx:30 rdx:0 rip:65536 [run vm] ****************************** [registers] rax:0 rbx:0 rcx:0 rdx:16 rip:65559
制限
- FreeBSD BHyVeに依存しています。後々Linux KVMへ移植したいと考えています。
- 初期化ルーチンがC拡張の中にハードコーディングされています。ここではページテーブルやGDTの初期化、インストラクションポインタやコントロールレジスタの設定を決め打ちで行い、64bitプロテクトモードで0x10000から起動するように設定されています。このようなコードは全てRubyへ移していく予定です。
- BHyVeの実装上の制約でデバイスが限られています。使えないレガシデバイスが多く存在します。
- BHyVeの実装上の制約でBIOS/UEFIをサポートしないため、ファームウェアをコールする実験には使えません。
- アセンブリロード以外の方法でのRubyからのゲストメモリ空間の読み書きは未実装です。
…というわけで、いまは制限だらけの実装ですが、もう少し機能が増えれば「今までRubyしか書いたことないけど、勉強のためにアセンブリコードを書いてみよう!」なんて用途に使えるかもしれません。
- 748 http://www.google.co.uk/url?sa=t&source=web&cd=1
- 201 https://www.google.co.jp/
- 85 http://b.hatena.ne.jp/hotentry/it
- 84 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=1&ved=0CC4QFjAA&url=http://d.hatena.ne.jp/syuu1228/20110728/1311878151&ei=W3C7UtzIJMbDkwWA_IHwBA&usg=AFQjCNGb-A5UfG20Z8Rzy6fixfRDgrTaEw&bvm=bv.58187178,d.dGI
- 67 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCwQFjAA&url=http://d.hatena.ne.jp/syuu1228/20111122/1321981903&ei=Ck27UtKeFs3TkAW4sIEw&usg=AFQjCNH84DupAkVgnFJ1Zqeg0nmHK8R83g&bvm=bv.58187178,d.dGI&cad=rja
- 61 https://www.facebook.com/
- 54 http://qiita.com/advent-calendar/2013/kernelvm
- 54 http://t.co/OuyER8Loqp
- 42 http://t.co/NH0CwxOt6S
- 34 http://htn.to/gnkcEB