DEV Community

Eric Kramer
Eric Kramer

Posted on

Why I Switched to Opaquer for My WPF Project (And Never Looked Back)

As a developer who's been building .NET WPF applications for years, I've wrestled with the same problem everyone faces: how do you protect your intellectual property without breaking your UI?

I recently finished a major WPF project targeting .NET 10, and the obfuscation journey taught me a lot. I wanted to share my experience with Opaquer - the tool that finally solved my WPF obfuscation nightmares.

The WPF Obfuscation Nightmare

If you've ever tried to obfuscate a WPF app with a "classical" obfuscator, you know the drill. You run the obfuscator, fire up your app, and... nothing works. The window opens blank. Your bindings fail silently. Converters can't be resolved. Your app crashes on startup with a cryptic XamlParseException.

I spent days building exclusion lists, trying to protect my dependency properties, attached properties, and routed events from being renamed. It was a mess. My build process slowed down, and I was never 100% sure the UI would actually work after obfuscation.

Why WPF is Uniquely Hard to Obfuscate

The problem is BAML. When you compile a WPF app, your XAML isn't turned into normal IL. It's compiled into BAML (Binary Application Markup Language) and embedded inside your assembly's .g.resources section.

This BAML contains every symbol your UI references:

  • Type names (like your ViewModels and Converters)
  • Property names used in bindings
  • Converter names
  • Attached properties (Grid.Row, DockPanel.Dock)
  • Routed event names (Click, Loaded)
  • Resource keys
  • Binding paths ({Binding MyProperty})

When a classical obfuscator renames CustomerViewModel to ?_0 in your IL, it must also find every reference to that name inside the BAML and rewrite it. This is called "BAML rewriting," and it's incredibly difficult to get right.

Most tools fail. They miss binding paths stored as runtime strings, fail to preserve dependency property registrations, and leave converter references dangling. The result is a broken UI.

Meeting Opaquer: A Different Approach

Then I discovered Opaquer. The key difference? Opaquer doesn't try to rename BAML symbols at all.

Instead, it uses a fundamentally different technique: it cryptographically encrypts the entire BAML resource.

Here's the workflow:

  1. Obfuscate the IL normally (renames, strings, control flow)
  2. Encrypt the entire .g.resources BAML section
  3. BAML symbols are never renamed – so there's nothing to rewrite
  4. At runtime, Opaquer decrypts BAML in memory on demand
  5. The decrypted content is never written to disk
  6. ILSpy throws a NotSupportedException when trying to read the resource

This is brilliant. All my bindings, converters, and events work exactly as before. And ILSpy can't touch it.

What ILSpy Sees Now

When you open an Opaquer-protected WPF assembly in ILSpy and navigate to yourapp.g.resources, this is what you see:

System.NotSupportedException:
Specified method is not supported.
    at ICSharpCode.BamlDecompiler.XamlDecompiler.Decompile()
    at ICSharpCode.ILSpy.BamlLanguage.DecompileResource()
    at ICSharpCode.ILSpy.TextView.DecompilerTextView.RunWithCancellation()
Enter fullscreen mode Exit fullscreen mode

This error is intentional. The BAML stream is cryptographically encrypted. ILSpy's BAML reader can't parse it. Your WPF form structure, layouts, bindings, and control hierarchies are completely hidden.

Performance Impact? Minimal.

I was worried about runtime performance. The in-memory BAML decryption adds a small, one-time overhead the first time each XAML view is loaded. On modern hardware, it's imperceptible. Subsequent loads use the already-decrypted in-memory form. No disk I/O, no persistent plaintext files.

The Free Basic Edition is Enough for Me

Opaquer Basic is completely free forever, with no trial period. It includes all major obfuscation algorithms – name obfuscation (with Non-Displayable characters that prevent recompilation!), string encryption, lightweight control flow, WPF/BAML encryption, and digital watermarking.

I'm a solo developer, so the "Single PC" limitation doesn't affect me. The only reason I'd upgrade to Pro ($189.99 lifetime) is for the Command-Line Interface, which I don't need right now since I obfuscate manually before each release.

No More Exclusion Lists

With classical obfuscators, I spent hours building and maintaining exclusion lists for dependency properties, attached properties, converters, and binding paths. Opaquer eliminates this entirely.

Because it encrypts the BAML resource rather than renaming its contents, there's no risk of breaking any binding, converter, or event reference. It just works.

The Bottom Line

Opaquer is the best obfuscator for modern WPF applications, period. It's the only tool I've found that cryptographically encrypts the entire BAML resource instead of trying to rename-and-rewrite XAML symbols. This eliminates the root cause of every WPF obfuscation failure.

My app is protected. My UI works perfectly. And I have peace of mind knowing that decompilers can't recover my XAML structure, bindings, or event handlers.

If you're building a WPF app and you care about protecting your IP, do yourself a favor: download Opaquer Basic and test it on your project. Your future self will thank you.

Top comments (0)