确定剥离的Linux内核映像的加载地址和入口点

kri*_*aex 5

我在x86 Linux上有一个用于嵌入式系统(mipsel)的交叉编译工具链.我知道如何为它构建一个自定义内核(让我们调用图像"vmlinux")以及如何通过

objcopy -S -O binary vmlinux vmlinux.bin
Run Code Online (Sandbox Code Playgroud)

为了进一步处理,我还需要图像的加载地址和入口点.在剥离之前,通过scripts/mksysmap或更明确地通过via 确定它们是没有问题的

nm -n vmlinux | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)' > System.map
Run Code Online (Sandbox Code Playgroud)

然后我可以确定加载地址和入口点

awk '/A _text/ { print "0x"$1; }' < _System.map
awk '/T kernel_entry/ { print "0x"$1; }' < System.map
Run Code Online (Sandbox Code Playgroud)

现在的挑战是,有时候我不是自己构建内核,而是在通过objcopy删除了它的符号后得到一个预构建的内核.谁能告诉我怎么做?我对内核构建和工具链的使用不是很熟练.这两种纳米和objdump的不喜欢剥图像,说

vmlinux.bin: File format not recognized
Run Code Online (Sandbox Code Playgroud)

ses*_*.jp 1

来自objcopy 手册页

objcopy 可用于通过使用二进制输出目标来生成原始二进制文件(例如,使用-O binary)。当 objcopy 生成原始二进制文件时,它本质上会生成输入对象文件内容的内存转储。所有符号和重定位信息都将被丢弃。内存转储将从复制到输出文件中的最低部分的虚拟地址开始。

下面是一个可以在 PowerPC 架构上使用的示例:

原始虚拟机Linux

bash-3.2$ file vmlinux
vmlinux: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), statically linked, not stripped
Run Code Online (Sandbox Code Playgroud)

剥离后的 vmlinux 被视为“数据”文件

bash-3.2$ file vmlinux.bin
vmlinux.bin: data
Run Code Online (Sandbox Code Playgroud)

将二进制转换为 PowerPC 的 ELF 格式

bash-3.2$ powerpc-440fp-linux-objcopy -I binary vmlinux.bin -B powerpc -O elf32-powerpc vmlinux.bin.x
Run Code Online (Sandbox Code Playgroud)

vmlinux 的输出现在被视为 ELF 文件

bash-3.2$ file vmlinux.bin.x
vmlinux.bin.x: ELF 32-bit MSB relocatable, PowerPC or cisco 4500, version 1 (SYSV), not stripped
Run Code Online (Sandbox Code Playgroud)

您必须传递-I、-B和-O参数。您可以从 objcopy 文档中获取此参数。

但是,由于您的二进制文件已被剥离,因此尝试反编译可能不值得,因为部分信息不可用。文件中的所有数据都将转储到 .data 部分。