2012-02-18 35 views
54

Tôi đang cố gắng để deobfuscate đoạn mã sau Perl (source):Làm thế nào để đúng deobfusacte một kịch bản 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; 

Khi chạy, nó in ra Just another genome hacker.

Sau khi chạy mã máng Deparseperltidy (perl -MO=Deparse jagh.pl | perltidy) mã trông như thế này :

(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; 
} 

Đây là những gì tôi có thể tự giải mã.

(my $d = 
"AA...GCTCACA\n" # snipped double helix part 
) =~ s/\s+//g; 

xóa tất cả khoảng trắng trong $d (xoắn kép).

(%a) = map({ chr $_, $i++; } 65, 84, 67, 71); 

làm cho một băm với như phím A, T, CG và như đánh giá cao 0, 1, 23. Tôi thường viết bằng Python, do đó, dịch này sang từ điển {'A': 0, 'B': 1, 'C': 2, 'D': 3} bằng Python.

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

tham gia các khóa của hàm băm với $;subscript separator for multidimensional array emulation. Các tài liệu nói rằng mặc định là "\ 034", giống như SUBSEP trong awk, nhưng khi tôi làm:

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

tôi nhận được giá trị 28? Ngoài ra, nó không phải là rõ ràng với tôi như thế nào này mô phỏng một mảng đa chiều. Có phải $p hiện có dạng như [['A'], ['T'], ['C'], ['G']] bằng Python không?

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

Chừng nào $d trận , thực thi mã trong khối thời gian. nhưng vì tôi không hoàn toàn hiểu cấu trúc $p là, tôi cũng có một thời gian khó hiểu những gì xảy ra ở đây.

next if $j++ % 96 >= 16; 

Tiếp tục nếu các $j modulo 96 là lớn hơn hoặc bằng 16. $j increments với mỗi đường đi qua của vòng lặp while (?).

$c = 0; 
foreach $d (0 .. 3) { 
    $c += $a{ substr $1, $d, 1 } * 4**$d; 
} 

Đối $d trong khoảng 0-3 trích xuất một số chuỗi con, nhưng vào thời điểm này tôi hoàn toàn bị mất. Một vài dòng cuối cùng nối tất cả mọi thứ và đánh giá kết quả.

+11

Câu hỏi thú vị. – Rayfleck

+16

Bạn nên luôn luôn cẩn thận về mã mà 'eval' obfuscated chuỗi. Tôi đã nhìn thấy một câu hỏi quanh co ở đây trên stackoverflow mà kết thúc với một eval của một chuỗi mà hóa ra là "" rm-rf/"'. – TLP

+2

Nhắc tôi về [Acme :: EyeDrops] (http://p3rl.org/Acme::EyeDrops). –

Trả lời

50

Thận trọng: không mù quáng chạy perl obfuscated, đặc biệt là nếu có một eval, backticks, system, open vv gọi đâu đó trong nó và đó có thể không phải tất cả các quá rõ ràng*. Làm xáo trộn nó với Deparse và thay thế cẩn thận eval s bằng các bản in là phải cho đến khi bạn hiểu điều gì đang diễn ra. Chạy trong một sandbox/với một người dùng không có đặc quyền/trong một máy ảo cũng nên được xem xét.

*s&&$_ⅇ đánh giá $_ để lấy ý định.


Quan sát đầu tiên: 034 là bát phân. Nó bằng 28 (dec) hoặc 0x1c (hex), vì vậy không có gì có tanh ở đó.

Điều $; hoàn toàn là làm xáo trộn, không thể tìm thấy lý do để sử dụng cụ thể. $p sẽ chỉ là một chuỗi A.T.C.G (với . được thay thế bằng $;, bất kể nó là gì).
Vì vậy, trong regex [$p] khớp với bất kỳ số nào trong số {'A', 'T', 'C', 'G', $;}. Kể từ $; không bao giờ xuất hiện trong $d, nó vô dụng ở đó. Đổi lại [$p]{4} phù hợp với bất kỳ chuỗi bốn chữ vào bộ nói trên, vì nếu điều này đã được sử dụng (bỏ qua sự vô dụng $;):

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

Nếu bạn phải viết những dòng này cho mình, sau khi đã loại bỏ khoảng trắng, bạn' d chỉ cần lấy mỗi chuỗi con liên tiếp của $d có độ dài bốn (giả sử không có ký tự nào khác trong $d).

Bây giờ phần này là thú vị:

foreach $d (0 .. 3) { 
    $c += $a{ substr $1, $d, 1 } * 4**$d; 
} 
  • $1 giữ điểm mã bốn chữ hiện hành. substr $1, $d, 1 trả về từng chữ liên tiếp từ điểm mã đó.
  • %a bản đồ A đến 00b (nhị phân), T đến 01b, C đến 10b và G đến 11b.

    A 00 
    T 01 
    C 10 
    G 11 
    
  • nhân với 4**$d sẽ tương đương với một Bitwise chuyển trái từ 0, 2, 4 và 6.

Vì vậy, cấu trúc này hài hước cho phép bạn xây dựng bất kỳ giá trị 8bit trong cơ sở- bốn hệ thống có ATCG làm chữ số!

tức là nó không chuyển đổi sau:

  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 

phần này:

next if $j++ % 96 >= 16; 

làm cho thời gian chuyển đổi ở trên chỉ dành cho những người đầu tiên 16 "codepoints", bỏ qua tới 80, sau đó chuyển đổi cho 16 tiếp theo, bỏ qua 80 tiếp theo, vv Về cơ bản, nó chỉ bỏ qua các phần của hình elip (hệ thống loại bỏ DNA rác).


Dưới đây là một văn bản xấu xí để chuyển đổi ADN mà bạn có thể sử dụng để sản xuất bất cứ điều gì để thay thế xoắn (không xử lý các điều 80 bỏ qua):

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 

Stick trong $d thay vì xoắn (và loại bỏ phần bỏ qua trong bộ giải mã).

+8

Bây giờ cho câu hỏi thực sự thú vị: Làm thế nào để bạn viết mã biến văn bản thành DNA? =) – TLP

+12

Văn bản với tập lệnh DNA (do đó unobfuscated nó không giống như perl thích hợp) cung cấp :) – Mat

+5

+1 Rất tốt :) Một điều về cảnh báo của bạn: Phần 'eval' cũng có thể được obfuscated. Mã tôi đã đề cập trong các chú thích chính đã sử dụng một cái gì đó như ';; s ;; $ _; see', là một số nhị phân trên' $ _'. – TLP

Các vấn đề liên quan