首页
社区
课程
招聘
[原创]逆向进入内核时代之APatch源码学习(01.模拟调试环境搭建, 远离拦路虎)
发表于: 2024-8-28 10:35 38990

[原创]逆向进入内核时代之APatch源码学习(01.模拟调试环境搭建, 远离拦路虎)

2024-8-28 10:35
38990

最近在讲解Linux内核kernel patch的实现原理, 其中不乏优秀的开源项目和内核大神, APatch就是其中之一.

APatch借鉴了magisk patch init和selinux的方式在内核层实现了hook(注意b跳转相关hook, 非inlinehook). 思维巧妙有较高的学习意义.

但是在上手探究原理的过程中, 如果使用真机的方式, 简单修改就会卡机, 需要重刷等.

好的环境是好的开始的前提, 因为我们是探究其原理, 简单过一下项目其实现方式与平台无关, 因此可以通过内核模拟的方式, 使用GDB探究其中的每一步实现, 完美规避.

系统环境配置【必备】
强烈建议使用Ubuntu22.04(8b2K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3#2A6M7Y4u0G2M7W2)9J5k6h3&6B7N6g2)9J5k6h3g2V1N6g2)9J5k6h3y4F1i4K6u0r3N6h3u0#2L8Y4c8#2i4K6u0V1M7X3g2D9k6h3q4K6k6i4y4Q4x3V1j5J5x3W2)9J5k6e0l9@1i4K6u0W2y4q4)9J5c8Y4g2T1N6h3&6@1N6g2)9J5k6o6t1J5i4K6u0W2x3o6c8Q4x3X3f1@1i4K6u0V1k6r3g2K6K9%4c8G2M7q4)9J5k6r3q4E0k6o6j5@1i4K6u0W2K9i4y4G2i4@1g2r3i4@1u0o6i4K6R3&6

安装Qemu

注意:不同的qemu版本可能起始的物理地址不同,本人电脑使用ubuntu22.04自带版本,6.2.0

要求:最好自己折腾, 也可以使用我准备好的。
b2dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6F1P5X3y4$3i4K6u0r3d9$3g2J5L8X3g2D9f1r3q4@1j5$3S2c8c8f1#2g2i4K6u0r3M7X3g2D9k6h3q4K6k6i4y4Q4x3V1k6@1j5h3N6Q4x3V1k6V1k6i4j5I4i4K6u0W2x3q4)9J5k6e0M7`.(手动编译查看github/workflow)
1.1 使用交叉编译器或者直接官方网站下载:

1.2 下载4.15.2内核

1.3 快速编译命令

要求:最好自己折腾,也可以使用已修改版本

1.1 参考链接
a79K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8X3I4A6N6i4W2A6L8X3N6Y4N6h3V1I4y4U0y4Q4x3V1k6S2M7Y4c8A6j5$3I4W2i4K6u0r3k6r3g2@1j5h3W2D9M7#2)9J5c8U0p5J5y4U0R3%4y4K6p5I4y4l9`.`.
3f3K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3#2Q4x3X3g2T1L8r3!0Y4i4K6u0W2j5$3S2A6L8X3q4#2L8X3W2^5i4K6u0W2L8X3g2@1i4K6u0r3N6h3W2V1i4K6u0V1x3U0p5@1x3e0V1#2x3K6m8Q4x3X3c8A6k6q4)9J5k6o6f1^5x3K6f1K6z5e0W2Q4x3X3g2Z5N6r3#2D9

6.1 编译busybox
27bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1N6i4y4&6j5X3!0^5i4K6u0W2L8X3g2@1i4K6u0r3k6r3!0%4L8X3I4G2j5h3c8K6i4K6u0r3i4K6y4r3b7#2)9K6c8p5#2Q4x3@1u0a6i4K6y4p5c8q4)9J5z5r3u0#2M7%4W2T1L8%4S2Q4x3U0V1`.

6.2 制作initrd

// makefile

它是针对地址处的入口点进行编译的0x40080000。
这个确切的地址来自 QEMU 虚拟设备的设计:
0x00000000 - 0x3FFFFFFF是内存映射外设的区域。使用此范围内的地址,您可以访问多个外设的寄存器来配置和控制它们,就像我们使用位于 0x09000000UART 的输出寄存器将文本字符串输出到终端一样。
0x40000000 - 0x4007FFFF是为引导加载程序保留的区域。
并且内核(或任何裸机应用程序)正在加载到地址 0x40080000。外围设备的寄存器
初始地址,即您的内核将被加载到的位置取决于引导加载程序的实现,如果您使用现有的硬件或模拟器,那么您很可能会处理现有的引导加载程序,它会将您的内核文件加载到某个预定义的地址。
2. 断点调试验证

f72K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6D9k6h3u0J5x3r3&6D9K9g2)9J5c8V1N6q4f1l9`.`. (GDB必备)
0c7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4k6h3u0Q4x3X3g2E0K9i4c8Q4x3X3g2W2k6s2g2Q4x3V1k6Y4L8Y4g2Q4x3V1k6V1L8$3y4Q4x3V1k6Z5N6r3#2D9i4K6u0r3k6$3c8T1i4K6g2X3y4#2)9J5k6h3S2@1L8h3H3`. (下断点)

