热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

抖音app协议逆向分析

准备工具抖音app(app下载连接)提取码:6666jadxgithub地址fiddlerfridagithub地址一台root好的android7.

准备工具


  • 抖音app(app下载连接) 提取码:6666
  • jadx github地址
  • fiddler
  • frida github地址
  • 一台root好的android7.0手机

如果你抓不到包请关注下一篇讲解各种抓包技巧
可以先关注我文章底部的公众号,后续将转移到微信公众号更新文章


本次主要演示抓取某个话题下的数据

没有图片的话是将图片过滤掉了,这样加载会更快
在这里插入图片描述


先抓包


话题首页

GET http://aweme.snssdk.com/aweme/v1/challenge/aweme/?ch_id=1603132116358228&query_type=0&cursor=0&count=20&type=5&retry_type=retry_http&iid=361063819794455&device_id=1126379551206542&ac=wifi&channel=yingyonghui&aid=2329&app_name=douyin_lite&version_code=180&version_name=1.8.0&device_platform=android&ssmix=a&device_type=Nexus+6P&device_brand=google&language=zh&os_api=25&os_version=7.1.1&openudid=df2eb2a465f9b18f&manifest_version_code=180&resolution=1440*2392&dpi=560&update_version_code=1800&_rticket=771495793&ts=1630245339&as=aac81339d8000bc5a7c813&cp=3a28c81339d8c8133a2032&mas=0133332319a3f3f3b323f9b9b93fef9cdaf3b323f9d3b993f97933 HTTP/1.1
Accept-Encoding: gzip
X-SS-QUERIES: dGMCA76ot3awALq29Cjed6Wxk9vvcxlI%2BcrVbsSshXPE367hsCodObDobByuYNDsyCWTS76ot3awAOm2rKzdv5e1E7B4tcJ4rILc5cqsABMctdUrsE%2BsYPhZcFX06I%2F6XKH1ew%3D%3D
X-SS-REQ-TICKET: 771495805
COOKIE: 你自己的COOKIE
X-Gorgon: 03742f2b00051aeec7dc6b6c24d8a111044edde107abede12ba7
X-Khronos: 771495
Host: aweme.snssdk.com
Connection: Keep-Alive
User-Agent: okhttp/3.10.0.1

翻页后的请求与响应

GET http://aweme.snssdk.com/aweme/v1/challenge/aweme/?ch_id=1603132116358228&query_type=0&cursor=20&count=20&type=5&retry_type=retry_http&iid=361063819794455&device_id=1126379551206542&ac=wifi&channel=yingyonghui&aid=2329&app_name=douyin_lite&version_code=180&version_name=1.8.0&device_platform=android&ssmix=a&device_type=Nexus+6P&device_brand=google&language=zh&os_api=25&os_version=7.1.1&openudid=df2eb2a465f9b18f&manifest_version_code=180&resolution=1440*2392&dpi=560&update_version_code=1800&_rticket=771550466&ts=1630245393&as=aac81339d8000bc5dec813&cp=3a28c81339d8c8133a2032&mas=0133332319a3f3f3b323f9b9b93fef9c44f3b323f9991993f97933 HTTP/1.1
Accept-Encoding: gzip
X-SS-QUERIES: dGMCA76ot3awALq29Cjed6Wxk9vvcxlI%2BcrVbsSshXPE367hsCodObDobByuYNDsyCWTS76ot3awAOm2rKzdv5e1E7B4tcJ4rILc5cqsABMctdUrsE%2BsYPhZcFX06I%2F6XKH1ew%3D%3D
X-SS-REQ-TICKET: 771550474
COOKIE:你自己的COOKIE
X-Gorgon: 03742f2b000547608bad6b6c24d8a111044edde107abede1b5f4
X-Khronos: 771550
Host: aweme.snssdk.com
Connection: Keep-Alive
User-Agent: okhttp/3.10.0.1

跑一段时间你会发现出不了数据
逐步替换url请求参数会发现是as cp mas这三个参数失效了,得逆向分析一波


逆向分析步骤


查壳

