Linux Kernel 调试环境配置
由于本人用的 Windows 虚拟机为 Hyper-v,希望能在 wsl 中调试 hyper-v 中的虚拟机,网上关于这个的内容比较少,做一下记录
设置串口
hyper-v 有点弱智,不能在 GUI 界面设置串口,只能从 powershell 设置串口路径,下述命令会将虚拟机内的 /dev/ttyS0
映射到 windows 的 \\.\pipe\ubuntu-rootkit
管道
1 | ❯ Get-VMComPort Ubuntu-20.04-rootkit |
参考自:hyper-v-generation-2-virtual-machines-part-5
为了方便调试,还需要在 wsl 中使用命令来把 windows 的串口映射到 linux 下的 pty
npiperelay: https://github.com/jstarks/npiperelay
1 | socat pty,link=./ubuntu-rootkit.pty,raw,echo=0 EXEC:"/mnt/d/tools/wsl/npiperelay.exe -ep -s //./pipe/ubuntu-rootkit",nofork |
配置 grub
修改 grub 配置文件是为了关闭 kaslr 以及设置 kgdb 调试用的串口信息。设置 kgdb 调试用的串口信息可以在系统启动后再进行设置,但是关闭 kaslr 只能修改 grub 的 kernel 启动参数。
若是不关闭 kaslr,在调试时栈帧符号可能会出现问题
关闭 kaslr:
未关闭 kaslr:
修改配置文件推荐在 /etc/grub.d/40_custom
直接添加 grub 启动项,旧启动项来自 /boot/grub/grub.cfg
, 添加了 kgdboc=ttyS0,115200 kgdbcon nokaslr
- kgdboc: kgdb over console
- kgdboc=ttyS0,115200 使用 ttyS0 连接,串口频率 115200
- 也可以通过 echo “ttyS0,115200” > /sys/module/kgdboc/parameters/kgdboc 进行配置
- kgdbwait: 启动阶段时进入调试模式
- nokaslr: 关闭 kaslr
- kgdbcon: 当 gdb 连接到内核时,kgdbcon 特性允许查看 gdb 内部的 printk() 消息。有两个方式激活该特性
- kgdbcon 内核参数
- echo 1 > /sys/module/kgdb/parameters/kgdb_use_con
- 不要在系统控制台使用这个参数
ubuntu 20.04 配置文件 /etc/grub.d/40_custom
1 | menuentry 'Ubuntu,KGDB with nokaslr' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-1d1a1fdb-e548-44f2-9e1f-5d230b6179e9' { |
配置资料来自: https://www.kernel.org/doc/htmldocs/kgdb/kgdbreboot.html
为了方便进入自己的 grub 启动项,可以修改 grub 配置文件 /etc/default/grub
中的 GRUB_TIMEOUT
进行完上述操作后需要执行命令让 grub 根据当前配置文件生成对应的启动文件
1 | update-grub |
中断 kernel
使用命令触发中断让 kernel 进入调试模式
1 | echo g > /proc/sysrq-trigger |
gdb 附加调试
内核调试信息可以在下面的网址找到,当前内核为 5.4.0-52
1 | http://ddebs.ubuntu.com/pool/main/l/linux/linux-image-unsigned-5.4.0-52-generic-dbgsym_5.4.0-52.57_amd64.ddeb |
解压出 vmlinux-5.4.0-52-generic
pwndbg,peda 对内核的支持好像有问题,建议使用 peda
1 | gdb ./vmlinux-5.4.0-52-generic |
在内核已经被中断的情况下可以看到当前寄存器信息:
加载源码
内核调试往往需要结合源码进行
1 | gef➤ set substitute-path /sources/were/compiled/here /put/sources/here |
或者把 kernel 源码解包到 /usr/src/kernel
或者 kernel build 的目录
GEF 配置 layout
1 | legend regs stack code args source memory threads trace extra |
根据个人习惯修改为
1 | gef config context.layout "regs code args source stack" |