Skip to content

[Bug] Signing with custom entitlements silently "succeeds" while zsign fails — LiveContainer install fails with ApplicationVerificationFailed (0xe8008001) #704

Description

@zHElEARN

Summary

When signing LiveContainer 3.8.0 with a custom entitlements file using the Entitlements (BETA) option (NIGHTLY/DEBUG builds), the signing flow completes without any error in the UI, but the produced app is not actually signed. Installing it then fails with:

ApplicationVerificationFailed
Failed to verify code signature of .../Payload/LiveContainer.app
0xe8008001
An unknown error has occurred
code 203
Image

The root cause is twofold:

  1. The bundled zsign version (6ffe703, zsign 0.7) fails while signing ShareExtension.appex with No enough CodeSignature space (now: 20480, need: 24991) — the known ReallocCodeSignSpace 16K buffer bug.
  2. Feather ignores the Bool return value of Zsign.sign() and only checks the completion error, so this zsign failure is silently swallowed and the unsigned bundle is moved to Signed and installed.

Environment

  • Feather: 2.9.0, NIGHTLY/DEBUG build (Entitlements (BETA) option visible)
  • Device: iPhone 17, iOS 26.6
  • IPA: LiveContainer 3.8.0 (official LiveContainer.ipa)
  • Provisioning profile: LiveContainer Development (com.zhelearn.livecontainer, development, get-task-allow=true)
  • Certificate: Apple Development
  • Entitlements: custom entitlements file (large keychain-access-groups list)

Steps to reproduce

  1. Open Feather (NIGHTLY/DEBUG build).
  2. Import LiveContainer.ipa (3.8.0).
  3. In the signing screen, select the certificate backed by the LiveContainer Development profile.
  4. Open Advanced → Entitlements (BETA) and select the custom entitlements file.
  5. Sign the app. The flow completes without an error in the UI.
  6. Install the signed app.

Expected behavior

Either the app is correctly signed and installs, or Feather reports that signing failed.

Actual behavior

The signing flow "succeeds", but the app bundle is left unsigned (original ad-hoc signature, no _CodeSignature). Installation fails with ApplicationVerificationFailed / 0xe8008001.

Evidence

1. zsign console log (captured from the device via xcrun devicectl device process launch --console)

>>> Signing: .../LiveContainer.app ...
>>> AppName:  LiveContainer
>>> BundleId: com.kdt.livecontainer
>>> Version:  3.8.0
>>> TeamId:   [REDACTED]
>>> SubjectCN: [REDACTED]
>>> ReadCache: NO
>>> Exclude MobileProvision: NO
>>> SignFile:  Frameworks/TestJITLess.dylib
>>> Can't find CodeSignature segment!
>>> Realloc CodeSignature space...
>>> Success!
>>> SignFile:  Frameworks/TweakLoader.dylib
>>> SignFile:  Frameworks/ZSign.dylib
>>> SignFolder: PlugIns/LiveProcess.appex, (LiveProcess)
>>> SignFolder: PlugIns/ShareExtension.appex, (ShareExtension)
>>> No enough CodeSignature space (now: 19520, need: 24991).
>>> Realloc CodeSignature space...
>>> Success!
>>> No enough CodeSignature space (now: 20480, need: 24991).
>>> Signed Failed! (0.023s, 23424us)
>>> Done.

The failure happens while signing ShareExtension.appex: zsign needs 24991 bytes of CodeSignature space, but after reallocation it only has 20480 bytes.

2. installd syslog (installation failure)

installd: -[MIExecutableBundle estimatedMemoryUsageToValidate]: Failed to lstat .../LiveContainer.app/_CodeSignature/CodeResources : No such file or directory (2)
installd{libmis.dylib} <ERROR>: unrecognized status -67023 from codesigning library
installd: +[MICodeSigningVerifier _validateSignatureAndCopyInfoForURL:...]: 80: Failed to verify code signature of .../LiveContainer.app : 0xe8008001 (An unknown error has occurred.)
installcoordinationd: "This app was not installed because its integrity could not be verified."

3. Signed artifact inspection (pulled from Documents/Signed/<UUID>/LiveContainer.app)

  • The main executable LiveContainer is byte-identical to the one in the original IPA:
SHA-256 (device "signed" binary): 12ab0e9a4222a904e067c49a4e253f1e0b2c963cb97bd67b02df5b2a56d47f21
SHA-256 (original IPA binary):    12ab0e9a4222a904e067c49a4e253f1e0b2c963cb97bd67b02df5b2a56d47f21
  • codesign -dvvv on the pulled binary shows the original ad-hoc signature was never replaced:
Format=Mach-O thin (arm64)
CodeDirectory v=20400 flags=0x2(adhoc)
Signature=adhoc
TeamIdentifier=not set
Sealed Resources=none
  • The bundle has no _CodeSignature directory (Feather removes it before signing and zsign never regenerated it).
  • embedded.mobileprovision was written (LiveContainer Development, App ID com.zhelearn.livecontainer), so zsign got past initialization and profile embedding, then failed before generating the code signature.

4. Source analysis

  • ZsignHandler.swift ignores the Bool returned by Zsign.sign(...) and only stores the completion error:
let _ = Zsign.sign(
    appPath: _appUrl.relativePath,
    provisionPath: ...,
    p12Path: ...,
    p12Password: ...,
    entitlementsPath: _options.appEntitlementsFile?.path ?? "",
    removeProvision: !_options.removeProvisioning,
    completion: { _, error in
        self.hadError = error
    }
)

When zsign fails in a path that does not populate the completion error, hadError stays nil and Feather continues as if signing succeeded.

var files = [
    "_CodeSignature", // Fallbaccck for some reason the locate doesnt work
    "embedded.mobileprovision", // Remove this because zsign doesn't replace it
    ...
]

