#!/usr/bin/perl # Always: use strict; use warnings; # Initialize variables. Some of them are named because of what they # were in the obfuscated version. For example, $right_parenthesis was # originally $) my %hash = (); my $left_bracket = 0; my @print_array = (); my $right_parenthesis = 0; my $scalar = q{}; my $semicolon = q{}; my $transform_ref = q{}; @print_array = qw( j q s u o X ); # one letter back: i p r t n = scrambled "print"! # ^-- last character is just a placeholder # to make the array 6 elements long # for later calculations # Set up some references $semicolon = \@print_array; $transform_ref = \&transform_print_array; # Get obfuscated "just another perl hacker" string $_ = ugly_data(); # Change all left braces to commas so original program could use commas as # quote delimiters tr[{] [,]; # "Fix" each character: if its ASCII number is higher than 95, use the # character whose ASCII number is 64 less. Otherwise use the character whose # ASCII number is 64 more. s{ (.) } { give_number ( $1 ) > 95 ? give_character( give_number( $1 ) - 64) : give_character( give_number( $1 ) + 64) }egxms; # Hash containing a reference and a constant - more obfuscation %hash = ( eval_ref => \&perform_eval, one => 1, ); # This transforms each character in the print array so it # contains p, r, i, n, t $transform_ref->(); # Since the final array index is an ugly convention, let's assign it to its # own variable. my $last_array_index = $#print_array; # This boils down to "eval print". Since $_ now contains the string # "just another perl hacker", and print with no arguments is the same as # print $_, this does the main work of the program. $hash{eval_ref}->( $semicolon->[ $scalar = $hash{one} ] # 1: p . $semicolon->[ ++$scalar ] # 2: r . $semicolon->[ $left_bracket ] # 0: i . $semicolon->[ -1 + $right_parenthesis - $right_parenthesis + $last_array_index ] # 4: n . $semicolon->[ $last_array_index - $scalar ] # 3: t ); # For the given character, return its ASCII value sub give_number { my ( $character ) = @_; return ord( $character ) } # For the given ASCII value, return its character sub give_character { my ( $character_number ) = @_; return chr( $character_number ) } # Unnecessary abstraction to perform an eval sub perform_eval { my ( $string_to_eval ) = @_; eval $string_to_eval; } # This transforms each character in the print array so it # contains p, r, i, n, t sub transform_print_array { for my $letter ( @print_array ) { $letter =~ s{ (.) } { give_character( give_number( $1 ) - 1) }exms } } # Obfuscated data. Keep at the bottom so its ugliness doesn't infect the rest # of the code layout sub ugly_data { return q[*534`!./4(%2`0%2{`(!#+%2] # says: "just another perl hacker" (after all the ord/chr are applied) } __END__ sub q{ord($_[0])}sub qq{chr($_[0])}(@q=(j,q,q,,q,s,,u,o,[$;=\@q,$"=sub{for(@q){ s/(.)/&qq(&q($1)-1)/e}},$_=q,*534`!./4(%2`0%2{`(!#+%2,,tr;{;,;,s/(.)/&q($1)>95? &qq(&q($1)-64):&qq(&q($ 1)+64)/eg,% q=(q,qq,,sub{eval$ _[0]},q,q,,1)])),&{$ "}, $q{qq}->(qq.$;->[$q=$q{q}]${$;}[++$q]$;->[$[]${$;}[-1+$)-$ )+$#q]$;->[$#q-$q].)