diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 14b8a374..0213a9a4 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -70,6 +70,7 @@ + diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs b/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs index 3196a49c..3ddfad8a 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs @@ -50,6 +50,8 @@ namespace de4dot.deobfuscators.dotNET_Reactor { class Deobfuscator : DeobfuscatorBase { Options options; + MethodsDecrypter methodsDecrypter; + internal class Options : OptionsBase { } @@ -75,10 +77,15 @@ namespace de4dot.deobfuscators.dotNET_Reactor { int val = 0; + if (methodsDecrypter.Detected) + val = 100; + return val; } protected override void scanForObfuscatorInternal() { + methodsDecrypter = new MethodsDecrypter(module); + methodsDecrypter.find(); } public override void deobfuscateBegin() { diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs b/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs new file mode 100644 index 00000000..e9f9e2db --- /dev/null +++ b/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs @@ -0,0 +1,105 @@ +/* + Copyright (C) 2011 de4dot@gmail.com + + This file is part of de4dot. + + de4dot 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. + + de4dot 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 de4dot. If not, see . +*/ + +using System; +using System.Collections.Generic; +using Mono.Cecil; +using de4dot.blocks; + +namespace de4dot.deobfuscators.dotNET_Reactor { + class MethodsDecrypter { + ModuleDefinition module; + MethodDefinition methodsDecrypterMethod; + + public bool Detected { + get { return methodsDecrypterMethod != null; } + } + + public MethodsDecrypter(ModuleDefinition module) { + this.module = module; + } + + public void find() { + var checkedMethods = new Dictionary(); + var callCounter = new CallCounter(); + int typesLeft = 30; + foreach (var type in module.GetTypes()) { + if (typesLeft-- <= 0) + break; + var cctor = DotNetUtils.getMethod(type, ".cctor"); + if (cctor == null || cctor.Body == null) + continue; + + foreach (var info in DotNetUtils.getCalledMethods(module, cctor)) { + var method = info.Item2; + var key = new MethodReferenceAndDeclaringTypeKey(method); + if (!checkedMethods.ContainsKey(key)) { + checkedMethods[key] = true; + if (!couldBeMethodsDecrypter(method)) + continue; + } + callCounter.add(method); + } + } + + methodsDecrypterMethod = (MethodDefinition)callCounter.most(); + } + + bool couldBeMethodsDecrypter(MethodDefinition method) { + if (!method.IsStatic) + return false; + if (method.Body == null) + return false; + if (method.Body.Instructions.Count < 2000) + return false; + + var localTypes = new Dictionary(StringComparer.Ordinal); + foreach (var local in method.Body.Variables) + localTypes[local.VariableType.FullName] = true; + var requiredTypes = new string[] { + "System.Byte[]", + "System.Diagnostics.StackFrame", + "System.IntPtr", + "System.IO.BinaryReader", + "System.IO.MemoryStream", + "System.Reflection.Assembly", + "System.Security.Cryptography.CryptoStream", + "System.Security.Cryptography.ICryptoTransform", + "System.Security.Cryptography.RijndaelManaged", + }; + foreach (var typeName in requiredTypes) { + if (!localTypes.ContainsKey(typeName)) + return false; + } + + if (!isResourceString(DotNetUtils.getCodeStrings(method))) + return false; + + return true; + } + + bool isResourceString(IList strings) { + foreach (var s in strings) { + if (DotNetUtils.getResource(module, s) != null) + return true; + } + return false; + } + } +}