56回答

2收藏

安卓逆向:某手机应用市场app so层算法还原

信息分享 信息分享 12542 人阅读 | 56 人回复 | 2020-11-15





前阵子写在公众号的,复制过来吸吸粉








正文



1.抓包








2.分析参数









只有一个加密参数:zsData ,看起来像 base64 编码。那先去在线 base64 网站试着解密一下,如果是就可以少掉很多头发啦




然鹅。。。并不是 ↓










所以继续,把apk拖进 jadx,反编译后搜索 zsdata ↓










点击跳转到图中标记 1 的函数  ↓










可以看到最后调用图中标注为 4 的 native 函数。




是个 native 层的函数,如果想省事就用 rpc 调用,

想掉头发就去还原算法。





先简单说下 frida-rpc:

图中标记的 2 的函数 ,里面的操作只是把str 和 str1 转换成 bytes 数组,最后传给 native 函数,没有其他的操作。




啥意思呢,就是这里函数 2 跟函数 4 的返回结果实际上是一样的。





那我们进行 hook 或者 frida-rpc 调用的时候都只需要关注76行的 函数 2 就行了,它参数和返回值都是字符串,都不用转换类型,打印或者传参都十分方便,比较省事。




这个函数第一个参数是 Context ,是上下文,其余三个参数不知道是什么,上frida hook 一下 ↓




可以看到都打印出来了,现在知道了参数,那我们就可以用 frida-rpc 来调用这个函数












native 层分析





1.定位加密函数





用 IDA 打开 so 文件




搜索一下函数名 o000000O 发现搜不到,那就是动态注册的。




那就从 JNI_OnLoad 函数里找到注册函数,再找到真实函数名,具体操作请看上一篇。




顺利的找到真实的函数名为:abc










为什么这里有六个参数?

是因为前面两个是JNI的参数,从第三个参数开始才是java层传来的参数,固定用法,记住就好。







2.静态分析




先找到 return,看最后的返回值是哪个变量赋值的




一顿分析










分析后找到关键函数,最后 return 的值就是 17





    v17 = j_j_salt_b64_encode(v31, (int)v13);





    继续找v31 和 v13











    v31是 java 层传进来的第 2 个参数转换成的 bytes 数组,也就是这一长串转换的








    然后找 v13






    因为 a5=null 所以 v13 = 'ZySOWKE3-1.Vtw#!8u&~5XeT%74Mz>bG'
    现在知道了 j_j_salt_b64_encode() 函数的两个参数





    还要进入这个函数,看看它是怎么加密的










    简单说下这个算法





    这个函数里有两个关键函数:

    • 23行的 j_j_md5() 函数,

    • 38行的 j_j_base64() 函数,




    j_j_md5() 函数对'ZySOW5KE3-1.Vtw#!8u&~5XeT%74Mz>bG'进行md5编码后转换成 bytes 数组




    36行 v5=参数1的数组长度, 只要v5!=v8,就一直循环,33行右边是两个数组的元素进行异或运算,填充到 v7




    38行的 result 就是我们要的 zsdata 参数,j_j_base64() 对填充后的 v7 bytes 数组进行 base64 加密。得到 zsdata




    python 还原算法:

    [ttreply]
    1. encode_str = r'{"terminal":"{"iccid":"","romName":"","50uid":"","geo":"","httpAgent":"Dalvik/2.1.0 (Linux; U; Android 6.0.1; Nexus 5 Build/MMB29S)","mac":"344df73cc3ee","romVersion":"","timestamp":"' + ts + r'","oaid":"","locationInfo":"{\\"area\\":\\"\\",\\"province\\":\\"\\",\\"city\\":\\"\\"}","osVerCode":"23","imei":"359250052185137","50uuid":"","brand":"google","osVerName":"6.0.1","netinfo":"WiFi","resolution":"1080*1776","adid":"874cc857371673e6","userAgent":"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MMB29S; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.117 Mobile Safari/537.36 package/com.market2345 versionName/7.5 versionCode/127","imsi":"","model":"Nexus 5"}","page":"1","type":"az_xpyx"}'
    复制代码
    1. v3 = list(encode_str.encode())
    复制代码
    1. v5 = len(v3)
    复制代码
    1. v2 = 'ZySOWKE3-1.Vtw#!8u&~5XeT%74Mz>bG'
    复制代码
    1. v16 = list(hashlib.md5(v2.encode()).hexdigest().encode())
    复制代码
    1. v7 = []
    复制代码
    1. v8 = 0
    复制代码
    1. if v5 >= 1:
    复制代码
    1. while v5 != v8:
    复制代码
    1. v7.append(v16[v8 % 32] ^ v3[v8])
    复制代码
    1. v8 += 1
    复制代码
    1. zsdata = base64.b64encode(''.join([chr(i) for i in v7]).encode()).decode()
    复制代码
    复制代码







    测试,通过







    更多文章请到公众号观看,公众号里的图也比较清晰






    [/ttreply]

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    分享到:
    回复

    使用道具 举报

    回答|共 56 个

    franky

    发表于 2020-11-16 13:42:20 | 显示全部楼层

    666
    回复

    使用道具 举报

    Helious

    发表于 2020-11-27 21:11:18 | 显示全部楼层

    学习学习
    回复

    使用道具 举报

    hongwang

    发表于 2020-12-5 13:54:08 | 显示全部楼层

    学习学习
    回复

    使用道具 举报

    化肥

    发表于 2020-12-15 20:07:16 | 显示全部楼层

    666
    回复

    使用道具 举报

    king1043

    发表于 2020-12-16 17:57:25 | 显示全部楼层

    66666666
    回复

    使用道具 举报

    Aimer

    发表于 2020-12-18 16:18:43 | 显示全部楼层

    66666666666
    回复

    使用道具 举报

    zhoubo

    发表于 2020-12-18 16:46:52 | 显示全部楼层

    1
    回复

    使用道具 举报

    进阶的小菜鸟

    发表于 2020-12-18 17:14:43 | 显示全部楼层

    学习学习
    回复

    使用道具 举报

    arbrad

    发表于 2020-12-21 22:30:33 | 显示全部楼层

    111111
    回复

    使用道具 举报