├── .gitattributes
├── .gitignore
├── .gitmodules
├── .nuget
├── NuGet.Config
└── NuGet.targets
├── Build
├── 7z.exe
├── Build.cmd
├── UpdateVersion.cs
├── UpdateVersion.csproj
└── files.lst
├── Confuser.CLI
├── Confuser.CLI.csproj
├── Options.cs
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
├── Confuser.Core
├── API
│ ├── APIStore.cs
│ ├── IDataStore.cs
│ └── IOpaquePredicate.cs
├── Annotations.cs
├── Confuser.Core.csproj
├── ConfuserComponent.cs
├── ConfuserContext.cs
├── ConfuserEngine.cs
├── ConfuserException.cs
├── ConfuserParameters.cs
├── CoreComponent.cs
├── DependencyResolver.cs
├── DnlibUtils.cs
├── Helpers
│ ├── ControlFlowGraph.cs
│ ├── InjectHelper.cs
│ ├── KeySequence.cs
│ └── MutationHelper.cs
├── ILogger.cs
├── LZMA
│ ├── Common
│ │ ├── CRC.cs
│ │ ├── InBuffer.cs
│ │ └── OutBuffer.cs
│ ├── Compress
│ │ ├── LZ
│ │ │ ├── IMatchFinder.cs
│ │ │ ├── LzBinTree.cs
│ │ │ ├── LzInWindow.cs
│ │ │ └── LzOutWindow.cs
│ │ ├── LZMA
│ │ │ ├── LzmaBase.cs
│ │ │ ├── LzmaDecoder.cs
│ │ │ └── LzmaEncoder.cs
│ │ └── RangeCoder
│ │ │ ├── RangeCoder.cs
│ │ │ ├── RangeCoderBit.cs
│ │ │ └── RangeCoderBitTree.cs
│ └── ICoder.cs
├── Marker.cs
├── MarkerResult.cs
├── ModuleSorter.cs
├── ModuleWriterListener.cs
├── NativeEraser.cs
├── NullLogger.cs
├── ObfAttrMarker.cs
├── ObfAttrParser.cs
├── Packer.cs
├── PluginDiscovery.cs
├── Project
│ ├── ConfuserPrj.xsd
│ ├── ConfuserProject.cs
│ ├── InvalidPatternException.cs
│ ├── PatternParser.cs
│ ├── PatternToken.cs
│ ├── PatternTokenizer.cs
│ └── Patterns
│ │ ├── AndOperator.cs
│ │ ├── DeclTypeFunction.cs
│ │ ├── FullNameFunction.cs
│ │ ├── HasAttrFunction.cs
│ │ ├── InheritsFunction.cs
│ │ ├── IsPublicFunction.cs
│ │ ├── IsTypeFunction.cs
│ │ ├── LiteralExpression.cs
│ │ ├── MatchFunction.cs
│ │ ├── MemberTypeFunction.cs
│ │ ├── ModuleFunction.cs
│ │ ├── NameFunction.cs
│ │ ├── NamespaceFunction.cs
│ │ ├── NotOperator.cs
│ │ ├── OrOperator.cs
│ │ ├── PatternExpression.cs
│ │ ├── PatternFunction.cs
│ │ └── PatternOperator.cs
├── Properties
│ └── AssemblyInfo.cs
├── Protection.cs
├── ProtectionDependencyAttributes.cs
├── ProtectionParameters.cs
├── ProtectionPhase.cs
├── ProtectionPipeline.cs
├── ProtectionPreset.cs
├── ProtectionSettings.cs
├── ProtectionTargets.cs
├── ServiceRegistry.cs
├── Services
│ ├── CompressionService.cs
│ ├── MarkerService.cs
│ ├── RandomService.cs
│ ├── RuntimeService.cs
│ └── TraceService.cs
├── UnreachableException.cs
└── Utils.cs
├── Confuser.DynCipher
├── AST
│ ├── ArrayIndexExpression.cs
│ ├── AssignmentStatement.cs
│ ├── BinOpExpression.cs
│ ├── Expression.cs
│ ├── LiteralExpression.cs
│ ├── LoopStatement.cs
│ ├── Statement.cs
│ ├── StatementBlock.cs
│ ├── UnaryOpExpression.cs
│ ├── Variable.cs
│ └── VariableExpression.cs
├── Confuser.DynCipher.csproj
├── DynCipherComponent.cs
├── DynCipherService.cs
├── Elements
│ ├── AddKey.cs
│ ├── BinOp.cs
│ ├── CryptoElement.cs
│ ├── Matrix.cs
│ ├── NumOp.cs
│ ├── RotateBit.cs
│ └── Swap.cs
├── Generation
│ ├── CILCodeGen.cs
│ ├── CipherGenContext.cs
│ ├── CipherGenerator.cs
│ ├── DMCodeGen.cs
│ ├── ExpressionGenerator.cs
│ └── x86CodeGen.cs
├── Properties
│ └── AssemblyInfo.cs
├── Transforms
│ ├── ConvertVariables.cs
│ ├── ExpansionTransform.cs
│ ├── MulToShiftTransform.cs
│ ├── NormalizeBinOpTransform.cs
│ └── ShuffleTransform.cs
└── Utils.cs
├── Confuser.Protections
├── AntiDebugProtection.cs
├── AntiDumpProtection.cs
├── AntiILDasmProtection.cs
├── AntiTamper
│ ├── AntiTamperProtection.cs
│ ├── DynamicDeriver.cs
│ ├── IKeyDeriver.cs
│ ├── IModeHandler.cs
│ ├── JITBody.cs
│ ├── JITMode.cs
│ ├── NormalDeriver.cs
│ └── NormalMode.cs
├── Compress
│ ├── Compressor.cs
│ ├── CompressorContext.cs
│ ├── DynamicDeriver.cs
│ ├── ExtractPhase.cs
│ ├── IKeyDeriver.cs
│ ├── NormalDeriver.cs
│ └── StubProtection.cs
├── Confuser.Protections.csproj
├── Constants
│ ├── CEContext.cs
│ ├── ConstantProtection.cs
│ ├── DynamicMode.cs
│ ├── EncodeElements.cs
│ ├── EncodePhase.cs
│ ├── IEncodeMode.cs
│ ├── InjectPhase.cs
│ ├── Mode.cs
│ ├── NormalMode.cs
│ ├── ReferenceReplacer.cs
│ └── x86Mode.cs
├── ControlFlow
│ ├── BlockParser.cs
│ ├── Blocks.cs
│ ├── CFContext.cs
│ ├── ControlFlowPhase.cs
│ ├── ControlFlowProtection.cs
│ ├── ExpressionPredicate.cs
│ ├── IPredicate.cs
│ ├── JumpMangler.cs
│ ├── ManglerBase.cs
│ ├── NormalPredicate.cs
│ ├── SwitchMangler.cs
│ └── x86Predicate.cs
├── InvalidMetadataProtection.cs
├── Properties
│ └── AssemblyInfo.cs
├── ReferenceProxy
│ ├── ExpressionEncoding.cs
│ ├── IRPEncoding.cs
│ ├── MildMode.cs
│ ├── NormalEncoding.cs
│ ├── RPContext.cs
│ ├── RPMode.cs
│ ├── ReferenceProxyPhase.cs
│ ├── ReferenceProxyProtection.cs
│ ├── StrongMode.cs
│ └── x86Encoding.cs
└── Resources
│ ├── DynamicMode.cs
│ ├── IEncodeMode.cs
│ ├── InjectPhase.cs
│ ├── MDPhase.cs
│ ├── Mode.cs
│ ├── NormalMode.cs
│ ├── REContext.cs
│ └── ResourceProtection.cs
├── Confuser.Renamer
├── AnalyzePhase.cs
├── Analyzers
│ ├── CaliburnAnalyzer.cs
│ ├── InterReferenceAnalyzer.cs
│ ├── JsonAnalyzer.cs
│ ├── LdtokenEnumAnalyzer.cs
│ ├── ResourceAnalyzer.cs
│ ├── TypeBlobAnalyzer.cs
│ ├── VTableAnalyzer.cs
│ ├── WPFAnalyzer.cs
│ └── WinFormsAnalyzer.cs
├── BAML
│ ├── BAMLAnalyzer.cs
│ ├── BAMLPropertyReference.cs
│ ├── BAMLStringReference.cs
│ ├── BamlDocument.cs
│ ├── BamlElement.cs
│ ├── BamlRW.cs
│ ├── BamlRecords.cs
│ ├── IBAMLReference.cs
│ ├── IKnownThings.cs
│ ├── KnownThingsv3.cs
│ ├── KnownThingsv4.cs
│ └── PropertyPath.cs
├── Confuser.Renamer.csproj
├── GenericArgumentResolver.cs
├── INameReference.cs
├── IRenamer.cs
├── NameProtection.cs
├── NameService.cs
├── PostRenamePhase.cs
├── Properties
│ └── AssemblyInfo.cs
├── References
│ ├── BAMLAttributeReference.cs
│ ├── BAMLConverterMemberReference.cs
│ ├── BAMLConverterTypeReference.cs
│ ├── BAMLEnumReference.cs
│ ├── BAMLPathTypeReference.cs
│ ├── BAMLTypeReference.cs
│ ├── CAMemberReference.cs
│ ├── MemberRefReference.cs
│ ├── OverrideDirectiveReference.cs
│ ├── ResourceReference.cs
│ ├── StringTypeReference.cs
│ └── TypeRefReference.cs
├── RenameMode.cs
├── RenamePhase.cs
├── ReversibleRenamer.cs
├── RickRoller.cs
└── VTable.cs
├── Confuser.Runtime
├── AntiDebug.Antinet.cs
├── AntiDebug.Safe.cs
├── AntiDebug.Win32.cs
├── AntiDump.cs
├── AntiTamper.JIT.cs
├── AntiTamper.Normal.cs
├── Compressor.Compat.cs
├── Compressor.cs
├── Confuser.Runtime.csproj
├── Constant.cs
├── Lzma.cs
├── Mutation.cs
├── Properties
│ └── AssemblyInfo.cs
├── RefProxy.Strong.cs
├── Resource.cs
└── antinet
│ ├── ABOUT
│ ├── AntiManagedDebugger.cs
│ ├── AntiManagedProfiler.cs
│ ├── HandleProcessCorruptedStateExceptionsAttribute.cs
│ └── PEInfo.cs
├── Confuser2.mono.sln
├── Confuser2.sln
├── ConfuserEx.snk
├── ConfuserEx
├── App.xaml
├── App.xaml.cs
├── BoolToVisibilityConverter.cs
├── BrushToColorConverter.cs
├── CompComboBox.xaml
├── CompComboBox.xaml.cs
├── ComponentConverter.cs
├── ComponentDiscovery.cs
├── ConfuserEx.csproj
├── ConfuserEx.ico
├── EnumValuesExtension.cs
├── FileDragDrop.cs
├── InvertBoolConverter.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Properties
│ └── AssemblyInfo.cs
├── Resources
│ ├── CREDITS
│ ├── Decode.png
│ ├── Error.png
│ ├── FontAwesome.otf
│ ├── New.png
│ ├── Open.png
│ ├── Save.png
│ ├── TeamLogo.png
│ └── Tools.png
├── Skin.cs
├── Skin.xaml
├── StackTraceDecoder.xaml
├── StackTraceDecoder.xaml.cs
├── ViewModel
│ ├── IViewModel.cs
│ ├── Project
│ │ ├── ProjectModuleVM.cs
│ │ ├── ProjectRuleVM.cs
│ │ ├── ProjectSettingVM.cs
│ │ └── ProjectVM.cs
│ ├── StringItem.cs
│ ├── UI
│ │ ├── AboutTabVM.cs
│ │ ├── AppVM.cs
│ │ ├── ProjectTabVM.cs
│ │ ├── ProtectTabVM.cs
│ │ ├── SettingsTabVM.cs
│ │ └── TabViewModel.cs
│ ├── Utils.cs
│ └── ViewModelBase.cs
├── Views.xaml
├── Views
│ ├── AboutTabView.xaml
│ ├── ProjectModuleView.xaml
│ ├── ProjectModuleView.xaml.cs
│ ├── ProjectRuleView.xaml
│ ├── ProjectRuleView.xaml.cs
│ ├── ProjectTabAdvancedView.xaml
│ ├── ProjectTabAdvancedView.xaml.cs
│ ├── ProjectTabView.xaml
│ ├── ProtectTabView.xaml
│ └── SettingsTabView.xaml
├── app.config
└── packages.config
├── GlobalAssemblyInfo.Template.cs
├── LICENSE
├── README.md
├── VERSION
├── additional
├── Icon.pdn
├── Icon16.pdn
├── Icon256.pdn
├── Icon32.pdn
├── Icon48.pdn
├── Icon64.pdn
├── ilspy.crproj
└── pdn.crproj
├── deps
└── Ookii.Dialogs.Wpf.dll
└── docs
├── DeclarativeObfuscation.txt
├── ProjectFormat.md
└── docs.shfbproj
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.cs diff=csharp
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | #ignore thumbnails created by windows
3 | Thumbs.db
4 | #Ignore files build by Visual Studio
5 | *.obj
6 | *.exe
7 | *.pdb
8 | *.user
9 | *.aps
10 | *.pch
11 | *.vspscc
12 | *_i.c
13 | *_p.c
14 | *.ncb
15 | *.suo
16 | *.tlb
17 | *.tlh
18 | *.bak
19 | *.cache
20 | *.ilk
21 | *.log
22 | [Bb]in
23 | [Dd]ebug*/
24 | *.lib
25 | *.sbr
26 | obj/
27 | [Rr]elease*/
28 | _ReSharper*/
29 | [Tt]est[Rr]esult*
30 |
31 | !packages/*/build/
32 | packages/
33 | /Confuser.Test
34 | *.sln.*
35 | gh-pages/
36 | GlobalAssemblyInfo.cs
37 | /Build/*.zip
38 | !Build/7z.exe
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "dnlib"]
2 | path = dnlib
3 | url = https://github.com/yck1509/dnlib.git
4 |
--------------------------------------------------------------------------------
/.nuget/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Build/7z.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yck1509/ConfuserEx/3e3e4ae8ef01e3a169591e9b7803408e38cce7ca/Build/7z.exe
--------------------------------------------------------------------------------
/Build/Build.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | %windir%\microsoft.net\framework\v4.0.30319\msbuild ..\Confuser2.sln /p:Configuration=Release "/p:Platform=Any CPU"
4 |
5 | IF %ERRORLEVEL% NEQ 0 GOTO err
6 |
7 | 7z a ConfuserEx_bin.zip -tzip @files.lst
8 | EXIT /B 0
9 |
10 | :err
11 | PAUSE
12 | EXIT /B 1
--------------------------------------------------------------------------------
/Build/UpdateVersion.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 |
5 | public static class Program {
6 | public static int Main(string[] args) {
7 | if (args.Length != 1) {
8 | Console.WriteLine("invalid argument length.");
9 | return -1;
10 | }
11 |
12 | string dir = args[0];
13 | string ver = File.ReadAllText(Path.Combine(dir, "VERSION"));
14 | string tag = null;
15 |
16 | string gitDir = Path.Combine(dir, ".git");
17 | if (!Directory.Exists(gitDir)) {
18 | Console.WriteLine("git repository not found.");
19 | }
20 | else {
21 | try {
22 | var info = new ProcessStartInfo("git", "describe");
23 | info.RedirectStandardOutput = true;
24 | info.UseShellExecute = false;
25 | using (Process ps = Process.Start(info)) {
26 | tag = ps.StandardOutput.ReadLine();
27 | string[] infos = tag.Split('-');
28 | if (infos.Length >= 3)
29 | ver = ver + "." + infos[infos.Length - 2];
30 | else
31 | ver = infos[0].Substring(1);
32 | ps.WaitForExit();
33 | if (ps.ExitCode != 0) {
34 | Console.WriteLine("error when executing git describe: " + ps.ExitCode);
35 | }
36 | }
37 | }
38 | catch {
39 | Console.WriteLine("error when executing git describe.");
40 | }
41 | }
42 | tag = tag ?? "v" + ver + "-custom";
43 |
44 | string template = Path.Combine(dir, "GlobalAssemblyInfo.Template.cs");
45 | string output = Path.Combine(dir, "GlobalAssemblyInfo.cs");
46 |
47 | string verInfo = File.ReadAllText(template);
48 | verInfo = verInfo.Replace("{{VER}}", ver);
49 | verInfo = verInfo.Replace("{{TAG}}", tag);
50 | File.WriteAllText(output, verInfo);
51 | Console.WriteLine("Version updated.");
52 | return 0;
53 | }
54 | }
--------------------------------------------------------------------------------
/Build/UpdateVersion.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Release
5 | AnyCPU
6 | {1e74b523-aa86-42a0-8116-fff7cebfcba7}
7 | Exe
8 | UpdateVersion
9 | UpdateVersion
10 | v2.0
11 |
12 |
13 | false
14 | None
15 | true
16 | .\
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Build/files.lst:
--------------------------------------------------------------------------------
1 | ..\Release\bin\Confuser.CLI.exe
2 | ..\Release\bin\Confuser.CLI.pdb
3 | ..\Release\bin\Confuser.Core.*
4 | ..\Release\bin\Confuser.DynCipher.*
5 | ..\Release\bin\Confuser.Protections.*
6 | ..\Release\bin\Confuser.Renamer.*
7 | ..\Release\bin\Confuser.Runtime.*
8 | ..\Release\bin\dnlib.*
9 | ..\Release\bin\ConfuserEx.exe
10 | ..\Release\bin\ConfuserEx.exe.config
11 | ..\Release\bin\ConfuserEx.pdb
12 | ..\Release\bin\System.Threading.dll
13 | ..\Release\bin\GalaSoft.MvvmLight.Extras.WPF4.dll
14 | ..\Release\bin\GalaSoft.MvvmLight.WPF4.dll
15 | ..\Release\bin\Microsoft.Practices.ServiceLocation.dll
16 | ..\Release\bin\Ookii.Dialogs.Wpf.dll
17 | ..\Release\bin\System.Windows.Interactivity.dll
--------------------------------------------------------------------------------
/Confuser.CLI/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | [assembly: AssemblyTitle("ConfuserEx Command-line")]
5 | [assembly: AssemblyDescription("Command-line interface of ConfuserEx")]
--------------------------------------------------------------------------------
/Confuser.Core/API/IDataStore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 | using dnlib.DotNet.Emit;
4 |
5 | namespace Confuser.Core.API {
6 | ///
7 | /// A data store.
8 | ///
9 | public interface IDataStore {
10 | ///
11 | /// Gets the priority of this data store; higher priority means it
12 | /// would be tried earlier.
13 | ///
14 | /// The priority of this data store.
15 | int Priority { get; }
16 |
17 | ///
18 | /// Gets the number of keys this predicate has.
19 | ///
20 | ///
21 | /// Keys are used by the data store to encrypt data/whatever purpose.
22 | ///
23 | /// The number of keys this data store has.
24 | int KeyCount { get; }
25 |
26 | ///
27 | /// Determines whether this data store can be used in the specified method.
28 | ///
29 | /// The method.
30 | /// true if this data store can be used in the specified method; otherwise, false.
31 | bool IsUsable(MethodDef method);
32 |
33 | ///
34 | /// Creates an accessor of this data store for the specified method.
35 | ///
36 | /// The method.
37 | /// The keys.
38 | /// The data to store.
39 | /// A newly accessor of this data store.
40 | IDataStoreAccessor CreateAccessor(MethodDef method, uint[] keys, byte[] data);
41 | }
42 |
43 | ///
44 | /// An accessor of data store.
45 | ///
46 | public interface IDataStoreAccessor {
47 | ///
48 | /// Emits the runtime instruction sequence for this accessor.
49 | ///
50 | /// An instruction sequence that returns the stored data.
51 | Instruction[] Emit();
52 | }
53 | }
--------------------------------------------------------------------------------
/Confuser.Core/ConfuserComponent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core {
4 | ///
5 | /// Represent a component in Confuser
6 | ///
7 | public abstract class ConfuserComponent {
8 | ///
9 | /// Gets the name of component.
10 | ///
11 | /// The name of component.
12 | public abstract string Name { get; }
13 |
14 | ///
15 | /// Gets the description of component.
16 | ///
17 | /// The description of component.
18 | public abstract string Description { get; }
19 |
20 | ///
21 | /// Gets the identifier of component used by users.
22 | ///
23 | /// The identifier of component.
24 | public abstract string Id { get; }
25 |
26 | ///
27 | /// Gets the full identifier of component used in Confuser.
28 | ///
29 | /// The full identifier of component.
30 | public abstract string FullId { get; }
31 |
32 | ///
33 | /// Initializes the component.
34 | ///
35 | /// The working context.
36 | protected internal abstract void Initialize(ConfuserContext context);
37 |
38 | ///
39 | /// Inserts protection stages into processing pipeline.
40 | ///
41 | /// The processing pipeline.
42 | protected internal abstract void PopulatePipeline(ProtectionPipeline pipeline);
43 | }
44 | }
--------------------------------------------------------------------------------
/Confuser.Core/ConfuserException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core {
4 | ///
5 | /// The exception that is thrown when a handled error occurred during the protection process.
6 | ///
7 | public class ConfuserException : Exception {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The inner exception, or null if no exception is associated with the error.
12 | public ConfuserException(Exception innerException)
13 | : base("Exception occurred during the protection process.", innerException) { }
14 | }
15 | }
--------------------------------------------------------------------------------
/Confuser.Core/ConfuserParameters.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core.Project;
3 |
4 | namespace Confuser.Core {
5 | ///
6 | /// Parameters that passed to .
7 | ///
8 | public class ConfuserParameters {
9 | ///
10 | /// Gets or sets the project that would be processed.
11 | ///
12 | /// The Confuser project.
13 | public ConfuserProject Project { get; set; }
14 |
15 | ///
16 | /// Gets or sets the logger that used to log the protection process.
17 | ///
18 | /// The logger, or null if logging is not needed.
19 | public ILogger Logger { get; set; }
20 |
21 | internal bool PackerInitiated { get; set; }
22 |
23 | ///
24 | /// Gets or sets the plugin discovery service.
25 | ///
26 | /// The plugin discovery service, or null if default discovery is used.
27 | public PluginDiscovery PluginDiscovery { get; set; }
28 |
29 | ///
30 | /// Gets or sets the marker.
31 | ///
32 | /// The marker, or null if default marker is used.
33 | public Marker Marker { get; set; }
34 |
35 | ///
36 | /// Gets the actual non-null logger.
37 | ///
38 | /// The logger.
39 | internal ILogger GetLogger() {
40 | return Logger ?? NullLogger.Instance;
41 | }
42 |
43 | ///
44 | /// Gets the actual non-null plugin discovery service.
45 | ///
46 | /// The plugin discovery service.
47 | internal PluginDiscovery GetPluginDiscovery() {
48 | return PluginDiscovery ?? PluginDiscovery.Instance;
49 | }
50 |
51 | ///
52 | /// Gets the actual non-null marker.
53 | ///
54 | /// The marker.
55 | internal Marker GetMarker() {
56 | return Marker ?? new ObfAttrMarker();
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/Confuser.Core/LZMA/Common/CRC.cs:
--------------------------------------------------------------------------------
1 | // Common/CRC.cs
2 |
3 | using System;
4 |
5 | namespace SevenZip {
6 | internal class CRC {
7 |
8 | public static readonly uint[] Table;
9 |
10 | private uint _value = 0xFFFFFFFF;
11 |
12 | static CRC() {
13 | Table = new uint[256];
14 | const uint kPoly = 0xEDB88320;
15 | for (uint i = 0; i < 256; i++) {
16 | uint r = i;
17 | for (int j = 0; j < 8; j++)
18 | if ((r & 1) != 0)
19 | r = (r >> 1) ^ kPoly;
20 | else
21 | r >>= 1;
22 | Table[i] = r;
23 | }
24 | }
25 |
26 | public void Init() {
27 | _value = 0xFFFFFFFF;
28 | }
29 |
30 | public void UpdateByte(byte b) {
31 | _value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);
32 | }
33 |
34 | public void Update(byte[] data, uint offset, uint size) {
35 | for (uint i = 0; i < size; i++)
36 | _value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
37 | }
38 |
39 | public uint GetDigest() {
40 | return _value ^ 0xFFFFFFFF;
41 | }
42 |
43 | private static uint CalculateDigest(byte[] data, uint offset, uint size) {
44 | var crc = new CRC();
45 | // crc.Init();
46 | crc.Update(data, offset, size);
47 | return crc.GetDigest();
48 | }
49 |
50 | private static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size) {
51 | return (CalculateDigest(data, offset, size) == digest);
52 | }
53 |
54 | }
55 | }
--------------------------------------------------------------------------------
/Confuser.Core/LZMA/Common/InBuffer.cs:
--------------------------------------------------------------------------------
1 | // InBuffer.cs
2 |
3 | using System;
4 | using System.IO;
5 |
6 | namespace SevenZip.Buffer {
7 | internal class InBuffer {
8 |
9 | private readonly byte[] m_Buffer;
10 | private readonly uint m_BufferSize;
11 | private uint m_Limit;
12 | private uint m_Pos;
13 | private ulong m_ProcessedSize;
14 | private Stream m_Stream;
15 | private bool m_StreamWasExhausted;
16 |
17 | public InBuffer(uint bufferSize) {
18 | m_Buffer = new byte[bufferSize];
19 | m_BufferSize = bufferSize;
20 | }
21 |
22 | public void Init(Stream stream) {
23 | m_Stream = stream;
24 | m_ProcessedSize = 0;
25 | m_Limit = 0;
26 | m_Pos = 0;
27 | m_StreamWasExhausted = false;
28 | }
29 |
30 | public bool ReadBlock() {
31 | if (m_StreamWasExhausted)
32 | return false;
33 | m_ProcessedSize += m_Pos;
34 | int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize);
35 | m_Pos = 0;
36 | m_Limit = (uint)aNumProcessedBytes;
37 | m_StreamWasExhausted = (aNumProcessedBytes == 0);
38 | return (!m_StreamWasExhausted);
39 | }
40 |
41 |
42 | public void ReleaseStream() {
43 | // m_Stream.Close();
44 | m_Stream = null;
45 | }
46 |
47 | public bool ReadByte(byte b) // check it
48 | {
49 | if (m_Pos >= m_Limit)
50 | if (!ReadBlock())
51 | return false;
52 | b = m_Buffer[m_Pos++];
53 | return true;
54 | }
55 |
56 | public byte ReadByte() {
57 | // return (byte)m_Stream.ReadByte();
58 | if (m_Pos >= m_Limit)
59 | if (!ReadBlock())
60 | return 0xFF;
61 | return m_Buffer[m_Pos++];
62 | }
63 |
64 | public ulong GetProcessedSize() {
65 | return m_ProcessedSize + m_Pos;
66 | }
67 |
68 | }
69 | }
--------------------------------------------------------------------------------
/Confuser.Core/LZMA/Common/OutBuffer.cs:
--------------------------------------------------------------------------------
1 | // OutBuffer.cs
2 |
3 | using System;
4 | using System.IO;
5 |
6 | namespace SevenZip.Buffer {
7 | internal class OutBuffer {
8 |
9 | private readonly byte[] m_Buffer;
10 | private readonly uint m_BufferSize;
11 | private uint m_Pos;
12 | private ulong m_ProcessedSize;
13 | private Stream m_Stream;
14 |
15 | public OutBuffer(uint bufferSize) {
16 | m_Buffer = new byte[bufferSize];
17 | m_BufferSize = bufferSize;
18 | }
19 |
20 | public void SetStream(Stream stream) {
21 | m_Stream = stream;
22 | }
23 |
24 | public void FlushStream() {
25 | m_Stream.Flush();
26 | }
27 |
28 | public void CloseStream() {
29 | m_Stream.Close();
30 | }
31 |
32 | public void ReleaseStream() {
33 | m_Stream = null;
34 | }
35 |
36 | public void Init() {
37 | m_ProcessedSize = 0;
38 | m_Pos = 0;
39 | }
40 |
41 | public void WriteByte(byte b) {
42 | m_Buffer[m_Pos++] = b;
43 | if (m_Pos >= m_BufferSize)
44 | FlushData();
45 | }
46 |
47 | public void FlushData() {
48 | if (m_Pos == 0)
49 | return;
50 | m_Stream.Write(m_Buffer, 0, (int)m_Pos);
51 | m_Pos = 0;
52 | }
53 |
54 | public ulong GetProcessedSize() {
55 | return m_ProcessedSize + m_Pos;
56 | }
57 |
58 | }
59 | }
--------------------------------------------------------------------------------
/Confuser.Core/LZMA/Compress/LZ/IMatchFinder.cs:
--------------------------------------------------------------------------------
1 | // IMatchFinder.cs
2 |
3 | using System;
4 | using System.IO;
5 |
6 | namespace SevenZip.Compression.LZ {
7 | internal interface IInWindowStream {
8 |
9 | void SetStream(Stream inStream);
10 | void Init();
11 | void ReleaseStream();
12 | Byte GetIndexByte(Int32 index);
13 | UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit);
14 | UInt32 GetNumAvailableBytes();
15 |
16 | }
17 |
18 | internal interface IMatchFinder : IInWindowStream {
19 |
20 | void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
21 | UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
22 |
23 | UInt32 GetMatches(UInt32[] distances);
24 | void Skip(UInt32 num);
25 |
26 | }
27 | }
--------------------------------------------------------------------------------
/Confuser.Core/LZMA/Compress/LZ/LzOutWindow.cs:
--------------------------------------------------------------------------------
1 | // LzOutWindow.cs
2 |
3 | using System;
4 | using System.IO;
5 |
6 | namespace SevenZip.Compression.LZ {
7 | internal class OutWindow {
8 |
9 | public uint TrainSize = 0;
10 | private byte[] _buffer;
11 | private uint _pos;
12 | private Stream _stream;
13 | private uint _streamPos;
14 | private uint _windowSize;
15 |
16 | public void Create(uint windowSize) {
17 | if (_windowSize != windowSize) {
18 | // System.GC.Collect();
19 | _buffer = new byte[windowSize];
20 | }
21 | _windowSize = windowSize;
22 | _pos = 0;
23 | _streamPos = 0;
24 | }
25 |
26 | public void Init(Stream stream, bool solid) {
27 | ReleaseStream();
28 | _stream = stream;
29 | if (!solid) {
30 | _streamPos = 0;
31 | _pos = 0;
32 | TrainSize = 0;
33 | }
34 | }
35 |
36 | public bool Train(Stream stream) {
37 | long len = stream.Length;
38 | uint size = (len < _windowSize) ? (uint)len : _windowSize;
39 | TrainSize = size;
40 | stream.Position = len - size;
41 | _streamPos = _pos = 0;
42 | while (size > 0) {
43 | uint curSize = _windowSize - _pos;
44 | if (size < curSize)
45 | curSize = size;
46 | int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize);
47 | if (numReadBytes == 0)
48 | return false;
49 | size -= (uint)numReadBytes;
50 | _pos += (uint)numReadBytes;
51 | _streamPos += (uint)numReadBytes;
52 | if (_pos == _windowSize)
53 | _streamPos = _pos = 0;
54 | }
55 | return true;
56 | }
57 |
58 | public void ReleaseStream() {
59 | Flush();
60 | _stream = null;
61 | }
62 |
63 | public void Flush() {
64 | uint size = _pos - _streamPos;
65 | if (size == 0)
66 | return;
67 | _stream.Write(_buffer, (int)_streamPos, (int)size);
68 | if (_pos >= _windowSize)
69 | _pos = 0;
70 | _streamPos = _pos;
71 | }
72 |
73 | public void CopyBlock(uint distance, uint len) {
74 | uint pos = _pos - distance - 1;
75 | if (pos >= _windowSize)
76 | pos += _windowSize;
77 | for (; len > 0; len--) {
78 | if (pos >= _windowSize)
79 | pos = 0;
80 | _buffer[_pos++] = _buffer[pos++];
81 | if (_pos >= _windowSize)
82 | Flush();
83 | }
84 | }
85 |
86 | public void PutByte(byte b) {
87 | _buffer[_pos++] = b;
88 | if (_pos >= _windowSize)
89 | Flush();
90 | }
91 |
92 | public byte GetByte(uint distance) {
93 | uint pos = _pos - distance - 1;
94 | if (pos >= _windowSize)
95 | pos += _windowSize;
96 | return _buffer[pos];
97 | }
98 |
99 | }
100 | }
--------------------------------------------------------------------------------
/Confuser.Core/MarkerResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using dnlib.DotNet;
4 |
5 | namespace Confuser.Core {
6 | ///
7 | /// Result of the marker.
8 | ///
9 | public class MarkerResult {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The modules.
14 | /// The packer.
15 | /// The external modules.
16 | public MarkerResult(IList modules, Packer packer, IList extModules) {
17 | Modules = modules;
18 | Packer = packer;
19 | ExternalModules = extModules;
20 | }
21 |
22 | ///
23 | /// Gets a list of modules that is marked.
24 | ///
25 | /// The list of modules.
26 | public IList Modules { get; private set; }
27 |
28 | ///
29 | /// Gets a list of external modules.
30 | ///
31 | /// The list of external modules.
32 | public IList ExternalModules { get; private set; }
33 |
34 | ///
35 | /// Gets the packer if exists.
36 | ///
37 | /// The packer, or null if no packer exists.
38 | public Packer Packer { get; private set; }
39 | }
40 | }
--------------------------------------------------------------------------------
/Confuser.Core/ModuleSorter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using dnlib.DotNet;
6 |
7 | namespace Confuser.Core {
8 | ///
9 | /// Sort modules according dependencies.
10 | ///
11 | internal class ModuleSorter {
12 | readonly List modules;
13 |
14 | public ModuleSorter(IEnumerable modules) {
15 | this.modules = modules.ToList();
16 | }
17 |
18 | public IList Sort() {
19 | var edges = new List();
20 | var roots = new HashSet(modules);
21 | var asmMap = modules.GroupBy(module => module.Assembly.ToAssemblyRef(), AssemblyNameComparer.CompareAll)
22 | .ToDictionary(gp => gp.Key, gp => gp.ToList(), AssemblyNameComparer.CompareAll);
23 |
24 | foreach (ModuleDefMD m in modules)
25 | foreach (AssemblyRef nameRef in m.GetAssemblyRefs()) {
26 | if (!asmMap.ContainsKey(nameRef))
27 | continue;
28 |
29 | foreach (var asmModule in asmMap[nameRef])
30 | edges.Add(new DependencyGraphEdge(asmModule, m));
31 | roots.Remove(m);
32 | }
33 |
34 | var sorted = SortGraph(roots, edges).ToList();
35 | Debug.Assert(sorted.Count == modules.Count);
36 | return sorted;
37 | }
38 |
39 | IEnumerable SortGraph(IEnumerable roots, IList edges) {
40 | var visited = new HashSet();
41 | var queue = new Queue(roots);
42 | do {
43 | while (queue.Count > 0) {
44 | var node = queue.Dequeue();
45 | visited.Add(node);
46 |
47 | Debug.Assert(!edges.Where(edge => edge.To == node).Any());
48 | yield return node;
49 |
50 | foreach (DependencyGraphEdge edge in edges.Where(edge => edge.From == node).ToList()) {
51 | edges.Remove(edge);
52 | if (!edges.Any(e => e.To == edge.To))
53 | queue.Enqueue(edge.To);
54 | }
55 | }
56 | if (edges.Count > 0) {
57 | foreach (var edge in edges) {
58 | if (!visited.Contains(edge.From)) {
59 | queue.Enqueue(edge.From);
60 | break;
61 | }
62 | }
63 | }
64 | } while (edges.Count > 0);
65 | }
66 |
67 | class DependencyGraphEdge {
68 | public DependencyGraphEdge(ModuleDefMD from, ModuleDefMD to) {
69 | From = from;
70 | To = to;
71 | }
72 |
73 | public ModuleDefMD From { get; private set; }
74 | public ModuleDefMD To { get; private set; }
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/Confuser.Core/ModuleWriterListener.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 | using dnlib.DotNet.Writer;
4 |
5 | namespace Confuser.Core {
6 | ///
7 | /// The listener of module writer event.
8 | ///
9 | public class ModuleWriterListener : IModuleWriterListener {
10 | ///
11 | void IModuleWriterListener.OnWriterEvent(ModuleWriterBase writer, ModuleWriterEvent evt) {
12 | if (evt == ModuleWriterEvent.PESectionsCreated)
13 | NativeEraser.Erase(writer as NativeModuleWriter, writer.Module as ModuleDefMD);
14 | if (OnWriterEvent != null) {
15 | OnWriterEvent(writer, new ModuleWriterListenerEventArgs(evt));
16 | }
17 | }
18 |
19 | ///
20 | /// Occurs when a module writer event is triggered.
21 | ///
22 | public event EventHandler OnWriterEvent;
23 | }
24 |
25 | ///
26 | /// Indicates the triggered writer event.
27 | ///
28 | public class ModuleWriterListenerEventArgs : EventArgs {
29 | ///
30 | /// Initializes a new instance of the class.
31 | ///
32 | /// The triggered writer event.
33 | public ModuleWriterListenerEventArgs(ModuleWriterEvent evt) {
34 | WriterEvent = evt;
35 | }
36 |
37 | ///
38 | /// Gets the triggered writer event.
39 | ///
40 | /// The triggered writer event.
41 | public ModuleWriterEvent WriterEvent { get; private set; }
42 | }
43 | }
--------------------------------------------------------------------------------
/Confuser.Core/NullLogger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core {
5 | ///
6 | /// An implementation that doesn't actually do any logging.
7 | ///
8 | internal class NullLogger : ILogger {
9 | ///
10 | /// The singleton instance of .
11 | ///
12 | public static readonly NullLogger Instance = new NullLogger();
13 |
14 | ///
15 | /// Prevents a default instance of the class from being created.
16 | ///
17 | NullLogger() { }
18 |
19 | ///
20 | public void Debug(string msg) { }
21 |
22 | ///
23 | public void DebugFormat(string format, params object[] args) { }
24 |
25 | ///
26 | public void Info(string msg) { }
27 |
28 | ///
29 | public void InfoFormat(string format, params object[] args) { }
30 |
31 | ///
32 | public void Warn(string msg) { }
33 |
34 | ///
35 | public void WarnFormat(string format, params object[] args) { }
36 |
37 | ///
38 | public void WarnException(string msg, Exception ex) { }
39 |
40 | ///
41 | public void Error(string msg) { }
42 |
43 | ///
44 | public void ErrorFormat(string format, params object[] args) { }
45 |
46 | ///
47 | public void ErrorException(string msg, Exception ex) { }
48 |
49 | ///
50 | public void Progress(int overall, int progress) { }
51 |
52 | ///
53 | public void EndProgress() { }
54 |
55 | ///
56 | public void Finish(bool successful) { }
57 |
58 | ///
59 | public void BeginModule(ModuleDef module) { }
60 |
61 | ///
62 | public void EndModule(ModuleDef module) { }
63 | }
64 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/InvalidPatternException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core.Project {
4 | ///
5 | /// The exception that is thrown when attempted to parse an invalid pattern.
6 | ///
7 | public class InvalidPatternException : Exception {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The message that describes the error.
12 | public InvalidPatternException(string message)
13 | : base(message) { }
14 |
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | /// The error message that explains the reason for the exception.
19 | ///
20 | /// The exception that is the cause of the current exception, or a null reference (Nothing in
21 | /// Visual Basic) if no inner exception is specified.
22 | ///
23 | public InvalidPatternException(string message, Exception innerException)
24 | : base(message, innerException) { }
25 | }
26 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/PatternTokenizer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Text;
4 |
5 | namespace Confuser.Core.Project {
6 | internal class PatternTokenizer {
7 | int index;
8 | string rulePattern;
9 |
10 | public void Initialize(string pattern) {
11 | rulePattern = pattern;
12 | index = 0;
13 | }
14 |
15 | void SkipWhitespace() {
16 | while (index < rulePattern.Length && char.IsWhiteSpace(rulePattern[index]))
17 | index++;
18 | }
19 |
20 | char? PeekChar() {
21 | if (index >= rulePattern.Length)
22 | return null;
23 | return rulePattern[index];
24 | }
25 |
26 | char NextChar() {
27 | if (index >= rulePattern.Length)
28 | throw new InvalidPatternException("Unexpected end of pattern.");
29 | return rulePattern[index++];
30 | }
31 |
32 | string ReadLiteral() {
33 | var ret = new StringBuilder();
34 | char delim = NextChar();
35 | Debug.Assert(delim == '"' || delim == '\'');
36 |
37 | char chr = NextChar();
38 | while (chr != delim) {
39 | // Escape sequence
40 | if (chr == '\\')
41 | ret.Append(NextChar());
42 | else
43 | ret.Append(chr);
44 | chr = NextChar();
45 | }
46 | return ret.ToString();
47 | }
48 |
49 | string ReadIdentifier() {
50 | var ret = new StringBuilder();
51 |
52 | char? chr = PeekChar();
53 | while (chr != null && (char.IsLetterOrDigit(chr.Value) || chr == '_' || chr == '-')) {
54 | ret.Append(NextChar());
55 | chr = PeekChar();
56 | }
57 |
58 | return ret.ToString();
59 | }
60 |
61 | public PatternToken? NextToken() {
62 | if (rulePattern == null)
63 | throw new InvalidOperationException("Tokenizer not initialized.");
64 |
65 | SkipWhitespace();
66 | char? tokenBegin = PeekChar();
67 | if (tokenBegin == null)
68 | return null;
69 |
70 | int pos = index;
71 | switch (tokenBegin.Value) {
72 | case ',':
73 | index++;
74 | return new PatternToken(pos, TokenType.Comma);
75 | case '(':
76 | index++;
77 | return new PatternToken(pos, TokenType.LParens);
78 | case ')':
79 | index++;
80 | return new PatternToken(pos, TokenType.RParens);
81 |
82 | case '"':
83 | case '\'':
84 | return new PatternToken(pos, TokenType.Literal, ReadLiteral());
85 |
86 | default:
87 | if (!char.IsLetter(tokenBegin.Value))
88 | throw new InvalidPatternException(string.Format("Unknown token '{0}' at position {1}.", tokenBegin, pos));
89 |
90 | return new PatternToken(pos, TokenType.Identifier, ReadIdentifier());
91 | }
92 | }
93 | }
94 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/AndOperator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// The AND operator.
7 | ///
8 | public class AndOperator : PatternOperator {
9 | internal const string OpName = "and";
10 |
11 | ///
12 | public override string Name {
13 | get { return OpName; }
14 | }
15 |
16 | ///
17 | public override bool IsUnary {
18 | get { return false; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | var a = (bool)OperandA.Evaluate(definition);
24 | if (!a) return false;
25 | return (bool)OperandB.Evaluate(definition);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/DeclTypeFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A function that compare the full name of declaring type.
7 | ///
8 | public class DeclTypeFunction : PatternFunction {
9 | internal const string FnName = "decl-type";
10 |
11 | ///
12 | public override string Name {
13 | get { return FnName; }
14 | }
15 |
16 | ///
17 | public override int ArgumentCount {
18 | get { return 1; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | if (!(definition is IMemberDef) || ((IMemberDef)definition).DeclaringType == null)
24 | return false;
25 | object fullName = Arguments[0].Evaluate(definition);
26 | return ((IMemberDef)definition).DeclaringType.FullName == fullName.ToString();
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/FullNameFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A function that compare the full name of definition.
7 | ///
8 | public class FullNameFunction : PatternFunction {
9 | internal const string FnName = "full-name";
10 |
11 | ///
12 | public override string Name {
13 | get { return FnName; }
14 | }
15 |
16 | ///
17 | public override int ArgumentCount {
18 | get { return 1; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | object name = Arguments[0].Evaluate(definition);
24 | return definition.FullName == name.ToString();
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/HasAttrFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A function that indicate whether the item has the given custom attribute.
7 | ///
8 | public class HasAttrFunction : PatternFunction {
9 | internal const string FnName = "has-attr";
10 |
11 | ///
12 | public override string Name {
13 | get { return FnName; }
14 | }
15 |
16 | ///
17 | public override int ArgumentCount {
18 | get { return 1; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | string attrName = Arguments[0].Evaluate(definition).ToString();
24 | return definition.CustomAttributes.IsDefined(attrName);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/InheritsFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A function that indicate whether the type inherits from the specified type.
7 | ///
8 | public class InheritsFunction : PatternFunction {
9 | internal const string FnName = "inherits";
10 |
11 | ///
12 | public override string Name {
13 | get { return FnName; }
14 | }
15 |
16 | ///
17 | public override int ArgumentCount {
18 | get { return 1; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | string name = Arguments[0].Evaluate(definition).ToString();
24 |
25 | var type = definition as TypeDef;
26 | if (type == null && definition is IMemberDef)
27 | type = ((IMemberDef)definition).DeclaringType;
28 | if (type == null)
29 | return false;
30 |
31 | if (type.InheritsFrom(name) || type.Implements(name))
32 | return true;
33 |
34 | return false;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/IsPublicFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A function that indicate the visibility of members.
7 | ///
8 | public class IsPublicFunction : PatternFunction {
9 | internal const string FnName = "is-public";
10 |
11 | ///
12 | public override string Name {
13 | get { return FnName; }
14 | }
15 |
16 | ///
17 | public override int ArgumentCount {
18 | get { return 0; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | var member = definition as IMemberDef;
24 | if (member == null)
25 | return false;
26 |
27 | var declType = ((IMemberDef)definition).DeclaringType;
28 | while (declType != null) {
29 | if (!declType.IsPublic)
30 | return false;
31 | declType = declType.DeclaringType;
32 | }
33 |
34 | if (member is MethodDef)
35 | return ((MethodDef)member).IsPublic;
36 | if (member is FieldDef)
37 | return ((FieldDef)member).IsPublic;
38 | if (member is PropertyDef)
39 | return ((PropertyDef)member).IsPublic();
40 | if (member is EventDef)
41 | return ((EventDef)member).IsPublic();
42 | if (member is TypeDef)
43 | return ((TypeDef)member).IsPublic || ((TypeDef)member).IsNestedPublic;
44 |
45 | throw new NotSupportedException();
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/IsTypeFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Text.RegularExpressions;
4 | using dnlib.DotNet;
5 |
6 | namespace Confuser.Core.Project.Patterns {
7 | ///
8 | /// A function that indicate the type of type(?).
9 | ///
10 | public class IsTypeFunction : PatternFunction {
11 | internal const string FnName = "is-type";
12 |
13 | ///
14 | public override string Name {
15 | get { return FnName; }
16 | }
17 |
18 | ///
19 | public override int ArgumentCount {
20 | get { return 1; }
21 | }
22 |
23 | ///
24 | public override object Evaluate(IDnlibDef definition) {
25 | TypeDef type = definition as TypeDef;
26 | if (type == null && definition is IMemberDef)
27 | type = ((IMemberDef)definition).DeclaringType;
28 | if (type == null)
29 | return false;
30 |
31 | string typeRegex = Arguments[0].Evaluate(definition).ToString();
32 |
33 | var typeType = new StringBuilder();
34 |
35 | if (type.IsEnum)
36 | typeType.Append("enum ");
37 |
38 | if (type.IsInterface)
39 | typeType.Append("interface ");
40 |
41 | if (type.IsValueType)
42 | typeType.Append("valuetype ");
43 |
44 | if (type.IsDelegate())
45 | typeType.Append("delegate ");
46 |
47 | if (type.IsAbstract)
48 | typeType.Append("abstract ");
49 |
50 | if (type.IsNested)
51 | typeType.Append("nested ");
52 |
53 | if (type.IsSerializable)
54 | typeType.Append("serializable ");
55 |
56 | return Regex.IsMatch(typeType.ToString(), typeRegex);
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/LiteralExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using dnlib.DotNet;
4 |
5 | namespace Confuser.Core.Project.Patterns {
6 | ///
7 | /// A literal expression.
8 | ///
9 | public class LiteralExpression : PatternExpression {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The literal.
14 | public LiteralExpression(object literal) {
15 | Literal = literal;
16 | }
17 |
18 | ///
19 | /// Gets the value of literal.
20 | ///
21 | /// The value of literal.
22 | public object Literal { get; private set; }
23 |
24 | ///
25 | public override object Evaluate(IDnlibDef definition) {
26 | return Literal;
27 | }
28 |
29 | ///
30 | public override void Serialize(IList tokens) {
31 | if (Literal is bool) {
32 | var value = (bool)Literal;
33 | tokens.Add(new PatternToken(TokenType.Identifier, value.ToString().ToLowerInvariant()));
34 | }
35 | else
36 | tokens.Add(new PatternToken(TokenType.Literal, Literal.ToString()));
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/MatchFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 | using dnlib.DotNet;
4 |
5 | namespace Confuser.Core.Project.Patterns {
6 | ///
7 | /// A function that match the full name of the definition with specified RegEx.
8 | ///
9 | public class MatchFunction : PatternFunction {
10 | internal const string FnName = "match";
11 |
12 | ///
13 | public override string Name {
14 | get { return FnName; }
15 | }
16 |
17 | ///
18 | public override int ArgumentCount {
19 | get { return 1; }
20 | }
21 |
22 | ///
23 | public override object Evaluate(IDnlibDef definition) {
24 | string regex = Arguments[0].Evaluate(definition).ToString();
25 | return Regex.IsMatch(definition.FullName, regex);
26 | }
27 | }
28 |
29 | ///
30 | /// A function that match the name of the definition with specified RegEx.
31 | ///
32 | public class MatchNameFunction : PatternFunction {
33 | internal const string FnName = "match-name";
34 |
35 | ///
36 | public override string Name {
37 | get { return FnName; }
38 | }
39 |
40 | ///
41 | public override int ArgumentCount {
42 | get { return 1; }
43 | }
44 |
45 | ///
46 | public override object Evaluate(IDnlibDef definition) {
47 | string regex = Arguments[0].Evaluate(definition).ToString();
48 | return Regex.IsMatch(definition.Name, regex);
49 | }
50 | }
51 |
52 | ///
53 | /// A function that match the name of declaring type with specified RegEx.
54 | ///
55 | public class MatchTypeNameFunction : PatternFunction {
56 | internal const string FnName = "match-type-name";
57 |
58 | ///
59 | public override string Name {
60 | get { return FnName; }
61 | }
62 |
63 | ///
64 | public override int ArgumentCount {
65 | get { return 1; }
66 | }
67 |
68 | ///
69 | public override object Evaluate(IDnlibDef definition) {
70 | if (definition is TypeDef) {
71 | string regex = Arguments[0].Evaluate(definition).ToString();
72 | return Regex.IsMatch(definition.Name, regex);
73 | }
74 | if (definition is IMemberDef && ((IMemberDef)definition).DeclaringType != null) {
75 | string regex = Arguments[0].Evaluate(definition).ToString();
76 | return Regex.IsMatch(((IMemberDef)definition).DeclaringType.Name, regex);
77 | }
78 | return false;
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/MemberTypeFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Text.RegularExpressions;
4 | using dnlib.DotNet;
5 |
6 | namespace Confuser.Core.Project.Patterns {
7 | ///
8 | /// A function that compare the type of definition.
9 | ///
10 | public class MemberTypeFunction : PatternFunction {
11 | internal const string FnName = "member-type";
12 |
13 | ///
14 | public override string Name {
15 | get { return FnName; }
16 | }
17 |
18 | ///
19 | public override int ArgumentCount {
20 | get { return 1; }
21 | }
22 |
23 | ///
24 | public override object Evaluate(IDnlibDef definition) {
25 | string typeRegex = Arguments[0].Evaluate(definition).ToString();
26 |
27 | var memberType = new StringBuilder();
28 |
29 | if (definition is TypeDef)
30 | memberType.Append("type ");
31 |
32 | if (definition is MethodDef) {
33 | memberType.Append("method ");
34 |
35 | var method = (MethodDef)definition;
36 | if (method.IsGetter)
37 | memberType.Append("propertym getter ");
38 | else if (method.IsSetter)
39 | memberType.Append("propertym setter ");
40 | else if (method.IsAddOn)
41 | memberType.Append("eventm add ");
42 | else if (method.IsRemoveOn)
43 | memberType.Append("eventm remove ");
44 | else if (method.IsFire)
45 | memberType.Append("eventm fire ");
46 | else if (method.IsOther)
47 | memberType.Append("other ");
48 | }
49 |
50 | if (definition is FieldDef)
51 | memberType.Append("field ");
52 |
53 | if (definition is PropertyDef)
54 | memberType.Append("property ");
55 |
56 | if (definition is EventDef)
57 | memberType.Append("event ");
58 |
59 | if (definition is ModuleDef)
60 | memberType.Append("module ");
61 |
62 | return Regex.IsMatch(memberType.ToString(), typeRegex);
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/ModuleFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A function that compare the module of definition.
7 | ///
8 | public class ModuleFunction : PatternFunction {
9 | internal const string FnName = "module";
10 |
11 | ///
12 | public override string Name {
13 | get { return FnName; }
14 | }
15 |
16 | ///
17 | public override int ArgumentCount {
18 | get { return 1; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | if (!(definition is IOwnerModule) && !(definition is IModule))
24 | return false;
25 | object name = Arguments[0].Evaluate(definition);
26 | if (definition is IModule)
27 | return ((IModule)definition).Name == name.ToString();
28 | return ((IOwnerModule)definition).Module.Name == name.ToString();
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/NameFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A function that compare the name of definition.
7 | ///
8 | public class NameFunction : PatternFunction {
9 | internal const string FnName = "name";
10 |
11 | ///
12 | public override string Name {
13 | get { return FnName; }
14 | }
15 |
16 | ///
17 | public override int ArgumentCount {
18 | get { return 1; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | object name = Arguments[0].Evaluate(definition);
24 | return definition.Name == name.ToString();
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/NamespaceFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 | using dnlib.DotNet;
4 |
5 | namespace Confuser.Core.Project.Patterns {
6 | ///
7 | /// A function that compare the namespace of definition.
8 | ///
9 | public class NamespaceFunction : PatternFunction {
10 | internal const string FnName = "namespace";
11 |
12 | ///
13 | public override string Name {
14 | get { return FnName; }
15 | }
16 |
17 | ///
18 | public override int ArgumentCount {
19 | get { return 1; }
20 | }
21 |
22 | ///
23 | public override object Evaluate(IDnlibDef definition) {
24 | if (!(definition is TypeDef) && !(definition is IMemberDef))
25 | return false;
26 | var ns = "^" + Arguments[0].Evaluate(definition).ToString() + "$";
27 |
28 | var type = definition as TypeDef;
29 | if (type == null)
30 | type = ((IMemberDef)definition).DeclaringType;
31 |
32 | if (type == null)
33 | return false;
34 |
35 | while (type.IsNested)
36 | type = type.DeclaringType;
37 |
38 | return type != null && Regex.IsMatch(type.Namespace ?? "", ns);
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/NotOperator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// The NOT operator.
7 | ///
8 | public class NotOperator : PatternOperator {
9 | internal const string OpName = "not";
10 |
11 | ///
12 | public override string Name {
13 | get { return OpName; }
14 | }
15 |
16 | ///
17 | public override bool IsUnary {
18 | get { return true; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | return !(bool)OperandA.Evaluate(definition);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/OrOperator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// The OR operator.
7 | ///
8 | public class OrOperator : PatternOperator {
9 | internal const string OpName = "or";
10 |
11 | ///
12 | public override string Name {
13 | get { return OpName; }
14 | }
15 |
16 | ///
17 | public override bool IsUnary {
18 | get { return false; }
19 | }
20 |
21 | ///
22 | public override object Evaluate(IDnlibDef definition) {
23 | var a = (bool)OperandA.Evaluate(definition);
24 | if (a) return true;
25 | return (bool)OperandB.Evaluate(definition);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/PatternExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using dnlib.DotNet;
4 |
5 | namespace Confuser.Core.Project.Patterns {
6 | ///
7 | /// A pattern expression.
8 | ///
9 | public abstract class PatternExpression {
10 | ///
11 | /// Evaluates the expression on the specified definition.
12 | ///
13 | /// The definition.
14 | /// The result value.
15 | public abstract object Evaluate(IDnlibDef definition);
16 |
17 | ///
18 | /// Serializes the expression into tokens.
19 | ///
20 | /// The output list of tokens.
21 | public abstract void Serialize(IList tokens);
22 | }
23 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/PatternFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A pattern function.
7 | ///
8 | public abstract class PatternFunction : PatternExpression {
9 | ///
10 | /// Gets the name of function.
11 | ///
12 | /// The name.
13 | public abstract string Name { get; }
14 |
15 | ///
16 | /// Gets the number of arguments of the function.
17 | ///
18 | /// The number of arguments.
19 | public abstract int ArgumentCount { get; }
20 |
21 | ///
22 | /// Gets or sets the arguments of function.
23 | ///
24 | /// The arguments.
25 | public IList Arguments { get; set; }
26 |
27 | ///
28 | public override void Serialize(IList tokens) {
29 | tokens.Add(new PatternToken(TokenType.Identifier, Name));
30 | tokens.Add(new PatternToken(TokenType.LParens));
31 | for (int i = 0; i < Arguments.Count; i++) {
32 | if (i != 0)
33 | tokens.Add(new PatternToken(TokenType.Comma));
34 | Arguments[i].Serialize(tokens);
35 | }
36 | tokens.Add(new PatternToken(TokenType.RParens));
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/Confuser.Core/Project/Patterns/PatternOperator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Confuser.Core.Project.Patterns {
5 | ///
6 | /// A pattern operator.
7 | ///
8 | public abstract class PatternOperator : PatternExpression {
9 | ///
10 | /// Gets the name of operator.
11 | ///
12 | /// The name.
13 | public abstract string Name { get; }
14 |
15 | ///
16 | /// Gets a value indicating whether this is an unary operator.
17 | ///
18 | /// true if this is an unary operator; otherwise, false.
19 | public abstract bool IsUnary { get; }
20 |
21 | ///
22 | /// Gets or sets the first operand.
23 | ///
24 | /// The first operand.
25 | public PatternExpression OperandA { get; set; }
26 |
27 | ///
28 | /// Gets or sets the second operand.
29 | ///
30 | /// The second operand.
31 | public PatternExpression OperandB { get; set; }
32 |
33 | ///
34 | public override void Serialize(IList tokens) {
35 | if (IsUnary) {
36 | tokens.Add(new PatternToken(TokenType.Identifier, Name));
37 | OperandA.Serialize(tokens);
38 | }
39 | else {
40 | OperandA.Serialize(tokens);
41 | tokens.Add(new PatternToken(TokenType.Identifier, Name));
42 | OperandB.Serialize(tokens);
43 | }
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/Confuser.Core/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | [assembly: AssemblyTitle("ConfuserEx Core")]
5 | [assembly: AssemblyDescription("Core framework of ConfuserEx")]
--------------------------------------------------------------------------------
/Confuser.Core/Protection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core {
4 | ///
5 | /// Base class of Confuser protections.
6 | ///
7 | ///
8 | /// A parameterless constructor must exists in derived classes to enable plugin discovery.
9 | ///
10 | public abstract class Protection : ConfuserComponent {
11 | ///
12 | /// Gets the preset this protection is in.
13 | ///
14 | /// The protection's preset.
15 | public abstract ProtectionPreset Preset { get; }
16 | }
17 | }
--------------------------------------------------------------------------------
/Confuser.Core/ProtectionDependencyAttributes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core {
4 | ///
5 | /// Indicates the must initialize before the specified protections.
6 | ///
7 | [AttributeUsage(AttributeTargets.Class)]
8 | public class BeforeProtectionAttribute : Attribute {
9 | ///
10 | /// Initializes a new instance of the class.
11 | ///
12 | /// The full IDs of the specified protections.
13 | public BeforeProtectionAttribute(params string[] ids) {
14 | Ids = ids;
15 | }
16 |
17 | ///
18 | /// Gets the full IDs of the specified protections.
19 | ///
20 | /// The IDs of protections.
21 | public string[] Ids { get; private set; }
22 | }
23 |
24 | ///
25 | /// Indicates the must initialize after the specified protections.
26 | ///
27 | [AttributeUsage(AttributeTargets.Class)]
28 | public class AfterProtectionAttribute : Attribute {
29 | ///
30 | /// Initializes a new instance of the class.
31 | ///
32 | /// The full IDs of the specified protections.
33 | public AfterProtectionAttribute(params string[] ids) {
34 | Ids = ids;
35 | }
36 |
37 | ///
38 | /// Gets the full IDs of the specified protections.
39 | ///
40 | /// The IDs of protections.
41 | public string[] Ids { get; private set; }
42 | }
43 | }
--------------------------------------------------------------------------------
/Confuser.Core/ProtectionPhase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core {
4 | ///
5 | /// Base class of protection phases.
6 | ///
7 | public abstract class ProtectionPhase {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The parent component of this phase.
12 | public ProtectionPhase(ConfuserComponent parent) {
13 | Parent = parent;
14 | }
15 |
16 | ///
17 | /// Gets the parent component.
18 | ///
19 | /// The parent component.
20 | public ConfuserComponent Parent { get; private set; }
21 |
22 | ///
23 | /// Gets the targets of protection.
24 | ///
25 | /// The protection targets.
26 | public abstract ProtectionTargets Targets { get; }
27 |
28 | ///
29 | /// Gets the name of the phase.
30 | ///
31 | /// The name of phase.
32 | public abstract string Name { get; }
33 |
34 | ///
35 | /// Gets a value indicating whether this phase process all targets, not just the targets that requires the component.
36 | ///
37 | /// true if this phase process all targets; otherwise, false.
38 | public virtual bool ProcessAll {
39 | get { return false; }
40 | }
41 |
42 | ///
43 | /// Executes the protection phase.
44 | ///
45 | /// The working context.
46 | /// The parameters of protection.
47 | protected internal abstract void Execute(ConfuserContext context, ProtectionParameters parameters);
48 | }
49 | }
--------------------------------------------------------------------------------
/Confuser.Core/ProtectionPreset.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core {
4 | ///
5 | /// Various presets of protections.
6 | ///
7 | public enum ProtectionPreset {
8 | /// The protection does not belong to any preset.
9 | None = 0,
10 |
11 | /// The protection provides basic security.
12 | Minimum = 1,
13 |
14 | /// The protection provides normal security for public release.
15 | Normal = 2,
16 |
17 | /// The protection provides better security with observable performance impact.
18 | Aggressive = 3,
19 |
20 | /// The protection provides strongest security with possible incompatibility.
21 | Maximum = 4
22 | }
23 | }
--------------------------------------------------------------------------------
/Confuser.Core/ProtectionSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Confuser.Core {
5 | ///
6 | /// Protection settings for a certain component
7 | ///
8 | public class ProtectionSettings : Dictionary> {
9 | ///
10 | /// Initializes a new instance of the class.
11 | ///
12 | public ProtectionSettings() { }
13 |
14 | ///
15 | /// Initializes a new instance of the class
16 | /// from an existing .
17 | ///
18 | /// The settings to copy from.
19 | public ProtectionSettings(ProtectionSettings settings) {
20 | if (settings == null)
21 | return;
22 |
23 | foreach (var i in settings)
24 | Add(i.Key, new Dictionary(i.Value));
25 | }
26 |
27 | ///
28 | /// Determines whether the settings is empty.
29 | ///
30 | /// true if the settings is empty; otherwise, false.
31 | public bool IsEmpty() {
32 | return Count == 0;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/Confuser.Core/ProtectionTargets.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core {
4 | ///
5 | /// Targets of protection.
6 | ///
7 | [Flags]
8 | public enum ProtectionTargets {
9 | /// Type definitions.
10 | Types = 1,
11 |
12 | /// Method definitions.
13 | Methods = 2,
14 |
15 | /// Field definitions.
16 | Fields = 4,
17 |
18 | /// Event definitions.
19 | Events = 8,
20 |
21 | /// Property definitions.
22 | Properties = 16,
23 |
24 | /// All member definitions (i.e. type, methods, fields, events and properties).
25 | AllMembers = Types | Methods | Fields | Events | Properties,
26 |
27 | /// Module definitions.
28 | Modules = 32,
29 |
30 | /// All definitions (i.e. All member definitions and modules).
31 | AllDefinitions = AllMembers | Modules
32 | }
33 | }
--------------------------------------------------------------------------------
/Confuser.Core/ServiceRegistry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Confuser.Core {
5 | ///
6 | /// A registry of different services provided by protections
7 | ///
8 | public class ServiceRegistry : IServiceProvider {
9 | readonly HashSet serviceIds = new HashSet();
10 | readonly Dictionary services = new Dictionary();
11 |
12 | ///
13 | object IServiceProvider.GetService(Type serviceType) {
14 | return services.GetValueOrDefault(serviceType, null);
15 | }
16 |
17 | ///
18 | /// Retrieves the service of type .
19 | ///
20 | /// The type of service.
21 | /// The service instance.
22 | public T GetService() {
23 | return (T)services.GetValueOrDefault(typeof(T), null);
24 | }
25 |
26 | ///
27 | /// Registers the service with specified ID .
28 | ///
29 | /// The service identifier.
30 | /// The service type.
31 | /// The service.
32 | /// Service with same ID or type has already registered.
33 | public void RegisterService(string serviceId, Type serviceType, object service) {
34 | if (!serviceIds.Add(serviceId))
35 | throw new ArgumentException("Service with ID '" + serviceIds + "' has already registered.", "serviceId");
36 | if (services.ContainsKey(serviceType))
37 | throw new ArgumentException("Service with type '" + service.GetType().Name + "' has already registered.", "service");
38 | services.Add(serviceType, service);
39 | }
40 |
41 | ///
42 | /// Determines whether the service with specified identifier has already registered.
43 | ///
44 | /// The service identifier.
45 | /// true if the service with specified identifier has already registered; otherwise, false.
46 | public bool Contains(string serviceId) {
47 | return serviceIds.Contains(serviceId);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/Confuser.Core/Services/RuntimeService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using dnlib.DotNet;
5 |
6 | namespace Confuser.Core.Services {
7 | internal class RuntimeService : IRuntimeService {
8 | ModuleDef rtModule;
9 |
10 | ///
11 | public TypeDef GetRuntimeType(string fullName) {
12 | if (rtModule == null) {
13 | Module module = typeof(RuntimeService).Assembly.ManifestModule;
14 | string rtPath = "Confuser.Runtime.dll";
15 | if (module.FullyQualifiedName[0] != '<')
16 | rtPath = Path.Combine(Path.GetDirectoryName(module.FullyQualifiedName), rtPath);
17 | rtModule = ModuleDefMD.Load(rtPath, new ModuleCreationOptions() { TryToLoadPdbFromDisk = true });
18 | rtModule.EnableTypeDefFindCache = true;
19 | }
20 | return rtModule.Find(fullName, true);
21 | }
22 | }
23 |
24 | ///
25 | /// Provides methods to obtain runtime library injection type.
26 | ///
27 | public interface IRuntimeService {
28 | ///
29 | /// Gets the specified runtime type for injection.
30 | ///
31 | /// The full name of the runtime type.
32 | /// The requested runtime type.
33 | TypeDef GetRuntimeType(string fullName);
34 | }
35 | }
--------------------------------------------------------------------------------
/Confuser.Core/UnreachableException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Core {
4 | ///
5 | /// The exception that is thrown when supposedly unreachable code is executed.
6 | ///
7 | public class UnreachableException : SystemException {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | public UnreachableException() :
12 | base("Unreachable code reached.") { }
13 | }
14 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/ArrayIndexExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public class ArrayIndexExpression : Expression {
5 | public Expression Array { get; set; }
6 | public int Index { get; set; }
7 |
8 | public override string ToString() {
9 | return string.Format("{0}[{1}]", Array, Index);
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/AssignmentStatement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public class AssignmentStatement : Statement {
5 | public Expression Target { get; set; }
6 | public Expression Value { get; set; }
7 |
8 | public override string ToString() {
9 | return string.Format("{0} = {1};", Target, Value);
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/BinOpExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public enum BinOps {
5 | Add,
6 | Sub,
7 | Div,
8 | Mul,
9 | Or,
10 | And,
11 | Xor,
12 | Lsh,
13 | Rsh
14 | }
15 |
16 | public class BinOpExpression : Expression {
17 | public Expression Left { get; set; }
18 | public Expression Right { get; set; }
19 | public BinOps Operation { get; set; }
20 |
21 | public override string ToString() {
22 | string op;
23 | switch (Operation) {
24 | case BinOps.Add:
25 | op = "+";
26 | break;
27 | case BinOps.Sub:
28 | op = "-";
29 | break;
30 | case BinOps.Div:
31 | op = "/";
32 | break;
33 | case BinOps.Mul:
34 | op = "*";
35 | break;
36 | case BinOps.Or:
37 | op = "|";
38 | break;
39 | case BinOps.And:
40 | op = "&";
41 | break;
42 | case BinOps.Xor:
43 | op = "^";
44 | break;
45 | case BinOps.Lsh:
46 | op = "<<";
47 | break;
48 | case BinOps.Rsh:
49 | op = ">>";
50 | break;
51 | default:
52 | throw new Exception();
53 | }
54 | return string.Format("({0} {1} {2})", Left, op, Right);
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/Expression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public abstract class Expression {
5 | public object Tag { get; set; }
6 | public abstract override string ToString();
7 |
8 | public static BinOpExpression operator +(Expression a, Expression b) {
9 | return new BinOpExpression {
10 | Left = a,
11 | Right = b,
12 | Operation = BinOps.Add
13 | };
14 | }
15 |
16 | public static BinOpExpression operator -(Expression a, Expression b) {
17 | return new BinOpExpression {
18 | Left = a,
19 | Right = b,
20 | Operation = BinOps.Sub
21 | };
22 | }
23 |
24 | public static BinOpExpression operator *(Expression a, Expression b) {
25 | return new BinOpExpression {
26 | Left = a,
27 | Right = b,
28 | Operation = BinOps.Mul
29 | };
30 | }
31 |
32 | public static BinOpExpression operator >>(Expression a, int b) {
33 | return new BinOpExpression {
34 | Left = a,
35 | Right = (LiteralExpression)(uint)b,
36 | Operation = BinOps.Rsh
37 | };
38 | }
39 |
40 | public static BinOpExpression operator <<(Expression a, int b) {
41 | return new BinOpExpression {
42 | Left = a,
43 | Right = (LiteralExpression)(uint)b,
44 | Operation = BinOps.Lsh
45 | };
46 | }
47 |
48 | public static BinOpExpression operator |(Expression a, Expression b) {
49 | return new BinOpExpression {
50 | Left = a,
51 | Right = b,
52 | Operation = BinOps.Or
53 | };
54 | }
55 |
56 | public static BinOpExpression operator &(Expression a, Expression b) {
57 | return new BinOpExpression {
58 | Left = a,
59 | Right = b,
60 | Operation = BinOps.And
61 | };
62 | }
63 |
64 | public static BinOpExpression operator ^(Expression a, Expression b) {
65 | return new BinOpExpression {
66 | Left = a,
67 | Right = b,
68 | Operation = BinOps.Xor
69 | };
70 | }
71 |
72 | public static UnaryOpExpression operator ~(Expression val) {
73 | return new UnaryOpExpression {
74 | Value = val,
75 | Operation = UnaryOps.Not
76 | };
77 | }
78 |
79 | public static UnaryOpExpression operator -(Expression val) {
80 | return new UnaryOpExpression {
81 | Value = val,
82 | Operation = UnaryOps.Negate
83 | };
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/LiteralExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public class LiteralExpression : Expression {
5 | public uint Value { get; set; }
6 |
7 | public static implicit operator LiteralExpression(uint val) {
8 | return new LiteralExpression { Value = val };
9 | }
10 |
11 | public override string ToString() {
12 | return Value.ToString("x8") + "h";
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/LoopStatement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace Confuser.DynCipher.AST {
5 | // i.e. for loop
6 | public class LoopStatement : StatementBlock {
7 | public int Begin { get; set; }
8 | public int Limit { get; set; }
9 |
10 | public override string ToString() {
11 | var ret = new StringBuilder();
12 | ret.AppendFormat("for (int i = {0}; i < {1}; i++)", Begin, Limit);
13 | ret.AppendLine();
14 | ret.Append(base.ToString());
15 | return ret.ToString();
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/Statement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public abstract class Statement {
5 | public object Tag { get; set; }
6 | public abstract override string ToString();
7 | }
8 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/StatementBlock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Confuser.DynCipher.AST {
6 | public class StatementBlock : Statement {
7 | public StatementBlock() {
8 | Statements = new List();
9 | }
10 |
11 | public IList Statements { get; private set; }
12 |
13 | public override string ToString() {
14 | var sb = new StringBuilder();
15 | sb.AppendLine("{");
16 | foreach (Statement i in Statements)
17 | sb.AppendLine(i.ToString());
18 | sb.AppendLine("}");
19 | return sb.ToString();
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/UnaryOpExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public enum UnaryOps {
5 | Not,
6 | Negate
7 | }
8 |
9 | public class UnaryOpExpression : Expression {
10 | public Expression Value { get; set; }
11 | public UnaryOps Operation { get; set; }
12 |
13 | public override string ToString() {
14 | string op;
15 | switch (Operation) {
16 | case UnaryOps.Not:
17 | op = "~";
18 | break;
19 | case UnaryOps.Negate:
20 | op = "-";
21 | break;
22 | default:
23 | throw new Exception();
24 | }
25 | return op + Value;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/Variable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public class Variable {
5 | public Variable(string name) {
6 | Name = name;
7 | }
8 |
9 | public string Name { get; set; }
10 | public object Tag { get; set; }
11 |
12 | public override string ToString() {
13 | return Name;
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/AST/VariableExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.DynCipher.AST {
4 | public class VariableExpression : Expression {
5 | public Variable Variable { get; set; }
6 |
7 | public override string ToString() {
8 | return Variable.Name;
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/DynCipherComponent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core;
3 |
4 | namespace Confuser.DynCipher {
5 | internal class DynCipherComponent : ConfuserComponent {
6 | public const string _ServiceId = "Confuser.DynCipher";
7 |
8 | public override string Name {
9 | get { return "Dynamic Cipher"; }
10 | }
11 |
12 | public override string Description {
13 | get { return "Provides dynamic cipher generation services."; }
14 | }
15 |
16 | public override string Id {
17 | get { return _ServiceId; }
18 | }
19 |
20 | public override string FullId {
21 | get { return _ServiceId; }
22 | }
23 |
24 | protected override void Initialize(ConfuserContext context) {
25 | context.Registry.RegisterService(_ServiceId, typeof(IDynCipherService), new DynCipherService());
26 | }
27 |
28 | protected override void PopulatePipeline(ProtectionPipeline pipeline) {
29 | //
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/DynCipherService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core.Services;
3 | using Confuser.DynCipher.AST;
4 | using Confuser.DynCipher.Generation;
5 |
6 | namespace Confuser.DynCipher {
7 | public interface IDynCipherService {
8 | void GenerateCipherPair(RandomGenerator random, out StatementBlock encrypt, out StatementBlock decrypt);
9 | void GenerateExpressionPair(RandomGenerator random, Expression var, Expression result, int depth, out Expression expression, out Expression inverse);
10 | }
11 |
12 | internal class DynCipherService : IDynCipherService {
13 | public void GenerateCipherPair(RandomGenerator random, out StatementBlock encrypt, out StatementBlock decrypt) {
14 | CipherGenerator.GeneratePair(random, out encrypt, out decrypt);
15 | }
16 |
17 | public void GenerateExpressionPair(RandomGenerator random, Expression var, Expression result, int depth, out Expression expression, out Expression inverse) {
18 | ExpressionGenerator.GeneratePair(random, var, result, depth, out expression, out inverse);
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Elements/AddKey.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core.Services;
3 | using Confuser.DynCipher.AST;
4 | using Confuser.DynCipher.Generation;
5 |
6 | namespace Confuser.DynCipher.Elements {
7 | internal class AddKey : CryptoElement {
8 | public AddKey(int index)
9 | : base(0) {
10 | Index = index;
11 | }
12 |
13 | public int Index { get; private set; }
14 |
15 | public override void Initialize(RandomGenerator random) { }
16 |
17 | void EmitCore(CipherGenContext context) {
18 | Expression val = context.GetDataExpression(Index);
19 |
20 | context.Emit(new AssignmentStatement {
21 | Value = val ^ context.GetKeyExpression(Index),
22 | Target = val
23 | });
24 | }
25 |
26 | public override void Emit(CipherGenContext context) {
27 | EmitCore(context);
28 | }
29 |
30 | public override void EmitInverse(CipherGenContext context) {
31 | EmitCore(context);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Elements/BinOp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core.Services;
3 | using Confuser.DynCipher.AST;
4 | using Confuser.DynCipher.Generation;
5 |
6 | namespace Confuser.DynCipher.Elements {
7 | internal enum CryptoBinOps {
8 | Add,
9 | Xor,
10 | Xnor
11 | }
12 |
13 | internal class BinOp : CryptoElement {
14 | public BinOp()
15 | : base(2) { }
16 |
17 | public CryptoBinOps Operation { get; private set; }
18 |
19 | public override void Initialize(RandomGenerator random) {
20 | Operation = (CryptoBinOps)random.NextInt32(3);
21 | }
22 |
23 | public override void Emit(CipherGenContext context) {
24 | Expression a = context.GetDataExpression(DataIndexes[0]);
25 | Expression b = context.GetDataExpression(DataIndexes[1]);
26 | switch (Operation) {
27 | case CryptoBinOps.Add:
28 | context.Emit(new AssignmentStatement {
29 | Value = a + b,
30 | Target = a
31 | });
32 | break;
33 | case CryptoBinOps.Xor:
34 | context.Emit(new AssignmentStatement {
35 | Value = a ^ b,
36 | Target = a
37 | });
38 | break;
39 | case CryptoBinOps.Xnor:
40 | context.Emit(new AssignmentStatement {
41 | Value = ~(a ^ b),
42 | Target = a
43 | });
44 | break;
45 | }
46 | }
47 |
48 | public override void EmitInverse(CipherGenContext context) {
49 | Expression a = context.GetDataExpression(DataIndexes[0]);
50 | Expression b = context.GetDataExpression(DataIndexes[1]);
51 | switch (Operation) {
52 | case CryptoBinOps.Add:
53 | context.Emit(new AssignmentStatement {
54 | Value = a - b,
55 | Target = a
56 | });
57 | break;
58 | case CryptoBinOps.Xor:
59 | context.Emit(new AssignmentStatement {
60 | Value = a ^ b,
61 | Target = a
62 | });
63 | break;
64 | case CryptoBinOps.Xnor:
65 | context.Emit(new AssignmentStatement {
66 | Value = a ^ (~b),
67 | Target = a
68 | });
69 | break;
70 | }
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Elements/CryptoElement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core.Services;
3 | using Confuser.DynCipher.Generation;
4 |
5 | namespace Confuser.DynCipher.Elements {
6 | internal abstract class CryptoElement {
7 | public CryptoElement(int count) {
8 | DataCount = count;
9 | DataIndexes = new int[count];
10 | }
11 |
12 | public int DataCount { get; private set; }
13 | public int[] DataIndexes { get; private set; }
14 |
15 | public abstract void Initialize(RandomGenerator random);
16 | public abstract void Emit(CipherGenContext context);
17 | public abstract void EmitInverse(CipherGenContext context);
18 | }
19 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Elements/RotateBit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core.Services;
3 | using Confuser.DynCipher.AST;
4 | using Confuser.DynCipher.Generation;
5 |
6 | namespace Confuser.DynCipher.Elements {
7 | internal class RotateBit : CryptoElement {
8 | public RotateBit()
9 | : base(1) { }
10 |
11 | public int Bits { get; private set; }
12 | public bool IsAlternate { get; private set; }
13 |
14 | public override void Initialize(RandomGenerator random) {
15 | Bits = random.NextInt32(1, 32);
16 | IsAlternate = (random.NextInt32() % 2 == 0);
17 | }
18 |
19 | public override void Emit(CipherGenContext context) {
20 | Expression val = context.GetDataExpression(DataIndexes[0]);
21 | VariableExpression tmp;
22 | using (context.AcquireTempVar(out tmp)) {
23 | if (IsAlternate)
24 | context.Emit(new AssignmentStatement {
25 | Value = (val >> (32 - Bits)),
26 | Target = tmp
27 | }).Emit(new AssignmentStatement {
28 | Value = (val << Bits) | tmp,
29 | Target = val
30 | });
31 | else
32 | context.Emit(new AssignmentStatement {
33 | Value = (val << (32 - Bits)),
34 | Target = tmp
35 | }).Emit(new AssignmentStatement {
36 | Value = (val >> Bits) | tmp,
37 | Target = val
38 | });
39 | }
40 | }
41 |
42 | public override void EmitInverse(CipherGenContext context) {
43 | Expression val = context.GetDataExpression(DataIndexes[0]);
44 | VariableExpression tmp;
45 | using (context.AcquireTempVar(out tmp)) {
46 | if (IsAlternate)
47 | context.Emit(new AssignmentStatement {
48 | Value = (val << (32 - Bits)),
49 | Target = tmp
50 | }).Emit(new AssignmentStatement {
51 | Value = (val >> Bits) | tmp,
52 | Target = val
53 | });
54 | else
55 | context.Emit(new AssignmentStatement {
56 | Value = (val >> (32 - Bits)),
57 | Target = tmp
58 | }).Emit(new AssignmentStatement {
59 | Value = (val << Bits) | tmp,
60 | Target = val
61 | });
62 | }
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Elements/Swap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core.Services;
3 | using Confuser.DynCipher.AST;
4 | using Confuser.DynCipher.Generation;
5 |
6 | namespace Confuser.DynCipher.Elements {
7 | internal class Swap : CryptoElement {
8 | public Swap()
9 | : base(2) { }
10 |
11 | public uint Mask { get; private set; }
12 | public uint Key { get; private set; }
13 |
14 | public override void Initialize(RandomGenerator random) {
15 | if (random.NextInt32(3) == 0)
16 | Mask = 0xffffffff;
17 | else
18 | Mask = random.NextUInt32();
19 | Key = random.NextUInt32() | 1;
20 | }
21 |
22 | void EmitCore(CipherGenContext context) {
23 | Expression a = context.GetDataExpression(DataIndexes[0]);
24 | Expression b = context.GetDataExpression(DataIndexes[1]);
25 | VariableExpression tmp;
26 |
27 | if (Mask == 0xffffffff) {
28 | /* t = a * k;
29 | a = b;
30 | b = t * k^-1;
31 | */
32 | using (context.AcquireTempVar(out tmp)) {
33 | context.Emit(new AssignmentStatement {
34 | Value = a * (LiteralExpression)Key,
35 | Target = tmp
36 | }).Emit(new AssignmentStatement {
37 | Value = b,
38 | Target = a
39 | }).Emit(new AssignmentStatement {
40 | Value = tmp * (LiteralExpression)MathsUtils.modInv(Key),
41 | Target = b
42 | });
43 | }
44 | }
45 | else {
46 | var mask = (LiteralExpression)Mask;
47 | var notMask = (LiteralExpression)~Mask;
48 | /* t = (a & mask) * k;
49 | a = a & (~mask) | (b & mask);
50 | b = b & (~mask) | (t * k^-1);
51 | */
52 | using (context.AcquireTempVar(out tmp)) {
53 | context.Emit(new AssignmentStatement {
54 | Value = (a & mask) * (LiteralExpression)Key,
55 | Target = tmp
56 | }).Emit(new AssignmentStatement {
57 | Value = (a & notMask) | (b & mask),
58 | Target = a
59 | }).Emit(new AssignmentStatement {
60 | Value = (b & notMask) | (tmp * (LiteralExpression)MathsUtils.modInv(Key)),
61 | Target = b
62 | });
63 | }
64 | }
65 | }
66 |
67 | public override void Emit(CipherGenContext context) {
68 | EmitCore(context);
69 | }
70 |
71 | public override void EmitInverse(CipherGenContext context) {
72 | EmitCore(context);
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Generation/CipherGenContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core.Services;
4 | using Confuser.DynCipher.AST;
5 |
6 | namespace Confuser.DynCipher.Generation {
7 | internal class CipherGenContext {
8 | readonly Variable[] dataVars;
9 | readonly Variable keyVar = new Variable("{KEY}");
10 | readonly RandomGenerator random;
11 | readonly List tempVars = new List();
12 | int tempVarCounter;
13 |
14 | public CipherGenContext(RandomGenerator random, int dataVarCount) {
15 | this.random = random;
16 | Block = new StatementBlock(); // new LoopStatement() { Begin = 0, Limit = 4 };
17 | dataVars = new Variable[dataVarCount];
18 | for (int i = 0; i < dataVarCount; i++)
19 | dataVars[i] = new Variable("v" + i) { Tag = i };
20 | }
21 |
22 | public StatementBlock Block { get; private set; }
23 |
24 | public Expression GetDataExpression(int index) {
25 | return new VariableExpression { Variable = dataVars[index] };
26 | }
27 |
28 | public Expression GetKeyExpression(int index) {
29 | return new ArrayIndexExpression {
30 | Array = new VariableExpression { Variable = keyVar },
31 | Index = index
32 | };
33 | }
34 |
35 | public CipherGenContext Emit(Statement statement) {
36 | Block.Statements.Add(statement);
37 | return this;
38 | }
39 |
40 | public IDisposable AcquireTempVar(out VariableExpression exp) {
41 | Variable var;
42 | if (tempVars.Count == 0)
43 | var = new Variable("t" + tempVarCounter++);
44 | else {
45 | var = tempVars[random.NextInt32(tempVars.Count)];
46 | tempVars.Remove(var);
47 | }
48 | exp = new VariableExpression { Variable = var };
49 | return new TempVarHolder(this, var);
50 | }
51 |
52 | struct TempVarHolder : IDisposable {
53 | readonly CipherGenContext parent;
54 | readonly Variable tempVar;
55 |
56 | public TempVarHolder(CipherGenContext p, Variable v) {
57 | parent = p;
58 | tempVar = v;
59 | }
60 |
61 | public void Dispose() {
62 | parent.tempVars.Add(tempVar);
63 | }
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | [assembly: AssemblyTitle("ConfuserEx Dynamic Cipher Library")]
5 | [assembly: AssemblyDescription("Cipher generator of ConfuserEx")]
--------------------------------------------------------------------------------
/Confuser.DynCipher/Transforms/ConvertVariables.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.DynCipher.AST;
3 |
4 | namespace Confuser.DynCipher.Transforms {
5 | internal class ConvertVariables {
6 | static Expression ReplaceVar(Expression exp, Variable buff) {
7 | if (exp is VariableExpression) {
8 | if (((VariableExpression)exp).Variable.Name[0] != 'v') return exp;
9 | return new ArrayIndexExpression {
10 | Array = new VariableExpression { Variable = buff },
11 | Index = (int)(exp as VariableExpression).Variable.Tag
12 | };
13 | }
14 | if (exp is ArrayIndexExpression) {
15 | ((ArrayIndexExpression)exp).Array = ReplaceVar(((ArrayIndexExpression)exp).Array, buff);
16 | }
17 | else if (exp is BinOpExpression) {
18 | ((BinOpExpression)exp).Left = ReplaceVar(((BinOpExpression)exp).Left, buff);
19 | ((BinOpExpression)exp).Right = ReplaceVar(((BinOpExpression)exp).Right, buff);
20 | }
21 | else if (exp is UnaryOpExpression) {
22 | ((UnaryOpExpression)exp).Value = ReplaceVar(((UnaryOpExpression)exp).Value, buff);
23 | }
24 | return exp;
25 | }
26 |
27 | static Statement ReplaceVar(Statement st, Variable buff) {
28 | if (st is AssignmentStatement) {
29 | ((AssignmentStatement)st).Value = ReplaceVar(((AssignmentStatement)st).Value, buff);
30 | ((AssignmentStatement)st).Target = ReplaceVar(((AssignmentStatement)st).Target, buff);
31 | }
32 | return st;
33 | }
34 |
35 | public static void Run(StatementBlock block) {
36 | var mainBuff = new Variable("{BUFFER}");
37 | for (int i = 0; i < block.Statements.Count; i++)
38 | block.Statements[i] = ReplaceVar(block.Statements[i], mainBuff);
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Transforms/ExpansionTransform.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Confuser.DynCipher.AST;
4 |
5 | namespace Confuser.DynCipher.Transforms {
6 | internal class ExpansionTransform {
7 | static bool ProcessStatement(Statement st, StatementBlock block) {
8 | if (st is AssignmentStatement) {
9 | var assign = (AssignmentStatement)st;
10 | if (assign.Value is BinOpExpression) {
11 | var exp = (BinOpExpression)assign.Value;
12 | if ((exp.Left is BinOpExpression || exp.Right is BinOpExpression) &&
13 | exp.Left != assign.Target) {
14 | block.Statements.Add(new AssignmentStatement {
15 | Target = assign.Target,
16 | Value = exp.Left
17 | });
18 | block.Statements.Add(new AssignmentStatement {
19 | Target = assign.Target,
20 | Value = new BinOpExpression {
21 | Left = assign.Target,
22 | Operation = exp.Operation,
23 | Right = exp.Right
24 | }
25 | });
26 | return true;
27 | }
28 | }
29 | }
30 | block.Statements.Add(st);
31 | return false;
32 | }
33 |
34 | public static void Run(StatementBlock block) {
35 | bool workDone;
36 | do {
37 | workDone = false;
38 | Statement[] copy = block.Statements.ToArray();
39 | block.Statements.Clear();
40 | foreach (Statement st in copy)
41 | workDone |= ProcessStatement(st, block);
42 | } while (workDone);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Transforms/MulToShiftTransform.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Confuser.DynCipher.AST;
5 |
6 | namespace Confuser.DynCipher.Transforms {
7 | internal class MulToShiftTransform {
8 | static uint NumberOfSetBits(uint i) {
9 | i = i - ((i >> 1) & 0x55555555);
10 | i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
11 | return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
12 | }
13 |
14 | static Expression ProcessExpression(Expression exp) {
15 | if (exp is BinOpExpression) {
16 | var binOp = (BinOpExpression)exp;
17 | if (binOp.Operation == BinOps.Mul && binOp.Right is LiteralExpression) {
18 | // Decompose multiplication into shifts, e.g. x * 3 => x << 1 + x
19 | uint literal = ((LiteralExpression)binOp.Right).Value;
20 | if (literal == 0) return (LiteralExpression)0;
21 | if (literal == 1) return binOp.Left;
22 |
23 | uint bits = NumberOfSetBits(literal);
24 | if (bits <= 2) {
25 | var sum = new List();
26 | int n = 0;
27 | while (literal != 0) {
28 | if ((literal & 1) != 0) {
29 | if (n == 0)
30 | sum.Add(binOp.Left);
31 | else
32 | sum.Add(binOp.Left << n);
33 | }
34 | literal >>= 1;
35 | n++;
36 | }
37 | BinOpExpression x = sum.OfType().First();
38 | foreach (Expression i in sum.Except(new[] { x }))
39 | x += i;
40 | return x;
41 | }
42 | }
43 | else {
44 | binOp.Left = ProcessExpression(binOp.Left);
45 | binOp.Right = ProcessExpression(binOp.Right);
46 | }
47 | }
48 | else if (exp is ArrayIndexExpression) {
49 | ((ArrayIndexExpression)exp).Array = ProcessExpression(((ArrayIndexExpression)exp).Array);
50 | }
51 | else if (exp is UnaryOpExpression) {
52 | ((UnaryOpExpression)exp).Value = ProcessExpression(((UnaryOpExpression)exp).Value);
53 | }
54 | return exp;
55 | }
56 |
57 | static void ProcessStatement(Statement st) {
58 | if (st is AssignmentStatement) {
59 | var assign = (AssignmentStatement)st;
60 | assign.Target = ProcessExpression(assign.Target);
61 | assign.Value = ProcessExpression(assign.Value);
62 | }
63 | }
64 |
65 | public static void Run(StatementBlock block) {
66 | foreach (Statement st in block.Statements)
67 | ProcessStatement(st);
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/Confuser.DynCipher/Transforms/NormalizeBinOpTransform.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.DynCipher.AST;
3 |
4 | namespace Confuser.DynCipher.Transforms {
5 | internal class NormalizeBinOpTransform {
6 | static Expression ProcessExpression(Expression exp) {
7 | if (exp is BinOpExpression) {
8 | var binOp = (BinOpExpression)exp;
9 | var binOpRight = binOp.Right as BinOpExpression;
10 | // a + (b + c) => (a + b) + c
11 | if (binOpRight != null && binOpRight.Operation == binOp.Operation &&
12 | (binOp.Operation == BinOps.Add || binOp.Operation == BinOps.Mul ||
13 | binOp.Operation == BinOps.Or || binOp.Operation == BinOps.And ||
14 | binOp.Operation == BinOps.Xor)) {
15 | binOp.Left = new BinOpExpression {
16 | Left = binOp.Left,
17 | Operation = binOp.Operation,
18 | Right = binOpRight.Left
19 | };
20 | binOp.Right = binOpRight.Right;
21 | }
22 |
23 | binOp.Left = ProcessExpression(binOp.Left);
24 | binOp.Right = ProcessExpression(binOp.Right);
25 |
26 | if (binOp.Right is LiteralExpression && ((LiteralExpression)binOp.Right).Value == 0 &&
27 | binOp.Operation == BinOps.Add) // x + 0 => x
28 | return binOp.Left;
29 | }
30 | else if (exp is ArrayIndexExpression) {
31 | ((ArrayIndexExpression)exp).Array = ProcessExpression(((ArrayIndexExpression)exp).Array);
32 | }
33 | else if (exp is UnaryOpExpression) {
34 | ((UnaryOpExpression)exp).Value = ProcessExpression(((UnaryOpExpression)exp).Value);
35 | }
36 | return exp;
37 | }
38 |
39 | static void ProcessStatement(Statement st) {
40 | if (st is AssignmentStatement) {
41 | var assign = (AssignmentStatement)st;
42 | assign.Target = ProcessExpression(assign.Target);
43 | assign.Value = ProcessExpression(assign.Value);
44 | }
45 | }
46 |
47 | public static void Run(StatementBlock block) {
48 | foreach (Statement st in block.Statements)
49 | ProcessStatement(st);
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/Confuser.Protections/AntiDumpProtection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Confuser.Core;
5 | using Confuser.Core.Helpers;
6 | using Confuser.Core.Services;
7 | using Confuser.Renamer;
8 | using dnlib.DotNet;
9 | using dnlib.DotNet.Emit;
10 |
11 | namespace Confuser.Protections {
12 | [BeforeProtection("Ki.ControlFlow")]
13 | internal class AntiDumpProtection : Protection {
14 | public const string _Id = "anti dump";
15 | public const string _FullId = "Ki.AntiDump";
16 |
17 | public override string Name {
18 | get { return "Anti Dump Protection"; }
19 | }
20 |
21 | public override string Description {
22 | get { return "This protection prevents the assembly from being dumped from memory."; }
23 | }
24 |
25 | public override string Id {
26 | get { return _Id; }
27 | }
28 |
29 | public override string FullId {
30 | get { return _FullId; }
31 | }
32 |
33 | public override ProtectionPreset Preset {
34 | get { return ProtectionPreset.Maximum; }
35 | }
36 |
37 | protected override void Initialize(ConfuserContext context) {
38 | //
39 | }
40 |
41 | protected override void PopulatePipeline(ProtectionPipeline pipeline) {
42 | pipeline.InsertPreStage(PipelineStage.ProcessModule, new AntiDumpPhase(this));
43 | }
44 |
45 | class AntiDumpPhase : ProtectionPhase {
46 | public AntiDumpPhase(AntiDumpProtection parent)
47 | : base(parent) { }
48 |
49 | public override ProtectionTargets Targets {
50 | get { return ProtectionTargets.Modules; }
51 | }
52 |
53 | public override string Name {
54 | get { return "Anti-dump injection"; }
55 | }
56 |
57 | protected override void Execute(ConfuserContext context, ProtectionParameters parameters) {
58 | TypeDef rtType = context.Registry.GetService().GetRuntimeType("Confuser.Runtime.AntiDump");
59 |
60 | var marker = context.Registry.GetService();
61 | var name = context.Registry.GetService();
62 |
63 | foreach (ModuleDef module in parameters.Targets.OfType()) {
64 | IEnumerable members = InjectHelper.Inject(rtType, module.GlobalType, module);
65 |
66 | MethodDef cctor = module.GlobalType.FindStaticConstructor();
67 | var init = (MethodDef)members.Single(method => method.Name == "Initialize");
68 | cctor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, init));
69 |
70 | foreach (IDnlibDef member in members)
71 | name.MarkHelper(member, marker, (Protection)Parent);
72 | }
73 | }
74 | }
75 | }
76 | }
--------------------------------------------------------------------------------
/Confuser.Protections/AntiILDasmProtection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Confuser.Core;
4 | using dnlib.DotNet;
5 |
6 | namespace Confuser.Protections {
7 | internal class AntiILDasmProtection : Protection {
8 | public const string _Id = "anti ildasm";
9 | public const string _FullId = "Ki.AntiILDasm";
10 |
11 | public override string Name {
12 | get { return "Anti IL Dasm Protection"; }
13 | }
14 |
15 | public override string Description {
16 | get { return "This protection marks the module with a attribute that discourage ILDasm from disassembling it."; }
17 | }
18 |
19 | public override string Id {
20 | get { return _Id; }
21 | }
22 |
23 | public override string FullId {
24 | get { return _FullId; }
25 | }
26 |
27 | public override ProtectionPreset Preset {
28 | get { return ProtectionPreset.Minimum; }
29 | }
30 |
31 | protected override void Initialize(ConfuserContext context) {
32 | //
33 | }
34 |
35 | protected override void PopulatePipeline(ProtectionPipeline pipeline) {
36 | pipeline.InsertPreStage(PipelineStage.ProcessModule, new AntiILDasmPhase(this));
37 | }
38 |
39 | class AntiILDasmPhase : ProtectionPhase {
40 | public AntiILDasmPhase(AntiILDasmProtection parent)
41 | : base(parent) { }
42 |
43 | public override ProtectionTargets Targets {
44 | get { return ProtectionTargets.Modules; }
45 | }
46 |
47 | public override string Name {
48 | get { return "Anti-ILDasm marking"; }
49 | }
50 |
51 | protected override void Execute(ConfuserContext context, ProtectionParameters parameters) {
52 | foreach (ModuleDef module in parameters.Targets.OfType()) {
53 | TypeRef attrRef = module.CorLibTypes.GetTypeRef("System.Runtime.CompilerServices", "SuppressIldasmAttribute");
54 | var ctorRef = new MemberRefUser(module, ".ctor", MethodSig.CreateInstance(module.CorLibTypes.Void), attrRef);
55 |
56 | var attr = new CustomAttribute(ctorRef);
57 | module.CustomAttributes.Add(attr);
58 | }
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/Confuser.Protections/AntiTamper/DynamicDeriver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core;
4 | using Confuser.Core.Services;
5 | using Confuser.DynCipher;
6 | using Confuser.DynCipher.AST;
7 | using Confuser.DynCipher.Generation;
8 | using dnlib.DotNet;
9 | using dnlib.DotNet.Emit;
10 |
11 | namespace Confuser.Protections.AntiTamper {
12 | internal class DynamicDeriver : IKeyDeriver {
13 | StatementBlock derivation;
14 | Action encryptFunc;
15 |
16 | public void Init(ConfuserContext ctx, RandomGenerator random) {
17 | StatementBlock dummy;
18 | ctx.Registry.GetService().GenerateCipherPair(random, out derivation, out dummy);
19 |
20 | var dmCodeGen = new DMCodeGen(typeof(void), new[] {
21 | Tuple.Create("{BUFFER}", typeof(uint[])),
22 | Tuple.Create("{KEY}", typeof(uint[]))
23 | });
24 | dmCodeGen.GenerateCIL(derivation);
25 | encryptFunc = dmCodeGen.Compile>();
26 | }
27 |
28 | public uint[] DeriveKey(uint[] a, uint[] b) {
29 | var ret = new uint[0x10];
30 | Buffer.BlockCopy(a, 0, ret, 0, a.Length * sizeof(uint));
31 | encryptFunc(ret, b);
32 | return ret;
33 | }
34 |
35 | public IEnumerable EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src) {
36 | var ret = new List();
37 | var codeGen = new CodeGen(dst, src, method, ret);
38 | codeGen.GenerateCIL(derivation);
39 | codeGen.Commit(method.Body);
40 | return ret;
41 | }
42 |
43 | class CodeGen : CILCodeGen {
44 | readonly Local block;
45 | readonly Local key;
46 |
47 | public CodeGen(Local block, Local key, MethodDef method, IList instrs)
48 | : base(method, instrs) {
49 | this.block = block;
50 | this.key = key;
51 | }
52 |
53 | protected override Local Var(Variable var) {
54 | if (var.Name == "{BUFFER}")
55 | return block;
56 | if (var.Name == "{KEY}")
57 | return key;
58 | return base.Var(var);
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/Confuser.Protections/AntiTamper/IKeyDeriver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core;
4 | using Confuser.Core.Services;
5 | using dnlib.DotNet;
6 | using dnlib.DotNet.Emit;
7 |
8 | namespace Confuser.Protections.AntiTamper {
9 | internal enum Mode {
10 | Normal,
11 | Dynamic
12 | }
13 |
14 | internal interface IKeyDeriver {
15 | void Init(ConfuserContext ctx, RandomGenerator random);
16 | uint[] DeriveKey(uint[] a, uint[] b);
17 | IEnumerable EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src);
18 | }
19 | }
--------------------------------------------------------------------------------
/Confuser.Protections/AntiTamper/IModeHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core;
3 |
4 | namespace Confuser.Protections.AntiTamper {
5 | internal interface IModeHandler {
6 | void HandleInject(AntiTamperProtection parent, ConfuserContext context, ProtectionParameters parameters);
7 | void HandleMD(AntiTamperProtection parent, ConfuserContext context, ProtectionParameters parameters);
8 | }
9 | }
--------------------------------------------------------------------------------
/Confuser.Protections/AntiTamper/NormalDeriver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core;
4 | using Confuser.Core.Services;
5 | using dnlib.DotNet;
6 | using dnlib.DotNet.Emit;
7 |
8 | namespace Confuser.Protections.AntiTamper {
9 | internal class NormalDeriver : IKeyDeriver {
10 | public void Init(ConfuserContext ctx, RandomGenerator random) {
11 | //
12 | }
13 |
14 | public uint[] DeriveKey(uint[] a, uint[] b) {
15 | var ret = new uint[0x10];
16 | for (int i = 0; i < 0x10; i++) {
17 | switch (i % 3) {
18 | case 0:
19 | ret[i] = a[i] ^ b[i];
20 | break;
21 | case 1:
22 | ret[i] = a[i] * b[i];
23 | break;
24 | case 2:
25 | ret[i] = a[i] + b[i];
26 | break;
27 | }
28 | }
29 | return ret;
30 | }
31 |
32 | public IEnumerable EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src) {
33 | for (int i = 0; i < 0x10; i++) {
34 | yield return Instruction.Create(OpCodes.Ldloc, dst);
35 | yield return Instruction.Create(OpCodes.Ldc_I4, i);
36 | yield return Instruction.Create(OpCodes.Ldloc, dst);
37 | yield return Instruction.Create(OpCodes.Ldc_I4, i);
38 | yield return Instruction.Create(OpCodes.Ldelem_U4);
39 | yield return Instruction.Create(OpCodes.Ldloc, src);
40 | yield return Instruction.Create(OpCodes.Ldc_I4, i);
41 | yield return Instruction.Create(OpCodes.Ldelem_U4);
42 | switch (i % 3) {
43 | case 0:
44 | yield return Instruction.Create(OpCodes.Xor);
45 | break;
46 | case 1:
47 | yield return Instruction.Create(OpCodes.Mul);
48 | break;
49 | case 2:
50 | yield return Instruction.Create(OpCodes.Add);
51 | break;
52 | }
53 | yield return Instruction.Create(OpCodes.Stelem_I4);
54 | }
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Compress/CompressorContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core.Services;
4 | using dnlib.DotNet;
5 |
6 | namespace Confuser.Protections.Compress {
7 | internal class CompressorContext {
8 | public AssemblyDef Assembly;
9 | public IKeyDeriver Deriver;
10 | public byte[] EncryptedModule;
11 | public MethodDef EntryPoint;
12 | public uint EntryPointToken;
13 | public byte[] KeySig;
14 | public uint KeyToken;
15 | public ModuleKind Kind;
16 | public List> ManifestResources;
17 | public int ModuleIndex;
18 | public string ModuleName;
19 | public byte[] OriginModule;
20 | public ModuleDef OriginModuleDef;
21 | public bool CompatMode;
22 |
23 | public byte[] Encrypt(ICompressionService compress, byte[] data, uint seed, Action progressFunc) {
24 | data = (byte[])data.Clone();
25 | var dst = new uint[0x10];
26 | var src = new uint[0x10];
27 | ulong state = seed;
28 | for (int i = 0; i < 0x10; i++) {
29 | state = (state * state) % 0x143fc089;
30 | src[i] = (uint)state;
31 | dst[i] = (uint)((state * state) % 0x444d56fb);
32 | }
33 | uint[] key = Deriver.DeriveKey(dst, src);
34 |
35 | var z = (uint)(state % 0x8a5cb7);
36 | for (int i = 0; i < data.Length; i++) {
37 | data[i] ^= (byte)state;
38 | if ((i & 0xff) == 0)
39 | state = (state * state) % 0x8a5cb7;
40 | }
41 | data = compress.Compress(data, progressFunc);
42 | Array.Resize(ref data, (data.Length + 3) & ~3);
43 |
44 | var encryptedData = new byte[data.Length];
45 | int keyIndex = 0;
46 | for (int i = 0; i < data.Length; i += 4) {
47 | var datum = (uint)(data[i + 0] | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24));
48 | uint encrypted = datum ^ key[keyIndex & 0xf];
49 | key[keyIndex & 0xf] = (key[keyIndex & 0xf] ^ datum) + 0x3ddb2819;
50 | encryptedData[i + 0] = (byte)(encrypted >> 0);
51 | encryptedData[i + 1] = (byte)(encrypted >> 8);
52 | encryptedData[i + 2] = (byte)(encrypted >> 16);
53 | encryptedData[i + 3] = (byte)(encrypted >> 24);
54 | keyIndex++;
55 | }
56 |
57 | return encryptedData;
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Compress/DynamicDeriver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core;
4 | using Confuser.Core.Services;
5 | using Confuser.DynCipher;
6 | using Confuser.DynCipher.AST;
7 | using Confuser.DynCipher.Generation;
8 | using dnlib.DotNet;
9 | using dnlib.DotNet.Emit;
10 |
11 | namespace Confuser.Protections.Compress {
12 | internal class DynamicDeriver : IKeyDeriver {
13 | StatementBlock derivation;
14 | Action encryptFunc;
15 |
16 | public void Init(ConfuserContext ctx, RandomGenerator random) {
17 | StatementBlock dummy;
18 | ctx.Registry.GetService().GenerateCipherPair(random, out derivation, out dummy);
19 |
20 | var dmCodeGen = new DMCodeGen(typeof(void), new[] {
21 | Tuple.Create("{BUFFER}", typeof(uint[])),
22 | Tuple.Create("{KEY}", typeof(uint[]))
23 | });
24 | dmCodeGen.GenerateCIL(derivation);
25 | encryptFunc = dmCodeGen.Compile>();
26 | }
27 |
28 | public uint[] DeriveKey(uint[] a, uint[] b) {
29 | var ret = new uint[0x10];
30 | Buffer.BlockCopy(a, 0, ret, 0, a.Length * sizeof(uint));
31 | encryptFunc(ret, b);
32 | return ret;
33 | }
34 |
35 | public IEnumerable EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src) {
36 | var ret = new List();
37 | var codeGen = new CodeGen(dst, src, method, ret);
38 | codeGen.GenerateCIL(derivation);
39 | codeGen.Commit(method.Body);
40 | return ret;
41 | }
42 |
43 | class CodeGen : CILCodeGen {
44 | readonly Local block;
45 | readonly Local key;
46 |
47 | public CodeGen(Local block, Local key, MethodDef method, IList instrs)
48 | : base(method, instrs) {
49 | this.block = block;
50 | this.key = key;
51 | }
52 |
53 | protected override Local Var(Variable var) {
54 | if (var.Name == "{BUFFER}")
55 | return block;
56 | if (var.Name == "{KEY}")
57 | return key;
58 | return base.Var(var);
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Compress/IKeyDeriver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core;
4 | using Confuser.Core.Services;
5 | using dnlib.DotNet;
6 | using dnlib.DotNet.Emit;
7 |
8 | namespace Confuser.Protections.Compress {
9 | internal enum Mode {
10 | Normal,
11 | Dynamic
12 | }
13 |
14 | internal interface IKeyDeriver {
15 | void Init(ConfuserContext ctx, RandomGenerator random);
16 | uint[] DeriveKey(uint[] a, uint[] b);
17 | IEnumerable EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src);
18 | }
19 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Constants/CEContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core;
4 | using Confuser.Core.Services;
5 | using Confuser.DynCipher;
6 | using Confuser.Renamer;
7 | using dnlib.DotNet;
8 | using dnlib.DotNet.Emit;
9 |
10 | namespace Confuser.Protections.Constants {
11 | internal class CEContext {
12 | public ConfuserContext Context;
13 | public ConstantProtection Protection;
14 | public ModuleDef Module;
15 |
16 | public FieldDef BufferField;
17 | public FieldDef DataField;
18 | public TypeDef DataType;
19 | public MethodDef InitMethod;
20 |
21 | public int DecoderCount;
22 | public List> Decoders;
23 |
24 | public EncodeElements Elements;
25 | public List EncodedBuffer;
26 |
27 | public Mode Mode;
28 | public IEncodeMode ModeHandler;
29 |
30 | public IDynCipherService DynCipher;
31 | public IMarkerService Marker;
32 | public INameService Name;
33 | public RandomGenerator Random;
34 |
35 | public TypeDef CfgCtxType;
36 | public MethodDef CfgCtxCtor;
37 | public MethodDef CfgCtxNext;
38 | public Dictionary>> ReferenceRepl;
39 | }
40 |
41 | internal class DecoderDesc {
42 | public object Data;
43 | public byte InitializerID;
44 | public byte NumberID;
45 | public byte StringID;
46 | }
47 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Constants/ConstantProtection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core;
3 | using Confuser.Protections.Constants;
4 | using dnlib.DotNet;
5 |
6 | namespace Confuser.Protections {
7 | public interface IConstantService {
8 | void ExcludeMethod(ConfuserContext context, MethodDef method);
9 | }
10 |
11 | [BeforeProtection("Ki.ControlFlow"), AfterProtection("Ki.RefProxy")]
12 | internal class ConstantProtection : Protection, IConstantService {
13 | public const string _Id = "constants";
14 | public const string _FullId = "Ki.Constants";
15 | public const string _ServiceId = "Ki.Constants";
16 | internal static readonly object ContextKey = new object();
17 |
18 | public override string Name {
19 | get { return "Constants Protection"; }
20 | }
21 |
22 | public override string Description {
23 | get { return "This protection encodes and compresses constants in the code."; }
24 | }
25 |
26 | public override string Id {
27 | get { return _Id; }
28 | }
29 |
30 | public override string FullId {
31 | get { return _FullId; }
32 | }
33 |
34 | public override ProtectionPreset Preset {
35 | get { return ProtectionPreset.Normal; }
36 | }
37 |
38 | public void ExcludeMethod(ConfuserContext context, MethodDef method) {
39 | ProtectionParameters.GetParameters(context, method).Remove(this);
40 | }
41 |
42 | protected override void Initialize(ConfuserContext context) {
43 | context.Registry.RegisterService(_ServiceId, typeof(IConstantService), this);
44 | }
45 |
46 | protected override void PopulatePipeline(ProtectionPipeline pipeline) {
47 | pipeline.InsertPreStage(PipelineStage.ProcessModule, new InjectPhase(this));
48 | pipeline.InsertPostStage(PipelineStage.ProcessModule, new EncodePhase(this));
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Constants/EncodeElements.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Protections.Constants {
4 | [Flags]
5 | internal enum EncodeElements {
6 | Strings = 1,
7 | Numbers = 2,
8 | Primitive = 4,
9 | Initializers = 8
10 | }
11 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Constants/IEncodeMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using dnlib.DotNet;
4 | using dnlib.DotNet.Emit;
5 |
6 | namespace Confuser.Protections.Constants {
7 | internal interface IEncodeMode {
8 | IEnumerable EmitDecrypt(MethodDef init, CEContext ctx, Local block, Local key);
9 | uint[] Encrypt(uint[] data, int offset, uint[] key);
10 |
11 | object CreateDecoder(MethodDef decoder, CEContext ctx);
12 | uint Encode(object data, CEContext ctx, uint id);
13 | }
14 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Constants/Mode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Confuser.Protections.Constants {
4 | internal enum Mode {
5 | Normal,
6 | Dynamic,
7 | x86
8 | }
9 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Constants/NormalMode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using Confuser.Core.Helpers;
5 | using Confuser.DynCipher;
6 | using dnlib.DotNet;
7 | using dnlib.DotNet.Emit;
8 |
9 | namespace Confuser.Protections.Constants {
10 | internal class NormalMode : IEncodeMode {
11 | public IEnumerable EmitDecrypt(MethodDef init, CEContext ctx, Local block, Local key) {
12 | for (int i = 0; i < 0x10; i++) {
13 | yield return Instruction.Create(OpCodes.Ldloc, block);
14 | yield return Instruction.Create(OpCodes.Ldc_I4, i);
15 | yield return Instruction.Create(OpCodes.Ldloc, block);
16 | yield return Instruction.Create(OpCodes.Ldc_I4, i);
17 | yield return Instruction.Create(OpCodes.Ldelem_U4);
18 | yield return Instruction.Create(OpCodes.Ldloc, key);
19 | yield return Instruction.Create(OpCodes.Ldc_I4, i);
20 | yield return Instruction.Create(OpCodes.Ldelem_U4);
21 | yield return Instruction.Create(OpCodes.Xor);
22 | yield return Instruction.Create(OpCodes.Stelem_I4);
23 | }
24 | }
25 |
26 | public uint[] Encrypt(uint[] data, int offset, uint[] key) {
27 | var ret = new uint[key.Length];
28 | for (int i = 0; i < key.Length; i++)
29 | ret[i] = data[i + offset] ^ key[i];
30 | return ret;
31 | }
32 |
33 | public object CreateDecoder(MethodDef decoder, CEContext ctx) {
34 | uint k1 = ctx.Random.NextUInt32() | 1;
35 | uint k2 = ctx.Random.NextUInt32();
36 | MutationHelper.ReplacePlaceholder(decoder, arg => {
37 | var repl = new List();
38 | repl.AddRange(arg);
39 | repl.Add(Instruction.Create(OpCodes.Ldc_I4, (int)MathsUtils.modInv(k1)));
40 | repl.Add(Instruction.Create(OpCodes.Mul));
41 | repl.Add(Instruction.Create(OpCodes.Ldc_I4, (int)k2));
42 | repl.Add(Instruction.Create(OpCodes.Xor));
43 | return repl.ToArray();
44 | });
45 | return Tuple.Create(k1, k2);
46 | }
47 |
48 | public uint Encode(object data, CEContext ctx, uint id) {
49 | var key = (Tuple)data;
50 | uint ret = (id ^ key.Item2) * key.Item1;
51 | Debug.Assert(((ret * MathsUtils.modInv(key.Item1)) ^ key.Item2) == id);
52 | return ret;
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ControlFlow/ControlFlowProtection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core;
3 | using Confuser.Protections.ControlFlow;
4 | using dnlib.DotNet;
5 |
6 | namespace Confuser.Protections {
7 | public interface IControlFlowService {
8 | void ExcludeMethod(ConfuserContext context, MethodDef method);
9 | }
10 |
11 | internal class ControlFlowProtection : Protection, IControlFlowService {
12 | public const string _Id = "ctrl flow";
13 | public const string _FullId = "Ki.ControlFlow";
14 | public const string _ServiceId = "Ki.ControlFlow";
15 |
16 | public override string Name {
17 | get { return "Control Flow Protection"; }
18 | }
19 |
20 | public override string Description {
21 | get { return "This protection mangles the code in the methods so that decompilers cannot decompile the methods."; }
22 | }
23 |
24 | public override string Id {
25 | get { return _Id; }
26 | }
27 |
28 | public override string FullId {
29 | get { return _FullId; }
30 | }
31 |
32 | public override ProtectionPreset Preset {
33 | get { return ProtectionPreset.Normal; }
34 | }
35 |
36 | public void ExcludeMethod(ConfuserContext context, MethodDef method) {
37 | ProtectionParameters.GetParameters(context, method).Remove(this);
38 | }
39 |
40 | protected override void Initialize(ConfuserContext context) {
41 | context.Registry.RegisterService(_ServiceId, typeof(IControlFlowService), this);
42 | }
43 |
44 | protected override void PopulatePipeline(ProtectionPipeline pipeline) {
45 | pipeline.InsertPreStage(PipelineStage.OptimizeMethods, new ControlFlowPhase(this));
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ControlFlow/ExpressionPredicate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.DynCipher.AST;
4 | using Confuser.DynCipher.Generation;
5 | using dnlib.DotNet.Emit;
6 |
7 | namespace Confuser.Protections.ControlFlow {
8 | internal class ExpressionPredicate : IPredicate {
9 | readonly CFContext ctx;
10 | Func expCompiled;
11 | Expression expression;
12 |
13 | bool inited;
14 | List invCompiled;
15 | Expression inverse;
16 | Local stateVar;
17 |
18 | public ExpressionPredicate(CFContext ctx) {
19 | this.ctx = ctx;
20 | }
21 |
22 | public void Init(CilBody body) {
23 | if (inited)
24 | return;
25 | stateVar = new Local(ctx.Method.Module.CorLibTypes.Int32);
26 | body.Variables.Add(stateVar);
27 | body.InitLocals = true;
28 | Compile(body);
29 | inited = true;
30 | }
31 |
32 | public void EmitSwitchLoad(IList instrs) {
33 | instrs.Add(Instruction.Create(OpCodes.Stloc, stateVar));
34 | foreach (Instruction instr in invCompiled)
35 | instrs.Add(instr.Clone());
36 | }
37 |
38 | public int GetSwitchKey(int key) {
39 | return expCompiled(key);
40 | }
41 |
42 | void Compile(CilBody body) {
43 | var var = new Variable("{VAR}");
44 | var result = new Variable("{RESULT}");
45 |
46 | ctx.DynCipher.GenerateExpressionPair(
47 | ctx.Random,
48 | new VariableExpression { Variable = var }, new VariableExpression { Variable = result },
49 | ctx.Depth, out expression, out inverse);
50 |
51 | expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
52 | .GenerateCIL(expression)
53 | .Compile>();
54 |
55 | invCompiled = new List();
56 | new CodeGen(stateVar, ctx, invCompiled).GenerateCIL(inverse);
57 | body.MaxStack += (ushort)ctx.Depth;
58 | }
59 |
60 | class CodeGen : CILCodeGen {
61 | readonly Local state;
62 |
63 | public CodeGen(Local state, CFContext ctx, IList instrs)
64 | : base(ctx.Method, instrs) {
65 | this.state = state;
66 | }
67 |
68 | protected override Local Var(Variable var) {
69 | if (var.Name == "{RESULT}")
70 | return state;
71 | return base.Var(var);
72 | }
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ControlFlow/IPredicate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using dnlib.DotNet.Emit;
4 |
5 | namespace Confuser.Protections.ControlFlow {
6 | internal interface IPredicate {
7 | void Init(CilBody body);
8 | void EmitSwitchLoad(IList instrs);
9 | int GetSwitchKey(int key);
10 | }
11 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ControlFlow/ManglerBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using dnlib.DotNet.Emit;
4 |
5 | namespace Confuser.Protections.ControlFlow {
6 | internal abstract class ManglerBase {
7 | protected static IEnumerable GetAllBlocks(ScopeBlock scope) {
8 | foreach (BlockBase child in scope.Children) {
9 | if (child is InstrBlock)
10 | yield return (InstrBlock)child;
11 | else {
12 | foreach (InstrBlock block in GetAllBlocks((ScopeBlock)child))
13 | yield return block;
14 | }
15 | }
16 | }
17 |
18 | public abstract void Mangle(CilBody body, ScopeBlock root, CFContext ctx);
19 | }
20 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ControlFlow/NormalPredicate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using dnlib.DotNet.Emit;
4 |
5 | namespace Confuser.Protections.ControlFlow {
6 | internal class NormalPredicate : IPredicate {
7 | readonly CFContext ctx;
8 | bool inited;
9 | int xorKey;
10 |
11 | public NormalPredicate(CFContext ctx) {
12 | this.ctx = ctx;
13 | }
14 |
15 | public void Init(CilBody body) {
16 | if (inited)
17 | return;
18 |
19 | xorKey = ctx.Random.NextInt32();
20 | inited = true;
21 | }
22 |
23 | public void EmitSwitchLoad(IList instrs) {
24 | instrs.Add(Instruction.Create(OpCodes.Ldc_I4, xorKey));
25 | instrs.Add(Instruction.Create(OpCodes.Xor));
26 | }
27 |
28 | public int GetSwitchKey(int key) {
29 | return key ^ xorKey;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Confuser.Protections/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | [assembly: AssemblyTitle("ConfuserEx Protections")]
5 | [assembly: AssemblyDescription("Protections and packers of ConfuserEx")]
--------------------------------------------------------------------------------
/Confuser.Protections/ReferenceProxy/ExpressionEncoding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.DynCipher.AST;
4 | using Confuser.DynCipher.Generation;
5 | using dnlib.DotNet;
6 | using dnlib.DotNet.Emit;
7 |
8 | namespace Confuser.Protections.ReferenceProxy {
9 | internal class ExpressionEncoding : IRPEncoding {
10 | readonly Dictionary>> keys = new Dictionary>>();
11 |
12 | public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg) {
13 | Tuple> key = GetKey(ctx, init);
14 |
15 | var invCompiled = new List();
16 | new CodeGen(arg, ctx.Method, invCompiled).GenerateCIL(key.Item1);
17 | init.Body.MaxStack += (ushort)ctx.Depth;
18 | return invCompiled.ToArray();
19 | }
20 |
21 | public int Encode(MethodDef init, RPContext ctx, int value) {
22 | Tuple> key = GetKey(ctx, init);
23 | return key.Item2(value);
24 | }
25 |
26 | void Compile(RPContext ctx, CilBody body, out Func expCompiled, out Expression inverse) {
27 | var var = new Variable("{VAR}");
28 | var result = new Variable("{RESULT}");
29 |
30 | Expression expression;
31 | ctx.DynCipher.GenerateExpressionPair(
32 | ctx.Random,
33 | new VariableExpression { Variable = var }, new VariableExpression { Variable = result },
34 | ctx.Depth, out expression, out inverse);
35 |
36 | expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
37 | .GenerateCIL(expression)
38 | .Compile>();
39 | }
40 |
41 | Tuple> GetKey(RPContext ctx, MethodDef init) {
42 | Tuple> ret;
43 | if (!keys.TryGetValue(init, out ret)) {
44 | Func keyFunc;
45 | Expression inverse;
46 | Compile(ctx, init.Body, out keyFunc, out inverse);
47 | keys[init] = ret = Tuple.Create(inverse, keyFunc);
48 | }
49 | return ret;
50 | }
51 |
52 | class CodeGen : CILCodeGen {
53 | readonly Instruction[] arg;
54 |
55 | public CodeGen(Instruction[] arg, MethodDef method, IList instrs)
56 | : base(method, instrs) {
57 | this.arg = arg;
58 | }
59 |
60 | protected override void LoadVar(Variable var) {
61 | if (var.Name == "{RESULT}") {
62 | foreach (Instruction instr in arg)
63 | Emit(instr);
64 | }
65 | else
66 | base.LoadVar(var);
67 | }
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ReferenceProxy/IRPEncoding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using dnlib.DotNet;
3 | using dnlib.DotNet.Emit;
4 |
5 | namespace Confuser.Protections.ReferenceProxy {
6 | internal interface IRPEncoding {
7 | Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg);
8 | int Encode(MethodDef init, RPContext ctx, int value);
9 | }
10 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ReferenceProxy/NormalEncoding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core.Services;
4 | using Confuser.DynCipher;
5 | using dnlib.DotNet;
6 | using dnlib.DotNet.Emit;
7 |
8 | namespace Confuser.Protections.ReferenceProxy {
9 | internal class NormalEncoding : IRPEncoding {
10 | readonly Dictionary> keys = new Dictionary>();
11 |
12 | public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg) {
13 | Tuple key = GetKey(ctx.Random, init);
14 | var ret = new List();
15 | if (ctx.Random.NextBoolean()) {
16 | ret.Add(Instruction.Create(OpCodes.Ldc_I4, key.Item1));
17 | ret.AddRange(arg);
18 | }
19 | else {
20 | ret.AddRange(arg);
21 | ret.Add(Instruction.Create(OpCodes.Ldc_I4, key.Item1));
22 | }
23 | ret.Add(Instruction.Create(OpCodes.Mul));
24 | return ret.ToArray();
25 | }
26 |
27 | public int Encode(MethodDef init, RPContext ctx, int value) {
28 | Tuple key = GetKey(ctx.Random, init);
29 | return value * key.Item2;
30 | }
31 |
32 | Tuple GetKey(RandomGenerator random, MethodDef init) {
33 | Tuple ret;
34 | if (!keys.TryGetValue(init, out ret)) {
35 | int key = random.NextInt32() | 1;
36 | keys[init] = ret = Tuple.Create(key, (int)MathsUtils.modInv((uint)key));
37 | }
38 | return ret;
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ReferenceProxy/RPContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confuser.Core;
4 | using Confuser.Core.Services;
5 | using Confuser.DynCipher;
6 | using Confuser.Renamer;
7 | using dnlib.DotNet;
8 | using dnlib.DotNet.Emit;
9 |
10 | namespace Confuser.Protections.ReferenceProxy {
11 | internal enum Mode {
12 | Mild,
13 | Strong,
14 | Ftn
15 | }
16 |
17 | internal enum EncodingType {
18 | Normal,
19 | Expression,
20 | x86
21 | }
22 |
23 | internal class RPContext {
24 | public ReferenceProxyProtection Protection;
25 | public CilBody Body;
26 | public HashSet BranchTargets;
27 | public ConfuserContext Context;
28 | public Dictionary Delegates;
29 | public int Depth;
30 | public IDynCipherService DynCipher;
31 | public EncodingType Encoding;
32 | public IRPEncoding EncodingHandler;
33 | public int InitCount;
34 | public bool InternalAlso;
35 | public IMarkerService Marker;
36 | public MethodDef Method;
37 | public Mode Mode;
38 |
39 | public RPMode ModeHandler;
40 | public ModuleDef Module;
41 | public INameService Name;
42 | public RandomGenerator Random;
43 | public bool TypeErasure;
44 | }
45 | }
--------------------------------------------------------------------------------
/Confuser.Protections/ReferenceProxy/ReferenceProxyProtection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confuser.Core;
3 | using Confuser.Protections.ReferenceProxy;
4 | using dnlib.DotNet;
5 |
6 | namespace Confuser.Protections {
7 | public interface IReferenceProxyService {
8 | void ExcludeMethod(ConfuserContext context, MethodDef method);
9 | void ExcludeTarget(ConfuserContext context, MethodDef method);
10 | bool IsTargeted(ConfuserContext context, MethodDef method);
11 | }
12 |
13 | [AfterProtection("Ki.AntiDebug", "Ki.AntiDump")]
14 | [BeforeProtection("Ki.ControlFlow")]
15 | internal class ReferenceProxyProtection : Protection, IReferenceProxyService {
16 | public const string _Id = "ref proxy";
17 | public const string _FullId = "Ki.RefProxy";
18 | public const string _ServiceId = "Ki.RefProxy";
19 |
20 | internal static object TargetExcluded = new object();
21 | internal static object Targeted = new object();
22 |
23 | public override string Name {
24 | get { return "Reference Proxy Protection"; }
25 | }
26 |
27 | public override string Description {
28 | get { return "This protection encodes and hides references to type/method/fields."; }
29 | }
30 |
31 | public override string Id {
32 | get { return _Id; }
33 | }
34 |
35 | public override string FullId {
36 | get { return _FullId; }
37 | }
38 |
39 | public override ProtectionPreset Preset {
40 | get { return ProtectionPreset.Normal; }
41 | }
42 |
43 | public void ExcludeMethod(ConfuserContext context, MethodDef method) {
44 | ProtectionParameters.GetParameters(context, method).Remove(this);
45 | }
46 |
47 | public void ExcludeTarget(ConfuserContext context, MethodDef method) {
48 | context.Annotations.Set(method, TargetExcluded, TargetExcluded);
49 | }
50 |
51 | public bool IsTargeted(ConfuserContext context, MethodDef method) {
52 | return context.Annotations.Get