0x00 起因
這是一個(gè)很狗血的故事,我們一些同學(xué)在做反編譯apk的作業(yè),然后呢突然有同學(xué)反饋就是說(shuō)某郵箱大師的apk不能夠反編譯,出現(xiàn)各種error。當(dāng)然起初我認(rèn)為是操作問(wèn)題或者工具的問(wèn)題,但是后來(lái)經(jīng)過(guò)我自己的實(shí)踐,發(fā)現(xiàn)的確也有這樣的問(wèn)題。然后就開(kāi)始了狗血之旅。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 調(diào)查
既然有了這樣一個(gè)錯(cuò)誤,那么自然就開(kāi)始了Google之旅。通過(guò)各種Google之后首先先排除了是dex2jar這個(gè)工具的問(wèn)題。當(dāng)然這個(gè)其中也嘗試了其他的各種工具想來(lái)替代的使用。比如:
- Baksmali - 使用最廣泛的DEX反編譯工具 (apktool/antilvl等使用)(https://code.google.com/p/smali/)
- dex2jar - 可以把DEX反編譯成jar的工具,然后通過(guò)JD-GUI查看。(http://code.google.com/p/dex2jar/)
- IDA Pro - (這個(gè)就不在介紹了吧?。?a target="_blank" rel="nofollow">https://www.hex-rays.com/index.shtml)
- androguard - 也是比較流行的。(https://code.google.com/p/androguard/)
但是可惜的是要么就是只有試用版,要么就是達(dá)不到我要的效果,我放棄了投機(jī)取巧的方式,還是安安靜靜地做個(gè)美男子去看問(wèn)題吧。(浪費(fèi)大把時(shí)間。。。。)
既然不換工具,那還是回到了dex文件本身,我大概也了解下結(jié)構(gòu)。
以及反編譯之后的結(jié)構(gòu)
那么還是先做了反編譯:
java -jar baksmali-2.1.1.jar -o /test/ classes.dex
得到了:
根據(jù)我們的錯(cuò)誤日志,我們定位到問(wèn)題就在[La/_;.a()V]這個(gè)地方。那么我找到了這個(gè)文件,字節(jié)碼如下:
.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
網(wǎng)絡(luò)上說(shuō)看雪上有一種常見(jiàn)的防護(hù)機(jī)制就是在smali中去寫(xiě)廢代碼,但是從這個(gè)文件中我也沒(méi)有看到廢代碼。其實(shí)到了這里線索就斷了,就不知道應(yīng)該走了。
0x02 突破
在走投無(wú)路的時(shí)候突然就想到了是不是有可能保護(hù)的機(jī)制是一樣的,只不過(guò)不一定是廢代碼。那么接下來(lái)就是要做的是修改smali文件,將smali轉(zhuǎn)換成dex。使用了
java -jar smali-2.1.1.jar /Users/monkey/Documents/test -o classes.dex
但是無(wú)論我修改什么代碼貌似都會(huì)出現(xiàn)最初出現(xiàn)的那個(gè)錯(cuò)誤日志,緊接著我使用了老方法,就是傳說(shuō)中的對(duì)比。我去下載了其他幾種apk,把字節(jié)碼的結(jié)構(gòu)和郵箱大師的結(jié)構(gòu)做了對(duì)比,發(fā)現(xiàn)其實(shí)其他apk并沒(méi)有出現(xiàn).smali這個(gè)文件,故而我就懷疑是不是這個(gè)文件本身就是阻礙反編譯的罪魁禍?zhǔn)?。所以我刪除了每個(gè)文件中的.smali文件,大概有10多個(gè)。接著打出dex,然后再用dex2jar對(duì)這個(gè)新的classes.dex反編譯,至少不報(bào)錯(cuò)了。
0x03 結(jié)果
最后方法都試一樣的,使用JD-GUI打開(kāi)jar文件,可以看到代碼了。這一路狗血的一塌糊涂。