/

Constant Mutation

Protection ID: constantMutation

Constant Mutation transforms numeric constants in your bytecode into equivalent arithmetic expressions. A simple int timeout = 30000 becomes a chain of operations that evaluates to the same value at runtime, preventing attackers from searching for known values.


Configuration

Groovy
shield {
    protections {
        constantMutation = true
    }
}

How It Works

Constant mutation replaces numeric literals in your code (integers, longs, doubles, and other numeric types) with arithmetic expressions that evaluate to the same value at runtime. This prevents attackers from identifying important values like buffer sizes, timeouts, retry limits, error codes, and other magic numbers during static analysis.

The protection decomposes each constant into a chain of randomly selected operations, so the same value produces different expressions on each build. This makes it impractical to write a pattern-based tool to recover the original values.

Before Shield

Java
private static final int MAX_RETRIES = 3;
private static final long TIMEOUT_MS = 30000L;
private static final int BUFFER_SIZE = 4096;

After Shield

Java
private static final int MAX_RETRIES = ((7 ^ 4) - (12 >> 2)) + ((~(-5)) - 1);
private static final long TIMEOUT_MS = ((16384L * 2) - (1024 << 1)) + (((~(-769L))));
private static final int BUFFER_SIZE = (2048 << 1) ^ (0);

Each constant is transformed using a different combination of operations, so patterns cannot be generalized.


Operation Categories

Shield uses 43 operations across 6 categories to transform constants:

CategoryOperationsExample
ArithmeticAdd, subtract, multiply, divide, remainder(15 * 2) + 1
ConditionalInline conditionals, comparisons(x == x) ? 31 : 0
LogicalAND, OR, XOR, NOT(0xFF ^ 0xE0)
ShiftLeft shift, right shift, unsigned right shift(1 << 12)
ConversionType casts between numeric types(int)(30000.0)
MixedChained operations from multiple categories((7 ^ 4) - (12 >> 2))

Operations are chained: a single constant may be decomposed into 3 to 6 nested operations, each randomly selected.


Excluding Constants

Use the @Exclude annotation to skip constant mutation for specific elements:

Java
import com.bytehide.shield.annotations.Exclude;

@Exclude(protections = {"ConstantMutation"})
public class MathConstants {
    public static final double PI = 3.14159265358979;
    public static final double E = 2.71828182845904;
}

Performance Impact

Constant mutation adds negligible runtime overhead. The arithmetic expressions are evaluated by the JVM at load time or JIT-compiled to the original constant value. The cost is primarily in bytecode size, not execution speed.


When to Use

Constant mutation is recommended for all production builds. It is especially useful for applications that use magic numbers for license validation, timeout or retry values that reveal server behavior, error codes that map to internal states, buffer sizes and limits that reveal implementation details, or any numeric values that could aid reverse engineering.


Previous
String Encryption