http://www.perlmonks.org?node_id=578955


in reply to Understanding Obfuscation

Understanding other people's obfuscations in $^F**2-1 simple steps:

I can only assume the OP is asking about this one (note, this is not my work, but it is not properly attributed on wikipedia. Chances are high it originally appeared here!):

`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=( $!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++; $_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++ ;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`

Step 1: reformat the obfuscation (if possible).

`$=`; $_=\%!; ($_)=/(.)/; $==++$|; ($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=( $!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++; $.++; $.++; $_++; $_++; ($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,); $,++; $,++; $^|=$"; `$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`

Or (or perhaps additionally), run the code through B::Deparse (  perl -MO=Deparse obfu.pl ):

`$=`; use Errno (); $_ = \%!; ($_) = /(.)/; $= = ++$|; ($., $/, $,, $\, $", $;, $^, $#, $~, $*, $:, @%) = ($! =~ /(.)(.).(.)( +.)(.)(.)..(.)(.)(.)..(.)......(.)/, $"), ++$=; ++$.; ++$.; ++$_; ++$_; ($_, $\, $,) = ($~ . $" . "$;$/$%[$?]$_$\$,$:$%[$?]", $" & $~, $#); ++$,; ++$,; $^ |= $"; `$_$\$,$/$:$;$~$*$%[$?]$.$~$*$#$%[$?]$;$\$"$^$~$*.>&$=`;

Step2: figure out what you can the old fashioned way. Be sure to have a copy of perldoc perlvar handy.

`60`; $_=\%!; print "\$_ is currently: $_\n"; ($_)=/(.)/; print "\$_ is currently: $_\n"; $= = ++$|; print "\$= is currently: $=\n"; print "\$! is currently: $!\n"; ( $., $/, $,, $\, $", $;, $^, $#, $~, $*, $:, @% ) = ( $!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++; print "\$. is currently: $.\n"; print "\$/ is currently: $/\n"; print "\$, is currently: $.\n"; print "\$\\ is currently: $\\n"; print "\$\" is currently: $\"\n"; print "\$; is currently: $;\n"; print "\$^ is currently: $^\n"; print "\$# is currently: $#\n"; print "\$~ is currently: $~\n"; print "\$* is currently: $*\n"; print "\$: is currently: $:\n"; print "\@% is currently: ", join( ' ', @% ), "\n"; $.++; $.++; print "\$. is currently: $.\n"; $_++; $_++; print "\$_ is currently: $_\n"; ( $_, $\, $, ) = ( $~ . $" . "$;$/$%[$?]$_$\$,$:$%[$?]", $" & $~, $#, +); print "\$_ is currently: $_\n"; print "\$\\ is currently: $\\n"; print "\$, is currently: $.\n"; $,++; $,++; print "\$, is currently: $.\n"; $^|=$"; print "\$^ is currently: $^\n"; print "\$\" is currently: $\"\n"; print "$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;" . $\ . $" . "$^$~$*.> +&$="; `$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`

Outputs:

$_ is currently: HASH(0x18092a8) $_ is currently: H $= is currently: 1 $! is currently: No such file or directory $. is currently: N u$/ is currently: o u$, is currently: N u$\ is currently: u u$" is currently: c u$; is currently: h u$^ is currently: nu$# is currently: l u$~ is currently: e u$* is currently: r u$: is currently: t u@% is currently: s s u$. is currently: P u$_ is currently: J u$_ is currently: echo Just a$\ is currently: a a$, is currently: P a$, is currently: P a$^ is currently: na$" is currently: c aecho Just another Perl hacker.>&2aJust another Perl hacker.

Nevermind the start of the lines on or around where $\ is set. According to perlvar, that's the output record separator (after I printed the trailing "\n" in the "currently" lines, perl appends the output records separator, hence the funny line beginnings).

Step 3: Apply intuition. It should be fairly obvious in the above example that the original code is simply building a command to run via qx//; "echo Just another Perl hacker.>&2". If at this point there are still things you don't understand, maybe that's when you start asking around in the chatterbox :)

Oh, there are a few things here and there that perhaps aren't sufficiently self-explanatory, but learning is half the fun. Especially rewarding is the why when you stumble across that.



--chargrill
s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)