Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Read carefully...

by Felonious (Chaplain)
on Oct 03, 2002 at 01:23 UTC ( [id://202412]=obfuscated: print w/replies, xml ) Need Help??

#!/usr/bin/perl -w use strict; ( sub { print map { $_->() } @_[3,1,2,0,4]; } )->( sub { no strict;q;read!; }, sub { ( sub { map { $_->() } @_[2,1,0] } )->( sub { 't ' }, sub { ( sub { $_[0]->(), 's' } )->( sub { 'u' } ) }, sub { 't', 'r' } ) }, sub { ( sub { map { $_->(), " " } @_; } )->( sub { lc ref sub { '', reverse 'J A P H !' } }, sub { ++($_="yot") }, sub { ( sub { @_[1,4,3,6,2,5,0]; } )->( split('',"thnva'e") ) } ) }, sub { ( sub { map { $_->() } @_[1,0] } )->( sub { ( sub { $_[0]->(), q;'t ; } )->( sub { 'n' } ) }, sub { no strict; Do } ) }, sub { $/ } )

[TINPC@perlcabal.com shh]$ su real

Replies are listed 'Best First'.
Re: Read carefully...
by krisahoch (Deacon) on Oct 03, 2002 at 18:25 UTC

    Awesome Felonious, well done!

    Category Score (1-10)
    Obfu Appearence 9
    Eye Pleasing Appearence 9
    Decryptability (high is good) 5
    Non-Forsee-able outpu 10
    My Rating 8(actually 8.1)

    Kristofer A. Hoch

    Disclaimer: These scores are subjective to my abilities, and awe. They are not meant to be representitive of other monks.
Re: Read carefully...
by Notromda (Pilgrim) on Oct 07, 2002 at 19:27 UTC
    Very suprising output... Emphasizes the need to run obfu code in an untrusted account. :) ++Felonius
Re: (SPOILER) Read carefully...
by meta4 (Monk) on Oct 09, 2002 at 21:41 UTC

    First, let me congratulate Felonius on a very fine obfuscation.

    However, The use of white space, while very commendable when writing "real" code, detracts a bit from the intended effect of the obfuscation. Here is your code with all the white space, a few semi-colons, and all the new lines removed. (It works exactly the same on my machine.)

    #!/usr/bin/perl -w use strict; (sub{print map{$_->()}@_[3,1,2,0,4]})->(sub{no strict;q;read!;},sub{(s +ub{ map{$_->()}@_[2,1,0]})->(sub{'t '},sub{(sub{$_[0]->(),'s'})->(sub {'u' +})}, sub {'t','r'})},sub{(sub{map{$_->()," "}@_;})->(sub{lc ref sub{'', rev +erse 'J A P H !'}},sub{++($_="yot")},sub{(sub{@_[1,4,3,6,2,5,0]})->(split(' +', "thnva'e"))})},sub{(sub {map{$_->()}@_[1,0]})->(sub{(sub{$_[0]->(), q; +'t ; })->(sub{'n'})},sub{no strict;Do})},sub{$/})

    I don't know if that really adds any mystery, but I think it makes it look more intimidating.

    Spoiling

    The main trick in this obfuscation comes from the idiom of calling a subroutine through a code reference like this $sub_ref->( 1, 2, 3 ). However, instead of defining a subroutine somewhere else and storing a reference to it in a scalar, you can define an anonymous code reference right where you are using it, like this ( sub{ print "@_" } ) -> ( 1, 2, 3 ). This has the exact same effect as print( 1, 2, 3 ). If you reformat the creation of the code reference the way Felonious does in the obfu it looks like this.

    ( sub { print "@_" } ) -> ( 1, 2, 3 );

    Felonius takes this idea several steps further, starting with the idea of passing code-references/anonymous-subroutines as arguments to another anonymous subroutine. A simple example of this is:

    ( sub { print map { $_->() } @_; } ) -> ( sub{ 'Just ' }, sub{ 'another ' }, sub{ 'Perl ' }, sub{ 'hacker,' }, );

    This code snippet creates a list of anonymous subroutines and passes it to another anonymous subroutine that just loops through the list calling each of the anonymous subroutines and collects all their output into another list. The resulting list is then printed.

    The next devious step Feloius takes is to fiddle a bit with the order of the list of anonymous functions using Perl's slice syntax on the argument array before handing the list off to map. Applying this to the previous example yields something like this.

    ( sub { print map { $_->() } @_[1,0,3,2]; } ) -> ( sub{ 'another ' }, sub{ 'Just ' }, sub{ 'hacker,' }, sub{ 'Perl ' }, );

    Then to top it all off, Felonious nests this entire construct inside itself. Here is another simplified example, which demonstrates this technique. <\p>

    ( sub { print map { $_->() } @_ } ) -> ( sub { ( sub { map { $_->() } @_ } ) -> ( sub { 'J' }, sub { 'A' } ) }, sub { ( sub { map { $_->() } @_ } ) -> ( sub { 'P' }, sub { 'H', '!' } ) } );

    If you can figure that snippet out most of Felonious' obfuscation will become clear. Felonious nests it up to three levels deep in some places. Notice in the above snippet the nested constructs are wrapped in a sub{...} block (operator?, function?). This keeps the anonymous subroutine from being evaluated even though arguments are supplied. (Someone else probably has a better explanation for this.)

    That explains most of the obfuscation. There are, however, two other tricks Felonius uses. First, Felonius uses Perl's string increment operator to turn "yot" into "you". This is what the line ++($_="yot") does. Then he gets the string "code" by calling ref on an anonymous subroutine, and lowercasing the result. This is what the following snippet does.

    lc ref sub { '', reverse 'J A P H !' }

    There are a few other tricks scattered around in the obfu, but if you understand the above tricks the rest of it should be relatively easy.

      Personally I thought that felonius' use of whitespace was the crowning glory of a masterpiece to rival erudil.

      If it's spoilers you want, this should clarify things completely 8^)

      #!/usr/bin/perl -w use strict; sub a{ print map{ $_->() } @_[3,1,2,0,4]; } sub b{ no strict;q;read!; } sub c{ c1( \&c11, \&c12, \&c13 ) } sub c1{ map{ $_->() } @_[2,1,0] } sub c11{ 't ' } sub c12{ c121( \&c122 ) } sub c121{ $_[0]->(), 's' } sub c122{ 'u' } sub c13{ 't', 'r' } sub d{ d1( \&d11, \&d12, \&d13 ) } sub d1{ map{ $_->(), " " } @_; } sub d11{ lc ref sub { '', reverse 'J A P H !' } } sub d12{ ++($_="yot") } sub d13{ d131( split('',"thnva'e") ) } sub d131{ @_[1,4,3,6,2,5,0]; } sub e{ e1( \&e11, \&e12 ) } sub e1{ map{ $_->() } @_[1,0] } sub e11{ e111( \&e1111 ) } sub e111{ $_[0]->(), q;'t ; } sub e1111{ 'n' } sub e12{ no strict; Do } sub f{ $/ } a( \&b, \&c, \&d, \&e, \&f );

      Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: obfuscated [id://202412]
Approved by hiseldl
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-03-28 20:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found