Kernel Ctf 环境准备
Contents
内核准备
打开调试
make menuconfig
开启如下选项:
Kernel hacking -> Compile-time checks and compiler options -> Compile the kernel with debug info
Kernel hacking -> Generic Kernel Debugging Instruments -> KGDB: kernel debugger
qemu-system-x86_64 关闭 Kernel ALSR 以便于调试内核:
-append "nokaslr"
调试内核时,为了加载 vmlinux 符号表,必须额外指定 -append “nokaslr"以关闭 kernel ASLR。这样符号表才能正确的对应至内存中的指定位置,否则将无法给目标函数下断点,
还可以通过内核选项关闭aslr:
Processor type and features ---> [ ] Randomize the address of the kernel image (KASLR)
内核中的对齐宏:__ALIGN_KERNEL
|
|
其本质就是对齐的地位补0,以8字节对齐为例:
int size = 8; <----> 1000(bin)
计算a以size为倍数的下界数:
就让这个数(要计算的这个数)表示成二进制时,最后三位为0就可以达到这个目标。只要下面这个数与a进行"与运算"就可以了:
11111111 11111111 11111111 11111000
而上面这个数实际下就是 ~(size - 1),可以将该数称为size的对齐掩码size_mask.
#define alignment_up(a, size) ((a+size-1) & (~ (size-1)))
注: 上界数的计算方法,如果要求出比a大的是不是需要加上8就可以了?可是如果a本身就是8的倍数,这样加8不就错了吗,所以在a基础上加上(size - 1), 然后与size的对齐掩码进行与运算.
所以0x123 八字节对齐为:
|
|
debug 启动参数:
|
|
-S :表示启动后就挂起,等待 gdb 连接;
-gdb tcp::12345 也可以改成-s 表示:-gdb tcp::1234
此时启动gdb:
|
|
一个简单的启动脚本:
|
|
效果图:
module gdb
- 在module 的Makefile中添加:
EXTRA_CFLAGS += -g
- 加载 ko, 获取ko地址:
1 2 3
sudo insmod ./xxx.ko MOD_ADDR=$(sudo cat /sys/module/xxx/sections/.text) echo "Module .text address: $MOD_ADDR"
- gdb 中添加ko
1 2 3
(gdb) add-symbol-file /work/mymodule/xxx.ko 0xffffffffc0000000 (gdb) b your_function (gdb) c
- 调用程序触发断点,成功进入断点
查看ko中是否有 debug信息:
objdump --syms xxx.ko | grep debug
或者:
readelf -S xxx.ko | grep debug
查看断点: 输入 info breakpoints 或 i b 命令来查看所有断点。GEF 会以表格形式显示断点信息
delete
<断点编号>: 删除指定的断点。
disable
<断点编号>: 禁用指定的断点,使其不生效,但保留在断点列表中。
enable
<断点编号>: 启用已禁用的断点。
clear
<函数名:行号>: 清除指定位置的断点。