diff --git a/NETReactorSlayer.Core/Stages/AssemblyResolver.cs b/NETReactorSlayer.Core/Stages/AssemblyResolver.cs index b4c3674..2b523d9 100644 --- a/NETReactorSlayer.Core/Stages/AssemblyResolver.cs +++ b/NETReactorSlayer.Core/Stages/AssemblyResolver.cs @@ -35,8 +35,14 @@ 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).Where(s => !string.IsNullOrEmpty(s) && + !s.StartsWith("@") && + !s.StartsWith("-") && + !s.StartsWith(".") && + !s.Contains("ANDROID")).Distinct()) + { assemblies.AddRange(GetAssemblies(prefix)); + } if (assemblies.Count < 1) return; diff --git a/NETReactorSlayer.Core/Stages/MethodDecrypter.cs b/NETReactorSlayer.Core/Stages/MethodDecrypter.cs index 663f205..eb1caa0 100644 --- a/NETReactorSlayer.Core/Stages/MethodDecrypter.cs +++ b/NETReactorSlayer.Core/Stages/MethodDecrypter.cs @@ -33,7 +33,7 @@ public void Run(IContext context) Context = context; try { - if (!Find() && !Find2()) + if (!Find() && !Find2() && !Find3()) { Context.Logger.Warn("Couldn't find any encrypted method."); return; @@ -65,7 +65,9 @@ private bool Find() 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&)") + "(System.UInt64&,System.IntPtr,System.IntPtr,System.UInt32,System.IntPtr&,System.UInt32&)") || + DotNetUtils.IsMethod(method, "System.Int32", + "(System.IntPtr,System.IntPtr,System.Byte[],System.UInt32,System.IntPtr&)") from methodDef in from x in method.DeclaringType.Methods where x.IsStatic && x.HasBody && x.Body.HasInstructions select x @@ -114,6 +116,55 @@ private bool Find2() return false; } + private bool Find3() + { + Func hasRequiredLocals = method => + method.Body.Variables.Any(v => v.Type.FullName.Contains("System.IO.MemoryStream")) && + method.Body.Variables.Any(v => v.Type.FullName.Contains("System.Security.Cryptography.CryptoStream")) && + method.Body.Variables.Any(v => v.Type.FullName.Contains("System.Security.Cryptography.ICryptoTransform")); + + Func hasCryptoStreamCtor = method => + method.Body.Instructions.Any(i => + i.OpCode == OpCodes.Newobj && + i.Operand is IMethod ctor && + ctor.DeclaringType.FullName == "System.Security.Cryptography.CryptoStream"); + + Func hasCryptoStreamHelpers = method => + method.Body.Instructions + .Where(i => i.OpCode == OpCodes.Call) + .Select(i => i.Operand as IMethod) + .Where(md => md != null) + .Any(md => + md.MethodSig.Params.Any(p => + p.FullName == "System.Security.Cryptography.CryptoStream" || + p.FullName == "System.Security.Cryptography.CipherMode")); + + Func isKnownDecrypter = method => + EncryptedResource.IsKnownDecrypter(method, Array.Empty(), true); + + Func isDecrypterMethod = method => + method.IsStatic && + method.HasBody && + method.Body.HasInstructions && + hasRequiredLocals(method) && + hasCryptoStreamCtor(method) && + hasCryptoStreamHelpers(method) && + isKnownDecrypter(method); + + foreach (var methodDef in Context.Module.GetTypes() + .SelectMany(t => t.Methods) + .Where(isDecrypterMethod)) + { + _encryptedResource = new EncryptedResource(Context, methodDef); + + if (_encryptedResource.EmbeddedResource != null) + return true; + + _encryptedResource.Dispose(); + } + return false; + } + private bool FindBinaryReaderMethod(out int popCallsCount) { popCallsCount = 0;