Как правильно деобфусакте скрипт Perl?
я пытаюсь deobfuscate следующие 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(,$d,1)}*(4**$d)}$perl.=chr $c}
eval $perl;
при запуске он выводит Just another genome hacker.
после запуска через код Deparse
и perltidy
(perl -MO=Deparse jagh.pl | perltidy
) код выглядит так:
( my $d =
"AA...GCTCACAn" # 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 , $d, 1 } * 4**$d;
}
$perl .= chr $c;
}
вот что я смог расшифровать самостоятельно.
( my $d =
"AA...GCTCACAn" # snipped double helix part
) =~ s/s+//g;
удаляет все пробелы в $d
(двойная спираль).
(%a) = map( { chr $_, $i++; } 65, 84, 67, 71 );
делает хэш с ключами A
, T
,C
и G
и как значения 0
,1
,2
и 3
.
Я обычно кодирую на Python, поэтому это переводится в словарь {'A': 0, 'B': 1, 'C': 2, 'D': 3}
в Python.
$p = join( $;, keys %a );
соединяет ключи хэша с $;
the разделитель индексов для эмуляции многомерных массивов. В документации говорится, что по умолчанию используется "34", то же самое, что и SUBSEP в awk, но когда я делаю:
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;
продолжить, если the $j
модуль 96 больше или равен 16. $j
инкременты с каждым проходом цикла while (?).
$c = 0;
foreach $d ( 0 .. 3 ) {
$c += $a{ substr , $d, 1 } * 4**$d;
}
на $d
в границах от 0
до 3
извлеките некоторую подстроку, но на данный момент я полностью потерян. Последние несколько строк объединяют все и оценивают результат.
1 ответ:
осторожностью: не запускайте вслепую запутанный perl, особенно если есть
eval
, backticks,system
,open
и т. д. позвоните куда-нибудь в него и это может быть не слишком очевидно*. Де-запутывание его сDeparse
и тщательно заменитьeval
S с операторами печати является обязательным, пока вы не поймете, что происходит. Запуск в песочнице/с непривилегированным пользователем / в виртуальной машине также следует учитывать.*
s&&$_ⅇ
оценивает$_
для intance.
первое наблюдение:
034
- это восьмеричное. Он равен 28 (dec) или 0x1c (hex), поэтому ничего подозрительного там нет.The
$;
вещь чисто запутывания, не могу найти причину, чтобы использовать это в частности.$p
будет просто строкаA.T.C.G
(С.
заменить на$;
, что бы это ни было).
Так что в регулярном выражении[$p]
совпадает с{'A', 'T', 'C', 'G', $;}
. Так как$;
не появляется в$d
, это было бесполезно. В свою очередь[$p]{4}
соответствует любой последовательности из четырех букв в приведенном выше наборе, как если бы это было использовано (игнорируя бесполезный$;
):while ( $d =~ /([ATCG]{4})/g ) { ... }
если бы вам пришлось написать это самостоятельно, после удаления пробелов, вы бы просто захватили каждую последующую подстроку
$d
длины четыре (предполагая, что нет других символов в$d
).теперь эта часть весело:
foreach $d ( 0 .. 3 ) { $c += $a{ substr , $d, 1 } * 4**$d; }
в настоящее время четыре буквы кода.
substr , $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.так что эта забавная конструкция позволяет вам постройте любое 8-битное значение в системе base-four с помощью
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 и т. д. Он по существу просто пропускает части эллипса (система удаления нежелательной ДНК).
вот уродливый конвертер текста в ДНК, который вы могли бы использовать чтобы произвести что-либо, чтобы заменить спираль (не обрабатывает 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
что вместо спирали (и удалить пропуская часть в декодере).