Comment trouver la fonction principale du point d'entrée de l'elfe fichier exécutable sans aucune information symbolique?
J'ai développé un petit programme cpp sur la plate-forme de Ubuntu-Linux 11.10.
Maintenant, je veux désosser. Je suis débutant. - Je utiliser de tels outils: GDB 7.0, hte éditeur, hexeditor.
Pour la première fois que j'ai fait c'est assez facile. Avec l'aide de l'information symbolique, j'ai fondé l'adresse de la fonction principale et fait tout ce dont j'avais besoin.
Ensuite, j'ai rayé (--strip-all
) exécutable elf-fichier et j'ai quelques problèmes.
Je sais que main
fonction commence à partir de 0x8960 dans ce programme.
Mais je n'ai pas une idée de comment je dois faire pour trouver ce point sans cette connaissance.
J'ai essayé de déboguer mon programme étape par étape à l'aide de gdb, mais il va dans __libc_start_main
puis dans la ld-linux.so.3
(donc, il détecte et charge les bibliothèques partagées nécessaires par un programme). J'ai débogué environ 10 minutes. Bien sûr, peut-être dans 20 minutes, je peux atteindre la principale fonction du point d'entrée, mais, il semble, que le moyen plus facile est d'exister.
Que dois-je faire pour trouver la main
de la fonction de point d'entrée sans aucune symbolique info?
Pourriez-vous me conseiller quelques bons livres/sites/other_sources de l'ingénierie inverse de elf-fichiers avec l'aide de gdb?
Toute aide serait appréciée.
Mat, Ok, je n'ai pas l'esprit, mais la question est la même.
Je pense que la glibc sur x86 pousse
main()
's adresse avant d'appeler __libc_start_main
sur _start
. Au moins, il fait y a pas longtemps.Oui, vous avez tout à fait raison! J'ai déjà trouvé hier dans une telle manière. 🙂
OriginalL'auteur Lucky Man | 2012-03-27
Vous devez vous connecter pour publier un commentaire.
Localisation
main()
dans une dépouillé Linux binaire ELF est simple. Pas de symbole d'information est nécessaire.Le prototype pour
__libc_start_principal
estLa mémoire d'exécution de l'adresse de
main()
est l'argument correspondant au premier paramètre,int (*main) (int, char**, char**)
. Cela signifie que la dernière adresse de mémoire enregistré sur l'exécution de la pile avant l'appel__libc_start_main
est l'adresse mémoire demain()
, puisque les arguments sont poussés dans l'exécution de la pile dans l'ordre inverse de leurs paramètres correspondants dans la définition de la fonction.On peut entrer
main()
dansgdb
en 4 étapes:__libc_start_main
est appelé_libc_start_main
continue
jusqu'à ce que le point de rupture pour lesmain()
est frappéLe processus est le même pour les deux versions 32 bits et 64 bits binaires ELF.
Entrer
main()
dans un exemple dépouillé 32-bit binaire ELF appelé "test_32":Entrer
main()
dans un exemple dépouillé 64-bit binaire ELF appelé "test_64":Un traitement détaillé de l'initialisation du programme et ce qui se produit avant
main()
est appelé et comment arriver àmain()
peuvent être trouvés se trouve dans Patrick Horgan du tutoriel "Linux x86 Programme de Démarrageou - Comment diable pouvons-nous obtenir de main()?"
OriginalL'auteur julian
Autant que je sache, une fois qu'un programme a été dépouillé, il n'y a pas de façon simple d'accéder à la fonction que le symbole
main
aurait autrement référencés.La valeur du symbole
main
est pas nécessaire pour le démarrage du programme: dans le format ELF, le début du programme est indiquée par lee_entry
domaine de l'ELFE exécutable en-tête. Ce champ normalement points de la bibliothèque C du code d'initialisation, et non pas directement àmain
.Tandis que la bibliothèque C du code d'initialisation fait appel
main()
après qu'il a mis en place le C de l'environnement d'exécution, cet appel est une fonction normale d'appel qui est entièrement résolu au moment de la liaison.Dans certains cas, la mise en œuvre spécifique de l'heuristique (c'est à dire, la connaissance spécifique de l'intérieur de la C runtime) pourraient être utilisés pour déterminer l'emplacement de
main
dans une dépouillé exécutable. Cependant, je ne suis pas au courant d'un portable moyen de le faire.OriginalL'auteur jkoshy
Si vous avez une version très dépouillée, ou même un fichier binaire qui est emballé, comme à l'aide de UPX, vous pouvez gdb sur elle dans le dur chemin que:
Et puis vous pouvez rompre dans GDB:
et puis, vous pouvez voir les instructions de participation:
J'espère que cela aide
OriginalL'auteur Breno Leitão