récemment (ne plus y aller) J'ai moi-même appris le format de fichier ELF. J'ai largement suivi la documentation ici: http://www.skyfree.org/linux/references/ELF_Format.pdf.Est-ce que sh_addr est toujours égal à sh_offset dans le format de fichier ELF?
Il était tout va très bien, et j'ai écrit ce programme pour me donner des informations au sujet d'une des sections de fichier ELF:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <elf.h>
void dumpShdrInfo(Elf32_Shdr elfShdr, const char *sectionName)
{
printf("Section '%s' starts at 0x%08X and ends at 0x%08X\n",
sectionName, elfShdr.sh_offset, elfShdr.sh_offset + elfShdr.sh_size);
}
int search(const char *name)
{
Elf32_Ehdr elfEhdr;
Elf32_Shdr *elfShdr;
FILE *targetFile;
char tempBuf[64];
int i, ret = -1;
targetFile = fopen(name, "r+b");
if(targetFile)
{
/* read the ELF header */
fread(&elfEhdr, sizeof(elfEhdr), 1, targetFile);
/* Elf32_Ehdr.e_shnum specifies how many sections there are */
elfShdr = calloc(elfEhdr.e_shnum, sizeof(*elfShdr));
assert(elfShdr);
/* set the file pointer to the section header offset and read it */
fseek(targetFile, elfEhdr.e_shoff, SEEK_SET);
fread(elfShdr, sizeof(*elfShdr), elfEhdr.e_shnum, targetFile);
/* loop through every section */
for(i = 0; (unsigned int)i < elfEhdr.e_shnum; i++)
{
/* if Elf32_Shdr.sh_addr isn't 0 the section will appear in memory*/
if(elfShdr[i].sh_addr)
{
/* set the file pointer to the location of the section's name and then read the name */
fseek(targetFile, elfShdr[elfEhdr.e_shstrndx].sh_offset + elfShdr[i].sh_name, SEEK_SET);
fgets(tempBuf, sizeof(tempBuf), targetFile);
#if defined(DEBUG)
dumpShdrInfo(elfShdr[i], tempBuf);
#endif
}
}
fclose(targetFile);
free(elfShdr);
}
return ret;
}
int main(int argc, char *argv[])
{
if(argc > 1)
{
search(argv[1]);
}
return 0;
}
Après l'exécution quelques fois sur quelques fichiers que j'ai remarqué quelque chose de bizarre. La section '.text' a toujours commencé à une adresse virtuelle très basse (nous parlons plus petit que 1000h). Après avoir creusé avec gdb pendant un moment, j'ai remarqué que pour chaque section, sh_addr était égal à sh_offset.
C'est ce que je suis confus au sujet de - Elf32_Shdr.sh_addr est documentée comme étant "l'adresse à laquelle le premier octet devrait résider", tandis que Elf32_Shdr.sh_offset est documentée comme étant "le décalage d'octets depuis le début du fichier au premier octet de la fonction ". Si ce sont les deux cas, cela n'a pas vraiment de sens pour moi qu'ils soient tous les deux égaux. Pourquoi est-ce? Maintenant, je sais que certaines sections contiennent des données non initialisées (.bss je pense), il serait donc logique que ces données n'apparaissent pas dans le fichier mais apparaissent dans la mémoire du processus. Cela signifierait que pour chaque section qui vient après celle mentionnée ci-dessus, trouver son adresse virtuelle serait beaucoup plus compliqué qu'une simple variable.
Cela étant dit, existe-t-il un moyen de déterminer réellement l'adresse virtuelle d'une section?
Utilisez-vous le code que j'ai collé? Si non, pourriez-vous indiquer ce que je fais mal? La sortie que je reçois est ici http://pastebin.com/qTPG85sT – masseyc
err, ne tenez pas compte de cela. http://stackoverflow.com/questions/3091363/question-about-the-elf-file-format-sh-addr-always-equals-sh-offset/3098927#3098927 – masseyc