Bio*_*eek 55 perl deobfuscation
我正在尝试反混淆以下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;
Run Code Online (Sandbox Code Playgroud)
运行时,会打印出来 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;
}
Run Code Online (Sandbox Code Playgroud)
这就是我自己能够解读的内容.
( my $d =
"AA...GCTCACA\n" # snipped double helix part
) =~ s/\s+//g;
Run Code Online (Sandbox Code Playgroud)
删除$d
(双螺旋)中的所有空格.
(%a) = map( { chr $_, $i++; } 65, 84, 67, 71 );
Run Code Online (Sandbox Code Playgroud)
使得散列与作为键A
,T
,C
和G
和作为值0
,1
,2
和3
.我通常使用Python编写代码,因此这将转换为{'A': 0, 'B': 1, 'C': 2, 'D': 3}
Python中的字典.
$p = join( $;, keys %a );
Run Code Online (Sandbox Code Playgroud)
加入与散列的键$;
的下标分离器,用于多维数组仿真.文档说默认为"\ 034",与awk中的SUBSEP相同,但是当我这样做时:
my @ascii = unpack("C*", $p);
print @ascii[1];
Run Code Online (Sandbox Code Playgroud)
我得到了价值28
?此外,我不清楚这是如何模拟多维数组的.是$p
现在有点像[['A'], ['T'], ['C'], ['G']]
在Python?
while ( $d =~ /([$p]{4})/g ) {
Run Code Online (Sandbox Code Playgroud)
只要$d
匹配([$p]{4})
,就执行while块中的代码.但由于我不完全了解结构$p
是什么,我也很难理解这里发生了什么.
next if $j++ % 96 >= 16;
Run Code Online (Sandbox Code Playgroud)
如果$j
模数96大于或等于16 $j
,则为while循环的每次通过增量(?).
$c = 0;
foreach $d ( 0 .. 3 ) {
$c += $a{ substr $1, $d, 1 } * 4**$d;
}
Run Code Online (Sandbox Code Playgroud)
对于$d
范围从0
以3
提取一些子,但在这一点上,我完全失去了.最后几行连接所有内容并评估结果.
Mat*_*Mat 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 ) { ... }
Run Code Online (Sandbox Code Playgroud)
如果你必须自己写这个,删除空格后,你只需要抓住$d
长度为4的每个连续子串(假设没有其他字符$d
).
现在这部分很有趣:
foreach $d ( 0 .. 3 ) {
$c += $a{ substr $1, $d, 1 } * 4**$d;
}
Run Code Online (Sandbox Code Playgroud)
$1
拥有当前的四字母代码点.substr $1, $d, 1
返回该代码点的每个连续字母. %a
映射A
到00b(二进制),T
01b,C
到10b和G
11b.
A 00
T 01
C 10
G 11
Run Code Online (Sandbox Code Playgroud)乘以4**$d
将等于0,2,4和6的按位左移.
所以这个有趣的结构允许你用base ATCG
作为数字在base-four系统中构建任何8bit值!
即它执行以下转换:
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
Run Code Online (Sandbox Code Playgroud)
这部分:
next if $j++ % 96 >= 16;
Run Code Online (Sandbox Code Playgroud)
使上述转换仅针对前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";
Run Code Online (Sandbox Code Playgroud)
$ perl q.pl 'print "BioGeek\n";'
AAGTCAGTTCCTCGCTATGTAACACACACAATTCCTGGCTGTATTTCTTTCTGCCTAGTTCGCTCACAGCGA
Run Code Online (Sandbox Code Playgroud)
坚持$d
使用而不是螺旋(并删除解码器中的跳过部分).