Obfuscating Ruby Code

Sorry, I meant:

puts Crypt::Fog.decrypt…

David

···

On Wed, 2 Jun 2004, David A. Black wrote:

This is probably a stupid question, but… what if someone did:

ruby -e ‘require “crypt/fog”; puts eval(Crypt::Fog.decrypt(…)’


David A. Black
dblack@wobblini.net

Hi –

···

On Thu, 3 Jun 2004, Michael Campbell wrote:

Well, you happen to know the method and the salt with which to decrypt
the example I gave you. Besides, the OP only hasked for obfuscation,
not encryption.’

Where does obfuscation stop and encryption begin?

I think (for this purpose anyway) encryption is one form of
obfuscation.

David


David A. Black
dblack@wobblini.net

Philipp Kern trash@philkern.de wrote in message news:slrncbrv95.qmp.trash@o2.net.philkern.de

···

On 2004-06-02, Daniel Berger djberg96@hotmail.com wrote:

ruby -e ‘require “crypt/fog”;eval(Crypt::Fog.decrypt(IO.readlines(“cfoo.rb”).to_s.chomp,44))’

And how do you obfuscate the salt? Because that’s the problem we try to deal
with. As soon as you call the decrypter you need the password available.

Bye,
phil

  1. Put above code in file
  2. chown root file
  3. chmod 700 file

Regards,

Dan

Hello Jim,

If that's the goal, why not use exerb with the ZLib option turned on?
The resulting binaries can't be grepped for source.

Sure, all someone would need to do is a little reverse engineering on
exerb to figure out how to extract the source, or simply have memorized
what a ZLib header looks like, but seems to me it's a "reasonable
barrier" for the purpose you're describing.

That said, it'd still be a great thing to have a general, more secure
way of securing ruby source. I'd like to be able to take advantage of
it as well.

Jim Moy

All this methods are killed with my 3 minutes 4 line hack.
You must change the interpreter - there is simply no other way.
Now that i posted the patch even a script kid that can use "google" can
crack your code.

···

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

Hi,

How does obfuscating solve your problem? How is that even
a problem? Just include a compiled ruby interpreter for
your target platform, and have a link in your code that
says “For more info about ruby and to download the
interpreter, go to www.ruby-lang.org” …

Obfuscaters serve no real use - as long as somebody can pass
your code through a lexer, it’s instantly unobfuscated.

I imagine the obfuscation would include translation of once-
meaningful identifiers (variable names, method names, …)
into meaningless gibberish. A lexer would not help much there.

Such an obfuscator sounds really tough to write for Ruby
though… I presume the string form of eval() would have
to be disallowed from referring to any code subject to
obfuscation…

I would be very interested in a working Ruby code obfuscator,
even given certain restrictions like that. I’m writing an
application in Ruby that will likely be heavily pirated, like
a video game, as soon as a cracked copy of it becomes
available. As with video games, which i used to do for about
9 years professionally, we’re just trying to delay the time it
takes for someone to produce a cracked version. At least,
I’m presuming anyone needing a Ruby code obfuscator is probably
coming from the same situation. That’s why I’d like one anyway.
I’m developing in Ruby because I want to add features faster
than the competition. (Not to mention how much fun programming
in Ruby is. :slight_smile: But I’ve gone into writing this app in Ruby
knowing I’m going to need some solution to delaying the
(inevitable) appearance of a cracked version of my app. So I’m
very glad to hear Ken is working on such a technology, and
grateful he’d be willing to share it.

Regards,

Bill

···

From: “Gregory Millam” walker@lethalcode.net

How about supplying a modified ruby interpreter? The only difference
between this one and the standard one is that it only reads encrypted
files that decrypt with the compiled in key or a key that in itself is
obfuscated in a file. This would mean that you don’t need to supply
readable source, in fact to the end user it would look like native or
byte code. You could extend this to have the code signed or something
if you wished.

J.

···

On 02/06/2004, at 12:28 PM, daz wrote:

Ken Hilton wrote:

[…] I’m actually designing an obfuscator and will happily share it
should a suitable alternative not already exist.

I think you’re on safe ground, Ken.

This thread may confirm:
www.ruby-talk.org/100469 (9 messages)

daz

Here are a few quick suggestions for the obfuscator:

– remove all comments.
– on a case by case basis, find each token that is not a reserved word
or operator and replace all occurrences of it with a randomly generated
string, preferrably as short as possible. Alternatively, start using
the letter a as a token and move down the alphabet, repeating letters as
needed, such as: a, b, c, … z, aa, bb, cc, … zz, aaa, etc. Be sure
to keep constants uppercase.
– remove all newlines, adding keywords as necessary to keep it compiling.
– rot13 all strings and surround them with de-rot13-ing code
– replace all require statements with the text of the included files
wrapped in a conditional, which in turn will reduce the number of files
you will distribute in the obfuscated version.

Carl

Hello Michael,

Hello Michael,

>> Does anyone know of a Ruby source code obfuscator that's reliable and
>> readily available? If so, I'd appreciate a pointer to it (apparently, both
>> ruby-lang and rubygarden are down at the time of this posting so I can't
>> check for myself.)

> Take a look at bRuby. It can dump the interal node-tree and then load it
> again (as far as I understand it). No Ruby sourcecode anymore. See also
> the Exerb project.

> http://bruby.sourceforge.jp/index.en.html

But this is easy to reverse. It does not much more then removing the

Hm, I thought, a node-dump does not contain the variable names (local
variables), or at least does not require them for execution? I am
probably wrong.

Look at "node.h". The nodes store ID values which are atoms (integers
that represent strings in a unique way). But there is no garantee that
one atom name integer as in the next ruby.exe start. And of course
they depend on the "require" order of the different source files.

Hm, sure, the method names must be stored. But one could modify the
interpreter to only store hashes of the method names, and use them to
call the methods. That might give quite good obfusciation.

There is no possible mapping for this. Hashes are not unique. You must
store the string in one way or the other. As long as you can look at
the source every person with 1 year C experience can reverse this.

···

On Wed, Jun 02, 2004 at 01:04:55PM +0200, Lothar Scholz wrote:

> On Wed, Jun 02, 2004 at 06:08:39AM +0900, Ken Hilton wrote:

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

David A. Black wrote:

Well, you happen to know the method and the salt with which to decrypt
the example I gave you. Besides, the OP only hasked for obfuscation,
not encryption.’

Where does obfuscation stop and encryption begin?

I think (for this purpose anyway) encryption is one form of
obfuscation.

I would refer to code that is ‘difficult to read’ by humans but is ‘normal’
for the machine as obfuscation while it is impossible to read by both human
and machine without a key is encryption.

David may be right technically.

rolo

···

On Thu, 3 Jun 2004, Michael Campbell wrote:

Daniel Berger wrote:

Philipp Kern trash@philkern.de wrote in message news:slrncbrv95.qmp.trash@o2.net.philkern.de

ruby -e ‘require “crypt/fog”;eval(Crypt::Fog.decrypt(IO.readlines(“cfoo.rb”).to_s.chomp,44))’

And how do you obfuscate the salt? Because that’s the problem we try to deal
with. As soon as you call the decrypter you need the password available.

Bye,
phil

  1. Put above code in file
  2. chown root file
  3. chmod 700 file

So does this mean that he should ask his client, to whom he is selling
the closed-source ruby software, for root access to their servers?

···

On 2004-06-02, Daniel Berger djberg96@hotmail.com wrote:

Daniel Berger wrote:

Philipp Kern <trash@philkern.de> wrote in message news:<slrncbrv95.qmp.trash@o2.net.philkern.de>...

ruby -e 'require "crypt/fog";eval(Crypt::Fog.decrypt(IO.readlines("cfoo.rb").to_s.chomp,44))'

And how do you obfuscate the salt? Because that's the problem we try to deal
with. As soon as you call the decrypter you need the password available.

1) Put above code in file
2) chown root file
3) chmod 700 file