This is expected pre-sign state; the bug is that zsign never writes a new _CodeSignature.

  • Feather's Zsign submodule is pinned at 6ffe703 (zsign 0.7). Its ReallocCodeSignSpace only adds a 16K buffer:
uint32_t uNewLength = m_uCodeLength + ZUtil::ByteAlign(((m_uCodeLength / 4096) + 1) * (20 + 32), 4096) + 16384; //16K May Be Enough
  • Upstream zsign already has a fix for this: fix: increase ReallocCodeSignSpace buffer from 16K to 32K (commit 252ef7b). The same failure reproduces locally with the same zsign 0.7 source (need: 25009 on the Mac vs 24991 on the device).

Comparison: official zsign vs bundled zsign

Both runs used the same LiveContainer 3.8.0 IPA, the same custom entitlements file, and a LiveContainer Development profile for the same App ID (com.zhelearn.livecontainer).

Official zsign v1.1.2 (Homebrew, macOS) — Signed OK

>>> Unzip:  LiveContainer.ipa (4.49 MB) -> /tmp/zsign_folder_... ...
>>> Unzip OK!
>>> BundleId:   com.kdt.livecontainer -> com.zhelearn.livecontainer
>>> BundleId:   com.kdt.livecontainer.LiveProcess -> com.zhelearn.livecontainer.LiveProcess, Plugin
>>> BundleId:   com.kdt.livecontainer.ShareExtension -> com.zhelearn.livecontainer.ShareExtension, Plugin
>>> BundleId:   com.kdt.livecontainer.LaunchAppExtension -> com.zhelearn.livecontainer.LaunchAppExtension, Plugin
>>> Signing:    /tmp/zsign_folder_.../Payload/LiveContainer.app ...
>>> AppName:    LiveContainer
>>> BundleId:   com.zhelearn.livecontainer
>>> Version:    3.8.0
>>> TeamId:     [REDACTED]
>>> SubjectCN:  [REDACTED]
>>> ReadCache:  NO
>>> SignFile:   LiveContainer
>>> SignFile:   PlugIns/LiveProcess.appex/LiveProcess
>>> SignFile:   PlugIns/ShareExtension.appex/ShareExtension
>>> No enough CodeSignature space (now: 19520, need: 23162).
>>> Realloc CodeSignature space...
>>> Success!
>>> SignFile:   PlugIns/LaunchAppExtension.appex/LaunchAppExtension
>>> No enough CodeSignature space (now: 19104, need: 21602).
>>> Realloc CodeSignature space...
>>> Success!
>>> SignFile:   Frameworks/OpenSSL.framework/OpenSSL
>>> No enough CodeSignature space (now: 26832, need: 39661).
>>> Realloc CodeSignature space...
>>> Success!
>>> SignFile:   Frameworks/TestJITLess.dylib
>>> Can't find CodeSignature segment!
>>> Realloc CodeSignature space...
>>> Success!
>>> SignFile:   Frameworks/ZSign.dylib
>>> SignFile:   Frameworks/CydiaSubstrate.framework/CydiaSubstrate
>>> SignFile:   Frameworks/LiveContainerShared.framework/LiveContainerShared
>>> SignFile:   Frameworks/TweakLoader.dylib
>>> SignFile:   Frameworks/LiveContainerSwiftUI.framework/LiveContainerSwiftUI
>>> No enough CodeSignature space (now: 24096, need: 28774).
>>> Realloc CodeSignature space...
>>> Success!
>>> SignFolder: PlugIns/LiveProcess.appex, (LiveProcess)
>>> SignFolder: PlugIns/ShareExtension.appex, (ShareExtension)
>>> SignFolder: PlugIns/LaunchAppExtension.appex, (LaunchAppExtension)
>>> SignFolder: Frameworks/OpenSSL.framework, (OpenSSL)
>>> SignFolder: Frameworks/CydiaSubstrate.framework, (CydiaSubstrate)
>>> SignFolder: Frameworks/LiveContainerShared.framework, (LiveContainerShared)
>>> SignFolder: Frameworks/LiveContainerSwiftUI.framework, (LiveContainerSwiftUI)
>>> SignFolder: LiveContainer.app, (LiveContainer)
>>> Signed OK! (0.050s, 50362us)
>>> Archiving:  LiveContainer-3.8.0-signed.ipa ...
>>> Archive OK! (10.70 MB)
>>> Done.

Bundled zsign v0.7 (Feather submodule 6ffe703, captured on device via Feather) — Signed Failed

Key lines (full log in Evidence 1):

>>> SignFolder: PlugIns/ShareExtension.appex, (ShareExtension)
>>> No enough CodeSignature space (now: 19520, need: 24991).
>>> Realloc CodeSignature space...
>>> Success!
>>> No enough CodeSignature space (now: 20480, need: 24991).
>>> Signed Failed! (0.023s, 23424us)

The official zsign (v1.1.2, which includes the 16K→32K ReallocCodeSignSpace fix) signs the same app successfully, while the bundled zsign (v0.7, submodule 6ffe703) fails on the same ShareExtension.appex because the reallocated space (20480) is still smaller than needed (24991).

Root cause

  1. zsign 0.7 cannot allocate enough CodeSignature space for ShareExtension.appex when the large custom entitlements file is applied → Signed Failed!.
  2. Feather ignores the zsign failure (the Bool return is discarded and no completion error is produced), so the unsigned bundle is treated as successfully signed.
  3. The resulting bundle has no valid code signature (_CodeSignature missing, binary still ad-hoc from the original IPA), so installd rejects it with 0xe8008001.

Request Agreement

  • I have read the requirements for opening an issue above

Contributor Checks

  • I am willing to attempt to make a pull request to fix this bug

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions