mltd繁中服 API速览

联动日服《这几天整的一些东西》

其实当时写的很不明确,我现在光看着一个内存debug也不知道是在哪里找到的


前言

在群里有人在问mltd繁中服相关,才知道可以下载了,然后itunes把以前转去韩区给[前]舍友的号又转到港区下程序去了

(插曲,这个号的安全验证问题被我忘完了,但是竟然itunes账号设置可以直接改区,神奇)

在我弄之前已经搞出来api域名是 theaterdays-zh.appspot.com ,和之前差不多可还行,估计万代直接把服务器基础框架复制过去了一份

本地改了hosts,打开SSLKillSwitch,电脑上开nginx+fiddler,请求顺利的就过来了,只有一个AppBoot和GetVersion能进来,因为还没正式开服

快速跑了一下之前的批量解密的脚本,果然失败了,所以通信密钥变了


正文

繁中版不知道为什么改成了ios11以上,这基本上就杜绝了debugserver的可能(我记得12上面是爆炸的,12.4越狱后还没试过,也没有时间去倒腾)

(另外其实我也没有试给ios9强行安装)

反正日常直接用了我自己搞出来的ios12能用的clutch提取方法直接搞主程序,然后扔进ida开始跑分析

跑的途中就开始搜索,搜了几个AesManaged RijndaelManaged都没有直接引用,然后搜 x-encryption-compress 搜到在类 Imas.Connection.Api 里面用到了,调用来源 Imas.Connection.Connection,然后在里面看到了 public byte[] DecKey(int eMode)

看到这里我就又打开了日服的版本,对比发现其实万代在繁中服把这部分算是重写了

日服里面的函数是 private byte[] DecryptKey(byte[] enckey) ,具体细节是在类初始化时从 metadata 里面读取两个32字节的字符串,对第一个字符串进行reverse,然后和第二个字符串异或,就是日服的密钥了

但是繁中服这边就完全不一样了

先是初始化时候一大堆常数的uint

然后进行一波乱序的Array_Copy,出来一个32字节一个64字节的字节数组,最后用这俩跑一遍aes decrypt

代码搞一下结果出来倒是也挺快

赋值那段我用vs写了个c直接帮我跑出来的,我可懒得自己一个个抄


后记&杂谈

这次从不一样的角度重新研究了一次mltd的密钥,上次基本上纯属凑巧,强行debug搞出了密钥,和最早挖内存挖出b站flash player的playurl salt差不多。这次更加系统的通过静态分析找到了密钥的位置并搞出了算法。

其实真的讲的话,万代这个密钥获取算法还是不够混淆,只是稍微防一下(比bang的直接能在metadata里面搜索出来好得多)

然后碎碎念,研究生入学了,然后就被导师一通安排,给安排的明明白白。人家上个班996顶天,我这直接给我排好了897(卒)

其实到现在还是有点目标不明确,搞不太懂方向

虽然说是报了驾校,但总感觉连这个都有点难以保证,尽量忙里偷闲吧

(家人还希望我继续考英语重新申个国外的研究生,对这个我也有点不太明确,到底怎么搞,去哪里之类的)

17 thoughts on “mltd繁中服 API速览”

  1. 感谢博主,第一次接触这方面的知识,折腾了好久终于搞定了,感恩~

    Tips:
    安卓用户可以用 Drony 来把 theaterdays-zh.appspot.com 的流量打到抓包工具上,比改hosts还是方便不少的

  2. Hello brother, I was searching for the information about MLTD and found your blog on Google.

    Sorry for writing the comment in English, I tried to translate with several translation services but all of them made weird results 🙁

    Different on ZH client is interesting, your post might be helpful on inspecting KR client.
    Also, thank you for the information about the API response on the comment. That’s very interesting!

    Anyway, I’m currently looking at the Japan region client, but things not going well.

    I tried to dump the libil2cpp.so with Il2CppDumper, but it seems that global-metadata.dat is obfuscated or using a different format, to prevent the inspection.

    I tried to inspect the il2cpp::vm::MetadataCache::Initialize and il2cpp::vm::MetadataLoader::LoadMetadataFile, but failed to figure out the magic on it.

    I tried to intercept the il2cpp::vm::MetadataLoader::LoadMetadataFile with Frida(similar to Clutch, but for Android), but it’s not called. I can’t figure out how they load the metadata file.

    Was global-metadata.dat not obfuscated when you looked into the ZH client? If it was obfuscated, can I get help on solving the magic?

    I’m looking forward to your reply. Thanks for reading!

    1. No worry, English comment is ok.

      JP ver Android is protected with AppGuard, while iOS is not protected. App Store does not allow any kind of obfuscation of main binary file, so dumping on iOS can sometime be much easier.
      I’m not sure if ZH / KR is protected too.

      1. Wow, it’s surprising that obfuscation is not allowed 😮

        It’s sad that I don’t have any iOS devices now, should get one to inspect it.

        And I’m not sure about ZH, but KR client is also protected by AppGuard.

        I have one more question about text content(looks like base64 encoded) of https requests to server. Are they encrypted with the way you described about the text content of response?

        Thanks for your help! I didn’t expect you will reply that fast :3

        1. Seems finding the key will be the point for getting the contents of API. Gonna try anything to find it.

          Since I don’t have an iOS device now, figuring out the magic on global-metadata.dat will be the best way to find the key.

          It looks that both JP and KR has same method for obfuscation, so it would be better to look on KR version first to find the magic — I’m newbie, think smaller one is better

          Anyway, Thank You!!

        2. Hello brother, I have got an iOS device and tried to capture the HTTP traffics with both iOS’ default network proxy and HTTP Catcher but failed to find the traffic heading to theaterdays.appspot.com.

          I have installed the certification and other requests are logged fine, such as smbeat or gameguard, a webpage for in-game notices, even the traffics from App Store.

          When I tried to capture the traffics on Android clients, they were sending an encrypted text for RPC over HTTPS. So I expected iOS will have the same method for connection but failed to capture them.

          Do iOS clients use a different way — not HTTP — to communicate with Firebase Server?

          Thanks for reading, have a good day!

        3. Hello brother, finally I succeed to get the content of requests!

          I was unable to find the position of the key in global-metadata, so I intercepted the call of System.Security.Cryptography.AesManaged$$CreateEncryptor with Frida, and got the key from its argument.

          What I’ve figured out is, Android and iOS Client uses the same key for AES-256-CBC, which must be expected, but I never thought about it. And the key has not been changed, I can see the same one in the picture of this article.

          So I captured the requests of Android client and decrypted it with the method you commented below, it works perfectly! I really appreciate your help!!

          Have a nice day!

        4. Wow congrats

          Also, on iOS to get the capture you need to control the DNS. It doesn’t use NSURLRequest so won’t follow system proxy settings.
          App like “HTTP Catcher” has this functionality built in

  3. 您好,ios11,开SSLKillSwitch,charles走代理,抓不到包。还显示连线失败。请教下您是如何处理的?期待回复,谢谢!

      1. 你好,修改hosts意思是修改手机的hosts,把theaterdays-zh.appspot.com这个网址指向fiddler的ip(192.168.1.100:8888)吗

3u进行回复 取消回复

电子邮件地址不会被公开。 必填项已用*标注

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax