本文重点如何查看一个patch是否进了google system image
问题初探
测试命令:
run cts-on-gsi -m CtsOsTestCases -t android.os.cts.ParcelTest#testMaliciousMapWrite
1 2 3 4 5 6 7 8 |
fail: junit.framework.AssertionFailedError: Should have thrown a BadParcelableException at junit.framework.Assert.fail(Assert.java:50) at android.os.cts.ParcelTest.testMaliciousMapWrite(ParcelTest.java:3269) at java.lang.reflect.Method.invoke(Native Method) at junit.framework.TestCase.runTest(TestCase.java:168) at junit.framework.TestCase.runBare(TestCase.java:134) at junit.framework.TestResult$1.protect(TestResult.java:115) at android.support.test.internal.runner.junit3.AndroidTestResult.runProtected(AndroidTestResult.java:73) |
像这种问题很明显就是google的安全补丁的问题,又因为我们刷了google system image,且CTS这条没过,因此我们就可以怀疑google的patch没进gsi
问题分析
首先找到相关的安全补丁如下:
那么补丁是否进了呢?
我们可以按照如下步骤进行处理:
1.解压google提供的system.img(使用simg2img)
我们可以将其中的system/framework文件夹完整的拷出来
2.观察这条补丁应该在的问题,对于我们这条补丁而言,本来应该在framework.jar里面
但是jar包里是空的,因此我们需要另想办法
3.反编译boot-framework.vdex
在O以前,我们可以通过baksmali.jar等工具来将odex->smali->dex→jar,根据这个路径反编出大致的jar包
但是O之后不能这么做了,上面的步骤我们就不详细介绍了
推荐使用https://github.com/anestisb/vdexExtractor 工具,通过反编vdex来查看
那么
vdexExtractor -i boot-framework.vdex -o . --deps -f -v 4
这样,对于O的版本,这样就可以直接解压出dex文件了;但是对于Android P还要再增加一个步骤
4.将cdex转换为dex
通过aosp的patch https://gist.github.com/anestisb/30265097ad9a5ea2f0ddf7e36db3f07d
编译出compact_dex_converter工具
compact_dex_converter -w ./ ./boot-framework_classes2.cdex
会生成一个boot-framework_classes2.cdex.new文件,这个其实就是dex文件
5.d2j-dex2jar.sh+010Editor dex→jar
如果magic header不对,用010Editor改一下,然后通过d2j-dex2jar.sh得到相应的framework.jar
见boot-framework2.jar
查看其中的Parcel.class,发现patch果然没进
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public final void writeMap(Map paramMap) { writeMapInternal(paramMap); } void writeMapInternal(Map<String, Object> paramMap) { if (paramMap == null) { writeInt(-1); return; } paramMap = paramMap.entrySet(); writeInt(paramMap.size()); paramMap = paramMap.iterator(); while (paramMap.hasNext()) { Map.Entry localEntry = (Map.Entry)paramMap.next(); writeValue(localEntry.getKey()); writeValue(localEntry.getValue()); } } |
则有充足的理由申请waive
问题总结
该问题引申出如何查看gsi乃至友商机型system.img的方法