Igor之前在 SO 上发布了一个关于 ARM 上 Linux 内核映像格式的很好的答案。
假设我无法启动我的内核映像,有人可以指导我在二进制文件中找到这个压缩符号表吗?
Igor之前在 SO 上发布了一个关于 ARM 上 Linux 内核映像格式的很好的答案。
假设我无法启动我的内核映像,有人可以指导我在二进制文件中找到这个压缩符号表吗?
解压并加载内核后,您需要找到几个对压缩符号表进行编码的表。这些是(按照通常的顺序,它们以二进制形式放置):
kallsyms_addresses
- 内核中所有公共符号的地址表kallsyms_num_syms
- 不是一个表格,而只是一个带有符号总数的整数(应该匹配上一个表格)kallsyms_names
- 将索引编码到令牌表中的长度前缀字节数组列表kallsyms_token_table
- 256 个以零结尾的标记的列表,从中构建符号名称kallsyms_token_index
- 256 空头指向相应的入口 kallsyms_token_table
他们不难找到一些经验。找到第一个的好方法是连续查找几个 0xC0008000 值,因为典型的内核符号表是这样开始的:
C0008000 T __init_begin
C0008000 T _sinittext
C0008000 T _stext
C0008000 T stext
找到表后,符号恢复就很简单了。我为 IDA 制作了一个自动执行的脚本,您可以在此处(kallsyms.py
在工具 zip 中)找到它。
有关如何在内核中实现的更多详细信息,请参阅kernel/kallsyms.c
。
您提到您确实有一个正在运行的内核可用。可以通过读取从正在运行的内核中获取符号信息/proc/kallsyms
。在较新的发行版上,出于安全原因,默认情况下禁用此信息(所有符号将显示为 0x0 地址),但您可以通过以 root 身份运行以下命令来手动启用它:
echo 0 > /proc/sys/kernel/kptr_restrict
一旦您获得了内核符号/地址对的列表,就可以很容易地将其转换为所需的任何格式,例如.idc
用于导入的 IDA脚本。
如果不让我接触文件并根据问题和链接的答案验证一些假设,回答这个问题有点棘手。但是,让我尝试一下,如果您详细说明文件的某些方面,也许我们可以进一步扩展它。
我们知道这是一个 ARM 文件,根据您的描述,这听起来很像U-Boot 的 ARM 内核映像。现在的问题是我不知道这是否属实,但是您可以运行经常提到的binwalk
或firmware-mod-kit
文件中的内容来查看它给了您什么。
如果这是U-Boot的 ARM 内核映像,您可能可以gzip
通过跳过映像的前 64 字节来获取数据(请参阅StackOverflow 上的此答案)。要点是:
dd if=<image> of=<recovered file> bs=64 skip=1
此跳过的64个字节块1和以其他方式从写入数据<image>
到<recovered file>
。从本质上讲,它逆转了 - 部分 -mkimage
工具的影响,这是 U-Boot 的一部分。
现在,假设到目前为止一切正常 - 这是一个巨大的假设 - 您应该能够解压缩 ( gzip -d
) 生成的文件并最终得到一些您希望的结果grep
。如果我是你,我会用它file
来检查它是什么类型的文件,如果我碰巧从中得到任何有意义的东西,则进一步处理它。如果没有,我会binwalk
再次处理该文件并在其上运行失败strings
。
编辑 x+1:
好的,我自己尝试了这个过程。下载了这个 Debian 包,解压,得到一个zImage-2.6.28.10-power51
,然后我在 010 编辑器中查看,这是真的,根据标记,这是一个 ARM 内核映像(请参阅下面的阅读部分):
之后,我尝试跳过第一个 64 字节,然后解压缩其余部分,但无济于事。多调查一下。
如果您设法使用这个不完整的答案获得更多信息,请编辑您的问题,一旦我注意到您的编辑,我将修改我的答案,以添加更多(希望有用)信息。
编辑 x+2:
好的,对于有问题的 zImage 事实证明binwalk
,在我的原始答案中提到,至少可以处理文件和输出:
12900 0x3264 gzip compressed data, from Unix, last modified: Mon Jul 23 13:41:37 2012, max compression
迷人的。让我们运行dd
以提取这些gzip
东西,然后提取它:
dd if=zImage-2.6.28.10-power51 of=extract.gz bs=12900 skip=1 && gunzip extract.gz && ls -l extract
一旦我提取它,我binwalk
注意到file
没有产生结果后再次运行:
DECIMAL HEX DESCRIPTION
-------------------------------------------------------------------------------------------------------
135456 0x21120 gzip compressed data, from Unix, last modified: Mon Jul 23 13:38:47 2012, max compression
973460 0xEDA94 ELF
1070320 0x1054F0 CramFS filesystem, big endian size 2126262976 CRC 0xdc0a0e1, edition 4040895977, 78662882 blocks, 271618533 files
但是,如果没有您的进一步输入,我现在不想继续。只是一个例子它如何能进行调查。还有一件事strings
确实会生成一个符号列表,但由于我认为您想要符号及其地址,因此我认为还有更多内容需要调查。
0x016F2818
可以在 offset 处找到的假设0x24
。这个论坛条目,特别是用户fattire的帖子,其中提到
您必须从 uRamdisk/uRecRam 中截取一个 64 字节的标头:
dd if=uRamdisk of=uRamdisk.cpio.gz bs=64 skip=1
gunzip uRamdisk.cpi.gz
cpio -i -F uRamdisk.cpio
这实质上意味着您必须期望initrd
在偏移量 64 处有一个(因此是 CPIO 格式)。也就是说,“内核映像”实际上是嵌入的旧内核格式initrd
(另请参阅mkimage
“创建旧遗留”下的手册页图片”)。