0x00 起因
这是一个很狗血的故事,我们一些同学在做反编译apk的作业,然后呢突然有同学反馈就是说某邮箱大师的apk不能够反编译,出现各种error。当然起初我认为是操作问题或者工具的问题,但是后来经过我自己的实践,发现的确也有这样的问题。然后就开始了狗血之旅。error message
如下:
com.googlecode.dex2jar.DexException: while accept method:[La/_;.a()V]
at com.googlecode.dex2jar.reader.DexFileReader.acceptMethod(DexFileReader.java:694)
at com.googlecode.dex2jar.reader.DexFileReader.acceptClass(DexFileReader.java:441)
at com.googlecode.dex2jar.reader.DexFileReader.accept(DexFileReader.java:323)
at com.googlecode.dex2jar.v3.Dex2jar.doTranslate(Dex2jar.java:85)
at com.googlecode.dex2jar.v3.Dex2jar.to(Dex2jar.java:261)
at com.googlecode.dex2jar.v3.Dex2jar.to(Dex2jar.java:252)
at com.googlecode.dex2jar.v3.Main.doData(Main.java:43)
at com.googlecode.dex2jar.v3.Main.doData(Main.java:35)
at com.googlecode.dex2jar.v3.Main.doFile(Main.java:63)
at com.googlecode.dex2jar.v3.Main.main(Main.java:86)
Caused by: com.googlecode.dex2jar.DexException: while accept code in method:[Landroid/_;.a()V]
at com.googlecode.dex2jar.reader.DexFileReader.acceptMethod(DexFileReader.java:684)
... 9 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 4
at com.googlecode.dex2jar.v3.V3CodeAdapter.visitUnopStmt(V3CodeAdapter.java:631)
at com.googlecode.dex2jar.reader.DexOpcodeAdapter.x2x(DexOpcodeAdapter.java:529)
at com.googlecode.dex2jar.reader.DexCodeReader.acceptInsn(DexCodeReader.java:425)
at com.googlecode.dex2jar.reader.DexCodeReader.accept(DexCodeReader.java:337)
at com.googlecode.dex2jar.reader.DexFileReader.acceptMethod(DexFileReader.java:682)
... 9 more
Done.
0x01 调查
既然有了这样一个错误,那么自然就开始了Google之旅。通过各种Google之后首先先排除了是dex2jr
这个工具的问题。当然这个其中也尝试了其他的各种工具想来替代的使用。比如:
- Baksmali - 使用最广泛的DEX反编译工具 (apktool/antilvl等使用)(https://code.google.com/p/smali/)
- dex2jar - 可以把DEX反编译成jar的工具,然后通过JD-GUI查看。(http://code.google.com/p/dex2jar/)
- IDA Pro - (这个就不在介绍了吧!)(https://www.hex-rays.com/index.shtml)
- androguard - 也是比较流行的。(https://code.google.com/p/androguard/)
但是可惜的是要么就是只有试用版,要么就是达不到我要的效果,我放弃了投机取巧的方式,还是安安静静地做个美男子去看问题吧。(浪费大把时间。。。。)
既然不换工具,那还是回到了dex文件本身,我大概也了解下结构。
以及反编译之后的结构
那么还是先做了反编译:java -jar baksmali-2.1.1.jar -o /test/ classes.dex
得到了:
根据我们的错误日志,我们定位到问题就在[La/_;.a()V]
这个地方。那么我找到了这个文件,字节码如下:
.class public La/_;
.super Ljava/lang/Object;
.source "a.java"
# virtual methods
.method public a()V
.registers 2
.prologue
.line 5
double-to-int p3, v0
move-wide/16 p54870, v0
.line 6
.local v0, "i":I
nop
.line 7
return-void
.end method
网络上说看雪上有一种常见的防护机制就是在smali中去写废代码,但是从这个文件中我也没有看到废代码。其实到了这里线索就断了,就不知道应该走了。
0x02 突破
在走投无路的时候突然就想到了是不是有可能保护的机制是一样的,只不过不一定是废代码。那么接下来就是要做的是修改smali文件,将smali转换成dex。使用了java -jar smali-2.1.1.jar /Users/monkey/Documents/test -o classes.dex
但是无论我修改什么代码貌似都会出现最初出现的那个错误日志,紧接着我使用了老方法,就是传说中的对比。我去下载了其他几种apk,把字节码的结构和邮箱大师的结构做了对比,发现其实其他apk并没有出现_.smali
这个文件,故而我就怀疑是不是这个文件本身就是阻碍反编译的罪魁祸首。所以我删除了每个文件中的_.smali
文件,大概有10多个。接着打出dex,然后再用dex2jar
对这个新的classes.dex
反编译,至少不报错了。
0x03 结果
最后方法都试一样的,使用JD-GUI
打开jar文件,可以看到代码了。这一路狗血的一塌糊涂。
我怕我10分钟就忘记了,所以这里记录下。。。。。