O**O 游戏中心 APP 排行榜数据安卓逆向参数分析 sign、sg、oak

O**O 游戏中心 APP 排行榜数据安卓逆向参数分析 sign、sg、oak

声明:本文只作学习研究,禁止用于非法用途,否则后果自负,敏感信息已做了加密隐藏,如有侵权,请告知删除,谢谢!

前言

目标是采集游戏排行榜中的游戏排行榜数据,需要准备一台安卓 root 后的后手机,配置完证书,准备好逆向工具。

抓包界面截图:
请添加图片描述

抓包内容截图:
请添加图片描述

目标请求:

import requests
url='https://api-cn.game.***.com/card/game/v1/rank/new?size=10&start=0'
headers={
    "refresh_times": "0",
    "CDO-GSLB": "1",
    "rt": "0",
    "page-id": "454",
    "romver": "-1",
    "User-Agent": "Xiaomi%2F2201123C%2F31%2F12%2FUNKNOWN%2F1000%2F2201%2F130701",
    "sign": "d607ed64c231bf6a8ac18a9e0c2c9a30",
    "nw": "1",
    "pid": "1000",
    "enter-id": "1",
    "snippetVersion": "5",
    "locale": "zh-CN;CN",
    "sg": "0902eb1bb12c1dbf7605bc083141da8f",
    "cpuAbilist": "arm64-v8a,armeabi-v7a,armeabi",
    "oak": "6486ed42c86ecc09",
    "id":"2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7",
    "rcm": "1",
    "ocp":"stat#1_ABTEST#14_usage#3_ai#0_main#24_community#1_preload#1_network#0_desktopspace#3_search#2_download#1_h5preload#1_homepage#1",
    "ocs": "Xiaomi%2F2201123C%2F31%2F12%2FUNKNOWN%2F1000%2FSKQ1.211006.001+test-keys%2F130701",
    "Accept": "application/x2-protostuff; charset=UTF-8",
    "ch": "2201",
    "appversion": "13.7.1",
    "token": "-1",
    "pkg-ver": "-1",
    "t": "1717377995077",
    "t-request-id": "e1f888a20d7e9fd***7fed87face3f",
    "appid": "Xiaomi#1000#CN",
    "pull_refresh": "0",
    "compressTool": "zstd-1.5.2-2",
    "child": "NULL",
    "Host": "api-cn.game.xxxxx.com",
    "Connection": "Keep-Alive",
    "Accept-Encoding": "gzip"
}

res=requests.get(url,headers=headers)
print(res.text)

经过分析对 headers 中部分重要参数进行对应说明

参数
参数说明抓包获取的值
sign签名1d607ed64c231bf6a8ac18a9e0c2c9a30
sg签名2
0902eb1bb12c1dbf7605bc083141da8f
oak签名密钥key6486ed42c86ecc09

也就是说我们搞清楚 sign、sg、oak 的生成规则就能完成请求模拟

正文

下面我们开始对 apk,进行逆向用到那些工具也会介绍

jadx-gui: jadx-gui 是一种基于 jadx 项目的图形界面工具,用于反编译Android 应用程序的工具。通过使用jadx-gui,开发人员可以打开 APK(Android应用程序包)文件,并查看其反编译的源代码。
用 jadx-gui 打开 apk 查看加密生成位置

请添加图片描述

点击搜索,搜索关键字"sign" 找到相关代码 进行分析查看

请添加图片描述

搜索到相关代码,方法 addSign 并发现这里对 headers 进行了添加,可以看出 m20754c 就是 sign 是通过 OcsTool.m20754c 方法生成的。我们右击该方法跳到声明处看下。
请添加图片描述

函数跳转到 native 层,so 文件名称:libocstool.so

so文件是unix(一个系统的名字)的动态连接库,是二进制文件,作用相当于windows下的.dll文件
有兴趣的可以去了解下 so 文件的加载过程,本文不再赘述。

找到 libocstool.so 文件,使用 ida 打开,找到签名生成函数,可以先用 jadx 导出资源文件
请添加图片描述

IDA Pro是目前很棒的静态反编译软件,是反编译者不可缺少的利器.巨酷的反编译软件,它可以更好的反汇编和更有深层分析.可以快速到达指定代码位置.
这里主义 IDA 有 32 位和 64 位之分,对应能打开的文件也不一样,加载时会提示
请添加图片描述

这时候更好 64 位进行打开

