[prog] 'protecting' perl code

Jacinta Richardson jarich at perltraining.com.au
Fri May 7 12:33:31 EST 2004


G'day Almut,

I'm going to vehemently disagree with some of your suggestions here.  It's
not personal.  :)  This is a response to both you and Riccarda.

> The key concept is "source filters". Perl provides low-level mechanisms
> to intervene with how the parser handles the stream of source code that
> makes up the script. Type 'perldoc perlfilter' to get a concise but
> good description of what this is all about.

Think twice before writing your own source filter.  I've seen enough
cases where things break due to source filters making mistakes.  And the
breakage can be really subtle and next to impossible to find sometimes.
Even Damian Conway's switch used to get caught up on some strange cases.

> It's important to understand, though, that this is always "security
> through obscurity". Even employing strong cryptography will not really
> help, as there will always be some point when the parser needs to see
> tiny portions of the cleartext perl code, to be able to execute it. 
> Also, you have to distribute the decrypting code itself (as part of
> the perl binary, typically). Otherwise, it wouldn't be possible to
> execute the script... (this holds independently of whether you decide
> to have the user enter some password to run the program).
> See further below on the minimum precautions needed to make life
> difficult for some potential cracker.

I agree.

> From the point of view of cryptography, the whole obfuscation approach
> is _always_ lame, but for many practical purposes, the time required to
> crack some program would typically be beyond what it's worth -- if done
> well enough.
> (Make sure, however, that your client knows about these facts...
> preferably in written form.)

I agree entirely.

> Here's a rough sketch of what needs to be done (more details upon
> request):
> 
> * write the source filter as an extension module in C.  Although you
> can, in principle, write source filters in perl (see Filter::Simple,
> for example), this would be too easy to reverse engineer.

My goodness that sounds painful...

> * link the module _statically_ with the perl interpreter (building it
> as a shared object (as usual) would make it rather easy to debug/crack).

Fair enough.

> * strip all symbol information from the resulting perl binary, to make
> debugging even more difficult.

.... there is a reason for that symbol information .... make sure your
code works before you do this step.  Debugging after this point will be
like having your fingernails pulled out

> * add a good amount of 'dummy' code with the only purpose to confuse,
> i.e. code that does seemingly useful operations, while the real
> required functionality happens as hidden side effects in the background.

Okay at this point I thoroughly disagree.  Unless the code you're
obscuring is 100% perfect and will never ever change (and even the hello
world program isn't that) this is the fastest way possible to make your code
unusable.

Perl programs are typically bad enough in the area of maintainability.
Adding dummy code and doing your useful stuff as hidden side effects...
yuck!  Sure noone will steal your code, they won't want it.

And when the author of all the dummy code leaves the business, gets hit
by a bus or otherwise the code will fall into some other poor sod's lap
and they're probably going to suggest rewriting it from scratch and
bundling with something like PAR.

I can't say strongly enough how fundamentally flawed this idea is.  From
a Software Engineering point of view I can't even really contemplate it.


* Almut forgot the good ole "make all the variable names look like
  rubbish and remove all possible whitespace".

This won't buy you a lot.  The perltidy program will cope with the
whitespace and substitution can slowly fix the rest.

> The general idea is that anyone running the perl interpreter in a
> debugger (like gdb) would have a hard time figuring out what's _really_
> going on...

And likewise for the poor person who has to maintain it.

> > Is this doable at all within a reasonable project time span, or should
> > I rather tell my client to use some commercial solution right away?
> 
> Depends. As a general rule, I'd say: if someone is willing to pay you
> (or your company) for it, why not just do it... :)
> (yes, sure, do some serious consulting first -- however, they may have
> their specific reasons for wanting a non-standard solution...  well,
> you get the idea).

As a professional who abides by the SAGE-AU ethics I disagree here too.
If an acceptable solution already exists (although I don't know whether
PAR or ActiveState's options are acceeptable) then it's wrong to make a
client pay for you to reengineer the wheel.  Especially if you don't
have a background in writing Perl parsers, compression software and
source encryption.

Assuming you are damn fine in Perl then in a month or two you could
probably come up with an acceptable solution which implemented many of
the things mentioned here.  It would probably break on all sorts of
input that you've never considered, but since you haven't considered it
you might not notice.

You could probably then offer to sell it in competition with some of the
other people who've written similar things.  :)  Depending on your
agreement with your client.

All the best,

	Jacinta

--
   ("`-''-/").___..--''"`-._          |  Jacinta Richardson         |
    `6_ 6  )   `-.  (     ).`-.__.`)  |  Perl Training Australia    |
    (_Y_.)'  ._   )  `._ `. ``-..-'   |      +61 3 9354 6001        |  
  _..`--'_..-_/  /--'_.' ,'           | contact at perltraining.com.au |
(il),-''  (li),'  ((!.-'              |   www.perltraining.com.au   |




More information about the Programming mailing list