我正在尝试追踪内核二进制文件; 有没有办法确定Linux'uImage'二进制文件的版本(构建字符串)?
运行
strings uImage
Run Code Online (Sandbox Code Playgroud)
通过各种拖尾grep声明导致我认为我正在处理压缩图像...
小智 6
根据内核的格式规范,这里是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)
我刚刚意识到,我可以立即访问的内核确实将版本字符串未压缩地存储在标头中。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。
您可能需要做的是准确确定压缩数据的开始位置(抱歉,无法帮助您,但尝试和错误可能会起作用),并编写一些代码以通过库运行它以选择哪种压缩算法正在使用中。