Skip to main content

.NET Reactor Code Protection Guide

This document describes the .NET Reactor three-tier protection strategy, exclusion lists, and packaging pipeline integration for GST projects. Currently applied to ProcessVision, with potential future expansion to Jope-SMB.

1. Three-Tier Protection Strategy

1.1 Strategy Overview

TierTargetProtection LevelApplicable Assemblies
MaxLicensing coreHighestGST.Core.Licensing
StandardBusiness logicBalancedGST.Core.*, GST.Protocols.*, GST.Plugin.*
LightInterfaces/UILowestGST.Core.Abstractions, GST.Core.Aspects, GST.UI.*

1.2 Protection Parameter Comparison

SettingLightStandardMax
NecroBit (IL → Native)-
NecroBit Reflection Mode--
Anti-Debug
Anti-ILDASM
Exclude Enums-
Exclude Methods--
Exclude Properties-
Remove Enum Fields--
Licensing / Hardware Lock--

2. Detailed Tier Descriptions

2.1 Max — Highest Protection

Profile: GSTProtection-Max.nrproj Applicable Assembly: GST.Core.Licensing

NecroBit = true(IL 完全轉換為 Native Code,移除所有 IL Metadata)
NecroBit Reflection Mode = false(停用 Reflection 相容性,最大化混淆)
Anti-Debug = true
Anti-ILDASM = true
Obfuscate_All_Method_Parameters = true
Remove_Enum_Fields = true
License_Hardware_Lock_Enabled = true(支援機台綁定)

Design Rationale: License validation is the most critical intellectual property and must be protected to the maximum extent against decompilation.

2.2 Standard — Balanced Protection

Profile: GSTProtection-Standard.nrproj Applicable Assemblies:

  • GST.Core.* (Core modules, excluding Abstractions, Aspects, Licensing, Localization)
  • GST.Protocols.* (Communication protocols)
  • GST.Plugin.* (Plugin framework, excluding DataLogging, RecipeManagement)
NecroBit = true(IL → Native)
NecroBit Reflection Mode = true(保留 Reflection 相容性,支援 DI/IoC)
Anti-Debug = true
Anti-ILDASM = true
Licensing = false

Design Rationale: Business logic needs protection, but Reflection must be preserved to support DI Containers and dynamic Plugin loading.

2.3 Light — Lowest Protection

Profile: GSTProtection-Light.nrproj Applicable Assemblies:

  • GST.Core.Abstractions (Interface definitions)
  • GST.Core.Aspects (Metalama AOP)
  • GST.UI.* (WPF UI components)
  • GST.ServiceInfrastructure.*
  • GST.Reporting.Core
NecroBit = false(停用,保留完整 IL)
Control Flow Obfuscation = false
Name Obfuscation = false
Anti-Debug = true
Anti-ILDASM = true
所有 Types/Methods/Properties/Parameters = Excluded

Design Rationale: These modules are primarily interfaces, UI Bindings, and AOP aspects. Aggressive obfuscation would break WPF Binding and Reflection. Only Anti-Tampering level protection is provided.


3. Exclusion List

3.1 Assemblies with No Protection

AssemblyReason
GST.App.ProcessVisionVelopack entry point, must remain in original state
GST.Core.LocalizationDynamic resource resolution incompatible with .NET Reactor
GST.Plugin.DataLoggingRuntime type loading conflicts
GST.Plugin.RecipeManagementSerialization/Reflection-intensive operations incompatible

3.2 ReadyToRun Exclusions (.csproj)

<PublishReadyToRunExclude Include="GST.Core.Localization.dll" />
<PublishReadyToRunExclude Include="GST.Plugin.DataLogging.dll" />
<PublishReadyToRunExclude Include="GST.Plugin.RecipeManagement.dll" />

ReadyToRun pre-JIT compiles IL to Native Code, which interferes with .NET Reactor's subsequent IL analysis and transformation.


4. Protection Script

4.1 File Locations

GST.App.ProcessVision/
├── protection/
│ ├── Protect-GstAssemblies.ps1 ← Protection execution script
│ ├── GSTProtection-Max.nrproj ← Max Profile
│ ├── GSTProtection-Standard.nrproj ← Standard Profile
│ └── GSTProtection-Light.nrproj ← Light Profile
└── build/
└── publish-velopack.ps1 ← Integrated packaging script

4.2 Protection Logic (Protect-GstAssemblies.ps1)

