Strip Bitcode
| Plan | Platforms | MASVS |
|---|---|---|
| Team | iOS | MASVS-RESILIENCE-3 |
Overview
Strip Bitcode removes embedded LLVM bitcode segments from compiled iOS binaries during the application build process. Bitcode is an intermediate representation (LLVM IR) that Apple used to enable App Store-side re-optimization of binaries for different device architectures. However, bitcode segments are trivially decompilable to near-source-quality code, dramatically increase binary size (often 2-4x), and serve no purpose for side-loaded or enterprise-distributed applications.
This control automatically scans all Mach-O binaries in the application bundle (main executable, frameworks, extensions) and removes the __LLVM segment using binary parsing and modification techniques. The result is a smaller, more secure binary that cannot be easily reverse-engineered through its bitcode representation.
Note: Apple deprecated bitcode in Xcode 14 (released September 2022) and no longer accepts bitcode submissions to the App Store. This control primarily serves as a defensive measure for applications built with legacy Xcode versions or that bundle third-party frameworks compiled with older toolchains.
How It Works
The control operates during the iOS application build pipeline after compilation and code signing, but before final packaging:
- Binary Discovery: The build system scans the extracted
.appbundle to locate all Mach-O binaries:
- Main executable (
AppName.app/AppName) - Embedded frameworks (
Frameworks/*.framework/<name>) - Dynamic libraries (
Frameworks/*.dylib) - App extensions (
PlugIns/*.appex/<name>)
- Bitcode Detection: Each binary is parsed as a Mach-O file (handling both thin and universal/fat binaries). The parser inspects load commands to identify the
__LLVMsegment, which contains:
__bundle: LLVM bitcode IR in a proprietary wrapper format__bitcode: Additional metadata for App Store re-compilation__cmdline: Original compiler command-line arguments
- Segment Removal: When bitcode is detected:
- All sections within the
__LLVMsegment are removed from the binary's section table - The segment's file size and virtual size are zeroed
- Segment content is overwritten with null bytes to reclaim disk space
- Load commands and offsets are adjusted to maintain binary integrity
- Binary Rewriting: The modified binary is written back to disk, replacing the original file. The tool preserves:
- Code signing (must be re-signed after this operation)
- All other segments and sections (executable code, data, resources)
- Fat binary architecture slices (each slice is processed independently)
- Size Optimization: Stripping bitcode typically reduces binary size by 50-75%, as the LLVM IR representation is verbose and includes metadata not present in the final machine code.
The control uses the LIEF (Library to Instrument Executable Formats) library for safe, cross-platform Mach-O binary manipulation.
Threats Mitigated
- Intermediate Representation Reverse Engineering: Bitcode contains LLVM IR, which is a high-level intermediate representation that decompiles to pseudo-C code far more readable than native ARM assembly. Removing bitcode eliminates this attack surface entirely.
- Algorithm Disclosure: LLVM IR preserves function names, control flow structures, and type information that may reveal proprietary algorithms, business logic, or cryptographic implementations.
- Binary Size Bloat: Large binaries increase distribution costs, download times, and on-device storage requirements. Stripping bitcode can reduce app size by hundreds of megabytes for complex applications.
- Metadata Leakage: The
__cmdlinesection contains the exact compiler command line used to build the app, potentially revealing internal build paths, developer usernames, or proprietary compiler flags.
Use Cases
- Applications built with Xcode 13 or earlier that have bitcode enabled (
ENABLE_BITCODE = YES) - Apps bundling third-party frameworks or SDKs compiled with older toolchains that include bitcode
- Enterprise or side-loaded applications that bypass the App Store and want to minimize reverse engineering risk
- Applications aiming to reduce binary size for faster downloads and reduced storage footprint
- Security-sensitive applications that must eliminate all non-essential binary metadata
Caveats
Apple Deprecated Bitcode (Xcode 14+)
As of Xcode 14 (September 2022), Apple no longer supports bitcode submission to the App Store. New projects have ENABLE_BITCODE set to NO by default. This control is primarily relevant for:
- Legacy applications maintained with Xcode 13 or earlier
- Third-party frameworks/SDKs that were pre-compiled with bitcode
- Historical builds that require bitcode stripping for security audits
For modern projects, this control may be a no-op if binaries contain no __LLVM segment.
Re-Signing Required
Stripping bitcode modifies the binary's load commands and segment structure, which invalidates the code signature. The build pipeline automatically re-signs the application after obfuscation controls are applied, but manual builds must ensure code signing occurs after bitcode stripping.
LIEF Library Dependency
The control requires the LIEF Python library (pip install lief). If LIEF is not installed in the build environment, the control will log an error and skip bitcode stripping. The build process will continue without failure.
Universal Binaries
Fat binaries (containing multiple architecture slices, e.g., arm64 and armv7) are processed correctly. Each slice is independently parsed and stripped. This ensures compatibility with universal frameworks targeting multiple device generations.
Support Matrix
| Platform | Minimum Version | Status |
|---|---|---|
| iOS | 9.0+ | ✅ Supported (for legacy bitcode binaries) |
Xcode Version Notes:
- Xcode 13 and earlier: Bitcode is optional (
ENABLE_BITCODEdefault varies by project age) - Xcode 14+: Bitcode is disabled and deprecated; this control strips residual bitcode from bundled frameworks only
How to Enable the Control
Navigate to Code Obfuscation from the AppTego portal, and expand the Metadata Reduction section. Under this section you will find the Strip Bitcode control. Click Enable to apply it to the next protected build.
API Configuration Example
{
"StripBitcode": {
"protection": true
}
}
protection: true— Remove__LLVMbitcode segments from all binaries in the app bundle (recommended for legacy builds)protection: false— No bitcode stripping; binaries retain original__LLVMsegments
Default Behavior: If the control is not present in the configuration, bitcode is not stripped (opt-in control).
Related Controls
- StripDebugSymbols — Removes DWARF debugging symbols and symbol tables to prevent function/variable name disclosure
- ObfuscateClassNames — Replaces Objective-C class names with randomized strings to hinder static analysis
- EncryptStrings — Protects string literals from plain-text disclosure in the binary