2012-06-16 5 views
7

Как видно из названия - пожалуйста, может кто-нибудь объяснить, как следующие сценарии работыDeparsing/Разложение - шаг за шагом этот обфусцированный PERL скрипт

печатается текст: «Ребята Perl умные»

''=~('(?{'.('])@@^{'^'-[).*[').'"'.('-[)@{:__({:)[{(-:)^}'^'}>[,[]*&[[[[>[[@[[*_').',$/})') 

это только печатает "б"

use strict; 
use warnings; 
''=~('(?{'.('_/).+{'^'/]@@_[').'"'.('=^'^'_|').',$/})') 

Perl--MO = Deparse показывает только это:

use warnings; 
use strict 'refs'; 
'' =~ m[(?{print "b",$/})]; 

, но havent any idea why ...; (

Каков рекомендуемый способ разложения, как скрипты? Как начать?

так, попытался это:

'' =~ 
(
     '(?{' 
     . 
     (
       '])@@^{'^'-[).*[' 
     ) 
     . 
     '"' 
     . 
     (
       '-[)@{:__({:)[{(-:)^}'^'}>[,[]*&[[[[>[[@[[*_' 
     ) 
     . 
     ',$/})' 
) 

несколько частей сцепляются по .. И результат побитового ^, вероятно, дает текстовые части. В:

perl -e "print '-[)@{:__({:)[{(-:)^}'^'}>[,[]*&[[[[>[[@[[*_'" 

печатает "ребята Perl умные" и первый ^ производящая "печать".

Но когда я переписать его:

'' =~ 
(
    '(?{' 
    . 
    (
     'print' 
    ) 
    . 
    '"' 
    . 
    (
     'Perl guys are smart' 
    ) 
    . 
    ',$/})' 
) 

Мой Perl сказал мне:

panic: top_env 

Странно, первый раз я видел, как сообщение об ошибке ...

То значит: не допускается замена 'str1'^'str2' на result (не понимаю почему) и почему perl печатает сообщение о панике?

мой Perl:

This is perl 5, version 12, subversion 4 (v5.12.4) built for darwin-multi-2level 

Ps: примеры генерируются here

+0

«Learn Perl» - очевидный ответ. –

+2

Но на самом деле никто не должен писать такой код, поэтому нет причин для его понимания. –

+0

thanx для объяснения;) – cajwine

ответ

5

В строке

.('_/).+{'^'/]@@_[ 

при оценке ']'^'-', результат будет буква p.^ - операция побитовой строки, поэтому после этого мы следуем буквам письма, чтобы получить строку результата.

Проверьте мой скрипт, он работает как ваш пример. Надеюсь, это поможет вам.

use v5.14; 

# actually we obfuscated print and your word + " 
# it looks like that (print).'"'.(yor_word") 
my $print = 'print'; 
my $string = 'special for stackoverflow by fxzuz"'; 

my $left = get_obfuscated($print); 
my $right = get_obfuscated($string); 

# prepare result regexp 
my $result = "'' =~ ('(?{'.($left).'\"'.($right).',\$/})');"; 

say 'result obfuscated ' . $result; 
eval $result; 

sub get_obfuscated { 

    my $string = shift; 
    my @letters = split //, $string; 

    # all symbols like :,&? etc (exclude ' and \) 
    # we use them for obfuscation 
    my @array = (32..38, 40..47, 58..64, 91, 93..95, 123..126); 

    my $left_str = ''; 
    my $right_str = ''; 

    # obfuscated letter by letter 
    for my $letter (@letters) { 

     my @result; 
     # get right xor letters 
     for my $symbol (@array) { 

      # prepare xor results 
      my $result = ord $letter^$symbol; 
      push @result, { left => $result, right => $symbol } if $result ~~ @array; 
     } 

     my $rand_elem = $result[rand $#result]; 
     $left_str .= chr $rand_elem->{left}; 
     $right_str .= chr $rand_elem->{right}; 
    } 

    my $obfuscated = "'$left_str'^'$right_str'"; 
    say "$string => $obfuscated"; 

    return $obfuscated; 
} 
3

Хитрость к пониманию того, что происходит здесь, чтобы посмотреть на строку строится по операцию XOR и сцеплений:

(?{print "Perl guys are smart",$/}) 

Это экспериментальная функция регулярного выражения формы (?{ code }). Так что вы видите, печататься на терминал является результатом

print "Perl guys are smart",$/ 

быть вызван ''=~.... $/ - это разделитель входных записей Perl, который по умолчанию является символом новой строки.