Project SEKAI Game Analysis

Hearing that Hatsune Miku released a new mobile game, I skillfully opened the Play Store, downloaded, and ran it. The game, just as skillfully, popped up with a smooth animation: 「通信エラーが発生しました」(“A communication error has occurred.”) Well, Japanese games loves abusing SafetyNet, after all.

Swiping back, I added the game to the MagiskHide list. Cleared the data, opened the game again—and… “A communication error has occurred.” Huh? What’s going on? I double-checked the settings, cleared the data again, but the error persisted. Slowly, I recalled the fear of being dominated by Disney+ Widevine L1. Could this game also enforce SafetyNet Hardware-backed Key Attestation?

Press START screen featuring Live2D animations

Opened a search engine and typed “Project SEKAI unable to connect.” Oh! Turns out it detected my VPN. Testing revealed the game likely uses something like the GeoIP2 Anonymous IP Database—it’s well-prepared. Given the exceptionally sincere design of the Press START interface, I didn’t give up. After some tinkering, I finally got into the game.

assetbundle.sekai.colorfulpalette.org
assetbundle-info.sekai.colorfulpalette.org
game-version.sekai.colorfulpalette.org
production-game-api.sekai.colorfulpalette.org
production-web.sekai.colorfulpalette.org
# Don’t ask, I don’t know what this is

Game Resource Analysis

Like a previously analyzed game (Dream Blast), this is a Unity game compiled with il2cpp.

Game resources are mainly divided into two types: local resources and on-demand (OnDemand) resources. Local resources can be directly unpacked with AssetStudio, while on-demand resources are cached in sdcard/Android/data/{package name}/data.

Resource Obfuscation

On-demand resources are lightly obfuscated using the Sekai.AssetBundleManager.XORStream function (libil2cpp.so). After removing a 0x4-byte flag, the first 0x80 bytes of the header are XORed with FF FF FF FF FF 00 00 00. This obfuscation method has minimal performance impact but effectively wastes analysts’ time—a decent trade-off.

Initially thought this header was a custom file packaging format, but it’s just XORed UnityFS…

I wrote a simple program, sekai-xor, to batch-decrypt obfuscated resources.

Live2D Resources

Live2D resources are unencrypted, but their storage structure and method differ from other games, so they cannot be directly exported using UnityLive2DExtractor. Model files are stored directly as .png, .moc3, .model3.json, and .physics3.json formats, which can be exported and viewed using AssetStudio.

Motion files are stored in Unity’s .anim format, where bound parameter names are not stored as strings like in .motion3.json but as crc32(parameter type + '/' + parameter name).

UnityLive2DExtractor retrieves the parameter list by reading the GameObject (Transform) corresponding to the motion file, calculating the crc32 of each parameter, and then converting the .anim file back to .motion3.json. However, this game seems to lack such GameObjects.

After analyzing a few files, I found that the parameter list in string form could only be found in .moc3. However, .moc3 is not an open-source format, and there are no public third-party parsers. For now, I’m extracting the parameter list by directly searching for ASCII characters in .moc3 to convert the crc32 parameters in .anim.

By modifying UnityLive2DExtractor, I achieved batch conversion of .anim files to .motion3.json: SEKAI2DMotionExtractor.

(★ ω ★)

Audio Resources

The game’s audio files are encrypted and packed into .acb format, which can be unpacked and decrypted using CriTools. A search revealed that the encryption key is the same as that used in *BanG Dream! Girls Band Party!*.

However, I couldn’t locate where this game stores its encryption key after analysis.

On-Demand Resources

The game includes a large amount of on-demand resources (~4GB). Some resources won’t download unless specific scenes are triggered. To obtain all resources, you either need to play through every branch or analyze the game’s network communication.

Network Communication Analysis

Since the game is still operational, this is only a brief analysis for learning and research purposes.

The game serializes data using MessagePack, encrypts it with a fixed AES key and IV using AES-128-CBC, and transmits it over TLS (https).

TLS certificate verification cannot be bypassed by importing root certificates. I suspect the verification occurs in the curl library of libunity.so. Disabling curl’s certificate verification is possible by binary-patching this file. I also found a useful ARM64 assembly code conversion site.

The AES key and IV are set in the Sekai.APIManager constructor. The specific key is exported to global-metadata.dat during compilation. Referring to Perfare’s article, I located the key and IV in this file.

MessagePack data can be directly converted to JSON for easier reading. Analyzing network communication reveals data like the list of on-demand resources.

Summary

I’ve never been a fan of mobile online games, but both the sheer volume of resource packages and the game itself give off a strong sense of sincerity.

This analysis was a small attempt at binary patching under ARM64. As with last time, it relied heavily on prior research and tools. If a few unknown algorithms were thrown in, it’d probably be a lot tougher.

Coxxs

Leave a Reply

Your email address will not be published. Required fields are marked *