Opaque Predicates
Protection ID: opaque_predicates
Opaque Predicates inserts conditional branches into your application where the outcome is predetermined but difficult to determine through static analysis. Decompilers must treat both branches as potentially reachable, increasing the complexity of the decompiled output.
Configuration
{
"protections": {
"opaque_predicates": "medium"
}
}{
"protections": {
"opaque_predicates": "medium"
}
}Available levels: "simple", "medium", "complex".
How It Works
A predicate is a condition that evaluates to true or false. An opaque predicate is a condition that always evaluates to the same result at runtime, but this cannot be easily determined by analyzing the binary statically.
For example, a condition based on a mathematical property that is always true will always take the same branch at runtime, but a static analyzer cannot prove this without solving the underlying mathematical problem. The analyzer must conservatively assume both branches are reachable, effectively doubling the amount of code it needs to consider.
When combined with Dead Code Injection, opaque predicates guard the injected paths, making it even harder to distinguish real code from noise.
Intensity Levels
| Level | Description |
|---|---|
simple | Basic predicates that defeat simple analysis |
medium | More complex conditions using mathematical and logical properties |
complex | Highly resistant predicates that require advanced symbolic analysis to resolve |
When to Use
Opaque Predicates are most effective when combined with other code obfuscation protections. They complement Control Flow Obfuscation by making it harder to simplify the obfuscated flow, and Dead Code Injection by guarding injected paths with conditions that appear real.
Related
- Control Flow Obfuscation - Restructure method logic
- Dead Code Injection - Insert unreachable code paths
- Protections Overview - All available protections