gpt4 book ai didi

c - 打开 ELF 文件并检查

转载 作者:行者123 更新时间:2023-11-30 15:49:37 31 4
gpt4 key购买 nike

我需要编写 C 程序来检查 ELF 链接 View 格式的目标文件并将其转换为可执行 View 格式,将其加载到内存中。

第一个问题:如何打开文件并读取它?

最佳答案

我尝试编写一些代码来读取 elf 文件,请参见下面:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <elf.h>
#include <sys/mman.h>
#include <stddef.h>

static void shdr_parse(void *ptr)
{
Elf32_Shdr *shdr_ptr = NULL;
Elf32_Ehdr *Elf32_ptr = (Elf32_Ehdr *)ptr;


int n = Elf32_ptr->e_shnum;
char *shstrtab = NULL;

printf("e_shstrndx: 0x%x\n", Elf32_ptr->e_shstrndx);
printf("e_shnum: 0x%x\n", Elf32_ptr->e_shnum);
/*
* first of all, let's get the shstrtab, we'll get
* the name of each section with it
*/
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
while (n--) {
if (shdr_ptr->sh_type == SHT_STRTAB) {
shstrtab = (char *)(ptr + shdr_ptr->sh_offset);
if (!strcmp(&shstrtab[shdr_ptr->sh_name], ".shstrtab"))
break;
}
shdr_ptr++;
}

/* list all of sections */
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
n = Elf32_ptr->e_shnum;
int i = 0;
while (n--) {
printf("[%02d]%s type: 0x%x, offset: 0x%x, size: 0x%x\n", i++,
&shstrtab[shdr_ptr->sh_name], shdr_ptr->sh_type,
shdr_ptr->sh_offset, shdr_ptr->sh_size);
shdr_ptr++;
}

printf("=== sizeof(Elf32_Sym): 0x%x\n", sizeof(Elf32_Sym));

/* list .gnu.hash */
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
n = Elf32_ptr->e_shnum;
i = 0;
while (n--) {
if (!strcmp(&shstrtab[shdr_ptr->sh_name], ".gnu.hash")) {
Elf32_Dyn *dyn_ptr = (Elf32_Dyn *)(ptr + shdr_ptr->sh_offset);
printf("GNU_HASH 0x%x\n", dyn_ptr->d_un.d_ptr);
break;
}
shdr_ptr++;
}

}

static void phdr_parse(void *ptr)
{
Elf32_Ehdr *Elf32_ptr = NULL;

Elf32_ptr = (Elf32_Ehdr *)ptr;
Elf32_Phdr *elf32_phdr = NULL;
int n, found = 0;

n = Elf32_ptr->e_phnum;
elf32_phdr = ptr + Elf32_ptr->e_phoff;
while (n--) {
if (elf32_phdr->p_type == PT_DYNAMIC) {
found = 1;
break;
}
elf32_phdr++;
}

if (found) {
printf("=== PT_DYNAMIC: offset: 0x%x, size: 0x%x\n",
elf32_phdr->p_offset, elf32_phdr->p_filesz);
printf("sizeof(Elf32_Dyn): %d\n", sizeof(Elf32_Dyn));
}

/* list all of dynamic sections */
Elf32_Dyn *dyn_entry = ptr + elf32_phdr->p_offset;
while (dyn_entry->d_tag != DT_NULL) {
if (dyn_entry->d_tag == 0x6ffffef5) {
printf("DT_HASH: addr: 0x%x\n", dyn_entry->d_un.d_ptr);
break;
}
printf("tag: 0x%x, value: 0x%x\n", dyn_entry->d_tag, dyn_entry->d_un.d_ptr);

dyn_entry++;
}

}

static void relocs_parse(void *ptr)
{
Elf32_Shdr *shdr_ptr = NULL;
Elf32_Ehdr *Elf32_ptr = (Elf32_Ehdr *)ptr;


int n = Elf32_ptr->e_shnum;
char *shstrtab = NULL;

/*
* first of all, let's get the shstrtab, we'll get
* the name of each section with it
*/
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
while (n--) {
if (shdr_ptr->sh_type == SHT_STRTAB) {
shstrtab = (char *)(ptr + shdr_ptr->sh_offset);
if (!strcmp(&shstrtab[shdr_ptr->sh_name], ".shstrtab"))
break;
}
shdr_ptr++;
}

/* list all of sections */
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
n = Elf32_ptr->e_shnum;
int i = 0;
while (n--) {
if (shdr_ptr->sh_type == SHT_REL || shdr_ptr->sh_type == SHT_RELA) {
printf("[%02d]%s type: 0x%x, offset: 0x%x, size: 0x%x\n", i++,
&shstrtab[shdr_ptr->sh_name], shdr_ptr->sh_type,
shdr_ptr->sh_offset, shdr_ptr->sh_size);

int n2 = (shdr_ptr->sh_size / sizeof(Elf32_Rel));
Elf32_Rel *rel = (Elf32_Rel *)(ptr + shdr_ptr->sh_offset);
while (n2--) {
printf("==== offset: 0x%x, sizeof(Elf32_Rel): 0x%x\n",
rel->r_offset, sizeof(Elf32_Rel));
}
}
shdr_ptr++;
}
}

static void symtab_parse(void *ptr)
{
Elf32_Shdr *shdr_ptr = NULL;
Elf32_Ehdr *Elf32_ptr = (Elf32_Ehdr *)ptr;


int n = Elf32_ptr->e_shnum;
char *shstrtab = NULL;

/*
* first of all, let's get the shstrtab, we'll get
* the name of each section with it
*/
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
while (n--) {
if (shdr_ptr->sh_type == SHT_STRTAB) {
shstrtab = (char *)(ptr + shdr_ptr->sh_offset);
if (!strcmp(&shstrtab[shdr_ptr->sh_name], ".shstrtab"))
break;
}
shdr_ptr++;
}

/* list all of sections */
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
n = Elf32_ptr->e_shnum;
int i = 0;
while (n--) {
if (shdr_ptr->sh_type == SHT_SYMTAB) {
printf("[%02d]%s type: 0x%x, offset: 0x%x, size: 0x%x\n", i++,
&shstrtab[shdr_ptr->sh_name], shdr_ptr->sh_type,
shdr_ptr->sh_offset, shdr_ptr->sh_size);

int n2 = (shdr_ptr->sh_size / sizeof(Elf32_Sym));
Elf32_Sym *sym = (Elf32_Sym *)(ptr + shdr_ptr->sh_offset);
while (n2--) {
printf("== value: 0x%x\n", sym->st_value);
sym++;
}
}
shdr_ptr++;
}
}

static void dynsym_parse(void *ptr)
{
Elf32_Shdr *shdr_ptr = NULL;
Elf32_Ehdr *Elf32_ptr = (Elf32_Ehdr *)ptr;


int n = Elf32_ptr->e_shnum;
char *shstrtab = NULL;

/*
* first of all, let's get the shstrtab, we'll get
* the name of each section with it
*/
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
while (n--) {
if (shdr_ptr->sh_type == SHT_STRTAB) {
shstrtab = (char *)(ptr + shdr_ptr->sh_offset);
if (!strcmp(&shstrtab[shdr_ptr->sh_name], ".shstrtab"))
break;
}
shdr_ptr++;
}

/* list all of sections */
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
n = Elf32_ptr->e_shnum;
int i = 0;
while (n--) {
if (shdr_ptr->sh_type == SHT_SYMTAB) {
printf("[%02d]%s type: 0x%x, offset: 0x%x, size: 0x%x\n", i++,
&shstrtab[shdr_ptr->sh_name], shdr_ptr->sh_type,
shdr_ptr->sh_offset, shdr_ptr->sh_size);

int n2 = (shdr_ptr->sh_size / sizeof(Elf32_Sym));
Elf32_Sym *sym = (Elf32_Sym *)(ptr + shdr_ptr->sh_offset);
while (n2--) {
printf("== value: 0x%x\n", sym->st_value);
sym++;
}
}
shdr_ptr++;
}
}

/*
* display the memory postion of members of hedr struct
*/
static void ehdr_show_addr(void *ptr)
{
Elf32_Ehdr *Elf32_ptr = (Elf32_Ehdr *)ptr;

printf("&e_ident: %p\n", &Elf32_ptr->e_ident);
printf("&e_entry: %p\n", &Elf32_ptr->e_entry);
printf("&e_flags: %p\n", &Elf32_ptr->e_flags);

}

static void ehdr_parse(void *ptr)
{
Elf32_Ehdr *Elf32_ptr = NULL;

Elf32_ptr = (Elf32_Ehdr *)ptr;
Elf32_Phdr *elf32_phdr = NULL;
int n;


printf("==================== EHDR ==================================\n");
printf("e_ident: %s\n", Elf32_ptr->e_ident);
printf("e_entry: %p\n", (void *)Elf32_ptr->e_entry);
printf("e_phoff: %ld\n", (unsigned long)Elf32_ptr->e_phoff);
printf("e_shoff: %ld\n", (unsigned long)Elf32_ptr->e_shoff);
printf("e_ehsize: %d\n", Elf32_ptr->e_ehsize & 0xffff);
printf("sizeof(Elf32_Ehdr): %d\n", sizeof(Elf32_Ehdr));
printf("e_phentsize: %d\n", Elf32_ptr->e_phentsize);
printf("e_phnum: %d\n", Elf32_ptr->e_phnum);
printf("e_shentsize: %d\n", Elf32_ptr->e_shentsize);
printf("e_shnum: %d\n", Elf32_ptr->e_shnum);
printf("e_shstrndx: %d\n", Elf32_ptr->e_shstrndx);
printf("==================== EHDR ==================================\n");

/* next, parse shdr */
shdr_parse(ptr + Elf32_ptr->e_shoff);
/* pdhr */
n = Elf32_ptr->e_phnum;
elf32_phdr = ptr + Elf32_ptr->e_phoff;
while (n--)
phdr_parse(elf32_phdr++);


}


int main(int argc, char *argv[])
{
int fd_src;
//size_t len = 0;
size_t filesize = 0;
void *ptr = NULL; /* ptr to binary file which mapped in memory */
if (argc != 2) {
printf("Usage: %s [ src bin ] ...\n", argv[0]);
exit(EXIT_FAILURE);
}

/*
* we'll calculate the file size then map to memory
*/
fd_src = open(argv[1], O_RDONLY);

if (fd_src < 0) {
printf("Failed to open %s!\n", argv[1]);
exit(EXIT_FAILURE);
}

/* get file size with lseek SEEK_END */
filesize = lseek(fd_src, 0, SEEK_END);
if (filesize < 0) {
perror("lseek failed!");
close(fd_src);
exit(EXIT_FAILURE);
}

ptr = mmap(0, filesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_src, 0);
if (ptr < 0) {
perror("mmap failed!");
close(fd_src);
exit(EXIT_FAILURE);
}

// ehdr_parse(ptr);
// ehdr_show_addr(ptr);
// shdr_parse(ptr);
/* phdr_parse(ptr); */
/* relocs_parse(ptr); */
dynsym_parse(ptr);

/* do the clean work */
munmap(ptr, filesize);
close(fd_src);

return EXIT_SUCCESS;
}

在开始旅程之前,最好阅读一些有关 elf 格式的内容,以便您更好地理解它,希望对您有所帮助。

关于c - 打开 ELF 文件并检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16176031/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com