Sorry, but this is getting sillier and siller :slight_smile:

The original problem is to obfuscate Ruby code against end users, which will have full control to the application, their machine, and the whole filesystem.

For the above to work, you'll have to distribute your software as in ASP/rented fashion, not shrink-wrapped. In this case, you don't need obfuscation anyway.

···

On 2004-06-02, Daniel Berger <djberg96@hotmail.com> wrote:

--
dave

Wouldn't a challenge/response system or private/public key encryption be better?

···

On Thursday, 3 June 2004 at 9:58:38 +0900, Daniel Berger wrote:

Philipp Kern <trash@philkern.de> wrote in message news:<slrncbrv95.qmp.trash@o2.net.philkern.de>...
> On 2004-06-02, Daniel Berger <djberg96@hotmail.com> wrote:
> > ruby -e 'require "crypt/fog";eval(Crypt::Fog.decrypt(IO.readlines("cfoo.rb").to_s.chomp,44))'
>
> And how do you obfuscate the salt? Because that's the problem we try to deal
> with. As soon as you call the decrypter you need the password available.
>
> Bye,
> phil

1) Put above code in file
2) chown root file
3) chmod 700 file

--
Jim Freeze
Stay away from flying saucers today.

Encryption may be a form of obsfuscation, but obsfuscation
is not a form of encryption.

···

