三、Android系统内核编译及刷机实战 (修改反调试标志位)
来源:互联网 发布:java线程并发实战视频 编辑:程序博客网 时间:2024/06/05 01:01
前言
在 二、Android系统源码编译及刷机实战 一文中,我们成功编译了Android 4.4.4_r1源码并刷入系统了 Nexus 5 设备,下面是设置界面的信息。上面显示的内核版本信息是3.4.0-gd59db4e
,内核的编译时间是Mon Mar 17 15:16:36 PDT 2014
,也就是说内核之前就已经编译过了,我们编译系统源码的时候并没有编译内核源码!那么编译好的内核文件放在了哪里呢?答案是device/<vendor>/<name>
目录,针对Nexus 5 设备,就是device/lge/hammerhead-kernel
目录
系统源码和内核源码是可以分开编译的,如果仅仅对内核修改,就没必要编译系统源码。所以下面的过程是在假设我们没有下载系统源码的情况下操作的!为了编译成功,没下载系统源码的同学一定要 参考 一、Android系统源码下载实战一文把编译环境配置一下。类似于Android源码根目录,可以新建一个内核编译项目的根目录文件夹AndroidKernal
,把后面的各种操作下载在该目录下进行。至于已经下载系统源码的同学,就在Android系统源码根目录下新建kernel
文件夹作为根目录。Google 官方教程:https://source.android.com/source/building-kernels
一、选择内核项目
我们首先应当确定自己设备所对应的内核。Google官方给出了二进制文件的名称及内核源代码所在Android源码树中的位置:(这时内核源代码还没有下载本地)
各个版本内核源码项目所对应的下载命令:Google也给出了相应的下载命令:
$ git clone https://android.googlesource.com/kernel/common.git$ git clone https://android.googlesource.com/kernel/hikey-linaro$ git clone https://android.googlesource.com/kernel/x86_64.git$ git clone https://android.googlesource.com/kernel/exynos.git$ git clone https://android.googlesource.com/kernel/goldfish.git$ git clone https://android.googlesource.com/kernel/msm.git$ git clone https://android.googlesource.com/kernel/omap.git$ git clone https://android.googlesource.com/kernel/samsung.git$ git clone https://android.googlesource.com/kernel/tegra.git
由于网络连接问题,可以把上面所有
git clone
命令中https://android.googlesource.com/
网址换成清华镜像站的https://aosp.tuna.tsinghua.edu.cn/
网址。
各个内核项目所支持的设备
goldfish
项目包含适用于所模拟的平台的内核源代码。msm
项目包含适用于 ADP1、ADP2、Nexus One、Nexus 4、Nexus 5、Nexus 6、Nexus 5X、Nexus 6P、Nexus 7 (2013)、Pixel 和 Pixel XL 的源代码,可用作使用 Qualcomm MSM 芯片组的起点。omap
项目用于 PandaBoard 和 Galaxy Nexus,可用作使用 TI OMAP 芯片组的起点。samsung
项目用于 Nexus S,可用作使用 Samsung Hummingbird 芯片组的起点。tegra
项目用于 Xoom、Nexus 7 (2012)、Nexus 9,可用作使用 NVIDIA Tegra 芯片组的起点。exynos
项目包含适用于 Nexus 10 的内核源代码,可用作使用 Samsung Exynos 芯片组的起点。x86_64
项目包含适用于 Nexus Player 的内核源代码,可用作使用 Intel x86_64 芯片组的起点。hikey-linaro
项目用于 HiKey 参考板,可用作使用 HiSilicon 620 芯片组的起点。
我用是Nexus 5手机, 代号 harmmerhead
(锤头),查找上表知道,内核二进制文件所在系统源码树的device/lge/hammerhead-kernel
目录,内核源码在系统源码树的kernel/msm
目录,内核对应的编译配置为hammerhead_defconfig
, 该版本内核项目对应的下载命令为
git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm.git
二、下载内核源码项目,检出内核分支代码
msm
内核项目是Google公司针对高通msm移动芯片组(骁龙处理器)而开发的内核项目,我们在之前创建的AndroidKernel
目录下执行git命令下载该项目(已经下载Android系统源码的同学在系统根目录下创建kernel
目录下进行下载)
$ git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm.git
这时msm
项目的.git
仓库 下载到了新创建的msm
目录中,而msm内核的代码还没有从本地.git
仓库中检出来,所以整个msm
目录空空的。
进入 msm
目录后,查看msm项目的所有分支。下面的只列出了Nexus 5(代号:harmmerhead)相关的内核分支
aosp444@aosp444-virtual-machine:~/AndroidKernel/msm$ git branch -a* master remotes/origin/HEAD -> origin/master remotes/origin/android-4.4 remotes/origin/android-4.4.y remotes/origin/android-msm-2.6.35 remotes/origin/android-msm-3.9-usb-and-mmc-hacks...... remotes/origin/android-msm-hammerhead-3.4-kitkat-mr1 remotes/origin/android-msm-hammerhead-3.4-kitkat-mr2 remotes/origin/android-msm-hammerhead-3.4-kk-fr1 remotes/origin/android-msm-hammerhead-3.4-kk-fr2 remotes/origin/android-msm-hammerhead-3.4-kk-r1 remotes/origin/android-msm-hammerhead-3.4-l-preview remotes/origin/android-msm-hammerhead-3.4-lollipop-mr1 remotes/origin/android-msm-hammerhead-3.4-lollipop-mr1.1 remotes/origin/android-msm-hammerhead-3.4-lollipop-release remotes/origin/android-msm-hammerhead-3.4-m-preview remotes/origin/android-msm-hammerhead-3.4-marshmallow remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr1 remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr2 remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr3......
该检出哪个分支呢?由于我不是特别熟悉git 命令操作,并不能根据git日志详细区分各个版本之间的区别。AOSP前技术领导人Jean-Baptiste Queru在给一位内核开发提交者的邮件中写道,在安卓分支后缀中,mr = "maintenance release", fr = "factory rom".
,分支的名字在开发中是不断变化,最好以commid id
进行提交。那么我们就以commid id
进行检出。官方给出的实例是按分支名进行下载,但是我暂时确定不了分支,所以采用了commid id
这种方式。
那么我们怎么获得内核的版本信息与其中commid id
呢?
官方给出了一条通用的命令,来获得指定二进制内核文件的版本信息
dd if=kernel bs=1 skip=$(LC_ALL=C grep -a -b -o $'\x1f\x8b\x08\x00\x00\x00\x00\x00' kernel | cut -d ':' -f 1) | zgrep -a 'Linux version'
例:
而Nexus 5 设备的内核名为zImage-dtb
,官方给出的针对该设备的命令是:
$ dd if=zImage-dtb bs=1 skip=$(LC_ALL=C od -Ad -x -w2 zImage-dtb | grep 8b1f | cut -d ' ' -f1 | head -1) | zgrep -a 'Linux version'
事实上,我们可以在设置 > 关于手机 > 内核版本
中直接查看内核版本信息,也可以通过cat /proc/version
命令查看。内核版本信息的格式为kernel version-gXXXXXXX
,其中 XXXXXXX
部分的值是git提交中 的short commit id
的值(即kernel version-g<short commit id>
),short commit id
的值为commit id
值的前7位。Nexus 5 设备Adnroid 4.4.4_r1
版本 AOSP自带的内核值是`3.4.0-gd59db4e
, 并且刷入手机能正常运行。
检出带代码有两种方式(推荐第二种):
一、直接 short commit id = d59db4e
来检出分支。
$ git checkout d59db4e
检出代码后的msm
目录:
二、确定 short commit id 所在的分支,按分支进行检出(推荐)
在本地 git clone
msm
项目后,本地只有一个’master’ 分支,我们可以执行git branch -r --contains d59db4e
命令来查看包含 d59db4e
commit id 的分支
然后我们可以在远程分支的基础上在本地分化出一个新的分支来
$ git checkout -b android-msm-hammerhead-3.4-kitkat-mr2 origin/android-msm-hammerhead-3.4-kitkat-mr2
我们输入git log
命令,发现d59db4e
值就是android-msm-hammerhead-3.4-kitkat-mr2
最后一次提交的 short commit id
三、下载预编译工具链,添加路径到PATH中
1.下载 gcc交叉编译工具链
之前下载过AOSP源码树的同学,就不用再下载预编译工具链了,AOSP跟目录中后该工具链。没有下载AOSP源码树的同学,在AndroidKernel
目录下执行该执行进行下载:
$ git clone https://aosp.tuna.tsinghua.edu.cn/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6
2.配置交叉工具链路径到环境变量中
已经下载 AOSP源码树的同学,进入的源码树根目录下 ,重新执行source build/envsetup.sh
命令就会自动配置好环境变量。
没有下载源树的同学,在AndroidKernel目录下执行export PATH=$(pwd)/arm-eabi-4.6/bin:$PATH
就会配置到环境变量中。
注意上述两种方法都是在命令行中配置的,计算机重启后会消失需重新配置,可将交叉编译工具的的bin路径写到~/.bashrc
文件中
四、配置编译选项,进行编译
编译前,一定要确定交叉工具链的路径在PATH
变量中。
在内核交叉编译前,配置一下编译选项
$ export ARCH=arm //指明目标体系架构,arm、x86、arm64、$ export CROSS_COMPILE=arm-eabi- //指定使用的交叉编译器的前缀
进入到msm
目录,配置
$ cd msm$ make hammerhead_defconfig
执行 make
命令进行编译
$ make
编译成功后,会提示
这时会在arch/arm/boot/
目录生成 Image
、zImage
、zImage-dtb
三个文件 。其中zImage-dtb
就是之前使用的内核二进制文件。
五、对boot.img 文件进行重打包
一、准备bootimg-tools工具
bootimg-tools工具是一款基于mkbootimg开发的boot.img 解包重打包C语言工具,github地址:https://github.com/pbatard/bootimg-tools
在乌班图上用下面的命令下载:
$ git clone https://github.com/pbatard/bootimg-tools.git
下载后进入bootimg-tools
目录,执行make
命令编译该项目,在 makebootimg目录下生成了相应的二进制执行文件,将该二进制文件所在路径添加到 PATH
路径中
$ make
二、使用 unmkbootimg
二进制文件进行解包
$ unmkbootimg -i boot.img
解包后生成 kernel
和 ramdisk.cpio.gz
两个文件
三、用unmkbootimg
将之前编译生成的 zImage-dtb
替换kernel
进行重打包
$ mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x00008000 --ramdisk_offset 0x02900000 --second_offset 0x00f00000 --tags_offset 0x02700000 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1' --kernel zImage-dtb --ramdisk ramdisk.cpio.gz -o bootnew.img
六、将新生成的bootnew.img刷入设备
输入下面的命令进入fastboot 模式,并解锁
$ adb reboot bootloader$ fastboot oem unlock
在bootloader
模式下输入下面的命令将bootnew.img
刷入boot
分区
$ fastboot flash boot bootnew.img
七、修改内核源码中的调试标志位
如果我们用推荐的第二种方式下载内核源码,输入git branch
命令可以查看当前已经切换到分支
我们可用git 工具对修改的内核源码进行版本控制。
下面修改相应的调试标志位:
第一处 msm/fs/proc/base.c
文件 273行 proc_pid_wchan
函数修改为(主要对285行进行了修改)
static int proc_pid_wchan(struct task_struct *task, char *buffer){ unsigned long wchan; char symname[KSYM_NAME_LEN]; wchan = get_wchan(task); if (lookup_symbol_name(wchan, symname) < 0) if (!ptrace_may_access(task, PTRACE_MODE_READ)) return 0; else return sprintf(buffer, "%lu", wchan); else{ if (strstr(symname, "trace")) { return sprintf(buffer, "%s", "sys_epoll_wait"); } return sprintf(buffer, "%s", symname); }}
第二处 msm/fs/proc/array.c
文件 134行
static const char * const task_state_array[] = { "R (running)", /* 0 */ "S (sleeping)", /* 1 */ "D (disk sleep)", /* 2 */ "S (sleeping)", /* 4 */ "S (sleeping)", /* 8 */ "Z (zombie)", /* 16 */ "X (dead)", /* 32 */ "x (dead)", /* 64 */ "K (wakekill)", /* 128 */ "W (waking)", /* 256 */};
第三处 msm/fs/proc/array.c
文件 180行
seq_printf(m, "State:\t%s\n" "Tgid:\t%d\n" "Pid:\t%d\n" "PPid:\t%d\n" "TracerPid:\t%d\n" "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), task_tgid_nr_ns(p, ns), pid_nr_ns(pid, ns), ppid, /*tpid*/0, cred->uid, cred->euid, cred->suid, cred->fsuid, cred->gid, cred->egid, cred->sgid, cred->fsgid);
修改完成后,将修改后的base.c
和 array.c
文件提交到本地仓库
$ git add array.c base.c$ git commit -m "change kernel anti flags"
再次按 上面的 三~ 六 步骤 编译内核重新生成boot.timg刷入手机
测了一下 TracerPid值为0
参考资料:
1.https://groups.google.com/forum/#!msg/android-building/5SKMilqvXys/LgbF576GF-YJ
2.https://softwarebakery.com/building-the-android-kernel-on-linux
3.http://marcin.jabrzyk.eu/posts/2014/05/building-and-booting-nexus-5-kernel
4.http://blog.csdn.net/qq1084283172/article/details/54880488
- 三、Android系统内核编译及刷机实战 (修改反调试标志位)
- 安卓源码+内核修改编译(修改内核调试标志绕过反调试)
- 修改Android真机的调试标志位
- 修改Android手机内核,绕过反调试
- 32位机器Ubuntu系统编译android 内核注意修改成64位
- 修改系统内核 绕过反调试 TracerPid为0
- 二、Android系统源码编译及刷机实战
- 32位机器Ubuntu系统编译android 内核注意修改点
- 逆向修改手机内核绕过反调试
- Ubuntu内核编译教程-修改内核(4.5位例)
- 解决应用的反调试方案解析(修改IDA调试端口修改内核信息)
- 编译Android内核 For nexus 5 以及绕过Android的反调试
- Android系统源码与内核下载编译及刷机讲解
- Android逆向之旅---应用的"反调试"方案解析(附加修改IDA调试端口和修改内核信息)
- Android Linux内核编译调试
- Android Linux内核编译调试
- Android Linux内核编译调试
- 编译android源码三(编译系统)
- bootstrap基础
- 过滤器
- Filter过滤器
- Google面试题 | 目标和
- setsockopt :SO_LINGER 选项设置 .http://blog.csdn.net/factor2000/article/details/3929816?ticket=ST-143210
- 三、Android系统内核编译及刷机实战 (修改反调试标志位)
- android nexus 系列 源码刷机教程(ubuntu)
- 音频技术1
- Android Unsafe 分析
- C++ cin.get()和cin.getline()方法详解及区别
- SIP基本信令
- java:for while do while循环
- 关于Mybatis的There is no getter for property named 'xxxx '错误
- 阿里巴巴天猫技术部-行业&供应链平台-前端招聘 资深前端开发工程师 15k-25k /杭州 / 经验3-5年 / 大专及以上 / 全职