Android破解初探之:Synthesia
( 原文地址:https://0xffff.one/d/479 )
最近试了一下Android的逆向,随便写(shui)篇帖子记录一下。
环境搭建·
首先说一下Android逆向相关的工具:
- Android Killer:(简称AK)主要用来做apk解包和重打包、重签名等,也可以用来看/改源码、搜索字符串等,可以在52的网盘里下载,另外网盘里也有新版的apktool、dex2jar等工具,虽然AK里面也有,但毕竟AK都有点旧了,对于较新版的AKP还是要用新版的工具的。
- Android Studio:(简称AS)就是Google的Android开发工具,主要可以用来做动态调试,虽然这次用不到hhhh。关于动态调试的方法可以参考这里,主要是找pid做端口转发那一步。
- IDA pro:通常APK解包后都会有一些.so的库,这个就需要用IDA来反编译和patch。
- Android的设备/虚拟机/模拟器:最好能配好adb,我用的是跑在虚拟机的android-x86。
- Java SDK:AK需要用到Java环境,大部分Android程序也需要Java环境,推荐Java8,我用Java10在重打包时翻了车 - -
解包·
首先需要搞到apk文件,我弄的是synthesia 10.6版本,当前Google Play上的那个,网上找下也可以搞到。用AK打开后是这样的:
第一次打开可能会提示Java SDK找不到,打开后在配置的Java那里选择JDK路径里的bin目录即可。
由于AK版本的问题,会卡在反编译源码那一步,把AK关掉后重启就可打开,但源码时没有反编译出来的,如果要源码的话可以另外用新版的dex2jar把AK目录里的 project/项目名字的文件夹/ProjectSrc/classes.dex 反编译出来(dex2jar和dex2smali都搞一下,然后把dex2smali搞出来的文件夹重命名smali),看源码时好像还要手动用AK的bin目录里的jd-gui打开。(注意:到这一步只能看到Java的代码,不能反编译.so库文件的代码)
在工具栏的Android里可以对已经连接adb的Android设备进行操作(注意必须先用adb连接,不然设备里没得选,AK的bin里自带adb,连接方法网上一大堆)。然后选项中的编译就是apk的重打包,如果重打包失败的话可以试下在AKPTOOL管理器里添加新版的apktool,另外Java的版本可可能会对编译有影响。
关于Synthesia·
Synthesia是一个弹琴的软件(对,虽然我也不知道为什么一个搞PWN的会搞上一个钢琴软件了hhhh),里面大部分功能都需要内购才能用的(虽然这次我搞的不是内购 - -)
在最新的版本里发现它在 Free Play 里可以有50秒的试用
在右上角会有个倒计时,倒计到0时就会弹出让我内购解锁:
既然是有倒计时,那么我直接把倒计时设成一个非常大的数不就等于无限试用了,也相当于把 Free Play 这个功能破掉了。
破解过程·
用AK瞄了一下后发现没有相关代码,于是就锁定了 libsynthesia.so 这个库,Synthesia做了x86、x86_64、arm_v7、arm_v8这四个库,由于我是用android-x86_64来调试,所以会以x64做例子,其他两个也大同小异。
x86_64·
首先要找到对应代码的位置,用字符串查找的方法。首先想到的是“free play”,但没找到什么东西,然后搜"demo"时找到了个“helpDemoLocked”,还无意中发现了“0:%02i”这个字串,这个就是printf里打印时间的格式了,引用的函数也只有一个,所以就可以直接锁定0x1CC150里的那个函数了。
下面说一下函数的大概功能,函数很长,但关注两个片段就好了。首先是大概是0x1CDB3A位置里:
可以大概看出1428行里就是用来计算显示的时间的,51000000就是试用倒计时的51秒,根据上下文可以发现这个计算出来的时间只是用来显示的,实际的时间会在上图的counter的变量里(名字只是我起的),如果找到这个变量改变的地方patch掉就可以了,但是有更简单的方法。
先来看一下第二个地方,大概0x1CDDC0的地方:
上图1511行的那个if就是判断如果时间够了后就弹出让我内购的那个框,如果把if的条件patch成永假(或直接跳转),那就可以跳过内购弹窗了。
patch!·
patch的有3个地方,其中2个是为了美观的 - -
第一个地方也就是最主要的是0x1CDDB5里,把“jnz”patch成“jmp”就可以绕过上面那个if条件直接跳转。
patch前:
patch后:
第二、三个地方只是为了右上角那个倒计时好看一点(让它消失有点麻烦,就顺便做成计时的了- -),做成计时器的话首先要让它开始时变成0,把0x1CDB4E里的"30A32C0h"patch成"0"
patch前:
patch后:
最后是把输出美观一些,把0x692FB3里的格式化字符串改一下,原先是"0:%02i"的改成“<%is->”,这个可以自己定制,怎么好看怎么改就好了,但是“%i”好像是一定要有的,不然会闪退。
patch前:
patch后:
说说arm·
arm的patch方法也是一样的,只是arm的汇编实在。。。
首先是arm里的"jmp"操作是用"B"指令(v7的在0x115C06),还有mov一次只能16位,v7的要用movw和movt分两次移动,v8的要mov … , sls #16、mov … , sls #32等移动
v7·
第一张有一个是多余的,主要是跳转那个:
v8·
重打包·
重打包用AK,按编译就行(傻子都会hhh,但注意patch后的库要放回project目录下的 Project/lib 对应的文件夹里),编译好的包在对应project目录里的bin目录里,直接安装就好。
结果·
最后就多了个计时器,50秒的试用也没了
最后的最后·
仅用于学术交流,请勿用于非法用途 :) https://drive.google.com/file/d/1L6B7aX0RJ4Zcy9Xgkfwq2ucAVPBiF19J/view?usp=sharing