android逆向|第一次进行android逆向的过程记录

前言 要逆向的是一款叫shengqian快报的app,具体要分析sign签名的加密过程。
环境配置及工具 系统:macOS 10.14.1
模拟器:mac版夜神模拟器 3.0.3.0
抓包工具:Charles
逆向工具:apk-tool、JD-GUI、frida、adb、dex2jar、objection
准备工作 从网上下载shengqian快报的apk保存到电脑上,打开夜神模拟器,将apk拖到夜神模拟器里面安装。
抓包分析 使用Charles对夜神模拟器进行抓包。(需要在夜神模拟器上安装好Charles的证书然后配置好代理)
打开shengqian快报app,对需要分析的页面进行抓包。
分析抓到的包,发现目标接口:
android逆向|第一次进行android逆向的过程记录
文章图片

返回的json就是需要的数据:
android逆向|第一次进行android逆向的过程记录
文章图片

ok。到这里目标接口就找到了,接下来要对这个接口进行分析。
分析发现这个接口接收一个post请求,包含了30多个参数,其中最重要的就是我们要分析的sign参数了。
android逆向|第一次进行android逆向的过程记录
文章图片

我们可以先尝试用postman或者python脚本向这个接口发送一个post请求试试,结果返回的是{"status_code":-1,"message":"invalid sign"},可以证明在服务器端进行了sign的校验,所以我们想要得到这个接口的数据就需要将sign加密过程找到然后伪造一个合法的post请求。
逆向分析 用apktool反编译apk文件为smali

apktool d jz_dsp_ydcx_zcw17.apk

将反编译后的文件夹后缀名修改为zip,然后进行解压,解压后的文件夹里含有classes.dex的文件。最后使用dex2jar工具将classes.dex文件转换为classes-dex2jar.jar文件。
用JD-GUI打开最后的jar文件,发现代码是经过混淆的。
android逆向|第一次进行android逆向的过程记录
文章图片

点开左上角的手电筒全局搜索sign,
android逆向|第一次进行android逆向的过程记录
文章图片

发现一处比较可疑的地方,这个e函数猜测应该就是用parama来加密,
android逆向|第一次进行android逆向的过程记录
文章图片

接下来进入e方法,可以确定这就是加密的方法了。stringBuilder创建了一个用&连接所有参数的字符串,最后又添加了一个32位的字符串,通过b.a()方法来加密。
android逆向|第一次进行android逆向的过程记录
文章图片

接下来进入b类查看,可以看出来这就是md5加密,
android逆向|第一次进行android逆向的过程记录
文章图片

确认完加密算法,就需要分析parama里面都是什么了。
打开夜神模拟器,adb shell进入命令行(模拟器的root启动要开启),运行frida-server。
模拟器里打开shengqian快报app,新开一个命令行输入下面命令查看进程,
frida-ps -U

找到对应进程android逆向|第一次进行android逆向的过程记录
文章图片
就可以开始hook了。
输入下面命令进入objection,
objection -g com.****.coupon explore

watch一下e方法看看返回值、调用栈和传入参数的内容都是啥。
android hooking watch class_method com.****.coupon.httptask.a.a.e --dump-args --dump-backtrace --dump-return

点击进入详情页后,发现e方法被调用了很多次,返回值其实就是加密后生成的sign(调用栈就不截图了)
android逆向|第一次进行android逆向的过程记录
文章图片

同时在Charles的抓到的目标接口中,发现sign和hook到的返回值一样。
android逆向|第一次进行android逆向的过程记录
文章图片

因此可以确认接口的sign是通过e这里生成的了。
接下来就要去分析传入e的parama是什么了。
读一下e方法里面的代码,可以看出来parama.k()可以获得一个List类型的对象,然后遍历这个对象并且生成一个url参数格式的字符串(name1=value1&name2=value2……)
android逆向|第一次进行android逆向的过程记录
文章图片

知道了这些就可以写一个简单的hook脚本来打印一下parama里面的内容了。
python脚本:
import sys import fridaPACKAGE = 'com.****.coupon'def hook(): jscode = open('script.js', 'r').read() # 查找USB设备并附加到目标进程 session = frida.get_usb_device().attach(PACKAGE) # 在目标进程里创建脚本 script = session.create_script(jscode) print('[*] Start attach') # 加载创建好的javascript脚本 script.load() # 读取系统输入 sys.stdin.read()if __name__ == '__main__': hook()

script.js:
function hook(){ Java.perform(function(){ var a = Java.use("com.****.coupon.httptask.a.a"); a.e.implementation = function(parama){ var result = this.e(parama); var l = parama.k().size(); console.log("len:",l,"len:",l); // 随便打印几个参数 console.log("parama1",parama.k().get(1)); console.log("parama31",parama.k().get(31)); console.log("parama34",parama.k().get(34)); return result; } }); }; setImmediate(function(){ setTimeout(hook, 2000); });

hook好之后,发现加密的这些参数其实就是post里面提交的参数,到这里sign分析就结束了。
【android逆向|第一次进行android逆向的过程记录】我们要实现sign加密算法的话,就保留关键的参数,然后将这些键值进行拼接,字符串的末尾要拼接"81f454ac98956541b195f2c7f9e53a06",最后再对字符串进行一次MD5就可以了。

    推荐阅读