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

SPOILER! (Guildenstern)Re: How to (ab)use substr

by Guildenstern (Deacon)
on May 03, 2001 at 21:25 UTC ( #77723=note: print w/ replies, xml ) Need Help??


in reply to How to (ab)use substr

Update: *sigh* Apparently, the READMORE tag has some issues. My apologies to all for the long post.

Well, this is the first obfu from Erudil that I was able to decipher, so I thought I'd break it down and write the spoiler.


#!/usr/bin/perl -w # how to (ab)use substr use strict; my $pi='3.14159210535152623346475240375062163750446240333543375062'; substr ($^X,0)= substr ($pi,-6);map{ substr ($^X,$.++,1)=chr( substr($pi,21,2)+ substr($pi,$_,2))}(12,28,-18,-6,-10,14);map{$^O=$"x( substr ($pi,-5,2)); substr ($^O,sin(++$a/8)*32+ substr ($pi,-2)/2+1,1)=$_; substr ($^O,sin($a/4)*( substr ($pi,2,2))+ substr ($pi,-7,-5)-1,1)=$_;print"$^O$/";eval($^X.('$b,'x3). substr ($pi,-3,1).'.'. substr ($pi,9,2));}(map{chr($_+ substr ($pi,21,2))}( substr ($pi,8)x3)=~/../g);


Let's clean up the formatting a bit first:

substr($^X,0)=substr($pi,-6); map{ substr($^X,$.++,1)=chr( substr($pi,21,2)+ substr($pi,$_,2)) }(12,28,-18,-6,-10,14); map{ $^O=$"x(substr ($pi,-5,2)); substr($^O,sin(++$a/8)*32+ substr($pi,-2)/2+1,1)=$_; substr($^O,sin($a/4)*( substr($pi,2,2))+ substr($pi,-7,-5)-1,1)=$_; print"$^O$/"; eval($^X.('$b,'x3). substr($pi,-3,1).'.'. substr($pi,9,2)); }(map{ chr($_+ substr($pi,21,2)) }(substr($pi,8)x3)=~/../g);


Let's remove some of the pesky maps

substr($^X,0)=substr($pi,-6); foreach (12,28,-18,-6,-10,14) { substr($^X,$.++,1)=chr( substr($pi,21,2)+ substr($pi,$_,2)); } # We need this for the moment to get # rid of the second map below. # Don't worry, it goes away. my @tempa; foreach (substr($pi,8)x3)=~/../g) { push(@tempa,chr($_+substr($pi,21,2))); } map{ $^O=$"x(substr ($pi,-5,2)); substr($^O,sin(++$a/8)*32+ substr($pi,-2)/2+1,1)=$_; substr($^O,sin($a/4)*( substr($pi,2,2))+ substr($pi,-7,-5)-1,1)=$_; print"$^O$/"; eval($^X.('$b,'x3). substr($pi,-3,1).'.'. substr($pi,9,2)); }(@tempa);


Now, most of the substr($pi,....) statements return the same value each time. Let's just replace those statements with their values.

substr($^X,0)=375062; foreach (12,28,-18,-6,-10,14) { substr($^X,$.++,1)=chr( 64+ substr($pi,$_,2)); } # We need this for the moment to get # rid of the second map below. # Don't worry, it goes away. my @tempa; foreach (substr($pi,8)x3)=~/../g) { push(@tempa,chr($_+64)); } map{ $^O=$"x(75); substr($^O,sin(++$a/8)*32+ 62/2+1,1)=$_; substr($^O,sin($a/4)*( 14)+ 33-1,1)=$_; print"$^O$/"; eval($^X.('$b,'x3). 0.'.'. 05); }(@tempa);


If we look at the first foreach, we can see that we are replacing the numerical values of $^X with character values, one by one. The resulting value of $^X is 'select', so we can eliminate the first foreach entirely (and do some more tidying).

$^X="select"; # We need this for the moment to get # rid of the second map below. # Don't worry, it goes away. my @tempa; foreach (substr($pi,8)x3)=~/../g) { push(@tempa,chr($_+64)); } map{ $^O=$"x75; substr($^O,sin(++$a/8)*32+32,1)=$_; substr($^O,sin($a/4)*14+32,1)=$_; print"$^O$/"; eval($^X.('$b,'x3).'0.05'); }(@tempa);


Now, we can finally get rid of that last pesky map statement.

$^X="select"; foreach (substr($pi,8)x3)=~/../g) { $_ = chr($_+64); $^O=$"x75; substr($^O,sin(++$a/8)*32+32,1)=$_; substr($^O,sin($a/4)*14+32,1)=$_; print"$^O$/"; eval($^X.('$b,'x3).'0.05'); }


Just for the sake of simplification, let's remove that eval statement as well, since it's really a select.

foreach (substr($pi,8)x3)=~/../g) { $_ = chr($_+64); $^O=$"x75; substr($^O,sin(++$a/8)*32+32,1)=$_; substr($^O,sin($a/4)*14+32,1)=$_; print"$^O$/"; select $b,$b,$b,0.05; }


Now it's fairly simple to tell what's going on. To make it even easier to see, let's replace the expression in the foreach. The combination of substr($pi,8)x3=~/../g and the $_ = chr($_+64) results in the string "Just~another~Perl~hacker~" repeated three times. Let's just add that to the foreach and clean up a bit more.

foreach (("Just~another~Perl~hacker~"x3)=~/./g) { $^O=$"x75; substr($^O,sin(++$a/8)*32+32,1)=$_; substr($^O,sin($a/4)*14+32,1)=$_; print"$^O$/"; select $b,$b,$b,0.05; }


That's about all we can do. From here, it should be fairly simple to divine what's happening. $^O gets set to 75 spaces. Then, the position of the next characters are determined by the sin function and placed into $^O with the substr. $^O is then printed followed by the local line-break character. The script then sleeps for 5 ms before printing the next line.

I hope I gave a good explanation. I know I skipped over several steps, but it should be apparent from step to step what I've changed. Anything that didn't change I didn't include from the original script. Yes $pi was tampered with, but I'd only expect PM users to notice that it's only good to the first 5 digits. :)

Guildenstern
Negaterd character class uber alles!


Comment on SPOILER! (Guildenstern)Re: How to (ab)use substr
Select or Download Code

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (10)
As of 2015-07-02 12:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (36 votes), past polls