diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 564996ad..7cfd4d34 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -142,6 +142,7 @@ + diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/Deobfuscator.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/Deobfuscator.cs index 30aa38fa..c4c85cb7 100644 --- a/de4dot.code/deobfuscators/Eazfuscator_NET/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/Eazfuscator_NET/Deobfuscator.cs @@ -55,6 +55,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { StringDecrypter stringDecrypter; AssemblyResolver assemblyResolver; ResourceResolver resourceResolver; + GetManifestResourceStreamRestorer getManifestResourceStreamRestorer; internal class Options : OptionsBase { } @@ -605,6 +606,9 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { addResourceToBeRemoved(info.Resource, "Encrypted resources"); addModuleCctorInitCallToBeRemoved(resourceResolver.InitMethod); + getManifestResourceStreamRestorer = new GetManifestResourceStreamRestorer(module); + getManifestResourceStreamRestorer.find(DeobfuscatedFile, this); + dumpEmbeddedAssemblies(); } @@ -615,6 +619,11 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { } } + public override void deobfuscateMethodEnd(Blocks blocks) { + getManifestResourceStreamRestorer.deobfuscate(blocks); + base.deobfuscateMethodEnd(blocks); + } + public override void deobfuscateEnd() { if (CanRemoveStringDecrypterType) { addTypesToBeRemoved(stringDecrypter.Types, "String decrypter type"); @@ -623,6 +632,8 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { } addTypeToBeRemoved(assemblyResolver.Type, "Assembly resolver type"); addTypeToBeRemoved(resourceResolver.Type, "Resource resolver type"); + addTypeToBeRemoved(getManifestResourceStreamRestorer.Type, "GetManifestResourceStream type"); + addResourceToBeRemoved(getManifestResourceStreamRestorer.Resource, "GetManifestResourceStream type resource"); base.deobfuscateEnd(); } diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/GetManifestResourceStreamRestorer.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/GetManifestResourceStreamRestorer.cs new file mode 100644 index 00000000..ad09d1fb --- /dev/null +++ b/de4dot.code/deobfuscators/Eazfuscator_NET/GetManifestResourceStreamRestorer.cs @@ -0,0 +1,105 @@ +/* + Copyright (C) 2011-2012 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 Mono.Cecil; +using de4dot.blocks; + +namespace de4dot.code.deobfuscators.Eazfuscator_NET { + class GetManifestResourceStreamRestorer : GetManifestResourceStreamRestorerBase { + TypeDefinition getManifestResourceStreamType; + EmbeddedResource getManifestResourceStreamTypeResource; + + public TypeDefinition Type { + get { return getManifestResourceStreamType; } + } + + public Resource Resource { + get { return getManifestResourceStreamTypeResource; } + } + + public GetManifestResourceStreamRestorer(ModuleDefinition module) + : base(module) { + } + + public void find(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { + foreach (var type in module.Types) { + if (type.Fields.Count != 1) + continue; + if (type.HasNestedTypes || type.HasGenericParameters || type.IsValueType) + continue; + if (DotNetUtils.getField(type, "System.Reflection.Assembly") == null) + continue; + if (DotNetUtils.getMethod(type, ".cctor") == null) + continue; + + var getStream2 = getTheOnlyMethod(type, "System.IO.Stream", "(System.Reflection.Assembly,System.Type,System.String)"); + var getNames = getTheOnlyMethod(type, "System.String[]", "(System.Reflection.Assembly)"); + if (getStream2 == null || getNames == null) + continue; + + var resource = findGetManifestResourceStreamTypeResource(type, simpleDeobfuscator, deob); + if (resource == null) + continue; + + getManifestResourceStreamType = type; + getManifestResourceStream1Method = null; + getManifestResourceStream2Method = getStream2; + getManifestResourceNamesMethod = getNames; + getManifestResourceStreamTypeResource = resource; + break; + } + } + + EmbeddedResource findGetManifestResourceStreamTypeResource(TypeDefinition type, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { + foreach (var method in type.Methods) { + if (!method.IsPrivate || !method.IsStatic || method.Body == null) + continue; + if (!DotNetUtils.isMethod(method, "System.String", "(System.Reflection.Assembly,System.Type,System.String)")) + continue; + simpleDeobfuscator.deobfuscate(method); + simpleDeobfuscator.decryptStrings(method, deob); + foreach (var s in DotNetUtils.getCodeStrings(method)) { + var resource = DotNetUtils.getResource(module, s) as EmbeddedResource; + if (resource != null) + return resource; + } + } + return null; + } + + static MethodDefinition getTheOnlyMethod(TypeDefinition type, string returnType, string parameters) { + MethodDefinition foundMethod = null; + + foreach (var method in type.Methods) { + if (!method.IsStatic || method.Body == null || method.HasGenericParameters) + continue; + if (method.IsPrivate) + continue; + if (!DotNetUtils.isMethod(method, returnType, parameters)) + continue; + + if (foundMethod != null) + return null; + foundMethod = method; + } + + return foundMethod; + } + } +}