2010-11-25 3 views
0

Est-il possible pour un programme écrit en C (ou assembly) et est lié avec c stdlib en utilisant gcc pour imprimer l'adresse de son entrée? (Puisque le symbole _start indique l'entrée du programme, je demande s'il est possible d'imprimer l'adresse de ce symbole depuis la fonction principale sans utiliser l'analyse du fichier exécutable ELF.)?Auto-identification d'entrée de programme

+0

Vous pouvez utiliser des composants intégrés pour obtenir une adresse dans la fonction d'entrée à partir de la trame de la pile, mais pas l'adresse de début. http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html Pourquoi voulez-vous l'adresse de départ? – Rup

+0

'& main'? ....... – khachik

Répondre

1

Pas très portable (c.-à-fonctionne sur ma machine, mais peut-être que c'est parce que les étoiles sont alignées)

#include <stdio.h> 

extern void _start(); 

int main(int argc,char *argv[]) 
{ 
    printf("%p\n",_start); 

    return 0; 
} 

Sur une boîte x86_64 RHEL 5.5, l'adresse imprimée correspond au point d'entrée d'adresse dans l'en-tête elfe, Je ne serais pas surpris si cela explose si le binaire est construit pour utiliser la randomisation de l'espace adresse.

+0

Oui, ça fonctionne, merci! Comment j'ajoute la randomisation de l'espace adresse? –

2

Je demande pourquoi vous avez besoin de faire cela, mais avez-vous essayé d'utiliser dlsym à vos fins?

+0

Je voulais juste savoir si cela peut être fait, je ne sais pas si cela a un aspect pratique. Quelle est la section dlsym dans ELF? –

+1

dlsym est une fonction qui vous renvoie une adresse basée sur le nom du symbole. par exemple. void * p = dlsym (handle, "_ start"); – nos

0

Pas de manière portable, non. En utilisant l'assembly pour une plate-forme connue, vous pouvez probablement revenir en arrière sur la pile d'appels et écrire l'adresse de retour (qui devrait se trouver dans la routine _start, si votre plateforme l'utilise) vers une variable accessible depuis le côté C.

Bien sûr, alors vous n'avez l'adresse de l'instruction suivante du call à votre main(), pas le début de la routine _start.

1
extern void _start(); 
printf("%p\n", (void *)_start); 

Ce n'est pas « portable » dans le sens que le langage C définit pas une telle chose en fonction _start, mais en supposant qu'il est mis en œuvre de cette façon, cela devrait fonctionner.