Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Obfuscating Ruby Code.

814 views
Skip to first unread message

Ken Hilton

unread,
Jun 1, 2004, 5:04:26 PM6/1/04
to
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.)

Thanks in advance,

Ken.


Mark Firestone

unread,
Jun 1, 2004, 5:33:18 PM6/1/04
to
You could just let me write the program for you. That should keep anyone
from reading it.

"Well if it makes you feel any better, he's probably doing her right now."

--------------------------------------------------------------
Website - http://www.retrobbs.org
Tradewars - telnet tradewars.retrobbs.org
BBS - http://bbs.retrobbs.org:8000
IRC - irc.retrobbs.org #main
WIKI - http://www.tpoh.org/cgi-bin/tpoh-wiki

Ken Hilton

unread,
Jun 1, 2004, 9:14:44 PM6/1/04
to
Too funny, I expected as much ;) Seriously, I have certain customers who do
not want to purchase a source code license but since Ruby source is required
(no pun intended) to deliver a Ruby app., customers must receive the source
(and converting to C is not generally an option.) I'm actually designing an
obfuscator and will happily share it should a suitable alternative not
already exist. (And I hope your code is not so unreadable as to be
considered self-obfuscating, unless of course you planned on everything
being written in Deutsch :)

Ken.

"I want to leave this world the same way I came into it: naked, spanked and
screaming."

"Mark Firestone" <hash...@retrobbs.org> wrote in message
news:016c01c4481f$d9cb6c70$4601a8c0@ebrius...

Gregory Millam

unread,
Jun 1, 2004, 9:58:31 PM6/1/04
to
Received: Wed, 2 Jun 2004 10:18:39 +0900
And lo, Ken wrote:

> Too funny, I expected as much ;) Seriously, I have certain customers who do
> not want to purchase a source code license but since Ruby source is required
> (no pun intended) to deliver a Ruby app., customers must receive the source
> (and converting to C is not generally an option.) I'm actually designing an
> obfuscator and will happily share it should a suitable alternative not
> already exist. (And I hope your code is not so unreadable as to be
> considered self-obfuscating, unless of course you planned on everything
> being written in Deutsch :)
>
> Ken.

Err ...

Obfuscate Ruby code? I'm at a loss here ... :D. Perl is inanely obfuscated by default, but Ruby?

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.

- Greg


daz

unread,
Jun 1, 2004, 10:27:39 PM6/1/04
to

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

Bill Kelly

unread,
Jun 1, 2004, 11:15:50 PM6/1/04
to
Hi, Ken,

From: "Ken Hilton" <ken...@comcast.net>
> I'm actually designing an
> obfuscator and will happily share it should a suitable alternative not
> already exist.

I'm very interested in this, and would be willing to help if I
could be of any assistance.

Have you decided on an approach? I presume there must be
restrictions on certain dynamic aspects of Ruby, such as
string eval() not being able to reference any obfuscated code?

Regards,

Bill


Bill Kelly

unread,
Jun 1, 2004, 11:18:44 PM6/1/04
to
Hi,

From: "Gregory Millam" <wal...@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...

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. :) 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

jm

unread,
Jun 1, 2004, 11:39:25 PM6/1/04
to
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.

Robert Klemme

unread,
Jun 2, 2004, 3:34:27 AM6/2/04
to

"Bill Kelly" <bi...@cts.com> schrieb im Newsbeitrag
news:004b01c44850$ebe89b90$6442a8c0@musicbox...

> Hi,
>
> From: "Gregory Millam" <wal...@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. :) 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(TM) 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

Michael Neumann

unread,
Jun 2, 2004, 3:56:41 AM6/2/04
to

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

Regards,

Michael


Andrew Walrond

unread,
Jun 2, 2004, 4:26:14 AM6/2/04
to
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(TM) 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...
>

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


Lothar Scholz

unread,
Jun 2, 2004, 6:57:09 AM6/2/04
to
Hello Bill,


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

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

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

Lothar Scholz

unread,
Jun 2, 2004, 7:04:58 AM6/2/04
to
Hello Michael,

MN> 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.)

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

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

But this is easy to reverse. It does not much more then removing the
comment lines. You can traverse the sourcecode and sometimes get a much
more readable source code - because the output routine is able to do
correct indentation. So there could be one generic tool(!!) to crack
protected ruby code and this is the main problem. The heart of copy
protection is to make the cracking process so difficult that only a
few very very skilled programmer can crack your application and need a
long time to do this.

Michael Neumann

