一、前言
最近有一個(gè)同學(xué),發(fā)給我一個(gè)設(shè)備流量訪(fǎng)問(wèn)檢測(cè)工具,但是奇怪的是,他從GP上下載下來(lái)之后安裝就沒(méi)有數(shù)據(jù)了,而在GP上直接安裝就可以。二次打包也會(huì)有問(wèn)題。所以這里就可以判斷這個(gè)app應(yīng)該是有簽名校驗(yàn)了,當(dāng)然還有其他的校驗(yàn)邏輯,我們打開(kāi)這個(gè)app界面如下,沒(méi)有任何數(shù)據(jù):
二、應(yīng)用分析
下面就來(lái)簡(jiǎn)單分析這個(gè)app,不多說(shuō)直接使用Jadx工具打開(kāi):
我們?cè)谑褂玫倪^(guò)程中會(huì)發(fā)現(xiàn)需要授權(quán)VPN權(quán)限,所以就斷定這個(gè)app利用了系統(tǒng)的VPNService功能開(kāi)發(fā)的,直接在xml中找到入口,然后進(jìn)入查看配置代碼:
繼續(xù)跟蹤查看內(nèi)部邏輯:
在Worker類(lèi)中,看到有一些核心的Native方法,開(kāi)發(fā)過(guò)VPNService都知道,攔截?cái)?shù)據(jù)等操作一般都會(huì)放到native去做,主要原因是性能會(huì)高點(diǎn)。不多說(shuō)直接使用IDA打開(kāi)libwebd.so文件,直接搜索NativeInit函數(shù),為什么搜索這個(gè)函數(shù)呢?因?yàn)橐豢催@個(gè)是初始化操作,而沒(méi)有數(shù)據(jù)的話(huà)那些校驗(yàn)判斷只會(huì)在這里,所以直接看這個(gè)函數(shù)實(shí)現(xiàn):
繼續(xù)往下看,他到底做了哪些驗(yàn)證,這里主要包括了三處驗(yàn)證,具體如下:
第一處驗(yàn)證:
驗(yàn)證安裝渠道是否為GP,這里利用了系統(tǒng)的getInstallerPackageName方法來(lái)做判斷,這個(gè)方法在很早的Android版本就有了,但是這個(gè)方法有很大使用問(wèn)題,后面會(huì)介紹。因?yàn)镚P安裝器包名是:com.android.vending,這里直接判斷如果安裝器不是GP就不進(jìn)行攔包操作了。
第二處驗(yàn)證:
應(yīng)用簽名校驗(yàn),這個(gè)已經(jīng)是最普遍的校驗(yàn)方法了,這里不多解釋了,直接使用kstools工具進(jìn)行爆破即可破解簽名校驗(yàn)。
第三處驗(yàn)證:
這個(gè)主要在AndroidManifest.xml中的android:debuggable="true"這個(gè)屬性值,我們之前如果想調(diào)試這個(gè)app的話(huà),一般都會(huì)手動(dòng)反編譯改這個(gè)屬性為true的。但是我們現(xiàn)在不需要調(diào)試,也沒(méi)必要進(jìn)行修改。這個(gè)驗(yàn)證對(duì)于我們來(lái)說(shuō)沒(méi)什么影響。
看到上面的三處驗(yàn)證,其實(shí)對(duì)于我們現(xiàn)在掌握的技術(shù)來(lái)說(shuō)都不難,特別是簽名校驗(yàn),完全可以使用kstools工具來(lái)搞定,一鍵化操作,不了解kstools工具的同學(xué)可以看這篇文章:Android中自動(dòng)爆破簽名校驗(yàn)工具kstools,這里同學(xué)自己使用工具操作一下即可過(guò)了這個(gè)驗(yàn)證。而第三處驗(yàn)證可以說(shuō)沒(méi)什么影響,不用管它。主要來(lái)看第一處驗(yàn)證。有的同學(xué)說(shuō)破解也簡(jiǎn)單,直接修改CBZ指令即可。但是這個(gè)就缺失了一些技巧,我們要的不是結(jié)果,而是學(xué)習(xí)的過(guò)程。接下來(lái)看看我是怎么破解這個(gè)校驗(yàn)的。又要多介紹一些知識(shí)點(diǎn)了。
三、破解方案
破解這個(gè)安裝渠道大致有兩個(gè)方案,一個(gè)是利用kstools工具源碼修改一下,攔截getInstallerPackageName方法,然后修改返回值即可,如下:
直接返回這個(gè)包名的的安裝器就是GP的,這樣在打包就可以給多人使用了。這個(gè)不多介紹了,感興趣的同學(xué)去下載源碼自己操作實(shí)踐一下即可:
https://github.com/fourbrother/kstools
還有一種超級(jí)簡(jiǎn)單的方式,直接使用命令** pm install -i[指定安裝器包名] apk文件**,這個(gè)命令應(yīng)該有很少人知道,但是這個(gè)簡(jiǎn)單的一個(gè)命令就可以在這里很方便的破解,可以指定一個(gè)app的安裝器。
我們安裝之后,可以在系統(tǒng)的 /data/system/packages.xml 中查看應(yīng)用對(duì)應(yīng)的安裝器名稱(chēng):
而這里又說(shuō)道一個(gè)知識(shí),就是系統(tǒng)的這個(gè)packages.xml文件,他就是設(shè)備安裝成功的應(yīng)用的一些詳細(xì)信息,包括使用到的權(quán)限,簽名信息,安裝渠道,各種標(biāo)志等。之前有人問(wèn)怎么獲取設(shè)備中的應(yīng)用安裝渠道來(lái)源,其實(shí)可以從這個(gè)文件中獲取到。從這里看到這個(gè)應(yīng)用現(xiàn)在的確是從GP上安裝的了,也說(shuō)明了上面的那個(gè)pm命令的確有效。
這時(shí)候我們?cè)倏纯磻?yīng)用的攔截是否有效果了:
看到了,這里開(kāi)始攔截設(shè)備的數(shù)據(jù)包了,從這里看這款app的確很有用,對(duì)于我們開(kāi)發(fā)來(lái)說(shuō),也算是一個(gè)很好的工具了,破解之后可以珍藏使用了。
對(duì)于第一種方式破解是最好的,因?yàn)槟菢涌梢越o多個(gè)人使用,而對(duì)于第二種命令指定安裝器的安裝方式,一般小白用戶(hù)肯定不知道。對(duì)于第一種方式破解只需要修改kstools源碼即可。
四、總結(jié)
好了到這里我們就破解成功了,可以愉快的使用這個(gè)app了,但是從上面來(lái)看了解到了新的防護(hù)策略就是判斷應(yīng)用是否來(lái)自于指定應(yīng)用市場(chǎng)。有的同學(xué)可能立馬想到了,為了防止二次打包,可以在應(yīng)用中判斷是否來(lái)自于主流的應(yīng)用市場(chǎng)渠道,如果不是就不走正確的邏輯了,這個(gè)也算是一個(gè)防護(hù)策略了,不過(guò)可惜的是這個(gè)想法是不可行的,如果可行就有很多app早這么干了。原因是因?yàn)檫@個(gè)系統(tǒng)方法:getInstallerPackageName,大家可以自己測(cè)試這個(gè)方法,會(huì)發(fā)現(xiàn):如果一個(gè)app是系統(tǒng)應(yīng)用,那么這個(gè)返回值可能是設(shè)備自帶的應(yīng)用市場(chǎng)。如果一個(gè)app是第三方應(yīng)用,并且從GP上安裝,方法返回值一定是com.android.vending;而如果是其他渠道安裝,比如國(guó)內(nèi)的應(yīng)用寶,手機(jī)助手,豌豆莢等。就有可能是null值,而是用pm這樣的命令,或者系統(tǒng)自帶的安裝器安裝的第三方應(yīng)用也有可能是null值,也就是說(shuō):這個(gè)系統(tǒng)api返回的應(yīng)用安裝器名稱(chēng)極不穩(wěn)定,完全就是不靠譜的方法,至少在國(guó)內(nèi)沒(méi)法使用的。所以幾乎可以忽略這個(gè)方法的。但是為何這個(gè)app敢這么干呢?其實(shí)我也很好奇。不過(guò)有一點(diǎn)可以說(shuō)明就是這個(gè)app開(kāi)發(fā)商就認(rèn)定了此app只在GP上發(fā)布,其他渠道都不發(fā)布,這樣只認(rèn)定GP上下載的app才算是合法的。比如一個(gè)國(guó)外用戶(hù),用了華為手機(jī)使用非GP渠道下載了這個(gè)app,那么可惜這個(gè)人也是不能使用的。我也很好奇這個(gè)app的開(kāi)發(fā)商為何要這么做?反正國(guó)內(nèi)的app應(yīng)該都不會(huì)這么做的。因?yàn)檫@個(gè)方法的返回值極不穩(wěn)定。
但是不能說(shuō)這個(gè)方法不靠譜,我們?cè)诤竺娴哪嫦蚓鸵雎赃@個(gè)防護(hù),后面我們?cè)谄平鈇pp依然遵從不變法則:全局搜索signature字符串來(lái)判斷是否有簽名校驗(yàn),全局搜索getInstallerPackageName方法是否有安全渠道驗(yàn)證。不管是在IDA還是Jadx中搜索,都是如此。