原文地址:https://www.52pojie.cn/thread-330022-1-1.html
0x1:
腾讯云加固:https://www.qcloud.com/product/appup.html
加固示例原版APK:https://pic.hzt360.com/downfile/beijing/elechongNFC.apk
a. 首先,看一下原APK和通过腾讯云应用加固后的文件相关变化
加固后的文件列表变化:
- 新增2个so文件:
- libmain.so
- libshell.so
- 修改:
- AndroidManifest.xml
- classes.dex
b. 用ApkTool反编译加固后的APK, 出现反编译不过去,错误日志如下:
-
通过下面日志能看出来是apktool解析
AndroidManifest.xml
时出错,注意绿色下划线的name=fasten
,这里TX加固是利用android系统解析axml的一个特点来导致apktool反编译时,在解析AndroidManifest.xml
时出错。关于利用
AndroidManifest.xml
这块的技术点可以参考一下万抽抽大神的文章:https://www.cnblogs.com/wanyuanchun/p/4084292.html -
下面来分析和修复
AndroidManifest.xml
分析前,还是得先了解一下AndroidManifest.xml的二进制格式,可以参考下列文章:
辅助分析AndroidManifest.xml的二进制格式可以使用下面的:
利用axml模版在010Editor解析
AndroidManifest.xml
能看到,有一个属性结构的name
成员的值是25,该值指向是string
的索引,同时也是res ID
的索引。
为什么这么做,哈哈哈,我懒,所以直接截图引用万抽抽大神的解释:
[w1]uri:命名空间的URI,是string的索引值
[w2]name:属性名,也是一个string的索引值
[w3]string:如果属性type为ATTR_STRING的话,此值就是属性android:name=”xxx”,xxx在string的索引值。其余情况均为0xffffffff
[w4]type:属性的类型,对于android:name,类型值为0x03000008
[w5]data:属性的数据值,对于ATTR_STRING而言,它的值就是string的值。
可以发现,结构体里面并没有一个叫做res ID的成员,那么系统又是如何获取某个属性的ID号的呢?原来这里的name成员是身兼两职,即作为属性名的一个string索引,又作为res ID的索引。比如这里name = 4,它对应StringChunk中的字符串为”name”,对应ResourceChunk中的res ID 0x01010003。所以要插入一个属性名为name,ID号又为0的属性,我们就必须新建一个string,该string的值为name,再新建一个res ID,值为0,且两者在各自Chunk区域的索引值是相等的(这是重点)。
所以fasten这个字符串可以随意改,关键还是ResID的值,TX加固对AndroidManifest.xml处理,是插入一下非法的属性ID (在Android的attr里没有一个ID为0x01017FFF),因为是非法的属性ID,Android是不会去解析,但ApkTool却会去解析,所以导致反编译出错了。
修复方法:
知道怎么回事,修复起来就很简单了,只要把非法的属性ID=0x0101FFFF改成一个合法的属性ID,比如把0x0101FFFF改成name的属性ID=0x01010003,然后再把修改后的AndroidManifest.xml再替换加固后apk里的AndroidManifest.xml,然后用apktook就可以顺利的成功的反编译出来。
反编译后,看加固修改后的AndroidManifest.xml和原版的AndroidManifest.xml多这三条:
1. <serviceandroid:name="com.tencent.mm.fasten.check.log" />
2. android:fasten="meta-data"
1. <meta-dataandroid:name="@anim/push_top_out2"android:value="meta-data" />