這里先提一種針對性校強但簡單好理解的辦法,純Java實現,代碼大概也就50行不到吧。
還有更強的並且能過各種保護(反調試反HOOK反內存修改等等)的萬能方法,不過較復雜,長篇大論的,等有空整理出來再提
本文適用場景:
1.需要重打包APK給普通用戶,沒有root權限也沒有HOOK框架
2.so很難脫殼修復分析修改,或者逆向時間會很長很長。
3.so中調用了this.getPackageManager().getPackageInfo來獲取簽名進行校驗
故事開始,某天,你暗戀的女神需要某個app的VIP,怎奈你兜兜空空如也,根本買不起VIP,然后你發現這個app的VIP是本地判斷的,於是……
經過一番折騰,很快就改好了APK,重打包安裝運行。提示非法操作?
又一番折騰,發現程序主要邏輯在so中,so被混淆的面目全非還進行了加固,最后發現在so中進行了APK簽名校驗,於是用hook過了簽名校驗,正常運行,VIP到手。
可是這樣怎么發給女神呢?女神的手機沒有root也沒有hook框架。分析so?實在太復雜了,一時半會根本來不及,要讓女神等你三五十天?恐怕到時候是備胎都當不成了吧。
怎么辦?
總體思路:
既然修改so不成,也無法使用hook框架,那么就從別處入手。
本文用本人曾經懸賞過的加固APK(懸賞期內沒人破解成功,加固強度還可以)進行分析:
由於so非常復雜,時間關系直接放棄分析。通過HOOK發現so的中簽名校驗是通過this.getPackageManager().getPackageInfo來獲取的,於是想法就來了——
這個this是MainActivity的實例,所以這個this是一個很大的突破口:
思路活躍的同學可能已經發現了,只要覆蓋MainActivity的getPackageManager就行了。
具體過程如下:
1.寫一個HookPackageManager,專門用來HOOK各種PM相關方法:
public class HookPackageManager extends PackageManager {
private PackageManager mBase; //用來做適配,返回其他信息
public HookPackageManager(PackageManager base) {
mBase = base;
}
@Override
public PackageInfo getPackageInfo(String packageName, int flags)
throws NameNotFoundException {
if (!"ywt.android.test6".equals(packageName)) {
//如果不是目標APK,則返回原始數據
return mBase.getPackageInfo(packageName, flags);
}
PackageInfo pkgInfo = new PackageInfo();
pkgInfo.signatures = new Signature[] {
new Signature(new byte[] {
//這是填寫原始APK中讀到的簽名,用來欺騙so,很長就不貼了,后面會給出APK,反編譯看即可。
})
};
return pkgInfo;
}
//下面還有很多需要implements的方法,太多了,就不寫了,后面會給出APK,反編譯看即可,只要用mBase一一調用返回即可。
}
2.寫一個HookMainActivity,代碼如下:
public class HookMainActivity extends Activity {
@Override
public PackageManager getPackageManager() {
//由於調用的是this.getPackageManager(),所以只要重寫getPackageManager,返回一個偽造的實例,就可以實現欺騙
PackageManager pm = new HookPackageManager(super.getPackageManager());
return pm;
}
}