Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
I figure I might as well take a stab at some more of Erudil's code after deciphering How to (ab)use substr. I don't in any way mean intend these spoilers to demean the work Erudil has done. I've discovered that it's far, far easier to deconstruct than construct. I'm not even sure I could come up with the thought processes necessary to create the obfus.

Now, on to the spoiler!

Okay. Usually the first step in understanding an obfuscation is to reformat the code so it's more readable. With this example, however, we don't quite want to do that yet. There are only a couple of lines at the very end that are of interest to us at the momemt. Let's break those out.

#!/usr/bin/perl -w # my 2 cents worth use strict; $_='$_=tue($=+(two ($;)>>(two($;)>>2+2))){tue (too(two(tue($=+(two($;)>>(two ($;)>>2+2))))+(two($;)>>2+2))){tue (too(two(tue($=+(two($;)>>(two($;)>>2+ 2))))+(two($;)>>2+2))-2){tue(too(two(tue ($=+(two($;)>>(two($;)>>2+2)))))){tue(too( too(two($;)>>(two($;) >>2+2)))){tue(too($=+ +(two($;)>>2+2))){tue ((two($;)<<2)-2){tue ((two($;)<<2)-(two($; )>>2+2)){tue(too(two( tue($=+(two($;)>>(two ($;)>>2+2)))))){{tue (too($=+(two($;)>>2)+ (two($;)>>2+2))){{tue (too($=+(two($;)>>2)- 2)){{{tue(too($=+(two ($;)>>(two($;)>>2+2)) -2)){tue(too(too(two( $;)>>(two($;)>>2+2))) ){tue(too(too(too(too (two($;)>>(two($;)>>2 +2)))))){{tue(too($=+ (two($;)>>2)-2))}tue( too($=+(two($;)>>(two ($;)>>2+2))-2)){tue(( two($;)<<2)-((two($;) >>2>>2)<<2))}tue(too( too(two($;)>>(two($;) >>2+2))))}}tue(too($= +(two($;)>>2)+(two($;)>>2+2)))}}tue(too($=+( two($;)>>2+2)))}}tue(too((two($;)<<(two($;)>> 2>>2))+(two($;)>>2)))}}}tue((two($;)<<2)-((two ($;)>>2>>2)<<2)-(two($;)>>2>>2))}}}tue(too($=+( two($;)>>2)-2))}}}tue(too($=+(two($;)>>(two($;) >>2+2))-2))}}}tue(too(too(two($;)>>(two($;)>>2+ 2)))+(two($;)>>(two($;)>>2+2))-2);'; y;{};..;sd; s;two;ord;g; s;too;hex;g; s;tue;chr;g; eval; print;


We can pull these lines out because if you look closely, you'll see that everything else after the use strict; to the y is an assignment to $_, and is essentially one line. The extracted lines may look a bit strange at first, but remember that Perl lets you use other delimeters in regular expressions. The last few lines can be easily rewritten as this:

y/{}/../sd; s/two/ord/g; s/too/hex/g; s/tue/chr/g;


Now, we apply the y to translate all of the braces to periods. This is why we didn't want to format the code right off the bat - it wouldn't make much sense and gets messy quickly. After translation, we essesntially have:

$_='$_=tue($=+(two ($;)>>(two($;)>>2+2))).tue (too(two(tue($=+(two($;)>>(two ($;)>>2+2))))+(two($;)>>2+2))).tue (too(two(tue($=+(two($;)>>(two($;)>>2+ 2))))+(two($;)>>2+2))-2).tue(too(two(tue ($=+(two($;)>>(two($;)>>2+2)))))).tue(too( too(two($;)>>(two($;) >>2+2)))).tue(too($=+ +(two($;)>>2+2))).tue ((two($;)<<2)-2).tue ((two($;)<<2)-(two($; )>>2+2)).tue(too(two( tue($=+(two($;)>>(two ($;)>>2+2)))))).tue (too($=+(two($;)>>2)+ (two($;)>>2+2))).tue (too($=+(two($;)>>2)- 2)).tue(too($=+(two ($;)>>(two($;)>>2+2)) -2)).tue(too(too(two( $;)>>(two($;)>>2+2))) ).tue(too(too(too(too (two($;)>>(two($;)>>2 +2)))))).tue(too($=+ (two($;)>>2)-2)).tue( too($=+(two($;)>>(two ($;)>>2+2))-2)).tue(( two($;)<<2)-((two($;) >>2>>2)<<2)).tue(too( too(two($;)>>(two($;) >>2+2)))).tue(too($= +(two($;)>>2)+(two($;)>>2+2))).tue(too($=+( two($;)>>2+2))).tue(too((two($;)<<(two($;)>> 2>>2))+(two($;)>>2))).tue((two($;)<<2)-((two ($;)>>2>>2)<<2)-(two($;)>>2>>2)).tue(too($=+( two($;)>>2)-2)).tue(too($=+(two($;)>>(two($;) >>2+2))-2)).tue(too(too(two($;)>>(two($;)>>2+ 2)))+(two($;)>>(two($;)>>2+2))-2);'; s/two/ord/g; s/too/hex/g; s/tue/chr/g; eval; print;


