在使用115网盘的时候,发现里面的离线下载功能的在线视频观看功能竟然有10分钟的广告时间,于是开始萌生尝试破解的它的想法,首先声明,本帖只作为技术研究,请读者遵守相关法律法规,不要侵犯以他人的商业利益为目的进行相关破解行为。
由于之前破解过多个apk 修改里面的smali代码研究相关的技术,所以刚开始我解开115网盘apk的时候,虽然看到里面的代码混淆了,经过一番研究之后,还是找到了广告的两个关键位置,一个开始播放前的10分钟内广告,一个是滑动进度条的时候的5到11秒随机长度广告,两个都是在VideoVitamioPlayActivity这个类里面,如下图:
找到VideoVitamioPlayActivity.smali文件,并找到上面图中两个位置的smali代码并删掉,重新编译成classes.dex文件,替换原来apk 包里面的相应文件,重新签名,放到手机安装成功。可总是打不开,我立刻把手机连接上电脑,看logcat输出,发现里面输入一个error,大大的“Illigal APP...”几个字出现在我眼前,我顿时兴奋了,决定继续玩它下去。
在logcat中,我看到这是native层里面报出的错误,心想这肯定是在第一个activity或application里面调用native代码,果然在DiskApplication这个类的onCreate方法里面找到了一行代码EncryptNative.init(getApplicationContext());,于是跟踪进去 ,发现其调用了yyw_encrypt.so库,并有两个对外方法:
public static native String getLoginSign(String paramString1, String paramString2, String paramString3); public static native void init(Object paramObject);
我开始尝试性的把DiskApplication里面的EncryptNative.init(getApplicationContext());删除掉再重新编译、运行。果然不出所料,APP可以运行起来了,可是在登陆的时候还是被强制关闭了,logcat依然输出大大的“Illigal APP...”。
这会我开始把yyw_encrypt.so扔进IDA pro,研究这两个方法的实现逻辑,如下图
从上图的方法可以看出来,init方法里面获取apk当前的签名经过sha1转换后与设定的两个sha1值进行相等比较,并把比较结果放到IS_CORRECT全局变量里面,只要一个相等,就会正常结束方法,否则跳转到loc_1720地址处弹出提示并关闭APP。而第二个方法:
从getLoginSign 方法的执行流程中可以看出这方法首先会判断IS_CORRECT是否等于1,如果不等于的话就跳转到loc_1458处执行,执行提示“Illigal APP...”和关闭app动作。而等于的话就直接进行登陆sign字符串的转换,而这个地方恰恰是没有和当前签名的sha1值进行相关运算,只是把参数里面的几个字符串进行相关运算返回一个结果 ,所以破解它的方法就轻松看出来了,只到把init的CMP处理的R9改成1就可以了,而为了达到这个目的,可以在很多地方入手,经过一番研究,最后我选择了equals函数入手,因为这是最简单方便的,只有init方法里面的两处调用,不会影响其它地方:
如图,在equals方法执行的最后面,R0作为返回数据存入的寄存器,里面存入的是判断结果,只要把R0存入立即数1,就可以返回相等的判断结果,于是开始查阅ARM的指令机器码(ARMv7-M Architecture Application Level Reference Manual),查询16位的Thumb指令的MOV立即数,在A6.7.75章节找到了这指令的相关说明:
根据文档说明 可以得到MOV R0,#1的机器码为:20 01,接着找到equals方法MOV R0,R5指令的所在位置为000015FB,打开Ultraedit,把000015FB的28 46改成01 20,改了之后再从IDA打开libyyw_encrypt, 里面的指令已经变成MOVS R0,#1,如下图所示:
由于修改的是armeabi-v7a里面的so,还需要修改armeabi里面的so, 虽然会有点区别,但是这个MOVS R0,#1指令在两个版本的ARM指令中是一样的,以同样的方法替换原来的机器码,过后替换掉原来apk中的so文件,重新签名,运行,登陆,离线播放,一切正常,成功干掉长广告,至此,破解终于完成。