Debug Removal
Protection ID: debugRemoval
Debug Removal strips debug metadata from your compiled bytecode, removing line numbers, local variable names, and source file references. This makes decompiled code harder to read and prevents attackers from correlating bytecode with your original source files.
Configuration
shield {
protections {
debugRemoval = true
}
}shield {
protections {
debugRemoval = true
}
}How It Works
Debug removal eliminates all debug-related metadata that the Java compiler embeds in your .class files. This metadata is useful during development (for stack traces and debugger variable inspection) but in production it provides a roadmap for reverse engineers to understand your code structure.
The protection removes line number tables, local variable names, and source file references from every class, making decompiled output significantly harder to follow.
What Gets Removed
| Metadata | Effect When Removed |
|---|---|
| Line numbers | Decompilers cannot show original line numbers |
| Variable names | Local variables appear as var0, var1, etc. |
| Source file | Source filename is removed from class metadata |
Before Shield
// Decompiled with line numbers and variable names
public void processOrder(Order order) { // line 42
String customerId = order.getCustomerId(); // line 43
double total = order.calculateTotal(); // line 44
paymentService.charge(customerId, total); // line 45
}// Decompiled with line numbers and variable names
public void processOrder(Order order) { // line 42
String customerId = order.getCustomerId(); // line 43
double total = order.calculateTotal(); // line 44
paymentService.charge(customerId, total); // line 45
}After Shield
// Decompiled without debug info
public void processOrder(Order var1) {
String var2 = var1.getCustomerId();
double var3 = var1.calculateTotal();
paymentService.charge(var2, var3);
}// Decompiled without debug info
public void processOrder(Order var1) {
String var2 = var1.getCustomerId();
double var3 = var1.calculateTotal();
paymentService.charge(var2, var3);
}Impact on Stack Traces
With debug info removed, stack traces no longer include line numbers:
// Before
java.lang.NullPointerException
at com.example.OrderService.processOrder(OrderService.java:44)
// After
java.lang.NullPointerException
at com.example.OrderService.processOrder(Unknown Source)// Before
java.lang.NullPointerException
at com.example.OrderService.processOrder(OrderService.java:44)
// After
java.lang.NullPointerException
at com.example.OrderService.processOrder(Unknown Source)To recover line numbers in production crash reports, use Shield's mapping files with your crash reporting tool.
Excluding from Debug Removal
import com.bytehide.shield.annotations.Exclude;
@Exclude(protections = {"DebugInfoRemoval"})
public class DiagnosticService {
// Debug info preserved for this class
}import com.bytehide.shield.annotations.Exclude;
@Exclude(protections = {"DebugInfoRemoval"})
public class DiagnosticService {
// Debug info preserved for this class
}When to Use
Debug Removal is one of the safest protections to enable. It has zero runtime performance impact (metadata is only used by debuggers and decompilers) and reduces APK size slightly. It is recommended for all production builds.
Related
- Name Obfuscation - Rename identifiers
- Mapping Files - Recover original stack traces
- Protections Overview - All available protections