我正在尝试对以下Perl代码进行反混淆处理(source):
#!/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
,{{1 }和2
。
我通常使用Python编写代码,因此这将转换为Python中的字典3
。
{'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
现在是否类似于Python中的$p
?
[['A'], ['T'], ['C'], ['G']]
只要 while ( $d =~ /([$p]{4})/g ) {
匹配$d
,就执行while块中的代码。但由于我不完全理解([$p]{4})
是什么结构,我也很难理解这里发生的事情。
$p
如果next if $j++ % 96 >= 16;
模96大于或等于16,则继续。$j
随着while循环(?)的每次传递递增。
$j
对于从$c = 0;
foreach $d ( 0 .. 3 ) {
$c += $a{ substr $1, $d, 1 } * 4**$d;
}
到$d
范围内的0
提取一些子字符串,但此时我完全迷失了。最后几行连接所有内容并评估结果。
答案 0 :(得分:50)
警告:不要盲目地运行混淆的perl,特别是如果有eval
,反引号,system
,open
等,请在其中的某处调用,这可能不太明显 * 。使用Deparse
对其进行去模糊处理并小心地用打印语句替换eval
是必须的,直到您了解正在发生的事情为止。应该考虑在沙箱中运行/使用非特权用户/在VM中运行。
* s&&$_ⅇ
评估$_
的情况。
首先观察:034
是八进制。它等于28(十进制)或0x1c(十六进制),所以没有什么可钓的。
$;
事情纯粹是混淆,找不到特别使用它的理由。 $p
只是一个字符串A.T.C.G
(.
取代$;
,无论它是什么)。
因此,正则表达式[$p]
匹配任何{'A', 'T', 'C', 'G', $;}
。由于$;
永远不会出现$d
,因此在那里无用。
反过来[$p]{4}
匹配上面集合中任意四个字母的序列,就像使用了它一样(忽略无用的$;
):
while ( $d =~ /([ATCG]{4})/g ) { ... }
如果你必须自己写这个,删除空格后,你只需抓住长度为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的按位左移。
因此,这个有趣的构造允许您在基数为4的系统中构建任何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转换器,你可以用它来产生任何东西来代替螺旋(不处理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
代替螺旋(并删除解码器中的跳过部分)。