# 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*