查壳的方式很多种,可以先用apktool解开查看特侦,如果应用被加固了,那么需要脱壳
脱壳的教程很多,可以优先考虑FDex2
在这里插入图片描述


jadx使用搜索大法搜索as cp mas三个参数

搜索需要讲究技巧,先搜索as和cp会直接死亡
在这里插入图片描述
在搜索时按照java的尿性会有以下几种形式(仅供参考)先找长字符的搜索

"mas
"mas=
"mas"
="mas"

果然给蒙对了
在这里插入图片描述
双击进入发现就是我们想要的
在这里插入图片描述
上图的代码如下

package com.ss.android.ugc.aweme.app.a;import android.text.TextUtils;
import com.meituan.robust.ChangeQuickRedirect;
import com.meituan.robust.PatchProxy;
import com.meituan.robust.PatchProxyResult;
import com.meizu.cloud.pushsdk.notification.model.AdvanceSetting;
import com.ss.android.common.applog.EagleEye;
import com.ss.android.common.applog.GlobalContext;
import com.ss.android.common.applog.UserInfo;
import com.ss.android.deviceregister.a;
import com.ss.android.ugc.aweme.app.AwemeApplication;
import com.ss.android.ugc.aweme.app.b.e;
import com.ss.sys.ces.out.ISdk;
import com.ss.sys.ces.out.StcSDKFactory;
import e.t;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;/* compiled from: ApiAntiSpamUtils */
public final class b {/* renamed from: a reason: collision with root package name */public static ChangeQuickRedirect f13081a;public static t a(t tVar, List list, int i) {String str;PatchProxyResult proxy = PatchProxy.proxy(new Object[]{tVar, list, new Integer(i)}, null, f13081a, true, 866, new Class[]{t.class, List.class, Integer.TYPE}, t.class);if (proxy.isSupported) {return (t) proxy.result;}String decode = URLDecoder.decode(tVar.toString());String b2 = a.b();if (b2 == null) {b2 = "";}if (decode.contains("&device_id=") || decode.contains("?device_id=")) {str = UserInfo.getUserInfo(i, decode, (String[]) list.toArray(new String[list.size()]), b2);} else {str = UserInfo.getUserInfo(i, decode, (String[]) list.toArray(new String[list.size()]), "");}t.a k = tVar.k();int length = str.length();if (TextUtils.isEmpty(str)) {k.a(AdvanceSetting.ADVANCE_SETTING, "a1iosdfgh").a("cp", "androide1");} else if (length % 2 == 0) {int i2 = length >> 1;String substring = str.substring(0, i2);ISdk sdk = StcSDKFactory.getSDK(GlobalContext.getContext(), (long) AwemeApplication.p().m());sdk.setSession(e.a());k.a(AdvanceSetting.ADVANCE_SETTING, substring).a("cp", str.substring(i2, length)).a("mas", EagleEye.byteArrayToHexStr(sdk.encode(substring.getBytes())));} else {k.a(AdvanceSetting.ADVANCE_SETTING, "a1qwert123").a("cp", "cbfhckdckkde1");}return k.b();}public static List a(String str) {int i = 0;PatchProxyResult proxy = PatchProxy.proxy(new Object[]{str}, null, f13081a, true, 867, new Class[]{String.class}, List.class);if (proxy.isSupported) {return (List) proxy.result;}ArrayList arrayList = new ArrayList();while (i <= str.length()) {int indexOf = str.indexOf(38, i);if (indexOf == -1) {indexOf = str.length();}int indexOf2 = str.indexOf(61, i);if (indexOf2 == -1 || indexOf2 > indexOf) {arrayList.add(URLDecoder.decode(str.substring(i, indexOf)));arrayList.add(null);} else {arrayList.add(URLDecoder.decode(str.substring(i, indexOf2)));arrayList.add(URLDecoder.decode(str.substring(indexOf2 + 1, indexOf)));}i = indexOf + 1;}return arrayList;}public static String b(String str) {PatchProxyResult proxy = PatchProxy.proxy(new Object[]{str}, null, f13081a, true, 868, new Class[]{String.class}, String.class);if (proxy.isSupported) {return (String) proxy.result;}if (TextUtils.isEmpty(str)) {return str;}try {return URLDecoder.decode(str, "UTF-8");} catch (UnsupportedEncodingException e2) {com.google.b.a.a.a.a.a.a(e2);return URLDecoder.decode(str);}}
}

