如何确定Linux内核'uImage'的构建版本?

Jam*_*mie 4 linux-kernel

我正在尝试追踪内核二进制文件; 有没有办法确定Linux'uImage'二进制文件的版本(构建字符串)?

运行

strings uImage
Run Code Online (Sandbox Code Playgroud)

通过各种拖尾grep声明导致我认为我正在处理压缩图像...

小智 6

根据内核的格式规范,这里是C代码:

kver.c

#include <stdio.h>

int main(int argc, char** argv){
    if (argc > 1){
        FILE* f = fopen(argv[1], "r");
        short offset = 0;
        char str[128];
        if(f){
            fseek(f, 0x20E, SEEK_SET);
            fread(&offset, 2, 1, f);
            fseek(f, offset + 0x200, SEEK_SET);
            fread(str, 128, 1, f);
            str[127] = '\0';
            printf("%s\n", str);
            fclose(f);
            return 0;
        }else {
            return 2;
        }
    } else {
        printf("use: kver [kernel image file]\n");
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

编译并运行:

gcc -o kver kver.c
./kver /boot/vmlinux-something
Run Code Online (Sandbox Code Playgroud)


小智 5

要找出已编译的Linux版本,请strings在未压缩的vmlinux映像上使用该实用程序.

例如:

strings linux-src/build/build-generic/vmlinux|grep "Linux version"

样本输出:

Linux version 3.2.0-56-generic (root@puerto-cayo) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #86 SMP Fri Nov 1 10:24:18 EDT 2013 (Ubuntu 3.2.0-56.86-generic 3.2.51)


Nic*_*ght 3

我刚刚意识到,我可以立即访问的内核确实将版本字符串未压缩地存储在标头中。strings uImage | grep 2.6对于任何 2.6 内核来说应该足够好,它几乎涵盖了过去 5 年多的所有内容)。

(原答案如下)


理论上这是可能的,但并非完全微不足道。

现代 Linux 内核版本使用名为 bzImage 的格式(适用于 x86/x86_64,其他平台上的 YMMV)。它实际上由一个 ELF 标头和一些其他细节(如一些解压缩代码)组成,后面是实际内核的压缩映像。

传统上,压缩算法是 zlib(与流行的误解相反,“bzImage”并不代表“bzipped image”,而是代表“big zImage”——原始 zImage 格式无法处理大内核),尽管 2.6 之后的版本.30还支持bzip2和LZMA。

您可能需要做的是准确确定压缩数据的开始位置(抱歉,无法帮助您,但尝试和错误可能会起作用),并编写一些代码以通过库运行它以选择哪种压缩算法正在使用中。