加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

Linux ELF文件:静态和动态ELF程序的哪个字节不同?

发布时间:2020-12-13 23:01:58 所属栏目:Linux 来源:网络整理
导读:我正在使用 linux elf文件. 我想检测,如果给定的精灵程序静态链接(完全静态链接,ldd说“不是动态可执行文件”)或动态链接. ELF适用于嵌入式Linux,因此我不能只运行它或使用ldd实用程序. 我希望通过读取和检查一些字节在我的程序中完全执行此操作.我不想依赖
我正在使用 linux elf文件.

我想检测,如果给定的精灵程序静态链接(完全静态链接,ldd说“不是动态可执行文件”)或动态链接. ELF适用于嵌入式Linux,因此我不能只运行它或使用ldd实用程序.

我希望通过读取和检查一些字节在我的程序中完全执行此操作.我不想依赖文件实用程序或libelf,binutils等.

哪个字节会有所不同?

解决方法

如何在 μClibc使用 ldd.c?如果需要,删除任何不需要的依赖项/检查应该相当容易.我认为这是一个更聪明的方法,而不是试图找出阅读man 5精灵的所有角落情况,尽管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 filen");
        return 0;
    }

    if (eh->e_type != ET_EXEC && eh->e_type != ET_DYN) {
        printf("Not executable or shared objectn");
        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 architecturen");
        return 0;
    }

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读