From: Marcel Ward Date: 2006-11-18T11:57:05+09:00 Subject: Re: Protecting commercial ruby source code On 17/11/06, Hiren Bridgmohun wrote: > Is there a way to obfuscate my ruby source code. > I have come across ZenObfuscate which at about $2500. > Does anyone know of any other options to protect ruby source code when it is > distributed to clients? I was thinking about this problem ealier this week and trying to come up with a simple obfuscation-through-obscurity solution -- possible to crack with the aid of a debugger but good enough to defeat casual browsing of the contents of an executable. One solution that seemed reasonably simple yet effective was to zip up all the Ruby source code libraries you want to hide and then in your C source, initialise the Ruby interpreter with a basic bootstrap and intialise a hash with your obfuscated libraries. The bootstrap then defines a new 'require' method which first looks for an obfuscated version of the library and evals that or, if the file was not in the hash, uses Kernel::require. I have knocked up a proof of concept using a 'Deobfuscator' module below. As I'm still a Ruby rookie, others may want to point out improvements or problems with this. module Deobfuscator require 'zlib' def self.add_lib(lib_name, obfuscated) @@zipped ||= {} @@zipped[lib_name] = obfuscated end def self.has_lib?(lib_name) @@zipped ||= {} puts "Looking for library #{lib_name} in our hash #{@@zipped.keys.inspect}" @@zipped.has_key? lib_name end def self.deobfuscate(lib_name) Zlib::Inflate.inflate(@@zipped[lib_name]) end def dump puts @@zipped.inspect end end def require(lib_name) if Deobfuscator::has_lib? lib_name puts "Using Deobfuscator to deobfuscate library (#{lib_name})" eval Deobfuscator::deobfuscate(lib_name) else puts "Using Kernel::require(#{lib_name})" Kernel::require(lib_name) end end TEST1 = < outputs the following: # Looking for library test2 in our hash ["test2", "test1"] # Using Deobfuscator to deobfuscate library (test2) # Looking for library test1 in our hash ["test2", "test1"] # Using Deobfuscator to deobfuscate library (test1) # Hello World! from library test1. Of course there could be more improvements to the final implementation, such as compressing the initial bootstrap code so the Ruby code is hidden until runtime (thereby ensuring people don't see any 'deflate's or 'inflate's in the executable strnigs and get ideas). Also one giveaway is that the hash keys are stored in plaintext here for ease of viewing. You'd probably want to obfuscate those similarly, which is easy enough. Again, this is pretty noddy obfuscation and it's not going to stop a hacker with a spare evening from getting hold of your code. For that you should probably go with the commercial option as they will almost certainly have invested time and effort on coming up with a far robust solution. Writing Ruby code to obfuscate a set of library files in a directory using the same method of obfuscation as above and generate C source to initialise the bootstrap should not be too difficult. -- Marcel