网上其实已经有很多大牛们发过关于Linux内核调试环境搭建的文章,但是我在使用的时候或多或少都遇到过一些这样或那样的问题。这方面之前确实也踩了很多坑,不过最终的实现效果,我觉得对我自己而言还算是比较完美的一个调试环境。这篇文章也谈不上是教程或者什么的,只是自己站在前辈们的肩膀上,自己做了一些微调,然后现在把它share出来;OK现在我们开始:)
【演示视频】
既然要写这个话题,主要是因为之前自己搭建Linux调试环境的时候总会有一些用起来不是很舒适的情况,比如:
1、省硬盘空间省CPU省内存:全调试环境占用空间不到30GB(比上述情况2缩减一半),只需要VMware启动一个虚拟机实例即可。节省CPU和内存资源。2、调试会话交互速度快:调试时可随时用Ctrl+C方式断下,而且速度很快,比named pipe方式调试明显感官上感觉速度快很多(因为使用了IP+端口方式调试而非串口调试)3、可对被调试系统的物理内存和特权寄存器进行读写,所以调试脏牛没问题。4、内核编译速度快:如果需要重新编译内核,每次仅需20分钟。这是在我2015款Macbook上编译所消耗的时间,不惧编译失败:)5、目标机安装啥版本内核都可以,即便是想使用512MB内存启动内核都可以:)不再有上面情况4所说的问题。6、不会有上面情况6那种抓狂BUG7、这个环境可以:一键使用Syzkaller进行Kernel Fuzzing;一键启动内核;一键调试内核;一键打开内核编译选项;一键编译内核;8、被调试机器启动速度快,在15秒左右(仍然是在我老掉牙的2015款Macbook上测试的时间)
1、VMware安装至可用(不推荐Virtualbox,用过一段时间,总感觉有很多隐形BUG)2、VMware上安装一个Ubuntu(建议最新版)3、在VMware中配置该Ubuntu虚拟机的CPU选项,打开所有与虚拟化相关的选项。CPU核心数设置的大一些,比如我设置了4(注意这里其实只在需要编译的情况下才需要设置4,一般情况下如果只是调试漏洞设置1就可以)。内存我设置了2GB。
4、建议在VMware中设置Ubuntu虚拟机的兼容性升级到最新版。
其实聪明的小伙伴看到本文第2部分的时候,就可能会猜到我这个环境是基于Syzkaller那个环境基础上修改的
参考Google的这篇Syzkaller搭建帮助文档(https://github.com/google/syzkaller/blob/master/docs/linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md)。需要注意的几个地方:
1、注意上述的Syzkaller搭建文档中的Kernel小节,本小节中所有的make命令(make defconfig、make kvmconfig、make oldconfig等命令)一概不需要执行,只需要执行一条命令即可:“make bzImage -j8 && make vmlinux -j8”(划重点!!每次修改内核代码后直接这么编译就行了,不放心的话就在执行这条make命令之前make clean一下,依然只需要20分钟或更短时间)。这条命令不会编译模块,只会编译bzImage和vmlinux两个文件,所以速度会大幅提高。注意最后的-j8是因为我为Ubuntu配置了4核。这里的数字不要太大,最好就是核心数*2。否则make过程可能会导致Ubuntu直接秒重启,看不到任何报错(之前遇到过的坑)2、如果需要Syzkaller,则需将上述文档中所有步骤全部操作完,否则最后一步Syzkaller部分不用做3、原文档中的那个sshd启动脚本(在文档中搜索sshd关键字可找到),在其中加两行,分别为 -s和 -cpu host。-s是让qemu开启gdbserver,并在1234端口监听,-cpu host是让qemu内跑的Linux内核以为当前CPU和真机CPU一个型号(在某些漏洞调试环境下有用,建议保持开启)。我的修改后的qemu启动脚本如下:qemu-system-x86_64 \ -kernel $KERNEL/arch/x86/boot/bzImage \ -append "console=ttyS0 root=/dev/sda nokaslr slub_debug=P kmemleak=off"\ -hda $IMAGE/stretch.img \ -net user,hostfwd=tcp::2222-:22 -net nic \ -enable-kvm \ -cpu host \ -nographic \ -serial mon:stdio \ -m 1G \ -s \ -smp 1 \ -pidfile Kernel.Boot.pid \ 2>&1 | tee Kernel.Boot.log4、一键调试脚本:cd Linux-Kernel && gdb vmlinux --eval-command="target remote tcp::1234"
1、注意上述的Syzkaller搭建文档中的Kernel小节,本小节中所有的make命令(make defconfig、make kvmconfig、make oldconfig等命令)一概不需要执行,只需要执行一条命令即可:“make bzImage -j8 && make vmlinux -j8”(划重点!!每次修改内核代码后直接这么编译就行了,不放心的话就在执行这条make命令之前make clean一下,依然只需要20分钟或更短时间)。这条命令不会编译模块,只会编译bzImage和vmlinux两个文件,所以速度会大幅提高。注意最后的-j8是因为我为Ubuntu配置了4核。这里的数字不要太大,最好就是核心数*2。否则make过程可能会导致Ubuntu直接秒重启,看不到任何报错(之前遇到过的坑)
2、如果需要Syzkaller,则需将上述文档中所有步骤全部操作完,否则最后一步Syzkaller部分不用做
3、原文档中的那个sshd启动脚本(在文档中搜索sshd关键字可找到),在其中加两行,分别为 -s和 -cpu host。-s是让qemu开启gdbserver,并在1234端口监听,-cpu host是让qemu内跑的Linux内核以为当前CPU和真机CPU一个型号(在某些漏洞调试环境下有用,建议保持开启)。我的修改后的qemu启动脚本如下:
qemu-system-x86_64 \ -kernel $KERNEL/arch/x86/boot/bzImage \ -append "console=ttyS0 root=/dev/sda nokaslr slub_debug=P kmemleak=off"\ -hda $IMAGE/stretch.img \ -net user,hostfwd=tcp::2222-:22 -net nic \ -enable-kvm \ -cpu host \ -nographic \ -serial mon:stdio \ -m 1G \ -s \ -smp 1 \ -pidfile Kernel.Boot.pid \ 2>&1 | tee Kernel.Boot.log4、一键调试脚本:cd Linux-Kernel && gdb vmlinux --eval-command="target remote tcp::1234"
qemu-system-x86_64 \ -kernel $KERNEL/arch/x86/boot/bzImage \ -append "console=ttyS0 root=/dev/sda nokaslr slub_debug=P kmemleak=off"\ -hda $IMAGE/stretch.img \ -net user,hostfwd=tcp::2222-:22 -net nic \ -enable-kvm \ -cpu host \ -nographic \ -serial mon:stdio \ -m 1G \ -s \ -smp 1 \ -pidfile Kernel.Boot.pid \ 2>&1 | tee Kernel.Boot.log
cd Linux-Kernel && gdb vmlinux --eval-command="target remote tcp::1234"
Q:为什么内核编译速度快了(只需20分钟左右)?A:我觉得因为只编译了 bzImage和vmlinux文件,没编译其他内核模块,所以速度变快了。这里有个tips,就是可以输入make help命令,查看make后面到底可以接哪些子命令。Q:如何对目标机的物理内存进行读写操作?A:在目标机命令行窗口中,按下Ctrl+A组合键后,再单独按下C键一次,即可完成从qemu前端和后端的切换。进入后端后输入help命令可看到qemu的内置命令。比如xp命令可以读目标机的物理内存空间。但是qemu貌似没提供目标机物理内存写的能力。但是这里有一个Trick:)就是利用qemu的gpa2hva命令。这个命令可以将目标机的物理地址转化为qemu进程的虚拟地址。所以需要对目标机的某个物理地址进行写时,可以将该目标机的物理地址先用gpa2hva命令转化为qemu进程的虚拟地址,然后再启用一个gdb attach住qemu进程,再对该虚拟地址进行写操作即可。Q:在VMware中再启动一个QEMU虚拟机,在QEMU中的运行速度不会慢么?A:理论上不会影响很多(感官上也没什么影响,反而因为只启动内核而不像发行版Linux那样需要加载很多软件,速度其实快了很多),根本原因是因为Nested虚拟化技术,所以速度很快。
Q:为什么内核编译速度快了(只需20分钟左右)?
A:我觉得因为只编译了 bzImage和vmlinux文件,没编译其他内核模块,所以速度变快了。这里有个tips,就是可以输入make help命令,查看make后面到底可以接哪些子命令。
Q:如何对目标机的物理内存进行读写操作?
A:在目标机命令行窗口中,按下Ctrl+A组合键后,再单独按下C键一次,即可完成从qemu前端和后端的切换。进入后端后输入help命令可看到qemu的内置命令。比如xp命令可以读目标机的物理内存空间。但是qemu貌似没提供目标机物理内存写的能力。但是这里有一个Trick:)就是利用qemu的gpa2hva命令。这个命令可以将目标机的物理地址转化为qemu进程的虚拟地址。所以需要对目标机的某个物理地址进行写时,可以将该目标机的物理地址先用gpa2hva命令转化为qemu进程的虚拟地址,然后再启用一个gdb attach住qemu进程,再对该虚拟地址进行写操作即可。
Q:在VMware中再启动一个QEMU虚拟机,在QEMU中的运行速度不会慢么?
A:理论上不会影响很多(感官上也没什么影响,反而因为只启动内核而不像发行版Linux那样需要加载很多软件,速度其实快了很多),根本原因是因为Nested虚拟化技术,所以速度很快。
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法