Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi All, I request some help in making code readable after the Deparse module of perl .
--------------------------------------- i have a script run.pl --------------------------------------- 1) perl -MO=Deparse run.pl >out --------------------------------------- this gives output in form eval eval qq["#!/usr/bin/perl\n\n#.....single line....."]; $: = 'P'; [...] $~ = 'h'; --------------------------------------- 2) set -f text=$(cat out) --------------------------------------- 3) echo -e $text --------------------------------------- but this method still leaves some special chars escaped in text like \" \\$ \{ \} \\& Has any monk tried this way to get output that resembles more/less like source. If someone can share that would be nice.
thanks, Kapil

Replies are listed 'Best First'.
Re: clean output from Deobfucation
by eyepopslikeamosquito (Archbishop) on Sep 21, 2010 at 08:08 UTC

    To give a specific example, this Acme::EyeDrops'ed program prints 99 bottles of beer:

    ''=~( '(?{' .('`' |'%') .('[' ^ +'-') .('`' |'!') .('`' |',') .'"'. ' +\\$' .'==' .('[' ^'+') .('`' |'/') . +('[' ^'+') .'||' .(';' &'=') .(';' & +'=') .';-' .'-'. '\\$' .'=;' .('[' ^ +'(') .('[' ^'.') .('`' |'"') .('!' ^ +'+') .'_\\{' .'(\\$' .';=('. '\\$=|' ."\|".( '` +'^'.' ).(('`')| '/').').' .'\\"'.+( '{'^'['). ('`'|'"') .(' +`'|'/' ).('['^'/') .('['^'/'). ('`'|',').( '`'|('%')). '\\".\\"'.( '['^ +('(')). '\\"'.('['^ '#').'!!--' .'\\$=.\\"' .('{'^'['). ('`'|'/').( '`'| +"\&").( '{'^"\[").( '`'|"\"").( '`'|"\%").( '`'|"\%").( '['^(')')). '\\" +).\\"'. ('{'^'[').( '`'|"\/").( '`'|"\.").( '{'^"\[").( '['^"\/").( '`'| +"\(").( '`'|"\%").( '{'^"\[").( '['^"\,").( '`'|"\!").( '`'|"\,").( '`'| +(',')). '\\"\\}'.+( '['^"\+").( '['^"\)").( '`'|"\)").( '`'|"\.").( '['^ +('/')). '+_,\\",'.( '{'^('[')). ('\\$;!').( '!'^"\+").( '{'^"\/").( '`'| +"\!").( '`'|"\+").( '`'|"\%").( '{'^"\[").( '`'|"\/").( '`'|"\.").( '`'| +"\%").( '{'^"\[").( '`'|"\$").( '`'|"\/").( '['^"\,").( '`'|('.')). ','. +(('{')^ '[').("\["^ '+').("\`"| '!').("\["^ '(').("\["^ '(').("\{"^ '[') +.("\`"| ')').("\["^ '/').("\{"^ '[').("\`"| '!').("\["^ ')').("\`"| '/') +.("\["^ '.').("\`"| '.').("\`"| '$')."\,".( '!'^('+')). '\\",_,\\"' .'!' +.("\!"^ '+').("\!"^ '+').'\\"'. ('['^',').( '`'|"\(").( '`'|"\)").( '`'| +"\,").( '`'|('%')). '++\\$="})' );$:=('.')^ '~';$~='@'| '(';$^=')'^ '['; +$/='`';
    Running the above code through perl -MO=Deparse produces:
    '' =~ /(?{eval"\$==pop||99;--\$=;sub\n_\{(\$;=(\$=||No).\" bottle\".\" +s\"x!!--\$=.\" of beer\").\" on the wall\"\}print+_,\", \$;!\nTake on +e down, pass it around,\n\",_,\"!\n\n\"while++\$="})/; $: = 'P'; $~ = 'h'; $^ = 'r'; $/ = '`';
    The last four lines above ($: = 'P';...) match your posted code and are just harmless "filler" code, setting a variety of Perl special variables to random values after the eval has already been executed. This filler code is meant to be a "no-op"; its only (cosmetic) purpose is to fully fill all the beer bottles with code. If you don't want the filler code to be inserted, you can set the Acme::EyeDrops FillerVar attribute to '' (see the documentation of FillerVar in the Acme::EyeDrops documentation for the gory details).

    If you squint, you'll notice that -MO=Deparse has deparsed the original:

    $:=('.')^ '~';
    to:
    $: = 'P';
    which is helpful and all that you'll get from Deparse.

    Update: You could manually do what Corion suggested by editing the Deparse output, just changing eval to print like so:

    '' =~ /(?{print"\$==pop||99;--\$=;sub\n_\{(\$;=(\$=||No).\" bottle\".\ +"s\"x!!--\$=.\" of beer\").\" on the wall\"\}print+_,\", \$;!\nTake o +ne down, pass it around,\n\",_,\"!\n\n\"while++\$="})/; $: = 'P'; $~ = 'h'; $^ = 'r'; $/ = '`';
    Running this produces the original source, without the annoying escapes:
    $==pop||99;--$=;sub _{($;=($=||No)." bottle"."s"x!!--$=." of beer")." on the wall"}print+_ +,", $;! Take one down, pass it around, ",_,"! "while++$=

      thats very good idea to change eval -> print
      But there are two of them evals.( for safekeeping the regexs that may get corrupt in EyeDrop tranform)

      I removed one and changed one to print and again :) we get exact line by line code that exactly the same as source ..

      !!! Million Thanks !!!

        I know it has been a year since last post, but this article just saved my life. Thank you wise monks!!!!

Re: clean output from Deobfucation
by Anonymous Monk on Sep 21, 2010 at 07:03 UTC
    That is not something which B::Deparse does. Apparently, that's the actual script's code you're looking at.

    You could try saving that code-in-a-string to a file, and try to deparse that.

      >That is not something which B::Deparse does. Apparently, that's the actual script's code you're looking at.

      Yes , deparse is parsing a code that is initially obfuscated by Acme::EyeDrops

      Now the script code that it prints I save that to a file "out" and then tried evaling that code-in-a-string by echo -e
      However I think I am missing your point . Thanks

        Maybe you want to look at B::Deobfuscate and especially overload::eval, which gives some more avenues of output. By overloading eval, you can replace the eval that must happen somewhere in obfuscated/encoded code with a print command and look at the code to be evaluated.