From 30ed03e6b6d24795448231aca3adbee3e05b6749 Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Sat, 27 Jan 2024 15:56:31 +0100 Subject: [PATCH 01/11] Fix NPE in StringDecrypter --- NETReactorSlayer.Core/Stages/StringDecrypter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NETReactorSlayer.Core/Stages/StringDecrypter.cs b/NETReactorSlayer.Core/Stages/StringDecrypter.cs index 9e5f97e..92f1271 100644 --- a/NETReactorSlayer.Core/Stages/StringDecrypter.cs +++ b/NETReactorSlayer.Core/Stages/StringDecrypter.cs @@ -263,7 +263,7 @@ private long InlineStringsDynamically() continue; var methodDef = ((IMethod)method.Body.Instructions[i + 1].Operand).ResolveMethodDef(); - if (!methodDef.HasReturnType) + if (methodDef is not {HasReturnType: true}) continue; if (TypeEqualityComparer.Instance.Equals(method.DeclaringType, methodDef.DeclaringType)) From 9ebaf712177e4666f485b71b17f9f53df64ab2d7 Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Sat, 27 Jan 2024 16:10:24 +0100 Subject: [PATCH 02/11] Fixed NPE in AssemblyResolver --- NETReactorSlayer.Core/Stages/AssemblyResolver.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NETReactorSlayer.Core/Stages/AssemblyResolver.cs b/NETReactorSlayer.Core/Stages/AssemblyResolver.cs index 389c9bf..b4c3674 100644 --- a/NETReactorSlayer.Core/Stages/AssemblyResolver.cs +++ b/NETReactorSlayer.Core/Stages/AssemblyResolver.cs @@ -35,7 +35,7 @@ public void Run(IContext context) return; var assemblies = new List(); - foreach (var prefix in DotNetUtils.GetCodeStrings(_resolverMethod)) + foreach (var prefix in DotNetUtils.GetCodeStrings(_resolverMethod).Distinct()) assemblies.AddRange(GetAssemblies(prefix)); if (assemblies.Count < 1) return; @@ -115,7 +115,7 @@ private IEnumerable GetAssemblies(string prefix) { var result = new List(); if (string.IsNullOrEmpty(prefix)) - return null; + return result; foreach (var rsrc in Context.Module.Resources) { if (rsrc is not EmbeddedResource resource) From 9d12a97dbc3d9115b04eb70720d06cbd1ef026ad Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Sat, 27 Jan 2024 18:12:53 +0100 Subject: [PATCH 03/11] Fixed decompressing resources when Brotli compression was used --- NETReactorSlayer.Core/Helper/DeobUtils.cs | 16 ++++++++++++++++ .../NETReactorSlayer.Core.csproj | 3 ++- NETReactorSlayer.Core/Stages/ResourceResolver.cs | 7 +++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/NETReactorSlayer.Core/Helper/DeobUtils.cs b/NETReactorSlayer.Core/Helper/DeobUtils.cs index 428cd8a..4cdcce0 100644 --- a/NETReactorSlayer.Core/Helper/DeobUtils.cs +++ b/NETReactorSlayer.Core/Helper/DeobUtils.cs @@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License using System; using System.IO; +using System.IO.Compression; using System.Linq; using System.Security.Cryptography; using dnlib.DotNet; @@ -89,5 +90,20 @@ public static byte[] Inflate(byte[] data, int start, int len, Inflater inflater) return memStream.ToArray(); } + + public static byte[] BrotliDecompress(byte[] data) + { +#if (NETSTANDARD || NET) + var memoryStream = new MemoryStream(); + using (var brotliStream = new BrotliStream(new MemoryStream(data), CompressionMode.Decompress)) + { + brotliStream.CopyTo(memoryStream); + } + + return memoryStream.ToArray(); +#else + throw new ApplicationException("Brotli decompression not available on .NET Framework version. Use .NET6+ version"); +#endif + } } } \ No newline at end of file diff --git a/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj b/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj index 365bca2..b2391df 100644 --- a/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj +++ b/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj @@ -10,7 +10,7 @@ - + ..\Libs\net35\de4dot.blocks.dll @@ -18,6 +18,7 @@ ..\Libs\netcoreapp3.1\de4dot.blocks.dll + diff --git a/NETReactorSlayer.Core/Stages/ResourceResolver.cs b/NETReactorSlayer.Core/Stages/ResourceResolver.cs index 55a7896..ed54f3d 100644 --- a/NETReactorSlayer.Core/Stages/ResourceResolver.cs +++ b/NETReactorSlayer.Core/Stages/ResourceResolver.cs @@ -124,8 +124,11 @@ private static byte[] Decompress(byte[] bytes) try { return QuickLz.Decompress(bytes); } catch { - try { return DeobUtils.Inflate(bytes, true); } - catch { return null; } + try { return DeobUtils.BrotliDecompress(bytes); } + catch { + try { return DeobUtils.Inflate(bytes, true); } + catch { return null; } + } } } From d7544ac84fa6c191239d1f771b81c0d010182f23 Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Sat, 15 Jun 2024 15:47:23 +0200 Subject: [PATCH 04/11] Extract EncryptedResource decrypters to separate files --- .../Helper/EncryptedResource.cs | 1114 +---------------- .../Helper/EncryptedResource/DecrypterV1.cs | 70 ++ .../Helper/EncryptedResource/DecrypterV2.cs | 380 ++++++ .../Helper/EncryptedResource/DecrypterV3.cs | 308 +++++ .../Helper/EncryptedResource/DecrypterV4.cs | 391 ++++++ 5 files changed, 1151 insertions(+), 1112 deletions(-) create mode 100644 NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV1.cs create mode 100644 NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV2.cs create mode 100644 NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV3.cs create mode 100644 NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource.cs b/NETReactorSlayer.Core/Helper/EncryptedResource.cs index fb39653..801f525 100644 --- a/NETReactorSlayer.Core/Helper/EncryptedResource.cs +++ b/NETReactorSlayer.Core/Helper/EncryptedResource.cs @@ -24,7 +24,7 @@ You should have received a copy of the GNU General Public License namespace NETReactorSlayer.Core.Helper { - internal class EncryptedResource : IDisposable + internal partial class EncryptedResource : IDisposable { public EncryptedResource(IContext context, MethodDef method, IList additionalTypes) { @@ -206,1116 +206,6 @@ private interface IDecrypter { byte[] Decrypt(EmbeddedResource resource); } - - #region Nested Types - - private class DecrypterV1 : IDecrypter - { - public DecrypterV1(MethodDef method) - { - _key = GetDecryptionKey(method); - _iv = GetDecryptionIV(method); - } - - public static bool CouldBeResourceDecrypter(MethodDef method, StringCounts stringCounts, - IEnumerable additionalTypes) - { - var requiredTypes = new[] - { - new List - { - "System.Byte[]", - "System.Security.Cryptography.CryptoStream", - "System.Security.Cryptography.ICryptoTransform", - "System.String", - "System.Boolean" - }, - new List - { - "System.Security.Cryptography.ICryptoTransform", - "System.IO.Stream", - "System.Int32", - "System.Byte[]", - "System.Boolean" - }, - new List - { - "System.Security.Cryptography.ICryptoTransform", - "System.Int32", - "System.Byte[]", - "System.Boolean" - } - }; - requiredTypes[0].AddRange(additionalTypes); - - if (stringCounts.All(requiredTypes[0]) || - stringCounts.All(requiredTypes[1]) || - (stringCounts.All(requiredTypes[2]) && method.Body.Instructions.Any(x => - x.OpCode.Equals(OpCodes.Newobj) && x.Operand != null && x.Operand.ToString()! - .Contains("System.Security.Cryptography.CryptoStream::.ctor")))) - return DotNetUtils.GetMethod(method.DeclaringType, - "System.Security.Cryptography.SymmetricAlgorithm", - "()") == null || (!stringCounts.Exists("System.UInt64") && - (!stringCounts.Exists("System.UInt32") || - stringCounts.Exists("System.Reflection.Assembly"))); - - return false; - } - - public byte[] Decrypt(EmbeddedResource resource) => - DeobUtils.AesDecrypt(resource.CreateReader().ToArray(), _key, _iv); - - - private readonly byte[] _key, _iv; - } - - private class DecrypterV2 : IDecrypter - { - public DecrypterV2(MethodDef method) - { - _key = GetDecryptionKey(method); - _iv = GetDecryptionIV(method); - _decrypterMethod = method; - _locals = new List(_decrypterMethod.Body.Variables); - if (!Initialize()) - throw new ApplicationException("Could not initialize decrypter"); - } - - public static bool CouldBeResourceDecrypter(StringCounts stringCounts, - IEnumerable additionalTypes) - { - var requiredTypes = new List - { - "System.Int32", - "System.Byte[]" - }; - requiredTypes.AddRange(additionalTypes); - return stringCounts.All(requiredTypes); - } - - public byte[] Decrypt(EmbeddedResource resource) - { - var encrypted = resource.CreateReader().ToArray(); - var decrypted = new byte[encrypted.Length]; - var sum = 0U; - - if (_isNewDecrypter) - for (var i = 0; i < encrypted.Length; i += 4) - { - var value = ReadUInt32(_key, i % _key.Length); - sum += value + CalculateMagic(sum + value); - WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); - } - else - for (var j = 0; j < encrypted.Length; j += 4) - { - sum = CalculateMagic(sum + ReadUInt32(_key, j % _key.Length)); - WriteUInt32(decrypted, j, sum ^ ReadUInt32(encrypted, j)); - } - - return decrypted; - } - - private bool Initialize() - { - var origInstrs = _decrypterMethod.Body.Instructions; - if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal) && - !FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) - { - if (!FindStartEnd2(ref origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal, out _emuArg, - ref _emuMethod, ref _locals)) - return false; - _isNewDecrypter = true; - } - - if (!_isNewDecrypter) - for (var i = 0; i < _iv.Length; i++) - { - var array = _key; - array[i] ^= _iv[i]; - } - - var count = emuEndIndex - emuStartIndex + 1; - _instructions = new List(count); - for (var j = 0; j < count; j++) - _instructions.Add(origInstrs[emuStartIndex + j].Clone()); - return true; - } - - private Local CheckLocal(Instruction instr, bool isLdloc) - { - switch (isLdloc) - { - case true when !instr.IsLdloc(): - case false when !instr.IsStloc(): - return null; - default: - return instr.GetLocal(_locals); - } - } - - private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) - { - startIndex = 0; - endIndex = 0; - tmpLocal = null; - if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) - return false; - if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) - return false; - startIndex = emuStartIndex; - endIndex = emuEndIndex; - tmpLocal = _emuLocal; - return true; - } - - private bool FindEnd(IList instrs, int startIndex, out int endIndex) - { - for (var i = startIndex; i < instrs.Count; i++) - { - var instr = instrs[i]; - if (instr.OpCode.FlowControl != FlowControl.Next) - break; - if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) - continue; - endIndex = i - 1; - return true; - } - - endIndex = 0; - return false; - } - - private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - Local local; - if (instrs[i].OpCode.Code.Equals(Code.Conv_U) && instrs[i + 1].OpCode.Code.Equals(Code.Ldelem_U1) && - instrs[i + 2].OpCode.Code.Equals(Code.Or) && CheckLocal(instrs[i + 3], false) != null && - (local = CheckLocal(instrs[i + 4], true)) != null && CheckLocal(instrs[i + 5], true) != null && - instrs[i + 6].OpCode.Code.Equals(Code.Add) && CheckLocal(instrs[i + 7], false) == local) - { - var instr = instrs[i + 8]; - var newStartIndex = i + 8; - if (instr.IsBr()) - { - instr = instr.Operand as Instruction; - newStartIndex = instrs.IndexOf(instr); - } - - if (newStartIndex >= 0 && instr != null && CheckLocal(instr, true) == local) - { - startIndex = newStartIndex; - tmpLocal = local; - return true; - } - } - - i++; - } - - startIndex = 0; - tmpLocal = null; - return false; - } - - private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, - out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && - instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && - instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && - instrs[i + 3].OpCode.Code.Equals(Code.Add)) - { - var newEndIndex = i + 3; - var newStartIndex = -1; - for (var x = newEndIndex; x > 0; x--) - if (instrs[x].OpCode.FlowControl != FlowControl.Next) - { - if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || - instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) - { - _decrypterVersion = DecrypterVersion.V69; - continue; - } - - break; - } - - var ckStartIndex = -1; - for (var y = newEndIndex; y >= 0; y--) - if (instrs[y].IsBr()) - { - if (instrs[y].Operand is not Instruction instr) - continue; - if (instrs.IndexOf(instr) < y) - { - if (instrs[y - 1].Operand is not Instruction) - continue; - instr = instrs[y - 1].Operand as Instruction; - if (instrs.IndexOf(instr) < y) - continue; - } - newStartIndex = instrs.IndexOf(instr); - ckStartIndex = newStartIndex; - break; - } - - - if (newStartIndex >= 0) - { - var checkLocs = new List(); - for (var y = newEndIndex; y >= newStartIndex; y--) - if (CheckLocal(instrs[y], true) is { } loc) - if (!checkLocs.Contains(loc)) - checkLocs.Add(loc); - - endIndex = newEndIndex; - startIndex = Math.Max(ckStartIndex, newStartIndex); - tmpLocal = CheckLocal(instrs[startIndex], true); - return true; - } - } - - i++; - } - - endIndex = 0; - startIndex = 0; - tmpLocal = null; - return false; - } - - private static bool FindStartEnd2(ref IList instrs, out int startIndex, out int endIndex, - out Local tmpLocal, out Parameter tmpArg, ref MethodDef methodDef, ref List locals) - { - foreach (var instr in instrs) - { - MethodDef method; - if (!instr.OpCode.Equals(OpCodes.Call) || (method = instr.Operand as MethodDef) == null || - method.ReturnType.FullName != "System.Byte[]") - continue; - - using var enumerator2 = DotNetUtils.GetMethodCalls(method).GetEnumerator(); - while (enumerator2.MoveNext()) - { - MethodDef calledMethod; - if ((calledMethod = enumerator2.Current as MethodDef) == null || - calledMethod.Parameters.Count != 2) - continue; - instrs = calledMethod.Body.Instructions; - methodDef = calledMethod; - locals = new List(calledMethod.Body.Variables); - startIndex = 0; - endIndex = instrs.Count - 1; - tmpLocal = null; - tmpArg = calledMethod.Parameters[1]; - return true; - } - } - - endIndex = 0; - startIndex = 0; - tmpLocal = null; - tmpArg = null; - return false; - } - - private static uint ReadUInt32(byte[] ary, int index) - { - var sizeLeft = ary.Length - index; - if (sizeLeft >= 4) - return BitConverter.ToUInt32(ary, index); - return sizeLeft switch - { - 1 => ary[index], - 2 => (uint)(ary[index] | (ary[index + 1] << 8)), - 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), - _ => throw new ApplicationException("Can't read data") - }; - } - - private static void WriteUInt32(IList ary, int index, uint value) - { - var num = ary.Count - index; - if (num >= 1) - ary[index] = (byte)value; - if (num >= 2) - ary[index + 1] = (byte)(value >> 8); - if (num >= 3) - ary[index + 2] = (byte)(value >> 16); - if (num >= 4) - ary[index + 3] = (byte)(value >> 24); - } - - private uint CalculateMagic(uint input) - { - if (_emuArg == null) - { - _instrEmulator.Initialize(_decrypterMethod, _decrypterMethod.Parameters, _locals, - _decrypterMethod.Body.InitLocals, false); - _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); - } - else - { - _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, - false); - _instrEmulator.SetArg(_emuArg, new Int32Value((int)input)); - } - - var index = 0; - while (index < _instructions.Count) - { - try - { - if (_decrypterVersion != DecrypterVersion.V69) - goto Emulate; - if (!_instructions[index].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) - goto Emulate; - if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && - !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) - goto Emulate; - if (!_instructions[index + 3].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) - goto Emulate; - if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) - goto Emulate; - if (!_instructions[index + 6].IsStloc()) - goto Emulate; - - switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) - { - case Int32Value int32: - { - if (int32.Value != Int32Value.Zero.Value) - index += 7; - break; - } - case Int64Value int64: - { - if (int64.Value != Int64Value.Zero.Value) - index += 7; - break; - } - case Real8Value real8Value: - { - if (!real8Value.Value.Equals(new Real8Value(0).Value)) - index += 7; - break; - } - } - } - catch { } - - Emulate: - _instrEmulator.Emulate(_instructions[index]); - index++; - } - - if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) - throw new ApplicationException("Couldn't calculate magic value"); - return (uint)tos.Value; - } - - - private readonly InstructionEmulator _instrEmulator = new(); - private readonly byte[] _key, _iv; - private readonly MethodDef _decrypterMethod; - private Parameter _emuArg; - private Local _emuLocal; - private MethodDef _emuMethod; - private List _instructions; - private bool _isNewDecrypter; - private List _locals; - private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; - } - - private class DecrypterV3 : IDecrypter - { - public DecrypterV3(MethodDef method) - { - _decrypterMethod = method; - _locals = new List(_decrypterMethod.Body.Variables); - if (!Initialize()) - throw new ApplicationException("Could not initialize decrypter"); - } - - public static bool CouldBeResourceDecrypter(StringCounts stringCounts, - IEnumerable additionalTypes) - { - var requiredTypes = new List - { - "System.Reflection.Emit.DynamicMethod", - "System.Reflection.Emit.ILGenerator" - }; - requiredTypes.AddRange(additionalTypes); - return stringCounts.All(requiredTypes); - } - - public byte[] Decrypt(EmbeddedResource resource) - { - var encrypted = resource.CreateReader().ToArray(); - var decrypted = new byte[encrypted.Length]; - var sum = 0U; - - for (var i = 0; i < encrypted.Length; i += 4) - { - sum = CalculateMagic(sum); - WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); - } - - return decrypted; - } - - private bool Initialize() - { - var origInstrs = _decrypterMethod.Body.Instructions; - if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal) && - !FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) - return false; - var count = emuEndIndex - emuStartIndex + 1; - _instructions = new List(count); - for (var i = 0; i < count; i++) - _instructions.Add(origInstrs[emuStartIndex + i].Clone()); - return true; - } - - private uint CalculateMagic(uint input) - { - _instrEmulator.Initialize(_decrypterMethod, _decrypterMethod.Parameters, _locals, - _decrypterMethod.Body.InitLocals, false); - _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); - - var index = 0; - while (index < _instructions.Count) - { - try - { - if (_decrypterVersion != DecrypterVersion.V69) - goto Emulate; - if (!_instructions[index].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) - goto Emulate; - if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && - !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) - goto Emulate; - if (!_instructions[index + 3].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) - goto Emulate; - if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) - goto Emulate; - if (!_instructions[index + 6].IsStloc()) - goto Emulate; - - switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) - { - case Int32Value int32: - { - if (int32.Value != Int32Value.Zero.Value) - index += 7; - break; - } - case Int64Value int64: - { - if (int64.Value != Int64Value.Zero.Value) - index += 7; - break; - } - case Real8Value real8Value: - { - if (!real8Value.Value.Equals(new Real8Value(0).Value)) - index += 7; - break; - } - } - } - catch { } - - Emulate: - _instrEmulator.Emulate(_instructions[index]); - index++; - } - - if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) - throw new ApplicationException("Couldn't calculate magic value"); - return (uint)tos.Value; - } - - private static uint ReadUInt32(byte[] ary, int index) - { - var sizeLeft = ary.Length - index; - if (sizeLeft >= 4) - return BitConverter.ToUInt32(ary, index); - return sizeLeft switch - { - 1 => ary[index], - 2 => (uint)(ary[index] | (ary[index + 1] << 8)), - 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), - _ => throw new ApplicationException("Can't read data") - }; - } - - private static void WriteUInt32(IList ary, int index, uint value) - { - var num = ary.Count - index; - if (num >= 1) - ary[index] = (byte)value; - if (num >= 2) - ary[index + 1] = (byte)(value >> 8); - if (num >= 3) - ary[index + 2] = (byte)(value >> 16); - if (num >= 4) - ary[index + 3] = (byte)(value >> 24); - } - - private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) - { - startIndex = 0; - endIndex = 0; - tmpLocal = null; - if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) - return false; - if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) - return false; - startIndex = emuStartIndex; - endIndex = emuEndIndex; - tmpLocal = _emuLocal; - return true; - } - - private bool FindEnd(IList instrs, int startIndex, out int endIndex) - { - for (var i = startIndex; i < instrs.Count; i++) - { - var instr = instrs[i]; - if (instr.OpCode.FlowControl != FlowControl.Next) - break; - if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) - continue; - endIndex = i - 1; - return true; - } - - endIndex = 0; - return false; - } - - private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - Local local; - if (instrs[i].OpCode.Code.Equals(Code.Conv_U) && instrs[i + 1].OpCode.Code.Equals(Code.Ldelem_U1) && - instrs[i + 2].OpCode.Code.Equals(Code.Or) && CheckLocal(instrs[i + 3], false) != null && - (local = CheckLocal(instrs[i + 4], true)) != null && CheckLocal(instrs[i + 5], true) != null && - instrs[i + 6].OpCode.Code.Equals(Code.Add) && CheckLocal(instrs[i + 7], false) == local) - { - var instr = instrs[i + 8]; - var newStartIndex = i + 8; - if (instr.IsBr()) - { - instr = instr.Operand as Instruction; - newStartIndex = instrs.IndexOf(instr); - } - - if (newStartIndex >= 0 && instr != null && CheckLocal(instr, true) == local) - { - startIndex = newStartIndex; - tmpLocal = local; - return true; - } - } - - i++; - } - - startIndex = 0; - tmpLocal = null; - return false; - } - - private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, - out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && - instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && - instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && - instrs[i + 3].OpCode.Code.Equals(Code.Add)) - { - var newEndIndex = i + 3; - var newStartIndex = -1; - for (var x = newEndIndex; x > 0; x--) - if (instrs[x].OpCode.FlowControl != FlowControl.Next) - { - if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || - instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) - { - _decrypterVersion = DecrypterVersion.V69; - continue; - } - - break; - } - - var ckStartIndex = -1; - for (var y = newEndIndex; y >= 0; y--) - if (instrs[y].IsBr()) - { - if (instrs[y].Operand is not Instruction instr) - continue; - if (instrs.IndexOf(instr) < y) - { - if (instrs[y - 1].Operand is not Instruction) - continue; - instr = instrs[y - 1].Operand as Instruction; - if (instrs.IndexOf(instr) < y) - continue; - } - newStartIndex = instrs.IndexOf(instr); - ckStartIndex = newStartIndex; - break; - } - - - if (newStartIndex >= 0) - { - var checkLocs = new List(); - for (var y = newEndIndex; y >= newStartIndex; y--) - if (CheckLocal(instrs[y], true) is { } loc) - if (!checkLocs.Contains(loc)) - checkLocs.Add(loc); - - endIndex = newEndIndex; - startIndex = Math.Max(ckStartIndex, newStartIndex); - tmpLocal = CheckLocal(instrs[startIndex], true); - return true; - } - } - - i++; - } - - endIndex = 0; - startIndex = 0; - tmpLocal = null; - return false; - } - - private Local CheckLocal(Instruction instr, bool isLdloc) - { - switch (isLdloc) - { - case true when !instr.IsLdloc(): - case false when !instr.IsStloc(): - return null; - default: - return instr.GetLocal(_locals); - } - } - - - private readonly InstructionEmulator _instrEmulator = new(); - private readonly List _locals; - private readonly MethodDef _decrypterMethod; - private Local _emuLocal; - private List _instructions; - private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; - } - - private class DecrypterV4 : IDecrypter - { - public DecrypterV4(MethodDef method) - { - if (!FindDecrypterMethod(method)) - throw new ApplicationException("Could not find decrypter method"); - - if (!FindEmulateMethod(_decrypterMethod)) - throw new ApplicationException("Could not find emulate method"); - - _key = GetDecryptionKey(_decrypterMethod); - _iv = GetDecryptionIV(_decrypterMethod); - _locals = new List(_emuMethod.Body.Variables); - if (!Initialize()) - throw new ApplicationException("Could not initialize decrypter"); - } - - public static bool CouldBeResourceDecrypter(MethodDef method, StringCounts stringCounts, - IEnumerable additionalTypes) - { - var requiredTypes = new List - { - "System.Int32", - "System.Byte[]" - }; - requiredTypes.AddRange(additionalTypes); - if (!stringCounts.All(requiredTypes)) - return false; - - var instrs = method.Body.Instructions; - - return instrs.Where(instr => instr.OpCode == OpCodes.Newobj).Any(instr => instr.Operand is IMethod - { - FullName: "System.Void System.Diagnostics.StackFrame::.ctor(System.Int32)" - }); - } - - public byte[] Decrypt(EmbeddedResource resource) - { - var encrypted = resource.CreateReader().ToArray(); - var decrypted = new byte[encrypted.Length]; - - uint sum = 0; - for (var i = 0; i < encrypted.Length; i += 4) - { - sum = CalculateMagic(sum + ReadUInt32(_key, i % _key.Length)); - WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); - } - - return decrypted; - } - - private bool FindDecrypterMethod(MethodDef method) - { - var instrs = method.Body.Instructions; - for (var i = 0; i < instrs.Count; i++) - { - if (instrs[i].OpCode != OpCodes.Ldsfld) - continue; - if (instrs[i + 1].OpCode != OpCodes.Ldstr) - continue; - if (instrs[i + 2].OpCode != OpCodes.Callvirt) - continue; - if (instrs[i + 3].OpCode != OpCodes.Ldarg_0) - continue; - var call = instrs[i + 4]; - if (call.OpCode != OpCodes.Call) - continue; - - _decrypterMethod = call.Operand as MethodDef; - return true; - } - - return false; - } - - private bool FindEmulateMethod(MethodDef method) - { - var instrs = method.Body.Instructions; - for (var i = 0; i < instrs.Count; i++) - { - if (instrs[i].OpCode != OpCodes.Newobj) - continue; - if (!instrs[i + 1].IsLdloc()) - continue; - if (!instrs[i + 2].IsLdloc()) - continue; - if (!instrs[i + 3].IsLdloc()) - continue; - var call = instrs[i + 4]; - if (call.OpCode != OpCodes.Call) - continue; - - _emuMethod = call.Operand as MethodDef; - return true; - } - - return false; - } - - private bool Initialize() - { - var origInstrs = _emuMethod.Body.Instructions; - - if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal)) - if (!FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) - return false; - - for (var i = 0; i < _iv.Length; i++) - _key[i] ^= _iv[i]; - - var count = emuEndIndex - emuStartIndex + 1; - _instructions = new List(count); - for (var i = 0; i < count; i++) - _instructions.Add(origInstrs[emuStartIndex + i].Clone()); - - return true; - } - - private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) - { - startIndex = 0; - endIndex = 0; - tmpLocal = null; - - if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) - return false; - if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) - return false; - startIndex = emuStartIndex; - endIndex = emuEndIndex; - tmpLocal = _emuLocal; - return true; - } - - private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, - out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && - instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && - instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && - instrs[i + 3].OpCode.Code.Equals(Code.Add)) - { - var newEndIndex = i + 3; - var newStartIndex = -1; - for (var x = newEndIndex; x > 0; x--) - if (instrs[x].OpCode.FlowControl != FlowControl.Next) - { - if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || - instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) - { - _decrypterVersion = DecrypterVersion.V69; - continue; - } - - break; - } - - var ckStartIndex = -1; - for (var y = newEndIndex; y >= 0; y--) - if (instrs[y].IsBr()) - { - if (instrs[y].Operand is not Instruction instr) - continue; - if (instrs.IndexOf(instr) < y) - { - if (instrs[y - 1].Operand is not Instruction) - continue; - instr = instrs[y - 1].Operand as Instruction; - if (instrs.IndexOf(instr) < y) - continue; - } - newStartIndex = instrs.IndexOf(instr); - ckStartIndex = newStartIndex; - break; - } - - - if (newStartIndex >= 0) - { - var checkLocs = new List(); - for (var y = newEndIndex; y >= newStartIndex; y--) - if (CheckLocal(instrs[y], true) is { } loc) - if (!checkLocs.Contains(loc)) - checkLocs.Add(loc); - - endIndex = newEndIndex; - startIndex = Math.Max(ckStartIndex, newStartIndex); - tmpLocal = CheckLocal(instrs[startIndex], true); - return true; - } - } - - i++; - } - - endIndex = 0; - startIndex = 0; - tmpLocal = null; - return false; - } - - private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) - { - for (var i = 0; i + 8 < instrs.Count; i++) - { - if (instrs[i].OpCode.Code != Code.Conv_U) - continue; - if (instrs[i + 1].OpCode.Code != Code.Ldelem_U1) - continue; - if (instrs[i + 2].OpCode.Code != Code.Or) - continue; - if (CheckLocal(instrs[i + 3], false) == null) - continue; - Local local; - if ((local = CheckLocal(instrs[i + 4], true)) == null) - continue; - if (CheckLocal(instrs[i + 5], true) == null) - continue; - if (instrs[i + 6].OpCode.Code != Code.Add) - continue; - if (CheckLocal(instrs[i + 7], false) != local) - continue; - var instr = instrs[i + 8]; - var newStartIndex = i + 8; - if (instr.IsBr()) - { - instr = instr.Operand as Instruction; - newStartIndex = instrs.IndexOf(instr); - } - - if (newStartIndex < 0 || instr == null) - continue; - if (CheckLocal(instr, true) != local) - continue; - - startIndex = newStartIndex; - tmpLocal = local; - return true; - } - - startIndex = 0; - tmpLocal = null; - return false; - } - - private bool FindEnd(IList instrs, int startIndex, out int endIndex) - { - for (var i = startIndex; i < instrs.Count; i++) - { - var instr = instrs[i]; - if (instr.OpCode.FlowControl != FlowControl.Next) - break; - if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) - continue; - - endIndex = i - 1; - return true; - } - - endIndex = 0; - return false; - } - - private Local CheckLocal(Instruction instr, bool isLdloc) - { - switch (isLdloc) - { - case true when !instr.IsLdloc(): - case false when !instr.IsStloc(): - return null; - default: - return instr.GetLocal(_locals); - } - } - - private uint CalculateMagic(uint input) - { - _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, - false); - _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); - - var index = 0; - while (index < _instructions.Count) - { - try - { - if (_decrypterVersion != DecrypterVersion.V69) - goto Emulate; - if (!_instructions[index].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) - goto Emulate; - if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && - !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) - goto Emulate; - if (!_instructions[index + 3].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) - goto Emulate; - if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) - goto Emulate; - if (!_instructions[index + 6].IsStloc()) - goto Emulate; - - switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) - { - case Int32Value int32: - { - if (int32.Value != Int32Value.Zero.Value) - index += 7; - break; - } - case Int64Value int64: - { - if (int64.Value != Int64Value.Zero.Value) - index += 7; - break; - } - case Real8Value real8Value: - { - if (!real8Value.Value.Equals(new Real8Value(0).Value)) - index += 7; - break; - } - } - } - catch { } - - Emulate: - _instrEmulator.Emulate(_instructions[index]); - index++; - } - - if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) - throw new ApplicationException("Couldn't calculate magic value"); - return (uint)tos.Value; - } - - private static uint ReadUInt32(byte[] ary, int index) - { - var sizeLeft = ary.Length - index; - if (sizeLeft >= 4) - return BitConverter.ToUInt32(ary, index); - return sizeLeft switch - { - 1 => ary[index], - 2 => (uint)(ary[index] | (ary[index + 1] << 8)), - 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), - _ => throw new ApplicationException("Can't read data") - }; - } - - private static void WriteUInt32(IList ary, int index, uint value) - { - var sizeLeft = ary.Count - index; - if (sizeLeft >= 1) - ary[index] = (byte)value; - if (sizeLeft >= 2) - ary[index + 1] = (byte)(value >> 8); - if (sizeLeft >= 3) - ary[index + 2] = (byte)(value >> 16); - if (sizeLeft >= 4) - ary[index + 3] = (byte)(value >> 24); - } - - - private readonly byte[] _key, _iv; - private MethodDef _decrypterMethod; - private MethodDef _emuMethod; - private List _instructions; - private readonly List _locals; - private readonly InstructionEmulator _instrEmulator = new(); - private Local _emuLocal; - private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; - } - - #endregion + } } \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV1.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV1.cs new file mode 100644 index 0000000..a327946 --- /dev/null +++ b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV1.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Linq; +using de4dot.blocks; +using dnlib.DotNet; +using dnlib.DotNet.Emit; + +namespace NETReactorSlayer.Core.Helper; + +internal partial class EncryptedResource +{ + private class DecrypterV1 : IDecrypter + { + public DecrypterV1(MethodDef method) + { + _key = GetDecryptionKey(method); + _iv = GetDecryptionIV(method); + } + + public static bool CouldBeResourceDecrypter(MethodDef method, StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new[] + { + new List + { + "System.Byte[]", + "System.Security.Cryptography.CryptoStream", + "System.Security.Cryptography.ICryptoTransform", + "System.String", + "System.Boolean" + }, + new List + { + "System.Security.Cryptography.ICryptoTransform", + "System.IO.Stream", + "System.Int32", + "System.Byte[]", + "System.Boolean" + }, + new List + { + "System.Security.Cryptography.ICryptoTransform", + "System.Int32", + "System.Byte[]", + "System.Boolean" + } + }; + requiredTypes[0].AddRange(additionalTypes); + + if (stringCounts.All(requiredTypes[0]) || + stringCounts.All(requiredTypes[1]) || + (stringCounts.All(requiredTypes[2]) && method.Body.Instructions.Any(x => + x.OpCode.Equals(OpCodes.Newobj) && x.Operand != null && x.Operand.ToString()! + .Contains("System.Security.Cryptography.CryptoStream::.ctor")))) + return DotNetUtils.GetMethod(method.DeclaringType, + "System.Security.Cryptography.SymmetricAlgorithm", + "()") == null || (!stringCounts.Exists("System.UInt64") && + (!stringCounts.Exists("System.UInt32") || + stringCounts.Exists("System.Reflection.Assembly"))); + + return false; + } + + public byte[] Decrypt(EmbeddedResource resource) => + DeobUtils.AesDecrypt(resource.CreateReader().ToArray(), _key, _iv); + + + private readonly byte[] _key, _iv; + } +} \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV2.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV2.cs new file mode 100644 index 0000000..023b573 --- /dev/null +++ b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV2.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections.Generic; +using de4dot.blocks; +using de4dot.blocks.cflow; +using dnlib.DotNet; +using dnlib.DotNet.Emit; + +namespace NETReactorSlayer.Core.Helper; + +internal partial class EncryptedResource +{ + private class DecrypterV2 : IDecrypter + { + public DecrypterV2(MethodDef method) + { + _key = GetDecryptionKey(method); + _iv = GetDecryptionIV(method); + _decrypterMethod = method; + _locals = new List(_decrypterMethod.Body.Variables); + if (!Initialize()) + throw new ApplicationException("Could not initialize decrypter"); + } + + public static bool CouldBeResourceDecrypter(StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new List + { + "System.Int32", + "System.Byte[]" + }; + requiredTypes.AddRange(additionalTypes); + return stringCounts.All(requiredTypes); + } + + public byte[] Decrypt(EmbeddedResource resource) + { + var encrypted = resource.CreateReader().ToArray(); + var decrypted = new byte[encrypted.Length]; + var sum = 0U; + + if (_isNewDecrypter) + for (var i = 0; i < encrypted.Length; i += 4) + { + var value = ReadUInt32(_key, i % _key.Length); + sum += value + CalculateMagic(sum + value); + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + else + for (var j = 0; j < encrypted.Length; j += 4) + { + sum = CalculateMagic(sum + ReadUInt32(_key, j % _key.Length)); + WriteUInt32(decrypted, j, sum ^ ReadUInt32(encrypted, j)); + } + + return decrypted; + } + + private bool Initialize() + { + var origInstrs = _decrypterMethod.Body.Instructions; + if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal) && + !FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) + { + if (!FindStartEnd2(ref origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal, out _emuArg, + ref _emuMethod, ref _locals)) + return false; + _isNewDecrypter = true; + } + + if (!_isNewDecrypter) + for (var i = 0; i < _iv.Length; i++) + { + var array = _key; + array[i] ^= _iv[i]; + } + + var count = emuEndIndex - emuStartIndex + 1; + _instructions = new List(count); + for (var j = 0; j < count; j++) + _instructions.Add(origInstrs[emuStartIndex + j].Clone()); + return true; + } + + private Local CheckLocal(Instruction instr, bool isLdloc) + { + switch (isLdloc) + { + case true when !instr.IsLdloc(): + case false when !instr.IsStloc(): + return null; + default: + return instr.GetLocal(_locals); + } + } + + private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) + { + startIndex = 0; + endIndex = 0; + tmpLocal = null; + if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) + return false; + if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) + return false; + startIndex = emuStartIndex; + endIndex = emuEndIndex; + tmpLocal = _emuLocal; + return true; + } + + private bool FindEnd(IList instrs, int startIndex, out int endIndex) + { + for (var i = startIndex; i < instrs.Count; i++) + { + var instr = instrs[i]; + if (instr.OpCode.FlowControl != FlowControl.Next) + break; + if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) + continue; + endIndex = i - 1; + return true; + } + + endIndex = 0; + return false; + } + + private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + Local local; + if (instrs[i].OpCode.Code.Equals(Code.Conv_U) && instrs[i + 1].OpCode.Code.Equals(Code.Ldelem_U1) && + instrs[i + 2].OpCode.Code.Equals(Code.Or) && CheckLocal(instrs[i + 3], false) != null && + (local = CheckLocal(instrs[i + 4], true)) != null && CheckLocal(instrs[i + 5], true) != null && + instrs[i + 6].OpCode.Code.Equals(Code.Add) && CheckLocal(instrs[i + 7], false) == local) + { + var instr = instrs[i + 8]; + var newStartIndex = i + 8; + if (instr.IsBr()) + { + instr = instr.Operand as Instruction; + newStartIndex = instrs.IndexOf(instr); + } + + if (newStartIndex >= 0 && instr != null && CheckLocal(instr, true) == local) + { + startIndex = newStartIndex; + tmpLocal = local; + return true; + } + } + + i++; + } + + startIndex = 0; + tmpLocal = null; + return false; + } + + private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, + out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && + instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && + instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && + instrs[i + 3].OpCode.Code.Equals(Code.Add)) + { + var newEndIndex = i + 3; + var newStartIndex = -1; + for (var x = newEndIndex; x > 0; x--) + if (instrs[x].OpCode.FlowControl != FlowControl.Next) + { + if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || + instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) + { + _decrypterVersion = DecrypterVersion.V69; + continue; + } + + break; + } + + var ckStartIndex = -1; + for (var y = newEndIndex; y >= 0; y--) + if (instrs[y].IsBr()) + { + if (instrs[y].Operand is not Instruction instr) + continue; + if (instrs.IndexOf(instr) < y) + { + if (instrs[y - 1].Operand is not Instruction) + continue; + instr = instrs[y - 1].Operand as Instruction; + if (instrs.IndexOf(instr) < y) + continue; + } + newStartIndex = instrs.IndexOf(instr); + ckStartIndex = newStartIndex; + break; + } + + + if (newStartIndex >= 0) + { + var checkLocs = new List(); + for (var y = newEndIndex; y >= newStartIndex; y--) + if (CheckLocal(instrs[y], true) is { } loc) + if (!checkLocs.Contains(loc)) + checkLocs.Add(loc); + + endIndex = newEndIndex; + startIndex = Math.Max(ckStartIndex, newStartIndex); + tmpLocal = CheckLocal(instrs[startIndex], true); + return true; + } + } + + i++; + } + + endIndex = 0; + startIndex = 0; + tmpLocal = null; + return false; + } + + private static bool FindStartEnd2(ref IList instrs, out int startIndex, out int endIndex, + out Local tmpLocal, out Parameter tmpArg, ref MethodDef methodDef, ref List locals) + { + foreach (var instr in instrs) + { + MethodDef method; + if (!instr.OpCode.Equals(OpCodes.Call) || (method = instr.Operand as MethodDef) == null || + method.ReturnType.FullName != "System.Byte[]") + continue; + + using var enumerator2 = DotNetUtils.GetMethodCalls(method).GetEnumerator(); + while (enumerator2.MoveNext()) + { + MethodDef calledMethod; + if ((calledMethod = enumerator2.Current as MethodDef) == null || + calledMethod.Parameters.Count != 2) + continue; + instrs = calledMethod.Body.Instructions; + methodDef = calledMethod; + locals = new List(calledMethod.Body.Variables); + startIndex = 0; + endIndex = instrs.Count - 1; + tmpLocal = null; + tmpArg = calledMethod.Parameters[1]; + return true; + } + } + + endIndex = 0; + startIndex = 0; + tmpLocal = null; + tmpArg = null; + return false; + } + + private static uint ReadUInt32(byte[] ary, int index) + { + var sizeLeft = ary.Length - index; + if (sizeLeft >= 4) + return BitConverter.ToUInt32(ary, index); + return sizeLeft switch + { + 1 => ary[index], + 2 => (uint)(ary[index] | (ary[index + 1] << 8)), + 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), + _ => throw new ApplicationException("Can't read data") + }; + } + + private static void WriteUInt32(IList ary, int index, uint value) + { + var num = ary.Count - index; + if (num >= 1) + ary[index] = (byte)value; + if (num >= 2) + ary[index + 1] = (byte)(value >> 8); + if (num >= 3) + ary[index + 2] = (byte)(value >> 16); + if (num >= 4) + ary[index + 3] = (byte)(value >> 24); + } + + private uint CalculateMagic(uint input) + { + if (_emuArg == null) + { + _instrEmulator.Initialize(_decrypterMethod, _decrypterMethod.Parameters, _locals, + _decrypterMethod.Body.InitLocals, false); + _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); + } + else + { + _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, + false); + _instrEmulator.SetArg(_emuArg, new Int32Value((int)input)); + } + + var index = 0; + while (index < _instructions.Count) + { + try + { + if (_decrypterVersion != DecrypterVersion.V69) + goto Emulate; + if (!_instructions[index].IsLdloc()) + goto Emulate; + if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) + goto Emulate; + if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && + !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) + goto Emulate; + if (!_instructions[index + 3].IsLdloc()) + goto Emulate; + if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) + goto Emulate; + if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) + goto Emulate; + if (!_instructions[index + 6].IsStloc()) + goto Emulate; + + switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) + { + case Int32Value int32: + { + if (int32.Value != Int32Value.Zero.Value) + index += 7; + break; + } + case Int64Value int64: + { + if (int64.Value != Int64Value.Zero.Value) + index += 7; + break; + } + case Real8Value real8Value: + { + if (!real8Value.Value.Equals(new Real8Value(0).Value)) + index += 7; + break; + } + } + } + catch { } + + Emulate: + _instrEmulator.Emulate(_instructions[index]); + index++; + } + + if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) + throw new ApplicationException("Couldn't calculate magic value"); + return (uint)tos.Value; + } + + + private readonly InstructionEmulator _instrEmulator = new(); + private readonly byte[] _key, _iv; + private readonly MethodDef _decrypterMethod; + private Parameter _emuArg; + private Local _emuLocal; + private MethodDef _emuMethod; + private List _instructions; + private bool _isNewDecrypter; + private List _locals; + private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; + } +} \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV3.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV3.cs new file mode 100644 index 0000000..1e25e05 --- /dev/null +++ b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV3.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections.Generic; +using de4dot.blocks.cflow; +using dnlib.DotNet; +using dnlib.DotNet.Emit; + +namespace NETReactorSlayer.Core.Helper; + +internal partial class EncryptedResource +{ + private class DecrypterV3 : IDecrypter + { + public DecrypterV3(MethodDef method) + { + _decrypterMethod = method; + _locals = new List(_decrypterMethod.Body.Variables); + if (!Initialize()) + throw new ApplicationException("Could not initialize decrypter"); + } + + public static bool CouldBeResourceDecrypter(StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new List + { + "System.Reflection.Emit.DynamicMethod", + "System.Reflection.Emit.ILGenerator" + }; + requiredTypes.AddRange(additionalTypes); + return stringCounts.All(requiredTypes); + } + + public byte[] Decrypt(EmbeddedResource resource) + { + var encrypted = resource.CreateReader().ToArray(); + var decrypted = new byte[encrypted.Length]; + var sum = 0U; + + for (var i = 0; i < encrypted.Length; i += 4) + { + sum = CalculateMagic(sum); + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + + return decrypted; + } + + private bool Initialize() + { + var origInstrs = _decrypterMethod.Body.Instructions; + if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal) && + !FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) + return false; + var count = emuEndIndex - emuStartIndex + 1; + _instructions = new List(count); + for (var i = 0; i < count; i++) + _instructions.Add(origInstrs[emuStartIndex + i].Clone()); + return true; + } + + private uint CalculateMagic(uint input) + { + _instrEmulator.Initialize(_decrypterMethod, _decrypterMethod.Parameters, _locals, + _decrypterMethod.Body.InitLocals, false); + _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); + + var index = 0; + while (index < _instructions.Count) + { + try + { + if (_decrypterVersion != DecrypterVersion.V69) + goto Emulate; + if (!_instructions[index].IsLdloc()) + goto Emulate; + if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) + goto Emulate; + if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && + !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) + goto Emulate; + if (!_instructions[index + 3].IsLdloc()) + goto Emulate; + if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) + goto Emulate; + if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) + goto Emulate; + if (!_instructions[index + 6].IsStloc()) + goto Emulate; + + switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) + { + case Int32Value int32: + { + if (int32.Value != Int32Value.Zero.Value) + index += 7; + break; + } + case Int64Value int64: + { + if (int64.Value != Int64Value.Zero.Value) + index += 7; + break; + } + case Real8Value real8Value: + { + if (!real8Value.Value.Equals(new Real8Value(0).Value)) + index += 7; + break; + } + } + } + catch { } + + Emulate: + _instrEmulator.Emulate(_instructions[index]); + index++; + } + + if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) + throw new ApplicationException("Couldn't calculate magic value"); + return (uint)tos.Value; + } + + private static uint ReadUInt32(byte[] ary, int index) + { + var sizeLeft = ary.Length - index; + if (sizeLeft >= 4) + return BitConverter.ToUInt32(ary, index); + return sizeLeft switch + { + 1 => ary[index], + 2 => (uint)(ary[index] | (ary[index + 1] << 8)), + 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), + _ => throw new ApplicationException("Can't read data") + }; + } + + private static void WriteUInt32(IList ary, int index, uint value) + { + var num = ary.Count - index; + if (num >= 1) + ary[index] = (byte)value; + if (num >= 2) + ary[index + 1] = (byte)(value >> 8); + if (num >= 3) + ary[index + 2] = (byte)(value >> 16); + if (num >= 4) + ary[index + 3] = (byte)(value >> 24); + } + + private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) + { + startIndex = 0; + endIndex = 0; + tmpLocal = null; + if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) + return false; + if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) + return false; + startIndex = emuStartIndex; + endIndex = emuEndIndex; + tmpLocal = _emuLocal; + return true; + } + + private bool FindEnd(IList instrs, int startIndex, out int endIndex) + { + for (var i = startIndex; i < instrs.Count; i++) + { + var instr = instrs[i]; + if (instr.OpCode.FlowControl != FlowControl.Next) + break; + if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) + continue; + endIndex = i - 1; + return true; + } + + endIndex = 0; + return false; + } + + private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + Local local; + if (instrs[i].OpCode.Code.Equals(Code.Conv_U) && instrs[i + 1].OpCode.Code.Equals(Code.Ldelem_U1) && + instrs[i + 2].OpCode.Code.Equals(Code.Or) && CheckLocal(instrs[i + 3], false) != null && + (local = CheckLocal(instrs[i + 4], true)) != null && CheckLocal(instrs[i + 5], true) != null && + instrs[i + 6].OpCode.Code.Equals(Code.Add) && CheckLocal(instrs[i + 7], false) == local) + { + var instr = instrs[i + 8]; + var newStartIndex = i + 8; + if (instr.IsBr()) + { + instr = instr.Operand as Instruction; + newStartIndex = instrs.IndexOf(instr); + } + + if (newStartIndex >= 0 && instr != null && CheckLocal(instr, true) == local) + { + startIndex = newStartIndex; + tmpLocal = local; + return true; + } + } + + i++; + } + + startIndex = 0; + tmpLocal = null; + return false; + } + + private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, + out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && + instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && + instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && + instrs[i + 3].OpCode.Code.Equals(Code.Add)) + { + var newEndIndex = i + 3; + var newStartIndex = -1; + for (var x = newEndIndex; x > 0; x--) + if (instrs[x].OpCode.FlowControl != FlowControl.Next) + { + if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || + instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) + { + _decrypterVersion = DecrypterVersion.V69; + continue; + } + + break; + } + + var ckStartIndex = -1; + for (var y = newEndIndex; y >= 0; y--) + if (instrs[y].IsBr()) + { + if (instrs[y].Operand is not Instruction instr) + continue; + if (instrs.IndexOf(instr) < y) + { + if (instrs[y - 1].Operand is not Instruction) + continue; + instr = instrs[y - 1].Operand as Instruction; + if (instrs.IndexOf(instr) < y) + continue; + } + newStartIndex = instrs.IndexOf(instr); + ckStartIndex = newStartIndex; + break; + } + + + if (newStartIndex >= 0) + { + var checkLocs = new List(); + for (var y = newEndIndex; y >= newStartIndex; y--) + if (CheckLocal(instrs[y], true) is { } loc) + if (!checkLocs.Contains(loc)) + checkLocs.Add(loc); + + endIndex = newEndIndex; + startIndex = Math.Max(ckStartIndex, newStartIndex); + tmpLocal = CheckLocal(instrs[startIndex], true); + return true; + } + } + + i++; + } + + endIndex = 0; + startIndex = 0; + tmpLocal = null; + return false; + } + + private Local CheckLocal(Instruction instr, bool isLdloc) + { + switch (isLdloc) + { + case true when !instr.IsLdloc(): + case false when !instr.IsStloc(): + return null; + default: + return instr.GetLocal(_locals); + } + } + + + private readonly InstructionEmulator _instrEmulator = new(); + private readonly List _locals; + private readonly MethodDef _decrypterMethod; + private Local _emuLocal; + private List _instructions; + private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; + } +} \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs new file mode 100644 index 0000000..d24af1a --- /dev/null +++ b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs @@ -0,0 +1,391 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using de4dot.blocks.cflow; +using dnlib.DotNet; +using dnlib.DotNet.Emit; + +namespace NETReactorSlayer.Core.Helper; + +internal partial class EncryptedResource +{ + private class DecrypterV4 : IDecrypter + { + public DecrypterV4(MethodDef method) + { + if (!FindDecrypterMethod(method)) + throw new ApplicationException("Could not find decrypter method"); + + if (!FindEmulateMethod(_decrypterMethod)) + throw new ApplicationException("Could not find emulate method"); + + _key = GetDecryptionKey(_decrypterMethod); + _iv = GetDecryptionIV(_decrypterMethod); + _locals = new List(_emuMethod.Body.Variables); + if (!Initialize()) + throw new ApplicationException("Could not initialize decrypter"); + } + + public static bool CouldBeResourceDecrypter(MethodDef method, StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new List + { + "System.Int32", + "System.Byte[]" + }; + requiredTypes.AddRange(additionalTypes); + if (!stringCounts.All(requiredTypes)) + return false; + + var instrs = method.Body.Instructions; + + return instrs.Where(instr => instr.OpCode == OpCodes.Newobj).Any(instr => instr.Operand is IMethod + { + FullName: "System.Void System.Diagnostics.StackFrame::.ctor(System.Int32)" + }); + } + + public byte[] Decrypt(EmbeddedResource resource) + { + var encrypted = resource.CreateReader().ToArray(); + var decrypted = new byte[encrypted.Length]; + + uint sum = 0; + for (var i = 0; i < encrypted.Length; i += 4) + { + sum = CalculateMagic(sum + ReadUInt32(_key, i % _key.Length)); + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + + return decrypted; + } + + private bool FindDecrypterMethod(MethodDef method) + { + var instrs = method.Body.Instructions; + for (var i = 0; i < instrs.Count; i++) + { + if (instrs[i].OpCode != OpCodes.Ldsfld) + continue; + if (instrs[i + 1].OpCode != OpCodes.Ldstr) + continue; + if (instrs[i + 2].OpCode != OpCodes.Callvirt) + continue; + if (instrs[i + 3].OpCode != OpCodes.Ldarg_0) + continue; + var call = instrs[i + 4]; + if (call.OpCode != OpCodes.Call) + continue; + + _decrypterMethod = call.Operand as MethodDef; + return true; + } + + return false; + } + + private bool FindEmulateMethod(MethodDef method) + { + var instrs = method.Body.Instructions; + for (var i = 0; i < instrs.Count; i++) + { + if (instrs[i].OpCode != OpCodes.Newobj) + continue; + if (!instrs[i + 1].IsLdloc()) + continue; + if (!instrs[i + 2].IsLdloc()) + continue; + if (!instrs[i + 3].IsLdloc()) + continue; + var call = instrs[i + 4]; + if (call.OpCode != OpCodes.Call) + continue; + + _emuMethod = call.Operand as MethodDef; + return true; + } + + return false; + } + + private bool Initialize() + { + var origInstrs = _emuMethod.Body.Instructions; + + if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal)) + if (!FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) + return false; + + for (var i = 0; i < _iv.Length; i++) + _key[i] ^= _iv[i]; + + var count = emuEndIndex - emuStartIndex + 1; + _instructions = new List(count); + for (var i = 0; i < count; i++) + _instructions.Add(origInstrs[emuStartIndex + i].Clone()); + + return true; + } + + private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) + { + startIndex = 0; + endIndex = 0; + tmpLocal = null; + + if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) + return false; + if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) + return false; + startIndex = emuStartIndex; + endIndex = emuEndIndex; + tmpLocal = _emuLocal; + return true; + } + + private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, + out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && + instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && + instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && + instrs[i + 3].OpCode.Code.Equals(Code.Add)) + { + var newEndIndex = i + 3; + var newStartIndex = -1; + for (var x = newEndIndex; x > 0; x--) + if (instrs[x].OpCode.FlowControl != FlowControl.Next) + { + if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || + instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) + { + _decrypterVersion = DecrypterVersion.V69; + continue; + } + + break; + } + + var ckStartIndex = -1; + for (var y = newEndIndex; y >= 0; y--) + if (instrs[y].IsBr()) + { + if (instrs[y].Operand is not Instruction instr) + continue; + if (instrs.IndexOf(instr) < y) + { + if (instrs[y - 1].Operand is not Instruction) + continue; + instr = instrs[y - 1].Operand as Instruction; + if (instrs.IndexOf(instr) < y) + continue; + } + newStartIndex = instrs.IndexOf(instr); + ckStartIndex = newStartIndex; + break; + } + + + if (newStartIndex >= 0) + { + var checkLocs = new List(); + for (var y = newEndIndex; y >= newStartIndex; y--) + if (CheckLocal(instrs[y], true) is { } loc) + if (!checkLocs.Contains(loc)) + checkLocs.Add(loc); + + endIndex = newEndIndex; + startIndex = Math.Max(ckStartIndex, newStartIndex); + tmpLocal = CheckLocal(instrs[startIndex], true); + return true; + } + } + + i++; + } + + endIndex = 0; + startIndex = 0; + tmpLocal = null; + return false; + } + + private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) + { + for (var i = 0; i + 8 < instrs.Count; i++) + { + if (instrs[i].OpCode.Code != Code.Conv_U) + continue; + if (instrs[i + 1].OpCode.Code != Code.Ldelem_U1) + continue; + if (instrs[i + 2].OpCode.Code != Code.Or) + continue; + if (CheckLocal(instrs[i + 3], false) == null) + continue; + Local local; + if ((local = CheckLocal(instrs[i + 4], true)) == null) + continue; + if (CheckLocal(instrs[i + 5], true) == null) + continue; + if (instrs[i + 6].OpCode.Code != Code.Add) + continue; + if (CheckLocal(instrs[i + 7], false) != local) + continue; + var instr = instrs[i + 8]; + var newStartIndex = i + 8; + if (instr.IsBr()) + { + instr = instr.Operand as Instruction; + newStartIndex = instrs.IndexOf(instr); + } + + if (newStartIndex < 0 || instr == null) + continue; + if (CheckLocal(instr, true) != local) + continue; + + startIndex = newStartIndex; + tmpLocal = local; + return true; + } + + startIndex = 0; + tmpLocal = null; + return false; + } + + private bool FindEnd(IList instrs, int startIndex, out int endIndex) + { + for (var i = startIndex; i < instrs.Count; i++) + { + var instr = instrs[i]; + if (instr.OpCode.FlowControl != FlowControl.Next) + break; + if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) + continue; + + endIndex = i - 1; + return true; + } + + endIndex = 0; + return false; + } + + private Local CheckLocal(Instruction instr, bool isLdloc) + { + switch (isLdloc) + { + case true when !instr.IsLdloc(): + case false when !instr.IsStloc(): + return null; + default: + return instr.GetLocal(_locals); + } + } + + private uint CalculateMagic(uint input) + { + _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, + false); + _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); + + var index = 0; + while (index < _instructions.Count) + { + try + { + if (_decrypterVersion != DecrypterVersion.V69) + goto Emulate; + if (!_instructions[index].IsLdloc()) + goto Emulate; + if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) + goto Emulate; + if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && + !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) + goto Emulate; + if (!_instructions[index + 3].IsLdloc()) + goto Emulate; + if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) + goto Emulate; + if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) + goto Emulate; + if (!_instructions[index + 6].IsStloc()) + goto Emulate; + + switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) + { + case Int32Value int32: + { + if (int32.Value != Int32Value.Zero.Value) + index += 7; + break; + } + case Int64Value int64: + { + if (int64.Value != Int64Value.Zero.Value) + index += 7; + break; + } + case Real8Value real8Value: + { + if (!real8Value.Value.Equals(new Real8Value(0).Value)) + index += 7; + break; + } + } + } + catch { } + + Emulate: + _instrEmulator.Emulate(_instructions[index]); + index++; + } + + if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) + throw new ApplicationException("Couldn't calculate magic value"); + return (uint)tos.Value; + } + + private static uint ReadUInt32(byte[] ary, int index) + { + var sizeLeft = ary.Length - index; + if (sizeLeft >= 4) + return BitConverter.ToUInt32(ary, index); + return sizeLeft switch + { + 1 => ary[index], + 2 => (uint)(ary[index] | (ary[index + 1] << 8)), + 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), + _ => throw new ApplicationException("Can't read data") + }; + } + + private static void WriteUInt32(IList ary, int index, uint value) + { + var sizeLeft = ary.Count - index; + if (sizeLeft >= 1) + ary[index] = (byte)value; + if (sizeLeft >= 2) + ary[index + 1] = (byte)(value >> 8); + if (sizeLeft >= 3) + ary[index + 2] = (byte)(value >> 16); + if (sizeLeft >= 4) + ary[index + 3] = (byte)(value >> 24); + } + + + private readonly byte[] _key, _iv; + private MethodDef _decrypterMethod; + private MethodDef _emuMethod; + private List _instructions; + private readonly List _locals; + private readonly InstructionEmulator _instrEmulator = new(); + private Local _emuLocal; + private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; + } +} \ No newline at end of file From 1fa14ee793c401666f21543ec5b0983b700e11dd Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Sun, 16 Jun 2024 22:51:54 +0200 Subject: [PATCH 05/11] Fixed .NET Core Method Decryption for DNR v6.9.8.0 --- .../Stages/MethodDecrypter.cs | 92 ++++++++++++++++--- 1 file changed, 81 insertions(+), 11 deletions(-) diff --git a/NETReactorSlayer.Core/Stages/MethodDecrypter.cs b/NETReactorSlayer.Core/Stages/MethodDecrypter.cs index 5feff43..374f226 100644 --- a/NETReactorSlayer.Core/Stages/MethodDecrypter.cs +++ b/NETReactorSlayer.Core/Stages/MethodDecrypter.cs @@ -134,6 +134,13 @@ private bool FindBinaryReaderMethod(out int popCallsCount) for (var i = 0; i < decrypterMethod.Body.Instructions.Count; i++) try { + var skip = CheckNet6Calls(decrypterMethod, i, method); + if (skip) + { + popCallsCount = 4; + break; + } + if (!decrypterMethod.Body.Instructions[i].IsLdloc() || !decrypterMethod.Body.Instructions[i + 1].OpCode.Equals(OpCodes.Callvirt) || decrypterMethod.Body.Instructions[i + 1].Operand is not MethodDef calledMethod || @@ -144,7 +151,7 @@ private bool FindBinaryReaderMethod(out int popCallsCount) popCallsCount++; } catch { } - + return true; } catch { } @@ -152,11 +159,43 @@ private bool FindBinaryReaderMethod(out int popCallsCount) return false; } + private bool CheckNet6Calls(MethodDef decrypterMethod, int i, MethodDef method) + { + //.NET 6+ doesn't only pop 4 times, it assigns them and does some obfuscated things, + //but they don't seem to be important + var inst = decrypterMethod.Body.Instructions; + if (!inst[i].IsLdloc() || + !inst[i + 1].OpCode.Equals(OpCodes.Callvirt) || + inst[i + 1].Operand is not MethodDef calledMethod1 || + !inst[i + 2].IsStloc() || + + !inst[i + 3].IsLdloc() || + !inst[i + 4].OpCode.Equals(OpCodes.Callvirt) || + inst[i + 4].Operand is not MethodDef calledMethod2 || + !inst[i + 5].OpCode.Equals(OpCodes.Stsfld) || + + !inst[i + 6].IsLdloc() || + !inst[i + 7].OpCode.Equals(OpCodes.Callvirt) || + inst[i + 7].Operand is not MethodDef calledMethod3 || + !inst[i + 8].OpCode.Equals(OpCodes.Pop) || + + !inst[i + 9].IsLdloc() || + !inst[i + 10].OpCode.Equals(OpCodes.Callvirt) || + inst[i + 10].Operand is not MethodDef calledMethod4 || + !inst[i + 11].IsStloc()) + return false; + + return MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod1, method) && + MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod2, method) && + MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod3, method) && + MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod4, method); + } + private bool RestoreMethodsBody(byte[] bytes) { var dumpedMethods = new DumpedMethods(); XorEncrypt(bytes, GetXorKey(_encryptedResource.DecrypterMethod)); - var isFindDnrMethod = FindDnrCompileMethod(_encryptedResource.DecrypterMethod.DeclaringType) != null; + var isFindDnrMethod = FindDnrCompileMethod(_encryptedResource.DecrypterMethod) != null; var methodsDataReader = ByteArrayDataReaderFactory.CreateReader(bytes); int tmp; @@ -328,15 +367,19 @@ private static bool IsUsingRva(MethodDef method) instrs[i + 8].OpCode.Code.Equals(Code.Call)).Any(); } - private static CompileMethodType GetCompileMethodType(IMethod method) + private static CompileMethodType GetCompileMethodType(IMethod method, string paramStruct = null) { if (DotNetUtils.IsMethod(method, "System.UInt32", "(System.UInt64&,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr&,System.UInt32&)")) return CompileMethodType.V1; - - return DotNetUtils.IsMethod(method, "System.UInt32", - "(System.IntPtr,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr,System.UInt32&)") - ? CompileMethodType.V2 + + if (DotNetUtils.IsMethod(method, "System.UInt32", + "(System.IntPtr,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr,System.UInt32&)")) + return CompileMethodType.V2; + + return paramStruct != null && DotNetUtils.IsMethod(method, "System.UInt32", + $"(System.IntPtr,System.IntPtr,{paramStruct}&,System.UInt32,System.IntPtr,System.UInt32&)") + ? CompileMethodType.V3 : CompileMethodType.Unknown; } @@ -373,12 +416,39 @@ private static long GetXorKey(MethodDef method) return 0; } - private static MethodDef FindDnrCompileMethod(TypeDef type) => - (from method in type.Methods + private static MethodDef FindDnrCompileMethod(MethodDef methodDef) + { + var type = methodDef.DeclaringType; + var methodCandidates = (from method in type.Methods where method.IsStatic && method.Body != null let sig = method.MethodSig where sig != null && sig.Params.Count == 6 - select method).FirstOrDefault(method => GetCompileMethodType(method) != CompileMethodType.Unknown); + select method).ToList(); + var dnrCompileMethod = methodCandidates.FirstOrDefault(method => GetCompileMethodType(method) != CompileMethodType.Unknown); + + if (dnrCompileMethod == null) + { + //.NET 6+ has a different compile method signature + var paramStruct = type.NestedTypes.FirstOrDefault(typeDef => + typeDef.Fields.Count == 4 && + typeDef.Fields[0].FieldType.FullName == "System.IntPtr" && + typeDef.Fields[1].FieldType.FullName == "System.IntPtr" && + typeDef.Fields[2].FieldType.FullName == "System.IntPtr" && + typeDef.Fields[3].FieldType.FullName == "System.Int32"); + + if (paramStruct != null) + { + var operands = methodDef.Body.Instructions + .Where(x => x.OpCode.Equals(OpCodes.Ldftn) && x.Operand is MethodDef) + .Select(x => x.Operand); + dnrCompileMethod = methodCandidates.Where(method => + GetCompileMethodType(method, paramStruct.FullName) != CompileMethodType.Unknown) + .FirstOrDefault(x => operands.Contains(x)); + } + } + + return dnrCompileMethod; + } private static void PatchDwords(MyPeImage peImage, ref DataReader reader, int count) { @@ -413,6 +483,6 @@ private static void XorEncrypt(byte[] data, long xorKey) private readonly short[] _nativeLdci40 = { 85, 139, 236, 51, 192, 93, 195 }; private EncryptedResource _encryptedResource; - private enum CompileMethodType { Unknown, V1, V2 } + private enum CompileMethodType { Unknown, V1, V2, V3 } } } \ No newline at end of file From 60879663f3fd63fdfb7486eb0bec0e29dc0b9932 Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Sun, 15 Dec 2024 02:06:13 +0100 Subject: [PATCH 06/11] Fixed string decryption with .NET Core assemblies. When Anti Tamper is enabled, it is not yet working --- .../Helper/EncryptedResource/DecrypterV4.cs | 104 +++++++++++++++++- 1 file changed, 100 insertions(+), 4 deletions(-) diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs index d24af1a..57d1ff3 100644 --- a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs +++ b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using de4dot.blocks.cflow; using dnlib.DotNet; using dnlib.DotNet.Emit; @@ -22,7 +23,8 @@ public DecrypterV4(MethodDef method) _key = GetDecryptionKey(_decrypterMethod); _iv = GetDecryptionIV(_decrypterMethod); _locals = new List(_emuMethod.Body.Variables); - if (!Initialize()) + + if (!Initialize() && !InitializeNetCore()) throw new ApplicationException("Could not initialize decrypter"); } @@ -54,14 +56,32 @@ public byte[] Decrypt(EmbeddedResource resource) uint sum = 0; for (var i = 0; i < encrypted.Length; i += 4) { - sum = CalculateMagic(sum + ReadUInt32(_key, i % _key.Length)); - WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + if (_netCoreDecrypterVersion) + { + var value = ReadUInt32(_key, i % _key.Length); + sum += value + CalculateMagic(sum + value); + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + else + { + sum = CalculateMagic(sum + ReadUInt32(_key, i % _key.Length)); + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + } + var debugStringValues = Encoding.Unicode.GetString(decrypted); + return decrypted; } private bool FindDecrypterMethod(MethodDef method) + { + return FindNetFrameworkDecrypterMethod(method) || + FindNetCoreDecrypterMethod(method); + } + + private bool FindNetFrameworkDecrypterMethod(MethodDef method) { var instrs = method.Body.Instructions; for (var i = 0; i < instrs.Count; i++) @@ -84,8 +104,43 @@ private bool FindDecrypterMethod(MethodDef method) return false; } + + private bool FindNetCoreDecrypterMethod(MethodDef method) + { + var instrs = method.Body.Instructions; + for (var i = 0; i < instrs.Count; i++) + { + if (instrs[i].OpCode != OpCodes.Ldtoken) + continue; + if (instrs[i + 1].OpCode != OpCodes.Call) + continue; + if (instrs[i + 2].OpCode != OpCodes.Call) + continue; + if (instrs[i + 3].OpCode != OpCodes.Callvirt) + continue; + if (instrs[i + 4].OpCode != OpCodes.Ldstr) + continue; + if (instrs[i + 5].OpCode != OpCodes.Callvirt) + continue; + var call = instrs[i + 6]; + if (call.OpCode != OpCodes.Call) + continue; + + _decrypterMethod = call.Operand as MethodDef; + _netCoreDecrypterVersion = true; + return true; + } + + return false; + } private bool FindEmulateMethod(MethodDef method) + { + return FindNetFrameworkEmulateMethod(method) || + FindNetCoreEmulateMethod(method); + } + + private bool FindNetFrameworkEmulateMethod(MethodDef method) { var instrs = method.Body.Instructions; for (var i = 0; i < instrs.Count; i++) @@ -108,6 +163,26 @@ private bool FindEmulateMethod(MethodDef method) return false; } + + private bool FindNetCoreEmulateMethod(MethodDef method) + { + var instrs = method.Body.Instructions; + for (var i = 0; i < instrs.Count; i++) + { + if (instrs[i].OpCode != OpCodes.Newobj) + continue; + if (!instrs[i + 1].IsLdloc()) + continue; + var call = instrs[i + 2]; + if (call.OpCode != OpCodes.Call) + continue; + + _emuMethod = call.Operand as MethodDef; + return true; + } + + return false; + } private bool Initialize() { @@ -127,6 +202,24 @@ private bool Initialize() return true; } + + private bool InitializeNetCore() + { + var origInstrs = _emuMethod.Body.Instructions; + + if (origInstrs.FirstOrDefault(x => x.OpCode.Equals(OpCodes.Call))?.Operand is not MethodDef magicMethod) + return false; + + _emuMethod = magicMethod; + _emuParameter = magicMethod.Parameters[1]; + _instructions = []; + foreach (var instr in magicMethod.Body.Instructions) + { + _instructions.Add(instr.Clone()); + } + + return true; + } private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) { @@ -292,7 +385,8 @@ private uint CalculateMagic(uint input) { _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, false); - _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); + if (_emuLocal != null) _instrEmulator.SetLocal(_emuLocal, new Int32Value((int) input)); + if (_emuParameter != null) _instrEmulator.SetArg(_emuParameter, new Int32Value((int) input)); var index = 0; while (index < _instructions.Count) @@ -386,6 +480,8 @@ private static void WriteUInt32(IList ary, int index, uint value) private readonly List _locals; private readonly InstructionEmulator _instrEmulator = new(); private Local _emuLocal; + private Parameter _emuParameter; + private bool _netCoreDecrypterVersion = false; private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; } } \ No newline at end of file From bf5bb928debaae4d69178ac0bc51c5bd349159c7 Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Sun, 15 Dec 2024 11:14:11 +0100 Subject: [PATCH 07/11] Fixes when anti tamper is enabled on a .NET Core assembly --- .../Helper/EncryptedResource/DecrypterV4.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs index 57d1ff3..5394a41 100644 --- a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs +++ b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs @@ -108,10 +108,13 @@ private bool FindNetFrameworkDecrypterMethod(MethodDef method) private bool FindNetCoreDecrypterMethod(MethodDef method) { var instrs = method.Body.Instructions; - for (var i = 0; i < instrs.Count; i++) + for (var i = 0; i < instrs.Count - 5; i++) { - if (instrs[i].OpCode != OpCodes.Ldtoken) - continue; + //this was not working with anti tamper enabled + //The instruction is modified in a later stage when enabled + //if (instrs[i].OpCode != OpCodes.Ldtoken) + // continue; + if (instrs[i + 1].OpCode != OpCodes.Call) continue; if (instrs[i + 2].OpCode != OpCodes.Call) From 46e3358bd8ad132aa852159bb7262088ac10c1af Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Sun, 15 Dec 2024 15:17:22 +0100 Subject: [PATCH 08/11] Fixed MethodDecrypter --- .../Stages/MethodDecrypter.cs | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/NETReactorSlayer.Core/Stages/MethodDecrypter.cs b/NETReactorSlayer.Core/Stages/MethodDecrypter.cs index 374f226..663f205 100644 --- a/NETReactorSlayer.Core/Stages/MethodDecrypter.cs +++ b/NETReactorSlayer.Core/Stages/MethodDecrypter.cs @@ -85,23 +85,31 @@ where call.MDToken.ToInt32() == method.MDToken.ToInt32() private bool Find2() { - var cctor = Context.Module.GlobalType.FindStaticConstructor(); - if (cctor is not { HasBody: true } || !cctor.Body.HasInstructions) - return false; - foreach (var instr in cctor.Body.Instructions.Where(instr => instr.OpCode.Equals(OpCodes.Call))) - if (instr.Operand is MethodDef { DeclaringType: { }, HasBody: true } methodDef && - methodDef.Body.HasInstructions) - if (DotNetUtils.GetMethod(methodDef.DeclaringType, - "System.Security.Cryptography.SymmetricAlgorithm", "()") != null) - { - if (!EncryptedResource.IsKnownDecrypter(methodDef, Array.Empty(), true)) - continue; + var staticConstructors = new[] + { + Context.Module.EntryPoint?.DeclaringType?.FindStaticConstructor(), + Context.Module.GlobalType.FindStaticConstructor() + }; - _encryptedResource = new EncryptedResource(Context, methodDef); - if (_encryptedResource.EmbeddedResource != null) - return true; - _encryptedResource.Dispose(); - } + foreach (var cctor in staticConstructors) + { + if (cctor is not { HasBody: true } || !cctor.Body.HasInstructions) + return false; + foreach (var instr in cctor.Body.Instructions.Where(instr => instr.OpCode.Equals(OpCodes.Call))) + if (instr.Operand is MethodDef { DeclaringType: not null, HasBody: true } methodDef && + methodDef.Body.HasInstructions) + if (DotNetUtils.GetMethod(methodDef.DeclaringType, + "System.Security.Cryptography.SymmetricAlgorithm", "()") != null) + { + if (!EncryptedResource.IsKnownDecrypter(methodDef, Array.Empty(), true)) + continue; + + _encryptedResource = new EncryptedResource(Context, methodDef); + if (_encryptedResource.EmbeddedResource != null) + return true; + _encryptedResource.Dispose(); + } + } return false; } From 0141c19d2b2a2a82b966b4093a2bca5285445f13 Mon Sep 17 00:00:00 2001 From: gembleman <81058727+gembleman@users.noreply.github.com> Date: Wed, 2 Jul 2025 06:05:40 +0900 Subject: [PATCH 09/11] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 65c6a44..cacaa2b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ GUI | CLI
### Binaries: -Get the latest stable version from [GitHub releases](https://github.com/SychicBoy/NETReactorSlayer/releases/latest). +I make no changes to this fork. I simply build it and publish releases.
+Get the latest stable version from [GitHub releases](https://github.com/gembleman/NETReactorSlayer/releases/latest).
+Thanks to [JBou](https://github.com/JBou/NETReactorSlayer) ### Documentation: Check out the [Wiki](https://github.com/SychicBoy/NETReactorSlayer/wiki) for guides and information on how to use it. From 588a3329b41bc489ce10831eae827eae8d820485 Mon Sep 17 00:00:00 2001 From: gembleman <81058727+gembleman@users.noreply.github.com> Date: Sun, 6 Jul 2025 16:57:07 +0900 Subject: [PATCH 10/11] Added .NET 9.0 support from CodeExplorer's source. --- .../NETReactorSlayer-x64.CLI.csproj | 35 +- NETReactorSlayer-x64.CLI/Program.cs | 4 +- .../NETReactorSlayer.CLI.csproj | 14 +- NETReactorSlayer.CLI/Program.cs | 2 +- .../Abstractions/IContext.cs | 4 +- NETReactorSlayer.Core/Abstractions/IInfo.cs | 2 +- NETReactorSlayer.Core/Abstractions/ILogger.cs | 2 +- .../Abstractions/IOptions.cs | 4 +- NETReactorSlayer.Core/Abstractions/IStage.cs | 2 +- NETReactorSlayer.Core/Context.cs | 23 +- NETReactorSlayer.Core/Helper/ArrayFinder.cs | 6 +- .../Helper/AssemblyModule.cs | 4 +- .../Helper/CodeVirtualizationUtils.cs | 4 +- NETReactorSlayer.Core/Helper/DeobUtils.cs | 22 +- .../Helper/DumpedMethodsRestorer.cs | 4 +- .../Helper/EncryptedResource.cs | 1280 ++++++++++++++- .../Helper/EncryptedResource/DecrypterV1.cs | 70 - .../Helper/EncryptedResource/DecrypterV2.cs | 380 ----- .../Helper/EncryptedResource/DecrypterV3.cs | 308 ---- .../Helper/EncryptedResource/DecrypterV4.cs | 490 ------ NETReactorSlayer.Core/Helper/FieldTypes.cs | 4 +- .../Helper/InvalidMethodBody.cs | 2 +- NETReactorSlayer.Core/Helper/LocalTypes.cs | 4 +- .../Helper/MethodBodyHeader.cs | 2 +- .../Helper/MethodBodyParser.cs | 4 +- .../Helper/MethodCallRemover.cs | 12 +- NETReactorSlayer.Core/Helper/MyPEImage.cs | 6 +- .../Helper/NativeUnpacker.cs | 22 +- NETReactorSlayer.Core/Helper/QuickLZ.cs | 2 +- NETReactorSlayer.Core/Helper/QuickLZBase.cs | 2 +- .../Helper/SimpleDeobfuscator.cs | 11 +- NETReactorSlayer.Core/Helper/StringCounts.cs | 2 +- .../Helper/TheAssemblyResolver.cs | 4 +- NETReactorSlayer.Core/Info.cs | 2 +- NETReactorSlayer.Core/Logger.cs | 22 +- .../NETReactorSlayer.Core.csproj | 12 +- NETReactorSlayer.Core/Options.cs | 69 +- NETReactorSlayer.Core/Program.cs | 8 +- .../Stages/AntiManipulationPatcher.cs | 4 +- .../Stages/AssemblyResolver.cs | 62 +- .../Stages/BooleanDecrypter.cs | 6 +- NETReactorSlayer.Core/Stages/Cleaner.cs | 20 +- .../Stages/ControlFlowDeobfuscator.cs | 1107 ++++++++++++- NETReactorSlayer.Core/Stages/CosturaDumper.cs | 6 +- .../Stages/MethodDecrypter.cs | 482 ++++-- NETReactorSlayer.Core/Stages/MethodInliner.cs | 235 ++- .../Stages/ProxyCallFixer.cs | 14 +- .../Stages/ResourceResolver.cs | 180 +- .../Stages/StringDecrypter.cs | 314 ++-- .../Stages/StrongNamePatcher.cs | 122 +- NETReactorSlayer.Core/Stages/SymbolRenamer.cs | 2 +- .../Stages/TokenDeobfuscator.cs | 66 +- NETReactorSlayer.Core/Stages/TypeRestorer.cs | 2 +- NETReactorSlayer.De4dot/Deobfuscator.cs | 2 +- NETReactorSlayer.De4dot/DeobfuscatorBase.cs | 2 +- NETReactorSlayer.De4dot/IDeobfuscator.cs | 2 +- NETReactorSlayer.De4dot/IObfuscatedFile.cs | 2 +- NETReactorSlayer.De4dot/MethodStack.cs | 6 +- .../NETReactorSlayer.De4dot.csproj | 6 +- NETReactorSlayer.De4dot/PushedArgs.cs | 4 +- NETReactorSlayer.De4dot/RandomNameChecker.cs | 2 +- .../Renamer/AsmModules/EventDefDict.cs | 2 +- .../Renamer/AsmModules/FieldDefDict.cs | 2 +- .../AsmModules/InterfaceMethodInfos.cs | 2 +- .../Renamer/AsmModules/MEventDef.cs | 2 +- .../Renamer/AsmModules/MGenericParamDef.cs | 2 +- .../Renamer/AsmModules/MMethodDef.cs | 2 +- .../Renamer/AsmModules/MPropertyDef.cs | 2 +- .../Renamer/AsmModules/MTypeDef.cs | 112 +- .../Renamer/AsmModules/MethodDefDict.cs | 2 +- .../Renamer/AsmModules/MethodInstances.cs | 12 +- .../Renamer/AsmModules/MethodNameGroup.cs | 16 +- .../Renamer/AsmModules/Module.cs | 2 +- .../Renamer/AsmModules/Modules.cs | 40 +- .../Renamer/AsmModules/PropertyDefDict.cs | 2 +- .../Renamer/AsmModules/TypeDefDict.cs | 2 +- .../Renamer/DerivedFrom.cs | 2 +- .../Renamer/ExistingNames.cs | 2 +- .../Renamer/MemberInfos.cs | 2 +- NETReactorSlayer.De4dot/Renamer/Renamer.cs | 162 +- .../Renamer/ResourceKeysRenamer.cs | 14 +- .../Renamer/ResourceRenamer.cs | 12 +- NETReactorSlayer.De4dot/Renamer/TypeInfo.cs | 82 +- NETReactorSlayer.De4dot/Renamer/TypeNames.cs | 14 +- .../Renamer/TypeRenamerState.cs | 2 +- NETReactorSlayer.De4dot/TypesRestorer.cs | 4 +- NETReactorSlayer.De4dot/TypesRestorerBase.cs | 6 +- NETReactorSlayer.GUI/Dialogs/MsgBox.cs | 4 +- NETReactorSlayer.GUI/Logger.cs | 2 +- NETReactorSlayer.GUI/MainWindow.Designer.cs | 1444 ++++++++++++++++- NETReactorSlayer.GUI/MainWindow.cs | 30 +- NETReactorSlayer.GUI/MenuColorTable.cs | 2 +- .../NETReactorSlayer.GUI.csproj | 7 +- NETReactorSlayer.GUI/Program.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/Resources.Designer.cs | 2 +- .../Properties/Settings.Designer.cs | 2 +- .../UserControls/NRSButton.Designer.cs | 2 +- .../UserControls/NRSButton.cs | 2 +- .../UserControls/NRSCheckBox.cs | 2 +- .../UserControls/NRSScrollBar.cs | 74 +- .../UserControls/NRSTextBox.Designer.cs | 2 +- .../UserControls/NRSTextBox.cs | 2 +- NETReactorSlayerCommon.props | 4 +- 104 files changed, 5227 insertions(+), 2360 deletions(-) delete mode 100644 NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV1.cs delete mode 100644 NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV2.cs delete mode 100644 NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV3.cs delete mode 100644 NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs diff --git a/NETReactorSlayer-x64.CLI/NETReactorSlayer-x64.CLI.csproj b/NETReactorSlayer-x64.CLI/NETReactorSlayer-x64.CLI.csproj index a627057..78308ce 100644 --- a/NETReactorSlayer-x64.CLI/NETReactorSlayer-x64.CLI.csproj +++ b/NETReactorSlayer-x64.CLI/NETReactorSlayer-x64.CLI.csproj @@ -3,27 +3,32 @@ - - AnyCPU + x86 ..\bin\$(Configuration)\ Exe + net9.0;net7.0;net48 + x64 - - - + + False + + + + False + - + + False + - - - - - - - + + False + - + + + - \ No newline at end of file + diff --git a/NETReactorSlayer-x64.CLI/Program.cs b/NETReactorSlayer-x64.CLI/Program.cs index 2c09f21..afe4949 100644 --- a/NETReactorSlayer-x64.CLI/Program.cs +++ b/NETReactorSlayer-x64.CLI/Program.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License using System; -namespace NETReactorSlayerr_x64.CLI +namespace NETReactorSlayer_x64.CLI { internal class Program { diff --git a/NETReactorSlayer.CLI/NETReactorSlayer.CLI.csproj b/NETReactorSlayer.CLI/NETReactorSlayer.CLI.csproj index d0227bf..3a12430 100644 --- a/NETReactorSlayer.CLI/NETReactorSlayer.CLI.csproj +++ b/NETReactorSlayer.CLI/NETReactorSlayer.CLI.csproj @@ -3,12 +3,20 @@ - - AnyCPU + x86 ..\bin\$(Configuration)\ Exe - true + net9.0;net7.0;net48 + x86 + + + + + 8 + + + 8 diff --git a/NETReactorSlayer.CLI/Program.cs b/NETReactorSlayer.CLI/Program.cs index ba8f342..551db58 100644 --- a/NETReactorSlayer.CLI/Program.cs +++ b/NETReactorSlayer.CLI/Program.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Abstractions/IContext.cs b/NETReactorSlayer.Core/Abstractions/IContext.cs index 46c111a..91ff2bf 100644 --- a/NETReactorSlayer.Core/Abstractions/IContext.cs +++ b/NETReactorSlayer.Core/Abstractions/IContext.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Reflection; using dnlib.DotNet; using NETReactorSlayer.Core.Helper; +using System.Reflection; namespace NETReactorSlayer.Core.Abstractions { diff --git a/NETReactorSlayer.Core/Abstractions/IInfo.cs b/NETReactorSlayer.Core/Abstractions/IInfo.cs index d9e0270..a652fd0 100644 --- a/NETReactorSlayer.Core/Abstractions/IInfo.cs +++ b/NETReactorSlayer.Core/Abstractions/IInfo.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Abstractions/ILogger.cs b/NETReactorSlayer.Core/Abstractions/ILogger.cs index 80fade1..81a9a20 100644 --- a/NETReactorSlayer.Core/Abstractions/ILogger.cs +++ b/NETReactorSlayer.Core/Abstractions/ILogger.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Abstractions/IOptions.cs b/NETReactorSlayer.Core/Abstractions/IOptions.cs index 599f349..4c11a45 100644 --- a/NETReactorSlayer.Core/Abstractions/IOptions.cs +++ b/NETReactorSlayer.Core/Abstractions/IOptions.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,8 +13,8 @@ You should have received a copy of the GNU General License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using NETReactorSlayer.De4dot.Renamer; +using System.Collections.Generic; namespace NETReactorSlayer.Core.Abstractions { diff --git a/NETReactorSlayer.Core/Abstractions/IStage.cs b/NETReactorSlayer.Core/Abstractions/IStage.cs index d9d9cce..c81b2e6 100644 --- a/NETReactorSlayer.Core/Abstractions/IStage.cs +++ b/NETReactorSlayer.Core/Abstractions/IStage.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Context.cs b/NETReactorSlayer.Core/Context.cs index 3da1bc6..2ee3872 100644 --- a/NETReactorSlayer.Core/Context.cs +++ b/NETReactorSlayer.Core/Context.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,15 +13,16 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Diagnostics; -using System.IO; -using System.Reflection; using dnlib.DotNet; using dnlib.DotNet.Writer; using dnlib.PE; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; using ILogger = NETReactorSlayer.Core.Abstractions.ILogger; namespace NETReactorSlayer.Core @@ -71,7 +72,7 @@ public bool Load() Process.Start(new ProcessStartInfo(Process.GetCurrentProcess().MainModule?.FileName, $"--del-temp {Process.GetCurrentProcess().Id} \"{Options.SourcePath}\"") - { WindowStyle = ProcessWindowStyle.Hidden }); + { WindowStyle = ProcessWindowStyle.Hidden }); Logger.Info("Native stub unpacked."); } @@ -125,6 +126,16 @@ public void Save() } } + + + // https://www.cnblogs.com/Fred1987/p/18603592 + + //copy from,https://gist.github.com/6rube/34b561827f0805f73742541b8b8bb770 + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + + static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); + private bool LoadAssembly() { try diff --git a/NETReactorSlayer.Core/Helper/ArrayFinder.cs b/NETReactorSlayer.Core/Helper/ArrayFinder.cs index 8791689..a670ee0 100644 --- a/NETReactorSlayer.Core/Helper/ArrayFinder.cs +++ b/NETReactorSlayer.Core/Helper/ArrayFinder.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -95,7 +95,7 @@ public static Value[] GetInitializedArray( emulator.Emulate(instr); } - done: + done: if (i != newarrIndex + 1) i--; newarrIndex = i; @@ -105,7 +105,7 @@ public static Value[] GetInitializedArray( private static int FindNewarr(MethodDef method, int arraySize) { - for (var i = 0;; i++) + for (var i = 0; ; i++) { if (!FindNewarr(method, ref i, out var size)) return -1; diff --git a/NETReactorSlayer.Core/Helper/AssemblyModule.cs b/NETReactorSlayer.Core/Helper/AssemblyModule.cs index 8a8a1dc..e78b452 100644 --- a/NETReactorSlayer.Core/Helper/AssemblyModule.cs +++ b/NETReactorSlayer.Core/Helper/AssemblyModule.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.IO; using dnlib.DotNet; +using System.IO; namespace NETReactorSlayer.Core.Helper { diff --git a/NETReactorSlayer.Core/Helper/CodeVirtualizationUtils.cs b/NETReactorSlayer.Core/Helper/CodeVirtualizationUtils.cs index 9383d1a..f350c4b 100644 --- a/NETReactorSlayer.Core/Helper/CodeVirtualizationUtils.cs +++ b/NETReactorSlayer.Core/Helper/CodeVirtualizationUtils.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Linq; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; +using System.Linq; namespace NETReactorSlayer.Core.Helper { diff --git a/NETReactorSlayer.Core/Helper/DeobUtils.cs b/NETReactorSlayer.Core/Helper/DeobUtils.cs index 4cdcce0..00cc17c 100644 --- a/NETReactorSlayer.Core/Helper/DeobUtils.cs +++ b/NETReactorSlayer.Core/Helper/DeobUtils.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,13 +13,12 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; +using ICSharpCode.SharpZipLib.Zip.Compression; using System; using System.IO; -using System.IO.Compression; using System.Linq; using System.Security.Cryptography; -using dnlib.DotNet; -using ICSharpCode.SharpZipLib.Zip.Compression; namespace NETReactorSlayer.Core.Helper { @@ -90,20 +89,5 @@ public static byte[] Inflate(byte[] data, int start, int len, Inflater inflater) return memStream.ToArray(); } - - public static byte[] BrotliDecompress(byte[] data) - { -#if (NETSTANDARD || NET) - var memoryStream = new MemoryStream(); - using (var brotliStream = new BrotliStream(new MemoryStream(data), CompressionMode.Decompress)) - { - brotliStream.CopyTo(memoryStream); - } - - return memoryStream.ToArray(); -#else - throw new ApplicationException("Brotli decompression not available on .NET Framework version. Use .NET6+ version"); -#endif - } } } \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/DumpedMethodsRestorer.cs b/NETReactorSlayer.Core/Helper/DumpedMethodsRestorer.cs index df7b79d..0e5a1d7 100644 --- a/NETReactorSlayer.Core/Helper/DumpedMethodsRestorer.cs +++ b/NETReactorSlayer.Core/Helper/DumpedMethodsRestorer.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,12 +13,12 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using dnlib.DotNet.MD; using dnlib.PE; +using System.Collections.Generic; namespace NETReactorSlayer.Core.Helper { diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource.cs b/NETReactorSlayer.Core/Helper/EncryptedResource.cs index 801f525..1092a18 100644 --- a/NETReactorSlayer.Core/Helper/EncryptedResource.cs +++ b/NETReactorSlayer.Core/Helper/EncryptedResource.cs @@ -1,21 +1,11 @@ -/* - Copyright (C) 2021 CodeStrikers.org - This file is part of NETReactorSlayer. - NETReactorSlayer is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - NETReactorSlayer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with NETReactorSlayer. If not, see . -*/ + using System; +using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Runtime.InteropServices; using de4dot.blocks; using de4dot.blocks.cflow; using dnlib.DotNet; @@ -24,7 +14,7 @@ You should have received a copy of the GNU General Public License namespace NETReactorSlayer.Core.Helper { - internal partial class EncryptedResource : IDisposable + internal class EncryptedResource : IDisposable { public EncryptedResource(IContext context, MethodDef method, IList additionalTypes) { @@ -72,6 +62,7 @@ private EmbeddedResource GetEncryptedResource(IContext context) return null; } + public static string DecrypterVer = ""; private IDecrypter GetDecrypter() { if (!DecrypterMethod.IsStatic || !DecrypterMethod.HasBody) @@ -79,18 +70,41 @@ private IDecrypter GetDecrypter() var localTypes = new LocalTypes(DecrypterMethod); + //if (DecrypterV2.CouldBeResourceDecrypter(localTypes, AdditionalTypes)) + //{ + DecrypterV5 dec_v5 = new DecrypterV5(DecrypterMethod); + if (dec_v5.Initialize()) + { + DecrypterVer = "V5 (trial)"; + return dec_v5; + } + //} + if (DecrypterV1.CouldBeResourceDecrypter(DecrypterMethod, localTypes, AdditionalTypes)) + { + DecrypterVer = "V1"; return new DecrypterV1(DecrypterMethod); - + } if (DecrypterV3.CouldBeResourceDecrypter(localTypes, AdditionalTypes)) + { + DecrypterVer = "V3"; return new DecrypterV3(DecrypterMethod); + } if (DecrypterV4.CouldBeResourceDecrypter(DecrypterMethod, localTypes, AdditionalTypes)) + { + DecrypterVer = "V4"; return new DecrypterV4(DecrypterMethod); + } - return DecrypterV2.CouldBeResourceDecrypter(localTypes, AdditionalTypes) - ? new DecrypterV2(DecrypterMethod) - : null; + if (DecrypterV2.CouldBeResourceDecrypter(localTypes, AdditionalTypes)) + { + + DecrypterVer = "V2"; + return new DecrypterV2(DecrypterMethod); + } + + return null; } public static bool IsKnownDecrypter(MethodDef method, IList additionalTypes, bool checkResource) @@ -171,41 +185,1231 @@ where instr.OpCode.Code is Code.Call or Code.Callvirt or Code.Newobj .Any(calledMethod => calledMethod.FullName.Contains(fullName)); } - public static bool TryGetLdcValue(Instruction instruction, out int value) + public MethodDef DecrypterMethod { get; } + public EmbeddedResource EmbeddedResource { get; private set; } + private IList AdditionalTypes { get; } + private IDecrypter Decrypter { get; set; } + + public enum DecrypterVersion { V69, V6X } + + private interface IDecrypter + { + byte[] Decrypt(EmbeddedResource resource); + } + + #region Nested Types + + private class DecrypterV1 : IDecrypter { - value = 0; + public DecrypterV1(MethodDef method) + { + _key = GetDecryptionKey(method); + _iv = GetDecryptionIV(method); + } + + public static bool CouldBeResourceDecrypter(MethodDef method, StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new[] + { + new List + { + "System.Byte[]", + "System.Security.Cryptography.CryptoStream", + "System.Security.Cryptography.ICryptoTransform", + "System.String", + "System.Boolean" + }, + new List + { + "System.Security.Cryptography.ICryptoTransform", + "System.IO.Stream", + "System.Int32", + "System.Byte[]", + "System.Boolean" + }, + new List + { + "System.Security.Cryptography.ICryptoTransform", + "System.Int32", + "System.Byte[]", + "System.Boolean" + } + }; + requiredTypes[0].AddRange(additionalTypes); + + if (stringCounts.All(requiredTypes[0]) || + stringCounts.All(requiredTypes[1]) || + (stringCounts.All(requiredTypes[2]) && method.Body.Instructions.Any(x => + x.OpCode.Equals(OpCodes.Newobj) && x.Operand != null && x.Operand.ToString()! + .Contains("System.Security.Cryptography.CryptoStream::.ctor")))) + return DotNetUtils.GetMethod(method.DeclaringType, + "System.Security.Cryptography.SymmetricAlgorithm", + "()") == null || (!stringCounts.Exists("System.UInt64") && + (!stringCounts.Exists("System.UInt32") || + stringCounts.Exists("System.Reflection.Assembly"))); - if (!instruction.IsLdcI4() && - !instruction.OpCode.Equals(OpCodes.Ldc_I8) && - !instruction.OpCode.Equals(OpCodes.Ldc_R4) && - !instruction.OpCode.Equals(OpCodes.Ldc_R8)) return false; + } + + public byte[] Decrypt(EmbeddedResource resource) => + DeobUtils.AesDecrypt(resource.CreateReader().ToArray(), _key, _iv); + - try + private readonly byte[] _key, _iv; + } + + private class DecrypterV2 : IDecrypter + { + public DecrypterV2(MethodDef method) { - value = instruction.IsLdcI4() ? - instruction.GetLdcI4Value() : - Convert.ToInt32(instruction.Operand); + _key = GetDecryptionKey(method); + _iv = GetDecryptionIV(method); + _decrypterMethod = method; + _locals = new List(_decrypterMethod.Body.Variables); + if (!Initialize()) + throw new ApplicationException("Could not initialize decrypter V2"); + } + + public static bool CouldBeResourceDecrypter(StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new List + { + "System.Int32", + "System.Byte[]" + }; + requiredTypes.AddRange(additionalTypes); + return stringCounts.All(requiredTypes); + } + public byte[] Decrypt(EmbeddedResource resource) + { + var encrypted = resource.CreateReader().ToArray(); + var decrypted = new byte[encrypted.Length]; + var sum = 0U; + + if (_isNewDecrypter) + for (var i = 0; i < encrypted.Length; i += 4) + { + var value = ReadUInt32(_key, i % _key.Length); + sum += value + CalculateMagic(sum + value); + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + else + for (var j = 0; j < encrypted.Length; j += 4) + { + sum = CalculateMagic(sum + ReadUInt32(_key, j % _key.Length)); + WriteUInt32(decrypted, j, sum ^ ReadUInt32(encrypted, j)); + } + + return decrypted; + } + + private bool Initialize() + { + var origInstrs = _decrypterMethod.Body.Instructions; + if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal) && + !FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) + { + if (!FindStartEnd2(ref origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal, out _emuArg, + ref _emuMethod, ref _locals)) + return false; + _isNewDecrypter = true; + } + + if (!_isNewDecrypter) + for (var i = 0; i < _iv.Length; i++) + { + var array = _key; + array[i] ^= _iv[i]; + } + + var count = emuEndIndex - emuStartIndex + 1; + _instructions = new List(count); + for (var j = 0; j < count; j++) + _instructions.Add(origInstrs[emuStartIndex + j].Clone()); return true; } - catch + + private Local CheckLocal(Instruction instr, bool isLdloc) + { + switch (isLdloc) + { + case true when !instr.IsLdloc(): + case false when !instr.IsStloc(): + return null; + default: + return instr.GetLocal(_locals); + } + } + + private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) + { + startIndex = 0; + endIndex = 0; + tmpLocal = null; + if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) + return false; + if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) + return false; + + startIndex = emuStartIndex; + endIndex = emuEndIndex; + tmpLocal = _emuLocal; + return true; + } + + private bool FindEnd(IList instrs, int startIndex, out int endIndex) + { + for (var i = startIndex; i < instrs.Count; i++) + { + var instr = instrs[i]; + if (instr.OpCode.FlowControl != FlowControl.Next) + break; + if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) + continue; + endIndex = i - 1; + return true; + } + + endIndex = 0; + return false; + } + + // https://www.cnblogs.com/Fred1987/p/18603592 + //copy from,https://gist.github.com/6rube/34b561827f0805f73742541b8b8bb770 + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); + + private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + Local local; + if (instrs[i].OpCode.Code.Equals(Code.Conv_U) && instrs[i + 1].OpCode.Code.Equals(Code.Ldelem_U1) && + instrs[i + 2].OpCode.Code.Equals(Code.Or) && CheckLocal(instrs[i + 3], false) != null && + (local = CheckLocal(instrs[i + 4], true)) != null && CheckLocal(instrs[i + 5], true) != null && + instrs[i + 6].OpCode.Code.Equals(Code.Add) && CheckLocal(instrs[i + 7], false) == local) + { + + var instr = instrs[i + 8]; + var newStartIndex = i + 8; + if (instr.IsBr()) + { + instr = instr.Operand as Instruction; + newStartIndex = instrs.IndexOf(instr); + } + + if (newStartIndex >= 0 && instr != null && CheckLocal(instr, true) == local) + { + startIndex = newStartIndex; + tmpLocal = local; + return true; + } + } + + i++; + } + + startIndex = 0; + tmpLocal = null; + return false; + } + + private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, + out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && + instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && + instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && + instrs[i + 3].OpCode.Code.Equals(Code.Add)) + { + var newEndIndex = i + 3; + var newStartIndex = -1; + for (var x = newEndIndex; x > 0; x--) + if (instrs[x].OpCode.FlowControl != FlowControl.Next) + { + if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || + instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) + { + _decrypterVersion = DecrypterVersion.V69; + continue; + } + + break; + } + + var ckStartIndex = -1; + for (var y = newEndIndex; y >= 0; y--) + if (instrs[y].IsBr()) + { + if (instrs[y].Operand is not Instruction instr) + continue; + if (instrs.IndexOf(instr) < y) + { + if (instrs[y - 1].Operand is not Instruction) + continue; + instr = instrs[y - 1].Operand as Instruction; + if (instrs.IndexOf(instr) < y) + continue; + } + newStartIndex = instrs.IndexOf(instr); + ckStartIndex = newStartIndex; + break; + } + + + if (newStartIndex >= 0) + { + var checkLocs = new List(); + for (var y = newEndIndex; y >= newStartIndex; y--) + if (CheckLocal(instrs[y], true) is { } loc) + if (!checkLocs.Contains(loc)) + checkLocs.Add(loc); + + endIndex = newEndIndex; + startIndex = Math.Max(ckStartIndex, newStartIndex); + tmpLocal = CheckLocal(instrs[startIndex], true); + return true; + } + } + + i++; + } + + endIndex = 0; + startIndex = 0; + tmpLocal = null; + return false; + } + + private static bool FindStartEnd2(ref IList instrs, out int startIndex, out int endIndex, + out Local tmpLocal, out Parameter tmpArg, ref MethodDef methodDef, ref List locals) { + foreach (var instr in instrs) + { + MethodDef method; + if (!instr.OpCode.Equals(OpCodes.Call) || (method = instr.Operand as MethodDef) == null || + method.ReturnType.FullName != "System.Byte[]") + continue; + + using var enumerator2 = DotNetUtils.GetMethodCalls(method).GetEnumerator(); + while (enumerator2.MoveNext()) + { + MethodDef calledMethod; + if ((calledMethod = enumerator2.Current as MethodDef) == null || + calledMethod.Parameters.Count != 2) + continue; + instrs = calledMethod.Body.Instructions; + methodDef = calledMethod; + locals = new List(calledMethod.Body.Variables); + startIndex = 0; + endIndex = instrs.Count - 1; + tmpLocal = null; + tmpArg = calledMethod.Parameters[1]; + return true; + } + } + + endIndex = 0; + startIndex = 0; + tmpLocal = null; + tmpArg = null; return false; } + + private static uint ReadUInt32(byte[] ary, int index) + { + var sizeLeft = ary.Length - index; + if (sizeLeft >= 4) + return BitConverter.ToUInt32(ary, index); + return sizeLeft switch + { + 1 => ary[index], + 2 => (uint)(ary[index] | (ary[index + 1] << 8)), + 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), + _ => throw new ApplicationException("Can't read data") + }; + } + + private static void WriteUInt32(IList ary, int index, uint value) + { + var num = ary.Count - index; + if (num >= 1) + ary[index] = (byte)value; + if (num >= 2) + ary[index + 1] = (byte)(value >> 8); + if (num >= 3) + ary[index + 2] = (byte)(value >> 16); + if (num >= 4) + ary[index + 3] = (byte)(value >> 24); + } + + private uint CalculateMagic(uint input) + { + if (_emuArg == null) + { + _instrEmulator.Initialize(_decrypterMethod, _decrypterMethod.Parameters, _locals, + _decrypterMethod.Body.InitLocals, false); + _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); + } + else + { + _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, + false); + _instrEmulator.SetArg(_emuArg, new Int32Value((int)input)); + } + + var index = 0; + while (index < _instructions.Count) + { + try + { + if (_decrypterVersion != DecrypterVersion.V69) + goto Emulate; + if (!_instructions[index].IsLdloc()) + goto Emulate; + if (!_instructions[index + 1].OpCode.Equals(OpCodes.Ldc_I4_0) && + (!_instructions[index + 1].IsLdcI4() || _instructions[index + 1].GetLdcI4Value() != 0)) + goto Emulate; + if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && + !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) + goto Emulate; + if (!_instructions[index + 3].IsLdloc()) + goto Emulate; + if (!_instructions[index + 4].OpCode.Equals(OpCodes.Ldc_I4_1) && + (!_instructions[index + 4].IsLdcI4() || _instructions[index + 4].GetLdcI4Value() != 1)) + goto Emulate; + if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) + goto Emulate; + if (!_instructions[index + 6].IsStloc()) + goto Emulate; + if (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false) + .Index) is Int32Value local && local.Value != Int32Value.Zero.Value) + index += 7; + } + catch { } + + Emulate: + _instrEmulator.Emulate(_instructions[index]); + index++; + } + + if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) + throw new ApplicationException("Couldn't calculate magic value"); + return (uint)tos.Value; + } + + + private readonly InstructionEmulator _instrEmulator = new(); + private readonly byte[] _key, _iv; + private readonly MethodDef _decrypterMethod; + private Parameter _emuArg; + private Local _emuLocal; + private MethodDef _emuMethod; + private List _instructions; + private bool _isNewDecrypter; + private List _locals; + private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; } - public MethodDef DecrypterMethod { get; } - public EmbeddedResource EmbeddedResource { get; private set; } - private IList AdditionalTypes { get; } - private IDecrypter Decrypter { get; set; } + private class DecrypterV3 : IDecrypter + { + public DecrypterV3(MethodDef method) + { + _decrypterMethod = method; + _locals = new List(_decrypterMethod.Body.Variables); + if (!Initialize()) + throw new ApplicationException("Could not initialize decrypter V3"); + } - public enum DecrypterVersion { V69, V6X } + public static bool CouldBeResourceDecrypter(StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new List + { + "System.Reflection.Emit.DynamicMethod", + "System.Reflection.Emit.ILGenerator" + }; + requiredTypes.AddRange(additionalTypes); + return stringCounts.All(requiredTypes); + } - private interface IDecrypter + public byte[] Decrypt(EmbeddedResource resource) + { + var encrypted = resource.CreateReader().ToArray(); + var decrypted = new byte[encrypted.Length]; + var sum = 0U; + + for (var i = 0; i < encrypted.Length; i += 4) + { + sum = CalculateMagic(sum); + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + + return decrypted; + } + + private bool Initialize() + { + var origInstrs = _decrypterMethod.Body.Instructions; + if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal) && + !FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) + return false; + var count = emuEndIndex - emuStartIndex + 1; + _instructions = new List(count); + for (var i = 0; i < count; i++) + _instructions.Add(origInstrs[emuStartIndex + i].Clone()); + return true; + } + + private uint CalculateMagic(uint input) + { + _instrEmulator.Initialize(_decrypterMethod, _decrypterMethod.Parameters, _locals, + _decrypterMethod.Body.InitLocals, false); + _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); + + var index = 0; + while (index < _instructions.Count) + { + try + { + if (_decrypterVersion != DecrypterVersion.V69) + goto Emulate; + if (!_instructions[index].IsLdloc()) + goto Emulate; + if (!_instructions[index + 1].OpCode.Equals(OpCodes.Ldc_I4_0) && + (!_instructions[index + 1].IsLdcI4() || _instructions[index + 1].GetLdcI4Value() != 0)) + goto Emulate; + if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && + !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) + goto Emulate; + if (!_instructions[index + 3].IsLdloc()) + goto Emulate; + if (!_instructions[index + 4].OpCode.Equals(OpCodes.Ldc_I4_1) && + (!_instructions[index + 4].IsLdcI4() || _instructions[index + 4].GetLdcI4Value() != 1)) + goto Emulate; + if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) + goto Emulate; + if (!_instructions[index + 6].IsStloc()) + goto Emulate; + if (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false) + .Index) is Int32Value local && local.Value != Int32Value.Zero.Value) + index += 7; + } + catch { } + + Emulate: + _instrEmulator.Emulate(_instructions[index]); + index++; + } + + if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) + throw new ApplicationException("Couldn't calculate magic value"); + return (uint)tos.Value; + } + + private static uint ReadUInt32(byte[] ary, int index) + { + var sizeLeft = ary.Length - index; + if (sizeLeft >= 4) + return BitConverter.ToUInt32(ary, index); + return sizeLeft switch + { + 1 => ary[index], + 2 => (uint)(ary[index] | (ary[index + 1] << 8)), + 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), + _ => throw new ApplicationException("Can't read data") + }; + } + + private static void WriteUInt32(IList ary, int index, uint value) + { + var num = ary.Count - index; + if (num >= 1) + ary[index] = (byte)value; + if (num >= 2) + ary[index + 1] = (byte)(value >> 8); + if (num >= 3) + ary[index + 2] = (byte)(value >> 16); + if (num >= 4) + ary[index + 3] = (byte)(value >> 24); + } + + private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) + { + startIndex = 0; + endIndex = 0; + tmpLocal = null; + if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) + return false; + if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) + return false; + startIndex = emuStartIndex; + endIndex = emuEndIndex; + tmpLocal = _emuLocal; + return true; + } + + private bool FindEnd(IList instrs, int startIndex, out int endIndex) + { + for (var i = startIndex; i < instrs.Count; i++) + { + var instr = instrs[i]; + if (instr.OpCode.FlowControl != FlowControl.Next) + break; + if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) + continue; + endIndex = i - 1; + return true; + } + + endIndex = 0; + return false; + } + + private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + Local local; + if (instrs[i].OpCode.Code.Equals(Code.Conv_U) && instrs[i + 1].OpCode.Code.Equals(Code.Ldelem_U1) && + instrs[i + 2].OpCode.Code.Equals(Code.Or) && CheckLocal(instrs[i + 3], false) != null && + (local = CheckLocal(instrs[i + 4], true)) != null && CheckLocal(instrs[i + 5], true) != null && + instrs[i + 6].OpCode.Code.Equals(Code.Add) && CheckLocal(instrs[i + 7], false) == local) + { + var instr = instrs[i + 8]; + var newStartIndex = i + 8; + if (instr.IsBr()) + { + instr = instr.Operand as Instruction; + newStartIndex = instrs.IndexOf(instr); + } + + if (newStartIndex >= 0 && instr != null && CheckLocal(instr, true) == local) + { + startIndex = newStartIndex; + tmpLocal = local; + return true; + } + } + + i++; + } + + startIndex = 0; + tmpLocal = null; + return false; + } + + private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, + out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && + instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && + instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && + instrs[i + 3].OpCode.Code.Equals(Code.Add)) + { + var newEndIndex = i + 3; + var newStartIndex = -1; + for (var x = newEndIndex; x > 0; x--) + if (instrs[x].OpCode.FlowControl != FlowControl.Next) + { + if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || + instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) + { + _decrypterVersion = DecrypterVersion.V69; + continue; + } + + break; + } + + var ckStartIndex = -1; + for (var y = newEndIndex; y >= 0; y--) + if (instrs[y].IsBr()) + { + if (instrs[y].Operand is not Instruction instr) + continue; + if (instrs.IndexOf(instr) < y) + { + if (instrs[y - 1].Operand is not Instruction) + continue; + instr = instrs[y - 1].Operand as Instruction; + if (instrs.IndexOf(instr) < y) + continue; + } + newStartIndex = instrs.IndexOf(instr); + ckStartIndex = newStartIndex; + break; + } + + + if (newStartIndex >= 0) + { + var checkLocs = new List(); + for (var y = newEndIndex; y >= newStartIndex; y--) + if (CheckLocal(instrs[y], true) is { } loc) + if (!checkLocs.Contains(loc)) + checkLocs.Add(loc); + + endIndex = newEndIndex; + startIndex = Math.Max(ckStartIndex, newStartIndex); + tmpLocal = CheckLocal(instrs[startIndex], true); + return true; + } + } + + i++; + } + + endIndex = 0; + startIndex = 0; + tmpLocal = null; + return false; + } + + private Local CheckLocal(Instruction instr, bool isLdloc) + { + switch (isLdloc) + { + case true when !instr.IsLdloc(): + case false when !instr.IsStloc(): + return null; + default: + return instr.GetLocal(_locals); + } + } + + + private readonly InstructionEmulator _instrEmulator = new(); + private readonly List _locals; + private readonly MethodDef _decrypterMethod; + private Local _emuLocal; + private List _instructions; + private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; + } + + private class DecrypterV4 : IDecrypter { - byte[] Decrypt(EmbeddedResource resource); + public DecrypterV4(MethodDef method) + { + if (!FindDecrypterMethod(method)) + throw new ApplicationException("Could not find decrypter method"); + + if (!FindEmulateMethod(_decrypterMethod)) + throw new ApplicationException("Could not find emulate method"); + + _key = GetDecryptionKey(_decrypterMethod); + _iv = GetDecryptionIV(_decrypterMethod); + _locals = new List(_emuMethod.Body.Variables); + if (!Initialize()) + throw new ApplicationException("Could not initialize decrypter V4"); + } + + public static bool CouldBeResourceDecrypter(MethodDef method, StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new List + { + "System.Int32", + "System.Byte[]" + }; + requiredTypes.AddRange(additionalTypes); + if (!stringCounts.All(requiredTypes)) + return false; + + var instrs = method.Body.Instructions; + + return instrs.Where(instr => instr.OpCode == OpCodes.Newobj).Any(instr => instr.Operand is IMethod + { + FullName: "System.Void System.Diagnostics.StackFrame::.ctor(System.Int32)" + }); + } + + public byte[] Decrypt(EmbeddedResource resource) + { + var encrypted = resource.CreateReader().ToArray(); + var decrypted = new byte[encrypted.Length]; + + uint sum = 0; + for (var i = 0; i < encrypted.Length; i += 4) + { + sum = CalculateMagic(sum + ReadUInt32(_key, i % _key.Length)); + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + + return decrypted; + } + + private bool FindDecrypterMethod(MethodDef method) + { + var instrs = method.Body.Instructions; + for (var i = 0; i < instrs.Count; i++) + { + if (instrs[i].OpCode != OpCodes.Ldsfld) + continue; + if (instrs[i + 1].OpCode != OpCodes.Ldstr) + continue; + if (instrs[i + 2].OpCode != OpCodes.Callvirt) + continue; + if (instrs[i + 3].OpCode != OpCodes.Ldarg_0) + continue; + var call = instrs[i + 4]; + if (call.OpCode != OpCodes.Call) + continue; + + _decrypterMethod = call.Operand as MethodDef; + return true; + } + + return false; + } + + private bool FindEmulateMethod(MethodDef method) + { + var instrs = method.Body.Instructions; + for (var i = 0; i < instrs.Count; i++) + { + if (instrs[i].OpCode != OpCodes.Newobj) + continue; + if (!instrs[i + 1].IsLdloc()) + continue; + if (!instrs[i + 2].IsLdloc()) + continue; + if (!instrs[i + 3].IsLdloc()) + continue; + var call = instrs[i + 4]; + if (call.OpCode != OpCodes.Call) + continue; + + _emuMethod = call.Operand as MethodDef; + return true; + } + + return false; + } + + private bool Initialize() + { + var origInstrs = _emuMethod.Body.Instructions; + + if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal)) + if (!FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) + return false; + + for (var i = 0; i < _iv.Length; i++) + _key[i] ^= _iv[i]; + + var count = emuEndIndex - emuStartIndex + 1; + _instructions = new List(count); + for (var i = 0; i < count; i++) + _instructions.Add(origInstrs[emuStartIndex + i].Clone()); + + return true; + } + + private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) + { + startIndex = 0; + endIndex = 0; + tmpLocal = null; + + if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) + return false; + if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) + return false; + startIndex = emuStartIndex; + endIndex = emuEndIndex; + tmpLocal = _emuLocal; + return true; + } + + private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, + out Local tmpLocal) + { + var i = 0; + while (i + 8 < instrs.Count) + { + if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && + instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && + instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && + instrs[i + 3].OpCode.Code.Equals(Code.Add)) + { + var newEndIndex = i + 3; + var newStartIndex = -1; + for (var x = newEndIndex; x > 0; x--) + if (instrs[x].OpCode.FlowControl != FlowControl.Next) + { + if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || + instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) + { + _decrypterVersion = DecrypterVersion.V69; + continue; + } + + break; + } + + var ckStartIndex = -1; + for (var y = newEndIndex; y >= 0; y--) + if (instrs[y].IsBr()) + { + if (instrs[y].Operand is not Instruction instr) + continue; + if (instrs.IndexOf(instr) < y) + { + if (instrs[y - 1].Operand is not Instruction) + continue; + instr = instrs[y - 1].Operand as Instruction; + if (instrs.IndexOf(instr) < y) + continue; + } + newStartIndex = instrs.IndexOf(instr); + ckStartIndex = newStartIndex; + break; + } + + + if (newStartIndex >= 0) + { + var checkLocs = new List(); + for (var y = newEndIndex; y >= newStartIndex; y--) + if (CheckLocal(instrs[y], true) is { } loc) + if (!checkLocs.Contains(loc)) + checkLocs.Add(loc); + + endIndex = newEndIndex; + startIndex = Math.Max(ckStartIndex, newStartIndex); + tmpLocal = CheckLocal(instrs[startIndex], true); + return true; + } + } + + i++; + } + + endIndex = 0; + startIndex = 0; + tmpLocal = null; + return false; + } + + private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) + { + for (var i = 0; i + 8 < instrs.Count; i++) + { + if (instrs[i].OpCode.Code != Code.Conv_U) + continue; + if (instrs[i + 1].OpCode.Code != Code.Ldelem_U1) + continue; + if (instrs[i + 2].OpCode.Code != Code.Or) + continue; + if (CheckLocal(instrs[i + 3], false) == null) + continue; + Local local; + if ((local = CheckLocal(instrs[i + 4], true)) == null) + continue; + if (CheckLocal(instrs[i + 5], true) == null) + continue; + if (instrs[i + 6].OpCode.Code != Code.Add) + continue; + if (CheckLocal(instrs[i + 7], false) != local) + continue; + var instr = instrs[i + 8]; + var newStartIndex = i + 8; + if (instr.IsBr()) + { + instr = instr.Operand as Instruction; + newStartIndex = instrs.IndexOf(instr); + } + + if (newStartIndex < 0 || instr == null) + continue; + if (CheckLocal(instr, true) != local) + continue; + + startIndex = newStartIndex; + tmpLocal = local; + return true; + } + + startIndex = 0; + tmpLocal = null; + return false; + } + + private bool FindEnd(IList instrs, int startIndex, out int endIndex) + { + for (var i = startIndex; i < instrs.Count; i++) + { + var instr = instrs[i]; + if (instr.OpCode.FlowControl != FlowControl.Next) + break; + if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) + continue; + + endIndex = i - 1; + return true; + } + + endIndex = 0; + return false; + } + + private Local CheckLocal(Instruction instr, bool isLdloc) + { + switch (isLdloc) + { + case true when !instr.IsLdloc(): + case false when !instr.IsStloc(): + return null; + default: + return instr.GetLocal(_locals); + } + } + + private uint CalculateMagic(uint input) + { + _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, + false); + _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); + + var index = 0; + while (index < _instructions.Count) + { + try + { + if (_decrypterVersion != DecrypterVersion.V69) + goto Emulate; + if (!_instructions[index].IsLdloc()) + goto Emulate; + if (!_instructions[index + 1].OpCode.Equals(OpCodes.Ldc_I4_0) && + (!_instructions[index + 1].IsLdcI4() || _instructions[index + 1].GetLdcI4Value() != 0)) + goto Emulate; + if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && + !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) + goto Emulate; + if (!_instructions[index + 3].IsLdloc()) + goto Emulate; + if (!_instructions[index + 4].OpCode.Equals(OpCodes.Ldc_I4_1) && + (!_instructions[index + 4].IsLdcI4() || _instructions[index + 4].GetLdcI4Value() != 1)) + goto Emulate; + if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) + goto Emulate; + if (!_instructions[index + 6].IsStloc()) + goto Emulate; + if (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false) + .Index) is Int32Value local && local.Value != Int32Value.Zero.Value) + index += 7; + } + catch { } + + Emulate: + _instrEmulator.Emulate(_instructions[index]); + index++; + } + + if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) + throw new ApplicationException("Couldn't calculate magic value"); + return (uint)tos.Value; + } + + private static uint ReadUInt32(byte[] ary, int index) + { + var sizeLeft = ary.Length - index; + if (sizeLeft >= 4) + return BitConverter.ToUInt32(ary, index); + return sizeLeft switch + { + 1 => ary[index], + 2 => (uint)(ary[index] | (ary[index + 1] << 8)), + 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), + _ => throw new ApplicationException("Can't read data") + }; + } + + private static void WriteUInt32(IList ary, int index, uint value) + { + var sizeLeft = ary.Count - index; + if (sizeLeft >= 1) + ary[index] = (byte)value; + if (sizeLeft >= 2) + ary[index + 1] = (byte)(value >> 8); + if (sizeLeft >= 3) + ary[index + 2] = (byte)(value >> 16); + if (sizeLeft >= 4) + ary[index + 3] = (byte)(value >> 24); + } + + + private readonly byte[] _key, _iv; + private MethodDef _decrypterMethod; + private MethodDef _emuMethod; + private List _instructions; + private readonly List _locals; + private readonly InstructionEmulator _instrEmulator = new(); + private Local _emuLocal; + private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; + } + + + private class DecrypterV5 : IDecrypter + { + public DecrypterV5(MethodDef method) + { + _key = GetDecryptionKey(method); + _iv = GetDecryptionIV(method); + _decrypterMethod = method; + //_locals = new List(_decrypterMethod.Body.Variables); + //if (!Initialize()) + // throw new ApplicationException("Could not initialize decrypter V5"); + } + + public static bool CouldBeResourceDecrypter(StringCounts stringCounts, + IEnumerable additionalTypes) + { + var requiredTypes = new List + { + "System.Int32", + "System.Byte[]" + }; + requiredTypes.AddRange(additionalTypes); + return stringCounts.All(requiredTypes); + } + + public unsafe byte[] Decrypt(EmbeddedResource resource) + { + byte[] encrypted = resource.CreateReader().ToArray(); + byte[] decrypted = new byte[encrypted.Length]; + uint sum = 0U; + + byte[] new_key = null; + if (_key != null && _iv != null) + { + new_key = _key; + for (int i = 0; i < _iv.Length; i++) + { + new_key[i] ^= _iv[i]; + } + } + + for (var i = 0; i < encrypted.Length; i += 4) + { + if (new_key != null) + sum += ReadUInt32(new_key, i % new_key.Length); + + sum += Enc_key; + WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); + } + + + + + + return decrypted; + } + + public bool Initialize() + { + var origInstrs = _decrypterMethod.Body.Instructions; + + // IL_0DB6: ldloc.s V_60 + // IL_0DB8: stloc.s V_60 + // IL_0DBA: ldloc.s V_60 + // IL_0DBC: ldc.i4 702695222 + // IL_0DC1: add + // IL_0DC2: stloc.s V_60 + for (int i = 0; i < origInstrs.Count - 11; i++) + { + if (origInstrs[i].IsLdloc() && origInstrs[i + 1].IsStloc() && + origInstrs[i + 2].IsLdloc() && origInstrs[i + 3].IsLdcI4() && + origInstrs[i + 4].OpCode == OpCodes.Add && origInstrs[i + 5].IsStloc()) + { + Local local1 = origInstrs[i].GetLocal(_decrypterMethod.Body.Variables); + if (local1 == null) continue; + Local local2 = origInstrs[i + 1].GetLocal(_decrypterMethod.Body.Variables); + if (local2 == null || local1 != local2) continue; + Local local3 = origInstrs[i + 2].GetLocal(_decrypterMethod.Body.Variables); + if (local3 == null || local1 != local3) continue; + Local local4 = origInstrs[i + 5].GetLocal(_decrypterMethod.Body.Variables); + if (local4 == null || local1 != local4) continue; + + Enc_key = (uint)origInstrs[i + 3].GetLdcI4Value(); + //MessageBox(new IntPtr(0), Enc_key.ToString(), "MessageBox", 0); + + return true; + + + } + + if (origInstrs[i].IsLdcI4() && + origInstrs[i + 1].OpCode == OpCodes.Add && origInstrs[i + 2].IsStloc() && + origInstrs[i + 3].IsLdloc() && origInstrs[i + 4].IsLdloc() && origInstrs[i + 5].OpCode == OpCodes.Ldc_I4_1 && + origInstrs[i + 6].OpCode == OpCodes.Sub && (origInstrs[i + 7].OpCode == OpCodes.Bne_Un || origInstrs[i + 7].OpCode == OpCodes.Bne_Un_S) && + origInstrs[i + 8].IsLdloc() && origInstrs[i + 9].OpCode == OpCodes.Ldc_I4_0 && (origInstrs[i + 10].OpCode == OpCodes.Ble || origInstrs[i + 10].OpCode == OpCodes.Ble_S)) + { + Enc_key = (uint)origInstrs[i].GetLdcI4Value(); + //MessageBox(new IntPtr(0), Enc_key.ToString(), "MessageBox", 0); + + return true; + } + + + } + return false; + } + + // https://www.cnblogs.com/Fred1987/p/18603592 + //copy from,https://gist.github.com/6rube/34b561827f0805f73742541b8b8bb770 + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); + + private static uint ReadUInt32(byte[] ary, int index) + { + var sizeLeft = ary.Length - index; + if (sizeLeft >= 4) + return BitConverter.ToUInt32(ary, index); + return sizeLeft switch + { + 1 => ary[index], + 2 => (uint)(ary[index] | (ary[index + 1] << 8)), + 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), + _ => throw new ApplicationException("Can't read data") + }; + } + + private static void WriteUInt32(IList ary, int index, uint value) + { + var num = ary.Count - index; + if (num >= 1) + ary[index] = (byte)value; + if (num >= 2) + ary[index + 1] = (byte)(value >> 8); + if (num >= 3) + ary[index + 2] = (byte)(value >> 16); + if (num >= 4) + ary[index + 3] = (byte)(value >> 24); + } + + private uint Enc_key; + private readonly byte[] _key, _iv; + private readonly MethodDef _decrypterMethod; + //private List _instructions; + //private bool _isNewDecrypter; + //private List _locals; + //private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; } - + + #endregion } } \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV1.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV1.cs deleted file mode 100644 index a327946..0000000 --- a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV1.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using de4dot.blocks; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - -namespace NETReactorSlayer.Core.Helper; - -internal partial class EncryptedResource -{ - private class DecrypterV1 : IDecrypter - { - public DecrypterV1(MethodDef method) - { - _key = GetDecryptionKey(method); - _iv = GetDecryptionIV(method); - } - - public static bool CouldBeResourceDecrypter(MethodDef method, StringCounts stringCounts, - IEnumerable additionalTypes) - { - var requiredTypes = new[] - { - new List - { - "System.Byte[]", - "System.Security.Cryptography.CryptoStream", - "System.Security.Cryptography.ICryptoTransform", - "System.String", - "System.Boolean" - }, - new List - { - "System.Security.Cryptography.ICryptoTransform", - "System.IO.Stream", - "System.Int32", - "System.Byte[]", - "System.Boolean" - }, - new List - { - "System.Security.Cryptography.ICryptoTransform", - "System.Int32", - "System.Byte[]", - "System.Boolean" - } - }; - requiredTypes[0].AddRange(additionalTypes); - - if (stringCounts.All(requiredTypes[0]) || - stringCounts.All(requiredTypes[1]) || - (stringCounts.All(requiredTypes[2]) && method.Body.Instructions.Any(x => - x.OpCode.Equals(OpCodes.Newobj) && x.Operand != null && x.Operand.ToString()! - .Contains("System.Security.Cryptography.CryptoStream::.ctor")))) - return DotNetUtils.GetMethod(method.DeclaringType, - "System.Security.Cryptography.SymmetricAlgorithm", - "()") == null || (!stringCounts.Exists("System.UInt64") && - (!stringCounts.Exists("System.UInt32") || - stringCounts.Exists("System.Reflection.Assembly"))); - - return false; - } - - public byte[] Decrypt(EmbeddedResource resource) => - DeobUtils.AesDecrypt(resource.CreateReader().ToArray(), _key, _iv); - - - private readonly byte[] _key, _iv; - } -} \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV2.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV2.cs deleted file mode 100644 index 023b573..0000000 --- a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV2.cs +++ /dev/null @@ -1,380 +0,0 @@ -using System; -using System.Collections.Generic; -using de4dot.blocks; -using de4dot.blocks.cflow; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - -namespace NETReactorSlayer.Core.Helper; - -internal partial class EncryptedResource -{ - private class DecrypterV2 : IDecrypter - { - public DecrypterV2(MethodDef method) - { - _key = GetDecryptionKey(method); - _iv = GetDecryptionIV(method); - _decrypterMethod = method; - _locals = new List(_decrypterMethod.Body.Variables); - if (!Initialize()) - throw new ApplicationException("Could not initialize decrypter"); - } - - public static bool CouldBeResourceDecrypter(StringCounts stringCounts, - IEnumerable additionalTypes) - { - var requiredTypes = new List - { - "System.Int32", - "System.Byte[]" - }; - requiredTypes.AddRange(additionalTypes); - return stringCounts.All(requiredTypes); - } - - public byte[] Decrypt(EmbeddedResource resource) - { - var encrypted = resource.CreateReader().ToArray(); - var decrypted = new byte[encrypted.Length]; - var sum = 0U; - - if (_isNewDecrypter) - for (var i = 0; i < encrypted.Length; i += 4) - { - var value = ReadUInt32(_key, i % _key.Length); - sum += value + CalculateMagic(sum + value); - WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); - } - else - for (var j = 0; j < encrypted.Length; j += 4) - { - sum = CalculateMagic(sum + ReadUInt32(_key, j % _key.Length)); - WriteUInt32(decrypted, j, sum ^ ReadUInt32(encrypted, j)); - } - - return decrypted; - } - - private bool Initialize() - { - var origInstrs = _decrypterMethod.Body.Instructions; - if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal) && - !FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) - { - if (!FindStartEnd2(ref origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal, out _emuArg, - ref _emuMethod, ref _locals)) - return false; - _isNewDecrypter = true; - } - - if (!_isNewDecrypter) - for (var i = 0; i < _iv.Length; i++) - { - var array = _key; - array[i] ^= _iv[i]; - } - - var count = emuEndIndex - emuStartIndex + 1; - _instructions = new List(count); - for (var j = 0; j < count; j++) - _instructions.Add(origInstrs[emuStartIndex + j].Clone()); - return true; - } - - private Local CheckLocal(Instruction instr, bool isLdloc) - { - switch (isLdloc) - { - case true when !instr.IsLdloc(): - case false when !instr.IsStloc(): - return null; - default: - return instr.GetLocal(_locals); - } - } - - private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) - { - startIndex = 0; - endIndex = 0; - tmpLocal = null; - if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) - return false; - if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) - return false; - startIndex = emuStartIndex; - endIndex = emuEndIndex; - tmpLocal = _emuLocal; - return true; - } - - private bool FindEnd(IList instrs, int startIndex, out int endIndex) - { - for (var i = startIndex; i < instrs.Count; i++) - { - var instr = instrs[i]; - if (instr.OpCode.FlowControl != FlowControl.Next) - break; - if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) - continue; - endIndex = i - 1; - return true; - } - - endIndex = 0; - return false; - } - - private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - Local local; - if (instrs[i].OpCode.Code.Equals(Code.Conv_U) && instrs[i + 1].OpCode.Code.Equals(Code.Ldelem_U1) && - instrs[i + 2].OpCode.Code.Equals(Code.Or) && CheckLocal(instrs[i + 3], false) != null && - (local = CheckLocal(instrs[i + 4], true)) != null && CheckLocal(instrs[i + 5], true) != null && - instrs[i + 6].OpCode.Code.Equals(Code.Add) && CheckLocal(instrs[i + 7], false) == local) - { - var instr = instrs[i + 8]; - var newStartIndex = i + 8; - if (instr.IsBr()) - { - instr = instr.Operand as Instruction; - newStartIndex = instrs.IndexOf(instr); - } - - if (newStartIndex >= 0 && instr != null && CheckLocal(instr, true) == local) - { - startIndex = newStartIndex; - tmpLocal = local; - return true; - } - } - - i++; - } - - startIndex = 0; - tmpLocal = null; - return false; - } - - private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, - out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && - instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && - instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && - instrs[i + 3].OpCode.Code.Equals(Code.Add)) - { - var newEndIndex = i + 3; - var newStartIndex = -1; - for (var x = newEndIndex; x > 0; x--) - if (instrs[x].OpCode.FlowControl != FlowControl.Next) - { - if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || - instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) - { - _decrypterVersion = DecrypterVersion.V69; - continue; - } - - break; - } - - var ckStartIndex = -1; - for (var y = newEndIndex; y >= 0; y--) - if (instrs[y].IsBr()) - { - if (instrs[y].Operand is not Instruction instr) - continue; - if (instrs.IndexOf(instr) < y) - { - if (instrs[y - 1].Operand is not Instruction) - continue; - instr = instrs[y - 1].Operand as Instruction; - if (instrs.IndexOf(instr) < y) - continue; - } - newStartIndex = instrs.IndexOf(instr); - ckStartIndex = newStartIndex; - break; - } - - - if (newStartIndex >= 0) - { - var checkLocs = new List(); - for (var y = newEndIndex; y >= newStartIndex; y--) - if (CheckLocal(instrs[y], true) is { } loc) - if (!checkLocs.Contains(loc)) - checkLocs.Add(loc); - - endIndex = newEndIndex; - startIndex = Math.Max(ckStartIndex, newStartIndex); - tmpLocal = CheckLocal(instrs[startIndex], true); - return true; - } - } - - i++; - } - - endIndex = 0; - startIndex = 0; - tmpLocal = null; - return false; - } - - private static bool FindStartEnd2(ref IList instrs, out int startIndex, out int endIndex, - out Local tmpLocal, out Parameter tmpArg, ref MethodDef methodDef, ref List locals) - { - foreach (var instr in instrs) - { - MethodDef method; - if (!instr.OpCode.Equals(OpCodes.Call) || (method = instr.Operand as MethodDef) == null || - method.ReturnType.FullName != "System.Byte[]") - continue; - - using var enumerator2 = DotNetUtils.GetMethodCalls(method).GetEnumerator(); - while (enumerator2.MoveNext()) - { - MethodDef calledMethod; - if ((calledMethod = enumerator2.Current as MethodDef) == null || - calledMethod.Parameters.Count != 2) - continue; - instrs = calledMethod.Body.Instructions; - methodDef = calledMethod; - locals = new List(calledMethod.Body.Variables); - startIndex = 0; - endIndex = instrs.Count - 1; - tmpLocal = null; - tmpArg = calledMethod.Parameters[1]; - return true; - } - } - - endIndex = 0; - startIndex = 0; - tmpLocal = null; - tmpArg = null; - return false; - } - - private static uint ReadUInt32(byte[] ary, int index) - { - var sizeLeft = ary.Length - index; - if (sizeLeft >= 4) - return BitConverter.ToUInt32(ary, index); - return sizeLeft switch - { - 1 => ary[index], - 2 => (uint)(ary[index] | (ary[index + 1] << 8)), - 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), - _ => throw new ApplicationException("Can't read data") - }; - } - - private static void WriteUInt32(IList ary, int index, uint value) - { - var num = ary.Count - index; - if (num >= 1) - ary[index] = (byte)value; - if (num >= 2) - ary[index + 1] = (byte)(value >> 8); - if (num >= 3) - ary[index + 2] = (byte)(value >> 16); - if (num >= 4) - ary[index + 3] = (byte)(value >> 24); - } - - private uint CalculateMagic(uint input) - { - if (_emuArg == null) - { - _instrEmulator.Initialize(_decrypterMethod, _decrypterMethod.Parameters, _locals, - _decrypterMethod.Body.InitLocals, false); - _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); - } - else - { - _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, - false); - _instrEmulator.SetArg(_emuArg, new Int32Value((int)input)); - } - - var index = 0; - while (index < _instructions.Count) - { - try - { - if (_decrypterVersion != DecrypterVersion.V69) - goto Emulate; - if (!_instructions[index].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) - goto Emulate; - if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && - !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) - goto Emulate; - if (!_instructions[index + 3].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) - goto Emulate; - if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) - goto Emulate; - if (!_instructions[index + 6].IsStloc()) - goto Emulate; - - switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) - { - case Int32Value int32: - { - if (int32.Value != Int32Value.Zero.Value) - index += 7; - break; - } - case Int64Value int64: - { - if (int64.Value != Int64Value.Zero.Value) - index += 7; - break; - } - case Real8Value real8Value: - { - if (!real8Value.Value.Equals(new Real8Value(0).Value)) - index += 7; - break; - } - } - } - catch { } - - Emulate: - _instrEmulator.Emulate(_instructions[index]); - index++; - } - - if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) - throw new ApplicationException("Couldn't calculate magic value"); - return (uint)tos.Value; - } - - - private readonly InstructionEmulator _instrEmulator = new(); - private readonly byte[] _key, _iv; - private readonly MethodDef _decrypterMethod; - private Parameter _emuArg; - private Local _emuLocal; - private MethodDef _emuMethod; - private List _instructions; - private bool _isNewDecrypter; - private List _locals; - private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; - } -} \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV3.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV3.cs deleted file mode 100644 index 1e25e05..0000000 --- a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV3.cs +++ /dev/null @@ -1,308 +0,0 @@ -using System; -using System.Collections.Generic; -using de4dot.blocks.cflow; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - -namespace NETReactorSlayer.Core.Helper; - -internal partial class EncryptedResource -{ - private class DecrypterV3 : IDecrypter - { - public DecrypterV3(MethodDef method) - { - _decrypterMethod = method; - _locals = new List(_decrypterMethod.Body.Variables); - if (!Initialize()) - throw new ApplicationException("Could not initialize decrypter"); - } - - public static bool CouldBeResourceDecrypter(StringCounts stringCounts, - IEnumerable additionalTypes) - { - var requiredTypes = new List - { - "System.Reflection.Emit.DynamicMethod", - "System.Reflection.Emit.ILGenerator" - }; - requiredTypes.AddRange(additionalTypes); - return stringCounts.All(requiredTypes); - } - - public byte[] Decrypt(EmbeddedResource resource) - { - var encrypted = resource.CreateReader().ToArray(); - var decrypted = new byte[encrypted.Length]; - var sum = 0U; - - for (var i = 0; i < encrypted.Length; i += 4) - { - sum = CalculateMagic(sum); - WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); - } - - return decrypted; - } - - private bool Initialize() - { - var origInstrs = _decrypterMethod.Body.Instructions; - if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal) && - !FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) - return false; - var count = emuEndIndex - emuStartIndex + 1; - _instructions = new List(count); - for (var i = 0; i < count; i++) - _instructions.Add(origInstrs[emuStartIndex + i].Clone()); - return true; - } - - private uint CalculateMagic(uint input) - { - _instrEmulator.Initialize(_decrypterMethod, _decrypterMethod.Parameters, _locals, - _decrypterMethod.Body.InitLocals, false); - _instrEmulator.SetLocal(_emuLocal, new Int32Value((int)input)); - - var index = 0; - while (index < _instructions.Count) - { - try - { - if (_decrypterVersion != DecrypterVersion.V69) - goto Emulate; - if (!_instructions[index].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) - goto Emulate; - if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && - !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) - goto Emulate; - if (!_instructions[index + 3].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) - goto Emulate; - if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) - goto Emulate; - if (!_instructions[index + 6].IsStloc()) - goto Emulate; - - switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) - { - case Int32Value int32: - { - if (int32.Value != Int32Value.Zero.Value) - index += 7; - break; - } - case Int64Value int64: - { - if (int64.Value != Int64Value.Zero.Value) - index += 7; - break; - } - case Real8Value real8Value: - { - if (!real8Value.Value.Equals(new Real8Value(0).Value)) - index += 7; - break; - } - } - } - catch { } - - Emulate: - _instrEmulator.Emulate(_instructions[index]); - index++; - } - - if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) - throw new ApplicationException("Couldn't calculate magic value"); - return (uint)tos.Value; - } - - private static uint ReadUInt32(byte[] ary, int index) - { - var sizeLeft = ary.Length - index; - if (sizeLeft >= 4) - return BitConverter.ToUInt32(ary, index); - return sizeLeft switch - { - 1 => ary[index], - 2 => (uint)(ary[index] | (ary[index + 1] << 8)), - 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), - _ => throw new ApplicationException("Can't read data") - }; - } - - private static void WriteUInt32(IList ary, int index, uint value) - { - var num = ary.Count - index; - if (num >= 1) - ary[index] = (byte)value; - if (num >= 2) - ary[index + 1] = (byte)(value >> 8); - if (num >= 3) - ary[index + 2] = (byte)(value >> 16); - if (num >= 4) - ary[index + 3] = (byte)(value >> 24); - } - - private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) - { - startIndex = 0; - endIndex = 0; - tmpLocal = null; - if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) - return false; - if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) - return false; - startIndex = emuStartIndex; - endIndex = emuEndIndex; - tmpLocal = _emuLocal; - return true; - } - - private bool FindEnd(IList instrs, int startIndex, out int endIndex) - { - for (var i = startIndex; i < instrs.Count; i++) - { - var instr = instrs[i]; - if (instr.OpCode.FlowControl != FlowControl.Next) - break; - if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) - continue; - endIndex = i - 1; - return true; - } - - endIndex = 0; - return false; - } - - private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - Local local; - if (instrs[i].OpCode.Code.Equals(Code.Conv_U) && instrs[i + 1].OpCode.Code.Equals(Code.Ldelem_U1) && - instrs[i + 2].OpCode.Code.Equals(Code.Or) && CheckLocal(instrs[i + 3], false) != null && - (local = CheckLocal(instrs[i + 4], true)) != null && CheckLocal(instrs[i + 5], true) != null && - instrs[i + 6].OpCode.Code.Equals(Code.Add) && CheckLocal(instrs[i + 7], false) == local) - { - var instr = instrs[i + 8]; - var newStartIndex = i + 8; - if (instr.IsBr()) - { - instr = instr.Operand as Instruction; - newStartIndex = instrs.IndexOf(instr); - } - - if (newStartIndex >= 0 && instr != null && CheckLocal(instr, true) == local) - { - startIndex = newStartIndex; - tmpLocal = local; - return true; - } - } - - i++; - } - - startIndex = 0; - tmpLocal = null; - return false; - } - - private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, - out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && - instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && - instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && - instrs[i + 3].OpCode.Code.Equals(Code.Add)) - { - var newEndIndex = i + 3; - var newStartIndex = -1; - for (var x = newEndIndex; x > 0; x--) - if (instrs[x].OpCode.FlowControl != FlowControl.Next) - { - if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || - instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) - { - _decrypterVersion = DecrypterVersion.V69; - continue; - } - - break; - } - - var ckStartIndex = -1; - for (var y = newEndIndex; y >= 0; y--) - if (instrs[y].IsBr()) - { - if (instrs[y].Operand is not Instruction instr) - continue; - if (instrs.IndexOf(instr) < y) - { - if (instrs[y - 1].Operand is not Instruction) - continue; - instr = instrs[y - 1].Operand as Instruction; - if (instrs.IndexOf(instr) < y) - continue; - } - newStartIndex = instrs.IndexOf(instr); - ckStartIndex = newStartIndex; - break; - } - - - if (newStartIndex >= 0) - { - var checkLocs = new List(); - for (var y = newEndIndex; y >= newStartIndex; y--) - if (CheckLocal(instrs[y], true) is { } loc) - if (!checkLocs.Contains(loc)) - checkLocs.Add(loc); - - endIndex = newEndIndex; - startIndex = Math.Max(ckStartIndex, newStartIndex); - tmpLocal = CheckLocal(instrs[startIndex], true); - return true; - } - } - - i++; - } - - endIndex = 0; - startIndex = 0; - tmpLocal = null; - return false; - } - - private Local CheckLocal(Instruction instr, bool isLdloc) - { - switch (isLdloc) - { - case true when !instr.IsLdloc(): - case false when !instr.IsStloc(): - return null; - default: - return instr.GetLocal(_locals); - } - } - - - private readonly InstructionEmulator _instrEmulator = new(); - private readonly List _locals; - private readonly MethodDef _decrypterMethod; - private Local _emuLocal; - private List _instructions; - private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; - } -} \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs b/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs deleted file mode 100644 index 5394a41..0000000 --- a/NETReactorSlayer.Core/Helper/EncryptedResource/DecrypterV4.cs +++ /dev/null @@ -1,490 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using de4dot.blocks.cflow; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - -namespace NETReactorSlayer.Core.Helper; - -internal partial class EncryptedResource -{ - private class DecrypterV4 : IDecrypter - { - public DecrypterV4(MethodDef method) - { - if (!FindDecrypterMethod(method)) - throw new ApplicationException("Could not find decrypter method"); - - if (!FindEmulateMethod(_decrypterMethod)) - throw new ApplicationException("Could not find emulate method"); - - _key = GetDecryptionKey(_decrypterMethod); - _iv = GetDecryptionIV(_decrypterMethod); - _locals = new List(_emuMethod.Body.Variables); - - if (!Initialize() && !InitializeNetCore()) - throw new ApplicationException("Could not initialize decrypter"); - } - - public static bool CouldBeResourceDecrypter(MethodDef method, StringCounts stringCounts, - IEnumerable additionalTypes) - { - var requiredTypes = new List - { - "System.Int32", - "System.Byte[]" - }; - requiredTypes.AddRange(additionalTypes); - if (!stringCounts.All(requiredTypes)) - return false; - - var instrs = method.Body.Instructions; - - return instrs.Where(instr => instr.OpCode == OpCodes.Newobj).Any(instr => instr.Operand is IMethod - { - FullName: "System.Void System.Diagnostics.StackFrame::.ctor(System.Int32)" - }); - } - - public byte[] Decrypt(EmbeddedResource resource) - { - var encrypted = resource.CreateReader().ToArray(); - var decrypted = new byte[encrypted.Length]; - - uint sum = 0; - for (var i = 0; i < encrypted.Length; i += 4) - { - if (_netCoreDecrypterVersion) - { - var value = ReadUInt32(_key, i % _key.Length); - sum += value + CalculateMagic(sum + value); - WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); - } - else - { - sum = CalculateMagic(sum + ReadUInt32(_key, i % _key.Length)); - WriteUInt32(decrypted, i, sum ^ ReadUInt32(encrypted, i)); - } - - } - - var debugStringValues = Encoding.Unicode.GetString(decrypted); - - return decrypted; - } - - private bool FindDecrypterMethod(MethodDef method) - { - return FindNetFrameworkDecrypterMethod(method) || - FindNetCoreDecrypterMethod(method); - } - - private bool FindNetFrameworkDecrypterMethod(MethodDef method) - { - var instrs = method.Body.Instructions; - for (var i = 0; i < instrs.Count; i++) - { - if (instrs[i].OpCode != OpCodes.Ldsfld) - continue; - if (instrs[i + 1].OpCode != OpCodes.Ldstr) - continue; - if (instrs[i + 2].OpCode != OpCodes.Callvirt) - continue; - if (instrs[i + 3].OpCode != OpCodes.Ldarg_0) - continue; - var call = instrs[i + 4]; - if (call.OpCode != OpCodes.Call) - continue; - - _decrypterMethod = call.Operand as MethodDef; - return true; - } - - return false; - } - - private bool FindNetCoreDecrypterMethod(MethodDef method) - { - var instrs = method.Body.Instructions; - for (var i = 0; i < instrs.Count - 5; i++) - { - //this was not working with anti tamper enabled - //The instruction is modified in a later stage when enabled - //if (instrs[i].OpCode != OpCodes.Ldtoken) - // continue; - - if (instrs[i + 1].OpCode != OpCodes.Call) - continue; - if (instrs[i + 2].OpCode != OpCodes.Call) - continue; - if (instrs[i + 3].OpCode != OpCodes.Callvirt) - continue; - if (instrs[i + 4].OpCode != OpCodes.Ldstr) - continue; - if (instrs[i + 5].OpCode != OpCodes.Callvirt) - continue; - var call = instrs[i + 6]; - if (call.OpCode != OpCodes.Call) - continue; - - _decrypterMethod = call.Operand as MethodDef; - _netCoreDecrypterVersion = true; - return true; - } - - return false; - } - - private bool FindEmulateMethod(MethodDef method) - { - return FindNetFrameworkEmulateMethod(method) || - FindNetCoreEmulateMethod(method); - } - - private bool FindNetFrameworkEmulateMethod(MethodDef method) - { - var instrs = method.Body.Instructions; - for (var i = 0; i < instrs.Count; i++) - { - if (instrs[i].OpCode != OpCodes.Newobj) - continue; - if (!instrs[i + 1].IsLdloc()) - continue; - if (!instrs[i + 2].IsLdloc()) - continue; - if (!instrs[i + 3].IsLdloc()) - continue; - var call = instrs[i + 4]; - if (call.OpCode != OpCodes.Call) - continue; - - _emuMethod = call.Operand as MethodDef; - return true; - } - - return false; - } - - private bool FindNetCoreEmulateMethod(MethodDef method) - { - var instrs = method.Body.Instructions; - for (var i = 0; i < instrs.Count; i++) - { - if (instrs[i].OpCode != OpCodes.Newobj) - continue; - if (!instrs[i + 1].IsLdloc()) - continue; - var call = instrs[i + 2]; - if (call.OpCode != OpCodes.Call) - continue; - - _emuMethod = call.Operand as MethodDef; - return true; - } - - return false; - } - - private bool Initialize() - { - var origInstrs = _emuMethod.Body.Instructions; - - if (!Find(origInstrs, out var emuStartIndex, out var emuEndIndex, out _emuLocal)) - if (!FindStartEnd(origInstrs, out emuStartIndex, out emuEndIndex, out _emuLocal)) - return false; - - for (var i = 0; i < _iv.Length; i++) - _key[i] ^= _iv[i]; - - var count = emuEndIndex - emuStartIndex + 1; - _instructions = new List(count); - for (var i = 0; i < count; i++) - _instructions.Add(origInstrs[emuStartIndex + i].Clone()); - - return true; - } - - private bool InitializeNetCore() - { - var origInstrs = _emuMethod.Body.Instructions; - - if (origInstrs.FirstOrDefault(x => x.OpCode.Equals(OpCodes.Call))?.Operand is not MethodDef magicMethod) - return false; - - _emuMethod = magicMethod; - _emuParameter = magicMethod.Parameters[1]; - _instructions = []; - foreach (var instr in magicMethod.Body.Instructions) - { - _instructions.Add(instr.Clone()); - } - - return true; - } - - private bool Find(IList instrs, out int startIndex, out int endIndex, out Local tmpLocal) - { - startIndex = 0; - endIndex = 0; - tmpLocal = null; - - if (!FindStart(instrs, out var emuStartIndex, out _emuLocal)) - return false; - if (!FindEnd(instrs, emuStartIndex, out var emuEndIndex)) - return false; - startIndex = emuStartIndex; - endIndex = emuEndIndex; - tmpLocal = _emuLocal; - return true; - } - - private bool FindStartEnd(IList instrs, out int startIndex, out int endIndex, - out Local tmpLocal) - { - var i = 0; - while (i + 8 < instrs.Count) - { - if (instrs[i].OpCode.Code.Equals(Code.Conv_R_Un) && - instrs[i + 1].OpCode.Code.Equals(Code.Conv_R8) && - instrs[i + 2].OpCode.Code.Equals(Code.Conv_U4) && - instrs[i + 3].OpCode.Code.Equals(Code.Add)) - { - var newEndIndex = i + 3; - var newStartIndex = -1; - for (var x = newEndIndex; x > 0; x--) - if (instrs[x].OpCode.FlowControl != FlowControl.Next) - { - if (instrs[x].OpCode.Equals(OpCodes.Bne_Un) || - instrs[x].OpCode.Equals(OpCodes.Bne_Un_S)) - { - _decrypterVersion = DecrypterVersion.V69; - continue; - } - - break; - } - - var ckStartIndex = -1; - for (var y = newEndIndex; y >= 0; y--) - if (instrs[y].IsBr()) - { - if (instrs[y].Operand is not Instruction instr) - continue; - if (instrs.IndexOf(instr) < y) - { - if (instrs[y - 1].Operand is not Instruction) - continue; - instr = instrs[y - 1].Operand as Instruction; - if (instrs.IndexOf(instr) < y) - continue; - } - newStartIndex = instrs.IndexOf(instr); - ckStartIndex = newStartIndex; - break; - } - - - if (newStartIndex >= 0) - { - var checkLocs = new List(); - for (var y = newEndIndex; y >= newStartIndex; y--) - if (CheckLocal(instrs[y], true) is { } loc) - if (!checkLocs.Contains(loc)) - checkLocs.Add(loc); - - endIndex = newEndIndex; - startIndex = Math.Max(ckStartIndex, newStartIndex); - tmpLocal = CheckLocal(instrs[startIndex], true); - return true; - } - } - - i++; - } - - endIndex = 0; - startIndex = 0; - tmpLocal = null; - return false; - } - - private bool FindStart(IList instrs, out int startIndex, out Local tmpLocal) - { - for (var i = 0; i + 8 < instrs.Count; i++) - { - if (instrs[i].OpCode.Code != Code.Conv_U) - continue; - if (instrs[i + 1].OpCode.Code != Code.Ldelem_U1) - continue; - if (instrs[i + 2].OpCode.Code != Code.Or) - continue; - if (CheckLocal(instrs[i + 3], false) == null) - continue; - Local local; - if ((local = CheckLocal(instrs[i + 4], true)) == null) - continue; - if (CheckLocal(instrs[i + 5], true) == null) - continue; - if (instrs[i + 6].OpCode.Code != Code.Add) - continue; - if (CheckLocal(instrs[i + 7], false) != local) - continue; - var instr = instrs[i + 8]; - var newStartIndex = i + 8; - if (instr.IsBr()) - { - instr = instr.Operand as Instruction; - newStartIndex = instrs.IndexOf(instr); - } - - if (newStartIndex < 0 || instr == null) - continue; - if (CheckLocal(instr, true) != local) - continue; - - startIndex = newStartIndex; - tmpLocal = local; - return true; - } - - startIndex = 0; - tmpLocal = null; - return false; - } - - private bool FindEnd(IList instrs, int startIndex, out int endIndex) - { - for (var i = startIndex; i < instrs.Count; i++) - { - var instr = instrs[i]; - if (instr.OpCode.FlowControl != FlowControl.Next) - break; - if (!instr.IsStloc() || instr.GetLocal(_locals) != _emuLocal) - continue; - - endIndex = i - 1; - return true; - } - - endIndex = 0; - return false; - } - - private Local CheckLocal(Instruction instr, bool isLdloc) - { - switch (isLdloc) - { - case true when !instr.IsLdloc(): - case false when !instr.IsStloc(): - return null; - default: - return instr.GetLocal(_locals); - } - } - - private uint CalculateMagic(uint input) - { - _instrEmulator.Initialize(_emuMethod, _emuMethod.Parameters, _locals, _emuMethod.Body.InitLocals, - false); - if (_emuLocal != null) _instrEmulator.SetLocal(_emuLocal, new Int32Value((int) input)); - if (_emuParameter != null) _instrEmulator.SetArg(_emuParameter, new Int32Value((int) input)); - - var index = 0; - while (index < _instructions.Count) - { - try - { - if (_decrypterVersion != DecrypterVersion.V69) - goto Emulate; - if (!_instructions[index].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 1], out var value) || value != 0) - goto Emulate; - if (!_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un) && - !_instructions[index + 2].OpCode.Equals(OpCodes.Bne_Un_S)) - goto Emulate; - if (!_instructions[index + 3].IsLdloc()) - goto Emulate; - if (!TryGetLdcValue(_instructions[index + 4], out value) || value != 1) - goto Emulate; - if (!_instructions[index + 5].OpCode.Equals(OpCodes.Sub)) - goto Emulate; - if (!_instructions[index + 6].IsStloc()) - goto Emulate; - - switch (_instrEmulator.GetLocal(CheckLocal(_instructions[index + 6], false).Index)) - { - case Int32Value int32: - { - if (int32.Value != Int32Value.Zero.Value) - index += 7; - break; - } - case Int64Value int64: - { - if (int64.Value != Int64Value.Zero.Value) - index += 7; - break; - } - case Real8Value real8Value: - { - if (!real8Value.Value.Equals(new Real8Value(0).Value)) - index += 7; - break; - } - } - } - catch { } - - Emulate: - _instrEmulator.Emulate(_instructions[index]); - index++; - } - - if (_instrEmulator.Pop() is not Int32Value tos || !tos.AllBitsValid()) - throw new ApplicationException("Couldn't calculate magic value"); - return (uint)tos.Value; - } - - private static uint ReadUInt32(byte[] ary, int index) - { - var sizeLeft = ary.Length - index; - if (sizeLeft >= 4) - return BitConverter.ToUInt32(ary, index); - return sizeLeft switch - { - 1 => ary[index], - 2 => (uint)(ary[index] | (ary[index + 1] << 8)), - 3 => (uint)(ary[index] | (ary[index + 1] << 8) | (ary[index + 2] << 16)), - _ => throw new ApplicationException("Can't read data") - }; - } - - private static void WriteUInt32(IList ary, int index, uint value) - { - var sizeLeft = ary.Count - index; - if (sizeLeft >= 1) - ary[index] = (byte)value; - if (sizeLeft >= 2) - ary[index + 1] = (byte)(value >> 8); - if (sizeLeft >= 3) - ary[index + 2] = (byte)(value >> 16); - if (sizeLeft >= 4) - ary[index + 3] = (byte)(value >> 24); - } - - - private readonly byte[] _key, _iv; - private MethodDef _decrypterMethod; - private MethodDef _emuMethod; - private List _instructions; - private readonly List _locals; - private readonly InstructionEmulator _instrEmulator = new(); - private Local _emuLocal; - private Parameter _emuParameter; - private bool _netCoreDecrypterVersion = false; - private DecrypterVersion _decrypterVersion = DecrypterVersion.V6X; - } -} \ No newline at end of file diff --git a/NETReactorSlayer.Core/Helper/FieldTypes.cs b/NETReactorSlayer.Core/Helper/FieldTypes.cs index 93d8625..8f02c21 100644 --- a/NETReactorSlayer.Core/Helper/FieldTypes.cs +++ b/NETReactorSlayer.Core/Helper/FieldTypes.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System.Collections.Generic; using System.Linq; -using dnlib.DotNet; namespace NETReactorSlayer.Core.Helper { diff --git a/NETReactorSlayer.Core/Helper/InvalidMethodBody.cs b/NETReactorSlayer.Core/Helper/InvalidMethodBody.cs index b0c3988..c312948 100644 --- a/NETReactorSlayer.Core/Helper/InvalidMethodBody.cs +++ b/NETReactorSlayer.Core/Helper/InvalidMethodBody.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Helper/LocalTypes.cs b/NETReactorSlayer.Core/Helper/LocalTypes.cs index 2cb55d5..70098af 100644 --- a/NETReactorSlayer.Core/Helper/LocalTypes.cs +++ b/NETReactorSlayer.Core/Helper/LocalTypes.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using dnlib.DotNet; using dnlib.DotNet.Emit; +using System.Collections.Generic; namespace NETReactorSlayer.Core.Helper { diff --git a/NETReactorSlayer.Core/Helper/MethodBodyHeader.cs b/NETReactorSlayer.Core/Helper/MethodBodyHeader.cs index 49d31df..e0080c9 100644 --- a/NETReactorSlayer.Core/Helper/MethodBodyHeader.cs +++ b/NETReactorSlayer.Core/Helper/MethodBodyHeader.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Helper/MethodBodyParser.cs b/NETReactorSlayer.Core/Helper/MethodBodyParser.cs index f77641d..269f38b 100644 --- a/NETReactorSlayer.Core/Helper/MethodBodyParser.cs +++ b/NETReactorSlayer.Core/Helper/MethodBodyParser.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.IO; using System; using System.IO; -using dnlib.IO; namespace NETReactorSlayer.Core.Helper { diff --git a/NETReactorSlayer.Core/Helper/MethodCallRemover.cs b/NETReactorSlayer.Core/Helper/MethodCallRemover.cs index 90ce4a6..d06ac3e 100644 --- a/NETReactorSlayer.Core/Helper/MethodCallRemover.cs +++ b/NETReactorSlayer.Core/Helper/MethodCallRemover.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,12 +13,12 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; +using System.Collections.Generic; +using System.Linq; namespace NETReactorSlayer.Core.Helper { @@ -40,9 +40,9 @@ public static long RemoveCalls(IContext context, List methods) { _methodRefInfos = new MethodDefAndDeclaringTypeDict>(); foreach (var type in context.Module.GetTypes()) - foreach (var method in type.Methods.Where(x => x.HasBody && x.Body.HasInstructions)) - foreach (var methodToRem in methods) - Add(method, methodToRem); + foreach (var method in type.Methods.Where(x => x.HasBody && x.Body.HasInstructions)) + foreach (var methodToRem in methods) + Add(method, methodToRem); return context.Module.GetTypes().Sum(type => type.Methods.Where(x => x.HasBody && x.Body.HasInstructions) diff --git a/NETReactorSlayer.Core/Helper/MyPEImage.cs b/NETReactorSlayer.Core/Helper/MyPEImage.cs index 024157e..50bb4e2 100644 --- a/NETReactorSlayer.Core/Helper/MyPEImage.cs +++ b/NETReactorSlayer.Core/Helper/MyPEImage.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,12 +13,12 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Linq; using de4dot.blocks; using dnlib.DotNet.MD; using dnlib.IO; using dnlib.PE; +using System; +using System.Linq; namespace NETReactorSlayer.Core.Helper { diff --git a/NETReactorSlayer.Core/Helper/NativeUnpacker.cs b/NETReactorSlayer.Core/Helper/NativeUnpacker.cs index 2f00339..d10fec3 100644 --- a/NETReactorSlayer.Core/Helper/NativeUnpacker.cs +++ b/NETReactorSlayer.Core/Helper/NativeUnpacker.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,12 +13,12 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.Linq; using dnlib.DotNet; using dnlib.PE; using ICSharpCode.SharpZipLib.Zip.Compression; +using System; +using System.Collections.Generic; +using System.Linq; namespace NETReactorSlayer.Core.Helper { @@ -78,9 +78,9 @@ private byte[] GetKeyData() { _isNet1X = false; foreach (var item in from item in _baseOffsets - let code = _peImage.OffsetReadBytes(item, _decryptMethodPattern.Length) - where DeobUtils.IsCode(_decryptMethodPattern, code) - select item) + let code = _peImage.OffsetReadBytes(item, _decryptMethodPattern.Length) + where DeobUtils.IsCode(_decryptMethodPattern, code) + select item) return GetKeyData(item); var net1XCode = _peImage.OffsetReadBytes(0x207E0, _startMethodNet1XPattern.Length); @@ -121,8 +121,8 @@ private static void Decrypt(IReadOnlyList keyData, IList data, int o var transformTemp = new ushort[256, 256]; for (var i = 0; i < 256; i++) - for (var j = 0; j < 256; j++) - transformTemp[i, j] = 0x400; + for (var j = 0; j < 256; j++) + transformTemp[i, j] = 0x400; var counter = 0x0B; byte newByte = 0; var ki = 0; @@ -166,8 +166,8 @@ private static void Decrypt(IReadOnlyList keyData, IList data, int o } for (var i = 0; i < 256; i++) - for (var j = 0; j < 256; j++) - transform[(byte)transformTemp[i, j], j] = (byte)i; + for (var j = 0; j < 256; j++) + transform[(byte)transformTemp[i, j], j] = (byte)i; for (var i = 0; i < count; i += 1024, offset += 1024) { diff --git a/NETReactorSlayer.Core/Helper/QuickLZ.cs b/NETReactorSlayer.Core/Helper/QuickLZ.cs index 304056e..fbd3cf6 100644 --- a/NETReactorSlayer.Core/Helper/QuickLZ.cs +++ b/NETReactorSlayer.Core/Helper/QuickLZ.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Helper/QuickLZBase.cs b/NETReactorSlayer.Core/Helper/QuickLZBase.cs index 58edbe0..61ad1a8 100644 --- a/NETReactorSlayer.Core/Helper/QuickLZBase.cs +++ b/NETReactorSlayer.Core/Helper/QuickLZBase.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Helper/SimpleDeobfuscator.cs b/NETReactorSlayer.Core/Helper/SimpleDeobfuscator.cs index f8071bd..0b10750 100644 --- a/NETReactorSlayer.Core/Helper/SimpleDeobfuscator.cs +++ b/NETReactorSlayer.Core/Helper/SimpleDeobfuscator.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,14 +13,14 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.Linq; using de4dot.blocks; using de4dot.blocks.cflow; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Stages; +using System; +using System.Collections.Generic; +using System.Linq; namespace NETReactorSlayer.Core.Helper { @@ -31,7 +31,7 @@ public static void Deobfuscate(MethodDef method) const SimpleDeobfuscatorFlags flags = 0; if (method == null || Check(method, SimpleDeobFlags.HasDeobfuscated)) return; - Deobfuscate(method, delegate(Blocks blocks) + Deobfuscate(method, delegate (Blocks blocks) { const bool disableNewCfCode = (flags & SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs) > 0U; var cflowDeobfuscator = @@ -166,6 +166,7 @@ protected override void OnInlinedMethod(MethodDef methodToInline, bool inlinedMe if (!inlinedMethod || methodToInline.IsPublic) return; Cleaner.AddMethodToBeRemoved(methodToInline); + // CodeExplorer was edit: MethodInliner.InlinedMethods++; } } diff --git a/NETReactorSlayer.Core/Helper/StringCounts.cs b/NETReactorSlayer.Core/Helper/StringCounts.cs index 061400c..487571e 100644 --- a/NETReactorSlayer.Core/Helper/StringCounts.cs +++ b/NETReactorSlayer.Core/Helper/StringCounts.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Helper/TheAssemblyResolver.cs b/NETReactorSlayer.Core/Helper/TheAssemblyResolver.cs index a3a8720..409f2b4 100644 --- a/NETReactorSlayer.Core/Helper/TheAssemblyResolver.cs +++ b/NETReactorSlayer.Core/Helper/TheAssemblyResolver.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,12 +13,12 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; -using dnlib.DotNet; namespace NETReactorSlayer.Core.Helper { diff --git a/NETReactorSlayer.Core/Info.cs b/NETReactorSlayer.Core/Info.cs index 8afb8f2..9adaa00 100644 --- a/NETReactorSlayer.Core/Info.cs +++ b/NETReactorSlayer.Core/Info.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Logger.cs b/NETReactorSlayer.Core/Logger.cs index 9b7b05b..51b18dc 100644 --- a/NETReactorSlayer.Core/Logger.cs +++ b/NETReactorSlayer.Core/Logger.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,10 +13,10 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using NETReactorSlayer.Core.Abstractions; using System; using System.Collections.Generic; using System.Reflection; -using NETReactorSlayer.Core.Abstractions; namespace NETReactorSlayer.Core { @@ -105,17 +105,17 @@ public void PrintLogo() Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(@" - ░█▄─░█ ░█▀▀▀ ▀▀█▀▀ - ░█░█░█ ░█▀▀▀ ─░█── - ░█──▀█ ░█▄▄▄ ─░█── + ???��?? ????? ????? + ?????? ????? ��??���� + ??����?? ????? ��??���� - ░█▀▀█ ░█▀▀▀ ─█▀▀█ ░█▀▀█ ▀▀█▀▀ ░█▀▀▀█ ░█▀▀█ - ░█▄▄▀ ░█▀▀▀ ░█▄▄█ ░█─── ─░█── ░█──░█ ░█▄▄▀ - ░█─░█ ░█▄▄▄ ░█─░█ ░█▄▄█ ─░█── ░█▄▄▄█ ░█─░█ + ????? ????? ��???? ????? ????? ?????? ????? + ????? ????? ????? ??������ ��??���� ??����?? ????? + ??��?? ????? ??��?? ????? ��??���� ?????? ??��?? - ░█▀▀▀█ ░█─── ─█▀▀█ ░█──░█ ░█▀▀▀ ░█▀▀█ - ─▀▀▀▄▄ ░█─── ░█▄▄█ ░█▄▄▄█ ░█▀▀▀ ░█▄▄▀ - ░█▄▄▄█ ░█▄▄█ ░█─░█ ──░█── ░█▄▄▄ ░█─░█ + ?????? ??������ ��???? ??����?? ????? ????? + ��????? ??������ ????? ?????? ????? ????? + ?????? ????? ??��?? ����??���� ????? ??��?? "); Console.ForegroundColor = ConsoleColor.White; diff --git a/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj b/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj index b2391df..2d10c75 100644 --- a/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj +++ b/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj @@ -1,4 +1,4 @@ - + @@ -6,11 +6,14 @@ ..\bin\$(Configuration)\ Library + True + AnyCPU + net48;net7.0;net9.0 - + ..\Libs\net35\de4dot.blocks.dll @@ -18,9 +21,8 @@ ..\Libs\netcoreapp3.1\de4dot.blocks.dll - - - + + diff --git a/NETReactorSlayer.Core/Options.cs b/NETReactorSlayer.Core/Options.cs index 4ed105e..c50e5e1 100644 --- a/NETReactorSlayer.Core/Options.cs +++ b/NETReactorSlayer.Core/Options.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,12 +13,12 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; -using System.IO; -using System.Linq; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Stages; using NETReactorSlayer.De4dot.Renamer; +using System.Collections.Generic; +using System.IO; +using System.Linq; using MemberInfo = System.Reflection.MemberInfo; namespace NETReactorSlayer.Core @@ -126,36 +126,36 @@ public Options(IReadOnlyList args) RemoveStage(typeof(SymbolRenamer)); break; case "--rename": - { - var chars = value.ToCharArray(); - RenamerFlags = RenamerFlags.RenameMethodArgs | RenamerFlags.RenameGenericParams; - foreach (var @char in chars) - switch (@char) - { - case 'n': - RenamerFlags |= RenamerFlags.RenameNamespaces; - break; - case 't': - RenamerFlags |= RenamerFlags.RenameTypes; - break; - case 'm': - RenamerFlags |= RenamerFlags.RenameMethods; - break; - case 'f': - RenamerFlags |= RenamerFlags.RenameFields; - break; - case 'p': - RenamerFlags |= RenamerFlags.RenameProperties | RenamerFlags.RestoreProperties | - RenamerFlags.RestorePropertiesFromNames; - break; - case 'e': - RenamerFlags |= RenamerFlags.RenameEvents | RenamerFlags.RestoreEvents | - RenamerFlags.RestoreEventsFromNames; - break; - } + { + var chars = value.ToCharArray(); + RenamerFlags = RenamerFlags.RenameMethodArgs | RenamerFlags.RenameGenericParams; + foreach (var @char in chars) + switch (@char) + { + case 'n': + RenamerFlags |= RenamerFlags.RenameNamespaces; + break; + case 't': + RenamerFlags |= RenamerFlags.RenameTypes; + break; + case 'm': + RenamerFlags |= RenamerFlags.RenameMethods; + break; + case 'f': + RenamerFlags |= RenamerFlags.RenameFields; + break; + case 'p': + RenamerFlags |= RenamerFlags.RenameProperties | RenamerFlags.RestoreProperties | + RenamerFlags.RestorePropertiesFromNames; + break; + case 'e': + RenamerFlags |= RenamerFlags.RenameEvents | RenamerFlags.RestoreEvents | + RenamerFlags.RestoreEventsFromNames; + break; + } - break; - } + break; + } } } @@ -217,7 +217,7 @@ private void RemoveStage(MemberInfo memberInfo) => new MethodDecrypter(), new ControlFlowDeobfuscator(), new AntiManipulationPatcher(), - new MethodInliner(), + new MethodInliner(), // one before new ProxyCallFixer(), new StringDecrypter(), new ResourceResolver(), @@ -225,6 +225,7 @@ private void RemoveStage(MemberInfo memberInfo) => new CosturaDumper(), new TokenDeobfuscator(), new BooleanDecrypter(), + new MethodInliner(), // one after BooleanDecrypter new StrongNamePatcher(), new TypeRestorer(), new Cleaner(), diff --git a/NETReactorSlayer.Core/Program.cs b/NETReactorSlayer.Core/Program.cs index b09864b..322755b 100644 --- a/NETReactorSlayer.Core/Program.cs +++ b/NETReactorSlayer.Core/Program.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,6 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using NETReactorSlayer.Core.Abstractions; +using NETReactorSlayer.Core.Helper; +using NETReactorSlayer.Core.Stages; using System; using System.Collections.Generic; using System.Diagnostics; @@ -20,9 +23,6 @@ You should have received a copy of the GNU General Public License using System.Linq; using System.Text; using System.Threading; -using NETReactorSlayer.Core.Abstractions; -using NETReactorSlayer.Core.Helper; -using NETReactorSlayer.Core.Stages; namespace NETReactorSlayer.Core { diff --git a/NETReactorSlayer.Core/Stages/AntiManipulationPatcher.cs b/NETReactorSlayer.Core/Stages/AntiManipulationPatcher.cs index 38858ed..3b5dfda 100644 --- a/NETReactorSlayer.Core/Stages/AntiManipulationPatcher.cs +++ b/NETReactorSlayer.Core/Stages/AntiManipulationPatcher.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,11 +13,11 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; +using System.Linq; namespace NETReactorSlayer.Core.Stages { diff --git a/NETReactorSlayer.Core/Stages/AssemblyResolver.cs b/NETReactorSlayer.Core/Stages/AssemblyResolver.cs index b4c3674..1217bd6 100644 --- a/NETReactorSlayer.Core/Stages/AssemblyResolver.cs +++ b/NETReactorSlayer.Core/Stages/AssemblyResolver.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,14 +13,14 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; namespace NETReactorSlayer.Core.Stages { @@ -35,7 +35,7 @@ public void Run(IContext context) return; var assemblies = new List(); - foreach (var prefix in DotNetUtils.GetCodeStrings(_resolverMethod).Distinct()) + foreach (var prefix in DotNetUtils.GetCodeStrings(_resolverMethod)) assemblies.AddRange(GetAssemblies(prefix)); if (assemblies.Count < 1) return; @@ -56,30 +56,30 @@ public void Run(IContext context) private void FindRequirements() { foreach (var type in from x in Context.Module.GetTypes() - where x.HasFields && !x.HasNestedTypes && !x.HasEvents && !x.HasProperties - select x) - foreach (var method in from x in type.Methods.ToArray() - where x.HasBody && x.Body.HasInstructions && x.IsStatic && - DotNetUtils.IsMethod(x, "System.Void", "()") && x.DeclaringType != null - select x) - foreach (var instr in method.Body.Instructions) - try - { - if (instr.Operand == null || !instr.Operand.ToString()!.Contains("add_AssemblyResolve")) - continue; - if (!CheckFields(method.DeclaringType.Fields)) - continue; - if (!FindResolverMethod(type, out var methodDef)) - continue; - var localTypes = new LocalTypes(methodDef); - if (!localTypes.All(_locals1) && !localTypes.All(_locals2) && !localTypes.All(_locals3)) - continue; - _resolverMethod = methodDef; - _resolverType = type; - _initialMethod = method; - return; - } - catch { } + where x.HasFields && !x.HasNestedTypes && !x.HasEvents && !x.HasProperties + select x) + foreach (var method in from x in type.Methods.ToArray() + where x.HasBody && x.Body.HasInstructions && x.IsStatic && + DotNetUtils.IsMethod(x, "System.Void", "()") && x.DeclaringType != null + select x) + foreach (var instr in method.Body.Instructions) + try + { + if (instr.Operand == null || !instr.Operand.ToString()!.Contains("add_AssemblyResolve")) + continue; + if (!CheckFields(method.DeclaringType.Fields)) + continue; + if (!FindResolverMethod(type, out var methodDef)) + continue; + var localTypes = new LocalTypes(methodDef); + if (!localTypes.All(_locals1) && !localTypes.All(_locals2) && !localTypes.All(_locals3)) + continue; + _resolverMethod = methodDef; + _resolverType = type; + _initialMethod = method; + return; + } + catch { } } private static bool FindResolverMethod(TypeDef type, out MethodDef method) @@ -115,7 +115,7 @@ private IEnumerable GetAssemblies(string prefix) { var result = new List(); if (string.IsNullOrEmpty(prefix)) - return result; + return null; foreach (var rsrc in Context.Module.Resources) { if (rsrc is not EmbeddedResource resource) diff --git a/NETReactorSlayer.Core/Stages/BooleanDecrypter.cs b/NETReactorSlayer.Core/Stages/BooleanDecrypter.cs index 9fdbb56..0e6f09a 100644 --- a/NETReactorSlayer.Core/Stages/BooleanDecrypter.cs +++ b/NETReactorSlayer.Core/Stages/BooleanDecrypter.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,13 +13,13 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Linq; namespace NETReactorSlayer.Core.Stages { diff --git a/NETReactorSlayer.Core/Stages/Cleaner.cs b/NETReactorSlayer.Core/Stages/Cleaner.cs index cfea88e..c7e269b 100644 --- a/NETReactorSlayer.Core/Stages/Cleaner.cs +++ b/NETReactorSlayer.Core/Stages/Cleaner.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,13 +13,19 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; -using System.Linq; + + + + + + using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System.Collections.Generic; +using System.Linq; namespace NETReactorSlayer.Core.Stages { @@ -174,10 +180,10 @@ private void FindAndRemoveDummyTypes(MethodDef method) method != Context.Module.EntryPoint)) return; foreach (var calledMethod in from calledMethod in DotNetUtils.GetCalledMethods(Context.Module, method) - where calledMethod.IsStatic && calledMethod.Body != null - where DotNetUtils.IsMethod(calledMethod, "System.Void", "()") - where IsEmptyMethod(calledMethod) - select calledMethod) + where calledMethod.IsStatic && calledMethod.Body != null + where DotNetUtils.IsMethod(calledMethod, "System.Void", "()") + where IsEmptyMethod(calledMethod) + select calledMethod) _methodCallCounter?.Add(calledMethod); var numCalls = 0; diff --git a/NETReactorSlayer.Core/Stages/ControlFlowDeobfuscator.cs b/NETReactorSlayer.Core/Stages/ControlFlowDeobfuscator.cs index e02dbbb..08523ce 100644 --- a/NETReactorSlayer.Core/Stages/ControlFlowDeobfuscator.cs +++ b/NETReactorSlayer.Core/Stages/ControlFlowDeobfuscator.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,13 +13,15 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; -using System.Linq; -using System.Reflection; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; namespace NETReactorSlayer.Core.Stages { @@ -28,9 +30,10 @@ internal class ControlFlowDeobfuscator : IStage public void Run(IContext context) { Context = context; - if (_fields.Count == 0) + if (int_fields.Count == 0) Initialize(); long count = 0; + long CountInlined = 0; foreach (var method in Context.Module.GetTypes().SelectMany(type => (from x in type.Methods where x.HasBody && x.Body.HasInstructions select x) .ToArray())) @@ -40,17 +43,49 @@ public void Run(IContext context) SimpleDeobfuscator.DeobfuscateBlocks(method); } + + + foreach (var method in Context.Module.GetTypes().SelectMany(type => + + (from x in type.Methods where x.HasBody && x.Body.HasInstructions select x) + + .ToArray())) + { + //SimpleDeobfuscator.Deobfuscate(method); + CountInlined += InlineBoolean(method); + //SimpleDeobfuscator.DeobfuscateBlocks(method); + } + + + + foreach (var method in Context.Module.GetTypes().SelectMany(type => + + (from x in type.Methods where x.HasBody && x.Body.HasInstructions select x) + + .ToArray())) + { + SimpleDeobfuscator.Deobfuscate(method); + //CountInlined += InlineBoolean(method); + SimpleDeobfuscator.DeobfuscateBlocks(method); + } + if (count > 0) Context.Logger.Info(count + " Equations resolved."); else Context.Logger.Warn( "Couldn't find any equation to resolve."); + + + + if (CountInlined > 0) + Context.Logger.Info(CountInlined + " ints inlined."); + } private void Initialize() { FindFieldsStatically(); - if (_fields.Count < 1) + if (int_fields.Count < 1) FindFieldsDynamically(); } @@ -63,7 +98,27 @@ private void FindFieldsStatically() x.Fields.Count(f => f.FieldType.FullName == "System.Int32" && f.IsAssembly && !f.HasConstant) >= 100)) { - _fields.Clear(); + + + int_fields.Clear(); + + byte_fields.Clear(); + sbyte_fields.Clear(); + + char_fields.Clear(); + + string_fields.Clear(); + + float_fields.Clear(); + + double_fields.Clear(); + short_fields.Clear(); + ushort_fields.Clear(); + uint_fields.Clear(); + long_fields.Clear(); + ulong_fields.Clear(); + bool_fields.Clear(); + foreach (var method in type.Methods.Where(x => x.IsStatic && x.IsAssembly && x.HasBody && x.Body.HasInstructions)) { @@ -85,23 +140,35 @@ private void FindFieldsStatically() ? method.Body.Instructions[i + 1] : null)?.Operand; var value = method.Body.Instructions[i].GetLdcI4Value(); - if (key != null && !_fields.ContainsKey(key)) - _fields.Add(key, value); + if (key != null && !int_fields.ContainsKey(key)) + int_fields.Add(key, value); else if (key != null) - _fields[key] = value; + int_fields[key] = value; } - if (_fields.Count != 0) + if (int_fields.Count != 0) typeDef = type; goto Continue; } } - Continue: + + + Continue: if (typeDef != null) Cleaner.AddTypeToBeRemoved(typeDef); } + + + // https://www.cnblogs.com/Fred1987/p/18603592 + + //copy from,https://gist.github.com/6rube/34b561827f0805f73742541b8b8bb770 + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + + static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); + private void FindFieldsDynamically() { TypeDef typeDef = null; @@ -109,7 +176,8 @@ private void FindFieldsDynamically() x => x.IsSealed && x.HasFields && x.Fields.Count(f => - f.FieldType.FullName == "System.Int32" && f.IsAssembly && !f.HasConstant) >= 100)) + (f.FieldType.FullName == "System.Int32") + && f.IsAssembly && !f.HasConstant) >= 100)) { if ((Context.Info.NativeStub && Context.Info.NecroBit) || !Context.Info.UsesReflection) @@ -118,27 +186,247 @@ private void FindFieldsDynamically() return; } - _fields.Clear(); + int_fields.Clear(); + + byte_fields.Clear(); + sbyte_fields.Clear(); + + char_fields.Clear(); + + string_fields.Clear(); - if (type.Fields.Where(x => x.FieldType.FullName == "System.Int32").All(x => x.IsStatic)) - foreach (var field in type.Fields.Where(x => x.FieldType.FullName == "System.Int32")) + float_fields.Clear(); + + double_fields.Clear(); + short_fields.Clear(); + ushort_fields.Clear(); + uint_fields.Clear(); + long_fields.Clear(); + ulong_fields.Clear(); + bool_fields.Clear(); + + bool FirstTime = true; + + if (type.Fields.Where(x => x.FieldType.FullName == "System.Int32" || x.FieldType.FullName == "System.UInt32" || + x.FieldType.FullName == "System.Int16" || x.FieldType.FullName == "System.UInt16" || + x.FieldType.FullName == "System.Int64" || x.FieldType.FullName == "System.UInt64" || x.FieldType.FullName == "System.Boolean" || + x.FieldType.FullName == "System.Byte" || x.FieldType.FullName == "System.SByte" || x.FieldType.FullName == "System.Char" || x.FieldType.FullName == "System.String" || + x.FieldType.FullName == "System.Single" || x.FieldType.FullName == "System.Double").All(x => x.IsStatic)) + foreach (var field in type.Fields.Where(x => x.FieldType.FullName == "System.Int32" || x.FieldType.FullName == "System.UInt32" || x.FieldType.FullName == "System.Int64" || x.FieldType.FullName == "System.UInt64" || x.FieldType.FullName == "System.Boolean" || + x.FieldType.FullName == "System.Int16" || x.FieldType.FullName == "System.UInt16" || x.FieldType.FullName == "System.Byte" || x.FieldType.FullName == "System.SByte" || x.FieldType.FullName == "System.Char" || x.FieldType.FullName == "System.String" || x.FieldType.FullName == "System.Single" || x.FieldType.FullName == "System.Double")) try { - var obj = Context.Assembly.ManifestModule.ResolveField((int)field.MDToken.Raw) + object obj = Context.Assembly.ManifestModule.ResolveField((int)field.MDToken.Raw) .GetValue(null); - if (obj == null || !int.TryParse(obj.ToString(), out var value)) - continue; - if (!_fields.ContainsKey(field)) - _fields.Add(field, value); - else - _fields[field] = value; + + if (obj == null) continue; + + if (obj is int) + { + + int value = (int)obj; + + if (!int_fields.ContainsKey(field)) + + int_fields.Add(field, value); + + else + + int_fields[field] = value; + } + + else if (obj is uint) + { + + uint uvalue = (uint)obj; + + if (!uint_fields.ContainsKey(field)) + + uint_fields.Add(field, uvalue); + + else + + uint_fields[field] = uvalue; + + } + + if (obj is short) + { + + short shortvalue = (short)obj; + + if (!short_fields.ContainsKey(field)) + + short_fields.Add(field, shortvalue); + + else + + short_fields[field] = shortvalue; + } + + else if (obj is ushort) + { + + ushort ushortvalue = (ushort)obj; + + if (!ushort_fields.ContainsKey(field)) + + ushort_fields.Add(field, ushortvalue); + + else + + ushort_fields[field] = ushortvalue; + + } + + else if (obj is ulong) + { + + ulong ulvalue = (ulong)obj; + + if (!ulong_fields.ContainsKey(field)) + + ulong_fields.Add(field, ulvalue); + + else + + ulong_fields[field] = ulvalue; + } + + else if (obj is long) + { + + long lvalue = (long)obj; + + if (!long_fields.ContainsKey(field)) + + long_fields.Add(field, lvalue); + + else + + long_fields[field] = lvalue; + } + + else if (obj is byte) + { + + byte bvalue = (byte)obj; + + if (!byte_fields.ContainsKey(field)) + + byte_fields.Add(field, bvalue); + + else + + byte_fields[field] = bvalue; + } + + else if (obj is sbyte) + { + + sbyte svalue = (sbyte)obj; + + if (!sbyte_fields.ContainsKey(field)) + + sbyte_fields.Add(field, svalue); + + else + + sbyte_fields[field] = svalue; + } + + else if (obj is bool) + { + + bool bvalue = (bool)obj; + + if (!bool_fields.ContainsKey(field)) + + bool_fields.Add(field, bvalue); + + else + + bool_fields[field] = bvalue; + } + + else if (obj is char) + { + + char charvalue = (char)obj; + + if (!char_fields.ContainsKey(field)) + + char_fields.Add(field, charvalue); + + else + + char_fields[field] = charvalue; + + } + + else if (obj is string) + { + + string strvalue = (string)obj; + + if (!string_fields.ContainsKey(field)) + + string_fields.Add(field, strvalue); + + else + + string_fields[field] = strvalue; + + } + + else if (obj is float) + + { + + float fvalue = (float)obj; + + if (!float_fields.ContainsKey(field)) + + float_fields.Add(field, fvalue); + + else + + float_fields[field] = fvalue; + + } + + else if (obj is double) + + { + + double dvalue = (double)obj; + + if (!double_fields.ContainsKey(field)) + + double_fields.Add(field, dvalue); + + else + + double_fields[field] = dvalue; + + } + } + catch (Exception exc) + { + if (FirstTime) + { + + MessageBox(new IntPtr(0), exc.ToString(), "Exception on Arithmetic fields", 0); + + FirstTime = false; + + } } - catch { } else if (type.Fields.Where(x => x.FieldType.FullName == "System.Int32").All(x => !x.IsStatic)) foreach (var instances in type.Fields.Where(x => x.FieldType.ToTypeDefOrRef().Equals(type))) try { - var instance = Context.Assembly.ManifestModule.ResolveField((int)instances.MDToken.Raw) + object instance = Context.Assembly.ManifestModule.ResolveField((int)instances.MDToken.Raw) .GetValue(null); if (instance == null) continue; @@ -153,27 +441,121 @@ private void FindFieldsDynamically() x.MDToken.ToInt32().Equals(runtimeField.MetadataToken)); if (field == null) continue; - if (runtimeField.GetValue(instance) is not int value) - continue; - if (!_fields.ContainsKey(field)) - _fields.Add(field, value); - else - _fields[field] = value; + + object obj = runtimeField.GetValue(instance); + + if (obj == null) continue; + + int value = 0; + if (obj is int) + { + + value = (int)obj; + + if (!int_fields.ContainsKey(field)) + + int_fields.Add(field, value); + + else + + int_fields[field] = value; + } + + // For non-static fields is only int + + /* + + else if (obj is byte) + + { + + byte bvalue = (byte)obj; + + if (!byte_fields.ContainsKey(field)) + + byte_fields.Add(field, bvalue); + + else + + byte_fields[field] = bvalue; + + } + + else if (obj is sbyte) + + { + + sbyte svalue = (sbyte)obj; + + if (!sbyte_fields.ContainsKey(field)) + + sbyte_fields.Add(field, svalue); + + else + + sbyte_fields[field] = svalue; + + } + else if (obj is float) + { + + float fvalue = (float)obj; + + if (!float_fields.ContainsKey(field)) + + float_fields.Add(field, fvalue); + + else + + float_fields[field] = fvalue; + + } + + else if (obj is double) + + { + + double dvalue = (double)obj; + + if (!double_fields.ContainsKey(field)) + + double_fields.Add(field, dvalue); + + else + + double_fields[field] = dvalue; + + } + + */ + } break; } - catch { } + catch (Exception exc) + { + + if (FirstTime) + + { + + MessageBox(new IntPtr(0), exc.ToString(), "Exception on Arithmetic fields", 0); + + FirstTime = false; + + } + } - if (_fields.Count < 100) + if (int_fields.Count < 100) continue; typeDef = type; break; } - if (_fields.All(x => x.Value == 0)) + if (int_fields.All(x => x.Value == 0)) { - _fields.Clear(); + int_fields.Clear(); return; } @@ -181,31 +563,642 @@ private void FindFieldsDynamically() Cleaner.AddTypeToBeRemoved(typeDef); } - private long Arithmetic(MethodDef method) + public static bool IsLdc(Instruction ins) + { - long count = 0; - for (var i = 0; i < method.Body.Instructions.Count; i++) - try - { - if ((method.Body.Instructions[i].OpCode != OpCodes.Ldsfld && - method.Body.Instructions[i].OpCode != OpCodes.Ldfld) || - method.Body.Instructions[i].Operand is not IField || - !_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var value) || - method.DeclaringType == _fields.First().Key.DeclaringType) - continue; - if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && - method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) - method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; - method.Body.Instructions[i] = Instruction.CreateLdcI4(value); - count++; - } - catch { } - return count; - } + switch (ins.OpCode.Code) + { + + case Code.Ldc_I4_M1: + + case Code.Ldc_I4_0: + + case Code.Ldc_I4_1: + + case Code.Ldc_I4_2: + + case Code.Ldc_I4_3: + + case Code.Ldc_I4_4: + + case Code.Ldc_I4_5: + + case Code.Ldc_I4_6: + + case Code.Ldc_I4_7: + + case Code.Ldc_I4_8: + + case Code.Ldc_I4_S: + + case Code.Ldc_I4: + + return true; + + + + default: + + return false; + + } + + + + } + + private long InlineBoolean(MethodDef method) + + { + + + + long count = 0; + + + + for (var i = 0; i < method.Body.Instructions.Count; i++) + try + { + if (method.Body.Instructions[i].OpCode != OpCodes.Call || + method.Body.Instructions[i].Operand is not MethodDef) + continue; + + + + MethodDef mdef = method.Body.Instructions[i].Operand as MethodDef; + + if (!mdef.IsStatic) continue; + + + + if (!mdef.HasBody || !mdef.Body.HasInstructions) + + continue; + + + + /* + + + + // Token: 0x06000108 RID: 264 RVA: 0x00002622 File Offset: 0x00000822 + + .method assembly hidebysig static + + bool smethod_17 () cil managed + + { + + // Header Size: 1 byte + + // Code Size: 5 (0x5) bytes + + .maxstack 8 + + + + /* 0x00000823 14 */ + + // IL_0000: ldnull + + ///* 0x00000824 14 */ IL_0001: ldnull + + ///* 0x00000825 FE01 */ IL_0002: ceq + + ///* 0x00000827 2A */ IL_0004: ret + + + + // } // end of method Class9::smethod_17 + + // */ + + + + if (mdef.Body.Instructions.Count == 4) + + { + + if (mdef.Body.Instructions[0].OpCode == OpCodes.Ldnull && + + mdef.Body.Instructions[1].OpCode == OpCodes.Ldnull && + + mdef.Body.Instructions[3].OpCode == OpCodes.Ret) + + { + + if (mdef.Body.Instructions[2].OpCode == OpCodes.Ceq) + + { + + method.Body.Instructions[i].OpCode = OpCodes.Ldc_I4_1; + + method.Body.Instructions[i].Operand = null; + + } + + + + } + + } + + + + if (mdef.Body.Instructions.Count != 2) + + continue; + + + + if (!IsLdc(mdef.Body.Instructions[0])) + + continue; + + + + if (mdef.Body.Instructions[1].OpCode != OpCodes.Ret) + + continue; + + + + Instruction ldci = Instruction.CreateLdcI4(mdef.Body.Instructions[0].GetLdcI4Value()); + + method.Body.Instructions[i].OpCode = ldci.OpCode; + + method.Body.Instructions[i].Operand = ldci.Operand; + + ldci = null; + + count++; + + + + + + } + + catch + + { + + + + } + + + + return count; + + } + + private long Arithmetic(MethodDef method) + { + long count = 0; + for (var i = 0; i < method.Body.Instructions.Count; i++) + try + { + if ((method.Body.Instructions[i].OpCode != OpCodes.Ldsfld && + method.Body.Instructions[i].OpCode != OpCodes.Ldfld) || + method.Body.Instructions[i].Operand is not IField) + continue; + + + + if (int_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var value) && + + method.DeclaringType != int_fields.First().Key.DeclaringType) + { + + //if (!((FieldDef)method.Body.Instructions[i].Operand).IsStatic) + + //{ + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + //} + + + + Instruction ldci = Instruction.CreateLdcI4(value); + + method.Body.Instructions[i].OpCode = ldci.OpCode; + + method.Body.Instructions[i].Operand = ldci.Operand; + + ldci = null; + + count++; + + + + } + + + + if (bool_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var boolvalue) && + + method.DeclaringType != bool_fields.First().Key.DeclaringType) + { + + //if (!((FieldDef)method.Body.Instructions[i].Operand).IsStatic) + + //{ + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + //} + + + + //Instruction ldci = Instruction.CreateLdcI4((int)uivalue); + + //method.Body.Instructions[i].OpCode = ldci.OpCode; + + // method.Body.Instructions[i].Operand = ldci.Operand; + + + + if (boolvalue == false) + + { + + method.Body.Instructions[i].OpCode = OpCodes.Ldc_I4_0; + + method.Body.Instructions[i].Operand = null; + + } + + else + + { + + method.Body.Instructions[i].OpCode = OpCodes.Ldc_I4_1; + + method.Body.Instructions[i].Operand = null; + + } + + + + count++; + + + + } + + if (uint_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var uivalue) && + + method.DeclaringType != uint_fields.First().Key.DeclaringType) + { + + //if (!((FieldDef)method.Body.Instructions[i].Operand).IsStatic) + + //{ + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + //} + + + + Instruction ldci = Instruction.CreateLdcI4((int)uivalue); + + method.Body.Instructions[i].OpCode = ldci.OpCode; + + method.Body.Instructions[i].Operand = ldci.Operand; + + ldci = null; + + count++; + + + + } + + + + if (long_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var lvalue) && + + method.DeclaringType != long_fields.First().Key.DeclaringType) + { + + //if (!((FieldDef)method.Body.Instructions[i].Operand).IsStatic) + + //{ + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + //} + + method.Body.Instructions[i].OpCode = OpCodes.Ldc_I8; + + method.Body.Instructions[i].Operand = (long)lvalue; + + count++; + + + + } + + + + if (ulong_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var ulvalue) && + + method.DeclaringType != ulong_fields.First().Key.DeclaringType) + { + + //if (!((FieldDef)method.Body.Instructions[i].Operand).IsStatic) + + //{ + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + //} + + method.Body.Instructions[i].OpCode = OpCodes.Ldc_I8; + + method.Body.Instructions[i].Operand = (long)ulvalue; + + count++; + + + + } + + + + if (short_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var svalue) && + + method.DeclaringType != short_fields.First().Key.DeclaringType) + { + + //if (!((FieldDef)method.Body.Instructions[i].Operand).IsStatic) + + //{ + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + //} + + + + Instruction ldci = Instruction.CreateLdcI4((int)svalue); + + method.Body.Instructions[i].OpCode = ldci.OpCode; + + method.Body.Instructions[i].Operand = ldci.Operand; + + ldci = null; + + count++; + + + + } + + + + if (ushort_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var usvalue) && + + method.DeclaringType != ushort_fields.First().Key.DeclaringType) + { + + //if (!((FieldDef)method.Body.Instructions[i].Operand).IsStatic) + + //{ + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + //} + + + + Instruction ldci = Instruction.CreateLdcI4((int)usvalue); + + method.Body.Instructions[i].OpCode = ldci.OpCode; + + method.Body.Instructions[i].Operand = ldci.Operand; + + ldci = null; + + count++; + + + + } + + + + if (byte_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var bvalue) && + + method.DeclaringType != byte_fields.First().Key.DeclaringType) + { + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + + + Instruction ldci = Instruction.CreateLdcI4((int)bvalue); + + method.Body.Instructions[i].OpCode = ldci.OpCode; + + method.Body.Instructions[i].Operand = ldci.Operand; + + ldci = null; + + count++; + + } + + + + if (sbyte_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var sbvalue) && + + method.DeclaringType != sbyte_fields.First().Key.DeclaringType) + { + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + + + Instruction ldci = Instruction.CreateLdcI4((int)sbvalue); + + method.Body.Instructions[i].OpCode = ldci.OpCode; + + method.Body.Instructions[i].Operand = ldci.Operand; + + ldci = null; + + count++; + + } + + + + if (char_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var cvalue) && + + method.DeclaringType != char_fields.First().Key.DeclaringType) + { + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + + + Instruction ldci = Instruction.CreateLdcI4((int)cvalue); + + method.Body.Instructions[i].OpCode = ldci.OpCode; + + method.Body.Instructions[i].Operand = ldci.Operand; + + ldci = null; + + count++; + + } + + + + if (string_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var stringvalue) && + + method.DeclaringType != string_fields.First().Key.DeclaringType) + { + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + + + method.Body.Instructions[i].OpCode = OpCodes.Ldstr; + + method.Body.Instructions[i].Operand = (string)stringvalue; + + count++; + + + + } + + + + if (float_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var fvalue) && + + method.DeclaringType != float_fields.First().Key.DeclaringType) + { + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + + + method.Body.Instructions[i].OpCode = OpCodes.Ldc_R4; + + method.Body.Instructions[i].Operand = (float)fvalue; + + count++; + + } + + + + if (double_fields.TryGetValue((IField)method.Body.Instructions[i].Operand, out var dvalue) && + + method.DeclaringType != double_fields.First().Key.DeclaringType) + { + + if (method.Body.Instructions[i].OpCode == OpCodes.Ldfld && + + method.Body.Instructions[i - 1].OpCode == OpCodes.Ldsfld) + + method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; + + + + method.Body.Instructions[i].OpCode = OpCodes.Ldc_R8; + + method.Body.Instructions[i].Operand = (double)dvalue; + + count++; + + } + + } + catch { } + + return count; + } + + + private IContext Context { get; set; } + private readonly Dictionary int_fields = new(); + + private readonly Dictionary float_fields = new(); + private readonly Dictionary double_fields = new(); + + private readonly Dictionary byte_fields = new(); + + private readonly Dictionary sbyte_fields = new(); + + private readonly Dictionary string_fields = new(); + + private readonly Dictionary char_fields = new(); + + private readonly Dictionary short_fields = new(); + private readonly Dictionary ushort_fields = new(); + private readonly Dictionary uint_fields = new(); + private readonly Dictionary long_fields = new(); + private readonly Dictionary ulong_fields = new(); + private readonly Dictionary bool_fields = new(); - private IContext Context { get; set; } - private readonly Dictionary _fields = new(); } } \ No newline at end of file diff --git a/NETReactorSlayer.Core/Stages/CosturaDumper.cs b/NETReactorSlayer.Core/Stages/CosturaDumper.cs index 828775c..ae6d3f0 100644 --- a/NETReactorSlayer.Core/Stages/CosturaDumper.cs +++ b/NETReactorSlayer.Core/Stages/CosturaDumper.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,11 +13,11 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; +using NETReactorSlayer.Core.Abstractions; using System.IO; using System.IO.Compression; using System.Linq; -using dnlib.DotNet; -using NETReactorSlayer.Core.Abstractions; namespace NETReactorSlayer.Core.Stages { diff --git a/NETReactorSlayer.Core/Stages/MethodDecrypter.cs b/NETReactorSlayer.Core/Stages/MethodDecrypter.cs index 663f205..8640812 100644 --- a/NETReactorSlayer.Core/Stages/MethodDecrypter.cs +++ b/NETReactorSlayer.Core/Stages/MethodDecrypter.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,16 +13,17 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using dnlib.IO; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; namespace NETReactorSlayer.Core.Stages { @@ -41,6 +42,14 @@ public void Run(IContext context) Context.Info.NecroBit = true; + if (_encryptedResource == null) + + { + + Context.Logger.Warn("Couldn't find encryptedResource."); + + } + var bytes = _encryptedResource.Decrypt(); if (!RestoreMethodsBody(bytes)) @@ -49,11 +58,14 @@ public void Run(IContext context) Cleaner.AddResourceToBeRemoved(_encryptedResource.EmbeddedResource); Cleaner.AddCallToBeRemoved(_encryptedResource.DecrypterMethod); Context.Logger.Info( - $"{Context.Module.GetTypes().SelectMany(x => x.Methods).Count()} Methods decrypted."); + $"{Context.Module.GetTypes().SelectMany(x => x.Methods).Count()} Methods decrypted.-{EncryptedResource.DecrypterVer}"); } catch (Exception ex) { - Context.Logger.Error($"An unexpected error occurred during decrypting methods. {ex.Message}."); + + Context.Logger.Error(ex.StackTrace.ToString()); + + Context.Logger.Error($"An unexpected error occurred during decrypting methods. {ex.Message}.-{EncryptedResource.DecrypterVer}"); } _encryptedResource?.Dispose(); @@ -62,17 +74,17 @@ public void Run(IContext context) private bool Find() { foreach (var methodDef in Context.Module.GetTypes().SelectMany(type => (from method in type.Methods.ToList() - where DotNetUtils.IsMethod(method, "System.UInt32", - "(System.IntPtr,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr,System.UInt32&)") || - DotNetUtils.IsMethod(method, "System.UInt32", - "(System.UInt64&,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr&,System.UInt32&)") - from methodDef in from x in method.DeclaringType.Methods - where x.IsStatic && x.HasBody && x.Body.HasInstructions - select x - from call in DotNetUtils.GetMethodCalls(methodDef) - where call.MDToken.ToInt32() == method.MDToken.ToInt32() - select methodDef).Where(methodDef => - EncryptedResource.IsKnownDecrypter(methodDef, Array.Empty(), true)))) + where DotNetUtils.IsMethod(method, "System.UInt32", + "(System.IntPtr,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr,System.UInt32&)") || + DotNetUtils.IsMethod(method, "System.UInt32", + "(System.UInt64&,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr&,System.UInt32&)") + from methodDef in from x in method.DeclaringType.Methods + where x.IsStatic && x.HasBody && x.Body.HasInstructions + select x + from call in DotNetUtils.GetMethodCalls(methodDef) + where call.MDToken.ToInt32() == method.MDToken.ToInt32() + select methodDef).Where(methodDef => + EncryptedResource.IsKnownDecrypter(methodDef, Array.Empty(), true)))) { _encryptedResource = new EncryptedResource(Context, methodDef); if (_encryptedResource.EmbeddedResource != null) @@ -85,31 +97,23 @@ where call.MDToken.ToInt32() == method.MDToken.ToInt32() private bool Find2() { - var staticConstructors = new[] - { - Context.Module.EntryPoint?.DeclaringType?.FindStaticConstructor(), - Context.Module.GlobalType.FindStaticConstructor() - }; - - foreach (var cctor in staticConstructors) - { - if (cctor is not { HasBody: true } || !cctor.Body.HasInstructions) - return false; - foreach (var instr in cctor.Body.Instructions.Where(instr => instr.OpCode.Equals(OpCodes.Call))) - if (instr.Operand is MethodDef { DeclaringType: not null, HasBody: true } methodDef && - methodDef.Body.HasInstructions) - if (DotNetUtils.GetMethod(methodDef.DeclaringType, - "System.Security.Cryptography.SymmetricAlgorithm", "()") != null) - { - if (!EncryptedResource.IsKnownDecrypter(methodDef, Array.Empty(), true)) - continue; + var cctor = Context.Module.GlobalType.FindStaticConstructor(); + if (cctor is not { HasBody: true } || !cctor.Body.HasInstructions) + return false; + foreach (var instr in cctor.Body.Instructions.Where(instr => instr.OpCode.Equals(OpCodes.Call))) + if (instr.Operand is MethodDef { DeclaringType: { }, HasBody: true } methodDef && + methodDef.Body.HasInstructions) + if (DotNetUtils.GetMethod(methodDef.DeclaringType, + "System.Security.Cryptography.SymmetricAlgorithm", "()") != null) + { + if (!EncryptedResource.IsKnownDecrypter(methodDef, Array.Empty(), true)) + continue; - _encryptedResource = new EncryptedResource(Context, methodDef); - if (_encryptedResource.EmbeddedResource != null) - return true; - _encryptedResource.Dispose(); - } - } + _encryptedResource = new EncryptedResource(Context, methodDef); + if (_encryptedResource.EmbeddedResource != null) + return true; + _encryptedResource.Dispose(); + } return false; } @@ -142,13 +146,6 @@ private bool FindBinaryReaderMethod(out int popCallsCount) for (var i = 0; i < decrypterMethod.Body.Instructions.Count; i++) try { - var skip = CheckNet6Calls(decrypterMethod, i, method); - if (skip) - { - popCallsCount = 4; - break; - } - if (!decrypterMethod.Body.Instructions[i].IsLdloc() || !decrypterMethod.Body.Instructions[i + 1].OpCode.Equals(OpCodes.Callvirt) || decrypterMethod.Body.Instructions[i + 1].Operand is not MethodDef calledMethod || @@ -159,7 +156,7 @@ private bool FindBinaryReaderMethod(out int popCallsCount) popCallsCount++; } catch { } - + return true; } catch { } @@ -167,56 +164,208 @@ private bool FindBinaryReaderMethod(out int popCallsCount) return false; } - private bool CheckNet6Calls(MethodDef decrypterMethod, int i, MethodDef method) + + + private MethodDef FindBinaryReaderReadInt32Method() { - //.NET 6+ doesn't only pop 4 times, it assigns them and does some obfuscated things, - //but they don't seem to be important - var inst = decrypterMethod.Body.Instructions; - if (!inst[i].IsLdloc() || - !inst[i + 1].OpCode.Equals(OpCodes.Callvirt) || - inst[i + 1].Operand is not MethodDef calledMethod1 || - !inst[i + 2].IsStloc() || - - !inst[i + 3].IsLdloc() || - !inst[i + 4].OpCode.Equals(OpCodes.Callvirt) || - inst[i + 4].Operand is not MethodDef calledMethod2 || - !inst[i + 5].OpCode.Equals(OpCodes.Stsfld) || - - !inst[i + 6].IsLdloc() || - !inst[i + 7].OpCode.Equals(OpCodes.Callvirt) || - inst[i + 7].Operand is not MethodDef calledMethod3 || - !inst[i + 8].OpCode.Equals(OpCodes.Pop) || - - !inst[i + 9].IsLdloc() || - !inst[i + 10].OpCode.Equals(OpCodes.Callvirt) || - inst[i + 10].Operand is not MethodDef calledMethod4 || - !inst[i + 11].IsStloc()) - return false; + var decrypterMethod = _encryptedResource.DecrypterMethod; + var calls = decrypterMethod.Body.Instructions + .Where(x => x.OpCode.Equals(OpCodes.Callvirt) && x.Operand is MethodDef).Select(x => x.Operand) + .Cast(); + foreach (var method in calls) + try + { + SimpleDeobfuscator.DeobfuscateBlocks(method); + if (method.MethodSig.RetType.FullName != "System.Int32" || + method.Body.Instructions.Count != 4) + continue; + + if (!method.Body.Instructions[0].IsLdarg() || + !method.Body.Instructions[1].OpCode.Equals(OpCodes.Ldfld) || + (!method.Body.Instructions[2].OpCode.Equals(OpCodes.Callvirt) && + !method.Body.Instructions[2].OpCode.Equals(OpCodes.Call)) || + !method.Body.Instructions[3].OpCode.Equals(OpCodes.Ret)) + continue; + + if (!method.Body.Instructions[2].Operand.ToString()!.Contains("System.Int32")) + continue; + + for (var i = 0; i < decrypterMethod.Body.Instructions.Count; i++) + try + { + if (!decrypterMethod.Body.Instructions[i].IsLdloc() || + !decrypterMethod.Body.Instructions[i + 1].OpCode.Equals(OpCodes.Callvirt) || + decrypterMethod.Body.Instructions[i + 1].Operand is not MethodDef calledMethod || + !decrypterMethod.Body.Instructions[i + 2].OpCode.Equals(OpCodes.Pop)) + continue; + + if (MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod, method)) + return method; + } + catch { } - return MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod1, method) && - MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod2, method) && - MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod3, method) && - MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod4, method); + // return true; + } + catch { } + + return null; } + + + // https://www.cnblogs.com/Fred1987/p/18603592 + + //copy from,https://gist.github.com/6rube/34b561827f0805f73742541b8b8bb770 + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); + + + /* + + @class.method_3(); + + @class.method_3(); + + @class.method_3(); + + int num20 = @class.method_3(); + + int num21 = @class.method_3(); + + */ + + public static int methodrcount; + private bool RestoreMethodsBody(byte[] bytes) { var dumpedMethods = new DumpedMethods(); XorEncrypt(bytes, GetXorKey(_encryptedResource.DecrypterMethod)); - var isFindDnrMethod = FindDnrCompileMethod(_encryptedResource.DecrypterMethod) != null; + var isFindDnrMethod = FindDnrCompileMethod(_encryptedResource.DecrypterMethod.DeclaringType) != null; var methodsDataReader = ByteArrayDataReaderFactory.CreateReader(bytes); int tmp; - if (FindBinaryReaderMethod(out var popCallsCount) && popCallsCount > 3) + if (FindBinaryReaderMethod(out var popCallsCount) && popCallsCount >= 3) + { + + + for (var i = 0; i < popCallsCount; i++) methodsDataReader.ReadInt32(); + + } else { + bool IsOk = false; + bool SpecialCase = false; + int ReadCount = 0; + int Keypos = GetXorKeyPos(_encryptedResource.DecrypterMethod); + if (Keypos > 0) + { + + MethodDef ReadInt32Method = FindBinaryReaderReadInt32Method(); + + if (ReadInt32Method != null) + + { + + + + for (int i = Keypos; i < _encryptedResource.DecrypterMethod.Body.Instructions.Count; i++) + + { + + if (_encryptedResource.DecrypterMethod.Body.Instructions[i].OpCode == OpCodes.Callvirt && + + _encryptedResource.DecrypterMethod.Body.Instructions[i].Operand != null && + + _encryptedResource.DecrypterMethod.Body.Instructions[i].Operand.ToString().Contains("ResolveMethod")) + + { + + IsOk = true; + + break; + + } + + + + if (_encryptedResource.DecrypterMethod.Body.Instructions[i].IsLdloc() && _encryptedResource.DecrypterMethod.Body.Instructions[i + 1].OpCode == OpCodes.Ldc_I4_4 && + + (_encryptedResource.DecrypterMethod.Body.Instructions[i + 2].OpCode == OpCodes.Bne_Un || _encryptedResource.DecrypterMethod.Body.Instructions[i + 2].OpCode == OpCodes.Bne_Un_S)) + + { + + SpecialCase = true; + + break; + + } + + + + if (_encryptedResource.DecrypterMethod.Body.Instructions[i].OpCode.Equals(OpCodes.Callvirt) || + _encryptedResource.DecrypterMethod.Body.Instructions[i].OpCode.Equals(OpCodes.Call)) + + { + + if (_encryptedResource.DecrypterMethod.Body.Instructions[i].Operand != null && + + _encryptedResource.DecrypterMethod.Body.Instructions[i].Operand == ReadInt32Method) + + ReadCount++; + + + + + + } + + + + + + } + + } + + } + + + + if (SpecialCase) + + { + + ReadCount -= 2; // skipp 2 ints + + IsOk = true; + + } + + + + if (IsOk && ReadCount >= 3) + { + + for (int i = 0; i < ReadCount; i++) + + methodsDataReader.ReadInt32(); + + } + + tmp = methodsDataReader.ReadInt32(); + if ((tmp & -16777216L) == 100663296L) + methodsDataReader.ReadInt32(); + else + methodsDataReader.Position -= 4U; + } var patchCount = methodsDataReader.ReadInt32(); @@ -226,8 +375,12 @@ private bool RestoreMethodsBody(byte[] bytes) var mode = methodsDataReader.ReadInt32(); tmp = methodsDataReader.ReadInt32(); methodsDataReader.Position -= 4U; + + //MessageBox(new IntPtr(0), mode.ToString(), "MessageBox", 0); + if ((tmp & -16777216L) == 100663296L) { + // methodsDataReader.Position += (uint)(8 * patchCount); patchCount = methodsDataReader.ReadInt32(); mode = methodsDataReader.ReadInt32(); @@ -289,6 +442,9 @@ private bool RestoreMethodsBody(byte[] bytes) PatchDwords(Context.PeImage, ref methodsDataReader, patchCount); methodsDataReader.ReadInt32(); + + methodrcount = 0; + while (methodsDataReader.Position < (ulong)(bytes.Length - 1)) { var rva3 = methodsDataReader.ReadUInt32(); @@ -296,8 +452,31 @@ private bool RestoreMethodsBody(byte[] bytes) var isNativeCode = index >= 1879048192U; var size2 = methodsDataReader.ReadInt32(); var methodData = methodsDataReader.ReadBytes(size2); + methodrcount++; + + //if (methodrcount == 5000) + + // break; + + + if (rva3 > 0x00002990 && rva3 < 0x000299C) + + { + + // break; + + } + else + { + + //continue; + + } + + if (!rvaToIndex.TryGetValue(rva3, out var methodIndex)) continue; + var methodToken = (uint)(100663297 + methodIndex); if (isNativeCode) { @@ -315,26 +494,46 @@ private bool RestoreMethodsBody(byte[] bytes) : new byte[] { 32, 222, 192, 173, 222, 109, 122 }; } + + var dumpedMethod = new DumpedMethod(); + Context.PeImage.ReadMethodTableRowTo(dumpedMethod, + MDToken.ToRID(methodToken)); + dumpedMethod.code = methodData; + var codeReader = Context.PeImage.Reader; + codeReader.Position = Context.PeImage.RvaToOffset(dumpedMethod.mdRVA); + var mbHeader = MethodBodyParser.ParseMethodBody(ref codeReader, out _, - out dumpedMethod.extraSections); + + out dumpedMethod.extraSections); + Context.PeImage.UpdateMethodHeaderInfo(dumpedMethod, mbHeader); + dumpedMethods.Add(dumpedMethod); + + + + //MethodDef method = Context.Module.ResolveMethod(index); + } } } using (Context.Module) { + + //MessageBox(new IntPtr(0), methodrcount.ToString(), "MessageBox", 0); + if (!isFindDnrMethod || mode == 1) Context.Module = Context.AssemblyModule.Reload( Context.PeImage.PeImageData, CreateDumpedMethodsRestorer(dumpedMethods), null); else if (dumpedMethods.Count > 0) + Context.Module = Context.AssemblyModule.Reload( Context.ModuleBytes, CreateDumpedMethodsRestorer(dumpedMethods), null); else @@ -375,20 +574,57 @@ private static bool IsUsingRva(MethodDef method) instrs[i + 8].OpCode.Code.Equals(Code.Call)).Any(); } - private static CompileMethodType GetCompileMethodType(IMethod method, string paramStruct = null) + private static CompileMethodType GetCompileMethodType(IMethod method) { if (DotNetUtils.IsMethod(method, "System.UInt32", "(System.UInt64&,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr&,System.UInt32&)")) return CompileMethodType.V1; - + if (DotNetUtils.IsMethod(method, "System.UInt32", - "(System.IntPtr,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr,System.UInt32&)")) + "(System.IntPtr,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr,System.UInt32&)")) return CompileMethodType.V2; - - return paramStruct != null && DotNetUtils.IsMethod(method, "System.UInt32", - $"(System.IntPtr,System.IntPtr,{paramStruct}&,System.UInt32,System.IntPtr,System.UInt32&)") - ? CompileMethodType.V3 - : CompileMethodType.Unknown; + + + + MethodDef mdef = method as MethodDef; + + if (mdef == null) + + return CompileMethodType.Unknown; + + + + if (mdef.ReturnType.ToString() == "System.UInt32") + + { + + if (mdef.Parameters[0].Type.ToString() == "System.IntPtr" && + + mdef.Parameters[1].Type.ToString() == "System.IntPtr") + + { + + if (mdef.Parameters[3].Type.ToString() == "System.UInt32" && mdef.Parameters[4].Type.ToString() == "System.IntPtr" && + + mdef.Parameters[5].Type.ToString() == "System.UInt32&") + + { + + //MessageBox(new IntPtr(0), mdef.Parameters[2].Type.ToString(), "MessageBox", 0); + + if (mdef.Parameters[2].Type.ToString().EndsWith("&")) + + return CompileMethodType.V3; + + } + + + + } + + } + + return CompileMethodType.Unknown; } private static DumpedMethodsRestorer CreateDumpedMethodsRestorer(DumpedMethods dumpedMethods) @@ -418,52 +654,66 @@ private static long GetXorKey(MethodDef method) return result; } - Continue: ; + Continue:; } return 0; } - private static MethodDef FindDnrCompileMethod(MethodDef methodDef) + + + private static int GetXorKeyPos(MethodDef method) { - var type = methodDef.DeclaringType; - var methodCandidates = (from method in type.Methods - where method.IsStatic && method.Body != null - let sig = method.MethodSig - where sig != null && sig.Params.Count == 6 - select method).ToList(); - var dnrCompileMethod = methodCandidates.FirstOrDefault(method => GetCompileMethodType(method) != CompileMethodType.Unknown); - - if (dnrCompileMethod == null) + for (var i = 0; i < method.Body.Instructions.Count - 1; i++) { - //.NET 6+ has a different compile method signature - var paramStruct = type.NestedTypes.FirstOrDefault(typeDef => - typeDef.Fields.Count == 4 && - typeDef.Fields[0].FieldType.FullName == "System.IntPtr" && - typeDef.Fields[1].FieldType.FullName == "System.IntPtr" && - typeDef.Fields[2].FieldType.FullName == "System.IntPtr" && - typeDef.Fields[3].FieldType.FullName == "System.Int32"); - - if (paramStruct != null) + if (method.Body.Instructions[i].OpCode.Code.Equals(Code.Ldind_I8)) { - var operands = methodDef.Body.Instructions - .Where(x => x.OpCode.Equals(OpCodes.Ldftn) && x.Operand is MethodDef) - .Select(x => x.Operand); - dnrCompileMethod = methodCandidates.Where(method => - GetCompileMethodType(method, paramStruct.FullName) != CompileMethodType.Unknown) - .FirstOrDefault(x => operands.Contains(x)); + var ldci4 = method.Body.Instructions[i + 1]; + long result; + if (ldci4.IsLdcI4()) + result = ldci4.GetLdcI4Value(); + else + { + if (!ldci4.OpCode.Code.Equals(Code.Ldc_I8)) + goto Continue; + result = (long)ldci4.Operand; + } + + return i; } + + + + Continue:; } - return dnrCompileMethod; + return -1; } + private static MethodDef FindDnrCompileMethod(TypeDef type) => + (from method in type.Methods + where method.IsStatic && method.Body != null + let sig = method.MethodSig + where sig != null && sig.Params.Count == 6 + select method).FirstOrDefault(method => GetCompileMethodType(method) != CompileMethodType.Unknown); + private static void PatchDwords(MyPeImage peImage, ref DataReader reader, int count) { for (var i = 0; i < count; i++) { var rva = reader.ReadUInt32(); var data = reader.ReadUInt32(); + + + + /*if (rva < 0x2500) + { + + //MessageBox(new IntPtr(0), rva.ToString("X8"), "SHEET", 0); + + continue; + }*/ + peImage.DotNetSafeWrite(rva, BitConverter.GetBytes(data)); } } diff --git a/NETReactorSlayer.Core/Stages/MethodInliner.cs b/NETReactorSlayer.Core/Stages/MethodInliner.cs index 4c5208e..bda6df4 100644 --- a/NETReactorSlayer.Core/Stages/MethodInliner.cs +++ b/NETReactorSlayer.Core/Stages/MethodInliner.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,41 +13,210 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; -using System.Linq; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; namespace NETReactorSlayer.Core.Stages { internal class MethodInliner : IStage { + + // https://www.cnblogs.com/Fred1987/p/18603592 + //copy from,https://gist.github.com/6rube/34b561827f0805f73742541b8b8bb770 + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); + public void Run(IContext context) { + long count = 0; var proxies = new HashSet(); foreach (var method in context.Module.GetTypes().SelectMany(type => from x in type.Methods.ToList() where x.HasBody && x.Body.HasInstructions select x)) try { - var length = method.Body.Instructions.Count; - var i = 0; - for (; i < length; i++) + + + + //MessageBox(new IntPtr(0), method.Body.Instructions[0].ToString(), "MessageBox", 0); + + //break; + + + + //if (method.Name.String != "XM3c8yL8YOc") + + // continue; + + /*if (method.DeclaringType.Name.String == "FrmToolBox" && method.Name.String == "Chihgu7Fc") + { - MethodDef methodDef; - if (!method.Body.Instructions[i].OpCode.Equals(OpCodes.Call) || - (methodDef = method.Body.Instructions[i].Operand as MethodDef) == null || - !IsInlineMethod(methodDef, out var instructions) || + + MessageBox(new IntPtr(0), method.Body.Instructions[0].ToString(), "MessageBox", 0); + + + + } + + else + + continue; + */ + + int length = method.Body.Instructions.Count; + + for (int i = 0; i < length; i++) + { + + // VIN_STUDEO.FrmToolBox.Chihgu7Fc(object, RoutedEventArgs) : void @06000017 + + + + /*if (method.Body.Instructions[i].Operand != null) + { + + MethodDef methodDefcrap = method.Body.Instructions[i].Operand as MethodDef; + + if (methodDefcrap!=null) + + { + + if (methodDefcrap.DeclaringType.Name.String == "FrmToolBox" && methodDefcrap.Name.String == "0") + + { + + MessageBox(new IntPtr(0), methodDefcrap.ToString(), "MessageBox", 0); + + } + + } + + } + */ + + MethodDef methodDef = null; + if (!method.Body.Instructions[i].OpCode.Equals(OpCodes.Call) && !method.Body.Instructions[i].OpCode.Equals(OpCodes.Callvirt)) + continue; + + methodDef = method.Body.Instructions[i].Operand as MethodDef; + + if (methodDef == null) continue; + + + + bool IsProperty = false; + + + + foreach (PropertyDef prop in method.DeclaringType.Properties) + + { + + if (prop.GetMethod == methodDef) + + { + + IsProperty = true; + + break; + + } + + + + if (prop.SetMethod == methodDef) + + { + + IsProperty = true; + + break; + + } + + } + + + + if (IsProperty) continue; + + + + /*if (methodDef.DeclaringType.Name.String == "FrmToolBox" && methodDef.Name.String == "0") + + { + + MessageBox(new IntPtr(0), method.ToString(), "MessageBox", 0); + + }*/ + + + if (method.Body.Instructions[i].OpCode.Equals(OpCodes.Callvirt) && !methodDef.IsVirtual) + continue; + + + if (!methodDef.IsStatic) + + { + + if ((i - 1) < 0) continue; + + if (method.Body.Instructions[i - 1].OpCode != OpCodes.Ldarg_0) + + continue; + + } + + + + if (!IsInlineMethod(methodDef, out var instructions) || !IsCompatibleType(method.DeclaringType, methodDef.DeclaringType)) continue; count++; - method.Body.Instructions[i].OpCode = OpCodes.Nop; - method.Body.Instructions[i].Operand = null; - length += instructions.Count; - foreach (var instr in instructions) - method.Body.Instructions.Insert(i++, instr); + + + + /*if (count == 10) + + { + + MessageBox(new IntPtr(0), methodDef.ToString(), "MessageBox", 0); + + continue; + + }*/ + + + + if (instructions.Count == 1) + { + + method.Body.Instructions[i].OpCode = instructions[0].OpCode; + + method.Body.Instructions[i].Operand = instructions[0].Operand; + + } + else + { + + method.Body.Instructions[i].OpCode = OpCodes.Nop; + + method.Body.Instructions[i].Operand = null; + + length += instructions.Count; + + foreach (var instr in instructions) + + method.Body.Instructions.Insert(i++, instr); + } + method.Body.UpdateInstructionOffsets(); proxies.Add(methodDef); } @@ -57,15 +226,17 @@ from x in type.Methods.ToList() where x.HasBody && x.Body.HasInstructions select catch { } foreach (var instruction in from type in context.Module.GetTypes() - from method in from x in type.Methods.ToArray() where x.HasBody && x.Body.HasInstructions select x - from instruction in method.Body.Instructions - select instruction) + from method in from x in type.Methods.ToArray() where x.HasBody && x.Body.HasInstructions select x + from instruction in method.Body.Instructions + select instruction) try { MethodDef item; if (instruction.OpCode.OperandType == OperandType.InlineMethod && (item = instruction.Operand as MethodDef) != null && proxies.Contains(item)) proxies.Remove(item); + + } catch { } @@ -76,26 +247,40 @@ from instruction in method.Body.Instructions private static bool IsInlineMethod(MethodDef method, out List instructions) { + instructions = new List(); - if (!method.HasBody || !method.IsStatic) + if (!method.HasBody || !method.Body.HasInstructions) + return false; + if (!method.IsStatic && method.Body.Instructions[0].OpCode != OpCodes.Ldarg_0) return false; + var list = method.Body.Instructions; - var index = list.Count - 1; + var index = list.Count - 1; // last instruction if (index < 1 || list[index].OpCode != OpCodes.Ret) return false; var code = list[index - 1].OpCode.Code; int length; if (code != Code.Call && code != Code.Callvirt && code != Code.Newobj) - { + { // threat Ldfld case: if (code != Code.Ldfld) return false; instructions.Add(new Instruction(list[index - 1].OpCode, list[index - 1].Operand)); length = (from i in list - where i.OpCode != OpCodes.Nop - select i).Count() - 2; - return length == 1 && length == method.Parameters.Count - 1; + where i.OpCode != OpCodes.Nop + select i).Count() - 2; // instructions wiouth Ldfld instruction and ret + return (length == 1 && length == method.Parameters.Count - 1) || (length == 1 && length == method.Parameters.Count); } + if (!method.IsStatic) // rest of instruction except Code.Ldfld not fixed for instance + return false; + + + //Edit: + + // return false; + + + instructions.Add(new Instruction(list[index - 1].OpCode, list[index - 1].Operand)); length = list.Count(i => i.OpCode != OpCodes.Nop) - 2; var count = list.Count - 2; @@ -103,6 +288,7 @@ private static bool IsInlineMethod(MethodDef method, out List instr { if (list[index - 2].IsLdcI4() && --length == method.Parameters.Count) { + count = list.Count - 3; instructions.Insert(0, new Instruction(list[index - 2].OpCode, list[index - 2].Operand)); } @@ -122,6 +308,7 @@ private static bool IsInlineMethod(MethodDef method, out List instr } return length == num; + } private static bool IsCompatibleType(IType origType, IType newType) => diff --git a/NETReactorSlayer.Core/Stages/ProxyCallFixer.cs b/NETReactorSlayer.Core/Stages/ProxyCallFixer.cs index e84b718..780b3af 100644 --- a/NETReactorSlayer.Core/Stages/ProxyCallFixer.cs +++ b/NETReactorSlayer.Core/Stages/ProxyCallFixer.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,15 +13,15 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; namespace NETReactorSlayer.Core.Stages { @@ -66,8 +66,8 @@ private bool Find() { var callCounter = new CallCounter(); foreach (var type in from x in Context.Module.GetTypes() - where x.Namespace.Equals("") && DotNetUtils.DerivesFromDelegate(x) - select x) + where x.Namespace.Equals("") && DotNetUtils.DerivesFromDelegate(x) + select x) if (type.FindStaticConstructor() is { } cctor) foreach (var method in DotNetUtils.GetMethodCalls(cctor).Where(method => method.MethodSig.GetParamCount() == 1 && diff --git a/NETReactorSlayer.Core/Stages/ResourceResolver.cs b/NETReactorSlayer.Core/Stages/ResourceResolver.cs index ed54f3d..c1560da 100644 --- a/NETReactorSlayer.Core/Stages/ResourceResolver.cs +++ b/NETReactorSlayer.Core/Stages/ResourceResolver.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,13 +13,16 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.Linq; + + using de4dot.blocks; using dnlib.DotNet; +using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Collections.Generic; +using System.Linq; namespace NETReactorSlayer.Core.Stages { @@ -28,6 +31,7 @@ internal class ResourceResolver : IStage public void Run(IContext context) { Context = context; + try { if (!Find()) @@ -38,15 +42,7 @@ public void Run(IContext context) using (_encryptedResource) { - DeobUtils.DecryptAndAddResources(Context.Module, - () => Decompress(_encryptedResource.Decrypt())); - - foreach (var methodToRemove in _methodToRemove) - Cleaner.AddCallToBeRemoved(methodToRemove.ResolveMethodDef()); - Cleaner.AddCallToBeRemoved(_encryptedResource.DecrypterMethod); - Cleaner.AddTypeToBeRemoved(_encryptedResource.DecrypterMethod.DeclaringType); - Cleaner.AddResourceToBeRemoved(_encryptedResource.EmbeddedResource); - Context.Logger.Info("Assembly resources decrypted"); + ProcessEncryptedResource(); } } catch (Exception ex) @@ -55,26 +51,115 @@ public void Run(IContext context) } } + /// + /// Processes encrypted resources. Handles VM (Code Virtualization) environments safely. + /// + private void ProcessEncryptedResource() + { + try + { + // Decrypt and decompress the resource + var rawDecrypted = _encryptedResource.Decrypt(); + if (rawDecrypted == null) + { + Context.Logger.Warn("Resource decryption returned null data."); + return; + } + var decompressedData = TryDecompress(rawDecrypted) ?? rawDecrypted; + + // Verify and process if it's valid .NET resource data + if (IsValidResourceData(decompressedData)) + { + DeobUtils.DecryptAndAddResources(Context.Module, () => decompressedData); + Context.Logger.Info("Assembly resources decrypted"); + } + else + { + Context.Logger.Info("[ResourceResolver] VM/Non-standard resource data detected - skipping normal processing"); + } + CleanupObfuscatorArtifacts(); + } + catch (Exception ex) + { + // Resource processing failure may be normal in VM environments + if (IsVMRelatedError(ex)) + { + Context.Logger.Warn($"Resource processing failed (VM environment): {ex.Message}"); + CleanupObfuscatorArtifacts(); + } + else throw; + } + } + + /// + /// Attempts to decompress data using various methods. + /// + private static byte[] TryDecompress(byte[] data) + { + // Try decompression in order: QuickLZ, Deflate (with/without header), then offset attempts + try { return QuickLz.Decompress(data); } catch { } + try { return DeobUtils.Inflate(data, false); } catch { } + try { return DeobUtils.Inflate(data, true); } catch { } + + // Common pattern in VM: Try decompression from different starting points + // Sometimes offset 9 works. Surely it's not because it's .NET 9, right? + for (int offset = 1; offset < Math.Min(data.Length, 20); offset++) + { + try { return DeobUtils.Inflate(data.Skip(offset).ToArray(), true); } catch { } + } + return null; + } + + /// + /// Checks if the data is valid .NET assembly resource data. + /// + private static bool IsValidResourceData(byte[] data) => + data != null && data.Length >= 64 && + ((data.Length > 2 && data[0] == 0x4D && data[1] == 0x5A) || data.Length >= 1000); + + /// + /// Checks if the exception is VM-related. + /// + private static bool IsVMRelatedError(Exception ex) => + ex.Message.Contains("Invalid DOS signature") || + ex.Message.Contains("decryptedResourceData is null") || + ex.Message.Contains("Not a valid PE file") || + ex is BadImageFormatException; + + /// + /// Cleans up obfuscation-related artifacts. + /// + private void CleanupObfuscatorArtifacts() + { + try + { + _methodToRemove.ForEach(method => Cleaner.AddCallToBeRemoved(method.ResolveMethodDef())); + Cleaner.AddCallToBeRemoved(_encryptedResource.DecrypterMethod); + Cleaner.AddTypeToBeRemoved(_encryptedResource.DecrypterMethod.DeclaringType); + Cleaner.AddResourceToBeRemoved(_encryptedResource.EmbeddedResource); + } + catch (Exception ex) + { + Context.Logger.Warn($"Cleanup failed: {ex.Message}"); + } + } + private bool Find() { foreach (var type in Context.Module.GetTypes()) { - if (type.BaseType != null && type.BaseType.FullName != "System.Object") - continue; - if (!CheckFields(type.Fields)) + if (type.BaseType?.FullName != "System.Object" || !CheckFields(type.Fields)) continue; + foreach (var decrypterMethod in from method in type.Methods - where method.IsStatic && method.HasBody - where DotNetUtils.IsMethod(method, "System.Reflection.Assembly", - "(System.Object,System.ResolveEventArgs)") || - DotNetUtils.IsMethod(method, "System.Reflection.Assembly", - "(System.Object,System.Object)") - where method.Body.ExceptionHandlers.Count == 0 - select GetDecrypterMethod(method, Array.Empty(), true) ?? - GetDecrypterMethod(method, Array.Empty(), false) + where method.IsStatic && method.HasBody && method.Body.ExceptionHandlers.Count == 0 + where DotNetUtils.IsMethod(method, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)") || + DotNetUtils.IsMethod(method, "System.Reflection.Assembly", "(System.Object,System.Object)") + select GetDecrypterMethod(method, Array.Empty(), true) ?? + GetDecrypterMethod(method, Array.Empty(), false) into decrypterMethod - where decrypterMethod != null - select decrypterMethod) + where decrypterMethod != null + select decrypterMethod) { _encryptedResource = new EncryptedResource(Context, decrypterMethod); if (_encryptedResource.EmbeddedResource == null) @@ -87,52 +172,33 @@ into decrypterMethod return true; } } - return false; } private static bool CheckFields(ICollection fields) { - if (fields.Count != 3 && fields.Count != 4) - return false; - - var numBools = fields.Count == 3 ? 1 : 2; + if (fields.Count != 3 && fields.Count != 4) return false; var fieldTypes = new FieldTypes(fields); - if (fieldTypes.Count("System.Boolean") != numBools) - return false; - if (fieldTypes.Count("System.Object") == 2) - return true; - if (fieldTypes.Count("System.String[]") != 1) - return false; - return fieldTypes.Count("System.Reflection.Assembly") == 1 || fieldTypes.Count("System.Object") == 1; - } + var numBools = fields.Count == 3 ? 1 : 2; - private MethodDef - GetDecrypterMethod(MethodDef method, IList additionalTypes, bool checkResource) - { - if (EncryptedResource.IsKnownDecrypter(method, additionalTypes, checkResource)) - return method; + return fieldTypes.Count("System.Boolean") == numBools && + (fieldTypes.Count("System.Object") == 2 || + (fieldTypes.Count("System.String[]") == 1 && + (fieldTypes.Count("System.Reflection.Assembly") == 1 || fieldTypes.Count("System.Object") == 1))); + } - return DotNetUtils.GetCalledMethods(Context.Module, method) + private MethodDef GetDecrypterMethod(MethodDef method, IList additionalTypes, bool checkResource) => + EncryptedResource.IsKnownDecrypter(method, additionalTypes, checkResource) ? method : + DotNetUtils.GetCalledMethods(Context.Module, method) .Where(calledMethod => DotNetUtils.IsMethod(calledMethod, "System.Void", "()")) - .FirstOrDefault(calledMethod => - EncryptedResource.IsKnownDecrypter(calledMethod, additionalTypes, checkResource)); - } + .FirstOrDefault(calledMethod => EncryptedResource.IsKnownDecrypter(calledMethod, additionalTypes, checkResource)); private static byte[] Decompress(byte[] bytes) { try { return QuickLz.Decompress(bytes); } - catch - { - try { return DeobUtils.BrotliDecompress(bytes); } - catch { - try { return DeobUtils.Inflate(bytes, true); } - catch { return null; } - } - } + catch { try { return DeobUtils.Inflate(bytes, true); } catch { return null; } } } - private IContext Context { get; set; } private EncryptedResource _encryptedResource; private readonly List _methodToRemove = new(); diff --git a/NETReactorSlayer.Core/Stages/StringDecrypter.cs b/NETReactorSlayer.Core/Stages/StringDecrypter.cs index 92f1271..cff1e81 100644 --- a/NETReactorSlayer.Core/Stages/StringDecrypter.cs +++ b/NETReactorSlayer.Core/Stages/StringDecrypter.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,24 +13,33 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Reflection; -using System.Text; + + + + using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using HarmonyLib; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; using Code = dnlib.DotNet.Emit.Code; +using OpCodes = dnlib.DotNet.Emit.OpCodes; namespace NETReactorSlayer.Core.Stages { internal class StringDecrypter : IStage { + public void Run(IContext context) { Context = context; @@ -78,10 +87,10 @@ private bool Find() if (type.BaseType != null && type.BaseType.FullName != "System.Object") continue; foreach (var method in from method in type.Methods - where method.IsStatic && method.HasBody - where DotNetUtils.IsMethod(method, "System.String", "(System.Int32)") - where EncryptedResource.IsKnownDecrypter(method, new[] { "System.String" }, true) - select method) + where method.IsStatic && method.HasBody + where DotNetUtils.IsMethod(method, "System.String", "(System.Int32)") + where EncryptedResource.IsKnownDecrypter(method, new[] { "System.String" }, true) + select method) { FindKeyIv(method); @@ -123,11 +132,11 @@ private void FindKeyIv(MethodDef method) "System.Security.Cryptography.CryptoStream" }; foreach (var instructions in from calledMethod in DotNetUtils.GetCalledMethods(Context.Module, method) - where calledMethod.DeclaringType == method.DeclaringType - where calledMethod.MethodSig.GetRetType().GetFullName() == "System.Byte[]" - let localTypes = new LocalTypes(calledMethod) - where localTypes.All(requiredTypes) - select calledMethod.Body.Instructions) + where calledMethod.DeclaringType == method.DeclaringType + where calledMethod.MethodSig.GetRetType().GetFullName() == "System.Byte[]" + let localTypes = new LocalTypes(calledMethod) + where localTypes.All(requiredTypes) + select calledMethod.Body.Instructions) { byte[] newKey = null, newIv = null; for (var i = 0; i < instructions.Count && (newKey == null || newIv == null); i++) @@ -175,20 +184,20 @@ private string Decrypt(int offset) switch (_stringDecrypterVersion) { case StringDecrypterVersion.V37: - { - var fileOffset = BitConverter.ToInt32(_decryptedResource, offset); - var length = BitConverter.ToInt32(Context.ModuleBytes, fileOffset); - encryptedStringData = new byte[length]; - Array.Copy(Context.ModuleBytes, fileOffset + 4, encryptedStringData, 0, length); - break; - } + { + var fileOffset = BitConverter.ToInt32(_decryptedResource, offset); + var length = BitConverter.ToInt32(Context.ModuleBytes, fileOffset); + encryptedStringData = new byte[length]; + Array.Copy(Context.ModuleBytes, fileOffset + 4, encryptedStringData, 0, length); + break; + } case StringDecrypterVersion.V38: - { - var rva = BitConverter.ToUInt32(_decryptedResource, offset); - var length = Context.PeImage.ReadInt32(rva); - encryptedStringData = Context.PeImage.ReadBytes(rva + 4, length); - break; - } + { + var rva = BitConverter.ToUInt32(_decryptedResource, offset); + var length = Context.PeImage.ReadInt32(rva); + encryptedStringData = Context.PeImage.ReadBytes(rva + 4, length); + break; + } default: throw new ApplicationException("Unknown string decrypter version"); } @@ -240,81 +249,153 @@ bool IsDecrypterMethod(IMDTokenProvider method) => method != null && return count; } + // https://www.cnblogs.com/Fred1987/p/18603592 + //copy from,https://gist.github.com/6rube/34b561827f0805f73742541b8b8bb770 + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); + + + /// + /// Dynamically decrypts string literals at runtime + /// Decrypts strings encrypted by .NET Reactor and restores them to their original form during runtime. + /// + /// The number of successfully decrypted strings private long InlineStringsDynamically() { + // Skip dynamic decryption under certain conditions + // Skip if NativeStub + NecroBit combination is used, or if reflection is not used if ((Context.Info.NativeStub && Context.Info.NecroBit) || !Context.Info.UsesReflection) return 0; - long count = 0; - MethodDef decrypterMethod = null; - EmbeddedResource encryptedResource = null; + try + { + // Execute the module constructor of the target assembly to perform static initialization + // This process initializes the data required for string decryption + RuntimeHelpers.RunModuleConstructor(Context.Assembly.ManifestModule.ModuleHandle); + } + catch (Exception exc) + { + Console.WriteLine($"Exception on ModuleConstructor: {exc}"); + } - StacktracePatcher.Patch(); + long count = 0; // Number of successfully decrypted strings + MethodDef decrypterMethod = null; // Decrypter method info (for later removal) + EmbeddedResource encryptedResource = null; // Encrypted resource info (for later removal) + bool FirstTime = true; // Flag to print only the first exception + + try + { + // Apply Harmony patch: Intercept StackFrame.GetMethod() calls + // This allows bypassing .NET Reactor's caller verification + StacktracePatcher.Patch(); + } + catch (Exception exc) + { + Console.WriteLine($"Exception on StringDec - Harmony: {exc}"); + } + + // Iterate through all types and methods to find string decryption patterns foreach (var type in Context.Module.GetTypes()) - foreach (var method in (from x in type.Methods where x.HasBody && x.Body.HasInstructions select x) - .ToArray()) - for (var i = 0; i < method.Body.Instructions.Count; i++) - try - { - if (!method.Body.Instructions[i].IsLdcI4() || - !method.Body.Instructions[i + 1].OpCode.Equals(OpCodes.Call)) - continue; + foreach (var method in (from x in type.Methods where x.HasBody && x.Body.HasInstructions select x).ToArray()) + for (var i = 0; i < method.Body.Instructions.Count; i++) + try + { + // Detect string decryption pattern: ldc.i4 (load integer) + call (method call) + // Example: ldc.i4 838 (string index) + call GQb61Dp8v (decryption method) + if (!method.Body.Instructions[i].IsLdcI4() || + !method.Body.Instructions[i + 1].OpCode.Equals(OpCodes.Call)) + continue; - var methodDef = ((IMethod)method.Body.Instructions[i + 1].Operand).ResolveMethodDef(); - if (methodDef is not {HasReturnType: true}) - continue; + // Extract information about the called method + var methodDef = ((IMethod)method.Body.Instructions[i + 1].Operand).ResolveMethodDef(); + if (methodDef == null) continue; - if (TypeEqualityComparer.Instance.Equals(method.DeclaringType, methodDef.DeclaringType)) - continue; + // Check if the method has a return type (string decryption methods must return string) + if (!methodDef.HasReturnType) + continue; - if (methodDef.ReturnType.FullName != "System.String" && - !(methodDef.DeclaringType != null && - methodDef.DeclaringType == type && - methodDef.ReturnType.FullName == "System.Object")) - continue; + // Exclude method calls within the same class (prevent self-invocation) + if (TypeEqualityComparer.Instance.Equals(method.DeclaringType, methodDef.DeclaringType)) + continue; - if (!methodDef.HasParams() || methodDef.Parameters.Count != 1 || - methodDef.Parameters[0].Type.FullName != "System.Int32") - continue; + // Validate return type: Must be System.String or System.Object under specific conditions + if (methodDef.ReturnType.FullName != "System.String" && + !(methodDef.DeclaringType != null && + methodDef.DeclaringType == type && + methodDef.ReturnType.FullName == "System.Object")) + continue; - if (!methodDef.Body.Instructions.Any(x => - x.OpCode.Equals(OpCodes.Callvirt) && x.Operand.ToString()! - .Contains("System.Reflection.Assembly::GetManifestResourceStream"))) - continue; + // Parameter validation: Must accept exactly one int parameter + // String decryption methods typically have the signature: string DecryptString(int index) + if (!methodDef.HasParams() || methodDef.Parameters.Count != 1 || + methodDef.Parameters[0].Type.FullName != "System.Int32") + continue; - var resourceName = DotNetUtils.GetCodeStrings(methodDef) - .FirstOrDefault(name => - Context.Assembly.GetManifestResourceNames().Any(x => x == name)); + // Check if the method internally calls GetManifestResourceStream + // .NET Reactor stores encrypted string data in resources + if (!methodDef.Body.Instructions.Any(x => + x.OpCode.Equals(OpCodes.Callvirt) && x.Operand.ToString()! + .Contains("System.Reflection.Assembly::GetManifestResourceStream"))) + continue; - if (resourceName == null) - continue; + // Extract the resource name used within the method + var resourceName = DotNetUtils.GetCodeStrings(methodDef) + .FirstOrDefault(name => + Context.Assembly.GetManifestResourceNames().Any(x => x == name)); - var result = (StacktracePatcher.PatchStackTraceGetMethod.MethodToReplace = - Context.Assembly.ManifestModule.ResolveMethod( - (int)methodDef.ResolveMethodDef().MDToken.Raw) as MethodInfo) - .Invoke(null, new object[] { method.Body.Instructions[i].GetLdcI4Value() }); + if (resourceName == null) + continue; - if (result is not string operand) - continue; - decrypterMethod ??= methodDef; - if (encryptedResource == null && - DotNetUtils.GetResource(Context.Module, resourceName) is EmbeddedResource resource) - encryptedResource = resource; - method.Body.Instructions[i].OpCode = OpCodes.Nop; - method.Body.Instructions[i + 1].OpCode = OpCodes.Ldstr; - method.Body.Instructions[i + 1].Operand = operand; - count += 1L; - } - catch { } + // Perform actual string decryption + // 1. Resolve the decryption method using reflection + var resolvedMethod = Context.Assembly.ManifestModule.ResolveMethod( + (int)methodDef.ResolveMethodDef().MDToken.Raw) as MethodInfo; - if (decrypterMethod == null || encryptedResource == null) - return count; - Cleaner.AddMethodToBeRemoved(decrypterMethod); - Cleaner.AddResourceToBeRemoved(encryptedResource); + // 2. Set MethodToReplace for Harmony patching + // This ensures that when StackFrame.GetMethod() is called within the decryption method, + // our specified method is returned, bypassing caller verification + StacktracePatcher.PatchStackTraceGetMethod.MethodToReplace = resolvedMethod; - return count; + // 3. Invoke the decryption method (pass string index as parameter) + var result = resolvedMethod.Invoke(null, new object[] { method.Body.Instructions[i].GetLdcI4Value() }); + + // 4. Verify that the result is a string + if (result is not string operand) + continue; + + // 5. Store information for cleanup (for later removal of decryption method and resources) + decrypterMethod ??= methodDef; + if (encryptedResource == null && + DotNetUtils.GetResource(Context.Module, resourceName) is EmbeddedResource resource) + encryptedResource = resource; + + // 6. Replace IL code: Change complex decryption calls to simple string loads + // Example: ldc.i4 838 + call GQb61Dp8v ¡æ nop + ldstr "decrypted string" + method.Body.Instructions[i].OpCode = OpCodes.Nop; // Remove index load + method.Body.Instructions[i + 1].OpCode = OpCodes.Ldstr; // Direct string load + method.Body.Instructions[i + 1].Operand = operand; // Set decrypted string + + count++; // Increment success counter + } + catch (Exception exc) + { + // Print only the first exception to prevent log spam + if (FirstTime) + { + Console.WriteLine($"Exception on StringDec: {exc}"); + FirstTime = false; + } + } + + // Cleanup: Add decryption-related code that is no longer needed to removal targets + if (decrypterMethod != null) + Cleaner.AddMethodToBeRemoved(decrypterMethod); + if (encryptedResource != null) + Cleaner.AddResourceToBeRemoved(encryptedResource); + + return count; // Return the number of successfully decrypted strings } @@ -327,32 +408,77 @@ private long InlineStringsDynamically() private enum StringDecrypterVersion { V37, V38 } #region Nested Types - public class StacktracePatcher { public static void Patch() { - harmony = new Harmony(HarmonyId); - harmony.PatchAll(Assembly.GetExecutingAssembly()); + try + { + if (harmony != null) + { + Console.WriteLine("Harmony already patched"); + return; + } + harmony = new Harmony(HarmonyId); + // Use PatchAll to apply annotation-based patches + harmony.PatchAll(Assembly.GetExecutingAssembly()); + Console.WriteLine($"PatchAll completed. Patched methods: {harmony.GetPatchedMethods().Count()}"); + + // Verify patch application + var stackFrameGetMethod = typeof(StackFrame).GetMethod("GetMethod", Type.EmptyTypes); + var patchInfo = Harmony.GetPatchInfo(stackFrameGetMethod); + if (patchInfo != null) + { + Console.WriteLine($"StackFrame.GetMethod patches - Prefixes: {patchInfo.Prefixes.Count}, Postfixes: {patchInfo.Postfixes.Count}"); + } + else + { + Console.WriteLine("ERROR: StackFrame.GetMethod is NOT patched!"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Patch Exception: {ex}"); + } } - private const string HarmonyId = "_"; - - // ReSharper disable once InconsistentNaming + private const string HarmonyId = "netreactorslayer.stringdecrypter"; private static Harmony harmony; + /// + /// Intercepts StackFrame.GetMethod() calls to bypass .NET Reactor's caller verification + /// [HarmonyPatch(typeof(StackFrame), "GetMethod")] public class PatchStackTraceGetMethod { - // ReSharper disable once UnusedMember.Global - // ReSharper disable once InconsistentNaming public static void Postfix(ref MethodBase __result) { - if (__result.DeclaringType != typeof(RuntimeMethodHandle)) + //Console.WriteLine($"[POSTFIX] Original result: {__result?.Name}"); + //Console.WriteLine($"[POSTFIX] DeclaringType: {__result?.DeclaringType?.Name ?? "null"}"); + + // More comprehensive conditions (considering modern .NET environments) + bool shouldReplace = + __result?.DeclaringType == typeof(RuntimeMethodHandle) || // Original condition + __result?.Name?.StartsWith("InvokeStub_") == true || // .NET Core/5+ pattern + (__result?.DeclaringType == null && MethodToReplace != null); // Handle null DeclaringType + + if (!shouldReplace) + { + //Console.WriteLine($"[POSTFIX] No replacement needed"); return; - __result = MethodToReplace ?? MethodBase.GetCurrentMethod(); + } + + if (MethodToReplace != null) + { + //Console.WriteLine($"[POSTFIX] Replacing {__result?.Name} with {MethodToReplace.Name}"); + __result = MethodToReplace; + } } + /// + /// The method that will replace the original method in StackFrame.GetMethod() calls + /// This is used to trick .NET Reactor into thinking the call is coming from an authorized method + /// public static MethodInfo MethodToReplace; } } diff --git a/NETReactorSlayer.Core/Stages/StrongNamePatcher.cs b/NETReactorSlayer.Core/Stages/StrongNamePatcher.cs index b64abf8..0fa17a4 100644 --- a/NETReactorSlayer.Core/Stages/StrongNamePatcher.cs +++ b/NETReactorSlayer.Core/Stages/StrongNamePatcher.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,12 +13,12 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; using NETReactorSlayer.Core.Helper; +using System.Linq; namespace NETReactorSlayer.Core.Stages { @@ -69,22 +69,22 @@ public void Run(IContext context) private MethodDef Find() => (from type in Context.Module.GetTypes() - from method in type.Methods - where method.IsStatic && method.Body != null - let sig = method.MethodSig - where sig != null && sig.Params.Count == 2 - where sig.RetType.ElementType is ElementType.Object or ElementType.String - where sig.Params[0]?.ElementType is ElementType.Object or ElementType.String - where sig.Params[1]?.ElementType is ElementType.Object or ElementType.String - select method).FirstOrDefault(method => new LocalTypes(method).All(new[] - { + from method in type.Methods + where method.IsStatic && method.Body != null + let sig = method.MethodSig + where sig != null && sig.Params.Count == 2 + where sig.RetType.ElementType is ElementType.Object or ElementType.String + where sig.Params[0]?.ElementType is ElementType.Object or ElementType.String + where sig.Params[1]?.ElementType is ElementType.Object or ElementType.String + select method).FirstOrDefault(method => new LocalTypes(method).All(new[] + { "System.Byte[]", "System.IO.MemoryStream", "System.Security.Cryptography.CryptoStream", "System.Security.Cryptography.MD5", "System.Security.Cryptography.Rijndael" }) || new LocalTypes(method).All(new[] - { + { "System.Byte[]", "System.IO.MemoryStream", "System.Security.Cryptography.SymmetricAlgorithm", @@ -93,55 +93,55 @@ where sig.Params[1]?.ElementType is ElementType.Object or ElementType.String private static Block GetBlock(Blocks blocks, IMethod methodDef) => (from block in blocks.MethodBlocks.GetAllBlocks() - where block.LastInstr.IsBrfalse() - let instructions = block.Instructions - where instructions.Count >= 11 - let i = instructions.Count - 11 - where instructions[i].OpCode.Code == Code.Ldtoken - where instructions[i].Operand is ITypeDefOrRef - where instructions[i + 1].OpCode.Code == Code.Call || - (instructions[i + 1].OpCode.Code == Code.Callvirt && - instructions[i + 1].Operand is IMethod - { - FullName: "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)" - }) - where instructions[i + 2].OpCode.Code == Code.Call || - (instructions[i + 2].OpCode.Code == Code.Callvirt && - instructions[i + 2].Operand is IMethod - { - FullName: "System.Reflection.Assembly System.Type::get_Assembly()" - }) - where instructions[i + 3].OpCode.Code == Code.Call || - (instructions[i + 3].OpCode.Code == Code.Callvirt && - instructions[i + 3].Operand is IMethod - { - FullName: "System.Reflection.AssemblyName System.Reflection.Assembly::GetName()" - }) - where instructions[i + 4].OpCode.Code == Code.Call || - (instructions[i + 4].OpCode.Code == Code.Callvirt && - instructions[i + 4].Operand is IMethod - { - FullName: "System.Byte[] System.Reflection.AssemblyName::GetPublicKeyToken()" - }) - where instructions[i + 5].OpCode.Code == Code.Call || - (instructions[i + 5].OpCode.Code == Code.Callvirt && - instructions[i + 5].Operand is IMethod - { - FullName: "System.String System.Convert::ToBase64String(System.Byte[])" - }) - where instructions[i + 6].OpCode.Code == Code.Ldstr - where instructions[i + 7].OpCode.Code == Code.Call || - (instructions[i + 7].OpCode.Code == Code.Callvirt && - instructions[i + 7].Operand is IMethod calledMethod && - MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod, methodDef)) - where instructions[i + 8].OpCode.Code == Code.Ldstr - where instructions[i + 9].OpCode.Code == Code.Call || - (instructions[i + 9].OpCode.Code == Code.Callvirt && - instructions[i + 9].Operand is IMethod - { - FullName: "System.Boolean System.String::op_Inequality(System.String,System.String)" - }) - select block).FirstOrDefault(); + where block.LastInstr.IsBrfalse() + let instructions = block.Instructions + where instructions.Count >= 11 + let i = instructions.Count - 11 + where instructions[i].OpCode.Code == Code.Ldtoken + where instructions[i].Operand is ITypeDefOrRef + where instructions[i + 1].OpCode.Code == Code.Call || + (instructions[i + 1].OpCode.Code == Code.Callvirt && + instructions[i + 1].Operand is IMethod + { + FullName: "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)" + }) + where instructions[i + 2].OpCode.Code == Code.Call || + (instructions[i + 2].OpCode.Code == Code.Callvirt && + instructions[i + 2].Operand is IMethod + { + FullName: "System.Reflection.Assembly System.Type::get_Assembly()" + }) + where instructions[i + 3].OpCode.Code == Code.Call || + (instructions[i + 3].OpCode.Code == Code.Callvirt && + instructions[i + 3].Operand is IMethod + { + FullName: "System.Reflection.AssemblyName System.Reflection.Assembly::GetName()" + }) + where instructions[i + 4].OpCode.Code == Code.Call || + (instructions[i + 4].OpCode.Code == Code.Callvirt && + instructions[i + 4].Operand is IMethod + { + FullName: "System.Byte[] System.Reflection.AssemblyName::GetPublicKeyToken()" + }) + where instructions[i + 5].OpCode.Code == Code.Call || + (instructions[i + 5].OpCode.Code == Code.Callvirt && + instructions[i + 5].Operand is IMethod + { + FullName: "System.String System.Convert::ToBase64String(System.Byte[])" + }) + where instructions[i + 6].OpCode.Code == Code.Ldstr + where instructions[i + 7].OpCode.Code == Code.Call || + (instructions[i + 7].OpCode.Code == Code.Callvirt && + instructions[i + 7].Operand is IMethod calledMethod && + MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod, methodDef)) + where instructions[i + 8].OpCode.Code == Code.Ldstr + where instructions[i + 9].OpCode.Code == Code.Call || + (instructions[i + 9].OpCode.Code == Code.Callvirt && + instructions[i + 9].Operand is IMethod + { + FullName: "System.Boolean System.String::op_Inequality(System.String,System.String)" + }) + select block).FirstOrDefault(); private IContext Context { get; set; } diff --git a/NETReactorSlayer.Core/Stages/SymbolRenamer.cs b/NETReactorSlayer.Core/Stages/SymbolRenamer.cs index f80cd20..e861ca9 100644 --- a/NETReactorSlayer.Core/Stages/SymbolRenamer.cs +++ b/NETReactorSlayer.Core/Stages/SymbolRenamer.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.Core/Stages/TokenDeobfuscator.cs b/NETReactorSlayer.Core/Stages/TokenDeobfuscator.cs index 664d315..9178ed5 100644 --- a/NETReactorSlayer.Core/Stages/TokenDeobfuscator.cs +++ b/NETReactorSlayer.Core/Stages/TokenDeobfuscator.cs @@ -13,11 +13,11 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.Core.Abstractions; +using System.Linq; namespace NETReactorSlayer.Core.Stages { @@ -31,8 +31,8 @@ public void Run(IContext context) long count = 0; foreach (var type in from type in context.Module.GetTypes() .Where(x => !x.HasProperties && !x.HasEvents && x.Fields.Count != 0) - from _ in type.Fields.Where(x => x.FieldType.FullName.Equals("System.ModuleHandle")) - select type) + from _ in type.Fields.Where(x => x.FieldType.FullName.Equals("System.ModuleHandle")) + select type) { foreach (var method in type.Methods.Where(x => x.MethodSig != null && x.MethodSig.Params.Count.Equals(1) && @@ -48,39 +48,39 @@ from _ in type.Fields.Where(x => x.FieldType.FullName.Equals("System.ModuleHandl goto Continue; } - Continue: + Continue: if (typeDef != null) foreach (var type in context.Module.GetTypes()) - foreach (var method in type.Methods.Where(x => x.HasBody && x.Body.HasInstructions)) - { - var gpContext = GenericParamContext.Create(method); - var blocks = new Blocks(method); - foreach (var block in blocks.MethodBlocks.GetAllBlocks()) - for (var i = 0; i < block.Instructions.Count; i++) - try - { - if (!block.Instructions[i].OpCode.Code.Equals(Code.Ldc_I4) || - block.Instructions[i + 1].OpCode.Code != Code.Call) - continue; - if (block.Instructions[i + 1].Operand is not IMethod iMethod || - !default(SigComparer).Equals(typeDef, iMethod.DeclaringType)) - continue; - var methodDef = DotNetUtils.GetMethod(context.Module, iMethod); - if (methodDef == null) - continue; - if (methodDef != typeMethod && methodDef != fieldMethod) - continue; - var token = (uint)(int)block.Instructions[i].Operand; - block.Instructions[i] = new Instr(OpCodes.Nop.ToInstruction()); - block.Instructions[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, - context.Module.ResolveToken(token, gpContext) as ITokenOperand)); - count++; - } - catch { } + foreach (var method in type.Methods.Where(x => x.HasBody && x.Body.HasInstructions)) + { + var gpContext = GenericParamContext.Create(method); + var blocks = new Blocks(method); + foreach (var block in blocks.MethodBlocks.GetAllBlocks()) + for (var i = 0; i < block.Instructions.Count; i++) + try + { + if (!block.Instructions[i].OpCode.Code.Equals(Code.Ldc_I4) || + block.Instructions[i + 1].OpCode.Code != Code.Call) + continue; + if (block.Instructions[i + 1].Operand is not IMethod iMethod || + !default(SigComparer).Equals(typeDef, iMethod.DeclaringType)) + continue; + var methodDef = DotNetUtils.GetMethod(context.Module, iMethod); + if (methodDef == null) + continue; + if (methodDef != typeMethod && methodDef != fieldMethod) + continue; + var token = (uint)(int)block.Instructions[i].Operand; + block.Instructions[i] = new Instr(OpCodes.Nop.ToInstruction()); + block.Instructions[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, + context.Module.ResolveToken(token, gpContext) as ITokenOperand)); + count++; + } + catch { } - blocks.GetCode(out var allInstructions, out var allExceptionHandlers); - DotNetUtils.RestoreBody(method, allInstructions, allExceptionHandlers); - } + blocks.GetCode(out var allInstructions, out var allExceptionHandlers); + DotNetUtils.RestoreBody(method, allInstructions, allExceptionHandlers); + } if (count == 0) diff --git a/NETReactorSlayer.Core/Stages/TypeRestorer.cs b/NETReactorSlayer.Core/Stages/TypeRestorer.cs index ba77d3c..8e33f8a 100644 --- a/NETReactorSlayer.Core/Stages/TypeRestorer.cs +++ b/NETReactorSlayer.Core/Stages/TypeRestorer.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.De4dot/Deobfuscator.cs b/NETReactorSlayer.De4dot/Deobfuscator.cs index 0280c6e..f4f538c 100644 --- a/NETReactorSlayer.De4dot/Deobfuscator.cs +++ b/NETReactorSlayer.De4dot/Deobfuscator.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Text.RegularExpressions; using dnlib.DotNet; +using System.Text.RegularExpressions; namespace NETReactorSlayer.De4dot { diff --git a/NETReactorSlayer.De4dot/DeobfuscatorBase.cs b/NETReactorSlayer.De4dot/DeobfuscatorBase.cs index 889a447..4c5b03b 100644 --- a/NETReactorSlayer.De4dot/DeobfuscatorBase.cs +++ b/NETReactorSlayer.De4dot/DeobfuscatorBase.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System; using System.Linq; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot { diff --git a/NETReactorSlayer.De4dot/IDeobfuscator.cs b/NETReactorSlayer.De4dot/IDeobfuscator.cs index bfe3176..1069e10 100644 --- a/NETReactorSlayer.De4dot/IDeobfuscator.cs +++ b/NETReactorSlayer.De4dot/IDeobfuscator.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; using NETReactorSlayer.De4dot.Renamer; +using System; namespace NETReactorSlayer.De4dot { diff --git a/NETReactorSlayer.De4dot/IObfuscatedFile.cs b/NETReactorSlayer.De4dot/IObfuscatedFile.cs index 6ff3120..d7471ff 100644 --- a/NETReactorSlayer.De4dot/IObfuscatedFile.cs +++ b/NETReactorSlayer.De4dot/IObfuscatedFile.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; using dnlib.DotNet; using NETReactorSlayer.De4dot.Renamer; +using System; namespace NETReactorSlayer.De4dot { diff --git a/NETReactorSlayer.De4dot/MethodStack.cs b/NETReactorSlayer.De4dot/MethodStack.cs index 5d94712..627a188 100644 --- a/NETReactorSlayer.De4dot/MethodStack.cs +++ b/NETReactorSlayer.De4dot/MethodStack.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,11 +13,11 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; +using System; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot { diff --git a/NETReactorSlayer.De4dot/NETReactorSlayer.De4dot.csproj b/NETReactorSlayer.De4dot/NETReactorSlayer.De4dot.csproj index 8d5075c..68e90fa 100644 --- a/NETReactorSlayer.De4dot/NETReactorSlayer.De4dot.csproj +++ b/NETReactorSlayer.De4dot/NETReactorSlayer.De4dot.csproj @@ -1,4 +1,4 @@ - + @@ -6,6 +6,8 @@ ..\bin\$(Configuration)\ Library + AnyCPU + net48;net7.0;net9.0 @@ -17,7 +19,7 @@ ..\Libs\netcoreapp3.1\de4dot.blocks.dll - + diff --git a/NETReactorSlayer.De4dot/PushedArgs.cs b/NETReactorSlayer.De4dot/PushedArgs.cs index db06588..8f7a24e 100644 --- a/NETReactorSlayer.De4dot/PushedArgs.cs +++ b/NETReactorSlayer.De4dot/PushedArgs.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using dnlib.DotNet.Emit; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot { diff --git a/NETReactorSlayer.De4dot/RandomNameChecker.cs b/NETReactorSlayer.De4dot/RandomNameChecker.cs index 4c7bbe0..c5a9226 100644 --- a/NETReactorSlayer.De4dot/RandomNameChecker.cs +++ b/NETReactorSlayer.De4dot/RandomNameChecker.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/EventDefDict.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/EventDefDict.cs index 1d84b1d..c451689 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/EventDefDict.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/EventDefDict.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using de4dot.blocks; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/FieldDefDict.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/FieldDefDict.cs index eee0ccc..d569fbd 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/FieldDefDict.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/FieldDefDict.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using de4dot.blocks; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/InterfaceMethodInfos.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/InterfaceMethodInfos.cs index d8cf4e5..7fe5635 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/InterfaceMethodInfos.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/InterfaceMethodInfos.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System; using System.Collections.Generic; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/MEventDef.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/MEventDef.cs index 77ad17a..6fe75b9 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/MEventDef.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/MEventDef.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System.Collections.Generic; using System.Linq; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/MGenericParamDef.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/MGenericParamDef.cs index 82342f1..934ce2a 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/MGenericParamDef.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/MGenericParamDef.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System.Collections.Generic; using System.Linq; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/MMethodDef.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/MMethodDef.cs index 3db2db4..ca0fd67 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/MMethodDef.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/MMethodDef.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using dnlib.DotNet; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/MPropertyDef.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/MPropertyDef.cs index 917af96..9403415 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/MPropertyDef.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/MPropertyDef.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System.Collections.Generic; using System.Linq; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/MTypeDef.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/MTypeDef.cs index 1c68bb4..770a52d 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/MTypeDef.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/MTypeDef.cs @@ -13,11 +13,11 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using de4dot.blocks; +using dnlib.DotNet; using System; using System.Collections.Generic; using System.Linq; -using de4dot.blocks; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { @@ -104,32 +104,32 @@ public void AddMembers() Add(new MPropertyDef(type.Properties[i], this, i)); foreach (var propDef in _properties.GetValues()) - foreach (var method in propDef.MethodDefs()) - { - var methodDef = FindMethod(method); - if (methodDef == null) - throw new ApplicationException("Could not find property method"); - methodDef.Property = propDef; - if (method == propDef.PropertyDef.GetMethod) - propDef.GetMethod = methodDef; - if (method == propDef.PropertyDef.SetMethod) - propDef.SetMethod = methodDef; - } + foreach (var method in propDef.MethodDefs()) + { + var methodDef = FindMethod(method); + if (methodDef == null) + throw new ApplicationException("Could not find property method"); + methodDef.Property = propDef; + if (method == propDef.PropertyDef.GetMethod) + propDef.GetMethod = methodDef; + if (method == propDef.PropertyDef.SetMethod) + propDef.SetMethod = methodDef; + } foreach (var eventDef in _events.GetValues()) - foreach (var method in eventDef.MethodDefs()) - { - var methodDef = FindMethod(method); - if (methodDef == null) - throw new ApplicationException("Could not find event method"); - methodDef.Event = eventDef; - if (method == eventDef.EventDef.AddMethod) - eventDef.AddMethod = methodDef; - if (method == eventDef.EventDef.RemoveMethod) - eventDef.RemoveMethod = methodDef; - if (method == eventDef.EventDef.InvokeMethod) - eventDef.RaiseMethod = methodDef; - } + foreach (var method in eventDef.MethodDefs()) + { + var methodDef = FindMethod(method); + if (methodDef == null) + throw new ApplicationException("Could not find event method"); + methodDef.Event = eventDef; + if (method == eventDef.EventDef.AddMethod) + eventDef.AddMethod = methodDef; + if (method == eventDef.EventDef.RemoveMethod) + eventDef.RemoveMethod = methodDef; + if (method == eventDef.EventDef.InvokeMethod) + eventDef.RaiseMethod = methodDef; + } } public void OnTypesRenamed() @@ -219,20 +219,20 @@ private void InitializeInterfaceMethods(MethodNameGroups groups) methodsDict[method.MethodDef] = method; foreach (var ifaceInfo in Interfaces) - foreach (var methodsList in ifaceInfo.TypeDef._virtualMethodInstances.GetMethods()) - { - if (methodsList.Count < 1) - continue; - var methodInst = methodsList[0]; - var ifaceMethod = methodInst.OrigMethodDef; - if (!ifaceMethod.IsVirtual()) - continue; - var ifaceMethodRef = - GenericArgsSubstitutor.Create(methodInst.MethodRef, ifaceInfo.TypeRef.TryGetGenericInstSig()); - if (!methodsDict.TryGetValue(ifaceMethodRef, out var classMethod)) - continue; - _interfaceMethodInfos.AddMethod(ifaceInfo, ifaceMethod, classMethod); - } + foreach (var methodsList in ifaceInfo.TypeDef._virtualMethodInstances.GetMethods()) + { + if (methodsList.Count < 1) + continue; + var methodInst = methodsList[0]; + var ifaceMethod = methodInst.OrigMethodDef; + if (!ifaceMethod.IsVirtual()) + continue; + var ifaceMethodRef = + GenericArgsSubstitutor.Create(methodInst.MethodRef, ifaceInfo.TypeRef.TryGetGenericInstSig()); + if (!methodsDict.TryGetValue(ifaceMethodRef, out var classMethod)) + continue; + _interfaceMethodInfos.AddMethod(ifaceInfo, ifaceMethod, classMethod); + } } methodsDict.Clear(); @@ -247,19 +247,19 @@ private void InitializeInterfaceMethods(MethodNameGroups groups) } foreach (var ifaceInfo in _allImplementedInterfaces.Keys) - foreach (var methodsList in ifaceInfo.TypeDef._virtualMethodInstances.GetMethods()) - { - if (methodsList.Count < 1) - continue; - var ifaceMethod = methodsList[0].OrigMethodDef; - if (!ifaceMethod.IsVirtual()) - continue; - var ifaceMethodRef = - GenericArgsSubstitutor.Create(ifaceMethod.MethodDef, ifaceInfo.TypeRef.TryGetGenericInstSig()); - if (!methodsDict.TryGetValue(ifaceMethodRef, out var classMethod)) - continue; - _interfaceMethodInfos.AddMethodIfEmpty(ifaceInfo, ifaceMethod, classMethod); - } + foreach (var methodsList in ifaceInfo.TypeDef._virtualMethodInstances.GetMethods()) + { + if (methodsList.Count < 1) + continue; + var ifaceMethod = methodsList[0].OrigMethodDef; + if (!ifaceMethod.IsVirtual()) + continue; + var ifaceMethodRef = + GenericArgsSubstitutor.Create(ifaceMethod.MethodDef, ifaceInfo.TypeRef.TryGetGenericInstSig()); + if (!methodsDict.TryGetValue(ifaceMethodRef, out var classMethod)) + continue; + _interfaceMethodInfos.AddMethodIfEmpty(ifaceInfo, ifaceMethod, classMethod); + } methodsDict.Clear(); var ifaceMethodsDict = @@ -291,9 +291,9 @@ private void InitializeInterfaceMethods(MethodNameGroups groups) } foreach (var __ in from info in _interfaceMethodInfos.AllInfos - from _ in info.IfaceMethodToClassMethod.Where(pair => pair.Value == null) - .Where(_ => ResolvedAllInterfaces()) - select info) + from _ in info.IfaceMethodToClassMethod.Where(pair => pair.Value == null) + .Where(_ => ResolvedAllInterfaces()) + select info) ResolvedBaseClasses(); foreach (var pair in _interfaceMethodInfos.AllInfos.SelectMany(info => info.IfaceMethodToClassMethod diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodDefDict.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodDefDict.cs index c2e85a2..a46fc60 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodDefDict.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodDefDict.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using de4dot.blocks; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodInstances.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodInstances.cs index 4ff7ba8..f72ff35 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodInstances.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodInstances.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using de4dot.blocks; using dnlib.DotNet; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { @@ -24,11 +24,11 @@ public class MethodInstances public void InitializeFrom(MethodInstances other, GenericInstSig git) { foreach (var list in other._methodInstances.Values) - foreach (var methodInst in list) - { - var newMethod = GenericArgsSubstitutor.Create(methodInst.MethodRef, git); - Add(new MethodInst(methodInst.OrigMethodDef, newMethod)); - } + foreach (var methodInst in list) + { + var newMethod = GenericArgsSubstitutor.Create(methodInst.MethodRef, git); + Add(new MethodInst(methodInst.OrigMethodDef, newMethod)); + } } public void Add(MethodInst methodInst) diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodNameGroup.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodNameGroup.cs index 1a064ca..5824ede 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodNameGroup.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/MethodNameGroup.cs @@ -34,16 +34,16 @@ public void Merge(MethodNameGroup other) public bool HasInterfaceMethod() => Methods.Any(method => method.Owner.TypeDef.IsInterface); public bool HasGetterOrSetterPropertyMethod() => (from method in Methods - where method.Property != null - let prop = method.Property - where method == prop.GetMethod || method == prop.SetMethod - select method).Any(); + where method.Property != null + let prop = method.Property + where method == prop.GetMethod || method == prop.SetMethod + select method).Any(); public bool HasAddRemoveOrRaiseEventMethod() => (from method in Methods - where method.Event != null - let evt = method.Event - where method == evt.AddMethod || method == evt.RemoveMethod || method == evt.RaiseMethod - select method).Any(); + where method.Event != null + let evt = method.Event + where method == evt.AddMethod || method == evt.RemoveMethod || method == evt.RaiseMethod + select method).Any(); public bool HasProperty() => Methods.Any(method => method.Property != null); diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/Module.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/Module.cs index feb3823..4f4e93e 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/Module.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/Module.cs @@ -13,10 +13,10 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System; using System.Collections.Generic; using System.Linq; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/Modules.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/Modules.cs index 19f6199..1595906 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/Modules.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/Modules.cs @@ -13,10 +13,10 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System; using System.Collections.Generic; using System.Linq; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { @@ -81,12 +81,12 @@ private void InitAllTypes() } foreach (var typeDef in _allTypes) - foreach (var iface in typeDef.TypeDef.Interfaces) - { - var ifaceTypeDef = ResolveType(iface.Interface) ?? ResolveOther(iface.Interface); - if (ifaceTypeDef != null) - typeDef.AddInterface(ifaceTypeDef, iface.Interface); - } + foreach (var iface in typeDef.TypeDef.Interfaces) + { + var ifaceTypeDef = ResolveType(iface.Interface) ?? ResolveOther(iface.Interface); + if (ifaceTypeDef != null) + typeDef.AddInterface(ifaceTypeDef, iface.Interface); + } var allTypesDict = new Dictionary(); foreach (var t in _allTypes) @@ -182,24 +182,24 @@ private IEnumerable FindModules(IType type) case ScopeType.AssemblyRef: return FindModules((AssemblyRef)scope); case ScopeType.ModuleDef: - { - var findModules = FindModules((ModuleDef)scope); - if (findModules != null) - return findModules; - break; - } - case ScopeType.ModuleRef: - { - var moduleRef = (ModuleRef)scope; - if (moduleRef.Name == type.Module.Name) { - var findModules = FindModules(type.Module); + var findModules = FindModules((ModuleDef)scope); if (findModules != null) return findModules; + break; } + case ScopeType.ModuleRef: + { + var moduleRef = (ModuleRef)scope; + if (moduleRef.Name == type.Module.Name) + { + var findModules = FindModules(type.Module); + if (findModules != null) + return findModules; + } - break; - } + break; + } } if (scopeType is not (ScopeType.ModuleRef or ScopeType.ModuleDef)) diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/PropertyDefDict.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/PropertyDefDict.cs index 0018b64..ab8c818 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/PropertyDefDict.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/PropertyDefDict.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using de4dot.blocks; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/AsmModules/TypeDefDict.cs b/NETReactorSlayer.De4dot/Renamer/AsmModules/TypeDefDict.cs index 2b87bf2..0d110d3 100644 --- a/NETReactorSlayer.De4dot/Renamer/AsmModules/TypeDefDict.cs +++ b/NETReactorSlayer.De4dot/Renamer/AsmModules/TypeDefDict.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using de4dot.blocks; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot.Renamer.AsmModules { diff --git a/NETReactorSlayer.De4dot/Renamer/DerivedFrom.cs b/NETReactorSlayer.De4dot/Renamer/DerivedFrom.cs index ba3b547..e52c007 100644 --- a/NETReactorSlayer.De4dot/Renamer/DerivedFrom.cs +++ b/NETReactorSlayer.De4dot/Renamer/DerivedFrom.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using NETReactorSlayer.De4dot.Renamer.AsmModules; using System; using System.Collections.Generic; -using NETReactorSlayer.De4dot.Renamer.AsmModules; namespace NETReactorSlayer.De4dot.Renamer { diff --git a/NETReactorSlayer.De4dot/Renamer/ExistingNames.cs b/NETReactorSlayer.De4dot/Renamer/ExistingNames.cs index 28cac57..6a836d8 100644 --- a/NETReactorSlayer.De4dot/Renamer/ExistingNames.cs +++ b/NETReactorSlayer.De4dot/Renamer/ExistingNames.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System; using System.Collections.Generic; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer { diff --git a/NETReactorSlayer.De4dot/Renamer/MemberInfos.cs b/NETReactorSlayer.De4dot/Renamer/MemberInfos.cs index 6fea428..58f6c23 100644 --- a/NETReactorSlayer.De4dot/Renamer/MemberInfos.cs +++ b/NETReactorSlayer.De4dot/Renamer/MemberInfos.cs @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; using NETReactorSlayer.De4dot.Renamer.AsmModules; +using System.Collections.Generic; namespace NETReactorSlayer.De4dot.Renamer { diff --git a/NETReactorSlayer.De4dot/Renamer/Renamer.cs b/NETReactorSlayer.De4dot/Renamer/Renamer.cs index b741276..fa427a4 100644 --- a/NETReactorSlayer.De4dot/Renamer/Renamer.cs +++ b/NETReactorSlayer.De4dot/Renamer/Renamer.cs @@ -13,13 +13,13 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using de4dot.blocks; +using dnlib.DotNet; +using NETReactorSlayer.De4dot.Renamer.AsmModules; using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; -using de4dot.blocks; -using dnlib.DotNet; -using NETReactorSlayer.De4dot.Renamer.AsmModules; namespace NETReactorSlayer.De4dot.Renamer { @@ -63,22 +63,22 @@ private void RenameResourceKeys() private static void RemoveUselessOverrides(MethodNameGroups groups) { foreach (var group in groups.GetAllGroups()) - foreach (var method in group.Methods) - { - if (!method.Owner.HasModule) - continue; - if (!method.IsPublic()) - continue; - var overrides = method.MethodDef.Overrides; - for (var i = 0; i < overrides.Count; i++) + foreach (var method in group.Methods) { - var overrideMethod = overrides[i].MethodDeclaration; - if (method.MethodDef.Name != overrideMethod.Name) + if (!method.Owner.HasModule) + continue; + if (!method.IsPublic()) continue; - overrides.RemoveAt(i); - i--; + var overrides = method.MethodDef.Overrides; + for (var i = 0; i < overrides.Count; i++) + { + var overrideMethod = overrides[i].MethodDeclaration; + if (method.MethodDef.Name != overrideMethod.Name) + continue; + overrides.RemoveAt(i); + i--; + } } - } } private void RenameTypeDefs() @@ -339,9 +339,9 @@ private void ResetVirtualPropertyNames(IEnumerable allGroups) foreach (var group in allGroups) { var prop = (from method in @group.Methods - where method.Property != null - where !method.Owner.HasModule - select method.Property).FirstOrDefault(); + where method.Property != null + where !method.Owner.HasModule + select method.Property).FirstOrDefault(); if (prop == null) continue; @@ -358,9 +358,9 @@ private void ResetVirtualEventNames(IEnumerable allGroups) foreach (var group in allGroups) { var evt = (from method in @group.Methods - where method.Event != null - where !method.Owner.HasModule - select method.Event).FirstOrDefault(); + where method.Event != null + where !method.Owner.HasModule + select method.Event).FirstOrDefault(); if (evt == null) continue; @@ -465,18 +465,18 @@ private void RestorePropertiesFromNames2(IEnumerable allGroups) } foreach (var type in _modules.AllTypes) - foreach (var method in type.AllMethodsSorted) - { - if (method.IsVirtual()) - continue; - if (method.Property != null) - continue; - var methodName = method.MethodDef.Name.String; - if (Utils.StartsWith(methodName, "get_", StringComparison.Ordinal)) - CreatePropertyGetter(methodName.Substring(4), method); - else if (Utils.StartsWith(methodName, "set_", StringComparison.Ordinal)) - CreatePropertySetter(methodName.Substring(4), method); - } + foreach (var method in type.AllMethodsSorted) + { + if (method.IsVirtual()) + continue; + if (method.Property != null) + continue; + var methodName = method.MethodDef.Name.String; + if (Utils.StartsWith(methodName, "get_", StringComparison.Ordinal)) + CreatePropertyGetter(methodName.Substring(4), method); + else if (Utils.StartsWith(methodName, "set_", StringComparison.Ordinal)) + CreatePropertySetter(methodName.Substring(4), method); + } } private void CreatePropertyGetter(string name, MMethodDef propMethod) @@ -681,18 +681,18 @@ private void RestoreEventsFromNames2(IEnumerable allGroups) } foreach (var type in _modules.AllTypes) - foreach (var method in type.AllMethodsSorted) - { - if (method.IsVirtual()) - continue; - if (method.Event != null) - continue; - var methodName = method.MethodDef.Name.String; - if (Utils.StartsWith(methodName, "add_", StringComparison.Ordinal)) - CreateEventAdder(methodName.Substring(4), method); - else if (Utils.StartsWith(methodName, "remove_", StringComparison.Ordinal)) - CreateEventRemover(methodName.Substring(7), method); - } + foreach (var method in type.AllMethodsSorted) + { + if (method.IsVirtual()) + continue; + if (method.Event != null) + continue; + var methodName = method.MethodDef.Name.String; + if (Utils.StartsWith(methodName, "add_", StringComparison.Ordinal)) + CreateEventAdder(methodName.Substring(4), method); + else if (Utils.StartsWith(methodName, "remove_", StringComparison.Ordinal)) + CreateEventRemover(methodName.Substring(7), method); + } } private void CreateEventAdder(string name, MMethodDef eventMethod) @@ -836,26 +836,26 @@ private string[] GetValidArgNames(MethodNameGroup group) { var methods = new List(group.Methods); foreach (var method in group.Methods) - foreach (var ovrd in method.MethodDef.Overrides) - { - var overrideRef = ovrd.MethodDeclaration; - var overrideDef = _modules.ResolveMethod(overrideRef); - if (overrideDef == null) + foreach (var ovrd in method.MethodDef.Overrides) { - var typeDef = _modules.ResolveType(overrideRef.DeclaringType) ?? - _modules.ResolveOther(overrideRef.DeclaringType); - if (typeDef == null) - continue; - overrideDef = typeDef.FindMethod(overrideRef); + var overrideRef = ovrd.MethodDeclaration; + var overrideDef = _modules.ResolveMethod(overrideRef); if (overrideDef == null) + { + var typeDef = _modules.ResolveType(overrideRef.DeclaringType) ?? + _modules.ResolveOther(overrideRef.DeclaringType); + if (typeDef == null) + continue; + overrideDef = typeDef.FindMethod(overrideRef); + if (overrideDef == null) + continue; + } + + if (overrideDef.VisibleParameterCount != method.VisibleParameterCount) continue; + methods.Add(overrideDef); } - if (overrideDef.VisibleParameterCount != method.VisibleParameterCount) - continue; - methods.Add(overrideDef); - } - var argNames = new string[group.Methods[0].ParamDefs.Count]; foreach (var method in methods) { @@ -1112,11 +1112,11 @@ private static MMethodDef GetPropertyMethod(MethodNameGroup group) => group.Methods.FirstOrDefault(method => method.Property != null); private string GetSuggestedPropertyName(MethodNameGroup group) => (from method in @group.Methods - where method.Property != null - select _memberInfos.Property(method.Property) + where method.Property != null + select _memberInfos.Property(method.Property) into info - where info.SuggestedName != null - select info.SuggestedName).FirstOrDefault(); + where info.SuggestedName != null + select info.SuggestedName).FirstOrDefault(); internal static ITypeDefOrRef GetScopeType(TypeSig typeSig) { @@ -1265,21 +1265,21 @@ private MMethodDef GetOverriddenMethod(MMethodDef overrideMethod) => _modules.ResolveMethod(overrideMethod.MethodDef.Overrides[0].MethodDeclaration); private string GetSuggestedMethodName(MethodNameGroup group) => (from method in @group.Methods - select _memberInfos.Method(method) + select _memberInfos.Method(method) into info - where info.SuggestedName != null - select info.SuggestedName).FirstOrDefault(); + where info.SuggestedName != null + select info.SuggestedName).FirstOrDefault(); private bool HasInvalidMethodName(MethodNameGroup group) => (from method in @group.Methods - let typeInfo = _memberInfos.Type(method.Owner) - let methodInfo = _memberInfos.Method(method) - where !typeInfo.NameChecker.IsValidMethodName(methodInfo.OldName) - select typeInfo).Any(); + let typeInfo = _memberInfos.Type(method.Owner) + let methodInfo = _memberInfos.Method(method) + where !typeInfo.NameChecker.IsValidMethodName(methodInfo.OldName) + select typeInfo).Any(); private static string GetAvailableName(string prefix, bool tryWithoutZero, MethodNameGroup group, Func checkAvailable) { - for (var i = 0;; i++) + for (var i = 0; ; i++) { var newName = i == 0 && tryWithoutZero ? prefix : prefix + i; if (checkAvailable(group, newName)) @@ -1302,14 +1302,14 @@ private bool HasDelegateOwner(MethodNameGroup group) => private void PrepareRenameEntryPoints() { foreach (var methodDef in from module in _modules.TheModules - select module.ModuleDefMd.EntryPoint + select module.ModuleDefMd.EntryPoint into entryPoint - where entryPoint != null - select _modules.ResolveMethod(entryPoint) + where entryPoint != null + select _modules.ResolveMethod(entryPoint) into methodDef - where methodDef != null - where methodDef.IsStatic() - select methodDef) + where methodDef != null + where methodDef.IsStatic() + select methodDef) { _memberInfos.Method(methodDef).SuggestedName = "Main"; if (methodDef.ParamDefs.Count != 1) @@ -1579,8 +1579,8 @@ public void VisitAll(Action func) _methodToGroup = new Dictionary(); foreach (var group in _groups) - foreach (var method in group.Methods) - _methodToGroup[method] = group; + foreach (var method in group.Methods) + _methodToGroup[method] = group; foreach (var type in _allTypes) Visit(type); diff --git a/NETReactorSlayer.De4dot/Renamer/ResourceKeysRenamer.cs b/NETReactorSlayer.De4dot/Renamer/ResourceKeysRenamer.cs index 93daaaa..fd96f2d 100644 --- a/NETReactorSlayer.De4dot/Renamer/ResourceKeysRenamer.cs +++ b/NETReactorSlayer.De4dot/Renamer/ResourceKeysRenamer.cs @@ -13,16 +13,16 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using de4dot.blocks; +using dnlib.DotNet; +using dnlib.DotNet.Emit; +using dnlib.DotNet.Resources; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; -using de4dot.blocks; -using dnlib.DotNet; -using dnlib.DotNet.Emit; -using dnlib.DotNet.Resources; namespace NETReactorSlayer.De4dot.Renamer { @@ -136,8 +136,8 @@ private static void Rename(TypeDef type, List renamed) nameToInfo[info.Element.Name] = info; foreach (var instrs in from method in type.Methods - where method.Body != null - select method.Body.Instructions) + where method.Body != null + select method.Body.Instructions) for (var i = 0; i < instrs.Count; i++) { var call = instrs[i]; @@ -223,7 +223,7 @@ private string CreatePrefixFromStringData(string data) private string CreateName(Func create) { - for (var counter = 0;; counter++) + for (var counter = 0; ; counter++) { var newName = create(counter); if (_newNames.ContainsKey(newName)) diff --git a/NETReactorSlayer.De4dot/Renamer/ResourceRenamer.cs b/NETReactorSlayer.De4dot/Renamer/ResourceRenamer.cs index 4186fc2..750a506 100644 --- a/NETReactorSlayer.De4dot/Renamer/ResourceRenamer.cs +++ b/NETReactorSlayer.De4dot/Renamer/ResourceRenamer.cs @@ -13,14 +13,14 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.De4dot.Renamer.AsmModules; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; namespace NETReactorSlayer.De4dot.Renamer { @@ -63,8 +63,8 @@ private void RenameResourceNamesInCode(List renamedTypes) oldNameToTypeInfo[EscapeTypeName(info.OldFullName)] = info; foreach (var instrs in from method in _module.GetAllMethods() - where method.HasBody - select method.Body.Instructions) + where method.HasBody + select method.Body.Instructions) for (var i = 0; i < instrs.Count; i++) { var instr = instrs[i]; diff --git a/NETReactorSlayer.De4dot/Renamer/TypeInfo.cs b/NETReactorSlayer.De4dot/Renamer/TypeInfo.cs index bd030e8..6655008 100644 --- a/NETReactorSlayer.De4dot/Renamer/TypeInfo.cs +++ b/NETReactorSlayer.De4dot/Renamer/TypeInfo.cs @@ -13,14 +13,14 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; using NETReactorSlayer.De4dot.Renamer.AsmModules; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; namespace NETReactorSlayer.De4dot.Renamer { @@ -154,10 +154,10 @@ private void PrepareRenameFields() var i = 0; var nameFormat = HasFlagsAttribute() ? "flag_{0}" : "const_{0}"; foreach (var fieldInfo in from fieldDef in Type.AllFieldsSorted - let fieldInfo = Field(fieldDef) - where !fieldInfo.Renamed - where fieldDef.FieldDef.IsStatic && fieldDef.FieldDef.IsLiteral - select fieldInfo) + let fieldInfo = Field(fieldDef) + where !fieldInfo.Renamed + where fieldDef.FieldDef.IsStatic && fieldDef.FieldDef.IsLiteral + select fieldInfo) { if (!checker.IsValidFieldName(fieldInfo.OldName)) fieldInfo.Rename(string.Format(nameFormat, i)); @@ -439,9 +439,9 @@ private void InitializeWindowsFormsFieldsAndProps() ourMethods.Add(methodDef.MethodDef, methodDef); foreach (var instructions in from methodDef in Type.AllMethods - where methodDef.MethodDef.Body != null - where !methodDef.MethodDef.IsStatic && !methodDef.MethodDef.IsVirtual - select methodDef.MethodDef.Body.Instructions) + where methodDef.MethodDef.Body != null + where !methodDef.MethodDef.IsStatic && !methodDef.MethodDef.IsVirtual + select methodDef.MethodDef.Body.Instructions) for (var i = 2; i < instructions.Count; i++) { var call = instructions[i]; @@ -462,22 +462,22 @@ private void InitializeWindowsFormsFieldsAndProps() { case Code.Call: case Code.Callvirt: - { - if (instr.Operand is not IMethod calledMethod) - continue; - var calledMethodDef = ourMethods.Find(calledMethod); - if (calledMethodDef == null) - continue; - fieldRef = GetFieldRef(calledMethodDef.MethodDef); - - var propDef = calledMethodDef.Property; - if (propDef == null) - continue; - - _memberInfos.Property(propDef).SuggestedName = fieldName; - fieldName = "_" + fieldName; - break; - } + { + if (instr.Operand is not IMethod calledMethod) + continue; + var calledMethodDef = ourMethods.Find(calledMethod); + if (calledMethodDef == null) + continue; + fieldRef = GetFieldRef(calledMethodDef.MethodDef); + + var propDef = calledMethodDef.Property; + if (propDef == null) + continue; + + _memberInfos.Property(propDef).SuggestedName = fieldName; + fieldName = "_" + fieldName; + break; + } case Code.Ldfld: fieldRef = instr.Operand as IField; break; @@ -664,9 +664,9 @@ private void InitFieldEventHandlers(FieldDefDictBase fieldDefDictBase var checker = NameChecker; foreach (var instructions in from methodDef in Type.AllMethods - where methodDef.MethodDef.Body != null - where !methodDef.MethodDef.IsStatic - select methodDef.MethodDef.Body.Instructions) + where methodDef.MethodDef.Body != null + where !methodDef.MethodDef.IsStatic + select methodDef.MethodDef.Body.Instructions) for (var i = 0; i < instructions.Count - 6; i++) { if (instructions[i].GetParameterIndex() != 0) @@ -736,11 +736,11 @@ private void InitTypeEventHandlers(MethodDefDictBase methodDefDictBa var checker = NameChecker; foreach (var instructions in from methodDef in Type.AllMethods - where methodDef.MethodDef.Body != null - where !methodDef.MethodDef.IsStatic - select methodDef.MethodDef + where methodDef.MethodDef.Body != null + where !methodDef.MethodDef.IsStatic + select methodDef.MethodDef into method - select method.Body.Instructions) + select method.Body.Instructions) for (var i = 0; i < instructions.Count - 5; i++) { if (instructions[i].GetParameterIndex() != 0) @@ -843,13 +843,13 @@ private string FindWindowsFormsClassName(MTypeDef type) private void FindInitializeComponentMethod(MTypeDef type, MMethodDef possibleInitMethod) { if ((from methodDef in type.AllMethods - where methodDef.MethodDef.Name == ".ctor" - where methodDef.MethodDef.Body != null - from instr in methodDef.MethodDef.Body.Instructions - where instr.OpCode.Code is Code.Call or Code.Callvirt - select instr).Any(instr => MethodEqualityComparer.CompareDeclaringTypes.Equals( - possibleInitMethod.MethodDef, - instr.Operand as IMethod))) + where methodDef.MethodDef.Name == ".ctor" + where methodDef.MethodDef.Body != null + from instr in methodDef.MethodDef.Body.Instructions + where instr.OpCode.Code is Code.Call or Code.Callvirt + select instr).Any(instr => MethodEqualityComparer.CompareDeclaringTypes.Equals( + possibleInitMethod.MethodDef, + instr.Operand as IMethod))) _memberInfos.Method(possibleInitMethod).SuggestedName = "InitializeComponent"; } diff --git a/NETReactorSlayer.De4dot/Renamer/TypeNames.cs b/NETReactorSlayer.De4dot/Renamer/TypeNames.cs index f9cbf91..acd7d08 100644 --- a/NETReactorSlayer.De4dot/Renamer/TypeNames.cs +++ b/NETReactorSlayer.De4dot/Renamer/TypeNames.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System; using System.Collections.Generic; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer { @@ -29,12 +29,12 @@ public string Create(TypeSig typeRef) case null: return UnknownNameCreator.Create(); case GenericInstSig gis: - { - if (gis.FullName == "System.Nullable`1" && - gis.GenericArguments.Count == 1 && gis.GenericArguments[0] != null) - typeRef = gis.GenericArguments[0]; - break; - } + { + if (gis.FullName == "System.Nullable`1" && + gis.GenericArguments.Count == 1 && gis.GenericArguments[0] != null) + typeRef = gis.GenericArguments[0]; + break; + } } var prefix = GetPrefix(typeRef); diff --git a/NETReactorSlayer.De4dot/Renamer/TypeRenamerState.cs b/NETReactorSlayer.De4dot/Renamer/TypeRenamerState.cs index 67a80fd..8c64166 100644 --- a/NETReactorSlayer.De4dot/Renamer/TypeRenamerState.cs +++ b/NETReactorSlayer.De4dot/Renamer/TypeRenamerState.cs @@ -13,9 +13,9 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; using System; using System.Collections.Generic; -using dnlib.DotNet; namespace NETReactorSlayer.De4dot.Renamer { diff --git a/NETReactorSlayer.De4dot/TypesRestorer.cs b/NETReactorSlayer.De4dot/TypesRestorer.cs index 65de900..702e012 100644 --- a/NETReactorSlayer.De4dot/TypesRestorer.cs +++ b/NETReactorSlayer.De4dot/TypesRestorer.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System; using dnlib.DotNet; +using System; namespace NETReactorSlayer.De4dot { diff --git a/NETReactorSlayer.De4dot/TypesRestorerBase.cs b/NETReactorSlayer.De4dot/TypesRestorerBase.cs index 58c6b4d..3a23d8d 100644 --- a/NETReactorSlayer.De4dot/TypesRestorerBase.cs +++ b/NETReactorSlayer.De4dot/TypesRestorerBase.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,11 +13,11 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ -using System.Collections.Generic; -using System.Linq; using de4dot.blocks; using dnlib.DotNet; using dnlib.DotNet.Emit; +using System.Collections.Generic; +using System.Linq; namespace NETReactorSlayer.De4dot { diff --git a/NETReactorSlayer.GUI/Dialogs/MsgBox.cs b/NETReactorSlayer.GUI/Dialogs/MsgBox.cs index 2d5aa93..f8bd4e3 100644 --- a/NETReactorSlayer.GUI/Dialogs/MsgBox.cs +++ b/NETReactorSlayer.GUI/Dialogs/MsgBox.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,6 +13,7 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using NETReactorSlayer.GUI.Properties; using System; using System.Collections.Generic; using System.Drawing; @@ -21,7 +22,6 @@ You should have received a copy of the GNU General Public License using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; -using NETReactorSlayer.GUI.Properties; namespace NETReactorSlayer.GUI.Dialogs { diff --git a/NETReactorSlayer.GUI/Logger.cs b/NETReactorSlayer.GUI/Logger.cs index 4db869d..6f88fa5 100644 --- a/NETReactorSlayer.GUI/Logger.cs +++ b/NETReactorSlayer.GUI/Logger.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.GUI/MainWindow.Designer.cs b/NETReactorSlayer.GUI/MainWindow.Designer.cs index fd4efa6..96e046c 100644 --- a/NETReactorSlayer.GUI/MainWindow.Designer.cs +++ b/NETReactorSlayer.GUI/MainWindow.Designer.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -48,1273 +48,2541 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow)); + this.pnlHeader = new System.Windows.Forms.Panel(); + this.picMenu = new System.Windows.Forms.PictureBox(); + this.panel4 = new System.Windows.Forms.Panel(); + this.picMinimize = new System.Windows.Forms.PictureBox(); + this.panel2 = new System.Windows.Forms.Panel(); + this.picExit = new System.Windows.Forms.PictureBox(); + this.picHeader = new System.Windows.Forms.PictureBox(); + this.panel3 = new System.Windows.Forms.Panel(); + this.pnlBase = new System.Windows.Forms.Panel(); + this.pnlButton = new System.Windows.Forms.Panel(); + this.btnStart = new NETReactorSlayer.GUI.UserControls.NrsButton(); + this.pnlSeparator = new System.Windows.Forms.Panel(); + this.panelLogs = new System.Windows.Forms.Panel(); + this.scrollbarLogs = new NETReactorSlayer.GUI.UserControls.NrsScrollBar(); + this.txtLogs = new System.Windows.Forms.RichTextBox(); + this.ctxLogs = new System.Windows.Forms.ContextMenuStrip(this.components); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + this.copyLogsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.pnlInput = new System.Windows.Forms.Panel(); + this.picBrowse = new System.Windows.Forms.PictureBox(); + this.pnlTextBox = new System.Windows.Forms.Panel(); + this.txtInput = new NETReactorSlayer.GUI.UserControls.NrsTextBox(); + this.pnlOptions = new System.Windows.Forms.Panel(); + this.tabelOptions = new System.Windows.Forms.TableLayoutPanel(); + this.chkDumpCosturaAsm = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkDecryptStrings = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkPatchAntiTD = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkDecryptBools = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkDumpDNRAsm = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkDecryptHiddenCalls = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkDeobCFlow = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkDecryptTokens = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkDecryptResources = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkRemoveRefProxies = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkDecryptMethods = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkSelectUnSelectAll = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkRemSn = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkRename = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.ctxRename = new System.Windows.Forms.ContextMenuStrip(this.components); + this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem13 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem15 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem16 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem12 = new System.Windows.Forms.ToolStripMenuItem(); + this.chkRenameShort = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkRemJunks = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkKeepTypes = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkRemCalls = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkPreserveAll = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.chkKeepOldMaxStack = new NETReactorSlayer.GUI.UserControls.NrsCheckBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.llblGitHub = new System.Windows.Forms.LinkLabel(); + this.label2 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.lblVersion = new System.Windows.Forms.Label(); + this.llblWebsite = new System.Windows.Forms.LinkLabel(); + this.label4 = new System.Windows.Forms.Label(); + this.lblAuthor = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.ctxMenu = new System.Windows.Forms.ContextMenuStrip(this.components); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripMenuItem(); + this.pnlHeader.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picMenu)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.picMinimize)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.picExit)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.picHeader)).BeginInit(); + this.pnlBase.SuspendLayout(); + this.pnlButton.SuspendLayout(); + this.panelLogs.SuspendLayout(); + this.ctxLogs.SuspendLayout(); + this.pnlInput.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picBrowse)).BeginInit(); + this.pnlTextBox.SuspendLayout(); + this.pnlOptions.SuspendLayout(); + this.tabelOptions.SuspendLayout(); + this.ctxRename.SuspendLayout(); + this.panel1.SuspendLayout(); + this.ctxMenu.SuspendLayout(); + this.SuspendLayout(); + // + // pnlHeader + // + this.pnlHeader.AutoSize = true; + this.pnlHeader.Controls.Add(this.picMenu); + this.pnlHeader.Controls.Add(this.panel4); + this.pnlHeader.Controls.Add(this.picMinimize); + this.pnlHeader.Controls.Add(this.panel2); + this.pnlHeader.Controls.Add(this.picExit); + this.pnlHeader.Controls.Add(this.picHeader); + this.pnlHeader.Controls.Add(this.panel3); + this.pnlHeader.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlHeader.Location = new System.Drawing.Point(30, 5); + this.pnlHeader.MinimumSize = new System.Drawing.Size(0, 60); + this.pnlHeader.Name = "pnlHeader"; - this.pnlHeader.Size = new System.Drawing.Size(997, 60); + + this.pnlHeader.Size = new System.Drawing.Size(952, 60); + this.pnlHeader.TabIndex = 2; + // + // picMenu + // + this.picMenu.Cursor = System.Windows.Forms.Cursors.Hand; + this.picMenu.Dock = System.Windows.Forms.DockStyle.Left; + this.picMenu.Image = global::NETReactorSlayer.GUI.Properties.Resources.Menu; + this.picMenu.Location = new System.Drawing.Point(10, 0); + this.picMenu.Name = "picMenu"; + this.picMenu.Size = new System.Drawing.Size(24, 60); + this.picMenu.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.picMenu.TabIndex = 18; + this.picMenu.TabStop = false; + this.picMenu.MouseClick += new System.Windows.Forms.MouseEventHandler(this.picMenu_MouseClick); + this.picMenu.MouseEnter += new System.EventHandler(this.picMenu_MouseEnter); + this.picMenu.MouseLeave += new System.EventHandler(this.picMenu_MouseLeave); + // + // panel4 + // + this.panel4.Dock = System.Windows.Forms.DockStyle.Left; + this.panel4.Location = new System.Drawing.Point(0, 0); + this.panel4.Name = "panel4"; + this.panel4.Size = new System.Drawing.Size(10, 60); + this.panel4.TabIndex = 19; + // + // picMinimize + // + this.picMinimize.Cursor = System.Windows.Forms.Cursors.Hand; + this.picMinimize.Dock = System.Windows.Forms.DockStyle.Right; + this.picMinimize.Image = global::NETReactorSlayer.GUI.Properties.Resources.Minimize; - this.picMinimize.Location = new System.Drawing.Point(929, 0); + + this.picMinimize.Location = new System.Drawing.Point(884, 0); + this.picMinimize.Name = "picMinimize"; + this.picMinimize.Size = new System.Drawing.Size(24, 60); + this.picMinimize.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.picMinimize.TabIndex = 3; + this.picMinimize.TabStop = false; + this.picMinimize.Click += new System.EventHandler(this.picMinimize_Click); + this.picMinimize.MouseEnter += new System.EventHandler(this.picMinimize_MouseEnter); + this.picMinimize.MouseLeave += new System.EventHandler(this.picMinimize_MouseLeave); + // + // panel2 + // + this.panel2.Dock = System.Windows.Forms.DockStyle.Right; - this.panel2.Location = new System.Drawing.Point(953, 0); + + this.panel2.Location = new System.Drawing.Point(908, 0); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(10, 60); + this.panel2.TabIndex = 16; + // + // picExit + // + this.picExit.Cursor = System.Windows.Forms.Cursors.Hand; + this.picExit.Dock = System.Windows.Forms.DockStyle.Right; + this.picExit.Image = global::NETReactorSlayer.GUI.Properties.Resources.Close; - this.picExit.Location = new System.Drawing.Point(963, 0); + + this.picExit.Location = new System.Drawing.Point(918, 0); + this.picExit.Name = "picExit"; + this.picExit.Size = new System.Drawing.Size(24, 60); + this.picExit.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.picExit.TabIndex = 2; + this.picExit.TabStop = false; + this.picExit.Click += new System.EventHandler(this.picExit_Click); + this.picExit.MouseEnter += new System.EventHandler(this.picExit_MouseEnter); + this.picExit.MouseLeave += new System.EventHandler(this.picExit_MouseLeave); + // + // picHeader + // + this.picHeader.Dock = System.Windows.Forms.DockStyle.Fill; + this.picHeader.Image = global::NETReactorSlayer.GUI.Properties.Resources.Header; + this.picHeader.Location = new System.Drawing.Point(0, 0); + this.picHeader.Name = "picHeader"; - this.picHeader.Size = new System.Drawing.Size(987, 60); + + this.picHeader.Size = new System.Drawing.Size(942, 60); + this.picHeader.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.picHeader.TabIndex = 1; + this.picHeader.TabStop = false; + this.picHeader.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown); + this.picHeader.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove); + this.picHeader.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OnMouseUp); + // + // panel3 + // + this.panel3.Dock = System.Windows.Forms.DockStyle.Right; - this.panel3.Location = new System.Drawing.Point(987, 0); + + this.panel3.Location = new System.Drawing.Point(942, 0); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(10, 60); + this.panel3.TabIndex = 17; + // + // pnlBase + // + this.pnlBase.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(23)))), ((int)(((byte)(23)))), ((int)(((byte)(23))))); + this.pnlBase.Controls.Add(this.pnlButton); + this.pnlBase.Controls.Add(this.pnlSeparator); + this.pnlBase.Controls.Add(this.panelLogs); + this.pnlBase.Controls.Add(this.pnlInput); + this.pnlBase.Controls.Add(this.pnlOptions); + this.pnlBase.Dock = System.Windows.Forms.DockStyle.Fill; + this.pnlBase.Location = new System.Drawing.Point(30, 65); + this.pnlBase.Name = "pnlBase"; + this.pnlBase.Padding = new System.Windows.Forms.Padding(30); - this.pnlBase.Size = new System.Drawing.Size(997, 526); + + this.pnlBase.Size = new System.Drawing.Size(952, 526); + this.pnlBase.TabIndex = 3; + // + // pnlButton + // + this.pnlButton.Controls.Add(this.btnStart); + this.pnlButton.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlButton.Location = new System.Drawing.Point(30, 450); + this.pnlButton.Name = "pnlButton"; + this.pnlButton.Padding = new System.Windows.Forms.Padding(200, 5, 200, 5); - this.pnlButton.Size = new System.Drawing.Size(937, 55); + + this.pnlButton.Size = new System.Drawing.Size(892, 55); + this.pnlButton.TabIndex = 16; + // + // btnStart + // + this.btnStart.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(27)))), ((int)(((byte)(27))))); + this.btnStart.BorderRadius = 25; + this.btnStart.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnStart.Dock = System.Windows.Forms.DockStyle.Fill; + this.btnStart.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32))))); + this.btnStart.FlatAppearance.BorderSize = 0; + this.btnStart.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18))))); + this.btnStart.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(34)))), ((int)(((byte)(34)))), ((int)(((byte)(34))))); + this.btnStart.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnStart.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnStart.ForeColor = System.Drawing.Color.Silver; + this.btnStart.Location = new System.Drawing.Point(200, 5); + this.btnStart.Name = "btnStart"; - this.btnStart.Size = new System.Drawing.Size(537, 45); + + this.btnStart.Size = new System.Drawing.Size(492, 45); + this.btnStart.TabIndex = 15; + this.btnStart.Text = "Start Deobfuscation"; + this.btnStart.TextTransform = NETReactorSlayer.GUI.UserControls.NrsButton.TextTransformEnum.None; + this.btnStart.UseVisualStyleBackColor = false; + this.btnStart.Click += new System.EventHandler(this.btnStart_Click); + // + // pnlSeparator + // + this.pnlSeparator.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlSeparator.Location = new System.Drawing.Point(30, 440); + this.pnlSeparator.Name = "pnlSeparator"; - this.pnlSeparator.Size = new System.Drawing.Size(937, 10); + + this.pnlSeparator.Size = new System.Drawing.Size(892, 10); + this.pnlSeparator.TabIndex = 15; + // + // panelLogs + // + this.panelLogs.Controls.Add(this.scrollbarLogs); + this.panelLogs.Controls.Add(this.txtLogs); + this.panelLogs.Dock = System.Windows.Forms.DockStyle.Top; + this.panelLogs.Location = new System.Drawing.Point(30, 259); + this.panelLogs.Name = "panelLogs"; + this.panelLogs.Padding = new System.Windows.Forms.Padding(2); - this.panelLogs.Size = new System.Drawing.Size(937, 181); + + this.panelLogs.Size = new System.Drawing.Size(892, 181); + this.panelLogs.TabIndex = 0; + // + // scrollbarLogs + // + this.scrollbarLogs.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(27)))), ((int)(((byte)(27))))); + this.scrollbarLogs.Dock = System.Windows.Forms.DockStyle.Right; - this.scrollbarLogs.Location = new System.Drawing.Point(920, 2); + + this.scrollbarLogs.Location = new System.Drawing.Point(875, 2); + this.scrollbarLogs.Maximum = 10; + this.scrollbarLogs.Name = "scrollbarLogs"; + this.scrollbarLogs.Size = new System.Drawing.Size(15, 177); + this.scrollbarLogs.TabIndex = 17; + this.scrollbarLogs.Text = "nrsScrollBar1"; + this.scrollbarLogs.ViewSize = 9; + this.scrollbarLogs.ValueChanged += new System.EventHandler(this.scrollbarLogs_ValueChanged); + // + // txtLogs + // + this.txtLogs.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(27)))), ((int)(((byte)(27))))); + this.txtLogs.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.txtLogs.ContextMenuStrip = this.ctxLogs; + this.txtLogs.Cursor = System.Windows.Forms.Cursors.IBeam; + this.txtLogs.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtLogs.ForeColor = System.Drawing.Color.Silver; + this.txtLogs.Location = new System.Drawing.Point(2, 2); + this.txtLogs.Name = "txtLogs"; + this.txtLogs.ReadOnly = true; + this.txtLogs.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None; - this.txtLogs.Size = new System.Drawing.Size(933, 177); + + this.txtLogs.Size = new System.Drawing.Size(888, 177); + this.txtLogs.TabIndex = 0; + this.txtLogs.TabStop = false; + this.txtLogs.Text = "\n Logs will appear here..."; + this.txtLogs.TextChanged += new System.EventHandler(this.txtLogs_TextChanged); + // + // ctxLogs + // + this.ctxLogs.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(23)))), ((int)(((byte)(23)))), ((int)(((byte)(23))))); + this.ctxLogs.ImageScalingSize = new System.Drawing.Size(20, 20); + this.ctxLogs.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripMenuItem2, + this.copyLogsToolStripMenuItem, + this.toolStripMenuItem1}); + this.ctxLogs.Name = "ctxLogs"; + this.ctxLogs.ShowImageMargin = false; - this.ctxLogs.Size = new System.Drawing.Size(124, 38); + + this.ctxLogs.Size = new System.Drawing.Size(110, 36); + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.AutoSize = false; + this.toolStripMenuItem2.Enabled = false; + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(185, 5); + this.toolStripMenuItem2.Text = " "; + // + // copyLogsToolStripMenuItem + // + this.copyLogsToolStripMenuItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.copyLogsToolStripMenuItem.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.copyLogsToolStripMenuItem.ForeColor = System.Drawing.Color.Silver; + this.copyLogsToolStripMenuItem.Name = "copyLogsToolStripMenuItem"; - this.copyLogsToolStripMenuItem.Size = new System.Drawing.Size(123, 24); + + this.copyLogsToolStripMenuItem.Size = new System.Drawing.Size(109, 22); + this.copyLogsToolStripMenuItem.Text = " Copy Logs"; + this.copyLogsToolStripMenuItem.Click += new System.EventHandler(this.copyLogsToolStripMenuItem_Click); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.AutoSize = false; + this.toolStripMenuItem1.Enabled = false; + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(185, 5); + this.toolStripMenuItem1.Text = " "; + // + // pnlInput + // + this.pnlInput.Controls.Add(this.picBrowse); + this.pnlInput.Controls.Add(this.pnlTextBox); + this.pnlInput.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlInput.Location = new System.Drawing.Point(30, 212); + this.pnlInput.Name = "pnlInput"; + this.pnlInput.Padding = new System.Windows.Forms.Padding(0, 10, 0, 10); - this.pnlInput.Size = new System.Drawing.Size(937, 47); + + this.pnlInput.Size = new System.Drawing.Size(892, 47); + this.pnlInput.TabIndex = 12; + // + // picBrowse + // + this.picBrowse.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(27)))), ((int)(((byte)(27))))); + this.picBrowse.Cursor = System.Windows.Forms.Cursors.Hand; + this.picBrowse.Dock = System.Windows.Forms.DockStyle.Right; + this.picBrowse.Image = global::NETReactorSlayer.GUI.Properties.Resources.Browse; - this.picBrowse.Location = new System.Drawing.Point(886, 10); + + this.picBrowse.Location = new System.Drawing.Point(841, 10); + this.picBrowse.Name = "picBrowse"; + this.picBrowse.Size = new System.Drawing.Size(51, 27); + this.picBrowse.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.picBrowse.TabIndex = 4; + this.picBrowse.TabStop = false; + this.picBrowse.Click += new System.EventHandler(this.picBrowse_Click); + // + // pnlTextBox + // + this.pnlTextBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(27)))), ((int)(((byte)(27))))); + this.pnlTextBox.Controls.Add(this.txtInput); + this.pnlTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.pnlTextBox.Location = new System.Drawing.Point(0, 10); + this.pnlTextBox.Name = "pnlTextBox"; + this.pnlTextBox.Padding = new System.Windows.Forms.Padding(0, 6, 0, 0); - this.pnlTextBox.Size = new System.Drawing.Size(937, 27); + + this.pnlTextBox.Size = new System.Drawing.Size(892, 27); + this.pnlTextBox.TabIndex = 1; + // + // txtInput + // + this.txtInput.AllowDrop = true; + this.txtInput.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(27)))), ((int)(((byte)(27))))); + this.txtInput.BorderRadius = 0; + this.txtInput.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.txtInput.Cursor = System.Windows.Forms.Cursors.IBeam; + this.txtInput.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtInput.Font = new System.Drawing.Font("Segoe UI Semibold", 7.2F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.txtInput.ForeColor = System.Drawing.Color.Silver; + this.txtInput.Location = new System.Drawing.Point(0, 6); + this.txtInput.Name = "txtInput"; + this.txtInput.PlaceHolderColor = System.Drawing.Color.Gray; + this.txtInput.PlaceHolderText = "DRAG & DROP TARGET FILE HERE OR ENTER FILE PATH"; + this.txtInput.Progress = 22F; + this.txtInput.ProgressColor = System.Drawing.Color.MediumSeaGreen; - this.txtInput.Size = new System.Drawing.Size(937, 21); + + this.txtInput.Size = new System.Drawing.Size(892, 21); + this.txtInput.TabIndex = 2; + this.txtInput.Tag = ""; + this.txtInput.Text = "DRAG & DROP TARGET FILE HERE OR ENTER FILE PATH"; + this.txtInput.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.txtInput.TextTransform = NETReactorSlayer.GUI.UserControls.NrsTextBox.TextTransformEnum.None; + this.txtInput.WordWrap = false; + this.txtInput.DragDrop += new System.Windows.Forms.DragEventHandler(this.txtInput_DragDrop); + this.txtInput.DragEnter += new System.Windows.Forms.DragEventHandler(this.txtInput_DragEnter); + // + // pnlOptions + // + this.pnlOptions.Controls.Add(this.tabelOptions); + this.pnlOptions.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlOptions.Location = new System.Drawing.Point(30, 30); + this.pnlOptions.Name = "pnlOptions"; + this.pnlOptions.Padding = new System.Windows.Forms.Padding(3, 0, 0, 3); - this.pnlOptions.Size = new System.Drawing.Size(937, 182); + + this.pnlOptions.Size = new System.Drawing.Size(892, 182); + this.pnlOptions.TabIndex = 11; + // + // tabelOptions + // + this.tabelOptions.ColumnCount = 3; + this.tabelOptions.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33332F)); + this.tabelOptions.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F)); + this.tabelOptions.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F)); + this.tabelOptions.Controls.Add(this.chkDumpCosturaAsm, 2, 3); + this.tabelOptions.Controls.Add(this.chkDecryptStrings, 2, 2); + this.tabelOptions.Controls.Add(this.chkPatchAntiTD, 2, 1); + this.tabelOptions.Controls.Add(this.chkDecryptBools, 1, 4); + this.tabelOptions.Controls.Add(this.chkDumpDNRAsm, 1, 3); + this.tabelOptions.Controls.Add(this.chkDecryptHiddenCalls, 1, 2); + this.tabelOptions.Controls.Add(this.chkDeobCFlow, 1, 1); + this.tabelOptions.Controls.Add(this.chkDecryptTokens, 0, 4); + this.tabelOptions.Controls.Add(this.chkDecryptResources, 0, 3); + this.tabelOptions.Controls.Add(this.chkRemoveRefProxies, 0, 2); + this.tabelOptions.Controls.Add(this.chkDecryptMethods, 0, 1); + this.tabelOptions.Controls.Add(this.chkSelectUnSelectAll, 0, 0); + this.tabelOptions.Controls.Add(this.chkRemSn, 2, 4); + this.tabelOptions.Controls.Add(this.chkRename, 0, 5); + this.tabelOptions.Controls.Add(this.chkRenameShort, 1, 5); + this.tabelOptions.Controls.Add(this.chkRemJunks, 0, 6); + this.tabelOptions.Controls.Add(this.chkKeepTypes, 2, 5); + this.tabelOptions.Controls.Add(this.chkRemCalls, 1, 6); + this.tabelOptions.Controls.Add(this.chkPreserveAll, 2, 6); + this.tabelOptions.Controls.Add(this.chkKeepOldMaxStack, 0, 7); + this.tabelOptions.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabelOptions.Location = new System.Drawing.Point(3, 0); + this.tabelOptions.Name = "tabelOptions"; + this.tabelOptions.RowCount = 8; + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571F)); + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571F)); + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571F)); + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571F)); + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571F)); + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571F)); + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571F)); + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tabelOptions.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tabelOptions.Size = new System.Drawing.Size(934, 179); + + this.tabelOptions.Size = new System.Drawing.Size(889, 179); + this.tabelOptions.TabIndex = 3; + // + // chkDumpCosturaAsm + // + this.chkDumpCosturaAsm.AutoSize = true; + this.chkDumpCosturaAsm.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDumpCosturaAsm.Checked = true; + this.chkDumpCosturaAsm.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDumpCosturaAsm.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDumpCosturaAsm.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDumpCosturaAsm.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDumpCosturaAsm.ForeColor = System.Drawing.Color.Silver; + this.chkDumpCosturaAsm.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDumpCosturaAsm.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDumpCosturaAsm.HoverForeColor = System.Drawing.Color.White; - this.chkDumpCosturaAsm.Location = new System.Drawing.Point(625, 69); + + this.chkDumpCosturaAsm.Location = new System.Drawing.Point(595, 69); + this.chkDumpCosturaAsm.Name = "chkDumpCosturaAsm"; + this.chkDumpCosturaAsm.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDumpCosturaAsm.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDumpCosturaAsm.PressForeColor = System.Drawing.Color.Gray; - this.chkDumpCosturaAsm.Size = new System.Drawing.Size(306, 16); + + this.chkDumpCosturaAsm.Size = new System.Drawing.Size(291, 16); + this.chkDumpCosturaAsm.TabIndex = 9; + this.chkDumpCosturaAsm.Tag = "--dump-costura"; + this.chkDumpCosturaAsm.Text = "Dump Costura-Fody Assemblies"; + this.chkDumpCosturaAsm.UseVisualStyleBackColor = true; + this.chkDumpCosturaAsm.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkDecryptStrings + // + this.chkDecryptStrings.AutoSize = true; + this.chkDecryptStrings.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDecryptStrings.Checked = true; + this.chkDecryptStrings.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDecryptStrings.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDecryptStrings.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDecryptStrings.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptStrings.ForeColor = System.Drawing.Color.Silver; + this.chkDecryptStrings.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptStrings.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptStrings.HoverForeColor = System.Drawing.Color.White; - this.chkDecryptStrings.Location = new System.Drawing.Point(625, 47); + + this.chkDecryptStrings.Location = new System.Drawing.Point(595, 47); + this.chkDecryptStrings.Name = "chkDecryptStrings"; + this.chkDecryptStrings.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptStrings.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptStrings.PressForeColor = System.Drawing.Color.Gray; - this.chkDecryptStrings.Size = new System.Drawing.Size(306, 16); + + this.chkDecryptStrings.Size = new System.Drawing.Size(291, 16); + this.chkDecryptStrings.TabIndex = 13; + this.chkDecryptStrings.Tag = "--dec-strings"; + this.chkDecryptStrings.Text = "Decrypt Strings"; + this.chkDecryptStrings.UseVisualStyleBackColor = true; + this.chkDecryptStrings.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkPatchAntiTD + // + this.chkPatchAntiTD.AutoSize = true; + this.chkPatchAntiTD.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkPatchAntiTD.Checked = true; + this.chkPatchAntiTD.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkPatchAntiTD.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkPatchAntiTD.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkPatchAntiTD.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkPatchAntiTD.ForeColor = System.Drawing.Color.Silver; + this.chkPatchAntiTD.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkPatchAntiTD.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkPatchAntiTD.HoverForeColor = System.Drawing.Color.White; - this.chkPatchAntiTD.Location = new System.Drawing.Point(625, 25); + + this.chkPatchAntiTD.Location = new System.Drawing.Point(595, 25); + this.chkPatchAntiTD.Name = "chkPatchAntiTD"; + this.chkPatchAntiTD.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkPatchAntiTD.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkPatchAntiTD.PressForeColor = System.Drawing.Color.Gray; - this.chkPatchAntiTD.Size = new System.Drawing.Size(306, 16); + + this.chkPatchAntiTD.Size = new System.Drawing.Size(291, 16); + this.chkPatchAntiTD.TabIndex = 11; + this.chkPatchAntiTD.Tag = "--rem-antis"; + this.chkPatchAntiTD.Text = "Remove Anti Tamper & Anti Debugger"; + this.chkPatchAntiTD.UseVisualStyleBackColor = true; + this.chkPatchAntiTD.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkDecryptBools + // + this.chkDecryptBools.AutoSize = true; + this.chkDecryptBools.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDecryptBools.Checked = true; + this.chkDecryptBools.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDecryptBools.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDecryptBools.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDecryptBools.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptBools.ForeColor = System.Drawing.Color.Silver; + this.chkDecryptBools.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptBools.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptBools.HoverForeColor = System.Drawing.Color.White; - this.chkDecryptBools.Location = new System.Drawing.Point(314, 91); + + this.chkDecryptBools.Location = new System.Drawing.Point(299, 91); + this.chkDecryptBools.Name = "chkDecryptBools"; + this.chkDecryptBools.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptBools.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptBools.PressForeColor = System.Drawing.Color.Gray; - this.chkDecryptBools.Size = new System.Drawing.Size(305, 16); + + this.chkDecryptBools.Size = new System.Drawing.Size(290, 16); + this.chkDecryptBools.TabIndex = 16; + this.chkDecryptBools.Tag = "--dec-bools"; + this.chkDecryptBools.Text = "Decrypt Booleans"; + this.chkDecryptBools.UseVisualStyleBackColor = true; + this.chkDecryptBools.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkDumpDNRAsm + // + this.chkDumpDNRAsm.AutoSize = true; + this.chkDumpDNRAsm.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDumpDNRAsm.Checked = true; + this.chkDumpDNRAsm.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDumpDNRAsm.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDumpDNRAsm.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDumpDNRAsm.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDumpDNRAsm.ForeColor = System.Drawing.Color.Silver; + this.chkDumpDNRAsm.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDumpDNRAsm.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDumpDNRAsm.HoverForeColor = System.Drawing.Color.White; - this.chkDumpDNRAsm.Location = new System.Drawing.Point(314, 69); + + this.chkDumpDNRAsm.Location = new System.Drawing.Point(299, 69); + this.chkDumpDNRAsm.Name = "chkDumpDNRAsm"; + this.chkDumpDNRAsm.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDumpDNRAsm.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDumpDNRAsm.PressForeColor = System.Drawing.Color.Gray; - this.chkDumpDNRAsm.Size = new System.Drawing.Size(305, 16); + + this.chkDumpDNRAsm.Size = new System.Drawing.Size(290, 16); + this.chkDumpDNRAsm.TabIndex = 10; + this.chkDumpDNRAsm.Tag = "--dump-asm"; + this.chkDumpDNRAsm.Text = "Dump Embedded Assemblies"; + this.chkDumpDNRAsm.UseVisualStyleBackColor = true; + this.chkDumpDNRAsm.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkDecryptHiddenCalls + // + this.chkDecryptHiddenCalls.AutoSize = true; + this.chkDecryptHiddenCalls.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDecryptHiddenCalls.Checked = true; + this.chkDecryptHiddenCalls.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDecryptHiddenCalls.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDecryptHiddenCalls.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDecryptHiddenCalls.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptHiddenCalls.ForeColor = System.Drawing.Color.Silver; + this.chkDecryptHiddenCalls.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptHiddenCalls.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptHiddenCalls.HoverForeColor = System.Drawing.Color.White; - this.chkDecryptHiddenCalls.Location = new System.Drawing.Point(314, 47); + + this.chkDecryptHiddenCalls.Location = new System.Drawing.Point(299, 47); + this.chkDecryptHiddenCalls.Name = "chkDecryptHiddenCalls"; + this.chkDecryptHiddenCalls.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptHiddenCalls.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptHiddenCalls.PressForeColor = System.Drawing.Color.Gray; - this.chkDecryptHiddenCalls.Size = new System.Drawing.Size(305, 16); + + this.chkDecryptHiddenCalls.Size = new System.Drawing.Size(290, 16); + this.chkDecryptHiddenCalls.TabIndex = 12; + this.chkDecryptHiddenCalls.Tag = "--fix-proxy"; + this.chkDecryptHiddenCalls.Text = "Fix proxied calls"; + this.chkDecryptHiddenCalls.UseVisualStyleBackColor = true; + this.chkDecryptHiddenCalls.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkDeobCFlow + // + this.chkDeobCFlow.AutoSize = true; + this.chkDeobCFlow.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDeobCFlow.Checked = true; + this.chkDeobCFlow.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDeobCFlow.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDeobCFlow.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDeobCFlow.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDeobCFlow.ForeColor = System.Drawing.Color.Silver; + this.chkDeobCFlow.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDeobCFlow.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDeobCFlow.HoverForeColor = System.Drawing.Color.White; - this.chkDeobCFlow.Location = new System.Drawing.Point(314, 25); + + this.chkDeobCFlow.Location = new System.Drawing.Point(299, 25); + this.chkDeobCFlow.Name = "chkDeobCFlow"; + this.chkDeobCFlow.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDeobCFlow.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDeobCFlow.PressForeColor = System.Drawing.Color.Gray; - this.chkDeobCFlow.Size = new System.Drawing.Size(305, 16); + + this.chkDeobCFlow.Size = new System.Drawing.Size(290, 16); + this.chkDeobCFlow.TabIndex = 4; + this.chkDeobCFlow.Tag = "--deob-cflow"; + this.chkDeobCFlow.Text = "Deobfuscate Control Flow"; + this.chkDeobCFlow.UseVisualStyleBackColor = true; + this.chkDeobCFlow.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkDecryptTokens + // + this.chkDecryptTokens.AutoSize = true; + this.chkDecryptTokens.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDecryptTokens.Checked = true; + this.chkDecryptTokens.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDecryptTokens.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDecryptTokens.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDecryptTokens.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptTokens.ForeColor = System.Drawing.Color.Silver; + this.chkDecryptTokens.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptTokens.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptTokens.HoverForeColor = System.Drawing.Color.White; + this.chkDecryptTokens.Location = new System.Drawing.Point(3, 91); + this.chkDecryptTokens.Name = "chkDecryptTokens"; + this.chkDecryptTokens.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptTokens.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptTokens.PressForeColor = System.Drawing.Color.Gray; - this.chkDecryptTokens.Size = new System.Drawing.Size(305, 16); + + this.chkDecryptTokens.Size = new System.Drawing.Size(290, 16); + this.chkDecryptTokens.TabIndex = 8; + this.chkDecryptTokens.Tag = "--deob-tokens"; + this.chkDecryptTokens.Text = "Deobfuscate Tokens"; + this.chkDecryptTokens.UseVisualStyleBackColor = true; + this.chkDecryptTokens.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkDecryptResources + // + this.chkDecryptResources.AutoSize = true; + this.chkDecryptResources.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDecryptResources.Checked = true; + this.chkDecryptResources.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDecryptResources.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDecryptResources.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDecryptResources.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptResources.ForeColor = System.Drawing.Color.Silver; + this.chkDecryptResources.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptResources.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptResources.HoverForeColor = System.Drawing.Color.White; + this.chkDecryptResources.Location = new System.Drawing.Point(3, 69); + this.chkDecryptResources.Name = "chkDecryptResources"; + this.chkDecryptResources.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptResources.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptResources.PressForeColor = System.Drawing.Color.Gray; - this.chkDecryptResources.Size = new System.Drawing.Size(305, 16); + + this.chkDecryptResources.Size = new System.Drawing.Size(290, 16); + this.chkDecryptResources.TabIndex = 6; + this.chkDecryptResources.Tag = "--dec-rsrc"; + this.chkDecryptResources.Text = "Decrypt Resources"; + this.chkDecryptResources.UseVisualStyleBackColor = true; + this.chkDecryptResources.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkRemoveRefProxies + // + this.chkRemoveRefProxies.AutoSize = true; + this.chkRemoveRefProxies.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkRemoveRefProxies.Checked = true; + this.chkRemoveRefProxies.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkRemoveRefProxies.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkRemoveRefProxies.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkRemoveRefProxies.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemoveRefProxies.ForeColor = System.Drawing.Color.Silver; + this.chkRemoveRefProxies.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemoveRefProxies.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRemoveRefProxies.HoverForeColor = System.Drawing.Color.White; + this.chkRemoveRefProxies.Location = new System.Drawing.Point(3, 47); + this.chkRemoveRefProxies.Name = "chkRemoveRefProxies"; + this.chkRemoveRefProxies.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemoveRefProxies.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRemoveRefProxies.PressForeColor = System.Drawing.Color.Gray; - this.chkRemoveRefProxies.Size = new System.Drawing.Size(305, 16); + + this.chkRemoveRefProxies.Size = new System.Drawing.Size(290, 16); + this.chkRemoveRefProxies.TabIndex = 5; + this.chkRemoveRefProxies.Tag = "--inline-methods"; + this.chkRemoveRefProxies.Text = "Inline Short Methods"; + this.chkRemoveRefProxies.UseVisualStyleBackColor = true; + this.chkRemoveRefProxies.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkDecryptMethods + // + this.chkDecryptMethods.AutoSize = true; + this.chkDecryptMethods.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkDecryptMethods.Checked = true; + this.chkDecryptMethods.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkDecryptMethods.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkDecryptMethods.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkDecryptMethods.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptMethods.ForeColor = System.Drawing.Color.Silver; + this.chkDecryptMethods.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptMethods.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptMethods.HoverForeColor = System.Drawing.Color.White; + this.chkDecryptMethods.Location = new System.Drawing.Point(3, 25); + this.chkDecryptMethods.Name = "chkDecryptMethods"; + this.chkDecryptMethods.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkDecryptMethods.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkDecryptMethods.PressForeColor = System.Drawing.Color.Gray; - this.chkDecryptMethods.Size = new System.Drawing.Size(305, 16); + + this.chkDecryptMethods.Size = new System.Drawing.Size(290, 16); + this.chkDecryptMethods.TabIndex = 7; + this.chkDecryptMethods.Tag = "--dec-methods"; + this.chkDecryptMethods.Text = "Decrypt Methods Body"; + this.chkDecryptMethods.UseVisualStyleBackColor = true; + this.chkDecryptMethods.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkSelectUnSelectAll + // + this.chkSelectUnSelectAll.AutoSize = true; + this.chkSelectUnSelectAll.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkSelectUnSelectAll.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkSelectUnSelectAll.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkSelectUnSelectAll.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkSelectUnSelectAll.ForeColor = System.Drawing.Color.Silver; + this.chkSelectUnSelectAll.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkSelectUnSelectAll.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkSelectUnSelectAll.HoverForeColor = System.Drawing.Color.White; + this.chkSelectUnSelectAll.Location = new System.Drawing.Point(3, 3); + this.chkSelectUnSelectAll.Name = "chkSelectUnSelectAll"; + this.chkSelectUnSelectAll.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkSelectUnSelectAll.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkSelectUnSelectAll.PressForeColor = System.Drawing.Color.Gray; - this.chkSelectUnSelectAll.Size = new System.Drawing.Size(305, 16); + + this.chkSelectUnSelectAll.Size = new System.Drawing.Size(290, 16); + this.chkSelectUnSelectAll.TabIndex = 17; + this.chkSelectUnSelectAll.Tag = ""; + this.chkSelectUnSelectAll.Text = "Select All"; + this.chkSelectUnSelectAll.UseVisualStyleBackColor = true; + this.chkSelectUnSelectAll.CheckedChanged += new System.EventHandler(this.chkSelectUnSelectAll_CheckedChanged); + // + // chkRemSn + // + this.chkRemSn.AutoSize = true; + this.chkRemSn.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkRemSn.Checked = true; + this.chkRemSn.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkRemSn.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkRemSn.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkRemSn.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemSn.ForeColor = System.Drawing.Color.Silver; + this.chkRemSn.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemSn.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRemSn.HoverForeColor = System.Drawing.Color.White; - this.chkRemSn.Location = new System.Drawing.Point(625, 91); + + this.chkRemSn.Location = new System.Drawing.Point(595, 91); + this.chkRemSn.Name = "chkRemSn"; + this.chkRemSn.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemSn.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRemSn.PressForeColor = System.Drawing.Color.Gray; - this.chkRemSn.Size = new System.Drawing.Size(306, 16); + + this.chkRemSn.Size = new System.Drawing.Size(291, 16); + this.chkRemSn.TabIndex = 2; + this.chkRemSn.Tag = "--rem-sn"; + this.chkRemSn.Text = "Remove Strong Name Removal Protection"; + this.chkRemSn.UseVisualStyleBackColor = true; + this.chkRemSn.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkRename + // + this.chkRename.AutoSize = true; + this.chkRename.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkRename.Checked = true; + this.chkRename.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkRename.ContextMenuStrip = this.ctxRename; + this.chkRename.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkRename.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkRename.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRename.ForeColor = System.Drawing.Color.Silver; + this.chkRename.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRename.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRename.HoverForeColor = System.Drawing.Color.White; + this.chkRename.Location = new System.Drawing.Point(3, 113); + this.chkRename.Name = "chkRename"; + this.chkRename.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRename.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRename.PressForeColor = System.Drawing.Color.Gray; - this.chkRename.Size = new System.Drawing.Size(305, 16); + + this.chkRename.Size = new System.Drawing.Size(290, 16); + this.chkRename.TabIndex = 17; + this.chkRename.Tag = "--rename ntmfe"; + this.chkRename.Text = "Rename obfuscated symbols name"; + this.chkRename.UseVisualStyleBackColor = true; + this.chkRename.CheckedChanged += new System.EventHandler(this.CheckedChanged); + this.chkRename.MouseClick += new System.Windows.Forms.MouseEventHandler(this.OpenCtxRename); + // + // ctxRename + // + this.ctxRename.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(23)))), ((int)(((byte)(23)))), ((int)(((byte)(23))))); + this.ctxRename.ImageScalingSize = new System.Drawing.Size(20, 20); + this.ctxRename.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripMenuItem8, + this.toolStripMenuItem9, + this.toolStripMenuItem10, + this.toolStripMenuItem13, + this.toolStripMenuItem15, + this.toolStripMenuItem14, + this.toolStripMenuItem16, + this.toolStripMenuItem12}); + this.ctxRename.Name = "ctxLogs"; + this.ctxRename.ShowImageMargin = false; - this.ctxRename.Size = new System.Drawing.Size(152, 158); + + this.ctxRename.Size = new System.Drawing.Size(132, 146); + this.ctxRename.Tag = "close"; + this.ctxRename.Closing += new System.Windows.Forms.ToolStripDropDownClosingEventHandler(this.ctxRename_Closing); + // + // toolStripMenuItem8 + // + this.toolStripMenuItem8.AutoSize = false; + this.toolStripMenuItem8.Enabled = false; + this.toolStripMenuItem8.Name = "toolStripMenuItem8"; + this.toolStripMenuItem8.Size = new System.Drawing.Size(185, 5); + this.toolStripMenuItem8.Text = " "; + // + // toolStripMenuItem9 + // + this.toolStripMenuItem9.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem9.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem9.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem9.Name = "toolStripMenuItem9"; - this.toolStripMenuItem9.Size = new System.Drawing.Size(151, 24); + + this.toolStripMenuItem9.Size = new System.Drawing.Size(131, 22); + this.toolStripMenuItem9.Tag = "n"; - this.toolStripMenuItem9.Text = " ✓ Namespaces"; + + this.toolStripMenuItem9.Text = " ? Namespaces"; + this.toolStripMenuItem9.Click += new System.EventHandler(this.SetRenamingOptions); + this.toolStripMenuItem9.MouseDown += new System.Windows.Forms.MouseEventHandler(this.KeepCtxRenameOpen); + // + // toolStripMenuItem10 + // + this.toolStripMenuItem10.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem10.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem10.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem10.Name = "toolStripMenuItem10"; - this.toolStripMenuItem10.Size = new System.Drawing.Size(151, 24); + + this.toolStripMenuItem10.Size = new System.Drawing.Size(131, 22); + this.toolStripMenuItem10.Tag = "t"; - this.toolStripMenuItem10.Text = " ✓ Types"; + + this.toolStripMenuItem10.Text = " ? Types"; + this.toolStripMenuItem10.Click += new System.EventHandler(this.SetRenamingOptions); + this.toolStripMenuItem10.MouseDown += new System.Windows.Forms.MouseEventHandler(this.KeepCtxRenameOpen); + // + // toolStripMenuItem13 + // + this.toolStripMenuItem13.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem13.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem13.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem13.Name = "toolStripMenuItem13"; - this.toolStripMenuItem13.Size = new System.Drawing.Size(151, 24); + + this.toolStripMenuItem13.Size = new System.Drawing.Size(131, 22); + this.toolStripMenuItem13.Tag = "m"; - this.toolStripMenuItem13.Text = " ✓ Methods"; + + this.toolStripMenuItem13.Text = " ? Methods"; + this.toolStripMenuItem13.Click += new System.EventHandler(this.SetRenamingOptions); + this.toolStripMenuItem13.MouseDown += new System.Windows.Forms.MouseEventHandler(this.KeepCtxRenameOpen); + // + // toolStripMenuItem15 + // + this.toolStripMenuItem15.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem15.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem15.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem15.Name = "toolStripMenuItem15"; - this.toolStripMenuItem15.Size = new System.Drawing.Size(151, 24); + + this.toolStripMenuItem15.Size = new System.Drawing.Size(131, 22); + this.toolStripMenuItem15.Tag = "f"; - this.toolStripMenuItem15.Text = " ✓ Fields"; + + this.toolStripMenuItem15.Text = " ? Fields"; + this.toolStripMenuItem15.Click += new System.EventHandler(this.SetRenamingOptions); + this.toolStripMenuItem15.MouseDown += new System.Windows.Forms.MouseEventHandler(this.KeepCtxRenameOpen); + // + // toolStripMenuItem14 + // + this.toolStripMenuItem14.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem14.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem14.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem14.Name = "toolStripMenuItem14"; - this.toolStripMenuItem14.Size = new System.Drawing.Size(151, 24); + + this.toolStripMenuItem14.Size = new System.Drawing.Size(131, 22); + this.toolStripMenuItem14.Tag = "p"; + this.toolStripMenuItem14.Text = " X Properties"; + this.toolStripMenuItem14.Click += new System.EventHandler(this.SetRenamingOptions); + this.toolStripMenuItem14.MouseDown += new System.Windows.Forms.MouseEventHandler(this.KeepCtxRenameOpen); + // + // toolStripMenuItem16 + // + this.toolStripMenuItem16.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem16.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem16.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem16.Name = "toolStripMenuItem16"; - this.toolStripMenuItem16.Size = new System.Drawing.Size(151, 24); + + this.toolStripMenuItem16.Size = new System.Drawing.Size(131, 22); + this.toolStripMenuItem16.Tag = "e"; - this.toolStripMenuItem16.Text = " ✓ Events"; + + this.toolStripMenuItem16.Text = " ? Events"; + this.toolStripMenuItem16.Click += new System.EventHandler(this.SetRenamingOptions); + this.toolStripMenuItem16.MouseDown += new System.Windows.Forms.MouseEventHandler(this.KeepCtxRenameOpen); + // + // toolStripMenuItem12 + // + this.toolStripMenuItem12.AutoSize = false; + this.toolStripMenuItem12.Enabled = false; + this.toolStripMenuItem12.Name = "toolStripMenuItem12"; + this.toolStripMenuItem12.Size = new System.Drawing.Size(185, 5); + this.toolStripMenuItem12.Text = " "; + // + // chkRenameShort + // + this.chkRenameShort.AutoSize = true; + this.chkRenameShort.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkRenameShort.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkRenameShort.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkRenameShort.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRenameShort.ForeColor = System.Drawing.Color.Silver; + this.chkRenameShort.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRenameShort.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRenameShort.HoverForeColor = System.Drawing.Color.White; - this.chkRenameShort.Location = new System.Drawing.Point(314, 113); + + this.chkRenameShort.Location = new System.Drawing.Point(299, 113); + this.chkRenameShort.Name = "chkRenameShort"; + this.chkRenameShort.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRenameShort.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRenameShort.PressForeColor = System.Drawing.Color.Gray; - this.chkRenameShort.Size = new System.Drawing.Size(305, 16); + + this.chkRenameShort.Size = new System.Drawing.Size(290, 16); + this.chkRenameShort.TabIndex = 18; + this.chkRenameShort.Tag = "--rename-short"; + this.chkRenameShort.Text = "Rename short names"; + this.chkRenameShort.UseVisualStyleBackColor = true; + this.chkRenameShort.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkRemJunks + // + this.chkRemJunks.AutoSize = true; + this.chkRemJunks.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkRemJunks.Checked = true; + this.chkRemJunks.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkRemJunks.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkRemJunks.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkRemJunks.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemJunks.ForeColor = System.Drawing.Color.Silver; + this.chkRemJunks.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemJunks.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRemJunks.HoverForeColor = System.Drawing.Color.White; + this.chkRemJunks.Location = new System.Drawing.Point(3, 135); + this.chkRemJunks.Name = "chkRemJunks"; + this.chkRemJunks.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemJunks.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRemJunks.PressForeColor = System.Drawing.Color.Gray; - this.chkRemJunks.Size = new System.Drawing.Size(305, 16); + + this.chkRemJunks.Size = new System.Drawing.Size(290, 16); + this.chkRemJunks.TabIndex = 2; + this.chkRemJunks.Tag = "--rem-junks"; + this.chkRemJunks.Text = "Remove Junks (BETA)"; + this.chkRemJunks.UseVisualStyleBackColor = true; + this.chkRemJunks.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkKeepTypes + // + this.chkKeepTypes.AutoSize = true; + this.chkKeepTypes.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkKeepTypes.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkKeepTypes.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkKeepTypes.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkKeepTypes.ForeColor = System.Drawing.Color.Silver; + this.chkKeepTypes.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkKeepTypes.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkKeepTypes.HoverForeColor = System.Drawing.Color.White; - this.chkKeepTypes.Location = new System.Drawing.Point(625, 113); + + this.chkKeepTypes.Location = new System.Drawing.Point(595, 113); + this.chkKeepTypes.Name = "chkKeepTypes"; + this.chkKeepTypes.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkKeepTypes.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkKeepTypes.PressForeColor = System.Drawing.Color.Gray; - this.chkKeepTypes.Size = new System.Drawing.Size(306, 16); + + this.chkKeepTypes.Size = new System.Drawing.Size(291, 16); + this.chkKeepTypes.TabIndex = 2; + this.chkKeepTypes.Tag = "--keep-types"; + this.chkKeepTypes.Text = "Keep Obfuscator Types"; + this.chkKeepTypes.UseVisualStyleBackColor = true; + this.chkKeepTypes.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkRemCalls + // + this.chkRemCalls.AutoSize = true; + this.chkRemCalls.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkRemCalls.Checked = true; + this.chkRemCalls.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkRemCalls.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkRemCalls.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkRemCalls.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemCalls.ForeColor = System.Drawing.Color.Silver; + this.chkRemCalls.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemCalls.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRemCalls.HoverForeColor = System.Drawing.Color.White; - this.chkRemCalls.Location = new System.Drawing.Point(314, 135); + + this.chkRemCalls.Location = new System.Drawing.Point(299, 135); + this.chkRemCalls.Name = "chkRemCalls"; + this.chkRemCalls.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkRemCalls.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkRemCalls.PressForeColor = System.Drawing.Color.Gray; - this.chkRemCalls.Size = new System.Drawing.Size(305, 16); + + this.chkRemCalls.Size = new System.Drawing.Size(290, 16); + this.chkRemCalls.TabIndex = 2; + this.chkRemCalls.Tag = "--rem-calls"; + this.chkRemCalls.Text = "Remove Calls To Obfuscator Types"; + this.chkRemCalls.UseVisualStyleBackColor = true; + this.chkRemCalls.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkPreserveAll + // + this.chkPreserveAll.AutoSize = true; + this.chkPreserveAll.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkPreserveAll.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkPreserveAll.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkPreserveAll.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkPreserveAll.ForeColor = System.Drawing.Color.Silver; + this.chkPreserveAll.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkPreserveAll.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkPreserveAll.HoverForeColor = System.Drawing.Color.White; - this.chkPreserveAll.Location = new System.Drawing.Point(625, 135); + + this.chkPreserveAll.Location = new System.Drawing.Point(595, 135); + this.chkPreserveAll.Name = "chkPreserveAll"; + this.chkPreserveAll.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkPreserveAll.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkPreserveAll.PressForeColor = System.Drawing.Color.Gray; - this.chkPreserveAll.Size = new System.Drawing.Size(306, 16); + + this.chkPreserveAll.Size = new System.Drawing.Size(291, 16); + this.chkPreserveAll.TabIndex = 15; + this.chkPreserveAll.Tag = "--preserve-all"; + this.chkPreserveAll.Text = "Preserve All MD Tokens"; + this.chkPreserveAll.UseVisualStyleBackColor = true; + this.chkPreserveAll.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // chkKeepOldMaxStack + // + this.chkKeepOldMaxStack.AutoSize = true; + this.chkKeepOldMaxStack.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(117)))), ((int)(((byte)(9)))), ((int)(((byte)(12))))); + this.chkKeepOldMaxStack.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkKeepOldMaxStack.Dock = System.Windows.Forms.DockStyle.Fill; + this.chkKeepOldMaxStack.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkKeepOldMaxStack.ForeColor = System.Drawing.Color.Silver; + this.chkKeepOldMaxStack.HoverBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkKeepOldMaxStack.HoverFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkKeepOldMaxStack.HoverForeColor = System.Drawing.Color.White; + this.chkKeepOldMaxStack.Location = new System.Drawing.Point(3, 157); + this.chkKeepOldMaxStack.Name = "chkKeepOldMaxStack"; + this.chkKeepOldMaxStack.PressBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(30)))), ((int)(((byte)(35))))); + this.chkKeepOldMaxStack.PressFillColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.chkKeepOldMaxStack.PressForeColor = System.Drawing.Color.Gray; - this.chkKeepOldMaxStack.Size = new System.Drawing.Size(305, 19); + + this.chkKeepOldMaxStack.Size = new System.Drawing.Size(290, 19); + this.chkKeepOldMaxStack.TabIndex = 14; + this.chkKeepOldMaxStack.Tag = "--keep-max-stack"; + this.chkKeepOldMaxStack.Text = "Keep Old Max Stack Value"; + this.chkKeepOldMaxStack.UseVisualStyleBackColor = true; + this.chkKeepOldMaxStack.CheckedChanged += new System.EventHandler(this.CheckedChanged); + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(27)))), ((int)(((byte)(27))))); + this.panel1.Controls.Add(this.llblGitHub); + this.panel1.Controls.Add(this.label2); + this.panel1.Controls.Add(this.label5); + this.panel1.Controls.Add(this.lblVersion); + this.panel1.Controls.Add(this.llblWebsite); + this.panel1.Controls.Add(this.label4); + this.panel1.Controls.Add(this.lblAuthor); + this.panel1.Controls.Add(this.label1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel1.Location = new System.Drawing.Point(30, 591); + this.panel1.Name = "panel1"; + this.panel1.Padding = new System.Windows.Forms.Padding(5, 10, 5, 0); - this.panel1.Size = new System.Drawing.Size(997, 40); + + this.panel1.Size = new System.Drawing.Size(952, 40); + this.panel1.TabIndex = 17; + // + // llblGitHub + // + this.llblGitHub.ActiveLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.llblGitHub.AutoSize = true; + this.llblGitHub.Dock = System.Windows.Forms.DockStyle.Left; + this.llblGitHub.Font = new System.Drawing.Font("Segoe UI Semibold", 7F, System.Drawing.FontStyle.Bold); + this.llblGitHub.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.llblGitHub.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); - this.llblGitHub.Location = new System.Drawing.Point(405, 10); + + this.llblGitHub.Location = new System.Drawing.Point(351, 10); + this.llblGitHub.Name = "llblGitHub"; - this.llblGitHub.Size = new System.Drawing.Size(45, 15); + + this.llblGitHub.Size = new System.Drawing.Size(38, 12); + this.llblGitHub.TabIndex = 7; + this.llblGitHub.TabStop = true; + this.llblGitHub.Tag = "https://github.com/SychicBoy/NETReactorSlayer"; + this.llblGitHub.Text = "GitHub"; + this.llblGitHub.VisitedLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.llblGitHub.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.llblGitHub_LinkClicked); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Dock = System.Windows.Forms.DockStyle.Left; + this.label2.Font = new System.Drawing.Font("Segoe UI Semibold", 7F, System.Drawing.FontStyle.Bold); + this.label2.ForeColor = System.Drawing.Color.Gray; - this.label2.Location = new System.Drawing.Point(316, 10); + + this.label2.Location = new System.Drawing.Point(272, 10); + this.label2.Name = "label2"; + this.label2.Padding = new System.Windows.Forms.Padding(20, 0, 0, 0); - this.label2.Size = new System.Drawing.Size(89, 15); + + this.label2.Size = new System.Drawing.Size(79, 12); + this.label2.TabIndex = 6; + this.label2.Text = "Repository: "; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Dock = System.Windows.Forms.DockStyle.Right; + this.label5.Font = new System.Drawing.Font("Segoe UI Semibold", 7F, System.Drawing.FontStyle.Bold); + this.label5.ForeColor = System.Drawing.Color.Gray; - this.label5.Location = new System.Drawing.Point(943, 10); + + this.label5.Location = new System.Drawing.Point(907, 10); + this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(49, 15); + + this.label5.Size = new System.Drawing.Size(40, 12); + this.label5.TabIndex = 4; + this.label5.Text = "Version:"; + // + // lblVersion + // + this.lblVersion.AutoSize = true; + this.lblVersion.Dock = System.Windows.Forms.DockStyle.Right; + this.lblVersion.Font = new System.Drawing.Font("Segoe UI Semibold", 7F, System.Drawing.FontStyle.Bold); + this.lblVersion.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); - this.lblVersion.Location = new System.Drawing.Point(992, 10); + + this.lblVersion.Location = new System.Drawing.Point(947, 10); + this.lblVersion.Name = "lblVersion"; - this.lblVersion.Size = new System.Drawing.Size(0, 15); + + this.lblVersion.Size = new System.Drawing.Size(0, 12); + this.lblVersion.TabIndex = 5; + // + // llblWebsite + // + this.llblWebsite.ActiveLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.llblWebsite.AutoSize = true; + this.llblWebsite.Dock = System.Windows.Forms.DockStyle.Left; + this.llblWebsite.Font = new System.Drawing.Font("Segoe UI Semibold", 7F, System.Drawing.FontStyle.Bold); + this.llblWebsite.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.llblWebsite.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); - this.llblWebsite.Location = new System.Drawing.Point(193, 10); + + this.llblWebsite.Location = new System.Drawing.Point(166, 10); + this.llblWebsite.Name = "llblWebsite"; - this.llblWebsite.Size = new System.Drawing.Size(123, 15); + + this.llblWebsite.Size = new System.Drawing.Size(106, 12); + this.llblWebsite.TabIndex = 3; + this.llblWebsite.TabStop = true; + this.llblWebsite.Tag = "https://www.CodeStrikers.org"; + this.llblWebsite.Text = "www.CodeStrikers.org"; + this.llblWebsite.VisitedLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); + this.llblWebsite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.llblWebsite_LinkClicked); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Dock = System.Windows.Forms.DockStyle.Left; + this.label4.Font = new System.Drawing.Font("Segoe UI Semibold", 7F, System.Drawing.FontStyle.Bold); + this.label4.ForeColor = System.Drawing.Color.Gray; - this.label4.Location = new System.Drawing.Point(117, 10); + + this.label4.Location = new System.Drawing.Point(99, 10); + this.label4.Name = "label4"; + this.label4.Padding = new System.Windows.Forms.Padding(20, 0, 0, 0); - this.label4.Size = new System.Drawing.Size(76, 15); + + this.label4.Size = new System.Drawing.Size(67, 12); + this.label4.TabIndex = 2; + this.label4.Text = "Website: "; + // + // lblAuthor + // + this.lblAuthor.AutoSize = true; + this.lblAuthor.Dock = System.Windows.Forms.DockStyle.Left; + this.lblAuthor.Font = new System.Drawing.Font("Segoe UI Semibold", 7F, System.Drawing.FontStyle.Bold); + this.lblAuthor.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(188)))), ((int)(((byte)(14)))), ((int)(((byte)(18))))); - this.lblAuthor.Location = new System.Drawing.Point(55, 10); + + this.lblAuthor.Location = new System.Drawing.Point(48, 10); + this.lblAuthor.Name = "lblAuthor"; - this.lblAuthor.Size = new System.Drawing.Size(62, 15); + + this.lblAuthor.Size = new System.Drawing.Size(51, 12); + this.lblAuthor.TabIndex = 1; + this.lblAuthor.Text = "SychicBoy"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Dock = System.Windows.Forms.DockStyle.Left; + this.label1.Font = new System.Drawing.Font("Segoe UI Semibold", 7F, System.Drawing.FontStyle.Bold); + this.label1.ForeColor = System.Drawing.Color.Gray; + this.label1.Location = new System.Drawing.Point(5, 10); + this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(50, 15); + + this.label1.Size = new System.Drawing.Size(43, 12); + this.label1.TabIndex = 0; + this.label1.Text = "Author: "; + // + // ctxMenu + // + this.ctxMenu.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(23)))), ((int)(((byte)(23)))), ((int)(((byte)(23))))); + this.ctxMenu.ImageScalingSize = new System.Drawing.Size(20, 20); + this.ctxMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripMenuItem3, + this.toolStripMenuItem6, + this.toolStripMenuItem7, + this.toolStripMenuItem4, + this.toolStripMenuItem5}); + this.ctxMenu.Name = "ctxLogs"; + this.ctxMenu.ShowImageMargin = false; - this.ctxMenu.Size = new System.Drawing.Size(169, 86); + + this.ctxMenu.Size = new System.Drawing.Size(147, 80); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.AutoSize = false; + this.toolStripMenuItem3.Enabled = false; + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(185, 5); + this.toolStripMenuItem3.Text = " "; + // + // toolStripMenuItem6 + // + this.toolStripMenuItem6.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem6.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem6.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem6.Name = "toolStripMenuItem6"; - this.toolStripMenuItem6.Size = new System.Drawing.Size(168, 24); + + this.toolStripMenuItem6.Size = new System.Drawing.Size(146, 22); + this.toolStripMenuItem6.Text = " Check For Update"; + this.toolStripMenuItem6.Click += new System.EventHandler(this.toolStripMenuItem6_Click); + // + // toolStripMenuItem7 + // + this.toolStripMenuItem7.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem7.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem7.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem7.Name = "toolStripMenuItem7"; - this.toolStripMenuItem7.Size = new System.Drawing.Size(168, 24); + + this.toolStripMenuItem7.Size = new System.Drawing.Size(146, 22); + this.toolStripMenuItem7.Text = " About"; + this.toolStripMenuItem7.Click += new System.EventHandler(this.toolStripMenuItem7_Click); + // + // toolStripMenuItem4 + // + this.toolStripMenuItem4.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripMenuItem4.Font = new System.Drawing.Font("Segoe UI Semibold", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.toolStripMenuItem4.ForeColor = System.Drawing.Color.Silver; + this.toolStripMenuItem4.Name = "toolStripMenuItem4"; - this.toolStripMenuItem4.Size = new System.Drawing.Size(168, 24); + + this.toolStripMenuItem4.Size = new System.Drawing.Size(146, 22); + this.toolStripMenuItem4.Text = " Exit"; + this.toolStripMenuItem4.Click += new System.EventHandler(this.toolStripMenuItem4_Click); + // + // toolStripMenuItem5 + // + this.toolStripMenuItem5.AutoSize = false; + this.toolStripMenuItem5.Enabled = false; + this.toolStripMenuItem5.Name = "toolStripMenuItem5"; + this.toolStripMenuItem5.Size = new System.Drawing.Size(185, 5); + this.toolStripMenuItem5.Text = " "; + // + // MainWindow + // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + + this.AutoScaleDimensions = new System.Drawing.SizeF(5F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(27)))), ((int)(((byte)(27)))), ((int)(((byte)(27))))); - this.ClientSize = new System.Drawing.Size(1057, 631); + + this.ClientSize = new System.Drawing.Size(1012, 631); + this.Controls.Add(this.pnlBase); + this.Controls.Add(this.pnlHeader); + this.Controls.Add(this.panel1); + this.Font = new System.Drawing.Font("Consolas", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ForeColor = System.Drawing.Color.White; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.Name = "MainWindow"; + this.Opacity = 0D; + this.Padding = new System.Windows.Forms.Padding(30, 5, 30, 0); + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = ".NET Reactor Slayer"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Closing); + this.Shown += new System.EventHandler(this.MainWindow_Shown); + this.pnlHeader.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.picMenu)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.picMinimize)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.picExit)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.picHeader)).EndInit(); + this.pnlBase.ResumeLayout(false); + this.pnlButton.ResumeLayout(false); + this.panelLogs.ResumeLayout(false); + this.ctxLogs.ResumeLayout(false); + this.pnlInput.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.picBrowse)).EndInit(); + this.pnlTextBox.ResumeLayout(false); + this.pnlOptions.ResumeLayout(false); + this.tabelOptions.ResumeLayout(false); + this.tabelOptions.PerformLayout(); + this.ctxRename.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ctxMenu.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } #endregion diff --git a/NETReactorSlayer.GUI/MainWindow.cs b/NETReactorSlayer.GUI/MainWindow.cs index 20abe12..4003d3f 100644 --- a/NETReactorSlayer.GUI/MainWindow.cs +++ b/NETReactorSlayer.GUI/MainWindow.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,6 +13,11 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using dnlib.DotNet; +using dnlib.PE; +using NETReactorSlayer.GUI.Dialogs; +using NETReactorSlayer.GUI.Properties; +using NETReactorSlayer.GUI.UserControls; using System; using System.Diagnostics; using System.Drawing; @@ -26,11 +31,6 @@ You should have received a copy of the GNU General Public License using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; -using dnlib.DotNet; -using dnlib.PE; -using NETReactorSlayer.GUI.Dialogs; -using NETReactorSlayer.GUI.Properties; -using NETReactorSlayer.GUI.UserControls; namespace NETReactorSlayer.GUI { @@ -486,8 +486,8 @@ private void CheckedChanged(object sender, EventArgs e) chkPreserveAll.Checked = false; if ((from x in tabelOptions.Controls.OfType() - where x.Name != "chkSelectUnSelectAll" - select x).Any(control => !control.Checked)) + where x.Name != "chkSelectUnSelectAll" + select x).Any(control => !control.Checked)) { _return = true; chkSelectUnSelectAll.Checked = false; @@ -515,19 +515,19 @@ private void chkSelectUnSelectAll_CheckedChanged(object sender, EventArgs e) chkRename.Tag = "--dont-rename"; chkRename.Checked = false; foreach (ToolStripMenuItem control in ctxRename.Items) - control.Text = control.Text.Replace("✓", "X"); + control.Text = control.Text.Replace("?", "X"); } else { chkRename.Tag = "--rename --rename ntmfpe"; chkRename.Checked = true; foreach (ToolStripMenuItem control in ctxRename.Items) - control.Text = control.Text.Replace("X", "✓"); + control.Text = control.Text.Replace("X", "?"); } foreach (var control in (from x in tabelOptions.Controls.OfType() - where x.Name != "chkSelectUnSelectAll" - select x).Where(control => control.Checked != @checked)) + where x.Name != "chkSelectUnSelectAll" + select x).Where(control => control.Checked != @checked)) { _return = true; control.Checked = @checked; @@ -604,14 +604,14 @@ private void SetRenamingOptions(object sender, EventArgs e) return; tag = tag.Replace("--rename ", string.Empty).Replace("--dont-rename", string.Empty); var text = control.Text; - if (text.Contains("✓")) + if (text.Contains("?")) { - control.Text = text.Replace("✓", "X"); + control.Text = text.Replace("?", "X"); chkRename.Tag = "--rename " + tag.Replace(option, string.Empty); } else if (text.Contains("X") && !tag.Contains(option)) { - control.Text = text.Replace("X", "✓"); + control.Text = text.Replace("X", "?"); chkRename.Tag = $"--rename {tag}{option}"; } diff --git a/NETReactorSlayer.GUI/MenuColorTable.cs b/NETReactorSlayer.GUI/MenuColorTable.cs index ee1a567..4d92c2f 100644 --- a/NETReactorSlayer.GUI/MenuColorTable.cs +++ b/NETReactorSlayer.GUI/MenuColorTable.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.GUI/NETReactorSlayer.GUI.csproj b/NETReactorSlayer.GUI/NETReactorSlayer.GUI.csproj index 9ba55a7..6589316 100644 --- a/NETReactorSlayer.GUI/NETReactorSlayer.GUI.csproj +++ b/NETReactorSlayer.GUI/NETReactorSlayer.GUI.csproj @@ -1,4 +1,4 @@ - + @@ -15,7 +15,8 @@ true true true - True + False + x86 @@ -44,7 +45,7 @@ .NET Framework 3.5 SP1 false - + diff --git a/NETReactorSlayer.GUI/Program.cs b/NETReactorSlayer.GUI/Program.cs index fdd8294..98fe066 100644 --- a/NETReactorSlayer.GUI/Program.cs +++ b/NETReactorSlayer.GUI/Program.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.GUI/Properties/AssemblyInfo.cs b/NETReactorSlayer.GUI/Properties/AssemblyInfo.cs index a7deee0..7cde3f4 100644 --- a/NETReactorSlayer.GUI/Properties/AssemblyInfo.cs +++ b/NETReactorSlayer.GUI/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; [assembly: AssemblyTitle(".NET Reactor Slayer")] diff --git a/NETReactorSlayer.GUI/Properties/Resources.Designer.cs b/NETReactorSlayer.GUI/Properties/Resources.Designer.cs index 93c5f9e..ff979ca 100644 --- a/NETReactorSlayer.GUI/Properties/Resources.Designer.cs +++ b/NETReactorSlayer.GUI/Properties/Resources.Designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 diff --git a/NETReactorSlayer.GUI/Properties/Settings.Designer.cs b/NETReactorSlayer.GUI/Properties/Settings.Designer.cs index a87a968..57d83c3 100644 --- a/NETReactorSlayer.GUI/Properties/Settings.Designer.cs +++ b/NETReactorSlayer.GUI/Properties/Settings.Designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 diff --git a/NETReactorSlayer.GUI/UserControls/NRSButton.Designer.cs b/NETReactorSlayer.GUI/UserControls/NRSButton.Designer.cs index 2d013d1..5274f2f 100644 --- a/NETReactorSlayer.GUI/UserControls/NRSButton.Designer.cs +++ b/NETReactorSlayer.GUI/UserControls/NRSButton.Designer.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.GUI/UserControls/NRSButton.cs b/NETReactorSlayer.GUI/UserControls/NRSButton.cs index 76ab82a..3171f84 100644 --- a/NETReactorSlayer.GUI/UserControls/NRSButton.cs +++ b/NETReactorSlayer.GUI/UserControls/NRSButton.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.GUI/UserControls/NRSCheckBox.cs b/NETReactorSlayer.GUI/UserControls/NRSCheckBox.cs index 302ce31..d9a7853 100644 --- a/NETReactorSlayer.GUI/UserControls/NRSCheckBox.cs +++ b/NETReactorSlayer.GUI/UserControls/NRSCheckBox.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.GUI/UserControls/NRSScrollBar.cs b/NETReactorSlayer.GUI/UserControls/NRSScrollBar.cs index a848623..1e56b41 100644 --- a/NETReactorSlayer.GUI/UserControls/NRSScrollBar.cs +++ b/NETReactorSlayer.GUI/UserControls/NRSScrollBar.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify @@ -13,11 +13,11 @@ You should have received a copy of the GNU General Public License along with NETReactorSlayer. If not, see . */ +using NETReactorSlayer.GUI.Properties; using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; -using NETReactorSlayer.GUI.Properties; namespace NETReactorSlayer.GUI.UserControls { @@ -118,46 +118,46 @@ protected override void OnMouseMove(MouseEventArgs e) switch (_isScrolling) { case false: - { - var thumbHot = _thumbArea.Contains(e.Location); - if (_thumbHot != thumbHot) - { - _thumbHot = thumbHot; - Invalidate(); - } - - var upArrowHot = _upArrowArea.Contains(e.Location); - if (_upArrowHot != upArrowHot) - { - _upArrowHot = upArrowHot; - Invalidate(); - } - - var downArrowHot = _downArrowArea.Contains(e.Location); - if (_downArrowHot != downArrowHot) { - _downArrowHot = downArrowHot; - Invalidate(); + var thumbHot = _thumbArea.Contains(e.Location); + if (_thumbHot != thumbHot) + { + _thumbHot = thumbHot; + Invalidate(); + } + + var upArrowHot = _upArrowArea.Contains(e.Location); + if (_upArrowHot != upArrowHot) + { + _upArrowHot = upArrowHot; + Invalidate(); + } + + var downArrowHot = _downArrowArea.Contains(e.Location); + if (_downArrowHot != downArrowHot) + { + _downArrowHot = downArrowHot; + Invalidate(); + } + + break; } - - break; - } case true when e.Button != MouseButtons.Left: // ReSharper disable once AssignNullToNotNullAttribute OnMouseUp(null); return; case true: - { - var difference = new Point(e.Location.X - _initialContact.X, e.Location.Y - _initialContact.Y); + { + var difference = new Point(e.Location.X - _initialContact.X, e.Location.Y - _initialContact.Y); - var thumbPos = _initialValue - _trackArea.Top; - var newPosition = thumbPos + difference.Y; + var thumbPos = _initialValue - _trackArea.Top; + var newPosition = thumbPos + difference.Y; - ScrollToPhysical(newPosition); - UpdateScrollBar(); + ScrollToPhysical(newPosition); + UpdateScrollBar(); - break; - } + break; + } } } @@ -183,11 +183,11 @@ private void ScrollTimerTick(object sender, EventArgs e) ScrollBy(-1); break; default: - { - if (_downArrowClicked) - ScrollBy(1); - break; - } + { + if (_downArrowClicked) + ScrollBy(1); + break; + } } } diff --git a/NETReactorSlayer.GUI/UserControls/NRSTextBox.Designer.cs b/NETReactorSlayer.GUI/UserControls/NRSTextBox.Designer.cs index 386b2c5..4982466 100644 --- a/NETReactorSlayer.GUI/UserControls/NRSTextBox.Designer.cs +++ b/NETReactorSlayer.GUI/UserControls/NRSTextBox.Designer.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayer.GUI/UserControls/NRSTextBox.cs b/NETReactorSlayer.GUI/UserControls/NRSTextBox.cs index 4f0249f..5e79885 100644 --- a/NETReactorSlayer.GUI/UserControls/NRSTextBox.cs +++ b/NETReactorSlayer.GUI/UserControls/NRSTextBox.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2021 CodeStrikers.org This file is part of NETReactorSlayer. NETReactorSlayer is free software: you can redistribute it and/or modify diff --git a/NETReactorSlayerCommon.props b/NETReactorSlayerCommon.props index 1279fa6..7986279 100644 --- a/NETReactorSlayerCommon.props +++ b/NETReactorSlayerCommon.props @@ -2,8 +2,8 @@ - net48;netcoreapp3.1;net6.0 - net6.0 + net48;net7.0 + net7.0 false false false From 60f8ebf40f699aa7b0a44202dc0f42042b31af5c Mon Sep 17 00:00:00 2001 From: gembleman <81058727+gembleman@users.noreply.github.com> Date: Sun, 6 Jul 2025 19:27:08 +0900 Subject: [PATCH 11/11] fix workflows, csproj --- .github/dependabot.yml | 15 +- .github/workflows/build.yml | 49 +++- .github/workflows/codeql-analysis.yml | 10 +- .../NETReactorSlayer-x64.CLI.csproj | 2 +- NETReactorSlayer-x64.CLI/packages.lock.json | 259 ++++++++++++++++++ .../NETReactorSlayer.CLI.csproj | 2 +- NETReactorSlayer.CLI/packages.lock.json | 259 ++++++++++++++++++ .../NETReactorSlayer.Core.csproj | 2 +- NETReactorSlayer.Core/packages.lock.json | 218 +++++++++++++++ .../NETReactorSlayer.De4dot.csproj | 2 +- NETReactorSlayer.De4dot/packages.lock.json | 59 ++++ NETReactorSlayer.GUI/packages.lock.json | 132 +++++++++ NETReactorSlayerCommon.props | 3 +- README.md | 1 - build.ps1 | 60 +++- 15 files changed, 1042 insertions(+), 31 deletions(-) create mode 100644 NETReactorSlayer-x64.CLI/packages.lock.json create mode 100644 NETReactorSlayer.CLI/packages.lock.json create mode 100644 NETReactorSlayer.Core/packages.lock.json create mode 100644 NETReactorSlayer.De4dot/packages.lock.json create mode 100644 NETReactorSlayer.GUI/packages.lock.json diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 507e20b..c10368e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -2,15 +2,18 @@ version: 2 updates: - - # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" - - # Maintain dependencies for nuget + interval: "weekly" + open-pull-requests-limit: 3 + - package-ecosystem: "nuget" directory: "/" schedule: - interval: "daily" + interval: "weekly" + open-pull-requests-limit: 5 + ignore: + - dependency-name: "*" + versions: ["*-preview*", "*-beta*", "*-alpha*"] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 84502d0..691a37f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ on: workflow_dispatch: env: - CI_REQ_DOTNET_SDK_VER: 6.0.x + CI_REQ_DOTNET_SDK_VER: 9.0.x jobs: build: @@ -27,37 +27,56 @@ jobs: shell: pwsh strategy: matrix: - platform: [netframework, net6.0-win32, net6.0-win64, net6.0-win-arm, net6.0-win-arm64, net6.0-linux64, net6.0-linux-arm, net6.0-linux-arm64, net6.0-osx64, netcoreapp3.1-win32, netcoreapp3.1-win64, netcoreapp3.1-win-arm, netcoreapp3.1-win-arm64, netcoreapp3.1-linux64, netcoreapp3.1-linux-arm, netcoreapp3.1-linux-arm64, netcoreapp3.1-osx64] + platform: [netframework, net9.0-win32, net9.0-win64, net9.0-win-arm64, net9.0-linux64, net9.0-linux-arm, net9.0-linux-arm64, net9.0-osx64, net6.0-win32, net6.0-win64, net6.0-win-arm, net6.0-win-arm64, net6.0-linux64, net6.0-linux-arm, net6.0-linux-arm64, net6.0-osx64, netcoreapp3.1-win32, netcoreapp3.1-win64, netcoreapp3.1-win-arm, netcoreapp3.1-win-arm64, netcoreapp3.1-linux64, netcoreapp3.1-linux-arm, netcoreapp3.1-linux-arm64, netcoreapp3.1-osx64] include: - platform: netframework build-dir: net48 + - platform: net9.0-win32 + build-dir: net9.0\win-x86\publish + + - platform: net9.0-win64 + build-dir: net9.0\win-x64\publish + + - platform: net9.0-win-arm64 + build-dir: net9.0\win-arm64\publish + + - platform: net9.0-linux64 + build-dir: net9.0\linux-x64\publish + + - platform: net9.0-linux-arm + build-dir: net9.0\linux-arm\publish + + - platform: net9.0-linux-arm64 + build-dir: net9.0\linux-arm64\publish + + - platform: net9.0-osx64 + build-dir: net9.0\osx-x64\publish - platform: net6.0-win32 build-dir: net6.0\win-x86\publish - platform: net6.0-win64 build-dir: net6.0\win-x64\publish - + - platform: net6.0-win-arm build-dir: net6.0\win-arm\publish - platform: net6.0-win-arm64 build-dir: net6.0\win-arm64\publish - + - platform: net6.0-linux64 build-dir: net6.0\linux-x64\publish - platform: net6.0-linux-arm build-dir: net6.0\linux-arm\publish - + - platform: net6.0-linux-arm64 build-dir: net6.0\linux-arm64\publish - platform: net6.0-osx64 build-dir: net6.0\osx-x64\publish - - + - platform: netcoreapp3.1-win32 build-dir: netcoreapp3.1\win-x86\publish @@ -89,15 +108,19 @@ jobs: submodules: true - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: ${{env.CI_REQ_DOTNET_SDK_VER}} + cache: true + cache-dependency-path: '**/packages.lock.json' - name: Setup MSBuild - uses: microsoft/setup-msbuild@v1.3 + uses: microsoft/setup-msbuild@v2 - name: Setup NuGet - uses: NuGet/setup-nuget@v1.2.0 + uses: nuget/setup-nuget@v2 + with: + nuget-version: 'latest' - name: Restore NuGet packages for NETReactorSlayer.GUI run: nuget restore NETReactorSlayer.GUI\NETReactorSlayer.GUI.csproj -PackagesDirectory .\packages\ @@ -114,17 +137,19 @@ jobs: run: Copy-Item -Path bin\Release\${{matrix.build-dir}}\* -Destination C:\builtfiles\NETReactorSlayer-${{matrix.platform}} -Recurse - name: Upload NETReactorSlayer - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ contains(matrix.platform, 'netframework') && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')) }} with: name: NETReactorSlayer-${{matrix.platform}} path: C:\builtfiles\NETReactorSlayer-${{matrix.platform}} if-no-files-found: error + compression-level: 6 - name: Upload NETReactorSlayer.CLI - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ !contains(matrix.platform, 'netframework') && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))}} with: name: NETReactorSlayer.CLI-${{matrix.platform}} path: C:\builtfiles\NETReactorSlayer-${{matrix.platform}} if-no-files-found: error + compression-level: 6 \ No newline at end of file diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index fd66167..50211ec 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -24,26 +24,28 @@ jobs: fail-fast: false matrix: language: [ 'csharp' ] - dotnet-version: [ '6.0.x' ] + dotnet-version: [ '9.0.x' ] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ matrix.dotnet-version }} + cache: true + cache-dependency-path: '**/packages.lock.json' - name: Build run: dotnet build NETReactorSlayer.sln - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" \ No newline at end of file diff --git a/NETReactorSlayer-x64.CLI/NETReactorSlayer-x64.CLI.csproj b/NETReactorSlayer-x64.CLI/NETReactorSlayer-x64.CLI.csproj index 78308ce..8158d8d 100644 --- a/NETReactorSlayer-x64.CLI/NETReactorSlayer-x64.CLI.csproj +++ b/NETReactorSlayer-x64.CLI/NETReactorSlayer-x64.CLI.csproj @@ -6,7 +6,7 @@ x86 ..\bin\$(Configuration)\ Exe - net9.0;net7.0;net48 + net9.0;net6.0;net7.0;net48;netcoreapp3.1 x64 diff --git a/NETReactorSlayer-x64.CLI/packages.lock.json b/NETReactorSlayer-x64.CLI/packages.lock.json new file mode 100644 index 0000000..28069fa --- /dev/null +++ b/NETReactorSlayer-x64.CLI/packages.lock.json @@ -0,0 +1,259 @@ +{ + "version": 1, + "dependencies": { + ".NETCoreApp,Version=v3.1": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==", + "dependencies": { + "System.Reflection.Emit": "4.7.0", + "System.Reflection.Emit.Lightweight": "4.7.0" + } + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==" + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==" + }, + "System.Reflection.Emit.Lightweight": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "a4OLB4IITxAXJeV74MDx49Oq2+PsF6Sml54XAFv+2RyWwtDBcabzoxiiJRhdhx+gaohLh4hEGCLQyBozXoQPqA==" + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + ".NETCoreApp,Version=v3.1/win-x64": {}, + ".NETFramework,Version=v4.8": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==" + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.2", + "contentHash": "BG/TNxDFv0svAzx8OiMXDlsHfGw623BZ8tCXw4YLhDFDvDhNUEV58jKYMGRnkbJNm7c3JNNJDiN7JBMzxRBR2w==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.2" + } + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + ".NETFramework,Version=v4.8/win-x64": {}, + "net6.0": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "6.0.11" + } + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "6.0.11", + "contentHash": "xqC1HIbJMBFhrpYs76oYP+NAskNVjc6v73HqLal7ECRDPIp4oRU5pPavkD//vNactCn9DA2aaald/I5N+uZ5/g==" + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net6.0/win-x64": {}, + "net7.0": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "8.0.5" + } + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.5", + "contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==", + "dependencies": { + "System.Text.Encodings.Web": "8.0.0" + } + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net7.0/win-x64": { + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==" + } + }, + "net9.0": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "9.0.1" + } + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "9.0.1", + "contentHash": "eqWHDZqYPv1PvuvoIIx5pF74plL3iEOZOl/0kQP+Y0TEbtgNnM2W6k8h8EPYs+LTJZsXuWa92n5W5sHTWvE3VA==" + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net9.0/win-x64": {} + } +} \ No newline at end of file diff --git a/NETReactorSlayer.CLI/NETReactorSlayer.CLI.csproj b/NETReactorSlayer.CLI/NETReactorSlayer.CLI.csproj index 3a12430..4d96cfd 100644 --- a/NETReactorSlayer.CLI/NETReactorSlayer.CLI.csproj +++ b/NETReactorSlayer.CLI/NETReactorSlayer.CLI.csproj @@ -6,7 +6,7 @@ x86 ..\bin\$(Configuration)\ Exe - net9.0;net7.0;net48 + net9.0;net6.0;net7.0;net48;netcoreapp3.1 x86 diff --git a/NETReactorSlayer.CLI/packages.lock.json b/NETReactorSlayer.CLI/packages.lock.json new file mode 100644 index 0000000..52a557d --- /dev/null +++ b/NETReactorSlayer.CLI/packages.lock.json @@ -0,0 +1,259 @@ +{ + "version": 1, + "dependencies": { + ".NETCoreApp,Version=v3.1": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==", + "dependencies": { + "System.Reflection.Emit": "4.7.0", + "System.Reflection.Emit.Lightweight": "4.7.0" + } + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==" + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==" + }, + "System.Reflection.Emit.Lightweight": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "a4OLB4IITxAXJeV74MDx49Oq2+PsF6Sml54XAFv+2RyWwtDBcabzoxiiJRhdhx+gaohLh4hEGCLQyBozXoQPqA==" + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + ".NETCoreApp,Version=v3.1/win-x86": {}, + ".NETFramework,Version=v4.8": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==" + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.2", + "contentHash": "BG/TNxDFv0svAzx8OiMXDlsHfGw623BZ8tCXw4YLhDFDvDhNUEV58jKYMGRnkbJNm7c3JNNJDiN7JBMzxRBR2w==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.2" + } + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + ".NETFramework,Version=v4.8/win-x86": {}, + "net6.0": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "6.0.11" + } + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "6.0.11", + "contentHash": "xqC1HIbJMBFhrpYs76oYP+NAskNVjc6v73HqLal7ECRDPIp4oRU5pPavkD//vNactCn9DA2aaald/I5N+uZ5/g==" + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net6.0/win-x86": {}, + "net7.0": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "8.0.5" + } + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.5", + "contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==", + "dependencies": { + "System.Text.Encodings.Web": "8.0.0" + } + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net7.0/win-x86": { + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==" + } + }, + "net9.0": { + "dnlib": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Transitive", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "9.0.1" + } + }, + "SharpZipLib": { + "type": "Transitive", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "9.0.1", + "contentHash": "eqWHDZqYPv1PvuvoIIx5pF74plL3iEOZOl/0kQP+Y0TEbtgNnM2W6k8h8EPYs+LTJZsXuWa92n5W5sHTWvE3VA==" + }, + "netreactorslayer.core": { + "type": "Project", + "dependencies": { + "Lib.Harmony": "[2.3.6, )", + "NETReactorSlayer.De4dot": "[6.4.0, )", + "SharpZipLib": "[1.4.2, )", + "dnlib": "[4.5.0, )" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net9.0/win-x86": {} + } +} \ No newline at end of file diff --git a/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj b/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj index 2d10c75..564948d 100644 --- a/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj +++ b/NETReactorSlayer.Core/NETReactorSlayer.Core.csproj @@ -8,7 +8,7 @@ Library True AnyCPU - net48;net7.0;net9.0 + net48;net6.0;net7.0;net9.0;netcoreapp3.1 diff --git a/NETReactorSlayer.Core/packages.lock.json b/NETReactorSlayer.Core/packages.lock.json new file mode 100644 index 0000000..7c93d73 --- /dev/null +++ b/NETReactorSlayer.Core/packages.lock.json @@ -0,0 +1,218 @@ +{ + "version": 1, + "dependencies": { + ".NETCoreApp,Version=v3.1": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==", + "dependencies": { + "System.Reflection.Emit": "4.7.0", + "System.Reflection.Emit.Lightweight": "4.7.0" + } + }, + "Lib.Harmony": { + "type": "Direct", + "requested": "[2.3.6, )", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==" + }, + "SharpZipLib": { + "type": "Direct", + "requested": "[1.4.2, )", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==" + }, + "System.Reflection.Emit.Lightweight": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "a4OLB4IITxAXJeV74MDx49Oq2+PsF6Sml54XAFv+2RyWwtDBcabzoxiiJRhdhx+gaohLh4hEGCLQyBozXoQPqA==" + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + ".NETFramework,Version=v4.8": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Direct", + "requested": "[2.3.6, )", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==" + }, + "SharpZipLib": { + "type": "Direct", + "requested": "[1.4.2, )", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.2" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.2", + "contentHash": "BG/TNxDFv0svAzx8OiMXDlsHfGw623BZ8tCXw4YLhDFDvDhNUEV58jKYMGRnkbJNm7c3JNNJDiN7JBMzxRBR2w==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.2" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net6.0": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Direct", + "requested": "[2.3.6, )", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "6.0.11" + } + }, + "SharpZipLib": { + "type": "Direct", + "requested": "[1.4.2, )", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "6.0.11", + "contentHash": "xqC1HIbJMBFhrpYs76oYP+NAskNVjc6v73HqLal7ECRDPIp4oRU5pPavkD//vNactCn9DA2aaald/I5N+uZ5/g==" + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net7.0": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Direct", + "requested": "[2.3.6, )", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "8.0.5" + } + }, + "SharpZipLib": { + "type": "Direct", + "requested": "[1.4.2, )", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.5", + "contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==", + "dependencies": { + "System.Text.Encodings.Web": "8.0.0" + } + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + }, + "net9.0": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "Lib.Harmony": { + "type": "Direct", + "requested": "[2.3.6, )", + "resolved": "2.3.6", + "contentHash": "HqXPz33Z+R8ZDCLS5pJZthg33AMdF1bQXUbz2V7Neb9E+sMQOf4S1wquhM4pLIZFX7BZcOQubclbVreiM1+qmw==", + "dependencies": { + "System.Text.Json": "9.0.1" + } + }, + "SharpZipLib": { + "type": "Direct", + "requested": "[1.4.2, )", + "resolved": "1.4.2", + "contentHash": "yjj+3zgz8zgXpiiC3ZdF/iyTBbz2fFvMxZFEBPUcwZjIvXOf37Ylm+K58hqMfIBt5JgU/Z2uoUS67JmTLe973A==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "9.0.1", + "contentHash": "eqWHDZqYPv1PvuvoIIx5pF74plL3iEOZOl/0kQP+Y0TEbtgNnM2W6k8h8EPYs+LTJZsXuWa92n5W5sHTWvE3VA==" + }, + "netreactorslayer.de4dot": { + "type": "Project", + "dependencies": { + "dnlib": "[4.5.0, )" + } + } + } + } +} \ No newline at end of file diff --git a/NETReactorSlayer.De4dot/NETReactorSlayer.De4dot.csproj b/NETReactorSlayer.De4dot/NETReactorSlayer.De4dot.csproj index 68e90fa..3605a24 100644 --- a/NETReactorSlayer.De4dot/NETReactorSlayer.De4dot.csproj +++ b/NETReactorSlayer.De4dot/NETReactorSlayer.De4dot.csproj @@ -7,7 +7,7 @@ ..\bin\$(Configuration)\ Library AnyCPU - net48;net7.0;net9.0 + net48;net6.0;net7.0;net9.0;netcoreapp3.1 diff --git a/NETReactorSlayer.De4dot/packages.lock.json b/NETReactorSlayer.De4dot/packages.lock.json new file mode 100644 index 0000000..a6c27ab --- /dev/null +++ b/NETReactorSlayer.De4dot/packages.lock.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "dependencies": { + ".NETCoreApp,Version=v3.1": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==", + "dependencies": { + "System.Reflection.Emit": "4.7.0", + "System.Reflection.Emit.Lightweight": "4.7.0" + } + }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==" + }, + "System.Reflection.Emit.Lightweight": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "a4OLB4IITxAXJeV74MDx49Oq2+PsF6Sml54XAFv+2RyWwtDBcabzoxiiJRhdhx+gaohLh4hEGCLQyBozXoQPqA==" + } + }, + ".NETFramework,Version=v4.8": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + } + }, + "net6.0": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + } + }, + "net7.0": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + } + }, + "net9.0": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + } + } + } +} \ No newline at end of file diff --git a/NETReactorSlayer.GUI/packages.lock.json b/NETReactorSlayer.GUI/packages.lock.json new file mode 100644 index 0000000..495e993 --- /dev/null +++ b/NETReactorSlayer.GUI/packages.lock.json @@ -0,0 +1,132 @@ +{ + "version": 1, + "dependencies": { + ".NETFramework,Version=v4.8": { + "dnlib": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "YkwstIbjyiJ12uGIAN8oSmImgVFkPHit7MJXPHvJqeKV1DMNqxZWszjHfykgiSs4Y/XmjnZts7pI2/AYme5/uA==" + }, + "System.Net.Http": { + "type": "Direct", + "requested": "[4.3.4, )", + "resolved": "4.3.4", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", + "dependencies": { + "System.Security.Cryptography.X509Certificates": "4.3.0" + } + }, + "System.Resources.Extensions": { + "type": "Direct", + "requested": "[5.0.0, )", + "resolved": "5.0.0", + "contentHash": "KBiqY/+W6hWVwucHBHO76JkgBGyawlxCcP946MhK8dNjalaBgZkyHaux8ko58PENTqQHHjoDa7cfIkAchfJPPA==", + "dependencies": { + "System.Memory": "4.5.4" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Security.Cryptography.Algorithms": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==", + "dependencies": { + "System.IO": "4.3.0", + "System.Runtime": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0" + } + }, + "System.Security.Cryptography.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==" + }, + "System.Security.Cryptography.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==" + }, + "System.Security.Cryptography.X509Certificates": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==", + "dependencies": { + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0" + } + } + }, + ".NETFramework,Version=v4.8/win-x86": { + "System.Net.Http": { + "type": "Direct", + "requested": "[4.3.4, )", + "resolved": "4.3.4", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", + "dependencies": { + "System.Security.Cryptography.X509Certificates": "4.3.0" + } + }, + "System.Security.Cryptography.Algorithms": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==", + "dependencies": { + "System.IO": "4.3.0", + "System.Runtime": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0" + } + }, + "System.Security.Cryptography.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==" + }, + "System.Security.Cryptography.X509Certificates": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==", + "dependencies": { + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0" + } + } + } + } +} \ No newline at end of file diff --git a/NETReactorSlayerCommon.props b/NETReactorSlayerCommon.props index 7986279..2b363ce 100644 --- a/NETReactorSlayerCommon.props +++ b/NETReactorSlayerCommon.props @@ -17,7 +17,8 @@ A deobfuscator and unpacker for Eziriz .NET Reactor CodeStrikers.org embedded - + true + \ No newline at end of file diff --git a/README.md b/README.md index cacaa2b..639591c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ GUI | CLI
### Binaries: -I make no changes to this fork. I simply build it and publish releases.
Get the latest stable version from [GitHub releases](https://github.com/gembleman/NETReactorSlayer/releases/latest).
Thanks to [JBou](https://github.com/JBou/NETReactorSlayer) diff --git a/build.ps1 b/build.ps1 index fd2f845..c16a77d 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,5 +1,5 @@ param( - [ValidateSet("all", "netframework", "net6.0-win32", "net6.0-win64", "net6.0-win-arm", "net6.0-win-arm64", "net6.0-linux64", "net6.0-linux-arm", "net6.0-linux-arm64", "net6.0-osx64", "netcoreapp3.1-win32", "netcoreapp3.1-win64", "netcoreapp3.1-win-arm", "netcoreapp3.1-win-arm64", "netcoreapp3.1-linux64", "netcoreapp3.1-linux-arm", "netcoreapp3.1-linux-arm64", "netcoreapp3.1-osx64")] + [ValidateSet("all", "netframework", "net9.0-win32", "net9.0-win64", "net9.0-win-arm64", "net9.0-linux64", "net9.0-linux-arm", "net9.0-linux-arm64", "net9.0-osx64", "net6.0-win32", "net6.0-win64", "net6.0-win-arm", "net6.0-win-arm64", "net6.0-linux64", "net6.0-linux-arm", "net6.0-linux-arm64", "net6.0-osx64", "netcoreapp3.1-win32", "netcoreapp3.1-win64", "netcoreapp3.1-win-arm", "netcoreapp3.1-win-arm64", "netcoreapp3.1-linux64", "netcoreapp3.1-linux-arm", "netcoreapp3.1-linux-arm64", "netcoreapp3.1-osx64")] [string]$framework = 'all', ${-no-msbuild} ) @@ -36,9 +36,35 @@ function BuildNETCore { Write-Host "Building .NET $architecture binaries" $runtimeidentifier = "$architecture" + + $platformTarget = "AnyCPU" + if ($architecture.Contains("x86") -and !$architecture.Contains("x64")) { + $platformTarget = "x86" + } elseif ($architecture.Contains("x64")) { + $platformTarget = "x64" + } elseif ($architecture.Contains("arm64")) { + $platformTarget = "ARM64" + } elseif ($architecture.Contains("arm")) { + $platformTarget = "ARM" + } + + # Fix: Only enable trimming for .NET Core 3.0+ and .NET 5+ + $publishTrimmed = "False" + $publishSingleFile = "False" + + # Check if the target framework supports trimming + $supportsTrimming = $false + if ($tfm -eq "netcoreapp3.1" -or $tfm.StartsWith("net5.") -or $tfm.StartsWith("net6.") -or $tfm.StartsWith("net7.") -or $tfm.StartsWith("net8.") -or $tfm.StartsWith("net9.") -or ($tfm.StartsWith("net") -and $tfm -match "^\d+\.\d+$" -and [int]($tfm.Split('.')[0].Substring(3)) -ge 5)) { + $supportsTrimming = $true + } + + if ($supportsTrimming) { + $publishTrimmed = "True" + $publishSingleFile = "True" + } if (${-no-msbuild}) { - dotnet publish NETReactorSlayer.CLI\NETReactorSlayer.CLI.csproj -v:m -c $configuration -f $tfm -r $runtimeidentifier --self-contained -p:IncludeNativeLibrariesForSelfExtract=true -p:PublishTrimmed=True -p:PublishSingleFile=true + dotnet publish NETReactorSlayer.CLI\NETReactorSlayer.CLI.csproj -v:m -c $configuration -f $tfm -r $runtimeidentifier --self-contained -p:IncludeNativeLibrariesForSelfExtract=true -p:PublishTrimmed=$publishTrimmed -p:PublishSingleFile=$publishSingleFile -p:PlatformTarget=$platformTarget if ($LASTEXITCODE) { Write-Host Write-Host ========================== @@ -47,7 +73,7 @@ function BuildNETCore { } } else { - msbuild NETReactorSlayer.CLI\NETReactorSlayer.CLI.csproj -v:m -m -restore -t:Publish -p:Configuration=$configuration -p:TargetFramework=$tfm -p:RuntimeIdentifier=$runtimeidentifier -p:SelfContained=True -p:IncludeNativeLibrariesForSelfExtract=true -p:PublishTrimmed=True -p:PublishSingleFile=true + msbuild NETReactorSlayer.CLI\NETReactorSlayer.CLI.csproj -v:m -m -restore -t:Publish -p:Configuration=$configuration -p:TargetFramework=$tfm -p:RuntimeIdentifier=$runtimeidentifier -p:SelfContained=True -p:IncludeNativeLibrariesForSelfExtract=true -p:PublishTrimmed=$publishTrimmed -p:PublishSingleFile=$publishSingleFile -p:PlatformTarget=$platformTarget if ($LASTEXITCODE) { Write-Host Write-Host ========================== @@ -59,6 +85,13 @@ function BuildNETCore { if($framework -eq 'all') { BuildNETFramework + BuildNETCore win-x86 "net9.0" + BuildNETCore win-x64 "net9.0" + BuildNETCore win-arm64 "net9.0" + BuildNETCore linux-x64 "net9.0" + BuildNETCore linux-arm "net9.0" + BuildNETCore linux-arm64 "net9.0" + BuildNETCore osx-x64 "net9.0" BuildNETCore win-x86 "net6.0" BuildNETCore win-x64 "net6.0" BuildNETCore win-arm "net6.0" @@ -84,6 +117,27 @@ else { if($framework -eq 'netframework'){ BuildNETFramework } + elseif($framework -eq 'net9.0-win32'){ + BuildNETCore win-x86 'net9.0' + } + elseif($framework -eq 'net9.0-win64'){ + BuildNETCore win-x64 'net9.0' + } + elseif($framework -eq 'net9.0-win-arm64'){ + BuildNETCore win-arm64 'net9.0' + } + elseif($framework -eq 'net9.0-linux64'){ + BuildNETCore linux-x64 'net9.0' + } + elseif($framework -eq 'net9.0-linux-arm'){ + BuildNETCore linux-arm 'net9.0' + } + elseif($framework -eq 'net9.0-linux-arm64'){ + BuildNETCore linux-arm64 'net9.0' + } + elseif($framework -eq 'net9.0-osx64'){ + BuildNETCore osx-x64 'net9.0' + } elseif($framework -eq 'net6.0-win32'){ BuildNETCore win-x86 'net6.0' }