2010-10-29 9 views
8

J'ai hérité d'un environnement qui a un script Perl "compilé" sous Unix. Est-il possible de décompiler, de désosser (quel que soit le terme) et d'obtenir le code source à partir du code objet compilé?Comment puis-je effectuer un reverse engineering d'un programme Perl compilé avec perlcc?

Peut-être pas possible, mais pensé que je demanderais plutôt que de supposer.

Merci, -Kevin.

+0

À des fins de référence, oui, le terme est «reverse engineering»; vous passez d'une représentation à faible abstraction (code compilé/machine) à une représentation à plus haute abstraction (code source structuré). –

Répondre

9

Oh mon dieu!

Si et seulement si il a été compilé en code binaire exécutable via perlcc -B, vous pourrait alors uncompile la même façon B :: Deparse fait. Vous récupéreriez toutes les sources qui n'étaient pas optimisées de cette façon. Cela pourrait sembler un peu drôle, mais ce serait un programme équivalent. Cependant, s'il a été entièrement compilé en code C et donc en assembleur et en langage machine et qu'il passe par ld pour un fichier a.out correct, vous ne pourrez rien faire de pareil. Ce serait comme essayer de démonter /bin/cat.

Alors ok, vous pouvez le démonter, mais il n'y a pas de joie à y avoir. Même si vous pourrait sortir le code C généré original - que vous ne pouvez pas - il serait pratiquement inutilisable.

Je suppose que vous pourriez exécuter les chaînes (1) pour voir si quelque chose d'utile restait dans un endroit permanent, mais je ne compterais pas dessus.

Désolé.

13

En quittant le backend bytecode tchrist déjà couvert et ne parle que du back-end C, tous perlcc ne traduit le optree de votre programme Perl compilé dans un programme C, qu'il compile ensuite. Ce programme C, lorsqu'il est exécuté, reconstruit alors cette optree en mémoire, et l'exécute fondamentalement comme le ferait habituellement Perl. Le but de cela est vraiment d'accélérer le temps de compilation du code perl normal.

Cette optrée de votre programme est alors disponible dans la variable globale PL_main_root. Nous avons déjà un module appelé B::Deparse, qui est capable de consommer optrees et de les transformer en code source qui est à peu près équivalent au code original à partir duquel l'optree a été compilé. Il arrive d'avoir une méthode compile qui retourne un coderef qui, lorsqu'il est exécuté, affichera le résultat de départ de PL_main_root.

Il existe également la fonction C Perl_eval_pv, que vous pouvez utiliser pour évaluer les fragments Perl à partir de l'espace 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 

Bien sûr l'habituel B :: mises en garde Deparse appliquent, mais ce sera certainement très pratique pour la marche arrière-engeneering. En fait, la reconstruction du code source original ne sera pas possible dans la plupart des cas, même si cela a fonctionné pour l'exemple ci-dessus. La magie gdb exacte que vous aurez à faire pour obtenir B :: Deparse pour vous donner quelque chose de sensible dépend aussi largement de votre perl. J'utilise un perl avec ithreads, et donc la multiplicité. C'est pourquoi je passe la variable my_perl. D'autres perls pourraient ne pas avoir besoin de ça.De plus, si quelqu'un supprime le binaire compilé par perlcc, les choses seront un peu plus difficiles, mais la même technique fonctionnera toujours.

Vous pouvez également utiliser cela pour compiler n'importe quelle optrée que vous pouvez obtenir d'une manière ou d'une autre à tout moment pendant l'exécution du programme. Jetez un oeil à B :: Deparse compile sub et faire quelque chose de similaire, sauf lui fournir un objet B pour tout optree que vous voulez déversé au lieu de B::main_root.

La même chose s'applique au backend de bytecode de perlcc. Je ne suis pas tout à fait sûr de l'arrière-plan C optimisé appelé CC.

+0

Je pensais seulement aux backends B et CC; J'avais oublié le backend C. – tchrist

+0

En fait, après avoir regardé brièvement le backend CC, il semble que ce soit le même que le backend C. C'est assez similaire pour que l'approche ci-dessus fonctionne de toute façon. – rafl

0

Utiliser 7-zip. Faites un clic droit sur le fichier exe, puis faites 7zip> Open Archive, puis prenez le fichier perl.

+2

Cela ne fonctionne que pour les programmes compressés, pas pour les programmes compilés. –

Questions connexes