本次分析针对米游社 app2.6.0 版本

学逆向的基础知识的时候一般都用的爆破的方法,无非改几个跳转和 0x1,0x0 而已,每次看到别人分析算法都非常羡慕。之前早有耳闻米游社 api 接口有一个经常变动的效验字段,所以今天就索性试了试。

MT 管理器提取安装包,没有加固。
点查看,粗略看了看,代码量挺大的,所以打算先定位到签到的 activity。
用 MT 管理器的 Activity 记录功能,定位到签到的 activity 是com.mihoyo.hyperion.web.MiHoYoWebActivity(看起来并没有什么用)

还是直接入手 apk 吧,用 Dex 编辑器++打开所有的 dex(MultiDex)。

因为在网上有一些讨论,所以大概知道效验的字段叫DS,直接搜索。
找到 809 个结果,不过也没啥,明显android.xxxcom.google.xxx之类的应该没啥关系,直接看com.mihoyo.xxx的就行。不太清楚为啥 MT 管理器搜索代码的时候就不能全字匹配,不过也无所谓,人工全字匹配也罢。
简单的几次尝试可以发现找到了想要的东西 (这名字取得也是非常文艺:达摩克里斯?)。

点进去反编译之。

static
{
    System.loadLibrary("dddd");
}
public DamoclesInterceptor()
{}
private final native String a();
private final native String a1();
private final native String a11();
private final native String a2();
private final native String a22();
private final native String a222(String str);
@d
public final native String a2222(@d String str);
@d
public e0 intercept(@d w.a aVar)
{
    RuntimeDirector runtimeDirector = m__m;
    if(runtimeDirector == null || !runtimeDirector.isRedirect(0))
    {
        k0.e(aVar, "chain");
        return aVar.a(aVar.request().l().a("DS", a2222(AManager.INSTANCE.k2())).a());
    }
    return(e0) runtimeDirector.invocationDispatch(0, this, new Object[]
    {
        aVar
    });
}

loadLibrarynative方法,看来等下得分析分析 so 文件。

注:loadLibrary是读取 lib 文件夹下的 libxxxx.so 文件,是用 c++之类的写的,叫做 native 编程。

先稳一手,看下下面那一串方法,我不会安卓/java 开发,不知道这个方法名字叫啥?e0 后面又有 intercept。干脆搜一下这个文件的名字DamoclesInterceptor看下调用的地方。

除了定义的地方,有两个地方调用了。

下面那个我没看懂在干什么,看上面那个。
反编译后容易看到里面的关键代码:

webViewJsCallbackBean.getData().
put("DS", new DamoclesInterceptor().a2222(AManager.INSTANCE.lk2()));

是在请求数据之类的?总之调用了 DamoclesInterceptor() 里面刚刚看到 native 的 a2222() 函数,传参是AManager.INSTANCE.lk2()先看下这个传参是何方神圣,翻到最上面看 import,这个 AManager 是从com.mihoyo.hyperion.manager导入的。
浏览一下这个AManageIK2方法,看到里面的内容我笑出了声,这一大堆数字看起来貌似在告诉我它就是关键要保护的东西。

@d
public final String lk2()
{
    int i;
    RuntimeDirector runtimeDirector = m__m;
    if(runtimeDirector != null && runtimeDirector.isRedirect(1))
    {
        return(String) runtimeDirector.invocationDispatch(1, this, a.a);
    }
    int[] iArr = {
        -120, -14348907, 192, -6561, 192, -1594323, -6561, 192, -14348907, -112, -100, 204, -120, 156, -1594323, 180, 174, -2187, -112, -98, -14348907, -2187, -19683, 168, 186, -100, -114, -2187, -108, -59049, 204, 156
    };
    StringBuilder sb = new StringBuilder();
    ArrayList < Number > arrayList = new ArrayList < > (iArr.length);
    for(int i2: iArr)
    {
        if(i2 < 0)
        {
            double d = (double) 6;
            i = ((double)(-i2)) >= Math.pow(3.0 d, d) ? (int)(((Math.log(-((double) i2)) / Math.log(3.0 d)) - d) + ((double) 48)) : ~i2;
        }
        else
        {
            i = (i2 / 3) + 48;
        }
        arrayList.add(Integer.valueOf(i));
    }
    ArrayList arrayList2 = new ArrayList(y.a(arrayList, 10));
    for(Number intValue: arrayList)
    {
        sb.append((char) intValue.intValue());
        arrayList2.add(sb);
    }
    String sb2 = sb.toString();
    k0.d(sb2, "sb.toString()");
    return sb2;
}

不会 java,用 python 照猫画虎写了个:

from math import log
iArr = [204, 180, -108, -122, -102, -118, -102, -114, -1594323, 162, -102, 174, -4782969, 210, 204, 222, -106, 204, 204, -6561, -531441, -122, 180, -6561, -59049, -108, -116, -120, 198, -104, -110, -177147]
arrayList = []
sb = ""
for i2 in iArr:
    if i2 < 0:
        d = 6
        if - i2 >= 3 ** 6:
            i = int((log(float(-i2)) / log(3.0) - d) + float(48))
        else:
            i = ~i2
    else:
        i = (i2 // 3) + 48
    arrayList.append(chr(i))
print("".join(arrayList))

运行之,得到结果tlkyeueq7fej8vtzitt26yl24kswrgm5
用 ida 反编译了下 so 文件发现这就是加密 DS 的salt。懒得分析后面的了,直接用别人现成的算了 (ps:现成指的是网上看到的用的是 web 的 salt,我改成安卓的 salt)。

def get_ds():
        n = 'tlkyeueq7fej8vtzitt26yl24kswrgm5'
        #n = 'hfiki8qvnuai95p2845psdo9ydcmsrc0' #这是 web 端的
        i = str(int(time.time()))
        r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6))
        c = hexdigest('salt=' + n + '&t=' + i + '&r=' + r)
        return '{},{},{}'.format(i, r, c)

至于抓包啥啥的我就懒得搞了,知道这个 DS 怎么来就行了,万一实在没办法了就跟进 ida 看下吧,那个活儿更累嘞。