Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Writing highly obfuscated code in Perl

by marko (Beadle)
on Jun 29, 2000 at 05:49 UTC ( [id://20312]=perltutorial: print w/replies, xml ) Need Help??

How do I write messy (and sometimes entertaining code code?

The first thing you will probably notice is that this tutorial is a bit Obfuscated. I thought I would match the theme :) Often one may ask how to write highly obfuscated code in Perl. Its easy to write code. But can you write unreadable code? This is a simple tutorial guide, if you want to become a pro, practice your art.


1) Take advantage of Perl's end of line character ";". Use it to dirty up your code. For example, if you want to go for a certain shape you can use ";"'s to spruce it up:
my $cash_in; my $cash_ot ; my $cash_iz ; my $cash_zi ; my $cash_zo ; my $cash_is ; my $cash_if;
Languages that use ';' as a "end line" character are generally better for obfuscated because you can mush your code like so:
my $var="null\n";chomp($var);if ($var="null"){print "Good";}
You can also make an off beat pattern for your ';''s to add a bit of confusion, like so:
my $var="null\n" ;chomp($var) ;if ($var="null") {print "Good" ;}

2) Always break up your equal signs. Ie:

Try to do:

$myvar = "fdfdjsk";
instead of:
$myvar = "fdfdjsk";

3) Don't forget that, if you need better "shaping", always break up your strings with a new line character "\n";
4) Regular expressions make for messy code, and that is what we are going for. Use them in excess whenever possible.
5) Add comments. Sometimes adding odd comments here and there can help enhance the shaping of your code. An example of this is found in my work : "modern (perl) art" in the Obfuscated Code section of www.perlmonks.org. However,never comment in a way that would clarify your code.
6) Try to name your variables in a simplistic, yet inconherent way. "woodzy" has done a great job of this with his work called "Email sig. Old news. :/" on www.perlmonks.org. For example:
  instead of $payroll, try $p
  instead of $atom, try $a

7) Keep working. Practice enough and you WILL get good results. Someday you will even do lettering. You don't beleive that thats possible? Check out "Yet Another Perl Conference" by Erudil and you will see what I mean.
8) Keep your code as mathematical as possible. Never leave a simple expression alone, ie (4+4), but rather turn it into (((1*3)+1) + ((100*((1*2)+2)) /(10*10))). Doing this will make your code unreadable real soon.
9) Packing and unpacking will cause your code to be just a bit more unreadble. You will find many examples of this in www.perlmonks.org Obfuscated Code board.
10) Be sure to view some of the code found in Obfuscated Code section of www.perlmonks.org, its real helpfull on giving you some ideas on where to get started at making your code more un-readable. Please note that this is by no means a complete tutorial. I really hope that some other "perl obfuscator" will jump in and write a tutorial much better than this.
Thank you and have a good obfuscated night.

Edit 2001-04-03 by tye

Replies are listed 'Best First'.
Re: Writing highly obfuscated code in Perl
by cLive ;-) (Prior) on Mar 14, 2001 at 20:19 UTC
    This is the shell of what I use. I actually build %replace_key manually. This version only works if you ensure that all subs and vars are unlikely to appear as words (or part of word) you print. Eg, don't use a var called $time if your script outputs something like:
    print "The time is $time\n";
    OK, here's the meat (unobfuscated, and well commented :)...
    #!/usr/bin/perl use strict; print "Enter path to script: "; my $script_path = (<STDIN>); # read in script open (SCRIPT, $script_path) || die("Can't find script $script_path - $ +!"); my $script_text = join '', (&lt;SCRIPT&gt;); close(SCRIPT); my %replace_key; # read in vars of at least 2 chars - well, I always use $i anyway :) while ($script_text =~ /\$(\w\w+)/gs) { $replace_key{$1} = 1; } # read in subs while ($script_text =~ /sub (\w+)/gs) { $replace_key{$1} = 1; } my $i=1; for (keys %replace_key) { my $replace = unpack ("B32", pack("N", $i)); # get binary of $i $replace =~ s/^0+(?=\d)//; # remove trailing zer +oes $replace =~ s/0/I/g; # change 0 -> I $replace =~ s/1/l/g; # change 1 -> l (lowe +rcase L) $i++; $script_text =~ s/$_/$replace/gs; # obfuscate } # remove extraneous CRs $script_text =~ s/;\s*\n\s*/;\n/gis; # now screw up tab spacing $script_text =~ s/\t+/"\t" x (int(rand 6))/ges; # take a look at your handywork print $script_text; exit(0);
    Depending on the consistancy of your coding style, you can add other obfuscations. EG, I always mark comments as:
    # ## comment
    so I can rip them all out with
    s/# ##[^\n]+\n\s*/\n/g;
    I also use the following:
    s/\{/n/ /g; s/\}\s+elsif/} elsif/g; s/;\s+my/; my/g;
    That leaves your code totally readable, but when you run it through the obfuscater and let it loose... ;-)

    Any othet s/obfuscation/pattern/ suggestions welcomed :)

    later

    cLive ;-)

