Lorsque j'utilise GDB pour déboguer un programme écrit en C, la commande Démontage indique les codes et leurs adresses dans la segmentation de la mémoire de code. Est-il possible de connaître ces adresses de mémoire à l'exécution? J'utilise Ubuntu OS. Merci.
[modifier] Pour être plus précis, je vais le démontrer avec l'exemple suivant. P>
#include <stdio.h>
int main(int argc,char *argv[]){
myfunction();
exit(0);
}
4 Réponses :
Pour obtenir une backtrage, utilisez Par exemple: P> exécufo.h code> comme documenté dans le manuel GNU LIBC .
./a(trace_pom+0xc9)[0x80487fd]
./a(DepositMoney+0x11)[0x8048862]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(main+0x1d)[0x80488a4]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7e16775]
./a[0x80486a1]
Existe-t-il une manière que je puisse extraire l'adresse de la fonction de dépôtMoney uniquement, les significations 0x8048872 devraient être la seule sortie au lieu d'imprimer tout le backtrage?
Ah, désolé, je pensais que tu voulais une arrière-marche complète.
La réponse ci-dessus est considérablement surchargée. Si la référence de fonction est statique, comme c'est-à-dire ci-dessus, l'adresse est simplement la valeur du nom de symbole dans le contexte du pointeur: Si vous saisissez la fonction de manière dynamique d'une bibliothèque partagée, Ensuite, la valeur renvoyée de DLSYM () (POSIX) ou GETProCaddress () (Windows) est également l'adresse de la fonction. p> Notez que le code ci-dessus risque de générer un avertissement avec certains compilateurs, comme ISO C techniquement interdit l'affectation entre le code et les pointeurs de données (certaines architectures les placent dans des espaces d'adresse physiquement distincts). P> et certains pédants soulignent que l'adresse renvoyée n'est pas et enfin, notez que "l'adresse" d'une fonction est un peu ambiguë. Si la fonction a été chargée de manière dynamique ou est une référence externe à un symbole exporté, ce que vous obtenez vraiment, c'est généralement un pointeur à un code de fixuption dans la "PLT" (un terme UNIX / ELF, bien que le mécanisme PE / COFF sur Windows soit similaire ) qui saute ensuite sur la fonction. p> p>
Merci beaucoup pour votre réponse fantastique. Puis-je poser cette question à l'avance: que diriez-vous d'obtenir l'adresse d'une ligne de code spécifique?
Pas de chance là-bas. Les compilateurs sont libres de réaménager et d'optimiser le code, il n'ya donc pas une seule région de mémoire qui correspond à une ligne ou à une expression donnée. Les debuggers peuvent faire un travail assez raisonnable de reconstruire cela à partir de la table des symboles et de déboguer des informations dans l'exécutable, mais malheureusement, vous entrez dans un vaudou profond que je ne sais pas hors main.
Belle réponse, bien expliquée. Vous pouvez également contourner le fait que la conversion entre le code et les pointeurs de données n'est pas définie, en appliquant cette astuce (comme dans "homme dlsym" dans la direction inverse): vide p; * (void (* i>) ()) & p = (void (*) ()) et mysculation; ou en utilisant un syndicat.
Si vous connaissez le nom de la fonction avant exécutions du programme, utilisez simplement
#include <bfd.h>
#include <stdio.h>
#include <stdlib.h>
#include <type.h>
#include <string.h>
long find_symbol(char *filename, char *symname)
{
bfd *ibfd;
asymbol **symtab;
long nsize, nsyms, i;
symbol_info syminfo;
char **matching;
bfd_init();
ibfd = bfd_openr(filename, NULL);
if (ibfd == NULL) {
printf("bfd_openr error\n");
}
if (!bfd_check_format_matches(ibfd, bfd_object, &matching)) {
printf("format_matches\n");
}
nsize = bfd_get_symtab_upper_bound (ibfd);
symtab = malloc(nsize);
nsyms = bfd_canonicalize_symtab(ibfd, symtab);
for (i = 0; i < nsyms; i++) {
if (strcmp(symtab[i]->name, symname) == 0) {
bfd_symbol_info(symtab[i], &syminfo);
return (long) syminfo.value;
}
}
bfd_close(ibfd);
printf("cannot find symbol\n");
}
Merci, c'est ce que je cherchais
Désolé pour la nécromancement; Cependant, j'ai trouvé cela vraiment utile. Connaissez-vous un tutoriel pour vous aider avec BFD?
À propos d'un commentaire dans une réponse (obtenir l'adresse d'une instruction), vous pouvez utiliser ce truc très laid il devrait être env [12] (l'EIP), mais être Attention car il a l'air de la machine dépendante, alors triple vérifie mon mot. Ceci est la sortie p> amusez-vous! P> p>
Vous posez des questions sur un désassembleur de temps d'exécution intégré dans votre programme?
Que voulez-vous vraiment?
Merci à tous. J'ai une bonne compréhension de cette affaire: D