All notable changes to this de4dotEx fork are documented here.
## [3.9.0-loxyB4A] - 2026-07-31
Adds support for newer **.NET Reactor** builds seen on .NET 10 assemblies (e.g. ABP Studio 3.0.8),
which the previous release could not fully process.
### Added
- **Split-method keystream string decryption (`DecrypterV5`).**
Newer .NET Reactor splits string decryption across methods: the `string Decrypt(int)` entry method
holds no key and only reads an already-decrypted blob, while a helper method it calls holds the
32-byte key + 16-byte IV and a leaf PRNG "magic" method. The resource key extraction now follows the
entry method's callees to that helper, extracts the key/IV (robust to up-front array allocation and
per-index overwrite obfuscation), and decrypts using the V2 `isNewDecrypter` keystream with the magic
method **emulated** (so per-build PRNG constants need no hardcoding).
- **Constant opaque-predicate folding during key extraction.**
When the key is guarded by boolean-decrypter predicates and by parameterless "always returns a
constant" methods (e.g. `… ldnull; ldnull; ceq; ret` ⇒ always true) that Reactor's cflow does not
fold, a stronger per-method pass (`DeepDeobfuscateMethod`) folds those predicates — recursively
cleaning + emulating each callee — so the guarding branches collapse and the key becomes extractable.
The boolean decrypter/inliner is now initialized before string decryption so it is available for this.
- **Never-written-field opaque-predicate folding & removal (`--dr4-fold-predicates`, default on).**
Reactor injects, per class, a self-typed static field plus a `static bool M() => field == null;`
predicate threaded through control flow. The backing field is written only by anti-tamper init that
de4dot removes, so post-deobfuscation it is never written and the predicate is a permanent constant.
A whole-assembly pass now:
- computes the set of static fields never targeted by `stsfld`,
- folds `field == null/!= null` predicates over those fields to their constant, letting cflow
collapse the fake branches, and
- removes the dead predicate methods and never-written state fields, but only when non-public,
provably constant, and unreferenced anywhere (Call/Callvirt/Ldftn checked).
Disable with `--dr4-fold-predicates false`.
### Fixed
- **`CflowConstantsInliner` no longer corrupts exception handlers / branch targets.**
`InlineAllConstants` replaced whole `Instruction` objects (`instrs = Instruction.CreateLdcI4(…)`),
so when the original `ldsfld`/`ldfld` was an exception-handler boundary (`HandlerEnd`) or branch
target, that reference was left pointing at a detached instruction and `InstructionListParser` threw
`KeyNotFoundException`, crashing deobfuscation of the whole assembly. The constant is now written in
place (`OpCode`/`Operand`), preserving instruction identity.
### Notes
- Validated on ABP Studio 3.0.8 (51 .NET Reactor DLLs): **51/51 deobfuscate + save with no crash and
no string-key failure** (previously one crashed and all failed string decryption). Public API surface
is byte-identical with `--dr4-fold-predicates` off vs on, confirming only obfuscator plumbing is
removed.
## [3.8.0] - prior
Base de4dotEx release (upstream de4dot + G DATA Advanced Analytics enhancements).