Table of Contents
在分析Linux的内核CVE,或者是编写相关的POC,有时候可能结果与预期不太符合,这个时候就需要查看内核的运行过程。
KGDB
kgdb提供了一种使用 gdb调试 Linux 内核的机制。使用KGDB可以象调试普通的应用程序那样,在内核中进行设置断点、检查变量值、单步跟踪程序运行等操作。
编译内核
首先是去https://source.android.com/source/building-kernels
下载对应的内核源代码。
msm对应大部分的nexus以及pixel手机
git clone https://android.googlesource.com/kernel/msm.git
下面以nexus5x(bullhead)为例子,生成一个.config
$ export ARCH=arm64
$ export CROSS_COMPILE=aarch64-linux-android-
$ cd msm
$ git checkout android-msm-bullhead-3.10-nougat
$ make bullhead_defconfig
然后配置.config
$ make menuconfig
主要开启
[*] Kernel hacking
[*] Compile the kernel with debug info
[*] KGDB: kernel debugging with remote gdb —>
[*] Enable dynamic printk() call support
编译得到的arch/arm64/boot/Image
GDB调试
模拟器启动
emulator -verbose -show-kernel -netfast -avd -avd Pixel_API_25 -kernel arch/arm64/boot/Image -qemu -gdb tcp::1234,ipv4 -S
-verbose -show-kernel选项可以看到内核的详细输出,-no-window -no-audio选项可以不启动界面,-qumu -s -S选项可以启动调试监听让内核启动时在端口1234等待。
利用目标平台的gdb去加载vmlinux
aarch64-linux-android-gdb ./vmlinux
target remote localhost:1234
内核已经跑起来了,这个时候直接c就可以继续执行了。
优化问题
但是在调试的时候想查看具体的某个变量的时候,会发现:
(gdb) p copied
$1 = <optimized out>
但是在编译的时候默认是-O2优化,所以查看变量时会出现optimized out
gdb调试程序的时候打印变量值会出现
情况,可以在gcc编译的时候加上 -O0参数项,意思是不进行编译优化,调试的时候就会顺畅了,运行流程不会跳来跳去的,发布项目的时候记得不要在使用 -O0参数项,gcc 默认编译或加上-O2优化编译会提高程序运行速度.
并且很多时候程序跑的时候,代码也是对应不上的。
尝试用-O0的选项重新编译内核。
这个时候,编译内核代码会出现问题
In file included from ./arch/arm64/include/asm/bitops.h:19:0,
from include/linux/bitops.h:36,
from arch/arm64/mm/context.c:20:
In function '__xchg',
inlined from 'flush_context' at arch/arm64/mm/context.c:58:10:
include/linux/compiler.h:437:38: error: call to '__compiletime_assert_67' declared with attribute error: BUILD_BUG failed
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:420:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^
include/linux/compiler.h:437:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/bug.h:50:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^
include/linux/bug.h:84:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
^
./arch/arm64/include/asm/cmpxchg.h:67:3: note: in expansion of macro 'BUILD_BUG'
BUILD_BUG();
^
In function '__xchg',
inlined from 'check_and_switch_context' at arch/arm64/mm/context.c:153:9:
include/linux/compiler.h:437:38: error: call to '__compiletime_assert_67' declared with attribute error: BUILD_BUG failed
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:420:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^
include/linux/compiler.h:437:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/bug.h:50:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^
include/linux/bug.h:84:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
^
./arch/arm64/include/asm/cmpxchg.h:67:3: note: in expansion of macro 'BUILD_BUG'
BUILD_BUG();
内核代码很多地方就是依赖优化的,如果关闭的话,编译不过。
编译kernel不使用-O2的补丁,不过,没有尝试这个方法。 build kernel without -O2 option
最后一个可以靠谱的方法就是在部分代码中关闭优化。
参考
KGDB + Eclipse debug Kernel on i.mx6 Android