Comment puis-je déterminer l'adresse de retour sur la pile?
Je sais que si je suis à l'intérieur d'une fonction foo()
qui est appelé quelque part de bar()
fonction, cette adresse de retour est poussé sur la pile.
#include <stdio.h>
void foo()
{
unsigned int x;
printf("inside foo %x\n", &x);
}
int main()
{
foo();
printf("in main\n");
return 0;
}
Dans le code ci-dessus, je vais avoir l'adresse de d'abord poussé variable locale sur la pile lors de foo fonction est active. Comment puis-je accéder à l'adresse de retour (principal appelé foo) qui est poussé quelque part avant cette variable sur la pile? C'est que l'emplacement fixe et peut être consulté par rapport à la première variable locale? Comment puis-je la modifier?
EDIT: Mon environnement est Ubuntu 9.04 sur processeur x86 avec le compilateur gcc.
source d'informationauteur vinit dhatrak | 2009-11-07
Vous devez vous connecter pour publier un commentaire.
Il y a un gcc builtin pour cela:
void * __builtin_return_address (unsigned int level)
Voir http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html
Sur certaines architectures, vous pouvez la trouver sur la pile par rapport au premier paramètre. Sur ia32, par exemple, les paramètres sont poussés (en ordre inverse) et qu'un appel est fait que de pousser l'adresse de retour. Rappelez-vous que la pile presque toujours (et sur ia32) pousse à la baisse. Bien que, techniquement, vous avez besoin de la ABI ou conventions d'appel (parfois appelé de liaison des conventions) pour votre langue et votre plate-forme matérielle, dans la pratique, vous pouvez généralement suppose que si vous savez comment l'appel de procédure machine op œuvres.
La relation entre le premier paramètre à une fonction et la position de l'adresse de retour sur la pile est beaucoup plus susceptibles d'être d'une manière fiable fixe la valeur de la relation entre le local et l'adresse de retour. Cependant, vous pouvez certainement imprimer l'adresse d'un local, et du premier paramètre, et vous trouverez souvent le PC entre les deux.
Lorsque vous déclarez des variables locales, ils sont aussi sur la pile - x, par exemple.
Ensuite, si vous déclarez un
int * xptr
et l'initialiser à&x
il pointe sur x.Rien (beaucoup) vous empêche de le décrémenter le pointeur de jeter un regard un peu avant, ou l'incrémentation de regarder la suite. Quelque part autour de il est de votre adresse de retour.
De savoir où l'adresse de retour est que vous devez savoir ce que le convention d'appel est. Ce sera généralement fixé par le compilateur et dépend de la plate-forme, mais vous pouvez le forcer dans la plate-forme de façon spécifique, par exemple à l'aide de
__declspec(stdcall)
sur windows. Un compilateur optimisant peut aussi inventer sa propre convention d'appel pour les fonctions qui n'ont pas de portée externe.Interdisant l'utilisation du compilateur built-ins pour obtenir l'adresse de retour, vous devriez recourir à l'assembleur en ligne pour obtenir de la valeur. D'autres techniques qui apparaissent à travailler en debug serait très vulnérable à des optimisations du compilateur déconner.
Vous pouvez sonde autour de la pile comme
Vous pouvez vous en sortir avec ce parce que C est célèbre pour ne pas être très particulier dans la façon de l'index d'un tableau. Ici, vous déclarez un mannequin tableau sur la pile, puis coup d'oeil autour de +/- par rapport à ça.
De Rob Walker fait, vous avez certainement besoin de savoir vos compilateurs convention d'appel, de comprendre les données que vous recherchez. Vous pouvez imprimer l'adresse de quelques fonctions, et de regarder pour les valeurs qui sont dans la même gamme, et intuit où l'adresse de retour est, par rapport à la tôle de tableau.
Mot d'avertissement - lisez tout ce que vous voulez, mais ne rien modifier à l'aide de ce tableau, à moins que (a) vous êtes absolument sûr de ce que la partie de la pile est en cours de modification, ou (b) veux juste voir une intéressante/imprévisible mode crash.
Veuillez également noter qu'en général il n'y a pas de garantie faite par le langage C que votre adresse de retour est sur une pile, ou en fait n'importe où dans la mémoire vive, à tous.
Il y a des architectures de processeurs que de stocker l'adresse de retour dans un registre, le recours à la RAM uniquement pour les appels commencent à nid. Il y a d'autres architectures où il y a une pile séparée pour les adresses de retour, qui n'est pas lisible par le PROCESSEUR. Elles peuvent toutes les deux ont encore des compilateurs C mis en œuvre pour eux.
C'est pourquoi vous avez besoin pour être plus clair avec votre environnement.
Essayer cette
La sortie doit ressembler à