Closed HalcyonSuoh closed 2 years ago
网页抓到了个salt,不知道有没有帮助,反正我换上之后没用。 jbjsz6CcmZQCViyBvtBwDdT6TRX09FR1 版本:2.11.0 设备类型:4
@HalcyonSuoh 应该是算法变了,这个值是从哪个页面提取到的?我看看能不能逆向工程一下
@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
太草了,用web抓到的salt,甚至连重发手机端的请求都不行。看来需要一个大佬从app扒一个salt
接口变了,/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库中,并且加了很多花指令,等有时间着再细看看
我这边看了一下,新的加密方案应该在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
了
可是我frida看他调用的是com.mihoyo.hyperion.net.bbbbb.a2222啊
网页抓到了个salt,不知道有没有帮助,反正我换上之后没用。 jbjsz6CcmZQCViyBvtBwDdT6TRX09FR1 版本:2.11.0 设备类型:4
不久之前2.11.0/4的DS用来请求也会invalid request,必须改UA从移动端获取2.11.1/5的才行
接口变了,/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),甚至关闭查询的都能查
从IOS抓包来看,DS 第一项值没变还是时间 第二项是6位数字 抓包来看存在递增的趋势,但是递增规律不明 这里提供三组数据,看看有没有大佬能 看 出规律(偷瞄)等大佬逆了Orz
1630770845,101481,0e7d5c72a7a80e80e53e35e3bb4f40d9
1630771370,101891,ef22f512bbfad9aa08036d80731978d3
1630807587,130236,d6413a3bccad7082d7a7b58c40856a0b
从IOS抓包来看,DS 第一项值没变还是时间 第二项是6位数字 抓包来看存在递增的趋势,但是递增规律不明 这里提供三组数据,看看有没有大佬能 看 出规律(偷瞄)等大佬逆了Orz
1630770845,101481,0e7d5c72a7a80e80e53e35e3bb4f40d9 1630771370,101891,ef22f512bbfad9aa08036d80731978d3 1630807587,130236,d6413a3bccad7082d7a7b58c40856a0b
第二项我感觉还算随机数(?),主要还是第三项
有人研究出来了吗(
新的算法与请求的接口有关,相同时间相同随机串的情况下,check会随请求的接口不同而有变化
com.mihoyo.hyperion.net.aaaaa.a2222
反混淆非常厉害,隐藏了调用,逆向应该还需要点时间
(我倒是发现同时请求的结果随机数相同
我现在不知道com.mihoyo.hyperion.net.aaaaa.a2222这个函数的入参是什么
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 }
}
使用跳转指令导致静态分析比较困难
读内存看算法应该是 (salt=内部生成&t=xxxx&r=和时间有关&b=第一个入参数&q=第二个)取md5
这个读出来算能对上
salt每次都不一样
似乎是套了一层老算法的结果做新salt
那r哪来的 和时间有关
同t的r都是一样的
但是salt会变
// 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;
}
因为没有老版本的apk我也不太清楚哪里变了
读内存看算法应该是 (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"}})
读内存看算法应该是 (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"}})
事实上你读到的这个是用来拼接第二个参数的
第一个一般是空的
我这边看了一下,新的加密方案应该在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)找到的
我这边看了一下,新的加密方案应该在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
读内存看算法应该是 (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被作为请求参数传入了
你肯定用不了
不过如果你能读到我前面那个salt理论上可以算ds
但是ds过期是一个小时(没啥用
一个属于我知识盲区的想法不一定有用 (不小心手抖发出去了) 如果静态调试比较困难的话,在AS里面进行动态调试会不会稍微好一些
动态调试是我不擅长的方面了,希望有大佬能来看看吧
动态调试是我不擅长的方面了,希望有大佬能来看看吧
有aaaaa.b5555的ida吗 发下看看
动态调试是我不擅长的方面了,希望有大佬能来看看吧
有aaaaa.b5555的ida吗 发下看看
libxxxxxx.so?
嗯
动态调试是我不擅长的方面了,希望有大佬能来看看吧
有aaaaa.b5555的ida吗 发下看看
libxxxxxx.so?
可能在libxxxx.so里面吧
如果libxxxxxx.so里面没有,那就是在libxxxx.so里面
static { System.loadLibrary("xxxx"); System.loadLibrary("xxxxxx"); }
这个class里面加载了两个so
在libxxxxxx里面
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 }
}
新方案全都是void foo()类型的
libxxxxxx.so 里面只有 a2222 和 a3333
而且新的算法似乎优化的非常好,全都是直接的指令
libxxxxxx.so 里面只有 a2222 和 a3333
看样子6个x的so是a开头的(a2222和a3333)提供调用,4个x的so是b开头的(b5555和b7777)提供调用
从其他接口获取的DS, x-rpc-client_type, x-rpc-app_version用来请求玩家信息会返回invalid request, 从米游社抓到的一组改uid重放也会返回invalid request