EOSSDK-Holos/keyDumper/bundle_decryption.md
2026-07-04 07:06:51 -03:00

2.8 KiB

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.

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

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