unread,
Jun 2, 2004, 7:24:46 AM6/2/04
to
On Wed, Jun 02, 2004 at 01:04:55PM +0200, Lothar Scholz wrote:
> Hello Michael,
>
> MN> 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.)
>
> MN> Take a look at bRuby. It can dump the interal node-tree and then load it
> MN> again (as far as I understand it). No Ruby sourcecode anymore. See also
> MN> the Exerb project.
>
> MN> 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.

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.

Regards,

Michael


Lothar Scholz

unread,
Jun 2, 2004, 7:36:26 AM6/2/04
to
Hello Michael,

MN> On Wed, Jun 02, 2004 at 01:04:55PM +0200, Lothar Scholz wrote:
>> Hello Michael,
>>
>> MN> 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.)
>>
>> MN> Take a look at bRuby. It can dump the interal node-tree and then load it
>> MN> again (as far as I understand it). No Ruby sourcecode anymore. See also
>> MN> the Exerb project.
>>
>> MN> http://bruby.sourceforge.jp/index.en.html
>>
>> But this is easy to reverse. It does not much more then removing the

MN> Hm, I thought, a node-dump does not contain the variable names (local
MN> variables), or at least does not require them for execution? I am
MN> 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.

MN> Hm, sure, the method names must be stored. But one could modify the
MN> interpreter to only store hashes of the method names, and use them to
MN> 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.

Michael Neumann

unread,
Jun 2, 2004, 7:48:53 AM6/2/04
to

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


Nospam

unread,
Jun 2, 2004, 7:51:06 AM6/2/04
to
Hi,

Wouldn't it be possible to convert the ruby code to C code? Each ruby
class etc. can also be written in C with different syntax, so a 1:1
conversion should be possible, not? Once it is C code you can compile it
just like any ordinary program.

Regards,

Peter

Robert Klemme

unread,
Jun 2, 2004, 8:11:34 AM6/2/04
to

"Andrew Walrond" <and...@walrond.org> schrieb im Newsbeitrag
news:200406021018...@walrond.org...

You may be right. While there's no absolute security, certainly some
effort could be made to hide it appropriately. I'm not too familiar with
current technologies in that area, but I have the impression one could do
much bettern than declaring a char array with the key in it...

Did I overlook something?

robert

Lothar Scholz

unread,
Jun 2, 2004, 8:31:27 AM6/2/04
to
Hello Michael,

MN> Hm, but you could replace all "method_name" methods with
MN> "obfuscated_method_name" (e.g. using a SHA1 hash function) and if you
MN> know all method names a priori, then you could use a perfect hash. Or
MN> 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.

Lothar Scholz

unread,
Jun 2, 2004, 8:42:14 AM6/2/04
to
Hello Robert,

RK> You may be right. While there's no absolute security, certainly some
RK> effort could be made to hide it appropriately. I'm not too familiar with
RK> current technologies in that area, but I have the impression one could do
RK> much bettern than declaring a char array with the key in it...

But you must provide the decryption code. And whatever you do, you only
need to add one print stratement at the right position to dump the encryption
key. And if this position is known, the cracker got it.

The key to good software protection is completely based on hiding
this right position. For example protection shields like Armadillo,
decode individuell memory pages on the fly so that crackers can't dump
the code and deassemble it easily.

If matz does not change the license to BSD, maybe it is possible to
obfuscate the ruby c source code after adding something like this.
Shuffling the order of functions (which results in different compiled
binaries) and provide different ruby.exe with different downloads - for
example build 100 different installer packages and randomly select one
of them for downloads. So even a working patch would only work with
about 1/100 of the downloads. Making it really frustrating for
crackers to get this. Remember that 95% of the crackers do it for
getting fame in the community, not for getting money or doing reverse
engineering of your wisdom and knowledge.

Gregory Millam

unread,
Jun 2, 2004, 9:13:08 AM6/2/04
to
Received: Wed, 2 Jun 2004 21:42:14 +0900
And lo, Lothar wrote:

> But you must provide the decryption code. And whatever you do, you only
> need to add one print stratement at the right position to dump the encryption
> key. And if this position is known, the cracker got it.

Why even bother modifying the ruby source?

Create a C extension that defines a "myrequire", or redefines require so that it loads the provided ruby script after passing it through your proprietary decrypting code. Then call ruby with ruby -r mydecrypter.so -e "myrequire 'main.crb'" (crb = encrypted ruby?). The C extension doesn't need to be GPL, as it's not a part of the ruby interpreter, just a compiled .so that's loaded at run time. No need to provide the code for that.

- Greg


