It is parametised so it will take the number of boxes in the output as an argument in the form:
# perl blah.pl 19x20
(19x20 is the default)
This will produce a file call al.avi in the directory from which it is run
$_=q^($w,$h)=s
plit/x/,shift||"19x20";$q=10+10*$w;$r=20+10*$h;@m=((31,(15)x
($w-1))x$h,(31)x$w);$m[$c]|=16,!(@a=grep!($m[$c+$$_[0]]&16+$|*$$_[1]),[-
1,8],[1,1],[$w,4],[-$w,2])?$c=pop@p:${($i,$j)=@{$a[rand@a
]};$m[$c]&=~
8/$j;push@p,$c;$m[$c+=$i]&=~$j;++$u-$h*$w+$h||map$_&=15,@m,splice(@p),$c
=$|=1}until$|&$c+2>$w*$h;$C=$q-4*int$q/4;$A=($q+$C)*$r;$u=pack"x"x(($q+$
C)*$r);subZd{my($f,$g,$h,$i,$e)=@_;@a=sort{"000$a"<=>"000$b"}$h,$i||$h;f
or($a[0]..$a[1]){$s=($r-$_)*($q+$C)+$f;vec($u,$_,8)=$e||2for$s..$s+$g-1}
};subZt{$a=shift;$x=10*($a%$w);$y=10*(2+int$a/$w)};dZ9,$q-20,10;dZ9,$q-2
0,$r-10;dZ9,1,10,$r-10;dZ$q-11,1,10,$r-10;map{t$_;if($_%$w){$m[$_]&2?d$x
-1,11,$y:"";$m[$_]&8?d$x+9,1,$y-10,$y:"";}}0..-1+$w*$h;$F="LIST";open(FH
,">al.avi");binmodeZFH;selectZFH;printZpack"L*",/\d/?$_:unpack"L*",$_Zfo
r"RIFF",(1256+($A+24)*($B=3+scalar@p)),"AVIZ$F",1216,"hdrlavih",56,50000
0,32,0,2064,$B,0,1,$A,$q,$r,(0)x4,$F,1140,"strlstrh",56,"vids",(0)x4,1,1
0,0,$B,$A,-1,(0)x3,"strf",1064,40,$q,$r,pack("SS",1,8),0,$A,(0)x4,pack((
"H"x1024),"f","f","f",0,"a"),$F,(4+($A+8)*$B),"movi";map{printZSTDOUTZ++
$G,$/;t$z||1;$l=$x;$t=$y;t$_;$ri=$x;if($l>$x){$ri=$l;$l=$x}d$l+2,5+$ri-$
l,($t<$y?$t:$y)-7,($t<$y?$y:$t)-3,1;$z=$_;print"00db".pack("L",$A).$u}@p
,(-1+$w*$h)x3;print"idx1".pack"L",16*$B;$o=4;for(1..$B){print"00db".pack
"LLL",16,$o,$A;$o+=$A+8}^;s#((?{$a.=$+})\s?(\S*)\s?)*#$a=~s/Z/ /g;$a#see
(that's supposed to be a movie frame clap board btw!)I've tested the output in windows media player and mplayer (on windows and linux), however i couldn't get it working with winamp - i tried to fix it, but i'm not entirely sure it's not winamp.
If there is enough interest i'll write a deobfuscation/explanation of what went into it, in the meantime here are some of my references:
I hope you all enjoy it.
Alex
Let me take a crack at deobfuscation ...
Ah yes, there it is; near the end of the program is the regular expression substitution (with a double evaluation):
I'm particularly impressed with the way you write directly to the .avi file. I'm going to definitely study how to do that, so I can make use of it in my own code!
% perl -MO=Deparse movies > movies1
% vi movies1
% cat movies1
$_ = qq[(\$w,\$h)=split/x/,shift||"19x20";
\$q=10+10*\$w;
\$r=20+10*\$h;
\@m=((31,(15\n )x(\$w-1))x\$h,(31)x\$w);
\$m[\$c]|=16,!(\@a=grep!(\$m[\$c+\$\$_[0]]&16+\$|*\$\$_[1]),\n [- 1,8],[1,1],[\$w,4],[-\$w,2])?\$c=pop\@p:\${(\$i,\$j)=\@{\$a[rand\@a]};
\$m[\$c]&=~\n 8/\$j;
push\@p,\$c;
\$m[\$c+=\$i]&=~\$j;
++\$u-\$h*\$w+\$h||map\$_&=15,\@m,splice(\@p),\$c\n =\$|=1}until\$|&\$c+2>\$w*\$h;
\$C=\$q-4*int\$q/4;
\$A=(\$q+\$C)*\$r;
\$u=pack"x"x((\$q+\$\n C)*\$r);
subZd{my(\$f,\$g,\$h,\$i,\$e)=\@_;
\@a=sort{"000\$a"<=>"000\$b"}\$h,\$i||\$h;
f\n or(\$a[0]..\$a[1]){\$s=(\$r-\$_)*(\$q+\$C)+\$f;
vec(\$u,\$_,8)=\$e||2for\$s..\$s+\$g-1}\n };
subZt{\$a=shift;
\$x=10*(\$a%\$w);
\$y=10*(2+int\$a/\$w)};
dZ9,\$q-20,10;
dZ9,\$q-2\n 0,\$r-10;
dZ9,1,10,\$r-10;
dZ\$q-11,1,10,\$r-10;
map{t\$_;
if(\$_%\$w){\$m[\$_]&2?d\$x\n -1,11,\$y:"";
\$m[\$_]&8?d\$x+9,1,\$y-10,\$y:"";
}}0..-1+\$w*\$h;
\$F="LIST";
open(FH\n ,">al.avi");
binmodeZFH;
selectZFH;
printZpack"L*",/\\d/?\$_:unpack"L*",\$_Zfo\n r"RIFF",(1256+(\$A+24)*(\$B=3+scalar\@p)),"AVIZ\$F",1216,"hdrlavih",56,50000\n 0,32,0,2064,\$B,0,1,\$A,\$q,\$r,(0)x4,\$F,1140,"strlstrh",56,"vids",(0)x4,1,1\n 0,0,\$B,\$A,-1,(0)x3,"strf",1064,40,\$q,\$r,pack("SS",1,8),0,\$A,(0)x4,pack((\n "H"x1024),"f","f","f",0,"a"),\$F,(4+(\$A+8)*\$B),"movi";
map{printZSTDOUTZ++\n \$G,\$/;
t\$z||1;
\$l=\$x;
\$t=\$y;
t\$_;
\$ri=\$x;
if(\$l>\$x){\$ri=\$l;
\$l=\$x}d\$l+2,5+\$ri-\$\n l,(\$t<\$y?\$t:\$y)-7,(\$t<\$y?\$y:\$t)-3,1;
\$z=\$_;
print"00db".pack("L",\$A).\$u}\@p\n ,(-1+\$w*\$h)x3;
print"idx1".pack"L",16*\$B;
\$o=4;
for(1..\$B){print"00db".pack\n "LLL",16,\$o,\$A;
\$o+=\$A+8}];
s[((?{$a.=$+})\s?(\S*)\s?)*][$a =~ s/Z/ /g; $a; ]see;
I knew you were writing to an .avi file (I didn't know you could do that ... very slick!), so I found the open statement: open(FH\n ,">al.avi");. But on the very next 2 lines: binmodeZFH; and selectZFH;. So you clearly had to be doing some processing on the string before using it.
s[((?{$a.=$+})\s?(\S*)\s?)*][$a =~ s/Z/ /g; $a; ]see;
So the next step is to drop one of the evaluations, and print the string *before* it would have been executed. This can even be done on the original program with some Unix pipes, and two calls to sed. (One call converts the double-evaluation to a single evaluation, and prints the string representing the innermost program instead of executing it. The second call simply changes semicolons to newlines to make the program readable):
% perl -MO=Deparse movies | sed s/see/se\;print/ | perl | sed s/\;/\;\\n/g
($w,$h)=split/x/,shift||"19x20";
$q=10+10*$w;
$r=20+10*$h;
@m=((31,(15)x($w-1))x$h,(31)x$w);
$m[$c]|=16,!(@a=grep!($m[$c+$$_[0]]&16+$|*$$_[1]),[-1,8],[1,1],[$w,4],[-$w,2])?$c=pop@p:${($i,$j)=@{$a[rand@a]};
$m[$c]&=~8/$j;
push@p,$c;
$m[$c+=$i]&=~$j;
++$u-$h*$w+$h||map$_&=15,@m,splice(@p),$c=$|=1}until$|&$c+2>$w*$h;
$C=$q-4*int$q/4;
$A=($q+$C)*$r;
$u=pack"x"x(($q+$C)*$r);
sub d{my($f,$g,$h,$i,$e)=@_;
@a=sort{"000$a"<=>"000$b"}$h,$i||$h;
for($a[0]..$a[1]){$s=($r-$_)*($q+$C)+$f;
vec($u,$_,8)=$e||2for$s..$s+$g-1}};
sub t{$a=shift;
$x=10*($a%$w);
$y=10*(2+int$a/$w)};
d 9,$q-20,10;
d 9,$q-20,$r-10;
d 9,1,10,$r-10;
d $q-11,1,10,$r-10;
map{t$_;
if($_%$w){$m[$_]&2?d$x-1,11,$y:"";
$m[$_]&8?d$x+9,1,$y-10,$y:"";
}}0..-1+$w*$h;
$F="LIST";
open(FH,">al.avi");
binmode FH;
select FH;
print pack"L*",/\d/?$_:unpack"L*",$_ for"RIFF",(1256+($A+24)*($B=3+scalar@p)),"AVI $F",1216,"hdrlavih",56,500000,32,0,2064,$B,0,1,$A,$q,$r,(0)x4,$F,1140,"strlstrh",56,"vids",(0)x4,1,10,0,$B,$A,-1,(0)x3,"strf",1064,40,$q,$r,pack("SS",1,8),0,$A,(0)x4,pack(("H"x1024),"f","f","f",0,"a"),$F,(4+($A+8)*$B),"movi";
map{print STDOUT ++$G,$/;
t$z||1;
$l=$x;
$t=$y;
t$_;
$ri=$x;
if($l>$x){$ri=$l;
$l=$x}d$l+2,5+$ri-$l,($t<$y?$t:$y)-7,($t<$y?$y:$t)-3,1;
$z=$_;
print"00db".pack("L",$A).$u}@p,(-1+$w*$h)x3;
print"idx1".pack"L",16*$B;
$o=4;
for(1..$B){print"00db".pack"LLL",16,$o,$A;
$o+=$A+8}
at which point the functionality of the program becomes decipherable.
CountZero
"If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
perlmonks.org content © perlmonks.org and Akhasha, CountZero, eric256, liverpole, marto, mikeock, parv, teamster_jr, wulvrine
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03