做自己的Android ROM,屏蔽对framework中的系统APK的签名检查
最近两天一直在尝试更新Android中的关键库以达到定制ROM的效果,中间比较曲折,记录下来供自己和大家参考。
因为我需要基于Android的原生代码做一定的修改,所以如果无法将我自己编译出的APK或Jar替换系统中的东西,则无法达成我的目标。
我的测试的机器:htc one 电信定制版(802d),Android版本:4.2.2;LG Nexus 4,Android版本:4.3。
测试第一步:
将手机root掉,以替换修改系统文件的权限。不同厂商的手机的root步骤不一样,自己上网搜索吧。
测试第二步:
使用我自己编译出来的SystemUI.apk,替换Nexus 4的SystemUI.apk,通过 adb logcat > 1.txt 查看日志,直接报下面的错;
W/PackageManager( 530): Signature mismatch for shared user : SharedUserSetting{41ea0bc8 android.uid.system/1000} E/PackageManager( 530): Package com.android.systemui has no signatures that match those in shared user android.uid.system; ignoring!
签名有问题,根据这个关键字“has no signatures that match those” 去搜索Android源代码,可以在PackageManagerService.java中找到如下函数:
private boolean verifySignaturesLP(PackageSetting pkgSetting,
PackageParser.Package pkg) {
if (pkgSetting.signatures.mSignatures != null) {
// Already existing package. Make sure signatures match
if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
PackageManager.SIGNATURE_MATCH) {
Slog.e(TAG, "Package " + pkg.packageName
+ " signatures do not match the previously installed version; ignoring!");
mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
return false;
}
}
// Check for shared user signatures
if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
Slog.e(TAG, "Package " + pkg.packageName
+ " has no signatures that match those in shared user "
+ pkgSetting.sharedUser.name + "; ignoring!");
mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
return false;
}
}
return true;
}
直接替换,肯定是不行了,签名通不过,那我可否尝试将签名检查的代码给屏蔽掉?
测试第三步:
尝试屏蔽对系统级APK的签名检查,代码已经找到,在这个目录下:frameworks/base/services/java/com/android/server/pm。
进一步分析,services目录下的内容,最终会被编译成 services.jar,adb shell 后,在 /system/framework 下可以找到 services.jar。
root@android:/system/framework # ls servi*
ls servi*
services.jar
在 out/target/product/generic/dex_bootjars/system/framework 这个目录下可以找到 services.jar,
直接使用自己编译出来的services.jar去替换 /system/framework下的同名jar包,重启os后,好像报的这个错误:DexOpt: mismatch dep signature,
然后os一直处于死循环中,无法开机成功。
根据“DexOpt: mismatch dep signature”这个关键字搜索,在DexPrepare.cpp中有对应的检查:
if (memcmp(signature, ptr, kSHA1DigestLen) != 0) {
LOGI("DexOpt: mismatch dep signature for '%s'", cacheFileName);
goto bail;
}
测试第四步:
既然第三步也不行,那我用自己编译出来的“libdvm.so” 将/system/lib下的同名文件更新掉,重启os后,还是类似的错误,签名摘要校验不过。
当前陷入了短时间的僵局,上网找了很多资料参考,大部分仅能参考,写得太不详细,直接我遇到了这个文档:《MIUI ROM定制教程》,
已经在我的百度网盘共享: http://pan.baidu.com/share/link?shareid=198381908&uk=4145338314
神一般的文档,将Android的系统框架,到刷机原理,再到一些刷机的具体细节,都写得非常清楚。
下面的过程是基于HTC ONE(802d)来测试的:
1、先找一个可刷机的ROM,我找到的是Nic_One_M7_802d_4.2.2_Devil_3.5_signed.zip,这个包可以刷机成功并且系统可用。
之前找的两个包可以刷机成功,但屏幕驱动似乎有问题,触屏无反应。
2、将原有包中的services.jar转成smali文件,通过 baksmali-1.4.2.jar 进行将 jar中的dex文件转成smali文件,将PackageManagerService.smali中的verifySignaturesLP函数的实现给修改掉,然后再使用smali-1.4.2.jar将反编译出的包含smali文件的目录转成dex文件,使用winrar打开services.jar,将新生成的classes.dex覆盖jar包中的classes.dex,将这个新jar包替换原ROM zip包中的同名文件。
再使用“土豆ROM工具箱” 将新ROM zip包重新签名下,再进行刷机。
经过几分钟的等待后,系统可用,并且使用我自己编译出的 SystemUI.apk 直接覆盖 /system/framework/ 下的同名文件,也不会再报签名错误,只是无法正常运行。
为了进一步验证,我将系统的 SystemUI.apk 复制我的电脑上,使用“土豆ROM工具箱”将其重新签名,然后再替换原生 SystemUI.apk,HTC手机也是可以正常运行的。
终于成功将系统APK签名验证这步给屏蔽了,这样我就可以基于此ROM做很多其它想做的事件了。
smali-1.4.2.jar、baksmali-1.4.2.jar的使用命令参考:
C:\Users\zhao3546\Desktop\Android\Android_framework_4.2>java -jar smali-1.4.2.jar -h
usage: java -jar smali.jar [options] [--] [<smali-file>|folder]*
assembles a set of smali files into a dex file
-?,--help prints the help message then exits. Specify
twice for debug options
-a,--api-level <API_LEVEL> The numeric api-level of the file to generate,
e.g. 14 for ICS. If not specified, it defaults
to 14 (ICS).
-o,--output <FILE> the name of the dex file that will be written.
The default is out.dex
-v,--version prints the version then exits
-x,--allow-odex-instructions allow odex instructions to be compiled into the
dex file. Only a few instructions are supported
- the ones that can exist in a dead code path
and not cause dalvik to reject the class C:\Users\zhao3546\Desktop\Android\Android_framework_4.2>java -jar baksmali-1.4.2.jar -h
usage: java -jar baksmali.jar [options] <dex-file>
disassembles and/or dumps a dex file
-?,--help prints the help message then exits.
Specify twice for debug options
-a,--api-level <API_LEVEL> The numeric api-level of the file
being disassembled. If not
specified, it defaults to 14 (ICS).
-b,--no-debug-info don't write out debug info (.local,
.param, .line, etc.)
-c,--bootclasspath <BOOTCLASSPATH> the bootclasspath jars to use, for
analysis. Defaults to
core.jar:ext.jar:framework.jar:andro
id.policy.jar:services.jar. If the
value begins with a :, it will be
appended to the default
bootclasspath instead of replacing
it
-d,--bootclasspath-dir <DIR> the base folder to look for the
bootclasspath files in. Defaults to
the current directory
-f,--code-offsets add comments to the disassembly
containing the code offset for each
address
-l,--use-locals output the .locals directive with
the number of non-parameter
registers, rather than the .register
directive with the total number of
register
-m,--no-accessor-comments don't output helper comments for
synthetic accessors
-o,--output <DIR> the directory where the disassembled
files will be placed. The default is
out
-p,--no-parameter-registers use the v<n> syntax instead of the
p<n> syntax for registers mapped to
method parameters
-r,--register-info <REGISTER_INFO_TYPES> print the specificed type(s) of
register information for each
instruction. "ARGS,DEST" is the
default if no types are specified.
Valid values are:
ALL: all pre- and post-instruction
registers.
ALLPRE: all pre-instruction
registers
ALLPOST: all post-instruction
registers
ARGS: any pre-instruction registers
used as arguments to the instruction
DEST: the post-instruction
destination register, if any
MERGE: Any pre-instruction register
has been merged from more than 1
different post-instruction register
from its predecessors
FULLMERGE: For each register that
would be printed by MERGE, also show
the incoming register types that
were merged
-s,--sequential-labels create label names using a
sequential numbering scheme per
label type, rather than using the
bytecode address
-v,--version prints the version then exits
-x,--deodex deodex the given odex file. This
option is ignored if the input file
is not an odex file
做自己的Android ROM,屏蔽对framework中的系统APK的签名检查的更多相关文章
- 运用Android ROM Manager应用安装ClockworkMod Recovery的详细教程
在安装ClockworkMod Recovery恢复模式之前,建议先认识下Google Android平台的ClockworkMod Recovery恢复模式 对于Android ROM Manage ...
- Android ROM 备书
1. Android ROM 目录接口 我们经常说的刷ROM是刷系统的意思,但是ROM的原意并不是这样,ROM的全称是read only memory只读储存器,正因为它是“只读”的,而且系统文件通常 ...
- Android ROM 制作教程
本文来自: 起点手机论坛 具体文章參考:http://www.qdppc.com/forum.php?mod=viewthread&tid=43751&fromuid=1 1.Andr ...
- Android ROM 打包记录
android5.1平板或手机应用层一些常用的修改项及目录所在: 1.所以系统应用所在的目录: \alps\packages\apps 2.一些系统属性的定义:并且可以仿写自行定义变量 \alps\b ...
- Android ROM适配
Android是开源的,不同的手机厂商都有自己定制的系统,所以这就给开发者带来了ROM适配难题.在一些群里面经常看到有人因为手机适配问题,说这个手机坑,那个手机坑,其实那是没有对ROM定制系统的一些变 ...
- 招聘:有兴趣做一个与Android对等的操作系统么?
招聘:有兴趣做一个与Android对等的操作系统么? 前不久我发了一篇<八一八招聘的那些事儿>讲了我自己作为求职者对招聘的一些看法.那个时候我还在求职,对求职的结果还是挺满意的,五家公司面 ...
- 详细介绍android rom移植知识普及
详细介绍android rom移植知识普及 最近接到很多兄弟们的求助,也回答过无数个和下面这个问题类似的问题: 如何编译android 原生代码得到一个rom,然后跑到某某手机上. 鉴于很多兄弟对这块 ...
- Android ROM开发(二)——ROM架构以及Updater-Script脚本分析,常见的Status错误解决办法
Android ROM开发(二)--ROM架构以及Updater-Script脚本分析,常见的Status错误解决办法 怪自己二了,写好的不小心弄没了,现在只好重新写一些了,上篇简单的配置了一下环境, ...
- Android ROM开发(三)——精简官方ROM并且内置ROOT权限,开启Romer之路
Android ROM开发(三)--精简官方ROM并且内置ROOT权限,开启Romer之路 相信ROM的相关信息大家通过前几篇的学习都是有所了解了,这里就不在一一提示了,这里我们下载一个官方包,我们还 ...
随机推荐
- android Graphics(四):canvas变换与操作
前言:前几篇讲解了有关canvas绘图的一些操作,今天更深入一些,讲讲对画布的操作,这篇文章不像前几篇那么容易理解,如果以前没有接触过画布的童鞋可能比较难以理解,为什么会这样.我尽量多画图,让大家更清 ...
- 【Hibernate】Illegal attempt to associate a collection with two open sessions
今天在用Hibernate对对象进行修改操作的时候报了这个错. 之前一直没什么错误,但是今天修改了一下表结构,增加了一个OneToMany的映射. 所以在我获取对象,重新set一个变量之后就报了这个错 ...
- 【JavaScript】强制缓存刷新
1.在js引用时加入时间戳. <script> document.write('<script src="xxx.js?_dc='+new Date().getTime() ...
- Cocoapods安装步骤
Cocoapods安装步骤 1.升级Ruby环境 终端输⼊入:$ gem update --system 此时会出现 ERROR: While executing gem ... (Gem::File ...
- ADO.NET 总结
一.简单介绍ADO.NET System.Data:DataTable,DataSet,DataRow,DataColumn,DataRelation,Constraint System.Data.C ...
- Executor框架
Executor框架是指java5中引入的一系列并发库中与executor相关的功能类,包括Executor.Executors.ExecutorService.CompletionService. ...
- 多层TreeWidget可选实现
http://download.csdn.net/detail/lingyunfuyu2/9117481
- 单实例支撑每天上亿个请求的SSDB
SSDB 是一个 C++ 开发的 NoSQL 存储服务器, 支持 zset, map 数据结构, 可替代 Redis, 特别适合存储集合数据. SSDB 被开发和开源出来后, 已经在生产环境经受了3个 ...
- 华为HCNA教程(笔记)
第一章 VRP操作基础 1VRP基础 MiniUsb串口连接交换机的方法 2eNSP入门 3命令行基础(1) eNSP中路由开启后(记住port)---第三方软件连接该路由方法:telnet 127. ...
- Repeater控件
一:http://www.cnblogs.com/foolin/archive/2011/08/31/2161342.html 二:http://www.cnblogs.com/shipfi/arch ...