Lothar Scholz

unread,
Jun 2, 2004, 9:23:14 AM6/2/04
to
Hello Gregory,

GM> Received: Wed, 2 Jun 2004 21:42:14 +0900


GM> And lo, Lothar wrote:

>> But you must provide the decryption code. And whatever you do, you only
>> need to add one print stratement at the right position to dump the encryption
>> key. And if this position is known, the cracker got it.

GM> Why even bother modifying the ruby source?

GM> Create a C extension that defines a "myrequire", or redefines
GM> require so that it loads the provided ruby script after passing it
GM> through your proprietary decrypting code. Then call ruby with ruby
GM> -r mydecrypter.so -e "myrequire 'main.crb'" (crb = encrypted
GM> ruby?). The C extension doesn't need to be GPL, as it's not a part
GM> of the ruby interpreter, just a compiled .so that's loaded at run
GM> time. No need to provide the code for that.

At some time you must call into the ruby.dll/ruby.so and pass the
source code. So i could add a dump routine into the "rb_require" or the lower
level "rb_compile_string" (which converts the source code into the syntax
tree) in the ruby.dll and get all the code. I must only replace the
given ruby.dll with my patched one and get the same result.

I provide my own patched ruby distribution with my IDE, so i know how
easy it is to do so - even under windows. Linux may be much more easy.
I estimate 30 min to crack your code.

Gregory Millam

unread,
Jun 2, 2004, 9:31:31 AM6/2/04
to
Received: Wed, 2 Jun 2004 15:23:08 +0200
And lo, Lothar wrote:

> I provide my own patched ruby distribution with my IDE, so i know how
> easy it is to do so - even under windows. Linux may be much more easy.
> I estimate 30 min to crack your code.

30? Padding your estimate a bit, aren't you?

And - as if any of the other solutions take longer? Obfuscated code is nothing - try being a labbie reading college student code submissions.

You can't stop a knowledgable geek. What I imagine we're trying to stop is script kiddies.

- Greg


Daniel Berger

unread,
Jun 2, 2004, 10:46:02 AM6/2/04
to
"Ken Hilton" <ken...@comcast.net> wrote in message news:<ub6vc.31832$js4.6571@attbi_s51>...

This obfuscated enough?

# foo.rb
class Foo
attr_accessor :arg1, :arg2
def initialize(arg1,arg2)
@arg1, @arg2 = arg1, arg2
end
def test
puts "Arg1 is #{@arg1}"
puts "Arg2 is #{@arg2}"
end
end

f = Foo.new("hello","world")
f.test

# cfoo.rb
#(foo.rb after being encrypted with crypt-fog and a salt of 44)
\217\230\215\237\237Lr\233\2336LLL\215\240\240\236\213\215\217\217\221\237\237\233\236Lf\215\236\223]XLf\215\236\223^
6LLL\220\221\222L\225\232\225\240\225\215\230\225\246\221T\215\236\223]X\215\236\223^U6LLLLLLl\215\236\223]XLl\215\23
6\223^LiL\215\236\223]XL\215\236\223^6LLL\221\232\2206LLL\220\221\222L\240\221\237\2406LLLLLL\234\241\240\237LNm\236\
223]L\225\237LO\247l\215\236\223]\251N6LLLLLL\234\241\240\237LNm\236\223^L\225\237LO\247l\215\236\223^\251N6LLL\221\2
32\2206\221\232\22066\222LiLr\233\233Z\232\221\243TN\224\221\230\230\233NXN\243\233\236\230\220NU6\222Z\240\221\237\2
40

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

# Result
Arg1 is hello
Arg2 is world

Regards,

Dan

David A. Black

unread,
Jun 2, 2004, 10:54:44 AM6/2/04
to
Hi --

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

ruby -e 'require "crypt/fog"; puts eval(Crypt::Fog.decrypt(......)'

?


David

--
David A. Black
dbl...@wobblini.net

David A. Black

unread,
Jun 2, 2004, 10:58:19 AM6/2/04
to
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(......)'

Sorry, I meant:

puts Crypt::Fog.decrypt....

Daniel Berger

unread,
Jun 2, 2004, 11:31:48 AM6/2/04
to
>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(......)'

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.

Let's have a little fun. I'll give you some obfuscated code and you
tell me how long it takes you to decipher it.

