Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Icarus

by Adam (Vicar)
on Mar 23, 2001 at 05:35 UTC ( #66546=obfuscated: print w/ replies, xml ) Need Help??

*$=sub{$a=q;}die;;sub u(){$_}$=&&unpack u=>u};s[] {82G5S="!A;F]T:&5R(%!E<FP\@:&%C:V5R}six;die&$=>$/
Don't hold it too close to the light, it will fall apart. :-)

Comment on Icarus
Download Code
Re: Icarus
by larryk (Friar) on Mar 23, 2001 at 15:35 UTC
    six lol. very good - i like it. it's a bit over my head but I get the general idea.
Re: Icarus
by jorg (Friar) on Mar 23, 2001 at 18:11 UTC
    would you care to explain this one to me? As obfuscation goes completely over my head yours looks like a nice and short example that i *might* be able to comprehend

    Jorg

    "Do or do not, there is no try" -- Yoda
      Here it is formated nicly:
      *$ = sub{ $a=q;}die;; sub u{ $_; } $= && unpack u => u; }; s[]{82G5S="!A;F]T:&5R(%!E<FP\@:&%C:V5R}six; die &$ => $/;
      Boiled down this can be represented by
      *$=sub{ unpack "u", $_; }; $_='82G5S="!A;F]T:&5R(%!E<FP@:&%C:V5R'; die &$, $/;
      or even a one-liner:
      die unpack ("u", '82G5S="!A;F]T:&5R(%!E<FP@:&%C:V5R'), $/;
      With this, you should be able to figure out what was done to hide the code.
      have a look with some formatting...
      I'm no expert but I'll have a go at explaining this one.

      *$=sub{ $a=q;}die;; sub u(){$_} $= && unpack u=>u }; s[]{82G5S="!A;F]T:&5R(%!E<FP\@:&%C:V5R}six; die &$=>$/

      I don't understand the *$ except that * is the typeglob prefix so *test="a" would mean $test is "a" $test[0] (from @test) is "a" and $test{a} is defined but with no value. In this case the Perl processID special variable $$ may be being overwritten with a ref(?) to the sub (someone help me out here please).

      The $a line is just to put someone offtrack - the q implies a singlequoted string to follow and the sneaky bit here is that Perl allows a ; to be the delimiter hence the ;;. The offputting bit is that if you put the newline in the wrong place then you get *$=sub{$a=q;} followed by die which appears to make sense. Truth is this whole line can be removed and the output won't be affected.

      sub u(){$_} is the same as sub u { return $_; }

      $= is a Perl special variable a.k.a. $FORMAT_LINES_PER_PAGE (default 60) and is used here simply as a true value so the unpack will be evaluated.

      the s[]{blahblahblah} is a substitution on $_ which is presumably a uuencoded string equating to "Just another Perl hacker" which the unpack reveals (six is just a clever arrangement of unnecessary modifiers to the substitution).

      the last line "die &$=>$/" just dies with the returned value from the sub defined earlier although (again help please) the =>$/ (which is the special variable for the input record separator) supresses the "at blah.pl line X" which usually follows - don't know how though.

      how did I do?

        aah yes indeed i'm starting to get the picture now thanks larryk, ++ tomorrow 'cuz haven't got any votes left.
        thanks again!

        Jorg

        "Do or do not, there is no try" -- Yoda
        Yes, you caught the general ideas, but I'll explain the parts you had questions on. Your formating of the code is correct, and the $a assignment is definatly there to throw you, which it didn't.

        *$=sub{}; is equivalent to &$=sub{}. This is equivalent to sub $ {}, except that you can't do that. The magic is in the typeglob, which recognizes that its getting an anonymous sub, and names it &$. The value of $$ (the PID) is left unchanged. :-)

        Next, you said: sub u(){$_} is the same as sub u { return $_; }, which it isn't. The parens() act as an empty prototype basically telling Perl that the letter u by itself is a valid function call. Otherwise you have to use &u or u(). This allows the u=>u in the next line. Also note that even though this sub is defined inside the scope of the other sub, it is still a package global subroutine - all subroutines are, regardless of where they are defined. Granted there is some magic involved with localized variables and closures, but this doesn't run into any of that.

        s[]{82G5S="!A;F]T:&5R(%!E<FP\@:&%C:V5R}six;
        Is kind of cool in that it takes $_, which is undefined, and replaces it with the payload, uuencoded. The six are just useless extensions, but distracting ones. Its also sort of a joke in that this was my sixth obfuscation posted here. Note that this will generate a warning about using an undefined variable, but will still pass strict.

        And last but not least, die &$=>$/ calls the sub defined earlier, which basically does die unpack( u=>u), $/ Now you asked about $/, it's default value is "\n". If you die with a string ending in a newline, then the "at blah.pl line X" is supressed. That's also true with warn. The u=>u is equivalent to "u", u() where the first u tells unpack to uudecode the return from u(), which just returns $_.

        Good job of taking this obfu apart.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (14)
As of 2014-09-18 19:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (123 votes), past polls