Re: Writing highly obfuscated code in Perl
by dmckee (Scribe) on Feb 24, 2001 at 18:49 UTC
    There's no mention of eval, which is probably the most overused construct in Japh creation. You suggest using $p instead of $payroll and $a instead of $atom. Why not use $a instead of $payroll and $p instead of $atom? Declare variables like $print which contains the text 'substr(' and $substr which contains the text 'print', which are used in a eval statment which uses their contents as part of the data. Make use of \t instead of spaces and \x33 instead of bangs. Declare seemingly important variables which contain the word 'Just' or 'Perl' and then never use them again.

    Use your imagination.

Re: Writing highly obfuscated code in Perl
by Wookie (Beadle) on Jul 14, 2001 at 03:11 UTC
    While I admit to being very new to Perl - I find default/pre-defined variables to be a source of constant inspiration. Using $_ $@ $| etc. can really confuse things. Oh yeah - and overuse $_ - superfluously if possible - as an example from my first attempt I submitted today:
    $_=_($_);$_+=$_;
    (_ is a sub that returns the input++) and now you can use any of the following - all to get 4:
    $_+=$_; $_=$_*$_; $_=$_**$_;
    game(Wookie,opponent) eq 'Wookie' ? undef $problem : remove_limbs(arms,opponent);
      Use strange delimiters for patternmatches and ee (or at least e)for substitutions, e.g. s?one?$another?gee

      Use ~~ instead of scalar

      (Thanks to Damian Conway for his talk "Extreme Perl" at the Perl-Workshop; the ideas abouve are from him). Use y instead of tr

      and so on and so on...

      perl -le "~~s--*l-e=>y²*(min²*(cme(²=>s)[^\w]))g=>print"

      Best regards,
      perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

Re: Writing highly obfuscated code in Perl
by jonadab (Parson) on Apr 19, 2005 at 11:41 UTC

    Some additional tips...

    • First, think of something interesting to do. Second, think of an unobvious way to accomplish it. Then start writing the code. With an obfuscated algorithm from the get-go, and code that does something interesting, your obfu will be sure to please.
    • Avoid using
      if (condition) { foo; } else { bar; }
      when you can instead use the trinary operator: (condition)?foo:bar;. This is especially important when you have nested conditionals.
    • Try to model parts of your code around paradigms that a lot of people aren't familiar or comfortable with, such as functional or logical programming. Combine these with often-poorly-understood data structures if possible. For instance, having map generate a hashref of closures each iteration is sure to confuse at least some of the people reading your code.
    • Include POD that is simultaneously cryptic and actively misleading.
    • Play strange games with context and precedence.
    • Abuse symbolic references.
    • Include at least one red herring, but make sure that it is just as obfuscated and hard to follow as the rest of the code, so that it will not be immediately written off as a red herring.
    • While writing your code, go ahead and use obfuscatory techniques, but keep some line breaks and comments in so you can keep track of what you're doing; once you get it working just the way you want and nicely obfuscated, then remove the comments, golf it down a little, and alter the whitespace to reform the code into the shape you want; test after every couple of changes to make sure it still does what you want.
    • Don't break up into subroutines at the natural places; leave things inline that in real code would be better broken out as subroutines, and instead break things out as subroutines that would be better off inline in real code. Make sure your subroutines do things with the caller's variables, if possible.
    • Try to use hashes and arrays with the same single-character names as the scalars you are using, especially any punctuation-named special variables you are abusing.
    • When using regular expressions, don't use regular /slashes/ as delimiters; find more interesting characters for that, preferably ones that are also used for other things both within the regexen (where they will have to be escaped) and near them in the code.
    • Abuse the /e modifier with regex substitutions.
    • Nested string eval can be fun; combine it with $_ and substitutions to create self-modifying code.
    • Use things for multiple unrelated purposes. For instance, if you have an array or hash that you happen to know contains some elements, you can grab it in scalar context any time you need a true value. Similarly, any variable that you know contains a non-numeric string can be used as zero in numeric context. Apply this principle as often as possible, in as many different ways as possible.
    • Converting foreach and even while loops into map will often shave off several characters, with the added benefit of allowing you to assign the result to an array (or hash!) which you can subsequently use as a red herring, a true value in boolean context, or even as a number.
    • Golf, but don't overgolf. Frequently the absolute shortest way to say something is not the most confusing.

    • "In adjectives, with the addition of inflectional endings, a changeable long vowel (Qamets or Tsere) in an open, propretonic syllable will reduce to Vocal Shewa. This type of change occurs when the open, pretonic syllable of the masculine singular adjective becomes propretonic with the addition of inflectional endings."  — Pratico & Van Pelt, BBHG, p68
Re: Writing highly obfuscated code in Perl
by Anonymous Monk on May 25, 2001 at 05:23 UTC
    BTW perl is a language that uses the semi colon character as a statement separator rather than as a statement terminator or "end line".
Re: Writing highly obfuscated code in Perl
by sleek (Sexton) on Sep 24, 2002 at 12:57 UTC
    Missed indentation. Indentation is usually used to make code highly readable. The same indentation can be used to make the code obfuscated. All depends on imagination.
RE: Writing highly obfuscated code in Perl
by i43s (Novice) on Jun 29, 2000 at 21:11 UTC
    This tutorial isn't comprehensive, obfuscation is in the eyes of the beholder, to many, this may be obfuscates:
    print join ' ', qw'Just another Perl Hacker';
    
    Abigail did a fine job at YAPC.
(OT) Re: Writing highly obfuscated code in Perl
by oylee (Pilgrim) on Jul 31, 2002 at 21:26 UTC
Re: Writing highly obfuscated code in Perl
by wirm (Initiate) on Apr 24, 2001 at 01:17 UTC
    I did this all from the start.. im a natural =]

    root: n. 1. Person who lurks around your box without you knowing.
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perltutorial [id://20312]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2024-12-09 07:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which IDE have you been most impressed by?













    Results (53 votes). Check out past polls.