55

我正在尝试对以下 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.

运行代码槽Deparseperltidy( 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 );

使用 as 键A、和和作为值T、和进行散列。我通常用 Python 编码,所以这会转化为Python 中的字典。CG0123{'A': 0, 'B': 1, 'C': 2, 'D': 3}

$p = join( $;, keys %a );

将散列的键与多维数组仿真$;的下标分隔符连接起来。文档说默认是“\034”,与 awk 中的 SUBSEP 相同,但是当我这样做时:

my @ascii = unpack("C*", $p);
print @ascii[1];

我得到了价值28?另外,我不清楚这如何模拟多维数组。现在是$p[['A'], ['T'], ['C'], ['G']]Python 中的东西吗?

    while ( $d =~ /([$p]{4})/g ) {

只要$d匹配([$p]{4}),就执行 while 块中的代码。但由于我不完全理解结构$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;
}

For$d在 from 范围内0提取3一些子字符串,但在这一点上我完全迷失了。最后几行连接所有内容并评估结果。

4

1 回答 1

51

注意:不要盲目地运行混淆的 perl,特别是如果其中有一个eval, 反引号, system,open等调用并且这可能不是很明显*。在您了解发生了什么之前,必须使用 print 语句对其进行去混淆Deparse并仔细替换s 。eval也应该考虑在沙箱中/使用非特权用户/在虚拟机中运行。

*s&&$_ⅇ评估$_实例。


第一个观察:034是八进制的。它等于 28(十进制)或 0x1c(十六进制),所以没有什么可疑的。

$;件事纯粹是混淆,找不到特别使用它的理由。$p将只是一个字符串A.T.C.G.替换为$;,无论它是什么)。
所以在正则表达式[$p]中匹配任何{'A', 'T', 'C', 'G', $;}. 由于$;从未出现在 中$d,因此在那里毫无用处。依次[$p]{4}匹配上述集合中的任何四个字母序列,就好像它已被使用(忽略无用的$;):

while ( $d =~ /([ATCG]{4})/g ) { ... }

如果您必须自己编写,在删除空格之后,您只需获取$d长度为 4 的每个连续子字符串(假设 中没有其他字符$d)。

现在这部分很有趣:

foreach $d ( 0 .. 3 ) {
    $c += $a{ substr $1, $d, 1 } * 4**$d;
}
  • $1保存当前的四字母代码点。substr $1, $d, 1从该代码点返回每个连续的字母。
  • %a映射A到 00b(二进制)、T01b、C10b 和G11b。

    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它而不是螺旋线(并删除解码器中的跳过部分)。

于 2012-02-18T15:13:02.243 回答