作ってみた

「任意のバイナリコードを他のローカルユーザに実行させられる脆弱性」があるかもしれないので、と一応注意

#!/usr/bin/ruby
# vi:set ts=3 sw=3:
# vim:set sts=0 noet:

require 'dl/import'
require 'tempfile'

module RASM
   extend DL::Importable

   EAX = :EAX
   EBX = :EBX
   ECX = :ECX
   EDX = :EDX

   def initialse_instance
      @bufs = {}
   end

   def asm
      @bufs[Thread.current] = ''
   end

   def push_code s
      @bufs[Thread.current] << s
   end

   def add op0, op1
      push_code 'add ' + op0.to_s + ', ' + op1.to_s + "\n"
   end

   def mov op0, op1
      push_code 'mov ' + op0.to_s + ', ' + op1.to_s + "\n"
   end

   def mul op
      push_code 'mul ' + op.to_s + "\n"
   end

   def ret
      push_code 'ret' + "\n"
   end

   def asm_fin
      funcname = '_' + rand.to_s[2..-1]
      code = ''
      code << 'global ' + funcname + "\n" + funcname + ':' + "\n"
      code << @bufs[Thread.current]
      @bufs.delete Thread.current
      basename = '/tmp/' + funcname
      tempfile = open basename + '.asm', 'w'
      tempfile.write code
      tempfile.close
      system 'nasm -f elf ' + basename + '.asm'
      system 'rm ' + basename + '.asm'
      system 'gcc -shared -fPIC -o ' + basename + '.so ' + basename + '.o'
      system 'rm ' + basename + '.o'
      RASM.dlload basename + '.so'
      system 'rm ' + basename + '.so'
      RASM.extern 'int ' + funcname + '()'
      funcname
   end
end

class Foo
   include RASM

   def initialize
      initialse_instance
   end

   def bar a, b, c
      asm
         mov EAX, a
         add EAX, b
         mov EBX, c
         mul EBX
         ret
      asm_fin
   end

   def call funcname
      RASM.__send__ funcname
   end
end

baz = Foo.new
funcname = baz.bar 2, 3, 4
result = baz.call funcname
p result

Ruby ← キーワード検索 SEO