Azure99 / GenshinPlayerQuery

根据原神uid查询玩家信息(基础数据、角色&装备、深境螺旋战绩等)
Apache License 2.0
371 stars 41 forks source link

现在一组DS似乎只能查询相对应UID #20

Closed HalcyonSuoh closed 2 years ago

HalcyonSuoh commented 2 years ago

从其他接口获取的DS, x-rpc-client_type, x-rpc-app_version用来请求玩家信息会返回invalid request, 从米游社抓到的一组改uid重放也会返回invalid request

Hellobaka commented 2 years ago

网页抓到了个salt,不知道有没有帮助,反正我换上之后没用。 jbjsz6CcmZQCViyBvtBwDdT6TRX09FR1 版本:2.11.0 设备类型:4

thezion commented 2 years ago

@HalcyonSuoh 应该是算法变了,这个值是从哪个页面提取到的?我看看能不能逆向工程一下

Hellobaka commented 2 years ago

@HalcyonSuoh 应该是算法变了,这个值是从哪个页面提取到的?我看看能不能逆向工程一下

我觉着算法的可能性不大,因为抓了一下访问别人角色的请求,看起来和自己的没什么区别.

下面这个是访问别人的请求头

GET https://api-takumi.mihoyo.com/game_record/app/genshin/api/index?server=cn_gf01&role_id=176856504 HTTP/1.1
Host: api-takumi.mihoyo.com
Connection: keep-alive
Accept: application/json, text/plain, */*
DS: 1630740479,147425,3c931f5075c9b6b0981eb002cde046d8
Origin: https://webstatic.mihoyo.com
x-rpc-app_version: 2.11.1
User-Agent: Mozilla/5.0 (Linux; Android 6.0.1; oppo R11s Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.70 Mobile Safari/537.36 miHoYoBBS/2.11.1
x-rpc-client_type: 5
Referer: https://webstatic.mihoyo.com/app/community-game-records/?bbs_presentation_style=fullscreen&bbs_auth_required=true&v=100&gid=2&user_id=278179014&game_id=2&uid=278179014
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.9
Cookie: ltoken=rCm7SxYCx**********FVUEYA4n2zvdTJm446Xlx; ltuid=73743492; account_id=73743492; login_ticket=fuiLfk*******qe7Td4zQxG2lR3B; cookie_token=IWuuu7NTTgpz********LXiqz30rqHl3f; _ga=GA1.2.1343338655.1630736092; _gid=GA1.2.1036569490.1630736092; aliyungf_tc=29f82eec5648e06e09600c86306a2d1f7ec983be73dd007a27704edd3b7b73f3; UM_distinctid=17bafa714ff2-0ec97adc92f0d6-5f340448-64140-17bafa71500e5; _MHYUUID=f9f5febd-e705-********-0c486a954160; _gat=1
X-Requested-With: com.mihoyo.hyperion

下面这个是访问自己的请求头

GET https://api-takumi.mihoyo.com/game_record/app/genshin/api/index?server=cn_gf01&role_id=100367198 HTTP/1.1
Host: api-takumi.mihoyo.com
Connection: keep-alive
Accept: application/json, text/plain, */*
DS: 1630740991,196514,37297a739d6a55f13db213a5c5564b16
Origin: https://webstatic.mihoyo.com
x-rpc-app_version: 2.11.1
User-Agent: Mozilla/5.0 (Linux; Android 6.0.1; oppo R11s Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.70 Mobile Safari/537.36 miHoYoBBS/2.11.1
x-rpc-client_type: 5
Referer: https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.9
Cookie: ltoken=rCm7SxYCx**********FVUEYA4n2zvdTJm446Xlx; ltuid=73743492; account_id=73743492; login_ticket=fuiLfk*******qe7Td4zQxG2lR3B; cookie_token=IWuuu7NTTgpz********LXiqz30rqHl3f; _ga=GA1.2.1343338655.1630736092; _gid=GA1.2.1036569490.1630736092; aliyungf_tc=29f82eec5648e06e09600c86306a2d1f7ec983be73dd007a27704edd3b7b73f3; UM_distinctid=17bafa714ff2-0ec97adc92f0d6-5f340448-64140-17bafa71500e5; _MHYUUID=f9f5febd-e705-********-0c486a954160; _gat=1
X-Requested-With: com.mihoyo.hyperion
Hellobaka commented 2 years ago

太草了,用web抓到的salt,甚至连重发手机端的请求都不行。看来需要一个大佬从app扒一个salt

Azure99 commented 2 years ago

接口变了,/game_record/genshin/api/index只能查自己的信息,新接口/game_record/app/genshin/api/index才可以查其他人的。

ds的算法也变了,在早期的版本中,salt和ds算法直接放在前端中,仅仅有个循环debugger来反调试(这也是为什么很容易就能扒出来)。后来将ds算法移到了app中,通过jsbridge调用,salt迁移到了app里(混淆后的方法是com.mihoyo.hyperion.manager.AManager.k2()),ds算法更进一步,放到了名为libdddd.so的库中,通过jni去调用(com.mihoyo.hyperion.net.bbbbb.a2222),但几乎没有加花,很容易就能逆向出来,算法也和web版一致,没有改变。

现在新的接口使用了新的算法,ds算法放到了libxxxxxx.so库中,并且加了很多花指令,等有时间着再细看看

thezion commented 2 years ago

谢大佬! 另外这边也有个讨论 https://github.com/Arondight/Adachi-BOT/issues/51#issuecomment-912883418

mark9804 commented 2 years ago

我这边看了一下,新的加密方案应该在com.mihoyo.hyperion.net.aaaaa.a2222当中

初步拆包之后,在/smali_classes3/j/q/d/y/h.smali下,搜索字段\u52a0\u5bc6\u65b9\u6848(即中文"加密方案")之后,会返回“老加密方案”(\u8001\u52a0\u5bc6\u65b9\u6848)和“新加密方案”(\u65b0\u52a0\u5bc6\u65b9\u6848)两个搜索结果。

旧的方案就是bbbbb.a2222,那么新加密方案应该就要找com.mihoyo.hyperion.net.aaaaa.a2222

lulu666lulu commented 2 years ago

可是我frida看他调用的是com.mihoyo.hyperion.net.bbbbb.a2222啊

HalcyonSuoh commented 2 years ago

网页抓到了个salt,不知道有没有帮助,反正我换上之后没用。 jbjsz6CcmZQCViyBvtBwDdT6TRX09FR1 版本:2.11.0 设备类型:4

不久之前2.11.0/4的DS用来请求也会invalid request,必须改UA从移动端获取2.11.1/5的才行

Womsxd commented 2 years ago

接口变了,/game_record/genshin/api/index只能查自己的信息,新接口/game_record/app/genshin/api/index才可以查其他人的。

ds的算法也变了,在早期的版本中,salt和ds算法直接放在前端中,仅仅有个循环debugger来反调试(这也是为什么很容易就能扒出来)。后来将ds算法移到了app中,通过jsbridge调用,salt迁移到了app里(混淆后的方法是com.mihoyo.hyperion.manager.AManager.k2()),ds算法更进一步,放到了名为libdddd.so的库中,通过jni去调用(com.mihoyo.hyperion.net.bbbbb.a2222),但几乎没有加花,很容易就能逆向出来,算法也和web版一致,没有改变。

现在新的接口使用了新的算法,ds算法放到了libxxxxxx.so库中,并且加了很多花指令,等有时间着再细看看

这里补充一下最早期的版本情况是:直接抓包,然后把api里面的Uid给修改成想查询的即可,无需登入,无其他限制(包括header头和ds),甚至关闭查询的都能查

ishkong commented 2 years ago

从IOS抓包来看,DS 第一项值没变还是时间 第二项是6位数字 抓包来看存在递增的趋势,但是递增规律不明 这里提供三组数据,看看有没有大佬能 看 出规律(偷瞄)等大佬逆了Orz

1630770845,101481,0e7d5c72a7a80e80e53e35e3bb4f40d9
1630771370,101891,ef22f512bbfad9aa08036d80731978d3
1630807587,130236,d6413a3bccad7082d7a7b58c40856a0b
Womsxd commented 2 years ago

从IOS抓包来看,DS 第一项值没变还是时间 第二项是6位数字 抓包来看存在递增的趋势,但是递增规律不明 这里提供三组数据,看看有没有大佬能 看 出规律(偷瞄)等大佬逆了Orz

1630770845,101481,0e7d5c72a7a80e80e53e35e3bb4f40d9
1630771370,101891,ef22f512bbfad9aa08036d80731978d3
1630807587,130236,d6413a3bccad7082d7a7b58c40856a0b

第二项我感觉还算随机数(?),主要还是第三项

lulu666lulu commented 2 years ago

有人研究出来了吗(

Lightczx commented 2 years ago

新的算法与请求的接口有关,相同时间相同随机串的情况下,check会随请求的接口不同而有变化

Lightczx commented 2 years ago

com.mihoyo.hyperion.net.aaaaa.a2222反混淆非常厉害,隐藏了调用,逆向应该还需要点时间

lulu666lulu commented 2 years ago

(我倒是发现同时请求的结果随机数相同

lulu666lulu commented 2 years ago

我现在不知道com.mihoyo.hyperion.net.aaaaa.a2222这个函数的入参是什么

Lightczx commented 2 years ago

IDA dumped

void Java_com_mihoyo_hyperion_net_aaaaa_a2222()
{
  int v0; // r0
  int v1; // r5
  char v2; // [sp+Ch] [bp-94h] BYREF
  char *v3; // [sp+40h] [bp-60h] BYREF
  char v4[92]; // [sp+44h] [bp-5Ch] BYREF

  v0 = sub_76494(&off_2BB22C);
  v1 = sub_82904(v0);
  v3 = &v2;
  sub_7B2A8(15, &v3, v4);
  __asm { BX              R0 }
}
Lightczx commented 2 years ago

使用跳转指令导致静态分析比较困难

lulu666lulu commented 2 years ago

读内存看算法应该是 (salt=内部生成&t=xxxx&r=和时间有关&b=第一个入参数&q=第二个)取md5

lulu666lulu commented 2 years ago

这个读出来算能对上

lulu666lulu commented 2 years ago

salt每次都不一样

Lightczx commented 2 years ago

似乎是套了一层老算法的结果做新salt

lulu666lulu commented 2 years ago

那r哪来的 和时间有关

lulu666lulu commented 2 years ago

同t的r都是一样的

lulu666lulu commented 2 years ago

但是salt会变

Lightczx commented 2 years ago
// local variable allocation has failed, the output may be wrong!
jstring __fastcall Java_com_mihoyo_hyperion_net_bbbbb_a(JNIEnv *env, jobject thiz)
{
  int v3; // r0
  const unsigned __int8 *v4; // r1
  _jstring *v5; // r4
  std::string v7; // [sp+0h] [bp-18h] BYREF

  *(_QWORD *)&v7.__r_.__value_._anon_0.__l.__cap_ = *(_QWORD *)&env;
  std::string::basic_string(&v7, "swxdtzit6yltz1i5sfaayltzitds2t26yl");
  v4 = v7.__r_.__value_._anon_0.__l.__data_;
  if ( !(v7.__r_.__value_._anon_0.__s._anon_0.__size_ << 31) )
    v4 = (const unsigned __int8 *)(v3 + 1);
  v5 = env->functions->NewStringUTF(env, v4);
  std::string::~string(&v7);
  return v5;
}
jstring __fastcall Java_com_mihoyo_hyperion_net_bbbbb_a1(JNIEnv *env, jobject thiz)
{
  const unsigned __int8 *v3; // r1
  _jstring *v4; // r4
  std::string v6; // [sp+Ch] [bp-9Ch] BYREF
  std::string v7; // [sp+18h] [bp-90h] BYREF
  std::string __lhs; // [sp+24h] [bp-84h] BYREF
  std::string v9; // [sp+30h] [bp-78h] BYREF
  std::string v10; // [sp+3Ch] [bp-6Ch] BYREF
  std::string __str; // [sp+48h] [bp-60h] BYREF
  std::string v12; // [sp+54h] [bp-54h] BYREF
  Random v13; // [sp+60h] [bp-48h] BYREF
  std::string v14; // [sp+64h] [bp-44h] BYREF
  struct timeval tv; // [sp+70h] [bp-38h] BYREF
  std::string __rhs; // [sp+78h] [bp-30h] BYREF
  CMD5 v17; // [sp+84h] [bp-24h] BYREF
  std::string v18; // 0:r2.8,8:^0.4 BYREF

  std::string::basic_string(&__rhs, "qwertueq");
  gettimeofday(&tv, 0);
  std::to_string(&v14, tv.tv_usec / 1000000 + tv.tv_sec);
  Random::random(&v12, &v13);
  std::operator+<char>(&__lhs, (const std::string::value_type *)"salt=", &__rhs);
  std::operator+<char>(&v9, &__lhs, "&t=");
  std::operator+<char>(&v10, &v9, &v14);
  std::operator+<char>((std::string *)&v17, &v10, "&r=");
  std::operator+<char>(&__str, (std::string *)&v17, &v12);
  std::string::~string((std::string *)&v17);
  std::string::~string(&v10);
  std::string::~string(&v9);
  std::string::~string(&__lhs);
  CMD5::CMD5(&v17);
  std::operator+<char>(&v7, &v14, (const std::string::value_type *)",");
  std::operator+<char>(&__lhs, &v7, &v12);
  std::operator+<char>(&v9, &__lhs, ",");
  std::string::basic_string((std::string *)&v18.__r_.__value_._anon_0.__r.__words[2], &__str);
  v18.__r_.__value_._anon_0.__l.__cap_ = (std::string::size_type)&v18.__r_.__value_._anon_0.__r.__words[2];
  CMD5::md5(&v6, &v17, v18);
  std::operator+<char>(&v10, &v9, &v6);
  std::string::~string(&v6);
  std::string::~string((std::string *)&v18.__r_.__value_._anon_0.__r.__words[2]);
  std::string::~string(&v9);
  std::string::~string(&__lhs);
  std::string::~string(&v7);
  v3 = __rhs.__r_.__value_._anon_0.__l.__data_;
  if ( !(__rhs.__r_.__value_._anon_0.__s._anon_0.__size_ << 31) )
    v3 = __rhs.__r_.__value_._anon_0.__s.__data_;
  v4 = env->functions->NewStringUTF(env, v3);
  std::string::~string(&v10);
  std::string::~string(&__str);
  std::string::~string(&v12);
  std::string::~string(&v14);
  std::string::~string(&__rhs);
  return v4;
}
jstring __fastcall Java_com_mihoyo_hyperion_net_bbbbb_a11(JNIEnv *env, jobject thiz)
{
  const unsigned __int8 *v3; // r1
  _jstring *v4; // r4
  std::string v6; // [sp+Ch] [bp-9Ch] BYREF
  std::string v7; // [sp+18h] [bp-90h] BYREF
  std::string __lhs; // [sp+24h] [bp-84h] BYREF
  std::string v9; // [sp+30h] [bp-78h] BYREF
  std::string v10; // [sp+3Ch] [bp-6Ch] BYREF
  std::string __str; // [sp+48h] [bp-60h] BYREF
  std::string v12; // [sp+54h] [bp-54h] BYREF
  Random v13; // [sp+60h] [bp-48h] BYREF
  std::string v14; // [sp+64h] [bp-44h] BYREF
  struct timeval tv; // [sp+70h] [bp-38h] BYREF
  std::string __rhs; // [sp+78h] [bp-30h] BYREF
  CMD5 v17; // [sp+84h] [bp-24h] BYREF
  std::string v18; // 0:r2.8,8:^0.4 BYREF

  std::string::basic_string(&__rhs, "q7fej8vtzitt26yl24kswrgm");
  gettimeofday(&tv, 0);
  std::to_string(&v14, tv.tv_usec / 1000000 + tv.tv_sec);
  Random::random(&v12, &v13);
  std::operator+<char>(&__lhs, (const std::string::value_type *)"salt=", &__rhs);
  std::operator+<char>(&v9, &__lhs, "&t=");
  std::operator+<char>(&v10, &v9, &v14);
  std::operator+<char>((std::string *)&v17, &v10, "&r=");
  std::operator+<char>(&__str, (std::string *)&v17, &v12);
  std::string::~string((std::string *)&v17);
  std::string::~string(&v10);
  std::string::~string(&v9);
  std::string::~string(&__lhs);
  CMD5::CMD5(&v17);
  std::operator+<char>(&v7, &v14, (const std::string::value_type *)",");
  std::operator+<char>(&__lhs, &v7, &v12);
  std::operator+<char>(&v9, &__lhs, ",");
  std::string::basic_string((std::string *)&v18.__r_.__value_._anon_0.__r.__words[2], &__str);
  v18.__r_.__value_._anon_0.__l.__cap_ = (std::string::size_type)&v18.__r_.__value_._anon_0.__r.__words[2];
  CMD5::md5(&v6, &v17, v18);
  std::operator+<char>(&v10, &v9, &v6);
  std::string::~string(&v6);
  std::string::~string((std::string *)&v18.__r_.__value_._anon_0.__r.__words[2]);
  std::string::~string(&v9);
  std::string::~string(&__lhs);
  std::string::~string(&v7);
  v3 = __rhs.__r_.__value_._anon_0.__l.__data_;
  if ( !(__rhs.__r_.__value_._anon_0.__s._anon_0.__size_ << 31) )
    v3 = __rhs.__r_.__value_._anon_0.__s.__data_;
  v4 = env->functions->NewStringUTF(env, v3);
  std::string::~string(&v10);
  std::string::~string(&__str);
  std::string::~string(&v12);
  std::string::~string(&v14);
  std::string::~string(&__rhs);
  return v4;
}
jstring __fastcall Java_com_mihoyo_hyperion_net_bbbbb_a2(JNIEnv *env, jobject thiz)
{
  const unsigned __int8 *v3; // r1
  _jstring *v4; // r4
  std::string v6; // [sp+Ch] [bp-9Ch] BYREF
  std::string v7; // [sp+18h] [bp-90h] BYREF
  std::string __lhs; // [sp+24h] [bp-84h] BYREF
  std::string v9; // [sp+30h] [bp-78h] BYREF
  std::string v10; // [sp+3Ch] [bp-6Ch] BYREF
  std::string __str; // [sp+48h] [bp-60h] BYREF
  std::string v12; // [sp+54h] [bp-54h] BYREF
  Random v13; // [sp+60h] [bp-48h] BYREF
  std::string v14; // [sp+64h] [bp-44h] BYREF
  struct timeval tv; // [sp+70h] [bp-38h] BYREF
  std::string __rhs; // [sp+78h] [bp-30h] BYREF
  CMD5 v17; // [sp+84h] [bp-24h] BYREF
  std::string v18; // 0:r2.8,8:^0.4 BYREF

  std::string::basic_string(&__rhs, "5");
  gettimeofday(&tv, 0);
  std::to_string(&v14, tv.tv_usec / 1000000 + tv.tv_sec);
  Random::random(&v12, &v13);
  std::operator+<char>(&__lhs, (const std::string::value_type *)"salt=", &__rhs);
  std::operator+<char>(&v9, &__lhs, "&t=");
  std::operator+<char>(&v10, &v9, &v14);
  std::operator+<char>((std::string *)&v17, &v10, "&r=");
  std::operator+<char>(&__str, (std::string *)&v17, &v12);
  std::string::~string((std::string *)&v17);
  std::string::~string(&v10);
  std::string::~string(&v9);
  std::string::~string(&__lhs);
  CMD5::CMD5(&v17);
  std::operator+<char>(&v7, &v14, (const std::string::value_type *)",");
  std::operator+<char>(&__lhs, &v7, &v12);
  std::operator+<char>(&v9, &__lhs, ",");
  std::string::basic_string((std::string *)&v18.__r_.__value_._anon_0.__r.__words[2], &__str);
  v18.__r_.__value_._anon_0.__l.__cap_ = (std::string::size_type)&v18.__r_.__value_._anon_0.__r.__words[2];
  CMD5::md5(&v6, &v17, v18);
  std::operator+<char>(&v10, &v9, &v6);
  std::string::~string(&v6);
  std::string::~string((std::string *)&v18.__r_.__value_._anon_0.__r.__words[2]);
  std::string::~string(&v9);
  std::string::~string(&__lhs);
  std::string::~string(&v7);
  v3 = __rhs.__r_.__value_._anon_0.__l.__data_;
  if ( !(__rhs.__r_.__value_._anon_0.__s._anon_0.__size_ << 31) )
    v3 = __rhs.__r_.__value_._anon_0.__s.__data_;
  v4 = env->functions->NewStringUTF(env, v3);
  std::string::~string(&v10);
  std::string::~string(&__str);
  std::string::~string(&v12);
  std::string::~string(&v14);
  std::string::~string(&__rhs);
  return v4;
}
jstring __fastcall Java_com_mihoyo_hyperion_net_bbbbb_a22(JNIEnv *env, jobject thiz)
{
  const unsigned __int8 *v3; // r1
  _jstring *v4; // r4
  std::string __lhs; // [sp+4h] [bp-84h] BYREF
  std::string v7; // [sp+10h] [bp-78h] BYREF
  std::string v8; // [sp+1Ch] [bp-6Ch] BYREF
  std::string v9; // [sp+28h] [bp-60h] BYREF
  std::string v10; // [sp+34h] [bp-54h] BYREF
  Random v11; // [sp+40h] [bp-48h] BYREF
  std::string v12; // [sp+44h] [bp-44h] BYREF
  struct timeval tv; // [sp+50h] [bp-38h] BYREF
  std::string __rhs; // [sp+58h] [bp-30h] BYREF
  CMD5 v15; // [sp+64h] [bp-24h] BYREF

  std::string::basic_string(&__rhs, "4kswrgm");
  gettimeofday(&tv, 0);
  std::to_string(&v12, tv.tv_usec / 1000000 + tv.tv_sec);
  Random::random(&v10, &v11);
  std::operator+<char>(&__lhs, (const std::string::value_type *)"salt=", &__rhs);
  std::operator+<char>(&v7, &__lhs, "&t=");
  std::operator+<char>(&v8, &v7, &v12);
  std::operator+<char>((std::string *)&v15, &v8, "&r=");
  std::operator+<char>(&v9, (std::string *)&v15, &v10);
  std::string::~string((std::string *)&v15);
  std::string::~string(&v8);
  std::string::~string(&v7);
  std::string::~string(&__lhs);
  CMD5::CMD5(&v15);
  std::operator+<char>(&__lhs, &v12, (const std::string::value_type *)",");
  std::operator+<char>(&v7, &__lhs, &v10);
  std::operator+<char>(&v8, &v7, ",");
  std::string::~string(&v7);
  std::string::~string(&__lhs);
  v3 = v8.__r_.__value_._anon_0.__l.__data_;
  if ( !(v8.__r_.__value_._anon_0.__s._anon_0.__size_ << 31) )
    v3 = v8.__r_.__value_._anon_0.__s.__data_;
  v4 = env->functions->NewStringUTF(env, v3);
  std::string::~string(&v8);
  std::string::~string(&v9);
  std::string::~string(&v10);
  std::string::~string(&v12);
  std::string::~string(&__rhs);
  return v4;
}
jstring __fastcall Java_com_mihoyo_hyperion_net_bbbbb_a222(JNIEnv *env, jobject thiz, jstring jstr)
{
  const unsigned __int8 *v5; // r5
  const unsigned __int8 *v6; // r1
  _jstring *v7; // r4
  std::string __lhs; // [sp+Ch] [bp-84h] BYREF
  std::string v10; // [sp+18h] [bp-78h] BYREF
  std::string v11; // [sp+24h] [bp-6Ch] BYREF
  std::string v12; // [sp+30h] [bp-60h] BYREF
  std::string v13; // [sp+3Ch] [bp-54h] BYREF
  Random v14; // [sp+48h] [bp-48h] BYREF
  std::string v15; // [sp+4Ch] [bp-44h] BYREF
  struct timeval tv; // [sp+58h] [bp-38h] BYREF
  std::string __rhs; // [sp+60h] [bp-30h] BYREF
  CMD5 v18; // [sp+6Ch] [bp-24h] BYREF
  std::string v19; // 0:r2.8,8:^0.4 BYREF

  std::string::basic_string(&__rhs, "4kswrgm");
  v5 = env->functions->GetStringUTFChars(env, jstr, 0);
  gettimeofday(&tv, 0);
  std::to_string(&v15, tv.tv_usec / 1000000 + tv.tv_sec);
  Random::random(&v13, &v14);
  std::operator+<char>(&__lhs, (const std::string::value_type *)"salt=", &__rhs);
  std::operator+<char>(&v10, &__lhs, "&t=");
  std::operator+<char>(&v11, &v10, &v15);
  std::operator+<char>((std::string *)&v18, &v11, "&r=");
  std::operator+<char>(&v12, (std::string *)&v18, &v13);
  std::string::~string((std::string *)&v18);
  std::string::~string(&v11);
  std::string::~string(&v10);
  std::string::~string(&__lhs);
  CMD5::CMD5(&v18);
  std::string::basic_string((std::string *)&v19.__r_.__value_._anon_0.__r.__words[2], v5);
  v19.__r_.__value_._anon_0.__l.__cap_ = (std::string::size_type)&v19.__r_.__value_._anon_0.__r.__words[2];
  CMD5::md5(&v11, &v18, v19);
  std::string::~string((std::string *)&v19.__r_.__value_._anon_0.__r.__words[2]);
  v6 = v11.__r_.__value_._anon_0.__l.__data_;
  if ( !(v11.__r_.__value_._anon_0.__s._anon_0.__size_ << 31) )
    v6 = v11.__r_.__value_._anon_0.__s.__data_;
  v7 = env->functions->NewStringUTF(env, v6);
  std::string::~string(&v11);
  std::string::~string(&v12);
  std::string::~string(&v13);
  std::string::~string(&v15);
  std::string::~string(&__rhs);
  return v7;
}
// local variable allocation has failed, the output may be wrong!
jstring __fastcall Java_com_mihoyo_hyperion_net_bbbbb_a2222(JNIEnv *env, jobject thiz, jstring jstr)
{
  const unsigned __int8 *v5; // r0
  std::string *v6; // r2
  const unsigned __int8 *v7; // r1
  _jstring *v8; // r4
  int v10; // [sp+0h] [bp-B8h]
  std::string v11; // [sp+4h] [bp-B4h] BYREF
  std::string v12; // [sp+10h] [bp-A8h] BYREF
  std::string v13; // [sp+1Ch] [bp-9Ch] BYREF
  std::string __lhs; // [sp+28h] [bp-90h] BYREF
  std::string v15; // [sp+34h] [bp-84h] BYREF
  std::string v16; // [sp+40h] [bp-78h] BYREF
  std::string __str; // [sp+4Ch] [bp-6Ch] BYREF
  std::string v18; // [sp+58h] [bp-60h] BYREF
  Random v19; // [sp+64h] [bp-54h] BYREF
  std::string v20; // [sp+68h] [bp-50h] BYREF
  struct timeval tv; // [sp+74h] [bp-44h] BYREF
  std::string __rhs; // [sp+7Ch] [bp-3Ch] BYREF
  std::string v23; // [sp+88h] [bp-30h] BYREF
  CMD5 v24; // [sp+94h] [bp-24h] BYREF

  std::string::basic_string(&v23, "4kswrgm");
  v5 = env->functions->GetStringUTFChars(env, jstr, 0);
  std::string::basic_string(&__rhs, v5);
  gettimeofday(&tv, 0);
  std::to_string(&v20, tv.tv_usec / 1000000 + tv.tv_sec);
  Random::random(&v18, &v19);
  std::operator+<char>(&__lhs, (const std::string::value_type *)"salt=", &__rhs);
  std::operator+<char>(&v15, &__lhs, "&t=");
  std::operator+<char>(&v16, &v15, &v20);
  std::operator+<char>((std::string *)&v24, &v16, "&r=");
  std::operator+<char>(&__str, (std::string *)&v24, &v18);
  std::string::~string((std::string *)&v24);
  std::string::~string(&v16);
  std::string::~string(&v15);
  std::string::~string(&__lhs);
  CMD5::CMD5(&v24);
  std::operator+<char>(&v13, &v20, (const std::string::value_type *)",");
  std::operator+<char>(&__lhs, &v13, &v18);
  std::operator+<char>(&v15, &__lhs, ",");
  std::string::basic_string(&v11, &__str);
  v6 = &v11;
  CMD5::md5(&v12, &v24, *(std::string *)(&v10 - 2));
  std::operator+<char>(&v16, &v15, &v12);
  std::string::~string(&v12);
  std::string::~string(&v11);
  std::string::~string(&v15);
  std::string::~string(&__lhs);
  std::string::~string(&v13);
  v7 = v16.__r_.__value_._anon_0.__l.__data_;
  if ( !(v16.__r_.__value_._anon_0.__s._anon_0.__size_ << 31) )
    v7 = v16.__r_.__value_._anon_0.__s.__data_;
  v8 = env->functions->NewStringUTF(env, v7);
  std::string::~string(&v16);
  std::string::~string(&__str);
  std::string::~string(&v18);
  std::string::~string(&v20);
  std::string::~string(&__rhs);
  std::string::~string(&v23);
  return v8;
}
Lightczx commented 2 years ago

因为没有老版本的apk我也不太清楚哪里变了

Womsxd commented 2 years ago

读内存看算法应该是 (salt=内部生成&t=xxxx&r=和时间有关&b=第一个入参数&q=第二个)取md5

考虑其中一个和uid有关?毕竟改了查询的uid之后旧的ds就不起作用了 以及调试js的时候有看到与客户端通讯的prototype.$postMessage2App(,) 调用差不多是A.default.prototype.$postMessage2App("getDS2",{body:"",query:{"action_ticket":undefined,'game_biz':"hk4e_cn"}})

lulu666lulu commented 2 years ago

读内存看算法应该是 (salt=内部生成&t=xxxx&r=和时间有关&b=第一个入参数&q=第二个)取md5

考虑其中一个和uid有关?毕竟改了查询的uid之后旧的ds就不起作用了 以及调试js的时候有看到与客户端通讯的prototype.$postMessage2App(,) 调用差不多是A.default.prototype.$postMessage2App("getDS2",{body:"",query:{"action_ticket":undefined,'game_biz':"hk4e_cn"}})

事实上你读到的这个是用来拼接第二个参数的

lulu666lulu commented 2 years ago

第一个一般是空的

Womsxd commented 2 years ago

我这边看了一下,新的加密方案应该在com.mihoyo.hyperion.net.aaaaa.a2222当中

初步拆包之后,在/smali_classes3/j/q/d/y/h.smali下,搜索字段\u52a0\u5bc6\u65b9\u6848(即中文"加密方案")之后,会返回“老加密方案”(\u8001\u52a0\u5bc6\u65b9\u6848)和“新加密方案”(\u65b0\u52a0\u5bc6\u65b9\u6848)两个搜索结果。

旧的方案就是bbbbb.a2222,那么新加密方案应该就要找com.mihoyo.hyperion.net.aaaaa.a2222

com.mihoyo.hyperion.net这里还有个aaaaa.b5555,调用方法和aaaaa.a2222基本一致,但是传入的参数并不清楚 似乎在xxxx.so里面,aaaaa.b5555在j.q.d.q0.l.p里面有被调用,我是通过dex2jar之后在jd-gui里面搜索getDS(勾选了String Constant)找到的

lulu666lulu commented 2 years ago

我这边看了一下,新的加密方案应该在com.mihoyo.hyperion.net.aaaaa.a2222当中 初步拆包之后,在/smali_classes3/j/q/d/y/h.smali下,搜索字段\u52a0\u5bc6\u65b9\u6848(即中文"加密方案")之后,会返回“老加密方案”(\u8001\u52a0\u5bc6\u65b9\u6848)和“新加密方案”(\u65b0\u52a0\u5bc6\u65b9\u6848)两个搜索结果。 旧的方案就是bbbbb.a2222,那么新加密方案应该就要找com.mihoyo.hyperion.net.aaaaa.a2222

com.mihoyo.hyperion.net这里还有个aaaaa.b5555,调用方法和aaaaa.a2222基本一致,但是传入的参数并不清楚 似乎在xxxx.so里面,aaaaa.b5555在j.q.d.q0.l.p里面有被调用,我是通过dex2jar之后在jd-gui里面搜索getDS(勾选了String Constant)找到的

确实是aaaaa.b5555 但是调用之后 我追踪到她也调用了a2222 所以我觉得楼上说的是对的这个salt来源是a2222

mark9804 commented 2 years ago

因为没有老版本的apk我也不太清楚哪里变了

网上应该可以搜到历史版本,我因为是海外学生,下不动这个apk,不知道会不会有帮助

lulu666lulu commented 2 years ago

读内存看算法应该是 (salt=内部生成&t=xxxx&r=和时间有关&b=第一个入参数&q=第二个)取md5

考虑其中一个和uid有关?毕竟改了查询的uid之后旧的ds就不起作用了 以及调试js的时候有看到与客户端通讯的prototype.$postMessage2App(,) 调用差不多是A.default.prototype.$postMessage2App("getDS2",{body:"",query:{"action_ticket":undefined,'game_biz':"hk4e_cn"}})

uid被作为请求参数传入了

lulu666lulu commented 2 years ago

你肯定用不了

lulu666lulu commented 2 years ago

不过如果你能读到我前面那个salt理论上可以算ds

lulu666lulu commented 2 years ago

但是ds过期是一个小时(没啥用

mark9804 commented 2 years ago

一个属于我知识盲区的想法不一定有用 (不小心手抖发出去了) 如果静态调试比较困难的话,在AS里面进行动态调试会不会稍微好一些

Lightczx commented 2 years ago

动态调试是我不擅长的方面了,希望有大佬能来看看吧

lulu666lulu commented 2 years ago

动态调试是我不擅长的方面了,希望有大佬能来看看吧

有aaaaa.b5555的ida吗 发下看看

Lightczx commented 2 years ago

动态调试是我不擅长的方面了,希望有大佬能来看看吧

有aaaaa.b5555的ida吗 发下看看

libxxxxxx.so?

lulu666lulu commented 2 years ago

Womsxd commented 2 years ago

动态调试是我不擅长的方面了,希望有大佬能来看看吧

有aaaaa.b5555的ida吗 发下看看

libxxxxxx.so?

可能在libxxxx.so里面吧 如果libxxxxxx.so里面没有,那就是在libxxxx.so里面 static { System.loadLibrary("xxxx"); System.loadLibrary("xxxxxx"); } 这个class里面加载了两个so

lulu666lulu commented 2 years ago

在libxxxxxx里面

Lightczx commented 2 years ago

libxxxx.so

void Java_com_mihoyo_hyperion_net_aaaaa_b5555()
{
  int v0; // r0
  int v1; // r5
  char v2; // [sp+Ch] [bp-94h] BYREF
  char *v3; // [sp+80h] [bp-20h] BYREF
  char v4[28]; // [sp+84h] [bp-1Ch] BYREF

  v0 = sub_76494(&off_2BB22C);
  v1 = sub_827D4(v0);
  v3 = &v2;
  sub_7EFA4(0, &v3, v4);
  __asm { BX              R0 }
}
Lightczx commented 2 years ago

新方案全都是void foo()类型的

Lightczx commented 2 years ago

libxxxxxx.so 里面只有 a2222 和 a3333

Lightczx commented 2 years ago

而且新的算法似乎优化的非常好,全都是直接的指令

Womsxd commented 2 years ago

libxxxxxx.so 里面只有 a2222 和 a3333

看样子6个x的so是a开头的(a2222和a3333)提供调用,4个x的so是b开头的(b5555和b7777)提供调用