.ko 文件分析小工具, 简易modinfo 工具(c 代码)


author: hjjdebug

date: 2026年 05月 09日 星期六 20:36:09 CST

descrip: .ko 文件分析小工具, 简易modinfo 工具(c 代码)


modinfo, 就是查找.ko文件的.modinfo 节,输出其中字符串的内容.

代码简单,只有88行, 但对elf64 格式却要求必需很清楚, 算elf 文件分析的一个小应用.

专门针对.ko文件(elf64格式)的分析工具

\$ wc -l modinfo.c

88 modinfo.c

\$ cat Makefile

all: modinfo

modinfo: modinfo.c

gcc -g -o modinfo modinfo.c

源代码:

cpp 复制代码
$ cat modinfo.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <elf.h>

/* 解析ELF .modinfo 节,打印模块所有信息 */
void parse_modinfo(const char *path)
{
    FILE *fp = fopen(path, "rb");
    if (!fp) {
        perror("fopen");
        return;
    }

    Elf64_Ehdr ehdr;
    // 读取ELF头部
    if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
        fprintf(stderr, "read ELF header failed\n");
        fclose(fp);
        return;
    }

    // 校验ELF魔数
    if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
        fprintf(stderr, "not a valid ELF file\n");
        fclose(fp);
        return;
    }

    // 读取节头表
    Elf64_Shdr *shdr = malloc(ehdr.e_shnum * sizeof(Elf64_Shdr));
    if (!shdr) {
        perror("malloc");
        fclose(fp);
        return;
    }

    fseek(fp, ehdr.e_shoff, SEEK_SET);
    fread(shdr, sizeof(Elf64_Shdr), ehdr.e_shnum, fp);

    // 找到节名字符串表
    Elf64_Shdr *strtab = &shdr[ehdr.e_shstrndx];
    char *shstr = malloc(strtab->sh_size);
    fseek(fp, strtab->sh_offset, SEEK_SET);
    fread(shstr, 1, strtab->sh_size, fp); //读取字符串表

    // 遍历所有节,找 .modinfo
    for (int i = 0; i < ehdr.e_shnum; i++) {
        char *sec_name = shstr + shdr[i].sh_name;

        if (strcmp(sec_name, ".modinfo") == 0) {
            // 读取 .modinfo 节内容
            char *mod_buf = malloc(shdr[i].sh_size);
            if (!mod_buf) {
                perror("malloc mod_buf");
                break;
            }
            fseek(fp, shdr[i].sh_offset, SEEK_SET);
            fread(mod_buf, 1, shdr[i].sh_size, fp);

            // 按 \0 分割每一个 modinfo 键值对
            char *p = mod_buf;
            while (p < mod_buf + shdr[i].sh_size) {
                if (*p == '\0') { p++; continue; }
                printf("%s\n", p);
                p += strlen(p) + 1;
            }

            free(mod_buf);
            break;
        }
    }

    free(shstr);
    free(shdr);
    fclose(fp);
}

int main(int argc, char **argv)
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <module.ko>\n", argv[0]);
        return 1;
    }

    parse_modinfo(argv[1]);
    return 0;
}

modinfo 输出实例

\$ ./modinfo ~/test/test_cdev/test_cdev.ko

description=Simplest Real Char Device Driver

license=GPL

srcversion=47E48C9BEF2BFCF3467D70B

depends=

retpoline=Y

name=test_cdev

vermagic=5.4.0-150-generic SMP mod_unload modversions

相关推荐
程序猿编码18 天前
给Linux程序穿“隐身衣”——ELF运行时加密器全解析(C/C++代码实现)
linux·c语言·c++·网络安全·elf·内存安全
拾光Ծ25 天前
吃透 Linux 静态库 / 动态库:ELF 文件、链接加载与进程地址空间详解
linux·动态库·静态库·elf·链接与加载·c/c++编程
程序猿编码1 个月前
隐匿注入型ELF加壳器:原理、设计与实现深度解析(C/C++ 代码实现)
c语言·网络·c++·elf·代码注入
liuluyang5303 个月前
AXF 文件转换为 BIN 文件方法
elf·编译文件·可执行文件转换
柏木乃一3 个月前
库的制作与原理(2)ELF格式,程序地址空间part2,程序加载
linux·服务器·c++·进程·elf··进程地址空间
hjjdebug4 个月前
elf 格式 relocation 概念
elf·symbol·reloc
程序猿编码5 个月前
恶意软件分析工具:ELF二进制文件的感染与分析原理(C/C++代码实现)
c语言·c++·网络安全·信息安全·elf·shellcode
再睡一夏就好5 个月前
深入理解Linux程序加载:从ELF文件到进程地址空间的完整旅程
linux·运维·服务器·c++·学习·elf
计算衎6 个月前
.c .o .a .elf .a2l hex map 这些后缀文件的互相之间的联系和作用
开发语言·elf·gcc·c/c++·a2l