当前位置: 首页 > 工具软件 > CM-Updater > 使用案例 >

CM系统应用源码分析与rom定制

莘欣怿
2023-12-01
关于<<Android深度探索(卷2)系统应用源代码分析与ROM定制>>总结
本书主要讲解对CM代码,移植,刷机,定制的入门,对rom定制方面有帮助,其中,值得学习的部分: androd ROOT原理; ROM的定制方面; recovery理解;安装与卸载应用;launcher的理解,需要总结的部分:
一. 关于android内核
(1)版本
google开放7套内核源码:common, exynos, goldfish, msm, omap, samsung, tegra
其中common是通用内核,后面6套都是以该源码为基础的; exynos是三星Exynos芯片的android设备; goldfish是android模拟器的内核源码; msm高通芯片的android设备内核; omap用于使用德州一起(TI)omap芯片的android内核; tegra用于使用恩威迪亚(NVIDIA)Tegra芯片的android设备内核.
(2)内核分支
在下载完源码之后,会出现文件夹是空的,其实所有的linux内核源码都已下好,只是都在版本库中.其中有很多的版本,进入内核源码下载目录,查看所有分支: git branch -a
然后查找到最常用的内核版本, { git checkout -b andorid-分支 }切换到该分支.
(3)配置
对于编译内核源码,需要配置的文件是 .config, 此时如果有现成的手机,可以从手机中获取( 从/proc目录中,得到config.gz文件,解压就可得到 .config ),直接覆盖就可编译,得到 zImage,然后将此文件做成镜像文件(boot.img)就可刷到手机上了.
如果手机上未找到 config.gz, 则要在.config中将CONFIG_IKCONFIG_PROC设为y,即可.
(4)编译
对于linux内核,要编译arm框架的CPU需要,需要使用交叉编译器,而源码中本身自带一款编译器,只是配置要求比较高.所以,在编译内核时,需要配置:
export PATH=$(pwd)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH
export ARCH=arm
export CROSS_COMPILE=arm-eabi-
第一行配置交叉编译器,第二条配置生成arm架构内核,第三条设置交叉编译器的前缀.
最后执行make就可在/arch/arm/boot/目录下得到zImage文件,就是linux内核的二进制版本.
(5)关于cm ROM
下载具体的源码,见CM13下载,
对于CM源码,编译成完整刷机包,步骤:
1. 编译之前,需要下载一些必要的library和apk文件,cm提供了下载的脚本 : ./vendor/cm/get-prebuilts
2. 1成功之后,下载android设备相关的源代码,即linux内核源码,这一步会将linux内核源码与android源码放在一起统一编译处理.这一步需要使用到设备的Codename,执行下面指令,来下载Codename相应的linux内核源码.
source build/envsetup.sh
breakfast Codename
完成后,会在根目录的kernel目录,并在kernel中还会根据不同的厂商建立相应的子目录.
3. 下载设备相关的私有文件(proprietary)文件
这一步需要连接android设备,执行下面的脚本,从设备中提取相应的文件.
./device/sansung/crespo/extract-files.sh
4. 打开缓存,加速编译
export USE_CCACHE=1
5. 编译
brunch Codename 编译会在out目录下打包成一个可以刷机的rom包.
*************************************************************************************************
小问题: apk程序不带odex文件
CM源码默认不生成odex程序优化的文件,不会影响开发,如果要打开,可以在 build/core/main.mk文件中,修改如下:
#ifneq (true, $(DISABLE_DEXPREOPT))
#ifeq ($(user_variant), user)
ifeq ($(HOST_OS), linux)
WITH_DEXPREOPT := true
endif
#endif
#endif
*************************************************************************************************
二. 提取root权限
android本身使用linux内核,开发中需要root权限,才能查看或执行的操作,所以需要 su工具,而android系统默认情况下是不带su命令的,所以,要想切换root用户,需要将su命令集成到现有的android系统中.而要集成,就需要android系统本身有root权限,这就造成了一个死循环.
此处提供的解决方案,前提:android允许进入bootloader模式,找到合适的recovery(可以使用第三方的recovery)
(1)提取root权限
a. 刷一个合适的recovery
在bootloader复制整个文件系统;在recovery模式下将文件复制到android设备指定的目录.
recovery可以使用第三方的recovery(如Clock Recovery),然后使用下面的指令将recovery刷入手机中:
adb reboot bootloader ; fastboot flash recovery recovery.img ; fastboot boot recovery.img
b. 破解su命令
此处关键的就是执行su命令,android系统默认的su命令只能是root用户调用,所以使用su命令之前,需要先破解su命令,修改su源码,将检测权限的代码去掉,然后将su命令刷到system/bin或system/xbin目录下
android源码中,su的源码位于 system/extras/su, 通过修改su.c来解除权限检测:
在main()函数中,添加:
if( setgit(git) || setuid(uid) ){
return 1;
}
......
execlp("/system/bin/sh", "sh", NULL);
上面添加的修改,核心有2点:通过setgid和setuid函数提升权限,即使任何用户在执行sh命令时都会拥有与sh命令拥有者同样的权限; 通过execlp函数执行sh命令.
修改完su.c后,编译好su,作为替换android系统的su文件
c. 制作recovery刷机文件(update.zip)
在现有android设备,没有root权限的情况下,可以制作recovery刷机包,来将su文件放到系统的制定目录.
本次由于只是替换一个文件,所有要制作的刷机包,只有2个目录: system和META-INF.其中system就是编译源码后在out目录下生成的system目录,也是进入android设备的shell后看到的系统目录,该目录下包含系统文件,本次只需要将su文件复制到system/xbin目录,所以在system目录下只有一个xbin子目录,并在该目录下只放一个su文件即可.
接着就需要写META-INF,此目录下,有写拷贝的脚本,/META-INF/com/google/android目录下有updater-script脚本(用来进行升级的脚本内容)和update-binary可执行文件(脚本语言解析器).
此时,我们就需要将拷贝文件的过程写在updater-script脚本即可.具体使用Edify语言,如下:
********************************************************************************
ui_print("mount /system");
run_program("/sbin/busybox", "mount", "-o", "rw", "/system");
ui_print("delete /system/xbin/su");
delete("/system/xbin/su");
ui_print("extract file");
#将刷机包中system目录的所有文件复制到/system目录中的相应位置
package_extract_dir("system", "/system");
ui_print("set permissions");
set_perm(0, 0, 0777, "/system/xbin/su");
unmount("/system");
ui_print("finished");
********************************************************************************
具体实现的过程就是:以读写模式挂在/system,删除旧的su文件,复制新的su文件,修改su文件的权限,卸载/system
对于updater-script脚本中, run_program调用了busybox命令,并通过mount操作,实质是:
busybox mount -o rw /system 此时挂在的system是读写的,若没有这些参数,默认是只读挂载.
复制脚本写完,然后复制一个update-binary,然后将这些文件压缩zip,刷机包就搞定了.然后在recovery模式中安装升级包即可.
d. 执行su命令提取root权限
当将新的su命令放到指定的目录下后,直接执行su命令,当前的shell就拥有了root权限了,
三. root权限的安全隐患



 类似资料: