RubyToRubyC - ruby's first real obfuscator?

| | Comments (6)
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:
$ 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:
// 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.

6 Comments

Again, awesome!!! This is getting cooler every time.

first this is great, but IIRC there was a simple ruby->rubyc translator in the 1.6 days so maybe not the first one :)

Could you show a less trivial example?

Very cool.

But why 'rbpath2class("Object")' instead of just 'rbcObject'?

Also, is the lack of formatting in the C code a product of your blog engine or is that the actual output? I suppose if obfuscation is the goal, then perhaps the lack of formatting is a good thing. :)

Dan

PS - How do I format my comments? It doesn't seem to like literal html.

Gabriele: url? Does it still work? Maybe I should say first real obfuscator for ruby 1.8+? :)

Dan: path2class is there presumably because this works w/ nested classes/modules. And yeah, no formatting because people aren't /supposed/ to read it. :P

comment formatting? no clue.

This is nifty, and seems far more than a joke. If you run rubicon through it, the result looks like a ruby C api test suite. If parrot is to ever support ruby, we will need one.

Also, indentation is trivial to add, and I've found it makes debugging generated C code much easier.

Leave a comment