diff --git a/UnConfuserEx/Protections/Constants/DynamicDecryptor.cs b/UnConfuserEx/Protections/Constants/DynamicDecryptor.cs index 356be06..d0843df 100644 --- a/UnConfuserEx/Protections/Constants/DynamicDecryptor.cs +++ b/UnConfuserEx/Protections/Constants/DynamicDecryptor.cs @@ -1,4 +1,5 @@ using dnlib.DotNet.Emit; +using MSILEmulator; using System; using System.Collections.Generic; using System.Linq; @@ -9,15 +10,16 @@ namespace UnConfuserEx.Protections.Constants internal class DynamicDecryptor : IDecryptor { private IList decryptInstructions; - private Func decryptDelegate; + private ILMethod decryptMethod; + private int[] arrayIndices; public DynamicDecryptor(IList decryptInstructions) { this.decryptInstructions = decryptInstructions; - decryptDelegate = GetDecryptDelegate(); + SetupDecryptMethod(); } - private Func GetDecryptDelegate() + private void SetupDecryptMethod() { SortedSet arrays = new(); for (int i = 0; i < decryptInstructions.Count - 2; i++) @@ -35,130 +37,13 @@ namespace UnConfuserEx.Protections.Constants } } } - int[] arrayIndices = arrays.ToArray(); + arrayIndices = arrays.ToArray(); if (arrayIndices.Length != 2) { throw new Exception("There should be two key arrays used in a dynamic derivation"); } - var deriverMethod = new SRE.DynamicMethod("", typeof(uint[]), new Type[] { typeof(uint[]), typeof(uint[]) }); - var il = deriverMethod.GetILGenerator(); - - // Setup locals - Dictionary locals = new(); - locals.Add(arrayIndices[0], 0); - il.DeclareLocal(typeof(uint[])); // key - locals.Add(arrayIndices[1], 1); - il.DeclareLocal(typeof(uint[])); // temp - - // Store passed arrays in the expected locals - il.Emit(SRE.OpCodes.Ldarg_0); - il.Emit(SRE.OpCodes.Stloc_S, 0); - il.Emit(SRE.OpCodes.Ldarg_1); - il.Emit(SRE.OpCodes.Stloc_S, 1); - - // Derivation - foreach (var instr in decryptInstructions) - { - var opcode = (SRE.OpCode)typeof(SRE.OpCodes).GetField(instr.OpCode.Code.ToString())!.GetValue(null)!; - - if (instr.Operand == null) - { - if (instr.OpCode.OpCodeType == OpCodeType.Macro) - { - if (instr.IsLdloc()) - { - var index = instr.OpCode.Value - OpCodes.Ldloc_0.Value; - int operand; - if (locals.ContainsKey(index)) - { - operand = locals[index]; - } - else - { - operand = locals.Count; - locals.Add(index, operand); - - il.DeclareLocal(typeof(uint)); - } - il.Emit(SRE.OpCodes.Ldloc_S, operand); - } - else if (instr.IsStloc()) - { - var index = instr.OpCode.Value - OpCodes.Ldloc_0.Value; - int operand; - if (locals.ContainsKey(index)) - { - operand = locals[index]; - } - else - { - operand = locals.Count; - locals.Add(index, operand); - - il.DeclareLocal(typeof(uint)); - } - il.Emit(SRE.OpCodes.Stloc_S, operand); - } - else - { - il.Emit(opcode); - } - } - else - { - il.Emit(opcode); - } - } - else if (instr.Operand is Local local) - { - var index = local.Index; - int operand; - if (locals.ContainsKey(index)) - { - operand = locals[index]; - } - else - { - operand = locals.Count; - locals.Add(index, operand); - - il.DeclareLocal(typeof(uint)); - } - il.Emit(opcode, operand); - } - else if (instr.Operand is sbyte sb) - { - il.Emit(opcode, sb); - } - else if (instr.Operand is int i) - { - il.Emit(opcode, i); - } - else if (instr.Operand is short s) - { - il.Emit(opcode, s); - } - else if (instr.Operand is byte b) - { - il.Emit(opcode, b); - } - else if (instr.Operand is long l) - { - il.Emit(opcode, l); - } - else - { - throw new Exception($"Unhandled operand type: { instr.Operand.GetType() }"); - } - } - - // Return the temp array - il.Emit(SRE.OpCodes.Ldloc_S, 1); - il.Emit(SRE.OpCodes.Ret); - - var deriverDelegate = (Func)deriverMethod.CreateDelegate(typeof(Func)); - return deriverDelegate; + decryptMethod = new ILMethod(decryptInstructions); } public byte[] DecryptData(uint[] data, uint[] key) @@ -166,6 +51,10 @@ namespace UnConfuserEx.Protections.Constants uint[] temp = new uint[key.Length]; byte[] ret = new byte[data.Length << 2]; int s = 0, d = 0; + + decryptMethod.SetLocal(arrayIndices[0], key); + decryptMethod.SetLocal(arrayIndices[1], temp); + while (s < data.Length) { for (int j = 0; j < 16; j++) @@ -173,7 +62,7 @@ namespace UnConfuserEx.Protections.Constants temp[j] = data[s + j]; } - temp = decryptDelegate.Invoke(key, temp); + decryptMethod.Emulate(); for (int j = 0; j < 16; j++) { diff --git a/UnConfuserEx/UnConfuserEx.cs b/UnConfuserEx/UnConfuserEx.cs index abeb0de..870dc61 100644 --- a/UnConfuserEx/UnConfuserEx.cs +++ b/UnConfuserEx/UnConfuserEx.cs @@ -43,8 +43,8 @@ namespace UnConfuserEx new AntiTamperRemover(), new ControlFlowRemover(), - new ResourcesRemover(), new ConstantsRemover(), + new ResourcesRemover(), new RefProxyRemover(), new AntiDumpRemover(), new AntiDebugRemover(),