gpt4 book ai didi

Linux ELF 文件 : Which byte will differ for static and dynamic ELF programs?

转载 作者:IT王子 更新时间:2023-10-29 01:24:46 25 4
gpt4 key购买 nike

我正在使用 linux elf 文件。

我想检测给定的 elf 程序是静态链接的(完全静态链接,ldd 表示“不是动态可执行文件”)还是动态链接的。 ELF 适用于嵌入式 Linux,所以我不能直接运行它或使用 ldd 实用程序。

我想通过读取和检查一些字节完全在我的程序中完成此操作。我不想依赖 file 实用程序或 libelf、binutils 等。

哪些字节会不同?

最佳答案

如何使用 ldd.c来自 μClibc ?如果你愿意,应该很容易去掉任何不需要的依赖项/检查。我认为这是一种比试图通过阅读 man 5 elf 找出所有极端情况更聪明的方法,尽管 FWIW 它看起来只是检查 PT_INTERP 程序头作为你在评论中怀疑。

更新:还有一些检查。我试图提取相关部分,但我不确定是否遗漏了任何内容,因此请自行检查。该代码检查 32 位和 64 位 x86 ELF 文件。它采用小端架构。

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <ctype.h>
#include <inttypes.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

#include <elf.h>

int main(int argc, char* argv[])
{
const char* fname = argv[0];
if (argc >= 2) fname = argv[1];

int fd;
struct stat st;
void *mapping;

if ((fd = open(fname, O_RDONLY)) == -1) {
perror(fname);
return 1;
}

if (fstat(fd, &st)) {
perror("fstat");
close(fd);
return 1;
}

if ((mapping = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
perror("mmap");
close(fd);
return 1;
}
const Elf32_Ehdr* eh = mapping;

if (st.st_size < (off_t)sizeof(Elf32_Ehdr) ||
eh->e_ident[EI_MAG0] != ELFMAG0 ||
eh->e_ident[EI_MAG1] != ELFMAG1 ||
eh->e_ident[EI_MAG2] != ELFMAG2 ||
eh->e_ident[EI_MAG3] != ELFMAG3 ||
eh->e_ident[EI_VERSION] != EV_CURRENT) {
printf("Not a valid ELF file\n");
return 0;
}

if (eh->e_type != ET_EXEC && eh->e_type != ET_DYN) {
printf("Not executable or shared object\n");
return 0;
}

int is_dynamic = 0;

// change as appropriate, but remember that byteswapping might be needed in some cases
if (eh->e_ident[EI_CLASS] == ELFCLASS32 && eh->e_ident[EI_DATA] == ELFDATA2LSB && eh->e_machine == EM_386) {
uint16_t ph_cnt;
for (ph_cnt = 0; ph_cnt < eh->e_phnum; ph_cnt++) {
const Elf32_Phdr* ph = (const Elf32_Phdr*)((const uint8_t*)mapping + eh->e_phoff + ph_cnt * eh->e_phentsize);
if (ph->p_type == PT_DYNAMIC || ph->p_type == PT_INTERP) {
is_dynamic = 1;
}
}
} else if (eh->e_ident[EI_CLASS] == ELFCLASS64 && eh->e_ident[EI_DATA] == ELFDATA2LSB && eh->e_machine == EM_X86_64) {
const Elf64_Ehdr* eh = mapping;
uint16_t ph_cnt;
for (ph_cnt = 0; ph_cnt < eh->e_phnum; ph_cnt++) {
const Elf64_Phdr* ph = (const Elf64_Phdr*)((const uint8_t*)mapping + eh->e_phoff + ph_cnt * eh->e_phentsize);
if (ph->p_type == PT_DYNAMIC || ph->p_type == PT_INTERP) {
is_dynamic = 1;
}
}
} else {
printf("Unsupported architecture\n");
return 0;
}

munmap(mapping, st.st_size);
close(fd);
printf("%s: %sdynamic\n", fname, is_dynamic?"":"not ");
return 0;
}

关于Linux ELF 文件 : Which byte will differ for static and dynamic ELF programs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7298365/

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