Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: first posted obfu, explanation

by chargrill (Parson)
on Jan 17, 2006 at 19:02 UTC ( [id://523809]=note: print w/replies, xml ) Need Help??


in reply to first time caller, long time listener

I just thought I'd post the steps I took to create this.

This is all pretty much a spoiler, so I'm tucking it all away into a readmore.

I started with the following code:
#!/usr/bin/perl -wire # sets -w, which only tries to slightly obfuscate that i'm using -i ( +$^I) to # hold "re". a later version of this, i added a comment below this li +ne that # read "# Just another Bird onawire", hoping that an observant deobfus +cator # would notice that that phrase contained most of "Just another Perl h +acker,", # had the right capitalization, and the correct number of characters, +and lead # the deobfuscator to believe that the comment might be used to genera +te the # phrase. # set $/ to 'J' to create the capital J. $/ = "J"; # set $\ (output record separator, saves from having to print it) to ' +,' for # the end of the japh. $\ = ","; # some basic character -> ord -> math -> character machinations. # this puts the string "kcahtona" into $r - those bits give "anoth" an +d "hack" # when reversed and substr'd out. $r = join "", map { $_ += 57; chr } map { ord } split //, "2*(/;65("; # t holds a list of single character symbols in the symbol table. @t = sort map { if( m/^\w$/m ){ $_ } } keys %{ *:: } ; # sub u returns a single space. sub u { $" } # sub s returns "re" . "htona" = "another" reversed. sub s { $^I . substr $r, 3, 5 } # sub j returns "l" . "re" . "P" = "Perl" reversed. i've learned that + the # symbol table gets populated in a reliable manner (at least reliable +enough # for the purposes of this JAPH) to be able to count on the position i +n a sorted # list of single character symbol table entries. sub j { $t[-5] . $^I . $t[-8] } # sub P returns "re" . "kcah" = "hacker" reversed. sub P { $^I . substr $r, 0, 4 } # sub l returns "t" . "s" . "u" . "J" = "Just" reversed. sub l { $t[-2] . $t[-3] . $t[-1]. $/ } print map { # this just adds a space (via sub u) after every word-retu +rning # subroutine unless it matches /ack/. if( m/ack/ ){ $_ } else { $_ .= &u } } # calls the subroutines in order, reversing the letters in each +word. map { scalar reverse } ( l, &s, &j, &P);

At this point, I thought it was a little confusing, but only slightly obfuscated (if at all) when compacted, etc. I replaced a few ","s with "=>"s, replaced "scalar" with "~~", changed m//m to m**m etc, and was left with this:

$/="J";$\=",";$r=join""=>map{$_+=57;chr}map{ord}split//=>"2*(/;65(";@t +=sort map{if(m*^\w$*m){$_}}keys%{*::};sub u{$"}sub s{$^I.substr$r,3,5}sub j{ +$t[-5].$^I .$t[-8]}sub P{$^I.substr$r,0,4}sub l{$t[-2].$t[-3].$t[-1].$/}print map +{if(m#ack# ){$_}else{$_.=&u}}map{~~reverse}(l,&s,&j,&P);

Starting to look promising, but I find it lacking a bit. I ran a quick tr/a-z0-9/b-za2-901/ and added a way to get it eval'd and was left with this:

#!/usr/bin/perl -wire $_=q|$/="J"; $\=","; $s=kpjo"",nbq{$_+=79;dis}nbq{pse}tqmju//,"4*(/;87 +(";@u=tpsu nbq{jg(n*^\x$*n){$_}}lfzt%{*::};tvc v{$"}tvc t{$^I.tvctus$s,5,7}tvc k{ +$u[-7].$^I .$u[-0]}tvc P{$^I.tvctus$s,2,6}tvc m{$u[-4].$u[-5].$u[-3].$/}qsjou nbq +{jg(n#bdl# ){ $_ }fmtf{ $_ .=&v}}nbq{~~sfwfstf}(m,&t,&k,&P);|; $_ =~ y[b-za2-901][a-z0-9]; eval

All well and good, except anyone can apply a mental tr/// and see that in the above code nbq=map,tvc=sub, etc.

The next step is to hide the tr/// string.

First I need some ord values with which to do some math.

sub r { 49 } # returns 49 sub a { r()-1 } # returns 48 sub b { a()-1 } # returns 47 sub c { b()+3 } # returns 50 sub d { 0 } # returns 0
... but I'd like to hide _that_ a bit, as well as throw anyone off the trail of my main tr/// (perhaps they'll try to apply _this_ tr/// to the main block above?) - therefore:
$e=q= fho'e{49} fho'n{e()-1} fho'o{n()-1} fho'p{o()+3} fho'q{0} =; $e=~y/a-z/n-za-m/; eval $e;

So now I need a way to create the string "y/b-za2-901/a-z0-9/", and that's where the last section comes from.

I'm essentially performing the following:

$A = ( scalar join '', map { $a = $_ + 48; $a = pack('c',$a); # converts ord to chr without usin +g 'chr' $a =~ s/(b|2)/$1-/; # appends a '-' if it's a 'b' or a + '2' $a } ( 50, 74, 49, 2, 9, 0, 1 ) );

$A now contains ( 'b-za2-901' )

$B = ( scalar join '', map { $b = $_ + 49; $b = pack('c',$b); # converts ord to chr without usin +g 'chr' $b =~ s/(a|0)/$1-/; # appends a '-' if it's an 'a' or +a '0' $b } ( 48, 74, -1, 8 ) );
$B now contains 'a-z0-9'.
join '', map { if( m/^\d+$/ ){ pack'c',$_ # if map encounters a number, convert it to chr } else{ $_ # otherwise, don't chr it. } } ( 121, 47, $A, 47, $B, 47 )

Now I've got "y/b-za2-901/a-z0-9/" and it gets eval'd and combined and obfuscated thusly:

eval join '', map{ if( m|^\d+$| ){ pack'c',$_ } else{$_} } ( 22 + c() + r(), b(), ( ~~ join '', map { $a = $_ + a(); $a = pack('c',$a); $a =~ s{(b|2)}[$1-]; $a } ( c(), 24 + c(), r(), 2, 9, d(), 1 ) ), b(), ( ~~ join '', map { $b = $_ + r(); $b = pack('c',$b); $b =~ s=(a|0)=$1-=; $b } ( a(), 24 + r(), -1,8 ) ), b() );

And that's the point where I decided enough was enough, and stopped obfuscating :)

Many thanks to the following monks, tidbits, and snippets: gmax and their post Structured obfuscation - the fifth level of obfuscation listed there in particular, and in Writing highly obfuscated code in Perl there are many gems including the ~~ for scalar substitution, and my inspiration for using $^I.

Hopefully, it's not bad form to post the explanation of my obfuscation to my post without giving anyone else the chance to do so :)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2025-06-20 01:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.