双机调试Linux内核

说明

使用woboq_codebrowser阅读Linux内核源代码这篇文章讲了如何看Linux源代码.本篇文章则是讲如何动态调试Linux内核代码.
在大佬的帮助下,花了半天的时间终于搭建好了Linux双击调试了.整个过程也是极端的复杂,需要设置的东西也是非常的多.

配置

本文双机调试Linux内核的配置如下:

  • VMWARE
  • 需要被调试的内核,本文选择的是4.17.0版本
  • 宿主机Ubuntu(这个没有要求,Windows或者是MacOS都可以)

CentOS7安装Kernel4.17

本文采用的是双机调试,直接使用Centos7作为内核的载体.由于Centos7默认的内核版本是3.10,为了调试了4.17,我们需要手动在Centos7上面安装4.17的内核,同时配置内核调试的选项.

下载所需内核

下载内核 4.17

解压

解压到/usr/src/kernels文件下,在此文件中存在当前系统所有的内核.

1
$ tar -xvf  linux-4.17.tar.xz -C /usr/src/kernels

加入调试Patch

根据这篇文章Re: [PATCH 0/5] kernel hacking: GCC optimization for debug experience (-Og)内核默认情况下都是开启了编译优化的,不方便我们进行动态调试.我们可以将这个篇文章中提供的5个patch加上去手动地关闭掉内核的编译优化.直接将所有的patch文件放至到/usr/src/kernels/linux-4.17文件中,使用patch -p1<nameofpatch.patch,以此安装所有的patch文件.

配置内核选项

接下来就是配置内核选项.为了调试方便,我们直接使用当前3.10内核的配置,之后再开启内核的调试符号.

  1. cp config-3.10.0-1062.4.3.el7.x86_64 /usr/src/kernels/linux-4.17/.config 使用当前系统3.10的内核配置选项
  2. make menuconfig 设置与内核调试有关的选项.需要配置的选项包括:
    1. 关闭Virtualization选项
    2. Kernel hacking/compile-time checks and compiler options 开启Compile the kernel with debug info选项,开启Disable compiler atuo-inline optimization和Optimize for better debugging experience选项(如果正确地打上了patch,就会开启这两个选项)
    3. 完成上面的配置之后,就会在当前目录生成.config文件.注释 CONFIG_DEBUG_RODATA_TEST 选项.(否则内核的text section将是只读的)

安装新内核模块

1
$ make && make modules_install && make headers_install && make install

关闭内核地址随机化保护

编辑 /etc/default/grub文件,修改GRUB_CMDLINE_LINUX增加nokalsr

1
GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet nokaslr"

关闭内核地址随机化;之后写入到grub2中.

1
sudo grub2-mkconfig -o /boot/grub2/grub.cfg 刷新grub2

重启测试

重启Centos7的虚拟机.如果以上配置成功,界面就会出现Centos4.17.0的内核选项,进入之后界面会出现Disable nokalsr的文字.

配置VMWARE

在对应的vmware的ceont7.vmx中加入如下的选项,让vmware支持内核调试.

1
2
3
4
debugStub.listen.guest64 = "TRUE" 
debugStub.listen.guest64.remote = "TRUE"
debugStub.hideBreakpoints = "FALSE"
monitor.debugOnStartGuest64 = "TRUE"

需要在关闭Centos7虚拟机的情况下添加上述选项

GDB远程调试

进入到 /usr/src/kernels/linux-4.17将其中vmlinux复制到我们的宿主机中(在本例中是ubuntu).vmlinux就是内核会运行的带符号表的内核镜像文件.之后我们使用gdb进行调试.
VMware虚拟机的调试服务是在主机的回环端口8864(32位虚拟机是8832),用gdb连接服务,调试虚拟机

1
2
3
4
$ gdb
(gdb) file vmlinux
(gdb) target remote 127.0.01:8864
(gdb) c

接下来就可以使用gdb肆意调试Linux内核了。

总结

下载内核的源代码就接近100M,但看内核整个的架构犹如盲人摸象,建议根据一个具体的功能点进行跟踪。

参考

linux内核漏洞调试:配置双机调试环境
2018.08 ubuntu 内核源码调试方法(双机调试)
在qemu环境中用gdb调试Linux内核
Linux环境下通过Vmware调试内核及模块
Linux关闭KASLR