Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Icarus

by jorg (Friar)
on Mar 23, 2001 at 18:11 UTC ( [id://66624]=note: print w/replies, xml ) Need Help??


in reply to Icarus

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

Replies are listed 'Best First'.
Re: Re: Icarus
by c-era (Curate) on Mar 23, 2001 at 20:26 UTC
    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.
Re: Re: Icarus
by larryk (Friar) on Mar 23, 2001 at 20:42 UTC
    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?

      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.

        Thankyou.

        I have just one other query. You seem to have used => as a comma replacement. I know this is alternate notation when defining a hash but will Perl always interpret this as a comma?

      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

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2024-04-19 15:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found