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

Hello Monks,

I had read up on the new nodes, so I went to the tutorials to select something that I thought might be interesting and improve my perl game, settling on 181977, which has a good example of Tk that a beginner can replicate. I downloaded and executed the script, finding that it produces a window that shows the contents of a directory, has another for a listing of a selected file, and a final one for the output if it's a perl script. It's billed as an "obfu decoder ring," as one can, allegedly, see the output of a script or with pasted-in text without giving it full-reign.

At the end of the thread, someone posted an obfuscated script, which I turned into a .pl file to see what it might reveal, getting no output. What's more, the poster claimed you would be more or less brainless to run it without the use of Safe.pm.

My question is: how do I use Safe.pm effectively? Assume that I have an obfu that I can make neither heads nor tails of. I won't list the one at the end of this node, because I don't know whether it is pernicious or not. What I have so far is this:

#!/usr/bin/perl use Safe; use 5.010; say "safe";

Thanks for your comment,

Replies are listed 'Best First'.
Re: using Safe.pm
by CountZero (Bishop) on Jul 06, 2015 at 06:07 UTC
    Nothing to do with your question about Safe, but perhaps you can add another window to the "obfu decoder ring" with the output of B::Deparse which can assist in understanding obfuscated code.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics

      An interesting challenge. I've been fiddling with it for 48 hours and decided that altering the windows/widgets was beyond my skill level. Since the output goes to STDOUT, I opted to create an event that would do so. I sincerely hope the readmore tags work this time:

      When I depress ctrl-d, I get to the sub that prints "before eval" to STDOUT. My current problem is writing the appropriate eval statement, in other words, trying to imitate the command line from within a program. My best guess did not work:

      #!/usr/bin/perl use Modern::Perl qw/2010/; use Safe; use File::Slurp; my $compartment = Safe->new(); my $japh = read_file( 'obfu3.pl' ) ; my $result = $compartment->reval($japh); say "Result is $result"; eval ('perl -MO=Deparse obfu3.pl');

      The top part works; the bottom doesn't. Looking for tips. Thank you.

        You don't have to start an external Perl instance. B::Deparse works equally well from within your script:
        use B::Deparse; my $deparse = B::Deparse->new(); my $body = $deparse->coderef2text(sub { # your program here }); print $body;

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        My blog: Imperial Deltronics
Re: using Safe.pm
by CountZero (Bishop) on Jul 06, 2015 at 05:55 UTC
    Did you read the documenation of Safe and more specifically, its reval method?

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics

      I did, but it's all very much above my head. If I stored the JAPH as a string called $japh, then would an appropriate call consist of:

      my $japh = 'bla bla bla'; my $return = reval($japh, STRICT); say "return is $return";
        No, that will not work.

        Safe is an object-oriented module and does not export a reval function.

        You use this module as follows:

        use Modern::Perl qw/2015/; use Safe; my $compartment = Safe->new(); my $unsafe_code = '# add some unsafe code here'; my $result = $compartment->reval($unsafe_code); say "Result is $result";

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        My blog: Imperial Deltronics

        I did, but it's all very much above my head. If I stored the JAPH as a string called $japh, then would an appropriate call consist of:

        You need to have the docs at eye level and start with SYNOPSIS of Safe, reval is a method