故事开始,某天,你暗恋的女神需要某个app的VIP,怎奈你兜兜空空如也,根本买不起VIP,然后你发现这个app的VIP是本地判断的,于是……
经过一番折腾,很快就改好了APK,重打包安装运行。提示非法操作?
又一番折腾,发现程序主要逻辑在so中,so被混淆的面目全非还进行了加固,最后发现在so中进行了APK签名校验,于是用hook过了签名校验,正常运行,VIP到手。
可是这样怎么发给女神呢?女神的手机没有root也没有hook框架。分析so?实在太复杂了,一时半会根本来不及,要让女神等你三五十天?恐怕到时候是备胎都当不成了吧。
怎么办?
既然修改so不成,也无法使用hook框架,那么就从别处入手。
由于so非常复杂,时间关系直接放弃分析。通过HOOK发现so的中签名校验是通过this.getPackageManager().getPackageInfo来获取的,于是想法就来了——
这个this是MainActivity的实例,所以这个this是一个很大的突破口:
思路活跃的同学可能已经发现了,只要覆盖MainActivity的getPackageManager就行了。
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一一调用返回即可。 }
public class HookMainActivity extends Activity { @Override public PackageManager getPackageManager() { //由于调用的是this.getPackageManager(),所以只要重写getPackageManager,返回一个伪造的实例,就可以实现欺骗 PackageManager pm = new HookPackageManager(super.getPackageManager()); return pm; } }
附件中包含了原始crackme.apk(重打包就会提示APK被修改)和过签名校验的crackme.apk(随便修改都不会提示APK被修改)