> Just for a little bit of fun, I wrote a dumb obfuscator. It takes a ruby script > and converts it to a C integer array with the ASCII values increased by > array size and the letter's index in the array. This is then included in a C > source file. This then converts the code back to a char array in dynamically > allocated memory and evaluates it with rb_eval_string_protect. The problem is that you have the original code in memory as you run the program... just stopping the program while it's running and inspecting the memory will give away the source without needing any magic tricks. What i would do, would be to run the program inside 'gdb', then interrupt it by sending it a signal, then dump the memory currently in use to a file, and scan the file for code. Now i just ran it with valgrind, and i guess i was just lucky, as you can see further down. I think it's a better approach to use a good obfuscator for method/variable/class/parameter renaming, and then encrypt the obfuscated code. You could generate a private/public key pair for each customer, encrypt the obfuscated code with the public key and encrypt the private key with the license details of the customer (something commonly used in shareware), then you write a decryption routine in C (C extension) to decrypt the private key with the customer details (name). I don't know whether it's a good 'barrier' against piracy, but since each copy would be encrypted with different keys, a simple patch would be useless. But it'd be a better barrier against 'code-stealing' if that's what you're concerned about. The hard part is making a good obfuscator for ruby, is there already a kind of analysis framework available for ruby ? Because it seems to me that a lot of work done for ruby code refactoring would be very usefull for a code obfuscator... code obfuscation is just a kind of automatic code refactoring ? (well, with quite the opposite intention :) Just my thoughts... Ruben ======================================== ruben@beast ruben $ valgrind --gdb-attach=yes ./foo ==5680== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux. ==5680== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward. ==5680== Using valgrind-2.0.0, a program supervision framework for x86-linux. ==5680== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward. ==5680== Estimated CPU clock rate is 1700 MHz ==5680== For more details, rerun with: -v ==5680== ==5680== Invalid read of size 1 ==5680== at 0x402D114C: rb_str_new2 (in /usr/lib/libruby18.so.1.8.1) ==5680== by 0x4026A6CF: rb_eval_string (in /usr/lib/libruby18.so.1.8.1) ==5680== by 0x4026A7C2: rb_eval_string_protect (in /usr/lib/libruby18.so.1.8.1) ==5680== by 0x80486CC: (within /home/ruben/foo) ==5680== Address 0x412EB0B6 is 0 bytes after a block of size 146 alloc'd ==5680== at 0x40028A51: malloc (in /usr/lib/valgrind/vgskin_memcheck.so) ==5680== by 0x804867C: (within /home/ruben/foo) ==5680== by 0x40325C3B: __libc_start_main (in /lib/libc-2.3.2.so) ==5680== by 0x80485B0: (within /home/ruben/foo) ==5680== ==5680== ---- Attach to GDB ? --- [Return/N/n/Y/y/C/c] ---- n ==5680== ==5680== Conditional jump or move depends on uninitialised value(s) ==5680== at 0x40008DAE: _dl_relocate_object (in /lib/ld-2.3.2.so) ==5680== by 0x4040D48D: (within /lib/libc-2.3.2.so) ==5680== by 0x4000B265: _dl_catch_error (in /lib/ld-2.3.2.so) ==5680== by 0x4040D6F2: _dl_open (in /lib/libc-2.3.2.so) ==5680== ==5680== ---- Attach to GDB ? --- [Return/N/n/Y/y/C/c] ---- y ==5680== starting GDB with cmd: /usr/bin/gdb -nw /proc/5680/exe 5680 ... so, then just checking the malloc-ed memory... (gdb) p /x (0x412EB0B6 - 146) $1 = 0x412eb024 (gdb) dump memory testje_foo 0x412eb024 0x412EB0B6 ruben@beast ruben $ cat testje_foo require 'openssl' puts "obfuscated ruby - woohoo!" puts "Here's a hash:" foo = OpenSSL::Digest::SHA1.new foo.update("obfuscate me baby") puts foo