Here's the code I used to generate this obfu.
First, I've written the algorithm in perl:
#!perl
use warnings;
use strict;
my @a = unpack "U*", `cat part3.txt` . pack "x";
my($b, $k, $c, $s);
use integer;
$k = 0;
goto F;
J:
#print "[J]";
64 < $c and goto W;
$b = $k;
F:
#print "[F";
$c = $a[$k];
#print chr($c) . "]";
$k += 1;
0 < $c and goto J;
#print "[0]\n";
exit;
W:
#print "[W]";
$s = 14;
S:
$c *= 4;
$s -= 1;
0 < $s and goto S;
0 < $c and goto F;
$c < 0 and goto F;
P:
#print "[P]";
$c = $a[$b];
print chr($c);
$b += 1;
$b < $k and goto P;
T:
#print "[T]";
$c = $a[$k];
64 < $c and goto C;
print chr(10);
goto F;
C:
#print "[C]";
print chr($c);
$k += 1;
goto T;
__END__
Then I transcoded that to an assembly language for the virtual machine the obfu interprets. This code, when ran with ruby, will assemble the obfu and write it to the file named "pie".
#!/home/ambrus/local/devel/bin/ruby -w
src = %{
?
ip: F
lt: ? !_
print: ?
buf: ?
t: ?
u: ?
_c: ?
_k: -Input
_b: ?
s: ?
$0: 0
$1: 1
$_1: -1
$_10: -10
$_14: -14
$64: 64
$_64: -64
J:
!buf buf buf $_lbrace print $1 print print buf buf buf $_karJ pr
+int $1 print print buf buf buf $_rbrace print $1 print print
u u u _c t t t u 1> 1> t $_64 1> lt 1: ? W1$W W1:
t t t _k _b _b _b t
F:
!buf buf buf $_lbrace print $1 print print buf buf buf $_karF pr
+int $1 print print
1> 1> 1> _k _c _c _c 1: ?
!buf buf buf _c print $1 print print buf buf buf $_rbrace print
+$1 print print
_k $1
1> 1> _c $0 1> lt 1: ? J1$J J1:
!buf buf buf $_lbrace print $1 print print buf buf buf $_kar0 pr
+int $1 print print buf buf buf $_rbrace print $1 print print bu
+f buf buf $_10 print $1 print print
ip Ex1$0 Ex1:
W:
!buf buf buf $_lbrace print $1 print print buf buf buf $_karW pr
+int $1 print print buf buf buf $_rbrace print $1 print print
s s s $_14
S:
t t t _c t _c _c _c _c t _c t
s $1
t t 1> 1> t s 1> lt 1: ? S1$S S1:
1> 1> _c $0 1> lt 1: ? F1$F F1:
t t 1> 1> t _c 1> lt 1: ? F2$F F2:
P:
!buf buf buf $_lbrace print $1 print print buf buf buf $_karP pr
+int $1 print print buf buf buf $_rbrace print $1 print print
1> 1> 1> _b _c _c _c 1: ?
buf buf buf _c print $1 print print
_b $1
u u u _k t t t _b 1> 1> t u 1> lt 1: ? P1$P P1:
T:
!buf buf buf $_lbrace print $1 print print buf buf buf $_karT pr
+int $1 print print buf buf buf $_rbrace print $1 print print
1> 1> 1> _k _c _c _c 1: ?
u u u _c t t t $_64 1> 1> t u 1> lt 1: ? C1$C C1:
buf buf buf $_10 print $1 print print
ip F3$F F3:
C:
!buf buf buf $_lbrace print $1 print print buf buf buf $_karC pr
+int $1 print print buf buf buf $_rbrace print $1 print print
buf buf buf _c print $1 print print
_k $1
ip T1$T T1:
W1$W: W1-W
J1$J: J1-J
Ex1$0: Ex1-0
F1$F: F1-F
F2$F: F2-F
F3$F: F3-F
P1$P: P1-P
C1$C: C1-C
T1$T: T1-T
S1$S: S1-S
!$_lbrace: -'[' $_rbrace: -']'
!$_karJ: -'J' $_karF: -'F' $_karW: -'W'
!$_karP: -'P' $_karT: -'T' $_karC: -'C' $_kar0: -'0'
Input:
};
def val e, sgn, adr = @code.size;
case e;
when /^(-?\d+)$/;
$1.to_i;
when /^'(.)'$/;
$1[0];
when /^\?$/;
0;
when /^([\w@%$.]+)<$/;
@labels[$1] or
fail "back reference not found: #{$1}";
when /^([\w@%$.]+)>$/;
(@forward[$1] ||= []).push [adr, sgn];
0;
when /^([\w@%$.]+)$/;
@labels[$1] or (
(@forward[$1] ||= []).push [adr, sgn];
0;
);
else
fail %Q'expr error: "#{e}"';
end;
end;
@code = [];
@labels = Hash[];
@forward = Hash[];
@literal = Hash[];
src.gsub!(/[#!].*/) {""};
src.scan(/(\S+)/) {
tok = $1;
if tok =~ /^([\w@%$.]+):$/;
@labels[$1] = @code.size;
(f = @forward[$1]) and
f.each {|fr|
(a, sgn) = fr;
@code[a] = sgn * @code.size;
};
@forward.delete($1);
else
r = 0;
tok.scan(/\G(?:(?:(-)|\+|)([^+\-]+)|(.))/) {
$3 and
fail "toke error 2";
sgn = (if $1; -1 else 1 end);
r += sgn * val($2, sgn);
};
@code.push r;
end;
};
@forward.empty? or
fail "forward reference not found: #{@forward.keys[0]}";
fh = File.open("pie", "w");
fh.print(%{#!perl
use warnings; use strict; use integer;
for(my@a=(
});
@code.each {|n|
Integer === n or
fail "internal error: invalid code";
fh.print n, ","
};
fh.print(%{
unpack"U*",`cat part3.txt`.v0);
$a[1];$a[3]&&print chr$a[4]){$a[2]=-(($a[$a[$a[1]++]]-=$a[$a[$a[1]++]]
+)<0)}
});
fh.close;
warn "" + @code.size.to_s + " words";
__END__
-
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.