#1 楼
解压缩并加载内核后,您需要找到几个对压缩符号表进行编码的表。它们是(按照通常的顺序放置在二进制文件中):kallsyms_addresses
-内核中所有公共符号的地址表kallsyms_num_syms
-不是表,而只是一个带有符号总数的整数(应该与上一个表匹配)kallsyms_names
-长度固定的字节数组的列表,这些数组将索引编码到令牌表中kallsyms_token_table
-256个以符号结尾的零终止令牌的列表,kallsyms_token_index
-指向kallsyms_token_table
中相应条目的256个短裤通过一些经验,他们并不难找到。查找第一个的好方法是连续查找多个0xC0008000值,因为典型的内核符号表的开始是这样的:
C0008000 T __init_begin
C0008000 T _sinittext
C0008000 T _stext
C0008000 T stext
找到表后符号恢复是微不足道的。我为IDA编写了一个脚本,该脚本会自动执行此操作,您可以在此处找到它(工具zip中的
kallsyms.py
)。有关在内核中如何实现的更多详细信息,请参见
kernel/kallsyms.c
。评论
啊,这正是我想要的。谢谢!到目前为止,我已经能够识别kallsyms_addresses,kallsyms_num_syms和kall_syms_names。我以为我找到了另外两个,但是您的脚本无法对名称进行解码。我确定我做错了。似乎很难知道kallsyms_names表的大小。你有什么建议吗?再次感谢你!
–mrduclaw
13年4月26日在2:22
kallsyms_token_table应该很明显-它看起来类似于“ tcp _”,0,“ ca”,0,“ unc _”,0,...等。
–伊戈尔·斯科钦斯基♦
13年4月26日在2:49
该死的,我认为那是我找到的那个。我会再玩一点。我敢肯定,这对我来说真是不可思议。再次感谢!
–mrduclaw
2013年4月26日下午3:06
#2 楼
您提到您确实有一个正在运行的内核。通过读取/proc/kallsyms
可以从正在运行的内核中获取符号信息。在较新的发行版中,出于安全原因(默认情况下,所有信息都将显示为0x0地址),默认情况下将禁用此信息,但是您可以通过以root用户身份运行以下命令来手动启用它:echo 0 > /proc/sys/kernel/kptr_restrict
> 一旦获得了内核符号/地址对的列表,就可以轻松转换为所需的任何格式,例如用于导入的IDA
.idc
脚本。评论
@ 0xC0000022L他在评论中回答了您:“我有一个运行中的内核副本,可以存储/ proc / kallsyms,但它们没有地址,只有名称(地址显示为0)。”
–mncoppola
13-4-25在14:42
#3 楼
如果不亲自回答问题并根据问题和链接的答案验证一些假设,回答这个问题就比较棘手。但是,让我尝试一下,如果您进一步详细说明文件的某些方面,也许我们可以进一步扩展它。我们知道这是一个ARM文件,从您的描述来看,这听起来像是ARM内核映像为U-Boot。现在的问题是,我不知道那是不是真的,但是您可以在文件上运行经常提到的
binwalk
或firmware-mod-kit
,看看能给您带来什么。如果这是U-的ARM内核映像,引导,您可以通过跳过映像的前64个字节来获取
gzip
数据(请参阅StackOverflow上的此答案)。要点是:dd if=<image> of=<recovered file> bs=64 skip=1
这将跳过1个64字节的块,否则将数据从
<image>
写入<recovered file>
。从本质上讲,它部分扭转了U引导程序mkimage
的作用。现在,假设到目前为止一切正常,这是一个巨大的假设,您应该能够解压(
gzip -d
)生成的文件,最后得到可以希望的东西。如果是您,请使用grep
检查文件的类型,如果碰巧从文件中获取了有意义的信息,请进行进一步处理。如果不是,我将再次使用file
处理该文件,并在其上运行binwalk
失败。编辑x + 1: 。下载了这个Debian软件包,将其解压缩,得到一个
strings
,然后我在010 Editor中对其进行了查看,的确,根据标记,这是一个ARM内核映像(请参见下面的阅读部分):之后,我尝试跳过前64个字节,然后解压缩其余字节,无济于事。调查更多。
如果您使用此不完整的答案设法获得更多信息,请编辑您的问题,一旦发现您的修改,我将修改答案,以添加更多(希望是有用的)信息。
编辑x + 2 :
好吧,对于我所原始回答中提到的zImage而言,
zImage-2.6.28.10-power51
至少可以处理文件并输出:12900 0x3264 gzip compressed data, from Unix, last modified: Mon Jul 23 13:41:37 2012, max compression
可爱。让我们运行
binwalk
来提取dd
的东西,然后将其提取:dd if=zImage-2.6.28.10-power51 of=extract.gz bs=12900 skip=1 && gunzip extract.gz && ls -l extract
一旦我将其提取,在注意到
gzip
没有产生结果之后,我再次运行binwalk
: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
但是,我不想在没有您进一步输入的情况下立即进行操作。只是一个如何进行调查的示例。
file
还会再产生一个符号列表,但是由于我想您想要符号及其地址,因此我认为还有很多地方要研究。进一步阅读:
本文档将验证这是否确实是我们期望/假定的格式的ARM内核映像。特别要检查一下可以在偏移量
strings
处找到0x016F2818
的假设。您必须切断uRamdisk / uRecRam的64字节标头:0x24
dd if=uRamdisk of=uRamdisk.cpio.gz bs=64 skip=1
gunzip uRamdisk.cpi.gz
,这实际上意味着您必须期望在偏移量64处使用
cpio -i -F uRamdisk.cpio
(因此为CPIO格式)。也就是说,“内核映像”实际上是嵌入initrd
的旧内核格式(另请参见initrd
手册页)在“创建旧的旧版图片”下)。
评论
您认为在什么基础上有符号?它们可能已被剥离,因为仅需要它们(例如)来加载内核模块。如果所有内容都链接到内核,则不需要符号。 ARM在嵌入式设备上的使用不成比例,可能有充分的理由将符号剥离出来而不用担心尺寸。在(类似)运行的内核上(或在类似QEMU的仿真器中),您是否尝试过Igor的建议来查看符号是否存在?@ 0xC0000022L我有一个运行中的内核副本,可以存储/ proc / kallsyms,但它们没有地址,只有名称(地址显示为0)。我试图了解(1)这些名称是从哪里来的-我假设它来自压缩表,但是我对看到它很感兴趣。 (2)如何解析地址。
0xC0000022L保留符号是可以在菜单配置中选择的选项。没有符号,内核oops将毫无意义。我有充分的理由相信这些符号没有被剥离。
@Mellowcandle您是否偶然知道哪个菜单配置选项会删除符号?
@mrduclaw:公平地说,只是试图确保我们所有人都没有追赶鬼;)-Mellowcandle:如果大小是主要动机,那么内核OOPS本身就毫无意义,因为如果内核不适合设备,反正不会运行:)