内核启动后, 可以通过gdb单步调试理解其中细节

9.1 因为内核在被执行之前还有bootloader的存在, 还记得前面qemu的bootloader实现么???

内核启动后我第一步想法是第一行运行代码是什么, 在什么位置呢, 对应的参数又是什么? 我的第一步想法是汇编入口加入延时.

入口延时

在汇编入口加入延时调试, 方便查看地址:

qemu bootloader传入的参数

前面只是自己编译内核并跑了起来, Apatch对应的APK功能包含boot.img解包并提取内核, 进行patch. 因为我们已经有了内核文件
所以可以直接命令行patch

Patched后再到qemu环境里面去跑起来看看吧?? 相信你一定会有所收获

fb1K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6*7K9s2g2S2L8X3I4S2L8W2)9J5k6i4A6Z5K9h3S2#2i4K6u0W2j5$3!0E0i4K6u0r3M7q4)9J5c8U0x3@1y4e0t1K6x3U0b7#2z5b7`.`.
441K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1K9h3I4A6j5X3W2D9K9g2)9J5k6h3y4G2L8g2)9J5c8Y4k6A6k6r3g2G2i4K6u0r3b7W2j5I4d9$3b7@1P5e0q4d9y4%4c8h3i4K6t1^5h3o6R3$3i4K6u0o6i4@1f1@1i4@1u0p5i4K6R3$3i4@1f1#2i4K6S2r3i4@1q4r3i4@1f1@1i4@1u0n7i4@1p5#2i4@1f1#2i4K6R3H3i4K6W2r3i4@1f1&6i4K6R3&6i4@1t1@1j5Y4g2K6P5h3u0G2P5q4!0q4y4g2)9^5z5q4!0n7y4W2!0q4y4q4!0n7c8q4)9&6b7#2)9J5z5b7`.`.
b87K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2*7K9r3W2Z5N6g2)9J5k6h3y4G2L8g2)9J5c8Y4m8W2L8%4m8D9k6g2)9J5c8X3&6G2j5X3!0V1P5g2)9#2k6X3E0F1L8%4N6Q4x3V1k6H3L8%4y4@1M7H3`.`.
161K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6*7K9s2g2S2L8X3I4S2L8W2)9J5k6i4A6Z5K9h3S2#2i4K6u0W2j5$3!0E0i4K6u0r3M7q4)9J5c8U0j5$3y4K6f1J5y4e0f1I4y4l9`.`.
a56K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2S2M7X3#2Q4x3X3g2U0L8$3#2Q4x3V1k6V1L8%4N6F1L8r3!0S2k6s2y4Q4x3V1k6Q4x3X3c8Q4x3V1k6S2M7X3#2Q4x3X3c8Y4L8Y4g2Q4x3X3c8@1L8$3!0D9j5$3S2S2K9h3&6Q4x3X3c8V1L8%4N6F1L8r3!0S2k6s2x3`.

图片描述

