Perl Obfuscator - Introduction and key concepts
Table of contents
- Key facts
- Key concept: exceptions - names of symbols that should not be modified
- Steps for obfuscating the project with Perl-Obfus
Key facts about Perl-Obfus
- It never overwrites input files.
- It has both GUI and command line interfaces. GUI uses command line interface under the hood, but GUI
adds some handy tools, so GUI interface is more powerfull and feature-rich and is more recommended to use.
It's really greatly recommended to use GUI interface to set up the project. Later you can export scripts (or .bat files for Windows) that allow you to build/rebuild/clean your project from command line - they are called buildscripts.
And if you insist on never using GUI interface (it's very bad idea!) you can still generate command line using GUI on your computer (go to on our site.
) or online command line builder available - Trial version can perform only one kind of transformation for symbol names - by prepending string
ReplacementFor_
to them. This does not limit your ability to evaluate Perl-Obfus in any way! The trial version does allow you to fully evaluate Perl-Obfus and prepare your project for obfuscation using only trial edition.Just imagine that instead of
ReplacmentFor_someFunction
you'll getz78a4b2e
. Those symbols that got prefix with trial version will become something unreadable when protected by non-trial. It's easier to prepare project for obfuscation using this kind of replacement (when some prefix is prepended), so it's called a debug mode. Using debug mode is recommended when using non-trial version of the product too! - as it allows to understand what's going on much easier (you'll get errors looking like "unknown symbol ReplacementFor_someFunction" instead of "unknown symbol z72a63be9f" - the former is much more readable when debugging!).Once you created a project, prepared it for protection using trial, you can purchase non-trial, just open that project in non-trial edition, click
and you'll get your project fully protected. So you won't loose any time spent evaluating trial edition. - Default settings and values of parameters are safe and reasonable.
- Obfuscation of the project is not as quick as zipping the folder with source code - you have to confiure your project (by listing names that should not be modified, called exceptions) and even modify your code a little in case you use eval() in your code . So be ready to spend from hours to days before you get protected version of your code that works correctly after obfuscation.
Key concept: exceptions - names of symbols that should not be modified
The purpose of Perl-Obfus is to replace symbols with meaningless names.
Apparently, not all symbols can be changed without introducing errors.
For example, names
of subs that you use from modules shipped with Perl, like getcwd
from POSIX.pm
,
can not be changed. Names of such symbols
should be added to the list of exceptions - so obfuscator does not change them
adding symbols to exceptions
.
Symbols defined in 3rd-party modules
If your code calls some functions from 3rd-party modules that you are not allowed to modify or are shipped with Perl , you have to list all symbols that you use from those modules as exceptions adding symbols to exceptions .
Perl-Obfus ships with a lot of tools that help generating exceptions for 3rd-party modules extacting list of symbols .
Exporting symbols to 3rd parties
If your code is in fact a module that you sell or distribute, then you have to list as exceptions all symbols defining its API adding symbols to exceptions . Use tools shipped with Perl-Obfus to generate exceptions for API of your module extacting list of symbols
Dealing with names of symbols in strings
Find all places in your code that uses symbol names to make a reference. Add the following lines to the begining of those files (or make sure that the definitions of these functions are visible to your code from some base module):
#the definition for SN and SNS BEGIN{eval('sub SNS{@_;}sub SN{$_[0];}');} #SN takes just 1 symbol as argument. #SNS takes a LIST of symbol names as arguments.Most typical is update necessary to
use vars
statement, where you will have to wrap
the list of symbol names into call of SNS
:
#before use vars qw($foo @bar %blah); #after use vars SNS(qw($foo @bar %blah));Sometimes you may have to put that
use vars
block inside BEGIN{}
block if use vars
block is at the topmost level in your file.
Sometimes, your code refers to names of functions or variables inside the strings, e.g. in strings passed to
eval()
function.
What to do in such case:
- If the name of the symbol inside the string is computed at runtime
- (e.g. entered by the user ), then the only
option you have is to list all possible names of symbols that can be used this way in your code
in the list of exceptions
adding symbols to exceptions
.
Sample:
sub f1 {} sub f2 {} my $subnm = CGI::param('what'); #assuming it can be 'f1' or 'f2', #you have to put both f1 and f2 to list of exceptions &$f1();
- If the name of the symbol is a constant string
- you have these options:
- put that symbol to the list of exceptions to prevent it from being modified adding symbols to exceptions .
- List that symbol as "quoted symbol name". In this case Perl-Obfus will replace every string
whose value is equal to the symbol name, with a string equal to mangled symbol name.
Strings that include some other characters around symbol name won't be changed.
Register "quoted symbol name" in
--quoted-symbol-names
command line option if using command line interface. if using GUI, or put them, one symbol per line,
to a text file and pass its name after - wrap that name in the call to
SN
function#before my $method = "process"; $obj->$method(); #after my $method = SN("process"); $obj->$method(); #before my $varname = "myvar"; eval("\$$varname = 23; \$blah = 15;"); #after my $varname = SN("myvar"); eval("\$$varname = 23; \$" . SN('blah') . "=15;");
For this to work, add the following lines to the begining of your files (or make sure that these definitions are visible to each of your files):BEGIN{eval('sub SNS{@_;}sub SN{$_[0];}');}
SN()
.
Update the export tables for your modules and 'use vars' statements
Modify all modules that have @EXPORT variable defined and that use Exporter.pm, to use SN and SNS subroutines (read previous step for more information). E.g. code before:
BEGIN { use Exporter (); use vars qw($VERSION @ISA @EXPORT %h1 @list1 $var2); $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw(%h1 @list1 $var2); };The code should look like the following after your modifications:
sub SN { '';$_[0]; } #return 1st argument sub SNS { '';@_; } #return all arguments BEGIN { use Exporter (); use vars (SNS(qw($VERSION @ISA @EXPORT %h1 @list1 $var2))); $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = SNS(qw(%h1 @list1 $var2)); };Note that list of names of variables in 'use vars' was wrapped in call of SNS; the initializer of @EXPORT was also wrapped in call of SNS();
Steps for obfuscating the project with Perl-Obfus
Step 1: add SN
to your code
Alter all places where your code refers to names of symbols inside string constants, by wrapping
names of symbols into a call of SN
or SNS
function,
as explained above.
Then test that after these changes your unobfuscated code works same as your original code.
Step 2: collect set of exceptions for your code
A lot of tools for this are shipped with Perl-Obfus extacting list of symbols
Step 3: process your code using lite protection and test it
With lite protection, names of symbols that are to be made unreadable, will just get ReplacementFor_
prefix.
This will result in error messages looking like "Undefined function ReplacementFor_SomeFunctionName"
when you'll run your code - it will clearly indicate that
symbol SomeFunctionName
should be added to the list of exceptions
(see more on what exceptions are here).
Proceed to next step only if your protected code works fine.
Step 4: process your code using non-lite protection and test it
After switching protection mode to non-lite, your code should work exactly as when protected by lite protection.
Note that trial version of Perl-Obfus can perform only one kind of transformation for symbol names -
by prepending prefix ReplacementFor_
to them. This does not limit your ability to evaluate Perl-Obfus in any way
as mangling integers and strings in non-lite mode is the same for both trial and non-trial, so once you tested your code
protected with trial in non-lite mode, you will need only minimal testing of code once upgrading trial into non-trial of
Perl-Obfus.