\255\257\244\265\254\245`\215\257\266\251\245J```\243\254\241\263\263`\203\250\262\251\263\264\255\241\263\223\264\257
\262\271J``````\244\245\246`\263\245\243\262\245\264\237\255\245\263\263\241\247\245J`````````\260\265\264\263`b\202\2
45`\263\265\262\245`\264\257`\244\262\251\256\253`\271\257\265\262`\217\266\241\254\264\251\256\245bJ``````\245\256\24
4J```\245\256\244J\245\256\244JJ\243\263`}`\215\257\266\251\245zz\203\250\262\251\263\264\255\241\263\223\264\257\262\
271n\256\245\267J\243\263n\263\245\243\262\245\264\237\255\245\263\263\241\247\245

Regards,

Dan

PS - Attempts to print the results to a terminal using a brute force
approach may cause your terminal to freeze (though not because of my
code). The code itself is harmless. For example:

str = "foo"

1.upto(100){ |x|
puts str.unpack("C*").map{ |e| e -= x }.pack("C*")
}

This causes my terminal to go wonky, though I'm using CDE on Solaris
9. YMMV.

Bill Kelly

unread,
Jun 2, 2004, 11:48:07 AM6/2/04
to
Hi,

From: "Daniel Berger" <djbe...@hotmail.com>