On Thursday, 3 June 2004 at 4:01:30 +0900, David A. Black wrote:

Hi --

On Thu, 3 Jun 2004, Michael Campbell wrote:

> > Well, you happen to know the method and the salt with which to decrypt
> > the example I gave you. Besides, the OP only hasked for obfuscation,
> > not encryption.'
>
> Where does obfuscation stop and encryption begin?

I think (for this purpose anyway) encryption is one form of
obfuscation.

--
Jim Freeze
What you don't know can hurt you, only you won't know it.

“Bill Kelly” billk@cts.com schrieb im Newsbeitrag
news:004b01c44850$ebe89b90$6442a8c0@musicbox…

Hi,

From: “Gregory Millam” walker@lethalcode.net

How does obfuscating solve your problem? How is that even
a problem? Just include a compiled ruby interpreter for
your target platform, and have a link in your code that
says “For more info about ruby and to download the
interpreter, go to www.ruby-lang.org” …

Obfuscaters serve no real use - as long as somebody can pass
your code through a lexer, it’s instantly unobfuscated.

I imagine the obfuscation would include translation of once-
meaningful identifiers (variable names, method names, …)
into meaningless gibberish. A lexer would not help much there.

Such an obfuscator sounds really tough to write for Ruby
though… I presume the string form of eval() would have
to be disallowed from referring to any code subject to
obfuscation…

Yes indeed. I harvest a slight doubt that this is possible in Ruby - at
least it’s an order of magnitude more difficult than for other languages:
you need to take into consideration

  • singleton methods
  • the eval family of methods
  • loaded modules
  • ObjectSpace
  • implicit conversions (you don’t want to change the name of #to_s or
    #coerce)
  • dynamic mixins

This will make it very hard to decide whether a given identifier (aka
constant) can safely be replaced by an obfuscated constant and which
constant to use.

I would be very interested in a working Ruby code obfuscator,
even given certain restrictions like that. I’m writing an
application in Ruby that will likely be heavily pirated, like
a video game, as soon as a cracked copy of it becomes
available. As with video games, which i used to do for about
9 years professionally, we’re just trying to delay the time it
takes for someone to produce a cracked version. At least,
I’m presuming anyone needing a Ruby code obfuscator is probably
coming from the same situation. That’s why I’d like one anyway.
I’m developing in Ruby because I want to add features faster
than the competition. (Not to mention how much fun programming
in Ruby is. :slight_smile: But I’ve gone into writing this app in Ruby
knowing I’m going to need some solution to delaying the
(inevitable) appearance of a cracked version of my app. So I’m
very glad to hear Ken is working on such a technology, and
grateful he’d be willing to share it.

Maybe your best bet is to encrypt all source code with a public keys and
create a compiled Ruby interpreter that decrypts code with a private key
when reading a file. That way others could use CryptRuby™ also. A
slight disadvantage is, that you need to keep the sources to yourself,
thus becoming the only source of compiled interpreters for that Ruby
variant…

Kind regards

robert

Hello Bill,

I imagine the obfuscation would include translation of once-
meaningful identifiers (variable names, method names, ...)
into meaningless gibberish. A lexer would not help much there.

Such an obfuscator sounds really tough to write for Ruby
though... I presume the string form of eval() would have
to be disallowed from referring to any code subject to
obfuscation...

I would be very interested in a working Ruby code obfuscator,
even given certain restrictions like that. I'm writing an
application in Ruby that will likely be heavily pirated, like
a video game, as soon as a cracked copy of it becomes
available. As with video games, which i used to do for about
9 years professionally, we're just trying to delay the time it
takes for someone to produce a cracked version. At least,
I'm presuming anyone needing a Ruby code obfuscator is probably
coming from the same situation. That's why I'd like one anyway.
I'm developing in Ruby because I want to add features faster
than the competition. (Not to mention how much fun programming
in Ruby is. :slight_smile: But I've gone into writing this app in Ruby
knowing I'm going to need *some* solution to delaying the
(inevitable) appearance of a cracked version of my app. So I'm
very glad to hear Ken is working on such a technology, and
grateful he'd be willing to share it.

I would also like to see something like this.
But to be true, it wouldn't help very much. The only real protection
system is to put the ruby source code under a BSD license so that you
can change the code and add some private decryption code inside the
"rb_compile_cstr" function. Of couse this can't be open source.
Remember that even a bytecode wouldn't help that much, as you can see
in decompiled Python/Java code. It's very readable.

So my request is up going to matz directly if he want's to change
the license for the ruby interpreter, allowing ruby to be more useable in
some kind of commerical applications.

···

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

Hm, but you could replace all “method_name” methods with
“obfuscated_method_name” (e.g. using a SHA1 hash function) and if you
know all method names a priori, then you could use a perfect hash. Or
if there should be a collision, then fall back using plain method names.

Obfusciating method names should be doable, and without knowing the real
names, it’s much harder to read.

Regards,

Michael

···

On Wed, Jun 02, 2004 at 01:36:24PM +0200, Lothar Scholz wrote:

Hello Michael,

On Wed, Jun 02, 2004 at 01:04:55PM +0200, Lothar Scholz wrote:

Hello Michael,

On Wed, Jun 02, 2004 at 06:08:39AM +0900, Ken Hilton wrote:

Does anyone know of a Ruby source code obfuscator that’s reliable and
readily available? If so, I’d appreciate a pointer to it (apparently, both
ruby-lang and rubygarden are down at the time of this posting so I can’t
check for myself.)

Take a look at bRuby. It can dump the interal node-tree and then load it
again (as far as I understand it). No Ruby sourcecode anymore. See also
the Exerb project.

http://bruby.sourceforge.jp/index.en.html

But this is easy to reverse. It does not much more then removing the

Hm, I thought, a node-dump does not contain the variable names (local
variables), or at least does not require them for execution? I am
probably wrong.

Look at “node.h”. The nodes store ID values which are atoms (integers
that represent strings in a unique way). But there is no garantee that
one atom name integer as in the next ruby.exe start. And of course
they depend on the “require” order of the different source files.

Hm, sure, the method names must be stored. But one could modify the
interpreter to only store hashes of the method names, and use them to
call the methods. That might give quite good obfusciation.

There is no possible mapping for this. Hashes are not unique. You must
store the string in one way or the other. As long as you can look at
the source every person with 1 year C experience can reverse this.

Quoteing carl@youngbloods.org, on Thu, Jun 03, 2004 at 10:06:20AM +0900:

Daniel Berger wrote:
>>And how do you obfuscate the salt? Because that's the problem we try to
>>deal
>>with. As soon as you call the decrypter you need the password available.
>
>1) Put above code in file
>2) chown root file
>3) chmod 700 file
>
So does this mean that he should ask his client, to whom he is selling
the closed-source ruby software, for root access to their servers?

