CTF-All-In-One/doc/4.1_linux_kernel_debug.md
2018-04-12 22:16:00 +08:00

3.7 KiB
Raw Blame History

4.1 Linux 内核调试

准备工作

与用户态程序不同为了进行内核调试我们需要两台机器一台调试另一台被调试。在调试机上需要安装必要的调试器如GDB被调试机上运行着被调试的内核。

这里选择用 Ubuntu16.04 来展示,因为该发行版默认已经开启了内核调试支持:

$ cat /boot/config-4.13.0-38-generic | grep GDB
# CONFIG_CFG80211_INTERNAL_REGDB is not set
CONFIG_SERIAL_KGDB_NMI=y
CONFIG_GDB_SCRIPTS=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
# CONFIG_KGDB_TESTS is not set
CONFIG_KGDB_LOW_LEVEL_TRAP=y
CONFIG_KGDB_KDB=y

获取符号文件

下面我们来准备调试需要的符号文件。看一下该版本的 code name

$ lsb_release -c
Codename:	xenial

然后在下面的目录下新建文件 ddebs.list其内容如下注意看情况修改Codename

$ cat /etc/apt/sources.list.d/ddebs.list 
deb http://ddebs.ubuntu.com/ xenial      main restricted universe multiverse
deb http://ddebs.ubuntu.com/ xenial-security main restricted universe multiverse
deb http://ddebs.ubuntu.com/ xenial-updates  main restricted universe multiverse
deb http://ddebs.ubuntu.com/ xenial-proposed main restricted universe multiverse

http://ddebs.ubuntu.com 是 Ubuntu 的符号服务器。执行下面的命令添加密钥:

$ wget -O - http://ddebs.ubuntu.com/dbgsym-release-key.asc | sudo apt-key add -

然后就可以更新并下载符号文件了:

$ sudo apt-get update
$ uname -r
4.13.0-38-generic
$ sudo apt-get install linux-image-4.13.0-38-generic-dbgsym

完成后,符号文件将会放在下面的目录下:

$ file /usr/lib/debug/boot/vmlinux-4.13.0-38-generic 
/usr/lib/debug/boot/vmlinux-4.13.0-38-generic: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=f00f4b7ef0ab8fa738b6a9caee91b2cbe23fef97, not stripped

可以看到这是一个静态链接的可执行文件,使用 gdb 即可进行调试,例如这样:

$ gdb -q /usr/lib/debug/boot/vmlinux-4.13.0-38-generic 
Reading symbols from /usr/lib/debug/boot/vmlinux-4.13.0-38-generic...done.
gdb-peda$ p init_uts_ns 
$1 = {
  kref = {
    refcount = {
      refs = {
        counter = 0x2
      }
    }
  }, 
  name = {
    sysname = "Linux", '\000' <repeats 59 times>, 
    nodename = "(none)", '\000' <repeats 58 times>, 
    release = "4.13.0-38-generic", '\000' <repeats 47 times>, 
    version = "#43~16.04.1-Ubuntu SMP Wed Mar 14 17:48:43 UTC 2018", '\000' <repeats 13 times>, 
    machine = "x86_64", '\000' <repeats 58 times>, 
    domainname = "(none)", '\000' <repeats 58 times>
  }, 
  user_ns = 0xffffffff822517a0 <init_user_ns>, 
  ucounts = 0x0 <irq_stack_union>, 
  ns = {
    stashed = {
      counter = 0x0
    }, 
    ops = 0xffffffff81e2cc80 <utsns_operations>, 
    inum = 0xeffffffe
  }
}

获取源文件

/etc/apt/sources.list 里的 deb-src 行都取消掉注释:

$ sed -i '/^#\sdeb-src /s/^#//' "/etc/apt/sources.list"

然后就可以更新并获取 Linux 内核源文件了:

$ sudo apt-get update
$ mkdir -p ~/kernel/source
$ cd ~/kernel/source
$ apt-get source $(dpkg-query '--showformat=${source:Package}=${source:Version}' --show linux-image-$(uname -r))
$ ls linux-hwe-4.13.0/
arch     CREDITS     debian.master  firmware  ipc      lib          net      security        tools   zfs
block    crypto      Documentation  fs        Kbuild   MAINTAINERS  README   snapcraft.yaml  ubuntu
certs    debian      drivers        include   Kconfig  Makefile     samples  sound           usr
COPYING  debian.hwe  dropped.txt    init      kernel   mm           scripts  spl