1. Scan all GST.*.dll files in the publish directory
2. Determine Tier by name:
├─ GST.Core.Licensing → Max Profile
├─ GST.Core.Abstractions → Light Profile
├─ GST.Core.Aspects → Light Profile
├─ GST.UI.* → Light Profile
├─ GST.ServiceInfrastructure.* → Light Profile
├─ GST.Reporting.Core → Light Profile
├─ GST.Core.* (remaining) → Standard Profile
├─ GST.Protocols.* → Standard Profile
└─ GST.Plugin.* (remaining) → Standard Profile
3. Skip assemblies in the exclusion list
4. Call dotnet_reactor_console.exe to protect each assembly
5. Remove .nrmap mapping files
6. Output protection summary report

4.3 Execution Methods

# 獨立執行保護(需先 dotnet publish)
cd protection
.\Protect-GstAssemblies.ps1 -PublishDir "..\bin\Release\net8.0-windows\win-x64\publish"

# 透過 publish-velopack.ps1 自動執行(推薦)
cd build
.\publish-velopack.ps1 -Version "1.0.6"

5. Packaging Pipeline Integration

5.1 Full Pipeline

Stage 1: PUBLISH
dotnet publish -c Release -r win-x64 --self-contained
└→ Output to publish/

Stage 2: PROTECT
Protect-GstAssemblies.ps1
└→ In-place protection of GST.*.dll in publish/

Stage 3: VELOPACK PACK
vpk pack --packId ProcessVision --mainExe Jope.App.ProcessVision.exe
└→ Produces .nupkg + Setup.exe + RELEASES

Stage 4: GITHUB RELEASE (Optional)
gh release create v{version} ...
└→ Upload to GitHub Releases

5.2 Pipeline Control Parameters

# 只到 Publish(不保護、不打包)
.\publish-velopack.ps1 -Step Publish

# 到 Protect(Publish + 保護)
.\publish-velopack.ps1 -Step Protect

# 到 Pack(完整流程,預設)
.\publish-velopack.ps1 -Step Pack

# 到 Release(完整流程 + 上傳 GitHub)
.\publish-velopack.ps1 -Step Release -UploadToGitHub

# 跳過保護
.\publish-velopack.ps1 -SkipProtection

6. Hardware Lock (Machine Binding)

6.1 Purpose

When deploying to a specific machine, the .NET Reactor Licensing feature binds to the Hardware ID, preventing the application from being copied and run on other machines.

6.2 Usage

.\publish-velopack.ps1 -Step Protect -HardwareId "ABCD-1234-EFGH-5678-IJKL"

6.3 How It Works

  1. The script temporarily modifies License_Hardware_ID in the .nrproj file
  2. Enables License_Hardware_Lock_Enabled in the Max Profile
  3. Executes protection
  4. After protection completes, automatically restores the .nrproj to its original state
  5. Supports multiple Hardware IDs (semicolon-separated)

Note: Hardware Lock and GST.Core.Licensing's Machine Fingerprint are different mechanisms. Hardware Lock is a .NET Reactor-level execution restriction, while Machine Fingerprint is an application-level license verification.


7. Frequently Asked Questions

7.1 Functionality Broken After Protection

Check whether the assembly should be added to the exclusion list. Common causes:

  • Reflection-intensive (DI, serialization) → Use Standard (with Reflection Mode enabled) or Light
  • WPF Binding (XAML bound to properties) → Use Light
  • Metalama Aspect (compile-time code generation) → Use Light
  • Dynamic resource loading (Localization JSON) → Add to exclusion list

7.2 Launch Failure After Velopack Installation

Confirm that GST.App.ProcessVision.dll (entry point) has not been protected. Velopack needs to read the entry point's metadata.

7.3 ReadyToRun and .NET Reactor Conflict

Incompatible assemblies must be added to both:

  1. PublishReadyToRunExclude in .csproj
  2. The exclusion list in Protect-GstAssemblies.ps1

8. Workflow for Adding New Assemblies

  1. Determine the assembly's nature (interface / business logic / core licensing)
  2. Select the corresponding Tier (Light / Standard / Max)
  3. Test that functionality works correctly after protection
  4. If incompatible, add to the exclusion list and update the .csproj ReadyToRun exclusions
  5. Update the assembly mapping table in this document

Document Version: v1.0 Created: 2026-03-16 Last Updated: 2026-03-16 Linear Issue: GST-169