And tell his customers that they aren't allowed root access to their own
servers! :slight_smile:

Sam

Great minds think alike. Coincidentally, my wife came to the same
conclusion last night, and she's not even in the industry.

"David Garamond" <lists@zara.6.isreserved.com> wrote in message
news:40BEFB85.8050003@zara.6.isreserved.com...

Daniel Berger wrote:
> Philipp Kern <trash@philkern.de> wrote in message

news:<slrncbrv95.qmp.trash@o2.net.philkern.de>...

>
>>
>>>ruby -e 'require

"crypt/fog";eval(Crypt::Fog.decrypt(IO.readlines("cfoo.rb").to_s.chomp,44))'

>>
>>And how do you obfuscate the salt? Because that's the problem we try to

deal

···

>>On 2004-06-02, Daniel Berger <djberg96@hotmail.com> wrote:
>>with. As soon as you call the decrypter you need the password available.
>>
>
> 1) Put above code in file
> 2) chown root file
> 3) chmod 700 file

Sorry, but this is getting sillier and siller :slight_smile:

The original problem is to obfuscate Ruby code against end users, which
will have full control to the application, their machine, and the whole
filesystem.

For the above to work, you'll have to distribute your software as in
ASP/rented fashion, not shrink-wrapped. In this case, you don't need
obfuscation anyway.

--
dave

It would be childs play to extract the private key from the interpreter
though.

···

On Wednesday 02 Jun 2004 08:38, Robert Klemme wrote:

Maybe your best bet is to encrypt all source code with a public keys and
create a compiled Ruby interpreter that decrypts code with a private key
when reading a file. That way others could use CryptRuby™ also. A
slight disadvantage is, that you need to keep the sources to yourself,
thus becoming the only source of compiled interpreters for that Ruby
variant…

Hello Michael,

Hm, but you could replace all "method_name" methods with
"obfuscated_method_name" (e.g. using a SHA1 hash function) and if you
know all method names a priori, then you could use a perfect hash. Or
if there should be a collision, then fall back using plain method names.

The main problem comes with the dynamic nature of ruby. Other people
already mentioned some of this. The node tree only gives you a nice
readable syntax representation, but it does not solve any of the
problems.

Of couse if you have a "clean" program then it shouldn't be so difficult, but
writing a generic obfuscator is an almost impossible way. For example
look at "tk.rb" - its a really ugly ruby code using all kind of tricks
that are possible with an interpreted ruby.

So to repeat myself the best way is to add some kind of decryption
into the ruby.exe and make the modified ruby source code as closed
source.

···

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's