android逆向8

来源:互联网 发布:ahc正品验证软件 编辑:程序博客网 时间:2024/06/05 09:05

做为Android开发者,我们应该知道没有签名的Apk是无法在真机(模拟器)上安装运行的。为了防止自己开发的Apk被别人二次打包,有些开发者会在App运行时获取当前Apk的签名信息并与正版Apk的签名信息进行比对,一旦发现不相同,就会弹出对话框提示用户当前应用是盗版或者终止App的运行,这就是Apk签名校验。开发者可以在Java层或者NDK层实现签名校验,而破解NDK层的签名校验要比破解Java层的签名校验难度更大一些。因为黑客一般会修改smali代码,然后再进行二次打包,而二次打包生成的classes.dex与正版Apk中的classes.dex肯定不同,所以有些开发者会采用classes.dex的 MD5校验来保护自己的Apk。本文要介绍的是破解Java层的签名校验,我当时是参考这篇文章:(爱加密系列教程七)程序员应该学习的签名破解学习签名破解的。下面就以某厂的电池管家为例,介绍一下破解Java层签名校验的流程。本文使用的电池管家版本为2.0.2,我们的目标是破解签名校验并进行二次打包(如果不绕过签名校验,运行二次打包生成的电池管家会出现闪退现象,有兴趣的童靴可以试试)。下面是具体步骤:

0x00 反编译电池管家Apk

      将电池管家Apk放入某个文件夹中,在该文件夹中打开命令提示符,
      输入命令:apktool d dianchiguanjia_10.apk
      如图1所示:


图1  输入命令反编译电池管家


0x01 定位获取当前Apk签名的函数

      使用Notepad++的“在文件中查找”功能定位到反编译apk所得到的smali文件夹,然后搜索签名信息对应的smali代码:
      ”Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature”。具体如图2和图3 所示:

       

                     图2 使用Notepad++在文件中查找字符串的功能   



图3  在反编译得到smali文件夹中查找签名字符串


     搜索完毕后,我们会发现有2个函数用到了签名信息,如图4所示:


图4  查找签名字符串所命中的目标


    我们依次查看这2个函数,先查看\qpm\gh.smali文件中的函数.method private a(Landroid/content/pm/PackageInfo;Lqpm/ge;)V,该函数一共调用了3次签名信息,但是该函数的返回值为Void,由此可以判断这应该不是获取Apk签名的函数。我们再来看一下\qpm\ec.smali文件中的函数.method private al(Ljava/lang/String;)Ljava/lang/String;,该函数只调用了1次签名信息,但是该函数的返回值为String,再次查看该函数的内部实现,我们可以断定这就是获取当前Apk签名信息的函数,具体如图5所示:


图5  获取Apk签名的函数


0x02 定位对比Apk签名的函数

         一般情况下,签名对比函数的实现流程如下所示:
      (1)获取当前Apk的签名信息;
      (2)获取正版Apk的签名信息;
      (3)将当前Apk的签名信息和正版Apk的签名信息进行比对,如果二者相同则返回真,如果不同则返回假。
       从上面的流程中,我们可以获取到两个关键信息:
       1.签名对比函数一定会调用“获取当前Apk的签名信息”函数,
       2.签名对比函数一定会出现equals函数以判断两个签名信息是否相同,而且签名对比函数的返回值一般是Bool类型。
      由此我们可以找到签名破解的突破点:通过查找smali文件夹中哪些函数调用了al函数,然后再依次筛选这些函数来定位对比Apk签名的函数。再次利用Notepad++的“在文件中查找”字符串的功能,输入搜索字符串“->al(”  /*在smali语法中->表示调用,注意不要遗漏了al函数后面所带的左括号*/ 。可以得到调用al函数的函数列表如图6所示:


图6  调用获取签名函数的函数列表


         虽然有7个函数调用了al函数,但是仔细查看我们不难发现真正与获取当前Apk签名函数 

         Lqpm/ec;->al(Ljava/lang/String;)Ljava/lang/String; 相吻合的只有一处:\qpm\ec.smali文件中的第444行,这条语句位于hD函数中。所以接下来我们需要重点关注hD这个函数,以判断其是否为签名对比函数。在hD函数中,我们发现了显示本Apk签名信息和正版Apk签名信息的语句块,分别如图7和图8所示:


图7 hD函数中显示本Apk签名信息的语句块


图8 hD函数中显示正版Apk签名信息的语句块


       继续查看hD函数,可以发现该函数将当前Apk信息与正版Apk签名信息进行了对比,如果二者相同则返回true,如果二者不相同则返回false。由此我们可以确定hD就是对比Apk签名的函数。

0x03 修改对比Apk签名的函数

       找到对比Apk签名函数hD后,只需要修改该函数的返回值,在hD函数中添加指令“const/4 v0, 0x01”令其强制返回true,即可破解Java层的Apk签名校验。具体如图9所示:


图9  强制hD函数的返回值为真


为了与正版Apk相区别,我们可以将\res\values\strings.xml中的app_name节点值改为“电池管家(签名破解版)”,具体如图10所示:


图10  修改App的名字


0x04  二次打包apk并进行签名
         打开命令提示符,
         输入命令:apktool b dianchiguanjia_10
         对电池管家进行二次打包,具体如图11所示:

图11  二次打包Apk并进行签名


         然后再用签名工具对二次打包生成的Apk进行签名即可。

0 0
原创粉丝点击