Как я могу перепроектировать программу Perl, которая была скомпилирована с помощью perlcc? - PullRequest
8 голосов
/ 29 октября 2010

Я унаследовал среду, в которой есть «скомпилированный» Perl-скрипт в Unix. Можно ли его декомпилировать, перепроектировать (каким бы ни был этот термин) и получить исходный код из скомпилированного объектного кода?

Возможно, это было бы невозможно, но я подумал, что лучше спросить, чем предположить.

Спасибо, Кевин.

Ответы [ 3 ]

13 голосов
/ 29 октября 2010

Оставляя в стороне бэк-код бэк-кода, о котором мы уже говорили, и говоря только о бэкэнде C, все, что делает perlcc, это переводит optree вашей скомпилированной perl-программы в программу на C, которую затем компилирует. Эта программа на C при запуске затем реконструирует этот optree в память и в основном выполняет его, как обычно это делает perl. Суть в том, чтобы ускорить время компиляции обычного Perl-кода.

Этот optree вашей программы будет доступен в глобальной переменной PL_main_root. У нас уже есть модуль с именем B::Deparse, который может использовать optrees и превращать их в исходный код, который примерно эквивалентен исходному коду, из которого скомпилирован optree. Бывает, что есть метод compile, который возвращает кодовую ссылку, которая при выполнении выдает результат разброса PL_main_root.

Также есть функция C Perl_eval_pv, которую вы можете использовать для оценки фрагментов Perl из пространства C.

$ echo 'print 42, "\\n"' > foo.pl
$ perl foo.pl
42
$ perlcc foo.pl
$ ./a.out
42
$ gdb a.out
...
(gdb) b perl_run
Breakpoint 1 at 0x4570e5: file perl.c, line 2213.
(gdb) r
...
Breakpoint 1, perl_run (my_perl=0xa11010) at perl.c:2213
(gdb) p Perl_eval_pv (my_perl, "use B::Deparse; B::Deparse->compile->()", 1)
print 42, "\n";
$1 = (SV *) 0xe47b10

Конечно, применяются обычные предостережения B :: Deparse, но это, безусловно, будет полезно для реинжиниринга. На самом деле восстановление исходного исходного кода в большинстве случаев будет невозможно, даже если это сработало для приведенного выше примера.

Точная магия GDB, которую вы должны будете сделать, чтобы получить B :: Deparse, чтобы дать вам что-то разумное, также во многом зависит от вашего Perl. Я использую Perl с ithreads, и, следовательно, множественность. Вот почему я передаю переменную my_perl. Другие perls могут не нуждаться в этом. Кроме того, если кто-то удалит двоичный файл, скомпилированный с помощью perlcc, все станет немного сложнее, но тот же метод будет работать.

Также вы можете использовать это для компиляции любого optree, который вы можете каким-то образом получить в любой момент во время выполнения программы. Посмотрите на скомпилируемую подпрограмму B :: Deparse и сделайте что-то похожее, за исключением того, что предоставьте ей объект B для любого optree, который вы хотите сбросить вместо B::main_root.

То же самое относится и к упомянутому бэк-коду байт-кода perlcc. Я не совсем уверен насчет оптимизированного бэкэнда C под названием CC.

10 голосов
/ 29 октября 2010

Боже мой!

Если и только если он был скомпилирован в исполняемый байт-код с помощью perlcc -B, вы могли бы , а затем скомпилировать его так же, как B :: Deparse. Вы получите все источники, которые не были оптимизированы таким образом. Это может выглядеть немного забавно, но это будет эквивалентная программа.

Однако, если он был полностью скомпилирован в код C, а затем в ассемблер и машинный язык и прошел через ld для правильного a.out файла, вы не сможете сделать ничего подобного. Это все равно что пытаться разобрать /bin/cat.

Так хорошо, вы можете разобрать его, но там нет радости. Даже если бы вы могли получить исходный сгенерированный код C - чего вы не можете - он был бы практически непригоден.

Полагаю, вы могли бы запустить на нем строк (1), чтобы посмотреть, осталось ли что-нибудь полезное где-нибудь навсегда, но я бы на это не рассчитывал.

Извините.

0 голосов
/ 14 февраля 2012

Используйте 7-почтовый индекс.Щелкните правой кнопкой мыши по exe-файлу, затем выполните 7zip> Открыть архив и затем захватите perl-файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...