バイトコードのローディング
ちょいとメモ。
require 'fiddle' class RubyVM class InstructionSequence addr = Fiddle.dlopen(nil)['rb_iseq_load'] fn = Fiddle::Function.new( addr, [Fiddle::TYPE_VOIDP] * 3, Fiddle::TYPE_VOIDP) define_singleton_method(:load) do |dat, par=nil, opt=nil| fn.call(Fiddle.dlwrap(dat), par, opt).to_value end end end bytecode = RubyVM::InstructionSequence.compile("p 1").to_a RubyVM::InstructionSequence.load(bytecode).eval #=> 1
ここにあったコードがWindowsだからなのかなんなのか動かなかったので動くように直して、テキストを食わせて動かす形にしてみた。
RubyはVMを使うようになってからバイトコードを解釈して動作していて、このバイナリをファイルに出力してそれを読むようにすればソースの隠蔽は可能である。問題点はRubyVM::InstructionSequence.loadが「食わせるバイナリを検証する機能がない」という理由でコメントアウトされているところだが、C用のインターフェイスは提供されているので例えばDXRubyから呼ぶというのも手である。しかしFiddleを使えばRubyから呼べる。DLを使うようにすればRuby1.9でもいけるんじゃないかと思う。無論、変なもの食わせるとコケるかもしれん。
ともあれ、これをうまいこと使えればソース隠蔽に道が開けるんじゃないかなーなど。ちなみにto_aした配列は厳密にはバイナリでは無い。