📜  如何提取和反汇编 Linux 内核

📅  最后修改于: 2022-05-13 01:56:11.567000             🧑  作者: Mango

如何提取和反汇编 Linux 内核

如果您想查找一些有故障的代码或想要检查各种函数的入口点,那么提取和检查 Linux 内核的反汇编汇编代码会非常有用。一旦您知道所需的必要工具,该过程就相当直观。

下面的过程是针对 Ubuntu 20.04 描述的,但也适用于其他基于 GNU/Linux 的操作系统。我们将使用所有 Ubuntu 发行版预装的 objdump 命令行实用程序。要检查它是否已安装并正常工作,请在您的终端上键入以下内容,您应该会看到有关该程序的版本和许可证信息。

objdump --version

Linux 内核可执行文件称为vmlinuz 。这是我们启动计算机时首先加载到内存中的可执行文件,这就是我们将要反汇编的内容。该文件位于/boot/目录下。然而,它被压缩了。我们必须先使用 Linux 头文件附带的 extract-vmlinux脚本在反汇编之前提取它。

步骤 1:将压缩的内核可执行文件复制到其他位置:
首先,我们将在我们选择的位置创建内核的副本,然后cd进入该目录。此步骤需要超级用户权限。

mkdir ~/kernel-tmp
sudo cp /boot/vmlinuz-$(uname -r) ~/kernel-tmp
cd kernel-tmp

第 2 步:提取内核:
现在我们将提取我们复制到目录中的压缩内核。我们将使用我们的 Linux 头文件附带的 extract-vmlinux 脚本。



sudo /usr/src/linux-headers-$(uname -r)/scripts/extract-vmlinux vmlinuz-$(uname -r) > decomp-vmlinuz

上面的命令将为我们的内核副本运行 extract-vmlinux脚本,并将其输出到一个名为decomp-vmlinuz的文件中,该文件将位于我们当前的工作目录下。

第 3 步:拆卸:
我们现在准备反汇编解压后的可执行文件。只需运行以下命令

objdump -D decomp-vmlinuz > disassembled-vmlinuz.asm

现在可以在 dissassembled-vmlinuz.asm文件中找到反汇编的内核代码。

第 4 步:寻找符号:
反汇编的内核文件没有符号,因此我们不能很容易地找到函数的起点。 Linux 将所有符号名称及其起始地址存储在一个单独的文件中。为了便于访问,我们还将复制该文件。

sudo cp /boot/System.map-$(uname -r) ./

现在,我们可以轻松地在System.map-xxx-xx-generic文件中搜索我们的符号名称以获取起始地址,然后我们可以在dissassembled-vmlinuz.asm文件中查找该地址。
例如,我们可以 grep for register_keyboard_notifier

sudo cat System.map-$(uname -r) | grep register_keyboard_notifier

这将给出一个有点像的输出:

ffffffff816ec720 T register_keyboard_notifier

我们可以复制起始地址并在反汇编的内核代码中搜索它以找到如下内容:

ffffffff816ec720:    e8 4b 13 98 ff           callq  0xffffffff8106da70
ffffffff816ec725:    55                       push   %rbp
ffffffff816ec726:    48 89 fe                 mov    %rdi,%rsi
ffffffff816ec729:    48 c7 c7 a0 f7 d8 82     mov    $0xffffffff82d8f7a0,%rdi
ffffffff816ec730:    48 89 e5                 mov    %rsp,%rbp
ffffffff816ec733:    e8 18 bb 9d ff           callq  0xffffffff810c8250
...