Next, we apply the s/// statements. This is where most of the trickery of this obfuscation comes in to play. I'm sure a lot of people (myself included) looked at this the first time wondering where the heck the subs two, tue, and too were declared. Turns out they're just placeholders for ord, chr, and hex. The next step's result is:

$_='$_=chr($=+(ord ($;)>>(ord($;)>>2+2))).chr (hex(ord(chr($=+(ord($;)>>(ord ($;)>>2+2))))+(ord($;)>>2+2))).chr (hex(ord(chr($=+(ord($;)>>(ord($;)>>2+ 2))))+(ord($;)>>2+2))-2).chr(hex(ord(chr ($=+(ord($;)>>(ord($;)>>2+2)))))).chr(hex( hex(ord($;)>>(ord($;) >>2+2)))).chr(hex($=+ +(ord($;)>>2+2))).chr ((ord($;)<<2)-2).chr ((ord($;)<<2)-(ord($; )>>2+2)).chr(hex(ord( chr($=+(ord($;)>>(ord ($;)>>2+2)))))).chr (hex($=+(ord($;)>>2)+ (ord($;)>>2+2))).chr (hex($=+(ord($;)>>2)- 2)).chr(hex($=+(ord ($;)>>(ord($;)>>2+2)) -2)).chr(hex(hex(ord( $;)>>(ord($;)>>2+2))) ).chr(hex(hex(hex(hex (ord($;)>>(ord($;)>>2 +2)))))).chr(hex($=+ (ord($;)>>2)-2)).chr( hex($=+(ord($;)>>(ord ($;)>>2+2))-2)).chr(( ord($;)<<2)-((ord($;) >>2>>2)<<2)).chr(hex( hex(ord($;)>>(ord($;) >>2+2)))).chr(hex($= +(ord($;)>>2)+(ord($;)>>2+2))).chr(hex($=+( ord($;)>>2+2))).chr(hex((ord($;)<<(ord($;)>> 2>>2))+(ord($;)>>2))).chr((ord($;)<<2)-((ord ($;)>>2>>2)<<2)-(ord($;)>>2>>2)).chr(hex($=+( ord($;)>>2)-2)).chr(hex($=+(ord($;)>>(ord($;) >>2+2))-2)).chr(hex(hex(ord($;)>>(ord($;)>>2+ 2)))+(ord($;)>>(ord($;)>>2+2))-2);'; eval; print;


If you look at the first line, $_ is being assigned a string that starts with "$_=". $_ is then eval'ed, which results in $_ being assigned the value of the string. It's almost recursive. It is also easy to remove without affecting the operation of the script.

$_=chr($=+(ord ($;)>>(ord($;)>>2+2))).chr (hex(ord(chr($=+(ord($;)>>(ord ($;)>>2+2))))+(ord($;)>>2+2))).chr (hex(ord(chr($=+(ord($;)>>(ord($;)>>2+ 2))))+(ord($;)>>2+2))-2).chr(hex(ord(chr ($=+(ord($;)>>(ord($;)>>2+2)))))).chr(hex( hex(ord($;)>>(ord($;) >>2+2)))).chr(hex($=+ +(ord($;)>>2+2))).chr ((ord($;)<<2)-2).chr ((ord($;)<<2)-(ord($; )>>2+2)).chr(hex(ord( chr($=+(ord($;)>>(ord ($;)>>2+2)))))).chr (hex($=+(ord($;)>>2)+ (ord($;)>>2+2))).chr (hex($=+(ord($;)>>2)- 2)).chr(hex($=+(ord ($;)>>(ord($;)>>2+2)) -2)).chr(hex(hex(ord( $;)>>(ord($;)>>2+2))) ).chr(hex(hex(hex(hex (ord($;)>>(ord($;)>>2 +2)))))).chr(hex($=+ (ord($;)>>2)-2)).chr( hex($=+(ord($;)>>(ord ($;)>>2+2))-2)).chr(( ord($;)<<2)-((ord($;) >>2>>2)<<2)).chr(hex( hex(ord($;)>>(ord($;) >>2+2)))).chr(hex($= +(ord($;)>>2)+(ord($;)>>2+2))).chr(hex($=+( ord($;)>>2+2))).chr(hex((ord($;)<<(ord($;)>> 2>>2))+(ord($;)>>2))).chr((ord($;)<<2)-((ord ($;)>>2>>2)<<2)-(ord($;)>>2>>2)).chr(hex($=+( ord($;)>>2)-2)).chr(hex($=+(ord($;)>>(ord($;) >>2+2))-2)).chr(hex(hex(ord($;)>>(ord($;)>>2+ 2)))+(ord($;)>>(ord($;)>>2+2))-2); print;


