如何正确deobfusacte Perl脚本?

时间:2012-02-18 14:45:50

标签: perl deobfuscation

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

通过Deparseperltidyperl -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 );

使用键ATCG以及值01,{{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提取一些子字符串,但此时我完全迷失了。最后几行连接所有内容并评估结果。

1 个答案:

答案 0 :(得分:50)

警告:不要盲目地运行混淆的perl,特别是如果有eval,反引号,systemopen等,请在其中的某处调用,这可能不太明显 * 。使用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返回该代码点的每个连续字母。
  • %aA映射到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代替螺旋(并删除解码器中的跳过部分)。