RubyToRubyC - ruby's first real obfuscator?
Published 2005-05-05 @ 17:08
Tagged ruby, metaruby, ruby2c, toys, zenobfuscate
Eric did something very very cool the other day. He wrote a new tail to the ruby2c pipeline that outputs Ruby C instead of generic C. As a result, he is able to automatically translate the following:
1 2 3 4 5 6 7 8 9 10 11 12 |
$ cat demo/factorial.rb class F def factorial(n) f = 1 n.downto(2) { |x| f *= x } return f end def main # horrid but funny hack return factorial(5) end end |
into:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// BEGIN METARUBY PREAMBLE #include <ruby.h> #define case_equal_long(x, y) (rb_funcall((x), rb_intern("==="), 1, (y))) // END METARUBY PREAMBLE // class F < Object static VALUE rrc_cF_factorial(VALUE __self, VALUE n) { VALUE f; VALUE x; f = LONG2FIX(1); x = n; while (RTEST(rb_funcall(x, rb_intern(">="), 1, LONG2FIX(2)))) { f = rb_funcall(f, rb_intern("*"), 1, x); x = rb_funcall(x, rb_intern("-"), 1, LONG2FIX(1)); }; return f; } void Init_F() { VALUE rrc_cF = rb_define_class("F", rb_path2class("Object")); rb_define_method(rrc_cF, "factorial", rrc_cF_factorial, 1); } |
As a result, pretty much any ruby code can be automatically translated to C with no real effort on our part. We can even bypass the type inference engine (for now at least). I think this is the first real step towards a ruby obfuscator.