如何正确解析Perl脚本?
我试图反混淆以下Perl代码(source):如何正确解析Perl脚本?
#!/usr/bin/perl
(my$d=q[AA GTCAGTTCCT
CGCTATGTA ACACACACCA
TTTGTGAGT ATGTAACATA
CTCGCTGGC TATGTCAGAC
AGATTGATC GATCGATAGA
ATGATAGATC GAACGAGTGA
TAGATAGAGT GATAGATAGA
GAGAGA GATAGAACGA
TC GATAGAGAGA
TAGATAGACA G
ATCGAGAGAC AGATA
GAACGACAGA TAGATAGAT
TGAGTGATAG ACTGAGAGAT
AGATAGATTG ATAGATAGAT
AGATAGATAG ACTGATAGAT
AGAGTGATAG ATAGAATGAG
AGATAGACAG ACAGACAGAT
AGATAGACAG AGAGACAGAT
TGATAGATAG ATAGATAGAT
TGATAGATAG AATGATAGAT
AGATTGAGTG ACAGATCGAT
AGAACCTTTCT CAGTAACAGT
CTTTCTCGC TGGCTTGCTT
TCTAA CAACCTTACT
G ACTGCCTTTC
TGAGATAGAT CGA
TAGATAGATA GACAGAC
AGATAGATAG ATAGAATGAC
AGACAGAGAG ACAGAATGAT
CGAGAGACAG ATAGATAGAT
AGAATGATAG ACAGATAGAC
AGATAGATAG ACAGACAGAT
AGACAGACTG ATAGATAGAT
AGATAGATAG AATGACAGAT
CGATTGAATG ACAGATAGAT
CGACAGATAG ATAGACAGAT
AGAGTGATAG ATTGATCGAC
TGATTGATAG ACTGATTGAT
AGACAGATAG AGTGACAGAT
CGACAGA TAGATAGATA
GATA GATAGATAG
ATAGACAGA G
AGATAGATAG ACA
GTCGCAAGTTC GCTCACA
])=~s/\s+//g;%a=map{chr $_=>$i++}65,84,67,
71;$p=join$;,keys%a;while($d=~/([$p]{4})/g
){next if$j++%96>=16;$c=0;for$d(0..3){$c+=
$a{substr($1,$d,1)}*(4**$d)}$perl.=chr $c}
eval $perl;
运行时,它打印出Just another genome hacker.
运行代码低谷Deparse
和perltidy
(perl -MO=Deparse jagh.pl | perltidy
)的代码如下所示后:
(my $d =
"AA...GCTCACA\n" # snipped double helix part
) =~ s/\s+//g;
(%a) = map({ chr $_, $i++; } 65, 84, 67, 71);
$p = join($;, keys %a);
while ($d =~ /([$p]{4})/g) {
next if $j++ % 96 >= 16;
$c = 0;
foreach $d (0 .. 3) {
$c += $a{ substr $1, $d, 1 } * 4**$d;
}
$perl .= chr $c;
}
这是我能够自己破译的。
(my $d =
"AA...GCTCACA\n" # snipped double helix part
) =~ s/\s+//g;
删除$d
(双螺旋)中的所有空白。
(%a) = map({ chr $_, $i++; } 65, 84, 67, 71);
使得散列与作为键A
,T
,C
和G
和作为值0
,1
,2
和3
。 我通常使用Python编码,因此这转换为Python中的字典{'A': 0, 'B': 1, 'C': 2, 'D': 3}
。
$p = join($;, keys %a);
加入与$;
的subscript separator for multidimensional array emulation哈希的键。该文件说,默认是“\ 034”,在AWK一样SUBSEP,但是当我做:
my @ascii = unpack("C*", $p);
print @ascii[1];
我得到的价值28
?此外,我不清楚这是如何模拟多维阵列。现在是$p
在Python中是什么样的[['A'], ['T'], ['C'], ['G']]
?
while ($d =~ /([$p]{4})/g) {
只要$d
比赛,在块而执行该代码。但由于我不完全了解什么结构$p
是,我也很难理解这里发生了什么。
next if $j++ % 96 >= 16;
继续,如果该模$j
96大于或等于16 $j
增量while循环的每次通过(?)。
$c = 0;
foreach $d (0 .. 3) {
$c += $a{ substr $1, $d, 1 } * 4**$d;
}
对于从0
范围$d
到3
提取一些子,但在这一点上,我完全失去了。最后几行连接所有内容并评估结果。
注意:不要盲目的跑混淆perl的,尤其是如果有一个eval
,反引号,system
,open
,等它打电话的地方,并可能不是太明显*。使用Deparse
对其进行去混淆处理,并且仔细地用打印语句替换eval
是必须的,直到您明白发生了什么为止。应该考虑在沙箱/非特权用户/在虚拟机中运行。
*s&&$_ⅇ
评估$_
为intance。
第一观察:034
是八进制。它等于28(十进制)或0x1c(十六进制),所以没有什么可怕的。
$;
事情纯属迷惑,特别是找不到理由。 $p
将只是一个字符串A.T.C.G
(而.
取代$;
,无论它是什么)。
所以在正则表达式[$p]
匹配{'A', 'T', 'C', 'G', $;}
中的任何一个。由于$;
从来没有出现在$d
,那里没用。 反过来[$p]{4}
四个字母的顺序匹配上面的设置,仿佛这已经使用(忽略无用$;
):
while ($d =~ /([ATCG]{4})/g) { ... }
如果你不得不写这个自己,在去除空白后,你” d只需抓取长度为4的$d
的每个连续子字符串(假设$d
中没有其他字符)。
现在,这部分很有趣:
foreach $d (0 .. 3) {
$c += $a{ substr $1, $d, 1 } * 4**$d;
}
-
$1
保持当前的四个字母的代码点。substr $1, $d, 1
返回该码点的每个连续字母。 -
%a
映射A
为00b(二进制),T
到01B,C
到10b和G
为11b。A 00 T 01 C 10 G 11
通过
4**$d
乘以将相当于0,2,4和6
逐位左移位所以这个有趣的结构允许你在碱基构建任何8位值四个系统以ATCG
作为数字!
即它执行以下操作的转换:
A A A A
AAAA -> 00000000
T A A T
TAAT -> 01000001 -> capital A in ascii
T A A C
CAAT -> 01000010 -> capital B in ascii
CAATTCCTGGCTGTATTTCTTTCTGCCT -> BioGeek
这部分:
next if $j++ % 96 >= 16;
使得上面的转换运行仅对于第一个16“码点”,跳过接下来的80,然后将其转换为接下来的16个,跳过下一个80个,等等。它基本上只是跳过椭圆的一部分(垃圾DNA去除系统)。
这里是一个丑陋的文字DNA转换器,你可以用它来生产任何东西来代替螺旋(不处理80跳跃的东西):
use strict;
use warnings;
my $in = shift;
my %conv = (0 => 'A', 1 => 'T', 2 => 'C', 3 => 'G');
for (my $i=0; $i<length($in); $i++) {
my $chr = substr($in, $i, 1);
my $chv = ord($chr);
my $encoded ="";
$encoded .= $conv{($chv >> 0) & 0x3};
$encoded .= $conv{($chv >> 2) & 0x3};
$encoded .= $conv{($chv >> 4) & 0x3};
$encoded .= $conv{($chv >> 6) & 0x3};
print $encoded;
}
print "\n";
$ perl q.pl 'print "BioGeek\n";'
AAGTCAGTTCCTCGCTATGTAACACACACAATTCCTGGCTGTATTTCTTTCTGCCTAGTTCGCTCACAGCGA
杖$d
,而不是螺旋线(并删除解码器中的跳过部分)。
真棒问题。 – Rayfleck 2012-02-18 14:55:16
你应该小心处理'eval'混淆字符串的代码。我在这里看到了一个迂回的问题,它以一个字符串的eval结尾的“rm -rf /”'结尾。 – TLP 2012-02-18 15:00:20
提醒我[Acme :: EyeDrops](http://p3rl.org/Acme::EyeDrops)。 – 2012-02-19 15:13:57