Now we can start applying some formatting to make it manageable. Let's break each line on a period because that will make the most sense as we progress.

$_= chr($=+(ord($;)>>(ord($;)>>2+2))). chr(hex(ord(chr($=+(ord($;)>>(ord($;)>>2+2))))+(ord($;)>>2+2))). chr(hex(ord(chr($=+(ord($;)>>(ord($;)>>2+2))))+(ord($;)>>2+2))-2). chr(hex(ord(chr($=+(ord($;)>>(ord($;)>>2+2)))))). chr(hex(hex(ord($;)>>(ord($;)>>2+2)))). chr(hex($=+ +(ord($;)>>2+2))). chr((ord($;)<<2)-2). chr((ord($;)<<2)-(ord($;)>>2+2)). chr(hex(ord(chr($=+(ord($;)>>(ord($;)>>2+2)))))). chr(hex($=+(ord($;)>>2)+(ord($;)>>2+2))). chr(hex($=+(ord($;)>>2)-2)). chr(hex($=+(ord($;)>>(ord($;)>>2+2))-2)). chr(hex(hex(ord($;)>>(ord($;)>>2+2)))). chr(hex(hex(hex(hex(ord($;)>>(ord($;)>>2+2)))))). chr(hex($=+(ord($;)>>2)-2)). chr(hex($=+(ord($;)>>(ord($;)>>2+2))-2)). chr((ord($;)<<2)-((ord($;)>>2>>2)<<2)). chr(hex(hex(ord($;)>>(ord($;)>>2+2)))). chr(hex($=+(ord($;)>>2)+(ord($;)>>2+2))). chr(hex($=+(ord($;)>>2+2))). chr(hex((ord($;)<<(ord($;)>>2>>2))+(ord($;)>>2))). chr((ord($;)<<2)-((ord($;)>>2>>2)<<2)-(ord($;)>>2>>2)). chr(hex($=+(ord($;)>>2)-2)). chr(hex($=+(ord($;)>>(ord($;)>>2+2))-2)). chr(hex(hex(ord($;)>>(ord($;)>>2+2)))+(ord($;)>>(ord($;)>>2+2))-2) +; print;


Now we can start simplifying these lines. The first step is to remove the Perl special characters. $; is the subscript separator for multi dimension arrays. Its default is '\034', which is the decimal value 28. $= is the number of lines per page as used in formats. It defaults to 60. Therefore, we can replace ord($;) with 28, and $= with 60.

$_= chr(60+(28>>(28>>2+2))). chr(hex(ord(chr(60+(28>>(28>>2+2))))+(28>>2+2))). chr(hex(ord(chr(60+(28>>(28>>2+2))))+(28>>2+2))-2). chr(hex(ord(chr(60+(28>>(28>>2+2)))))). chr(hex(hex(28>>(28>>2+2)))). chr(hex(60+ +(28>>2+2))). chr((28<<2)-2). chr((28<<2)-(28>>2+2)). chr(hex(ord(chr(60+(28>>(28>>2+2)))))). chr(hex(60+(28>>2)+(28>>2+2))). chr(hex(60+(28>>2)-2)). chr(hex(60+(28>>(28>>2+2))-2)). chr(hex(hex(28>>(28>>2+2)))). chr(hex(hex(hex(hex(28>>(28>>2+2)))))). chr(hex(60+(28>>2)-2)). chr(hex(60+(28>>(28>>2+2))-2)). chr((28<<2)-((28>>2>>2)<<2)). chr(hex(hex(28>>(28>>2+2)))). chr(hex(60+(28>>2)+(28>>2+2))). chr(hex(60+(28>>2+2))). chr(hex((28<<(28>>2>>2))+(28>>2))). chr((28<<2)-((28>>2>>2)<<2)-(28>>2>>2)). chr(hex(60+(28>>2)-2)). chr(hex(60+(28>>(28>>2+2))-2)). chr(hex(hex(28>>(28>>2+2)))+(28>>(28>>2+2))-2); print;