在这里俺 ctrl+f 进行搜索 定位到 so 中的映射方法,点击_c 看下逻辑
请添加图片描述

点击后按 f5 切换视图
请添加图片描述

下面就是考验 C 语言基础的时候了
可以很明显看出 MD5 关键字,我们也可以在 sign 的格式中大概猜出是 md5
还记得 m20754c 传入了什么吗

String m20754c = OcsTool.m20754c(append.toString(), append.length());
一个字符串 和 字符串的长度
可以看出

v20 = _JNIEnv::GetMethodID(v26, v21, “update”, “([B)V”);
v19 = _JNIEnv::GetMethodID(v26, v21, “digest”, “()[B”);
v5 = _JNIEnv::NewStringUTF(v26, “MD5”);
v18 = _JNIEnv::CallStaticObjectMethod(v26, v21, v4, v5);
是 v4 代码 md5 这里可以看出是吧 md5 的加密方法赋值给了 v18,update 应该是用来添加加密参数的的也就是 v20

所以 _JNIEnv::CallVoidMethod(v26, v18, v20, v6); 例这种就是吧 v6 添加到 md5 的加密参数中那么 v6 是什么呢 v6 = _JNIEnv::NewByteArray(v26, 48); 是开辟了一个 48 位的内存地址创建指定长度的 byte 数组。然后把 k2 放了进去 可 k2 是什么呢
右击 k2 jump
请添加图片描述

有个 init_keys 和 init_keys2 函数,我们先看下 init_keys2
请添加图片描述

看得出 k k2 是由 v6=a1 生成的 a1 是传参 那我们右击 init_keys2 跳到 jump 转到调用处看看

请添加图片描述

往上跳上层后跳到了 init_keys
在这里插入图片描述

可以看出传入的参数是 v4 和 v3 而 这俩参数是判断应用包名得到的
那么我们的参数就是

v4 = “6486ed42c86ecc09”;
v3 = “a83c3e95c524ac6a3af81e3e12314dd295”;
接着我们回到 init_keys2 看下 k 和 k2 如何生成的

__int64 __fastcall init_keys2(char *a1, char *a2)
{
  __int64 result; // x0
  int j; // [xsp-2Ch] [xbp-2Ch]
  signed int i; // [xsp-24h] [xbp-24h]
  char *v5; // [xsp-20h] [xbp-20h]
  char *v6; // [xsp-18h] [xbp-18h]
  v6 = a1;
  v5 = a2;
  k = malloc(17LL);
  result = malloc(49LL);
  k2 = result;
  for ( i = 0; i < 16; ++i )
  {
    *(_BYTE *)(k + i) = v6[i];
    *(_BYTE *)(k2 + i) = *(_BYTE *)(k + i);
  }
  *(_BYTE *)(k + 16) = 0;
  for ( j = 0; j < 16; ++j )
  {
    *(_BYTE *)(k2 + j + 16) = v5[j + 18];
    *(_BYTE *)(k2 + j + 32) = v5[j + 2];
  }
  *(_BYTE *)(k2 + 48) = 0;
  return result;
}

python 模拟还原一下分析一下看出 k 就是 v6
而 k2 就是 v5 v6 拼接的

key2='6486ed42c86ecc09'
key2=key2+'0'*(48-len(key2))
print(key2)
v="a83c3e95c524ac6a3af81e3e12314dd295"
key2=list(key2)
v=list(v)
for j in range(16):
    # print(key2[16+j],v[j + 18])
    key2[16+j]=v[j + 18]
    key2[32+j]=v[j + 2]
print(''.join(key2))
# 6486ed42c86ecc0900000000000000000000000000000000
# 6486ed42c86ecc09f81e3e12314dd2953c3e95c524ac6a3a

好得到了 k2 我们回到 md5 加密的_c 中

目前知道 md5(k2)

请添加图片描述

这里添加了第二个参数是我们传过来的第一个字符串参数我们这里 a3
目前知道 md5(k2+a3)
请添加图片描述

这里看出 v24+48 而 v24 指向我们传过来的参数 a4 也就是 len(a3)
目前知道 md5(k2+a3+(len(a3)+48))
请添加图片描述

最后加载了一字符串常量
OBSCURE_CODE
在这里插入图片描述

双击跟进去能找到

那我们现在总结一下

sign=md5(k2+a3+(len(a3)+48)+OBSCURE_CODE)

oka=6486ed42c86ecc09=k

还差一个 sg

我们回到jadx看下sg 是传入到那个方法

请添加图片描述

请添加图片描述

可以看到sg 调用了m20750a这个方法进行了加密并且传入了一下参数和sign

/* renamed from: a */
    public static String m20750a(Request request, String str, String str2, String str3) {
        return m20755d((str + request.getRequestHeader().get("Accept") + m20749a(request.getMethod()) + 
str2).toLowerCase(), str3);
    }
    /* renamed from: d */
    public static native String m20755d(String str, String str2);
  /* renamed from: a */
    private static String m20749a(int i) {
        return i != 1 ? i != 2 ? i != 4 ? "get" : TtmlNode.TAG_HEAD : "put" : "post";
    }

可以看出是调用了m20755d这个方法并且传入了 几个参数 这个对应着_d我们回到ida看下

请添加图片描述

可以看出这里调用了md5对a3+k+a4+len(a3+k+a4) 进行了加密

后面又对这个加密结果的byte字节数据数组%10 然后再相加 最后去这个结果的个位=v24

请添加图片描述

然后用v24%5 取对应两个字符串数组的对应元素

请添加图片描述

在这里插入图片描述

并且判断v24的结果采用那种加密方式,一种是md5 另一种是v37对应的SHA1 加密参数是

a3+v21+v20+len(a3+v21+v20)

请添加图片描述

到这里我们总结一下sg获取的过程是竖线对传入的参数进行Md5加密后 然后获取加密结果的校验位 通过校验位获取校验数组中的字符串 再根据校验位现在不同的加密方法 既md5 sha1


到目前为止我们已经获取获取到了 需要的三个参数的加密方法和过程,下面我们要寻找加密这三个参数 传入了那些值,由于oak是固定值 我们这里只需要关心sign sg

请添加图片描述

这里我们去hook addSign

jadx 显示的包名是package okhttp3.internal.tls; 类名是ady 方法名是addSign 直接去hook定位不到

点击这里能发现混淆后的包名a.a.a.ady 这样就能定位到了

请添加图片描述

hook的方法众多frida xposed 等 这里不过多介绍

时间:2024-0
6-05 11:36:54

类名:a.a.a.ady

日志名称:已拦截-addSign(Request,String,long,String)

参数1
参数类型:com.nearme.network.proto.a
参数值:com.nearme.network.proto.a@23c2cfa

参数2
参数类型:java.lang.String
参数值:Xiaomi%2F2201123C%2F31%2F12%2FUNKNOWN%2F1000%2FSKQ1.211006.001+test-keys%2F130701

参数3
参数类型:java.lang.Long
参数值:1717558614167

参数4
参数类型:java.lang.String
参数值:2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7



返回结果类型:void
返回结果值:null

我们回顾下sign=md5(k2+a3+(len(a3)+48)+OBSCURE_CODE)

k2 OBSCURE_CODE 都是固定值 只要看a3就行

k2=6486ed42c86ecc09f81e3e12314dd2953c3e95c524ac6a3a

OBSCURE_CODE=STORENEWMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANYFY/UJGSzhIhpx6YM5KJ9yRHc7YeURxzb9tDvJvMfENHlnP3DtVkOIjERbpsSd76fjtZnMWY60TpGLGyrNkvhHAo9yURpPQoI0eg3SLFmTEI/MUiPRCwfwYf2deqKKlsmMSysYYHX9JiGzQuWiYZaawxprSuiqDGvAYEAtQ0QV00gGABISljNMy5aeDBBTSBWG2OjxJhxLRbndZM81OsMFysgC7dq+bUS6ke1YrDWgsoFhRxxTtx/2gDYciGp/c/h0Td5pGw7T9W6zo2xWI5oh1WyTnn0Xj17O9CmOk4fFDpJ6bapL+fyDy7gkEUChJ9+p66WSAlsfUhJ2TECQQD5sFWMGE2IiEuz4fIPaDrNST***/ZpZ7VzB2tcG7GyZRx5YORbZmX1jR7l3H4F98MgqCGs88w6FKnCpxDK3AkEA225CphAcfyiH0ShlZxEXBgIYt3V8nQuc/g2KJtiV6eeFkxmOMHbVTPGkARvt5VoPYEjwPTg43oqTDJVtlWagyQJBLno9aHNExvznyD4/pR4hec6qqLNgMyIYMfHCl6d3UodVvC1HO1/nMPl+4GvuRnxuoBtxj/PTe7AlUbYPMCQQDOkf4sVv58tqslO+I6JNyHy3F5RCELtuMUR6rG5x46FLqqwGQbO8ORq+m5IZHTV/Uhr4h6GXNwDpVW0gBAkAp/v3tPI1riz6UuG0I6uf5er26yl5evPyPrjrD299L4Qy/1EIunayC7JYcSGlR01+EDYYgwUkec+QgrRC/NstV

a3 是传入的append 既new StringBuilder(str).append(j).append(str2).append(str4).append(str3);

str=Xiaomi%2F2201123C%2F31%2F12%2FUNKNOWN%2F1000%2FSKQ1.211006.001+test-keys%2F130701

j=时间戳=1717558614167

str2=2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7

str4=/card/game/v1/rank/new

str3=size=10&start=0

len(a3)+48=281

python 模拟获取下

from spiderx import sx
def get_Sign(url):
    k2='6486ed42c86ecc09f81e3e12314dd2953c3e95c524ac6a3a'
    OBSCURE_CODE='STORENEWMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANYFY/UJGSzhIhpx6YM5KJ9yRHc7YeURxzb9tDvJvMfENHlnP3DtVkOIjERbpsSd76fjtZnMWY60TpGLGyrNkvuV40L15JQhHAo9yURpP***3SLFmTEI/MUiPRCwfwYf2deqKKlsmMSysYYHX9JiGzQuWiYZaawxprSuiqDGvAgMBAAECgYEAtQ0QV00gGABISljNMy5aeDBBTSBWG2OjxJhxLRbndZM81OsMFysgC7dq+bUS6ke1YrDWgsoFhRxxTtx/2gDYciGp/c/h0Td5pGw7T9W6zo2xWI5oh1WyTnn0Xj17O9CmOk4fFDpJ6ba***gkEUChJ9+p66WSAlsfUhJ2TECQQD5sFWMGE2IiEuz4fIPaDrNSTHeFQQr/ZpZ7VzB2tcG7GyZRx5YORbZmX1jR7l3H4F98MgqCGs88w6FKnCpxDK3AkEA225CphAcfyiH0ShlZxE***8nQuc/g2KJtiV6eeFkxmOMHbVTPGkARvt5VoPYEjwPTg43oqTDJVtlWagyQJBAOvEeJLno9aHNExvznyD4/pR4hec6qqLNgMyIYMfHCl6d3UodVvC1HO1/nMPl+4GvuRnxuoBtxj/PTe7AlUbYPMCQQDOkf4sVv58tqslO+I6JNyHy3F5RCELtuMUR6rG5x46FLqqwGQbO8ORq+m5IZHTV/Uhr4h6GXNwDQRh1EpVW0gBAkAp/v3tPI1riz6UuG0I6***l5evPyPrjrD299L4Qy/1EIunayC7JYcSGlR01+EDYYgwUkec+QgrRC/NstV'
    str1='Xiaomi%2F2201123C%2F31%2F12%2FUNKNOWN%2F1000%2FSKQ1.211006.001+test-keys%2F130701' 
    j=sx.获取_URL_QUERY(url).split('&ts=')[-1]
    str2='2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7'
    str4=sx.获取_PATH(url)
    str3=sx.获取_URL_QUERY(url).split('&ts=')[0]
    a3=str1+j+str2+str4+str3
    print(k2+a3+str(len(a3)+48)+OBSCURE_CODE)
    return sx.加密_MD5(k2+a3+str(len(a3)+48)+OBSCURE_CODE)

url = "https://api-cn.game.***.com/card/game/v1/rank/new?size=10&start=0&ts=1717572906855"
print(get_Sign(url))
#e01d294a4e2a243b1024e14ad104241b

sg 先看传入了那几个参数

请添加图片描述

str5=url编码(str4+str3)

accept=‘application/x2-protostuff; charset=UTF-8’

getMethod=‘get’

str2=‘2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7’

j=时间戳=1717558614167

a3=str5+accept+getMethod+str2+j 后转小写

a4=Sign

k=‘6486ed42c86ecc09’

MD5(a3+k+a4+str(len(a3+k+a4)))

后面根据这个结果获取校验位

然后在获取校验数组中的字符串

然后再根据校验位选择加密算发

python 模拟

# 传入了两个参数一个是sign
def get_sg(url):
    k='6486ed42c86ecc09'
    str4=sx.获取_PATH(url)
    str3=sx.获取_URL_QUERY(url).split('&ts=')[0]
    j=sx.获取_URL_QUERY(url).split('&ts=')[-1]
    str2='2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7'
   
    str5=sx.url编码(str4+str3).replace('/','%2f')
    # sx.urlencode
    accept='application/x2-protostuff; charset=UTF-8'
    getMethod='get'
    a3=(str5+accept+getMethod+str2+j).lower()
    a4=get_Sign(url)
    # print(a3)
    # 先对传入的a3,a4 md5加密获取校验位
    m5=sx.加密_MD5(a3+k+a4+str(len(a3+k+a4)))
    print(m5)
    # sx.by
    v23=0
    # 将字符串编码为字节对象

    for i in bytearray(m5.encode("utf-8")):
        print(i)
        v23=v23+(abs(i)%10)
    v24=v23%10
    print(v23,v24)
    sgk=[ "cab2f5d9***4eea71",
         "3e8d4f1c***a6e09", 
         "c5ca81b***91663db",
         "517e950***d031cb",
         "f87***121dba1cf23"][::-1]
    sgsk=[ "d9275c219e852***b5e60cb5ceccd523b5",
          "6bf7d491e5ab***931f91eb4c9a1640", 
          "0ca3e6b70c***c4cf53ead33d158e83",
          "464c604***069a3e585d8bfe3b90",
          "f1184b1998***d10aa5b8dd039ef8f"]  [::-1]
    v21=sgk[v24%5]
    v20=sgsk[v24%5]
    print(a3+v21+v20+str(len(a3+v21+v20)))
    # print(v24)
    if v24 >=5:
        return sx.加密_SHA1(   a3+v21+v20+str(len(a3+v21+v20)))
 
    else:
        return sx.加密_MD5(   a3+v21+v20+str(len(a3+v21+v20)))

完整调用代码

import gzip
import time
import requests

url = "https://api-cn.game.***.com/card/game/v1/rank/new?size=10&start=0"


from spiderx import sx
def get_Sign(url):
    k2='6486ed42c86ecc09f81e3e12314dd2953c3e95c524ac6a3a'
    OBSCURE_CODE='STORENEWMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANYFY/UJGSzhIhpx6YM5KJ9yRHc7YeURxzb9tDvJvMfENHlnP3DtVkOIjERbpsSd76fjtZnMWY60***rNkvuV40L15JQhHAo9yURpPQoI0eg3SLFmTEI/MUiPRCwfwYf2deqKKlsmMSysYYHX9JiGzQuWiYZaawxprSuiqDGvAgMBAAECgYEAtQ0QV00gGABISljNMy5aeDBBTSBWG2OjxJhxLRbndZM***ysgC7dq+bUS6ke1YrDWgsoFhRxxTtx/2gDYciGp/c/h0Td5pGw7T9W6zo2xWI5oh1WyTnn0Xj17O9CmOk4fFDpJ6bapL***EA225CphAcfyiH0ShlZxEXBgIYt3V8nQuc***V6eeFkxmOMHbVTPGkARvt5VoPYEjwPTg43oqTDJVtlWagyQJBAOvEeJLno9aHNExvznyD4/pR4hec6qqLNgMyIYMfHCl6d3UodVvC1HO1/nMPl+4GvuRnxuoBtxj/PTe7AlUbYPMCQQDOkf4sVv58tqslO+I6JNyHy3F5RCELtuMUR6rG5x46FLqqwGQbO8ORq+m5IZHTV/U***h6GXNwDQRh1EpVW0gBAkAp/v3tPI1riz6UuG0I6uf5er26yl5evPyPrjrD299L4Qy/1EIunayC7JYcSGlR01+EDYYgwUkec+QgrRC/NstV'
    str1='Xiaomi%2F2201123C%2F31%2F12%2FUNKNOWN%2F1000%2FSKQ1.211006.001+test-keys%2F130701' 
    j=sx.获取_URL_QUERY(url).split('&ts=')[-1]
    str2='2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7'
    str4=sx.获取_PATH(url)
    str3=sx.获取_URL_QUERY(url).split('&ts=')[0]
    a3=str1+j+str2+str4+str3
    # print(k2+a3+str(len(a3)+48)+OBSCURE_CODE)
    return sx.加密_MD5(k2+a3+str(len(a3)+48)+OBSCURE_CODE)



# 传入了两个参数一个是sign
def get_sg(url):
    k='6486ed42c86ecc09'
    str4=sx.获取_PATH(url)
    str3=sx.获取_URL_QUERY(url).split('&ts=')[0]
    j=sx.获取_URL_QUERY(url).split('&ts=')[-1]
    str2='2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7'
   
    str5=sx.url编码(str4+str3).replace('/','%2f')
    # sx.urlencode
    accept='application/x2-protostuff; charset=UTF-8'
    getMethod='get'
    a3=(str5+accept+getMethod+str2+j).lower()
    a4=get_Sign(url)
    # print(a3)
    # 先对传入的a3,a4 md5加密获取校验位
    m5=sx.加密_MD5(a3+k+a4+str(len(a3+k+a4)))
    print(m5)
    # sx.by
    v23=0
    # 将字符串编码为字节对象

    for i in bytearray(m5.encode("utf-8")):
        # print(i)
        v23=v23+(abs(i)%10)
    v24=v23%10
    # print(v23,v24)
    sgk=[ "cab2f***d94d4eea71",
         "3e8d4f1c***aa6e09", 
         "c5ca81b03***663db",
         "517e95007dd031cb",
         "f8730121dba1cf23"][::-1]
    sgsk=[ "d9275c219***52eb5e60cb5ceccd523b5",
          "6bf7d491e5ab9da2931***eb4c9a1640", 
          "0ca3e6b70***0fc4cf53ead33d158e83",
          "464c6045b59a3***69a3e585d8bfe3b90",
          "f1184b1998cc***d10aa5b8dd039ef8f"] [::-1]
    v21=sgk[v24%5]
    v20=sgsk[v24%5]
    # print(a3+v21+v20+str(len(a3+v21+v20)))
    # print(v24)
    if v24 >=5:
        return sx.加密_SHA1(   a3+v21+v20+str(len(a3+v21+v20)))
 
    else:
        return sx.加密_MD5(   a3+v21+v20+str(len(a3+v21+v20)))
  
t=str(int(time.time()*1000))
# print(t)
# t='1717579661756'
#    1717581525911
headers={
  
    "sign": get_Sign(url+'&ts='+t),
    "sg":get_sg(url+'&ts='+t),
        "refresh_times": "0",
    "CDO-GSLB": "1",
    "rt": "0",
    "page-id": "454",
    "romver": "-1",
    "User-Agent": "Xiaomi%2F2201123C%2F31%2F12%2FUNKNOWN%2F1000%2F2201%2F130701",
    "nw": "1",
    "pid": "1000",
    "enter-id": "1",
    "snippetVersion": "5",
    "locale": "zh-CN;CN",
    "cpuAbilist": "arm64-v8a,armeabi-v7a,armeabi",
    "oak": "6486ed42c86ecc09",
    "id": "2112#ea832cefcd7173c8a3fe8cd5b7b275cf#82374ccde246ea12a880ed874be5335f04189155b692e08ff418e6ca5e4f28f7",
    "rcm": "1",
    "ocp": "stat#1_ABTEST#14_usage#3_ai#0_main#24_community#1_preload#1_network#0_desktopspace#3_search#2_download#1_h5preload#1_homepage#1",
    "ocs": "Xiaomi%2F2201123C%2F31%2F12%2FUNKNOWN%2F1000%2FSKQ1.211006.001+test-keys%2F130701",
    "Accept": "application/x2-protostuff; charset=UTF-8",
    "ch": "2201",
    "appversion": "13.7.1",
    "token": "-1",
    "pkg-ver": "-1",
    "t":t,
    "t-request-id": "23cd4ab76e7b090***f957b0940636",
    "appid": "Xiaomi#1000#CN",
    "pull_refresh": "0",
    "compressTool": "zstd-1.5.2-2",
    "child": "NULL",
    "Host": "api-cn.game.XXXX.com",
    "Connection": "Keep-Alive",
    "Accept-Encoding": "gzip"
  
}
# print(headers)
response = requests.get(url, headers=headers)
response.encoding='utf-8_sig'
# print([response.text])
import re


games=re.findall('RankResourceDto.*?\x1a.(.*?)\x08\(\x000\x00:',response.text)
for game in games:
    print('--------')
    print(game)

请添加图片描述


结束~~~ ablbld~~~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值