Goal
Make every ConfuserEx build and every obfuscation run produce unique output that cannot be identified by generic deobfuscation tools or AV heuristics. Two levels of uniqueness that stack for maximum stealth.
The Problem
Every ConfuserEx-obfuscated assembly carries identical fingerprints — same namespace (System.Core.Internal), same magic constants (0x3dbb2819), same watermark (ProtectedByAttribute), same algorithm patterns. Tools like de4dot pattern-match these known values. AV heuristics flag the same byte sequences. Every user's output looks identical.
The Solution: Two-Level Uniqueness
Level 1 — Source Identity Script (uniquify.py)
A setup script that makes your ConfuserEx build unrecognizable as ConfuserEx. Run once per environment.
Targets:
| Fingerprint |
Default Value |
Randomized |
| Runtime namespace |
System.Core.Internal |
Derived from seed |
| Runtime type names |
Constant, Resource, Compressor, etc. |
Derived from seed |
| Runtime DLL name |
System.Core.Runtime.dll |
Derived from seed |
| Product string |
"Protected" |
User's choice |
| Default magic constants |
0x3dbb2819, 0x3ddb2819, etc. |
Derived from seed |
| Process name checks |
"dnspy" |
Expanded/obfuscated |
| Watermark attribute name |
ProtectedByAttribute |
User's choice or random |
Script features:
--seed "phrase" — deterministic, reproducible
--dry-run — show changes without modifying
--test — build + run tests after modification
--restore — revert to defaults
Level 2 — Per-Project Obfuscation Identity (runtime)
Randomize cryptographic constants per obfuscation run. Works on stock or script-customized builds.
Targets:
| Fingerprint |
Current |
After |
| Anti-tamper feedback constant |
0x3dbb2819 hardcoded |
Derived from project seed |
| Compressor feedback constant |
0x3ddb2819 hardcoded |
Derived from project seed |
| Hash constants |
0x6fff61 / 0x5e3f1f hardcoded |
Derived from project seed |
| CFGCtx multiplier |
0x21412321 hardcoded |
Derived from project seed |
| XorShift parameters |
12/25/27 hardcoded |
Picked from valid set per seed |
| Prime moduli |
0x143fc089 etc. hardcoded |
Picked from valid prime set per seed |
Implementation: Convert hardcoded constants to Mutation.KeyI* placeholders. The MutationHelper system already injects per-run values — minimal new infrastructure needed.
Watermark Configurability
Currently hardcoded (always on or off via source edit). Should be project-level:
<!-- Disable watermark -->
<protection id="watermark" action="remove" />
<!-- Custom watermark -->
<protection id="watermark">
<argument name="text" value="MyCompany Security" />
<argument name="attributeName" value="SecurityStampAttribute" />
</protection>
Default: off (no fingerprint unless explicitly enabled).
How The Levels Stack
| Setup |
de4dot |
AV heuristics |
Per-project analysis |
| Stock ConfuserEx |
Works |
Flags it |
Easy |
| Level 2 only |
Constant matching fails |
Reduced |
Needed per project |
| Level 1 only |
Name detection fails |
Fails |
Harder |
| Level 1 + Level 2 |
Completely fails |
Fails |
Needs reverse engineering per build AND per project |
Out of Scope (Hard Fingerprints)
These require architectural redesign, not randomization:
- JIT hook technique (hooking
ICorJitCompiler::compileMethod)
- Anti-dump PE header zeroing behavior
- LZMA decompressor algorithm structure
- Reference proxy DynamicMethod architecture
Documented for awareness but not part of this feature.
Implementation Order
- Watermark configurability — quick win, project-level on/off with custom text
- Level 2 — convert magic constants to mutation keys, per-run randomization
- Level 1 — the
uniquify.py script for source-level identity change
Related Issues
Goal
Make every ConfuserEx build and every obfuscation run produce unique output that cannot be identified by generic deobfuscation tools or AV heuristics. Two levels of uniqueness that stack for maximum stealth.
The Problem
Every ConfuserEx-obfuscated assembly carries identical fingerprints — same namespace (
System.Core.Internal), same magic constants (0x3dbb2819), same watermark (ProtectedByAttribute), same algorithm patterns. Tools like de4dot pattern-match these known values. AV heuristics flag the same byte sequences. Every user's output looks identical.The Solution: Two-Level Uniqueness
Level 1 — Source Identity Script (
uniquify.py)A setup script that makes your ConfuserEx build unrecognizable as ConfuserEx. Run once per environment.
Targets:
System.Core.InternalConstant,Resource,Compressor, etc.System.Core.Runtime.dll"Protected"0x3dbb2819,0x3ddb2819, etc."dnspy"ProtectedByAttributeScript features:
--seed "phrase"— deterministic, reproducible--dry-run— show changes without modifying--test— build + run tests after modification--restore— revert to defaultsLevel 2 — Per-Project Obfuscation Identity (runtime)
Randomize cryptographic constants per obfuscation run. Works on stock or script-customized builds.
Targets:
0x3dbb2819hardcoded0x3ddb2819hardcoded0x6fff61/0x5e3f1fhardcoded0x21412321hardcoded12/25/27hardcoded0x143fc089etc. hardcodedImplementation: Convert hardcoded constants to
Mutation.KeyI*placeholders. TheMutationHelpersystem already injects per-run values — minimal new infrastructure needed.Watermark Configurability
Currently hardcoded (always on or off via source edit). Should be project-level:
Default: off (no fingerprint unless explicitly enabled).
How The Levels Stack
Out of Scope (Hard Fingerprints)
These require architectural redesign, not randomization:
ICorJitCompiler::compileMethod)Documented for awareness but not part of this feature.
Implementation Order
uniquify.pyscript for source-level identity changeRelated Issues