sudo apt update
sudo apt-get install qemu qemu-system qemu-user
root@happy /s/qemu_linux# qemu-system-aarch64 --version
QEMU emulator version 6.2.0 (Debian 1:6.2+dfsg-2ubuntu6.19)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
sudo apt update
sudo apt-get install qemu qemu-system qemu-user
root@happy /s/qemu_linux# qemu-system-aarch64 --version
QEMU emulator version 6.2.0 (Debian 1:6.2+dfsg-2ubuntu6.19)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
sudo apt-get update
sudo apt-get install gcc-10-aarch64-linux-gnu
sudo mv  /usr/bin/aarch64-linux-gnu-gcc-10  /usr/bin/aarch64-linux-gnu-gcc
sudo apt-get update
sudo apt-get install gcc-10-aarch64-linux-gnu
sudo mv  /usr/bin/aarch64-linux-gnu-gcc-10  /usr/bin/aarch64-linux-gnu-gcc
> curl -L -O https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.15.2.tar.gz
> curl -L -O https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.15.2.tar.gz
sudo apt-get install git
git clone https://github.com/nzcv/KernelPatchQEMU.git
 
cd KernelPatchQEMU
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
sudo apt-get install git
git clone https://github.com/nzcv/KernelPatchQEMU.git
 
cd KernelPatchQEMU
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
//使用工程内部直接patch
patch lib/Kconfig.debug < ../patch/Kconfig.debug.patch
//使用工程内部直接patch
patch lib/Kconfig.debug < ../patch/Kconfig.debug.patch
make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
//default and save exit
make defconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
make -j8 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
 
其他配置:
CONFIG_DEBUG_KERNEL=y
make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
//default and save exit
make defconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
make -j8 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
 
其他配置:
CONFIG_DEBUG_KERNEL=y
make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
Settings  --->
[*] Build static binary (no shared libs)    //静态编译
[*] Build with debug information            //可选,带调试信息,方便后续调试
make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
Settings  --->
[*] Build static binary (no shared libs)    //静态编译
[*] Build with debug information            //可选,带调试信息,方便后续调试
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- install
find . | cpio -o --format=newc > ../rootfs.img
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- install
find . | cpio -o --format=newc > ../rootfs.img
init:
    cd ./initramfs && find . -print0|cpio --null -ov --format=newc|gzip -9>../build/initramfs.cpio.gz
 
run:
    qemu-system-aarch64 -kernel Image -initrd build/initramfs.cpio.gz -m 1G -nographic --append "earlyprintk=serail,ttyS0 console=ttyS0"
 
run2:
    qemu-system-aarch64  -M virt -cpu cortex-a57 -smp 1 -m 1G  -kernel Image  -nographic  -append "console=ttyAMA0 root=/dev/vda oops=panic panic_on_warn=1 panic=-1 ftrace_dump_on_oops=orig_cpu debug earlyprintk=serial slub_debug=UZ" -initrd build/initramfs.cpio.gz
 
old:
    cp ../linux-4.15.2/arch/arm64/boot/Image .
    qemu-system-aarch64  -M virt -cpu cortex-a57 -smp 1 -m 1G  -kernel Image  -nographic  -append "console=ttyAMA0 oops=panic panic_on_warn=1 panic=-1 ftrace_dump_on_oops=orig_cpu debug earlyprintk=serial slub_debug=UZ root=/dev/ram rdinit=/bin/sh" -initrd rootfs.img.gz -S -gdb tcp::9000
 
patch:
    qemu-system-aarch64  -M virt -cpu cortex-a57 -smp 1 -m 1G  -kernel Image2  -nographic  -append "console=ttyAMA0 oops=panic panic_on_warn=1 panic=-1 ftrace_dump_on_oops=orig_cpu debug earlyprintk=serial slub_debug=UZ root=/dev/ram rdinit=/bin/sh" -initrd rootfs.img.gz -S -gdb tcp::9000
init:
    cd ./initramfs && find . -print0|cpio --null -ov --format=newc|gzip -9>../build/initramfs.cpio.gz
 
run:
    qemu-system-aarch64 -kernel Image -initrd build/initramfs.cpio.gz -m 1G -nographic --append "earlyprintk=serail,ttyS0 console=ttyS0"
 
run2:
    qemu-system-aarch64  -M virt -cpu cortex-a57 -smp 1 -m 1G  -kernel Image  -nographic  -append "console=ttyAMA0 root=/dev/vda oops=panic panic_on_warn=1 panic=-1 ftrace_dump_on_oops=orig_cpu debug earlyprintk=serial slub_debug=UZ" -initrd build/initramfs.cpio.gz
 
