这个Apk的界面和功能刚才是一样的,只是实际的序列号不一样,没错,这个apk的序列号是变化的,具体就是每次程序启动就会产生一个10000以内的随机的整数,然后这个随机数就作为正确的序列号。当然,实际的软件不会有出现每次都不一样的序列号。这里使用随机数也是为了使得解密难道加大点,另外也希望起到抛砖引玉的作用。
目标还是一样:找出这个正确的序列号。
在这里,解密的思想是使用smali代码注入。简单的说,就是让程序通过修改反编译的smali代码,让程序本身去告诉我们,这个序列号是什么。
可能很多朋友觉得,读smali代码可以,怎么写是问题。其实也比较简单,照葫芦画瓢就可以了。
先讲讲我的思路,如果要在Android画面上多加一个控件用于显示正确的序列号,这样可能还要修改layout布局,麻烦不要紧,最怕出错。所以,个人觉得最稳妥的办法,就是使用Log类。所以,我的想法是在打印序列号错误信息的时候。同时把正确的序列号通过Log.d输出到logcat中。
破解步骤:
1.1第一步还是一样的,反编译apk。
先使用apktool反编译apk应用程序得到CrackMe-RandomInteger,为了不破坏这个反编译出来的代码,我复制一份并改名为CrackMe-RandomIntegerTest。
1.2简单阅读理解代码:代码中如何得到这个正确的序列号
有语言基础的,应该不难懂,注意到我们稍候用到的一个地方。
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的代码呢?
我的方法很笨,但也很实用,我新建了个应用程序,就写两句:
2 Log . d( " SN: " , String . valueOf(a));
然后使用apktool反编译这个apk,然后就得到了Log.d的smali代码了,关键的两句大概是这样的。
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中获取到正确的序列号。加入的代码如下。
在实际操作的时候,复制粘贴代码比较妥当。
2 iget - object v1 , p0 , Lcom / mstar / test / LisenceCheck$ 1 ; - > this$ 0 : Lcom / mstar / test / LisenceCheck ;
3 iget v1 , v1 , Lcom / mstar / test / LisenceCheck ; - > a : I
4 invoke - static { v1 } , Ljava / lang / String ; - > valueOf ( I ) Ljava / lang / String ;
5 move - result - object v1
6 invoke - static { v0 , v1 } , Landroid / util / Log ; - > d ( Ljava / lang / String ; Ljava / lang / String ; ) I
1.5 打包并签名apk文件。
打包:
签名:
1.6安装到虚拟机中进行测试
使用adb push上传到模拟器中的sdcard中。然后使用apk安装器。
为什么要使用apk安装器使用呢?因为假如我们的apk有问题,apk安装器安装的过程中,我们可以看到logcat中的错误信息,然后或许可以排除一些基本的错误。但如果你直接adb push到/data/app中,可能就看不到这些信息。并且,错误的apk应用程序,可能不会出现在系统的菜单中。
运行后,我们随便输入一个序列号:
然后点击验证,理所当然的,出现Lisence uncorrect!的信息(如果你随便都能猜中10000以内的随机数,请告诉我,咱们去买6合彩)。
然后,我们adb shell,然后logcat,就能从中看到正确的序列号输出。
看到了吧,这里是我们使用log.d输出的正确的序列号。7716,然后,我们在apk中输入这个序列号。lisence correct!解密成功了。
值得注意的是,这个APK的序列号是在OnCreate通过随机数获取的,可能你下次启动程序时,就会变化。
使用到的apk文件在我的共享资源中,需要的朋友请前往下载。