mental note: perl -MParse::RecDescent - <grammar_file> <module_name>
It's odd, and a little unsettling, to reflect upon the fact that
English is the only major language in which "I" is capitalized; in many
other languages "You" is capitalized and the "i" is lower case.
-- Sydney J. Harris
Please note: the following tutorial on obfuscation is now quite dated. I do not have the current incentive to update it. Peruse at your own risk.
Recently i have been haunting the Obfuscated Code area of this place and having fun de-obfu-ing the less than readable code and learning from others attempts. In this quest for enlightenment i have found the following facts that may help others on their quest for obfuscation. The following is a list of contrary axioms; the opposite seems to be correct at first glance. Following the axioms will be an example and counter-example as well as a brief description and possible pitfalls.
1) Whitespace does not an obfu make
While whitespace is an amusing part of obfuscation, if all your code has going for it is a cool looking pattern, don't submit it. It's not obfuscation. Adding whitespace to an obfuscation and making it look interesting is an afterthought of obfuscation (well, usually :) It is very appropriate to make your obfu eye-pleasing, but it better be an obfu before you've done that.
2) pack/unpack is not obfuscation
The reason i list the counter-example is because it is not unpacking anything like what you think at first glance. While the obfu itself does need some work, that is an acceptable use of unpack. On the other hand, looking at the example we see a fairly common use of unpack: get the string and unpack it, oh look the string is japh. While a packed string is line noise, it's easy to see past it and note what the code is doing if it's a simple obfu.
3) chr/ord is not an obfuscation
Even i've been guilty of this one, but hopefully not disdainfully so. We've all used chr/ord at some time or another, but the previous two false axioms are merely explicit statements that fall under the following general category:
4) A one trick pony is not an obfuscation
If your obfuscation only does one thing, it's not an obfuscation. Newbies learning obfuscation often take one particular trick and put a little code around it and think it's an obfu. This is a trap, because unless you're as good as japhy at misdirecting people, it'll be obvious.
5) Do not use Obfuscations to learn Perl
(no examples shown)
If you are on the path to learning Perl, do not use obfuscation as your learning tool. My best reason for this is given here, but to sum up: warnings and strict are often optional in obfuscations. They are not optional in production code. If you are learning perl, learn as you would for production code. Also, if you have to avoid using warnings or strict for an obfuscation, make sure you know why. It is better to make an obfu that works around that and is still just as unreadable.
While that's all great and you now hopefully have an understanding of what not to do, here's some help for what you want to do:
1) Learn from others
This is the single most important tip i can give. If you really want to learn to be an obfu ninja, you must train to be an obfu ninja. It doesn't just come naturally. The following is a short list of people who are good at obfu you may wish to read up on:
If at first you can't get some of the obfus that's ok; some of them are really obfuscated. But at least try to de-obfu a few of them and see what tricks they used. You can learn many useful things that way. Note also that there are many, many obfuscations in the Obfuscated Code section, don't feel you need only learn from masters, a novice may teach you as well.
i'm sure you expected this one. The first few obfuscations you try are sure to be not very obfuscated, people expect that. But as you get practice (and learn from others) you'll have a better understanding of what truly is hard to read. And just generally, please don't post every practice obfuscation you write to perlmonks, we're trying to maintain an above average signal to noise ratio here and every bit of help counts :)
3) Learn Perl from Obfuscation
Once you have gotten past speaking baby perl and are learning to write perl like perl, an obfuscation can be just the thing to help learn a function well. And (ab)using a function can make the code horribly difficult to read :) Another good way to learn things is by finding the breaking point. Obfuscation can be a way to "break" Perl and find out more about Perl from why it broke, how it broke, and other analytical questions.
4) Learn the Art of Misdirection
One of the things i have been failing at repeatedly is how many layers of misdirection i wrap into the code. The point is best made by Abigail here with a subtle application.
Unfortunately too many misdirections can be a Bad Thing(tm). Think of a layer of misdirection as a permutation, then we can say it's possible that the composition of misdirections may be closer to the original code than any one particular misdirection. Learning how to obfuscate (in an abstract sense) is learning how to write different misdirections that together form something more difficult to understand than the original. Oddly enough, sometimes the number of misdirections is zero (just show the code and have no fear, no one will understand it anyway)
With that, here are some obfu's i've studied recently that i've found
NOTE: any /msg welcome on making this quasi-tutorial better...
PS thanks go to Erudil for all the help