Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

My first attempt at obfu

by fokat (Deacon)
on Aug 22, 2002 at 05:07 UTC ( [id://191928]=obfuscated: print w/replies, xml ) Need Help??

Dear monks:

I offer to your infinite wisdom my very first wandering into the arts of obfuscating code.

#/usr/bin/perl -w use strict; $_[$_]=0 for 0..7;my$i; for my$a(grep{s@^00@@}unpack'B8' x28,join'',map{chr}split/\*+/,q{61*31*28*32*20* 40*25*63*63*9*52*58*49*18*30*47*20*2*10*4*8*63*63*1*36*2*13* 30}){$i=0;grep{$_[$i++].=$_}split//,$a;length$_ [0]==8&&print pack'B8',$_ for@_ ;length$_[0]==8&&grep{ $_=0}@_;}print"\n";
As per the tradition set forth by our ancestors, I always try to Use strict and warnings.

Regards.

Replies are listed 'Best First'.
Re: My first attempt at obfu (attempted helpfulness)
by jynx (Priest) on Aug 22, 2002 at 20:50 UTC

    My usual disclaimer:

    Realizing that i'm not a master at obfu, the following code may or may not be more difficult to parse than the original. But i had fun with the exercise, and hopefully this will help others a bit as well...

    That being said, here's another Attempted Helpfulness...

    First of all, let's seperate that obfu into some proper white-spacing to see where to begin. My formatting attempts produced:

    #/usr/bin/perl -w use strict; $_[$_]=0 for 0..7; my$i; for my$a(grep{s@^00@@} unpack'B8'x28, join'', map{chr} split/\*+/, q{61*31*28*32*20*40*25*63*63*9*52*58*49*18*30*47*20*2*10*4*8*63*63*1*3 +6*2*13*30} ){ $i=0; grep{$_[$i++].=$_}split//,$a; length$_[0]==8 && print pack'B8',$_ for@_; length$_[0]==8 && grep{$_=0}@_; } print"\n";
    Not to nitpick, but here's a few points:
    • Doing extra work for initialization, while nice (and in this case necessary), let's the reader see where you're starting from.
    • Checking against explicit values let's the reader know explicitly what a value is expected to be, allowing them to trace the code more easily
    • Redundant code amalgamates chunks of code that are easier to understand
    • Using built-in functions rather than features gives the reader explicit behavior
    • Using explicit delimiters for data is a tad unsubtle
    • Using $_ where available makes it to that readers can't always see where you're referencing it, as opposed to using an explicit loop value (for your for loop)
    Those were the points that i most thought worthwhile to go through, unfortunately it takes a bit for some of them. Here are some iterations that show one possible direction for the code...

    1
    Alright, that splitting on asterisk has to go bye-bye...

    $_[$_]=0 for 0..7;my$i; for my$a(grep{s@^00@@} unpack'B8'x28, join'', map{chr} '61312832204025636309525849183047200210040863630136021330'=~/ +../g ){ $i=0; grep{$_[$i++].=$_}split//,$a; length$_[0]==8 && print pack'B8',$_ for@_; length$_[0]==8 && grep{$_=0}@_; } print"\n";
    2
    Change the initialization of @_. My penchant is to use split, and it seems that in perl 5.8 warnings doesn't complain about split's moving things to @_ anymore :)
    NOTE: have to wrap the code in an anonymous sub block in order to use the split trick...
    sub{split//,'0'x6;my$i; for my $a(grep{s@^00@@} unpack'B8'x28, join'', map{chr} '61312832204025636309525849183047200210040863630136021330'=~/ +../g ){ $i=0; grep{$_[$i++].=$_}split//,$a; length$_[0]==8 && print pack'B8',$_ for@_; length$_[0]==8 && grep{$_=0}@_; }print"\n"}->()
    3
    Use the $_ default variable for the for loop, and stop using split for the grep. Also note how the $_ inside of the grep doesn't need to be changed :)
    sub{split//,'0'x6;my$i; for (grep{s@^00@@} unpack'B8'x28, join'', map{chr} '61312832204025636309525849183047200210040863630136021330'=~/ +../g ){ $i=0; grep{$_[$i++].=$_}/./g; length$_[0]==8 && print pack'B8',$_ for@_; length$_[0]==8 && grep{$_=0}@_; }print"\n"}->()
    4
    Get rid of $i, since it requires declaration and initializaion...
    ($; requires initialization, but it's hopefully less obvious)
    move the grep to a map (my paranoia :)
    sub{split//,'0'x6;$;--; for (grep{s@^00@@} unpack'B8'x28, join'', map{chr} '61312832204025636309525849183047200210040863630136021330'=~/ +../g ){ map{$_[($;+=1)%=6].=$_}/./g; length$_[0]==8 && print pack'B8',$_ for@_; length$_[0]==8 && grep{$_=0}@_; }print"\n"}->()
    5
    Get rid of the redundant length checks...
    sub{split//,'0'x6;$;--; for (grep{s@^00@@} unpack'B8'x28, join'', map{chr} '61312832204025636309525849183047200210040863630136021330'=~/ +../g ){ map{$_[($;+=1)%=6].=$_}/./g; for (@_) { length==8 && (print(pack'B8',$_) and ($_=0)) } }print"\n"}->()
    6
    Combine the $_ assignment and print, stop using length to check, add a small bit of misdirection (using ?: instead of &&), and since we only have one statement, move to a postfix for

    some notes:

    1. print returns 1 if successful, so -1+print returns 0
    2. The $_ assignment happens after the print, so we don't sully what we're printing beforehand
    3. In the for(@_) loop $_ will be the elements of @_, and /./g in array context returns each element. Wrapping that like @{[/./g]} and using it in scalar context makes it evaluate numerically returning the length of $_...
    4. Using length-8 instead of length==8 makes it so that the false section of the ?: will do the processing, but there's no longer an explicit check against a number...
    5. In the ?:, ?? is a regular expression matching on $_.
    sub{split//,'0'x6;$;--; for (grep{s@^00@@} unpack'B8'x28, join'', map{chr} '61312832204025636309525849183047200210040863630136021330'=~/ +../g ){ map{$_[($;+=1)%=6].=$_}/./g; @{[/./g]}-8???:($_=-1+print pack'B8',$_)for@_ }print"\n"}->()
    7 (final version)
    Now because there's no reason to give people the easiest time figuring out what's going on, change some delimiters and collapse it again into a few lines of text (again using my predilection for even lines of code in obfuscations)...
    sub{split q,,,q;0;x6;$;--;for(grep s,^00,,,unpack'B8'x28,join'',map ch +r,q,61 312832204025636309525849183047200210040863630136021330,=~m,..,g){map$_ +[($;+= 1)%=6].=$_,m,.,g;@{[m,.,g]}-8???:($_=-1+print pack'B8',$_)for@_}print$ +/}->()
    It still compiles and runs under strict and warnings, but now it's more difficult to break it into chewable chunks. Anyway, that's the process i went through after running your obfu. Sorry about the long post, but with any luck it was helpful...

    nuf evah,
    jynx

    update: fixed a typo (thanx to Ferret for catching it)

    Also, i would like to note that this was an obfuscation before i twisted it. The reason is because the algorithm is difficult to comprehend. All i did was add some window dressing to it. i hope i didn't sound critical in the above post, because this was a good first obfu before the window dressing :-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2024-03-29 11:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found