这里有一个AdvanceSetting.ADVANCE_SETTING
我们查找一下声明
在这里插入图片描述

这一节我们只做fridaRpc调用下一节我们直接用python还原这三个参数

在这里插入图片描述
现在我们已经很清楚需要hook UserInfo.getUserInfo()这个方法

import os
import sysimport fridadef on_message(message, data):if message[&#39;type&#39;] == &#39;send&#39;:print("[*] {0}".format(message[&#39;payload&#39;]))else:print(message)js_code = """
Java.perform(function(){var UserInfo = Java.use(&#39;com.ss.android.common.applog.UserInfo&#39;);UserInfo.getUserInfo.overload(&#39;int&#39;, &#39;java.lang.String&#39;, &#39;[Ljava.lang.String;&#39;, &#39;java.lang.String&#39;).implementation=function(a,b,c,d){send(&#39;a:&#39;+a);send(&#39;b:&#39;+b);send(&#39;c:&#39;+c);send(&#39;d:&#39;+d);user=this.UserInfo(a,b,c,d);return user;}
});
"""process = frida.get_remote_device().attach(&#39;com.ss.android.ugc.aweme.lite&#39;)
script = process.create_script(js_code)
script.on(&#39;message&#39;, on_message)
script.load()
sys.stdin.read()

getUserInfo的各个参数如下
在这里插入图片描述
第一个是时间戳
第二个是你传入的请求url
第三个是请求的参数构成的字符串
第四个是一堆数字其实就是deviceId,从下面这个if else可以得知
在这里插入图片描述

frida.rpc hook模板如下

hook_code = &#39;&#39;&#39;
rpc.exports = {getSign: function(str){send(&#39;getSign&#39;);Java.perform(function(){})}
};
&#39;&#39;&#39;

于是结合djax代码可的代码如下

def on_message(message, data):if message[&#39;type&#39;] == &#39;send&#39;:print("[*] {0}".format(message[&#39;payload&#39;]))else:print(message)js_code = """
rpc.exports = {getsign: function (timestamps, base_url, params, device_id) {var sig = "aa";Java.perform(function () {send(&#39;getsign&#39;);var StcSDKFactory = Java.use(&#39;com.ss.sys.ces.out.StcSDKFactory&#39;);var GlobalCOntext= Java.use(&#39;com.ss.android.common.applog.GlobalContext&#39;);var AwemeApplication = Java.use(&#39;com.ss.android.ugc.aweme.app.AwemeApplication&#39;);var EagleEye = Java.use(&#39;com.ss.android.common.applog.EagleEye&#39;);var sdk = StcSDKFactory.getSDK(GlobalContext.getContext(), AwemeApplication.p().m());var UserInfo = Java.use(&#39;com.ss.android.common.applog.UserInfo&#39;);var aac=params.toArray(params.length);var user_info = UserInfo.getUserInfo(timestamps,base_url,params,device_id);var as = user_info.substring(0, 22);var cp = user_info.substring(22, user_info.length);var mas = EagleEye.byteArrayToHexStr(sdk.encode(getBytes(as)));sig = &#39;&as=&#39;+as+&#39;&cp=&#39;+cp+&#39;&mas=&#39;+mas;})return sig;}
}function getBytes(s) {var bytes = [];for (var i = 0; i }"""process = frida.get_remote_device().attach(&#39;com.ss.android.ugc.aweme.lite&#39;)
script = process.create_script(js_code)
script.on(&#39;message&#39;, on_message)
script.load()a= int(time.time())b="https://aweme-eagle.snssdk.com/aweme/v1/feed/?type=0&max_cursor=0&min_cursor=0&count=6&volume=0.0&pull_type=1&need_relieve_aweme=0&filter_warn=0&ts=1630343714&app_type=lite&os_api=25&device_platform=android&device_type=Xiaomi&iid=361063819794455&ssmix=a&manifest_version_code=180&dpi=560&version_code=180&app_name=douyin_lite&version_name=1.8.0&openudid=df2eb2a465f9b18f&device_id=1126379551206542&resolution=1440*2392&os_version=7.1.1&language=zh&device_brand=google&ac=wifi&update_version_code=1800&aid=2329&channel=yingyonghui&_rticket=1630343715767"c="type,0,max_cursor,0,min_cursor,0,count,6,volume,0.0,pull_type,1,need_relieve_aweme,0,filter_warn,0,ts,1630343714,app_type,lite,os_api,25,device_platform,android,device_type,Xiaomi,iid,361063819794455,ssmix,a,manifest_version_code,180,dpi,560,version_code,180,app_name,douyin_lite,version_name,1.8.0,openudid,df2eb2a465f9b18f,device_id,1126379551206542,resolution,1440*2392,os_version,7.1.1,language,zh,device_brand,google,ac,wifi,update_version_code,1800,aid,2329,channel,yingyonghui,_rticket,1630343715767"d="1126379551206542"
sig = script.exports.getsign(a, b, c, d)
print(sig)

最终的结果如下图所示,每一次的调用都是生成不同的参数
在这里插入图片描述

​欢迎关注"python网络爬虫大数据与逆向工程"公众号,一起学习更多关于网络爬虫和逆向工程方面的知识
在这里插入图片描述


推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • intellij idea的安装与使用(保姆级教程)
    intellijidea的安装与使用(保姆级教程)IntelliJ在业界被公认为最好的java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(gi ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
  • 基于移动平台的会展导游系统APP设计与实现的技术介绍与需求分析
    本文介绍了基于移动平台的会展导游系统APP的设计与实现过程。首先,对会展经济和移动互联网的概念进行了简要介绍,并阐述了将会展引入移动互联网的意义。接着,对基础技术进行了介绍,包括百度云开发环境、安卓系统和近场通讯技术。然后,进行了用户需求分析和系统需求分析,并提出了系统界面运行流畅和第三方授权等需求。最后,对系统的概要设计进行了详细阐述,包括系统前端设计和交互与原型设计。本文对基于移动平台的会展导游系统APP的设计与实现提供了技术支持和需求分析。 ... [详细]
  • charles3.11.1抓https包
    结论先行:用的是安卓测试机,没加固之前的生产环境的安装包,可以抓到https请求加固之后的包【也就是要上应用市场的包】,抓不到https请求电脑上的操作:1.安装证书【电脑上安装了 ... [详细]
  • 2021年最详细的Android屏幕适配方案汇总
    1Android屏幕适配的度量单位和相关概念建议在阅读本文章之前,可以先阅读快乐李同学写的文章《Android屏幕适配的度量单位和相关概念》,这篇文章 ... [详细]
  • 1、不要使用国内第三方加固2、去掉android:debuggable”true”,不然会报一下错误,特别注意使用了一些第三方SDK,例如ShareSDKUploadfailedY ... [详细]
  • 家里没有台式机,在手机上怎么设置密码?
      1、先将网线(猫出来的网线)插在路由器的WAN口,开启无线路由器的电源在手机上设置路由器。2、手机打开无线搜索路由器,连接无线路由器(新路由器 ... [详细]
  • 如题如示,在网上查了下c#直接操作ppt的例子,但都只是很简单的写了下打开PPT插入标题插入一个图表等,但是都没有更具体的有如何可以直接更改PPT图表的数据源数据的例子。我现在的需求是,我有一个P ... [详细]
  • Imdevelopinganappwhichneedstogetmusicfilebystreamingforplayinglive.我正在开发一个应用程序,需要通过流 ... [详细]
  • 这两天用到了ListView,写下遇到的一些问题。首先是ListView本身与子控件的焦点问题,比如我这里子控件用到了Button,在需要ListView中的根布局属性上加上下面的这一个属性:and ... [详细]
author-avatar
强压谷攻
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有