Android Apk解密工程初探(2)--代码注入

来源:互联网 发布:淘宝艾滋病试纸准确吗 编辑:程序博客网 时间:2024/05/21 19:49

这个Apk的界面和功能刚才是一样的,只是实际的序列号不一样,没错,这个apk的序列号是变化的,具体就是每次程序启动就会产生一个10000以内的随机的整数,然后这个随机数就作为正确的序列号。当然,实际的软件不会有出现每次都不一样的序列号。这里使用随机数也是为了使得解密难道加大点,另外也希望起到抛砖引玉的作用。

目标还是一样:找出这个正确的序列号。

在这里,解密的思想是使用smali代码注入。简单的说,就是让程序通过修改反编译的smali代码,让程序本身去告诉我们,这个序列号是什么。

可能很多朋友觉得,读smali代码可以,怎么写是问题。其实也比较简单,照葫芦画瓢就可以了。

先讲讲我的思路,如果要在Android画面上多加一个控件用于显示正确的序列号,这样可能还要修改layout布局,麻烦不要紧,最怕出错。所以,个人觉得最稳妥的办法,就是使用Log类。所以,我的想法是在打印序列号错误信息的时候。同时把正确的序列号通过Log.d输出到logcat中。

破解步骤:

1.1第一步还是一样的,反编译apk。

先使用apktool反编译apk应用程序得到CrackMe-RandomInteger,为了不破坏这个反编译出来的代码,我复制一份并改名为CrackMe-RandomIntegerTest。

clip_image002

1.2简单阅读理解代码:代码中如何得到这个正确的序列号

有语言基础的,应该不难懂,注意到我们稍候用到的一个地方。

1 iget-object v1, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck; 
 
2 iget v1, v1, Lcom/mstar/test/LisenceCheck;->a:I 
 
3 invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; 
 
4 move-result-object v1

上述这段代码,就是从前面的OnCreate中获取已经得到的随机数a(具体的OnCreate可以看看LisenceCheck.smali的代码)放到v1中,然后再把v1转换为字符串放到v1中。

简单备注:

第二行的“a:I” 中的a是变量名,I是整数的意思。

第三行的“{v1}”这样用大括号标起来就是作为参数传入后面的方法。

1.3打造Log.d的smali代码。

上面的序列号我们可以照葫芦画瓢得到。那Log.d怎么写这个smali的代码呢?

我的方法很笨,但也很实用,我新建了个应用程序,就写两句:

1 int a = 0;
2 Log.d("  SN:  ", String.valueOf(a));

然后使用apktool反编译这个apk,然后就得到了Log.d的smali代码了,关键的两句大概是这样的。

1 const-string v0, "  SN:  "
2 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

1.4 把1.2、1.3部分的代码,合并加入到合适的位置。

我们当然是把代码加到lisence uncorrect!后面(放到goto :goto_0前面),以便我们输入一个错误的序列号的时候,能够在logcat中获取到正确的序列号。加入的代码如下。

在实际操作的时候,复制粘贴代码比较妥当。

const-string v0, "  SN:  " 
 
iget-object v1, p0, Lcom/mstar/test/LisenceCheck$1;->this$0:Lcom/mstar/test/LisenceCheck; 
 
iget v1, v1, Lcom/mstar/test/LisenceCheck;->a:I 
 
invoke-static {v1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; 
 
move-result-object v1 
 
6 invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

1.5 打包并签名apk文件。

打包:

clip_image012

签名:

clip_image014

1.6安装到虚拟机中进行测试

使用adb push上传到模拟器中的sdcard中。然后使用apk安装器。

为什么要使用apk安装器使用呢?因为假如我们的apk有问题,apk安装器安装的过程中,我们可以看到logcat中的错误信息,然后或许可以排除一些基本的错误。但如果你直接adb push到/data/app中,可能就看不到这些信息。并且,错误的apk应用程序,可能不会出现在系统的菜单中。

运行后,我们随便输入一个序列号:

clip_image016

然后点击验证,理所当然的,出现Lisence uncorrect!的信息(如果你随便都能猜中10000以内的随机数,请告诉我,咱们去买6合彩)。

然后,我们adb shell,然后logcat,就能从中看到正确的序列号输出。

clip_image018

看到了吧,这里是我们使用log.d输出的正确的序列号。7716,然后,我们在apk中输入这个序列号。lisence correct!解密成功了。

clip_image020

值得注意的是,这个APK的序列号是在OnCreate通过随机数获取的,可能你下次启动程序时,就会变化。

使用到的apk文件在我的共享资源中,需要的朋友请前往下载。