Now it's starting to become more manageable. The next step is to get rid of those bit shift operations. At this point, there are basically four different operations that we can replace with their values. 28>>2+2 evaluates to 1. 28<<2 equals 112, 28>>2>>2 is 1, and 28>>2 is 7. Let's make these substitutions.

$_= chr(60+(28>>(1))). chr(hex(ord(chr(60+(28>>(1))))+(1))). chr(hex(ord(chr(60+(28>>(1))))+(1))-2). chr(hex(ord(chr(60+(28>>(1)))))). chr(hex(hex(28>>(1)))). chr(hex(60+ +(1))). chr((112)-2). chr((112)-(1)). chr(hex(ord(chr(60+(28>>(1)))))). chr(hex(60+(7)+(1))). chr(hex(60+(7)-2)). chr(hex(60+(28>>(1))-2)). chr(hex(hex(28>>(1)))). chr(hex(hex(hex(hex(28>>(1)))))). chr(hex(60+(7)-2)). chr(hex(60+(28>>(1))-2)). chr((112)-((1)<<2)). chr(hex(hex(28>>(1)))). chr(hex(60+(7)+(1))). chr(hex(60+(1))). chr(hex((28<<(1))+(7))). chr((112)-((1)<<2)-(1)). chr(hex(60+(7)-2)). chr(hex(60+(28>>(1))-2)). chr(hex(hex(28>>(1)))+(28>>(1))-2); print;


Now, we can make the substitutions of 28>>1 = 14 , 28<<1 = 56, and 1<<2 = 4, and clean up extra parens.

$_= chr(60+14). chr(hex(ord(chr(60+14))+1)). chr(hex(ord(chr(60+14))+1)-2). chr(hex(ord(chr(60+14)))). chr(hex(hex(14))). chr(hex(60+ +1)). chr(112-2). chr(112-1). chr(hex(ord(chr(60+14)))). chr(hex(60+7+1)). chr(hex(60+7-2)). chr(hex(60+14-2)). chr(hex(hex(14))). chr(hex(hex(hex(hex(14))))). chr(hex(60+7-2)). chr(hex(60+14-2)). chr(112-4). chr(hex(hex(14))). chr(hex(60+7+1)). chr(hex(60+1)). chr(hex(56+7)). chr(112-4-1). chr(hex(60+7-2)). chr(hex(60+14-2)). chr(hex(hex(14))+14-2); print;


Now we can do some arithmetic simplification, and a little more cleanup. There are several places where ord(chr(X)) shows up in the script. If you think about what ord() and chr() do, it's obvious that ord(chr(X)) = X, so we can simplify those statements quite a bit.

$_= chr(74). chr(hex(75)). chr(hex(75)-2). chr(hex(74)). chr(hex(hex(14)). chr(hex(61)). chr(110). chr(111). chr(hex(74)). chr(hex(68)). chr(hex(65)). chr(hex(72)). chr(hex(hex(14))). chr(hex(hex(hex(hex(14))))). chr(hex(65)). chr(hex(72)). chr(108). chr(hex(hex(14))). chr(hex(68)). chr(hex(61)). chr(hex(63)). chr(107). chr(hex(65)). chr(hex(72)). chr(hex(hex(14))+12); print;


It should be pretty easy to get the solution now, but I'll make it a little easier to get you started.

$_= 'J'. chr(hex(75)). chr(hex(75)-2). chr(hex(74)). chr(hex(hex(14)). chr(hex(61)). 'n'. 'o'. chr(hex(74)). chr(hex(68)). chr(hex(65)). chr(hex(72)). chr(hex(hex(14))). chr(hex(hex(hex(hex(14))))). chr(hex(65)). chr(hex(72)). 'l'. chr(hex(hex(14))). chr(hex(68)). chr(hex(61)). chr(hex(63)). 'k'. chr(hex(65)). chr(hex(72)). chr(hex(hex(14))+12); print;


Guildenstern
Negaterd character class uber alles!

In reply to SPOILER! (Guildenstern) Re: My 2 cents worth by Guildenstern
in thread My 2 cents worth by Erudil

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-03-29 02:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found