Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

SPOILERS Re: *Poof *, and it's gone.

by jweed (Chaplain)
on Feb 13, 2004 at 04:14 UTC ( #328724=note: print w/replies, xml ) Need Help??

in reply to *Poof *, and it's gone.

Since deobfuscating obfus helps me learn, an explanation follows:
Let's get it into proper format first:
$g ='* * * * * Just another Perl hacker. * * * * *'; $t=length $g; sub h{ select $9,$8,$7,pop } $|++; $r="\r".' 'x$t; print $g; h(1); { h(.15); print " $r\r@{[' 'x(($t-length $g)/2)]}$g"; do { die"$r\n" }unless $g=~s/(.)(.)/($1,$2)[rand(2)]/gex; redo }
Line by line:
$g ='* * * * * Just another Perl hacker. * * * * *'; ; $t=length $g;
Sets string $g to the specified value, and sets $t to 48, the length of $g. So far so good.
sub h{ select $9,$8,$7,pop }
4-arg select does some funky stuff with filehandles, but if the first 3 arguments are undef (which they are here), it simply sleeps for the time (in seconds) specified by the fourth argument, which, in this case, is the first argument for h. So h sleeps for any number of seconds that its argument specifies.
Unbuffer the output, so characters show up on screen right as perl prints them.
$r="\r".' 'x$t; print $g;
Sets $r to a return character, followed by 48 spaces (the length of our JAPH string). Call this our clear string. A carriage return is NOT a newline. It brings the carriage to the beginning of a line but it does not advance the line. Thus, this string is effectively a "line clearer". Since the maximal string is only 48 characters, this string clears our line for all intents and purposes. Then, print the JAPH string.

h(1); { h(.15); print " $r\r@{[' 'x(($t-length $g)/2)]}$g";
Beginning the meat of the obfu here, we pause for one second, then begin a bare block which we will redo until certain conditions are met.

This bock begins by pausing for 1/6 of a second or so, and then prints our clear ($r) and returns to the beginning of the line. We have a blank line for printing. Now, it interpolates into the string a bunch of spaces, one for each two by which the current $g and its original length differ. Since we haven't changed $g yet, this is zero. Then we print the JAPH string.
do { die"$r\n" }unless $g=~s/(.)(.)/($1,$2)[rand(2)]/gex; redo
Let's examine the condition first: for every 2 characters in our japh string, we delete one. It now has a length of 48/2 = 24. If there are fewer than 2 characters left, then we die and print our clear string followed by a newline. Then, we go back to the blocks beginning to do it over. Let's look at the print statement for this next loop to get a feel for how it works:
print " $r\r@{[' 'x(($t-length $g)/2)]}$g";
Now, we print our control string and a return. Nothing new. But now, $t (the original length, 48) and length $g (the current length, 24), differ by 24, making it necessary to print 12 spaces at the beginning of the JAPH string. This has the effect of centering the string:
Since the orignal string was 48 characters, printing 12 spaces at the beginning of the string keeps 24 characters centered in this 48 character "box". Rinse and repeat, halving the number of characters each time.

And that's it. The spaces keep it centered, and Kaiser JAPHy is never seen again.

Code is (almost) always untested.

Replies are listed 'Best First'.
Re: SPOILERS Re: *Poof *, and it's gone.
by davido (Cardinal) on Feb 13, 2004 at 05:39 UTC
    Congratulations, you're 100% correct. I really think it takes about ten times more patience to deobfuscate one of these things than it does to dream it up. I'm flattered you were intregued enough to tackle it.

    Good job.


Log In?

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

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2018-10-17 23:29 GMT
Find Nodes?
    Voting Booth?
    When I need money for a bigger acquisition, I usually ...

    Results (99 votes). Check out past polls.