old:
    cp ../linux-4.15.2/arch/arm64/boot/Image .
    qemu-system-aarch64  -M virt -cpu cortex-a57 -smp 1 -m 1G  -kernel Image  -nographic  -append "console=ttyAMA0 oops=panic panic_on_warn=1 panic=-1 ftrace_dump_on_oops=orig_cpu debug earlyprintk=serial slub_debug=UZ root=/dev/ram rdinit=/bin/sh" -initrd rootfs.img.gz -S -gdb tcp::9000
 
patch:
    qemu-system-aarch64  -M virt -cpu cortex-a57 -smp 1 -m 1G  -kernel Image2  -nographic  -append "console=ttyAMA0 oops=panic panic_on_warn=1 panic=-1 ftrace_dump_on_oops=orig_cpu debug earlyprintk=serial slub_debug=UZ root=/dev/ram rdinit=/bin/sh" -initrd rootfs.img.gz -S -gdb tcp::9000
static const ARMInsnFixup bootloader_aarch64[] = {
    { 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
    { 0xaa1f03e1 }, /* mov x1, xzr */
    { 0xaa1f03e2 }, /* mov x2, xzr */
    { 0xaa1f03e3 }, /* mov x3, xzr */
    { 0x58000084 }, /* ldr x4, entry ; Load the lower 32-bits of kernel entry */
    { 0xd61f0080 }, /* br x4      ; Jump to the kernel entry point */
    { 0, FIXUP_ARGPTR_LO }, /* arg: .word @DTB Lower 32-bits */
    { 0, FIXUP_ARGPTR_HI}, /* .word @DTB Higher 32-bits */
    { 0, FIXUP_ENTRYPOINT_LO }, /* entry: .word @Kernel Entry Lower 32-bits */
    { 0, FIXUP_ENTRYPOINT_HI }, /* .word @Kernel Entry Higher 32-bits */
    { 0, FIXUP_TERMINATOR }
};
static const ARMInsnFixup bootloader_aarch64[] = {
    { 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
    { 0xaa1f03e1 }, /* mov x1, xzr */
    { 0xaa1f03e2 }, /* mov x2, xzr */
    { 0xaa1f03e3 }, /* mov x3, xzr */
    { 0x58000084 }, /* ldr x4, entry ; Load the lower 32-bits of kernel entry */
    { 0xd61f0080 }, /* br x4      ; Jump to the kernel entry point */
    { 0, FIXUP_ARGPTR_LO }, /* arg: .word @DTB Lower 32-bits */
    { 0, FIXUP_ARGPTR_HI}, /* .word @DTB Higher 32-bits */
    { 0, FIXUP_ENTRYPOINT_LO }, /* entry: .word @Kernel Entry Lower 32-bits */
    { 0, FIXUP_ENTRYPOINT_HI }, /* .word @Kernel Entry Higher 32-bits */
    { 0, FIXUP_TERMINATOR }

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-9-25 17:26 被周晓梦Chew编辑 ,原因:
收藏
免费 15
支持
分享
最新回复 (9)
雪    币: 1503
活跃值: (3694)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2024-8-28 11:25
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
感谢分享,跟着楼主学习
2024-8-28 15:10
0
雪    币: 4960
活跃值: (14952)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
4
大apatch时代开启!
2024-8-28 17:05
3
雪    币: 123
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
自己定制自己的APatch,我把财富都留在了内核
2024-8-29 10:53
1
雪    币: 5
活跃值: (3010)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
apatch太好用了
2024-8-29 15:28
0
雪    币: 257
活跃值: (280)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
涿州飞神 自己定制自己的APatch,我把财富都留在了内核
是的, 财富都留在了内核
2024-8-30 10:34
0
雪    币: 5141
活跃值: (4940)
能力值: ( LV10,RANK:171 )
在线值:
发帖
回帖
粉丝
8
感谢分享!!
2024-9-2 10:06
0
雪    币: 257
活跃值: (280)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
珍惜Any 大apatch时代开启!
大航海时代,现在越来越卷了,路飞都太阳神了。我最开始接触20年那个时候,那个时候在内核做分析的人好少
2024-9-8 20:34
0
雪    币: 257
活跃值: (280)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10

补录上视频链接 【0基础入门Linux内核安全】 



最后于 2024-9-23 11:03 被周晓梦Chew编辑 ,原因:
2024-9-23 11:02
0
游客
登录 | 注册 方可回帖
返回