Description

Asset bundle extraction is the practice of pulling textures, meshes, prefabs, animations, and scripts back out of a shipped Unity game. Open-source tools like AssetStudio, AssetRipper, and UABE read raw .bundle files straight off disk or out of a CDN response and reconstruct browsable, re-importable Unity assets in minutes. For free demos that is mostly a curiosity; for paid content, season passes, level packs, or proprietary art it is the part of the pipeline that decides whether your assets stay yours.
A small protection layer in front of the bundle file is enough to break those tools. Unity's bundle parser expects a very specific binary header, so wrapping each bundle in an envelope that the parser cannot recognize forces an attacker to find and reverse the unwrap step before any extraction tool can do anything useful. Doing it once, in the build pipeline, with a transparent runtime counterpart, keeps the rest of your game code untouched.
Addressable Shield
GuardingPearSoftware's Addressable Shield is a drop-in encryption layer for Unity Addressable Asset Bundles. Every .bundle file produced by Unity Addressables is encrypted at build time and transparently decrypted at runtime, with no changes to your existing Addressables.LoadAssetAsync(...) or AssetReference calls. Local bundles (StreamingAssets, persistentDataPath) and remote bundles (http / https CDNs) are both supported.
Addressable Shield targets Unity 6 (6000.x) or newer and requires the com.unity.addressables package. The runtime ships under Assets/GUPS/Addressable Shield/Source/; the build pipeline lives under Editor/Source/ and is stripped from player builds by the editor-only asmdef.
Integration
Addressable Shield is plug and play. You replace the standard packed build script with EncryptedAddressableBuilder (GUPS Encrypted Build Script) and the standard AssetBundleProvider with EncryptedAddressableProvider (GUPS Encrypted Asset Bundle Provider). From that point on every Addressables build encrypts every bundle in Addressables.BuildPath, and every runtime load decrypts the bundle on its way to AssetBundle.LoadFrom.... The five steps to wire that up are covered in the How to start page.
Once configured you do not have to call any encryption or decryption API yourself. The build script's DoBuild override runs the standard packed build first, then post-processes every produced *.bundle. The runtime provider's Provide(...) reads the encrypted container and hands the decrypted bytes to Unity, so your game-side code keeps using AssetReference.InstantiateAsync(...) exactly as before.
Code Example
A typical scene loader looks identical with or without Addressable Shield, because the protection layer sits below the Addressables API:
public sealed class CubeSpawner : MonoBehaviour
{
public AssetReferenceGameObject cubeReference;
private void Start()
{
AsyncOperationHandle<GameObject> handle =
cubeReference.InstantiateAsync(Vector3.zero, Quaternion.identity);
handle.Completed += op =>
{
if (op.Status == AsyncOperationStatus.Succeeded)
{
Debug.Log($"Spawned '{op.Result.name}'.");
}
};
}
}
The only thing that changes between an unprotected project and a protected one is the provider that resolves the underlying bundle. Switching Asset Bundle Provider to GUPS Encrypted Asset Bundle Provider in AddressableAssetSettings (or per group) is the entire game-side opt-in.
Local and Remote Bundles
Local bundles (StreamingAssets, persistentDataPath, anything reachable through plain file IO) take the lower-memory route. EncryptedAssetBundleResource reads the encrypted container from disk, decrypts it, writes the plaintext to a temporary file under Application.temporaryCachePath, and hands that path to AssetBundle.LoadFromFileAsync(...). The temp file is deleted when Addressables releases the bundle.
Remote bundles (http / https CDNs) take the in-memory route. The provider downloads the encrypted bytes via UnityWebRequest, decrypts them in memory, and calls AssetBundle.LoadFromMemoryAsync(plaintext) directly. There is no on-disk temp file in that case, because remote bundles do not have a stable local path to begin with.
The CDN must serve the encrypted .bundle files exactly as built. Any server-side transcoding (re-gzip, content sniffing, byte-range stitching that drops trailing bytes) breaks and the load fails with a clear error. Configure the bundle file extension as a passthrough binary type and you are fine.
Integrity
Addressable Shield validates every container before touching the decrypt step.
When any of the integrity checks fails the load surfaces an InvalidDataException ("Encrypted bundle hash mismatch (tampered or corrupted)", "Encrypted bundle magic mismatch", "Encrypted bundle offset out of range", ...) and Addressables fails the operation cleanly instead of feeding garbage into Unity's bundle parser. Bit-flips in transit, partial CDN responses, and after-build edits all produce the same hash mismatch.