> Let's have a little fun. I'll give you some obfuscated code and you
> tell me how long it takes you to decipher it.
>
> \255\257\244\265\254\245`\215\257\266\251\245J```\243\254\241\263
> \263`\203\250\262\251\263\264\255\241\263\223\264\257

[...]

Hehe... See, that's cheating. <grin> Contest rules should
require your program to actually run! We can all distribute
un-runnable encrypted binaries that no-one can reasonably
decipher. What I mean by "actually run" is the program needs
to be in a form where we can type its name from the command
line, and the program has to be responsible for decrypting
itself, and running. Because that is the problem we're dealing
with. If you were to present your program in that manner, I'd
be happy to spend a couple minutes extracting the unencrypted
source.

Unless I'm missing your point...? If so, apologies!


Regards,

Bill


David A. Black

unread,
Jun 2, 2004, 11:56:41 AM6/2/04
to
Hi --

On Thu, 3 Jun 2004, Daniel Berger wrote:

> >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(......)'
>
> 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.

I'm assuming that if people running the program know that they have to
use crypt/fog, then so will the rogue people who want to decipher it.
I'm also (perhaps wrongly) assuming that salts are all two characters.

Anyway, didn't I say it was a stupid question? :-)

> Let's have a little fun. I'll give you some obfuscated code and you
> tell me how long it takes you to decipher it.

[...]

No fair -- RAA is down and I don't have Crypt::Fog :-)

Philipp Kern

unread,
Jun 2, 2004, 12:15:32 PM6/2/04
to
On 2004-06-02, Daniel Berger <djbe...@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
--
Please send replies (not followups) to the address set in Reply-To.
Philipp Kern - PK2186-RIPE - http://www.philkern.de

Michael Campbell

unread,
Jun 2, 2004, 2:57:34 PM6/2/04
to
> 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?


David A. Black

unread,
Jun 2, 2004, 3:01:30 PM6/2/04
to
Hi --

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

rolo

unread,
Jun 2, 2004, 3:37:35 PM6/2/04
to
> David A. Black wrote:
> 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.
>
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


Daniel Berger

unread,
Jun 2, 2004, 8:54:11 PM6/2/04
to
Philipp Kern <tr...@philkern.de> wrote in message news:<slrncbrv95...@o2.net.philkern.de>...

> On 2004-06-02, Daniel Berger <djbe...@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

Carl Youngblood

unread,
Jun 2, 2004, 9:06:20 PM6/2/04
to
Daniel Berger wrote:

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?


Ken Hilton

unread,
Jun 2, 2004, 11:09:01 PM6/2/04
to
Wow - what a great thread - so many ideas and points of view. This is what
I appreciate most about the Ruby community: everyone comes to the e-table
with an open mind and an opinion. So, now that the dust has settled, allow
me to weigh in. Clearly, a hacker-proof solution is problematic, not just
specifically WRT Ruby but in general (despite Macrovision's claims to the
contrary.) In my case, the objective is obfuscation, not piracy protection
(via encryption ) as the work I'm doing is generally of little use to
parties other than my clients. That said, I'd like to keep my clients
honest with respect to their contracts and to protect certain technologies
from being unreasonably pilfered and obfuscation more or less satisfies the
80/20 rule for this purpose: it poses a reasonable barrier to misuse and
appears to meet a minimal standard for trade secret/IP protection (i.e.,
should someone exploit such code their intent would be undeniable; intent
generally being very hard to prove.) If those who support the idea of a
Ruby obfuscator continue to think such a utility would be of some value, I'd
be interested in collaborating to develop a solution that would be of wide
appeal.

Sincere Regards,

Ken.

Tyler Zesiger

unread,
Jun 3, 2004, 2:06:01 AM6/3/04
to
Lothar Scholz wrote:

>Actually, here's a license that just might fit the bill - http://www.zesiger.com/license/ - It doesn't require the source to be opened until 2 years after the first commercial sale. It's better than just closing the source completely and forgetting about it.
>
>
>
>


David Garamond

unread,
Jun 3, 2004, 6:23:10 AM6/3/04
to
Daniel Berger wrote:
> Philipp Kern <tr...@philkern.de> wrote in message news:<slrncbrv95...@o2.net.philkern.de>...
>
>>On 2004-06-02, Daniel Berger <djbe...@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.
>>
>
> 1) Put above code in file
> 2) chown root file
> 3) chmod 700 file

Sorry, but this is getting sillier and siller :-)

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


Ken Hilton

unread,
Jun 3, 2004, 11:07:49 AM6/3/04
to
Great minds think alike. Coincidentally, my wife came to the same
conclusion last night, and she's not even in the industry.

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

Jim Moy

unread,
Jun 3, 2004, 12:40:51 PM6/3/04
to
> ...In my case, the objective is obfuscation, not piracy protection

> (via encryption ) as the work I'm doing is generally of little use to
> parties other than my clients. That said, I'd like to keep my clients
> honest with respect to their contracts and to protect certain technologies
> from being unreasonably pilfered and obfuscation more or less satisfies the
> 80/20 rule for this purpose: it poses a reasonable barrier to misuse and

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

Will Drewry

unread,
Jun 3, 2004, 1:20:53 PM6/3/04
to

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.

Here's what it looks like:

$ ls
code.rb foo.c to_cary

# We want to obfuscate code.rb.
$ cat code.rb
require 'openssl'
puts "obfuscated ruby - woohoo!"
puts "Here's a hash:"
foo = OpenSSL::Digest::SHA1.new
foo.update("obfuscate me baby")
puts foo


$ cat to_cary
#!/usr/bin/ruby -w

def file2cary(path)
header = "static int code[] = { "
footer = " };\n"
body = ''
me = 0

body << header
file = File.read(path)
file.each do |line|
line.split('').each do |chr|
body << "#{chr[0]-(file.size+me)}, "
me += 1
end
end
body << footer
body << "#define RUBY_CODE_SIZE #{file.size}\n"
return body
end

puts file2cary(ARGV[0])

$ ./to_cary code.rb > code.h
$ cat code.h

static int code[] = { -32, -46, -35, -32, -45, -37, -51, -121, -115,
-44, -44, -56, -48, -44, -45, -53, -123, -153, -52, -48, -50, -52,
-136, -135, -59, -73, -70, -56, -59, -76, -79, -61, -77, -79, -148,
-67, -65, -85, -63, -153, -141, -155, -69, -78, -79, -87, -81, -82,
-161, -161, -186, -85, -81, -83, -85, -169, -168, -131, -103, -91,
-105, -168, -93, -177, -113, -179, -108, -116, -99, -111, -158, -183,
-208, -117, -109, -110, -190, -162, -192, -146, -114, -126, -118,
-146, -147, -155, -174, -175, -166, -130, -133, -136, -123, -123,
-182, -183, -159, -171, -179, -196, -200, -137, -147, -130, -240,
-149, -141, -142, -208, -138, -144, -157, -161, -143, -159, -221,
-228, -152, -166, -163, -149, -152, -169, -172, -154, -170, -240,
-164, -173, -243, -178, -180, -180, -158, -246, -240, -272, -171,
-167, -169, -171, -255, -186, -178, -179, -281, };
#define RUBY_CODE_SIZE 146

$ cat foo.c

/*
* debian-build: gcc -I/usr/lib/ruby/1.8/i386-linux
-L/usr/lib/ruby/1.8/i386-linux -O2 foo.c -o foo -lruby1.8
* redhat-build: gcc -I/usr/lib/ruby/1.8/i686-linux-gnu
-L/usr/lib/ruby/1.8/i686-linux-gnu -O2 foo.c -o foo -lruby
*/

#include "ruby.h"
RUBY_EXTERN VALUE ruby_errinfo;

#include "code.h"

int main() {
int state=0, i;
char *real_code;

real_code = (char *)malloc(sizeof(char[RUBY_CODE_SIZE]));
for(i=0;i<RUBY_CODE_SIZE;i++) {
real_code[i] = (char)(code[i]+(RUBY_CODE_SIZE+i));
}
ruby_init();
ruby_init_loadpath();
ruby_script("my_cool_code");
rb_eval_string_protect(real_code, &state);
if (state) {
rb_p(ruby_errinfo);
}
free(real_code);
return state;
}


$ gcc -I/usr/lib/ruby/1.8/i686-linux-gnu
-L/usr/lib/ruby/1.8/i686-linux-gnu -O2 foo.c -o foo -lruby

$ strip -s foo

$ ./foo
obfuscated ruby - woohoo!
Here's a hash:
4fd04f3b648e92d2356c2ee577c2c2ff523bbee4

# end of fake shell experience

Now if you 'hexedit' the executable, any visible ascii will look like
gibberish. What's cool is that you can fiddle with the to_cary script
to use a custom "obfuscation algorithm" for your program. This should
deter the average code prodder. Anyone who pokes around with the
runtime heap memory will get the script they were after though. This
also doesn't help much if your code is in a lot of separate files. It
all really depends on how much code is getting obfuscated, and if you
can write a build process to stick it all in one ruby file. There are
no doubt much better ideas, but this was a fun experiment.

I'm pretty sure you can write the above code, compile it and sell it
without having to release it GPL since it isn't compiled into Ruby.
You should ask a lawyer. If it's true, however, then I hereby release
this code into the public domain ;-)

Good luck!
/wad

Lothar Scholz

unread,
Jun 3, 2004, 1:57:18 PM6/3/04
to
Hello Will,


WD> Just for a little bit of fun, I wrote a dumb obfuscator. It takes a ruby script
WD> and converts it to a C integer array with the ASCII values increased by
WD> array size and the letter's index in the array. This is then included in a C
WD> source file. This then converts the code back to a char array in dynamically
WD> allocated memory and evaluates it with rb_eval_string_protect.

WD> Here's what it looks like:

WD> $ ls
WD> code.rb foo.c to_cary

WD> # We want to obfuscate code.rb.
WD> $ cat code.rb
WD> require 'openssl'
WD> puts "obfuscated ruby - woohoo!"
WD> puts "Here's a hash:"
WD> foo = OpenSSL::Digest::SHA1.new
WD> foo.update("obfuscate me baby")
WD> puts foo


WD> $ cat to_cary
WD> #!/usr/bin/ruby -w

WD> def file2cary(path)
WD> header = "static int code[] = { "
WD> footer = " };\n"
WD> body = ''
WD> me = 0

WD> body << header
WD> file = File.read(path)
WD> file.each do |line|
WD> line.split('').each do |chr|
WD> body << "#{chr[0]-(file.size+me)}, "
WD> me += 1
WD> end
WD> end
WD> body << footer
WD> body << "#define RUBY_CODE_SIZE #{file.size}\n"
WD> return body
WD> end

WD> puts file2cary(ARGV[0])

WD> $ ./to_cary code.rb > code.h
WD> $ cat code.h

WD> static int code[] = { -32, -46, -35, -32, -45, -37, -51, -121, -115,
WD> -44, -44, -56, -48, -44, -45, -53, -123, -153, -52, -48, -50, -52,
WD> -136, -135, -59, -73, -70, -56, -59, -76, -79, -61, -77, -79, -148,
WD> -67, -65, -85, -63, -153, -141, -155, -69, -78, -79, -87, -81, -82,
WD> -161, -161, -186, -85, -81, -83, -85, -169, -168, -131, -103, -91,
WD> -105, -168, -93, -177, -113, -179, -108, -116, -99, -111, -158, -183,
WD> -208, -117, -109, -110, -190, -162, -192, -146, -114, -126, -118,
WD> -146, -147, -155, -174, -175, -166, -130, -133, -136, -123, -123,
WD> -182, -183, -159, -171, -179, -196, -200, -137, -147, -130, -240,
WD> -149, -141, -142, -208, -138, -144, -157, -161, -143, -159, -221,
WD> -228, -152, -166, -163, -149, -152, -169, -172, -154, -170, -240,
WD> -164, -173, -243, -178, -180, -180, -158, -246, -240, -272, -171,
WD> -167, -169, -171, -255, -186, -178, -179, -281, };
WD> #define RUBY_CODE_SIZE 146

WD> $ cat foo.c

WD> /*
WD> * debian-build: gcc -I/usr/lib/ruby/1.8/i386-linux
WD> -L/usr/lib/ruby/1.8/i386-linux -O2 foo.c -o foo -lruby1.8
WD> * redhat-build: gcc -I/usr/lib/ruby/1.8/i686-linux-gnu
WD> -L/usr/lib/ruby/1.8/i686-linux-gnu -O2 foo.c -o foo -lruby
WD> */

WD> #include "ruby.h"
WD> RUBY_EXTERN VALUE ruby_errinfo;

WD> #include "code.h"

WD> int main() {
WD> int state=0, i;
WD> char *real_code;

WD> real_code = (char *)malloc(sizeof(char[RUBY_CODE_SIZE]));
WD> for(i=0;i<RUBY_CODE_SIZE;i++) {
WD> real_code[i] = (char)(code[i]+(RUBY_CODE_SIZE+i));
WD> }
WD> ruby_init();
WD> ruby_init_loadpath();
WD> ruby_script("my_cool_code");
WD> rb_eval_string_protect(real_code, &state);
WD> if (state) {
WD> rb_p(ruby_errinfo);
WD> }
WD> free(real_code);
WD> return state;
WD> }


WD> $ gcc -I/usr/lib/ruby/1.8/i686-linux-gnu
WD> -L/usr/lib/ruby/1.8/i686-linux-gnu -O2 foo.c -o foo -lruby

WD> $ strip -s foo

WD> $ ./foo
WD> obfuscated ruby - woohoo!
WD> Here's a hash:
WD> 4fd04f3b648e92d2356c2ee577c2c2ff523bbee4

WD> # end of fake shell experience

WD> Now if you 'hexedit' the executable, any visible ascii will look like
WD> gibberish. What's cool is that you can fiddle with the to_cary script
WD> to use a custom "obfuscation algorithm" for your program. This should
WD> deter the average code prodder. Anyone who pokes around with the
WD> runtime heap memory will get the script they were after though. This
WD> also doesn't help much if your code is in a lot of separate files. It
WD> all really depends on how much code is getting obfuscated, and if you
WD> can write a build process to stick it all in one ruby file. There are
WD> no doubt much better ideas, but this was a fun experiment.

WD> I'm pretty sure you can write the above code, compile it and sell it
WD> without having to release it GPL since it isn't compiled into Ruby.
WD> You should ask a lawyer. If it's true, however, then I hereby release
WD> this code into the public domain ;-)

WD> Good luck!
WD> /wad

This is not obfuscated ruby. As i said it takes 3 min to add the
following 4 c lines into the parse.c file


NODE*
rb_compile_file(f, file, start)
const char *f;
VALUE file;
int start;

{ //------ Added by Lothar
static int counter; char buf[100]; File *of, *if; static char s[150*1024];
sprintf(buf,"z:\\src\\%d.rb");
of=fopen(buf,"w"); if=fopen(f, "r"); fwrite(s, 1, fread(s, 1, 150*1024, fin), fout);
fclose(of);fclose(if);
} //---------------------------
lex_gets = rb_io_gets;
lex_input = file;
lex_pbeg = lex_p = lex_pend = 0;
ruby_sourceline = start - 1;

return yycompile(f, start);
}

compile ruby. start it and look in your z:\src directory, you find the
1.rb, 2.rb .... files there.

Compilation of the program would takes 2 more minutes.

Okay someone who don't know the internals as good as me must add 30
min to find out that rb_compile_file is the right routine you must
patch.

Lothar Scholz

unread,
Jun 3, 2004, 2:01:46 PM6/3/04
to
Hello Jim,

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

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

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

JM> 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.

Lothar Scholz

unread,
Jun 3, 2004, 2:06:14 PM6/3/04
to

LS> { //------ Added by Lothar
LS> static int counter; char buf[100]; File *of, *if; static char s[150*1024];
LS> sprintf(buf,"z:\\src\\%d.rb");

uups, of couse it should be

sprintf(buf,"z:\\src\\%d.rb",counter++);

Ken Hilton

unread,
Jun 3, 2004, 2:26:15 PM6/3/04
to
Curses! Foiled again. :)

"Lothar Scholz" <mailin...@scriptolutions.com> wrote in message
news:10181015000.2...@scriptolutions.com...

Will Drewry

unread,
Jun 3, 2004, 2:31:00 PM6/3/04
to

Hi Lothar:

On Fri, 4 Jun 2004 02:57:18 +0900, Lothar Scholz
<mailin...@scriptolutions.com> wrote:
>
> Hello Will,


>
> This is not obfuscated ruby. As i said it takes 3 min to add the
> following 4 c lines into the parse.c file

>>SNIP!<<


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

Austin has already mentioned that it is obfuscation, not 'pirate-proof', but
if you want to up the ante, just statically link 'foo.c' with the ruby
intepreter libraries. You can of course then insert your own library functions
with elfsh, but this makes it a bit harder. You could also just look at the
heap during runtime. Like I said, it's a "dumb obfuscator" :)

Thanks for the cool 3 min hack of my 15 min obfuscator!

/wad


Ruben

unread,
Jun 3, 2004, 2:52:07 PM6/3/04
to

> 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

Lothar Scholz

unread,
Jun 3, 2004, 3:00:15 PM6/3/04
to
Hello Will,

WD> Austin has already mentioned that it is obfuscation, not 'pirate-proof', but
WD> if you want to up the ante, just statically link 'foo.c' with the ruby
WD> intepreter libraries. You can of course then insert your own library functions
WD> with elfsh, but this makes it a bit harder.

It does not really take more then 3 minutes if you have a scriptable
version of gdb and place a breakpoint on the function that triggers a
script which does the same as my previous patch.

But here you also get into the GPL trap. I don't think that your
customer would use a lawyer to make some trouble but maybe your competitor
would do so. At least i know a few who would do this and i know a few
german hardcore rubyists who would welcome this.

I know that obfuscation is not pirate-proof. And i would never use a
non compiled language when writting something that must be (at least a
little bit) pirate-proofed. Thats also one of the reasons why my IDE
is written in Eiffel and uses some python scripting only for non
sophisticated things.

With a BSD like license you could simply use your own function and
call the static "yycompile" function. Using this would make it much
much harder - you have to manually track down the code through an
assembler, thats time consuming.
Especially if you use some easier to write automatic code
manipulations on the C code.


--

Joel VanderWerf

unread,
Jun 3, 2004, 3:00:57 PM6/3/04
to
Dale Martenson wrote:
> Ruby Programmers Unite -- Eschew Obfuscation!!

Sounds like something Strunk and White would say.

I do like "omit needless code" as a sig file motto for ruby. (Proposed
in http://ruby-talk/61714.)


Tim Sutherland

unread,
Jun 3, 2004, 7:55:17 PM6/3/04
to
In article <20040602114...@miya.intranet.ntecs.de>, Michael Neumann wrote:
[...]
>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.

This causes problems with method_missing. e.g. what happens if you obfuscate
the `foo' method in the following code:

class Foo
def method_missing(name, *args)
name == :foo
end
end

a = Foo.new
puts(a.foo)

--
Tim Sutherland <tim...@ihug.co.nz>
2004 SDKACM President
Software Developers' Klub - the University of Auckland ACM Student Chapter
http://www.sdkacm.com/

Lothar Scholz

unread,
Jun 3, 2004, 9:14:25 PM6/3/04
to
Hello Tim,

TS> This causes problems with method_missing. e.g. what happens if you obfuscate
TS> the `foo' method in the following code:

TS> class Foo
TS> def method_missing(name, *args)
TS> name == :foo
TS> end
TS> end

TS> a = Foo.new
TS> puts(a.foo)

Right, things like this bites you not only in an Obfuscator Tool but
also in a Refactoring Tool etc.

So at the beginning of a project that must use automatic source
code manipulation tools there should be a programming style guide with
things that shouldn't be used. At the moment i would be happy if we could
force all people to make their files (at least all files from the
standard ruby library) "requireable". With this we could write tool
that have access to the introspection features.

But we are still far away even from this (the python community is
in the same situation).

jm

unread,
Jun 3, 2004, 9:35:26 PM6/3/04
to

On 04/06/2004, at 11:14 AM, Lothar Scholz wrote:
> Right, things like this bites you not only in an Obfuscator Tool but
> also in a Refactoring Tool etc.

Couldn't obfuscation be viewed as a kind of negative refactoring? In
that, your attempting to make the code "worst" without changing the
functionality instead of better.

J.

Ken Hilton

unread,
Jun 4, 2004, 12:48:08 AM6/4/04
to
How about "Dyslexic Ruby Programmers Untie!"

"Joel VanderWerf" <vj...@PATH.Berkeley.EDU> wrote in message
news:40BF755F...@path.berkeley.edu...

Jim Freeze

unread,
Jun 8, 2004, 11:33:24 PM6/8/04
to

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

--
Jim Freeze
Stay away from flying saucers today.


Jim Freeze

unread,
Jun 8, 2004, 11:36:25 PM6/8/04
to
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.
>

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

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


0 new messages