成长值: 201
 签到天数: 5053 天 [LV.Master]伴坛终老  
 | 
 
 
发表于 2017/2/19 01:16
|
显示全部楼层
|阅读模式
| Google Chrome 56.0.2924.87 | Windows 10  
 
 
 
标 题: 【原创】调试小技巧:绕过apk安装时的签名验证 
作 者: flankersky 
时 间: 2014-08-06,18:27:06 
链 接: http://bbs.pediy.com/showthread.php?t=190876 
 
小菜第一次发帖,不知道这篇文章有没有意义,大家多多包涵,多多指点。本文所说的小技巧的作用只有一个,就是能让你重打包某些有签名验证的apk用于调试,除此之外,确实没什么用处,大牛们可以直接飘过了。 
 
1、 
      事情是这样的,最近在调试一个apk,有签名验证,验证方法是将签名信息发往服务器验证的,所以不能进行重打包。更变态的是,签名信息的获取是在.so里调用Java层的getPackageInfo实现的。 
      最初的想法就是能hook住getPackageInfo,替换掉里面的签名信息。试过用xposed hook 函数getPackageInfo,但是没有成功,咨询过高人说是“动态加载的.so是没法hook住的”,所以这种方法就作罢了。还想过.so注入,定制rom等方法,但因自己都没有做过,就没有尝试。 
 
2、 
      其实自己一直有个想法,就是能不能把重打包之后的apk里的签名信息(RSA文件)换成原apk的签名信息,如果这样能安装成功的话,是不是就能突破这种签名验证了。 
      在网上看到了一篇文章http://wendal.net/321.html,说通过修改services.jar能“移除apk的签名验证机制”,于是就试验了一下,把重打包过的apk里的CERT.RSA文件替换为原先apk里的CERT.RSA,然后按照作者的方法修改了services.odex(网上有对odex的修改方法),结果还是没有安装成功,但是直接修改odex的方法还是很不错的。错误的原因可能还是因为修改的函数不对引起的。于是,根据安装时报出来的错误INSTALL_PARSE_FAILED_NO_CERTIFICATES,还有Logcat里的堆栈信息,去源码里去找。最后定位到了出错的位置是在android4.0\libcore\luni\src\main\java\org\apache\harmony\security\utils\JarUtils.java中的verifySignature函数,在函数的最后: 
代码: 
if(!sig.verify(sigInfo.getEncryptedDigest())) { 
               throw new SecurityException("Incorrect signature"); 
            }  
 
抛出了个异常,罪魁祸首就是这个异常,函数的意思应该是验证CERT.RSA里的签名信息正确与否,所以这里应该直接跳过就OK了。 
观察源码,最后这部分代码是编译到了core.jar里,也就是/system/framework/core.odex里。 
将code.odex反编译出来,找到\core\org\apache\harmony\security\utils\JarUtils.smali,在verifySignature函数中找到下面的位置,添加上红色的那句话。 
 
代码: 
  invoke-virtual {v0, v1}, Ljava/security/Signature;->verify([B)Z 
    move-result v27 
    const v27, 0x1 
    if-nez v27, :cond_186  
 
最后,重新编译成odex,替换掉原先的core.odex。 
再按上面说的,将重打包过的apk里的CERT.RSA替换为原先apk里的CERT.RSA。就可以正确安装,并且获取的签名信息还是原先的apk的签名信息,可以愉快的进行调试了。。。 
 
PS: 
      直接修改odex据说是有风险的,所以,大家小伙伴们修改之后要是开不了机,不要来找我。上面的测试只在NEXUS 4上测试通过。 
另外,这只是自己想出来的方法,不知道大家都是用的什么方法,希望大家不吝赐教啊。 
 
-------------------------------------- 
2014-08-07 14:10 
 
多谢@SpaceDye 提醒,我怎么就没想到写个xposed插件呢。 
代码就几行,但能达到上面修改code.odex的效果。代码就直接贴出来了。 
代码: 
   public void initZygote(StartupParam startupParam) throws Throwable { 
       
               XposedHelpers.findAndHookMethod("java.security.Signature",null,"verify", byte[].class,new XC_MethodHook(){ 
             protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
               XposedBridge.log("disabled verifysignature......"); 
               param.setResult(Boolean.TRUE); 
          }    
               });  
 
Xposed框架插件下载地址:https://pan.baidu.com/s/1nv4UkFf 
 
 |   
 
 
 
 |