反编译Apk时你是否遇到过下图中的错误,反编译进行到AndroidManifest.xml
就报错了,然后就没有然后了。
这是因为该apk的AndroidManifest.xml
文件被特殊处理过,导致apktool
在反编译时报错。
我们知道AndroidManifest.xml
是以AXML格式存在于apk中的,而AXML文件的魔数(前4个字节)为0x03000800
。
apktool
在反编译AndroidManifest.xml
前会先判断魔数是否符合条件,不符合会直接抛出异常并终止反编译。
从apktool
源码中看确实如此:
//ExtDataInput
public void skipCheckInt(int expected) throws IOException {
int got = readInt();
if (got != expected) {
throw new IOException(String.format(
"Expected: 0x%08x, got: 0x%08x", expected, got));
}
}
//AXmlResourceParser
private final void doNext() throws IOException {
// Delayed initialization.
if (m_strings == null) {
//就是在这里调用skipCheckInt判断魔数
m_reader.skipCheckInt(CHUNK_AXML_FILE);
/*
* chunkSize
*/
m_reader.skipInt();
m_strings = StringBlock.read(m_reader);
m_namespaces.increaseDepth();
m_operational = true;
}
...
利用apktool
这一“特性”,我们就可以通过修改AndroidManifest.xml
的魔数来防止反编译。
如何修改Apk中AndroidManifest.xml
魔数?
-
apktool d -r xxx.apk
(-r
指不反编译资源)通过该命令反编译目标apk
. - 用
010Editor
打开AndroidManifest.xml
文件。如下图:
- 将第一个字节从
03
修改为01
后保存。 -
apktool b xxx
通过该命令重新编译,之后对生成的apk
重新签名后就可以正常安装/发布了。 - 此时再用
apktool
反编译生成的apk
文件就会发现无法正常反编译了。
那遇到这种apk该如何正确反编译呢?
大致有两种方案:
- 先将
AndroidManifest.xml
文件的魔数修改为0x03000800
,再用apktool
继续反编译。
-
修改
apktool
源码。
找到源码中校验魔数的代码(见前文的代码段),然后可以简单粗暴的添加异常捕捉。private final void doNext() throws IOException { // Delayed initialization. if (m_strings == null) { try{ m_reader.skipCheckInt(CHUNK_AXML_FILE); }catch (Throwable t){ t.printStackTrace(); } /* * chunkSize */ m_reader.skipInt(); m_strings = StringBlock.read(m_reader); m_namespaces.increaseDepth(); m_operational = true; } ...
附:
apktool
源码地址:https://github.com/iBotPeaches/Apktool
AndroidManifest.xml
被修改过的apk
下载地址:http://7u2ne2.com1.z0.glb.clouddn.com/demo.apk
修改过的apktool
下载地址:http://7u2ne2.com1.z0.glb.clouddn.com/apktool.zip
010Editor
下载地址:http://www.sweetscape.com/010editor/mac_osx.html
网友评论
是因为Android解析Manifest文件时,只会去判断文件名称AndroidManifest.xml,而不会查看文件格式?