Overview
When Refractor obfuscates your code, it renames classes, methods, and fields to short, meaningless identifiers. The symbol map preserves the original names so you can:- Deobfuscate stack traces from production builds
- Debug obfuscated binaries by translating error messages
- Understand crash reports with obfuscated symbols
Configuration
Specify the output path inrefractor.yaml:
symbol_map.json (current directory)
File Format
The symbol map is a JSON object with obfuscated names as keys and original names as values.Structure
- Pretty-printed with 2-space indentation
- UTF-8 encoded
- Key: Obfuscated identifier (short name)
- Value: Original identifier (full name)
Example Output
For a simple Dart application:What Gets Mapped?
The symbol map includes:Classes
All project class names renamed by the
rename passMethods
Instance methods, static methods, and functions
Fields
Instance fields, static fields, and top-level variables
Properties
Getters and setters (if renamed)
The symbol map only includes renamed symbols. If
preserve_main: true, the main() function won’t appear in the map.Using the Symbol Map
Deobfuscating Stack Traces
When your obfuscated app crashes, stack traces contain obfuscated names:- Load
refractor_map.json - Look up
a→PaymentService - Look up
b→processPayment - Look up
d→Logger - Look up
e→log
Manual Lookup
You can parse the JSON in any language:Reverse Lookup
To find the obfuscated name for an original identifier:File Location
The symbol map is written to the path specified in your configuration:- Parent directories are created automatically if they don’t exist
- Existing files are overwritten
- Relative paths are resolved from the working directory
Recommended Locations
Build directory
Store alongside compiled output:✅ Keeps maps with their corresponding builds
✅ Easy to clean with
✅ Easy to clean with
rm -rf build/Version-specific path
Include version numbers for multiple releases:✅ Track maps across versions
✅ Deobfuscate old crash reports
✅ Deobfuscate old crash reports
Security Best Practices
Do:
- ✅ Add
symbol_map.jsonto.gitignore - ✅ Store maps in secure, access-controlled locations
- ✅ Use version-specific filenames (
map_v1.2.3.json) - ✅ Encrypt symbol maps at rest
- ✅ Include maps in secure backup systems
Don’t:
- ❌ Commit symbol maps to version control
- ❌ Include maps in app bundles or containers
- ❌ Store maps in public cloud storage
- ❌ Share maps in public issue trackers
- ❌ Embed map contents in source code
When Symbol Maps Are Generated
Refractor writes the symbol map during therefractor build command:
Build Output
Implementation Details
The symbol map is generated by theSymbolTable class:
Source: lib/src/engine/symbol_table.dart
Source: lib/src/engine/symbol_table.dart
/home/daytona/workspace/source/lib/src/engine/symbol_table.dart:1Troubleshooting
Symbol map is empty
Symbol map is empty
Cause: No symbols were renamed (rename pass disabled or no project libraries).Fix: Enable the
rename pass:Symbol map not created
Symbol map not created
Cause: Output directory doesn’t exist or insufficient permissions.Fix: Ensure parent directories exist and are writable. Refractor creates them automatically, but check file permissions.
Can't find original name
Can't find original name
Cause: The identifier wasn’t renamed (preserved, external, or excluded).Fix: Check if the symbol is from:
- External packages (never renamed)
- Excluded files (
refractor.exclude) - Preserved functions (
preserve_main: true)
Related Pages
refractor.yaml
Configure symbol map path and passes
Rename Pass
Learn how symbol renaming works