转载请注明地址:https://blog.csdn.net/lynnchurch/article/details/95100451
为了防止安卓App被Apktool反编译和回编译,有一种比较有效的手段就是针对Apktool的漏洞进行防护,使Apktool在反编译或回编译的过程中发生异常而导致失败。所以要想绕过此类防护手段,就得修复Apktool的相关漏洞,好在Apktool是开源的,于是我们就可以通过研究Apktool的源代码来进行修复。下面是关于目前所遇到的一些问题的说明与修复。
目录
注意:本文的目的在于逆向分析技术的学习与研究,切勿用于非法目的
原Apktool项目地址:https://github.com/iBotPeaches/Apktool
问题一:Could not decode file
反编译的过程中出现如下错误:
S: Could not decode file, replacing by FALSE value: layout/xxx_item.xml
这是由于向resources.arsc
文件中定义了一些并不存在且实际app又不需要的资源,所以按照此无实际资源的文件路径进行解码的时候会出现异常。
解决方案就是在ARSCDecoder.readEntry()
方法中创建ResResSpec
和ResResource
实例之前去判断资源路径所指的资源是否存在,存在则创建相应实例,否则就过滤该资源,代码如下所示:
if (value instanceof ResFileValue) {
String valueStr = value.toString();
Directory apkDir;
try {
apkDir = ApkDecoder.getApkFile().getDirectory();
} catch (DirectoryException e) {
throw new AndrolibException(e.getMessage());
}
if (!apkDir.containsFile(valueStr)) {
return;
}
}
问题二:Cant find 9patch chunk in file
反编译的过程中出现如下警告:
W: Cant find 9patch chunk in file: "drawable-hdpi-v4/abc_list_selector_disabled_holo_light.9.png". Renaming it to *.png.
这是由于打包的时候在gradle中配置了 shrinkResources true,这样那些没有被用到的.9.png图会被处理成宽高各3个像素的png图(虽然文件扩展名是.9.png,但实际格式是png),所以Apktool遇到这种图会修改他们的扩展名为.png,而遇到真正的.9.png图就会给他们周边加相应的黑线(apk包里的.9.png图在打包的过程中会把黑线去掉,而我们用Apktool进行回编译是需要黑线的)。
问题三:No resource found that matches the given name(APKTOOL_DUMMY_xxx)
回编译过程出现如下警告:
W: D:\demo\res\anim\abc_grow_fade_in_from_bottom.xml:4: error: Error: No resource found that matches the given name (at 'interpolator' with value '@android:anim/APKTOOL_DUMMY_6').
继而出现如下异常:
brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1)
这个问题是由于ARSCDecoder.addMissingResSpecs()
方法导致的,顾名思义就是添加丢失的资源规格。Apktool在解析ResTable_entry偏移数组的时候发现有些条目的偏移值为-1,这就意味着该条目没有相应的资源规格,对于这种情况Apktool会强行添加名如APKTOOL_DUMMY_6
这种形式的规格名去构建相应的资源规格,这样一来回编译的时候就会出现No resource found that matches the given name
这样的警告。解决方案简单粗暴,就是注释掉ARSCDecoder.addMissingResSpecs()
方法,后面验证发现可以正常回编译。
问题四:No resource identifier found
回编译过程出现如下警告并出现异常导致失败:
W: D:\demo_res_guard\res\layout\a2.xml:5: error: No resource identifier found for attribute 'exampleColor' in package 'me.lynnchurch.customview'
出现这个警告是由于使用了如微信的AndResGuard进行了资源混淆,就会找不到相应的资源ID。
aapt在编译布局文件的时候会给其中的自定义属性添加ID(在这之前会对values目录下的资源如自定义属性生成对应的ID),添加ID是通过属性名去之前生成的资源ID表中去查找的。经过资源混淆的apk在用Apktool反编译生成的atrrs.xml文件中的属性名也是混淆的,但是布局文件中的属性名却还是原名,所以通过布局文件中的属性名去查找ID会提示No resource identifier found for attribute 'xxxAttr'
。
所以要想解决这个问题,就得让Apktool在反编译的时候对混淆的属性名进行还原。通过分析Apktool的源码,发现进行xml文件解析的主要是AXmlResourceParser
这个类,其中getAttributeName()
方法用于读取属性名,而这个属性名正是我们需要的原属性名,拿到这个属性名后就可以替换从resources.arsc
中读取的混淆后的属性名,原属性名和混淆后的属性名通过属性资源ID进行映射。关键代码如下:
ResID resID = new ResID(getAttributeNameResource(index));
if (mAttrDecoder.getCurrentPackage().hasResSpec(resID)) {
ResResSpec resSpec = mAttrDecoder.getCurrentPackage().getResSpec(resID);
resSpec.setName(value);
}
经测试成功将混淆的属性名还原,再进行回编译已无No resource identifier found for attribute 'xxxAttr'
警告,如此便可绕过AndResGuard这类资源混淆工具的反编译防护机制。
问题五:No resource found that matches the given name(?attr/xxx)
回编译过程出现如下警告并出现异常导致失败:
W: D:\demo\res\layout\a1.xml:5: error: Error: No resource found that matches the given name (at 'style' with value '?attr/actionBarStyle').
通过aapt
dump出能够正常回编译的xml文件style属性是这样的:A: style=?0x7f020005
,dump出回编译异常的xml文件style属性是这样的:A: style=?0x7f020005 (Raw: "?attr/actionBarStyle")
,通过对比发现发生异常的xml文件style属性多了个(Raw: "?attr/actionBarStyle")
。
正常的xml反编译后生成的style属性内容是这样的style="?f"
,而异常的xml反编译后生成的style属性却是这样的style="?attr/actionBarStyle"
,前者能够成功找到所需的资源,后者却找不到并报出No resource found that matches the given name
这样的警告。
通过以上分析,解决问题的思路就出来了,那就是解析形如A: style=?0x7f020005 (Raw: "?attr/actionBarStyle")
这样的属性时,只取?0x7f020005
这样的值。
回到Apktool源码中,发现ResScalarValue.encodeAsResXmlAttr()
方法是对属性值进行处理的,具体处理细节如下:
public String encodeAsResXmlAttr() throws AndrolibException {
if (mRawValue != null) {
return mRawValue;
}
return encodeAsResXml();
}
发现它是优先取mRawValue
这个值,也就是上面所说的(Raw: "?attr/actionBarStyle")
这样的值,那么忽略掉mRawValue
这样的值应该就能解决问题了,如下:
public String encodeAsResXmlAttr() throws AndrolibException {
return encodeAsResXml();
}
经过以上处理,反编译回编译验证通过。
暂时对这五个问题进行分析修复,后续遇到新的问题会更新本文,大家如有遇到新的问题,欢迎在本文下方评论,一起学习交流,文中如有不妥之处,还请斧正。
本文fork的Apktool项目地址:https://github.com/lynnchurch/Apktool