mirror of
https://codeberg.org/Nixietab/EOSSDK-Holos.git
synced 2026-08-21 20:23:28 -04:00
65 lines
2.8 KiB
Markdown
65 lines
2.8 KiB
Markdown
# Bundle Decryption & Extraction
|
|
|
|
## Overview
|
|
|
|
Holo's Hanafuda (Unity 6000.0.25f1, IL2CPP) encrypts its 559 addressable asset bundles using a custom **AES-256-ECB** stream cipher implementation. This document outlines the encryption scheme, the discovery process, and how to use the `extract_bundles.py` script to decrypt and extract the assets.
|
|
|
|
## Encryption Scheme
|
|
|
|
The game implements a custom stream cipher by leveraging AES-256-ECB as a keystream generator. The encryption keys were found by developing a custom **EOSSDK** proxy DLL that dumps keys at runtime.
|
|
|
|
| Property | Value |
|
|
|---|---|
|
|
| Cipher | AES-256-ECB, `PaddingMode.None` |
|
|
| Key | 32 ASCII bytes: `rK7CcATuZk7LAmhqqU4iBLNmAq8QbK3s` |
|
|
| Keystream | `AES_ECB(key, counter_block)` |
|
|
| Counter block | `[le64(counter) \| 8 zero bytes]` (16 bytes) |
|
|
| Counter start | `pos/16 + 1` (first block = counter 1) |
|
|
|
|
### Decryption Logic
|
|
Files are encrypted using a block-by-block XOR operation against an AES-generated keystream. To decrypt these bundles, you can use the `extract_bundles.py` script, which calculates the counter for each 16-byte block and reverses the XOR encryption.
|
|
|
|
```python
|
|
# The process is something like this:
|
|
counter_block = struct.pack('<q', pos // 16 + 1) + b'\x00' * 8
|
|
keystream = AES_ECB(key, counter_block)
|
|
plaintext[i] = ciphertext[i] XOR keystream[i]
|
|
|
|
```
|
|
|
|
## Discovery & Key Extraction
|
|
|
|
The encryption keys and metadata were recovered using a custom **EOSSDK** proxy DLL (`main.c`). By replacing the legitimate `EOSSDK-Win64-Shipping.dll` with this proxy, we successfully:
|
|
|
|
* **Intercepted Key Derivation**: Hooked `GenerateKey` and `GenerateIV` to capture the 32-byte AES key and bundle naming patterns.
|
|
* **Memory Scanning**: Implemented a background thread to scan process memory for UnityFS headers and key string patterns.
|
|
* **Asset Loading Hooks**: Hooked `EncryptAssetBundleResource.LoadLocal` to map encrypted bundles to their file paths.
|
|
|
|
## Extraction Process
|
|
|
|
### Prerequisites
|
|
|
|
Ensure you have the necessary Python libraries installed:
|
|
|
|
```bash
|
|
pip install pycryptodome UnityPy
|
|
|
|
```
|
|
|
|
### Script: `extract_bundles.py`
|
|
|
|
This script performs a two-phase extraction:
|
|
|
|
1. **Decryption**: Reads encrypted `.bundle` files from the game directory and writes decrypted `.unity3d` files to the output folder using the discovered AES key.
|
|
2. **Asset Parsing**: Uses `UnityPy` to iterate through the decrypted bundles to extract Textures, Sprites, Meshes, and Audio.
|
|
|
|
## Asset Breakdown
|
|
|
|
| Type | Count | Notes |
|
|
| --- | --- | --- |
|
|
| AudioClip | 3149 | FSB5 format |
|
|
| Texture2D | 1312 | Backgrounds/UI |
|
|
| Sprite | 1298 | Atlas-sliced character art |
|
|
| TextAsset | 71 | Dialogue/Config |
|
|
|
|
*Note: The asset extraction done by the script is purely a example, to actually extract all the possible files correctly, you should use a software like AssetRipper*
|