diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj
index 7525dd6b..56fdba30 100644
--- a/de4dot.code/de4dot.code.csproj
+++ b/de4dot.code/de4dot.code.csproj
@@ -155,12 +155,12 @@
-
+
-
+
@@ -181,6 +181,7 @@
+
diff --git a/de4dot.code/deobfuscators/CodeVeil/ResourceDecrypter.cs b/de4dot.code/deobfuscators/CodeVeil/ResourceDecrypter.cs
index e19396c7..26d3b14b 100644
--- a/de4dot.code/deobfuscators/CodeVeil/ResourceDecrypter.cs
+++ b/de4dot.code/deobfuscators/CodeVeil/ResourceDecrypter.cs
@@ -36,7 +36,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
MethodDefinition resTypeCtor;
TypeDefinition resourceFlagsType;
TypeDefinition resourceEnumeratorType;
- GetManifestResourceRestorerBase getManifestResourceRestorer;
+ ResourceMethodsRestorerBase resourceMethodsRestorer;
public bool CanRemoveTypes {
get {
@@ -78,7 +78,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
public void initialize() {
- getManifestResourceRestorer = new GetManifestResourceRestorerBase(module);
+ resourceMethodsRestorer = new ResourceMethodsRestorerBase(module);
findEncryptedResourceStreamType();
findEncryptedResourceSet();
findEncryptedResourceReader();
@@ -264,8 +264,8 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (!findManifestResourceStreamMethods(type, out getManifestResourceStreamMethodTmp1, out getManifestResourceStreamMethodTmp2))
continue;
- getManifestResourceRestorer.GetStream1Method = getManifestResourceStreamMethodTmp1;
- getManifestResourceRestorer.GetStream2Method = getManifestResourceStreamMethodTmp2;
+ resourceMethodsRestorer.createGetManifestResourceStream1(getManifestResourceStreamMethodTmp1);
+ resourceMethodsRestorer.createGetManifestResourceStream2(getManifestResourceStreamMethodTmp2);
encryptedResourceStreamType = type;
return;
}
@@ -355,7 +355,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (encryptedResourceStreamType == null)
return;
- getManifestResourceRestorer.deobfuscate(blocks);
+ resourceMethodsRestorer.deobfuscate(blocks);
}
}
}
diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/Deobfuscator.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/Deobfuscator.cs
index 9f20e78d..0d21f5ef 100644
--- a/de4dot.code/deobfuscators/Eazfuscator_NET/Deobfuscator.cs
+++ b/de4dot.code/deobfuscators/Eazfuscator_NET/Deobfuscator.cs
@@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
StringDecrypter stringDecrypter;
AssemblyResolver assemblyResolver;
ResourceResolver resourceResolver;
- GetManifestResourceRestorer getManifestResourceRestorer;
+ ResourceMethodsRestorer resourceMethodsRestorer;
internal class Options : OptionsBase {
}
@@ -129,8 +129,8 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
addResourceToBeRemoved(info.Resource, "Encrypted resources");
addModuleCctorInitCallToBeRemoved(resourceResolver.InitMethod);
- getManifestResourceRestorer = new GetManifestResourceRestorer(module);
- getManifestResourceRestorer.find(DeobfuscatedFile, this);
+ resourceMethodsRestorer = new ResourceMethodsRestorer(module);
+ resourceMethodsRestorer.find(DeobfuscatedFile, this);
dumpEmbeddedAssemblies();
}
@@ -143,7 +143,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
}
public override void deobfuscateMethodEnd(Blocks blocks) {
- getManifestResourceRestorer.deobfuscate(blocks);
+ resourceMethodsRestorer.deobfuscate(blocks);
base.deobfuscateMethodEnd(blocks);
}
@@ -156,8 +156,8 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
addTypeToBeRemoved(assemblyResolver.Type, "Assembly resolver type");
addTypeToBeRemoved(assemblyResolver.OtherType, "Assembly resolver other type");
addTypeToBeRemoved(resourceResolver.Type, "Resource resolver type");
- addTypeToBeRemoved(getManifestResourceRestorer.Type, "GetManifestResourceStream type");
- addResourceToBeRemoved(getManifestResourceRestorer.Resource, "GetManifestResourceStream type resource");
+ addTypeToBeRemoved(resourceMethodsRestorer.Type, "GetManifestResourceStream type");
+ addResourceToBeRemoved(resourceMethodsRestorer.Resource, "GetManifestResourceStream type resource");
fixInterfaces();
base.deobfuscateEnd();
diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/GetManifestResourceRestorer.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/ResourceMethodsRestorer.cs
similarity index 92%
rename from de4dot.code/deobfuscators/Eazfuscator_NET/GetManifestResourceRestorer.cs
rename to de4dot.code/deobfuscators/Eazfuscator_NET/ResourceMethodsRestorer.cs
index 0278f6fc..e256d88d 100644
--- a/de4dot.code/deobfuscators/Eazfuscator_NET/GetManifestResourceRestorer.cs
+++ b/de4dot.code/deobfuscators/Eazfuscator_NET/ResourceMethodsRestorer.cs
@@ -21,7 +21,7 @@ using Mono.Cecil;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
- class GetManifestResourceRestorer : GetManifestResourceRestorerBase {
+ class ResourceMethodsRestorer : ResourceMethodsRestorerBase {
TypeDefinition getManifestResourceStreamType;
EmbeddedResource getManifestResourceStreamTypeResource;
@@ -33,7 +33,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
get { return getManifestResourceStreamTypeResource; }
}
- public GetManifestResourceRestorer(ModuleDefinition module)
+ public ResourceMethodsRestorer(ModuleDefinition module)
: base(module) {
}
@@ -58,9 +58,8 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
continue;
getManifestResourceStreamType = type;
- getManifestResourceStream1Method = null;
- getManifestResourceStream2Method = getStream2;
- getManifestResourceNamesMethod = getNames;
+ createGetManifestResourceStream2(getStream2);
+ createGetManifestResourceNames(getNames);
getManifestResourceStreamTypeResource = resource;
break;
}
diff --git a/de4dot.code/deobfuscators/GetManifestResourceRestorerBase.cs b/de4dot.code/deobfuscators/GetManifestResourceRestorerBase.cs
deleted file mode 100644
index fcc796ca..00000000
--- a/de4dot.code/deobfuscators/GetManifestResourceRestorerBase.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- 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 Mono.Cecil.Cil;
-using de4dot.blocks;
-
-namespace de4dot.code.deobfuscators {
- class GetManifestResourceRestorerBase {
- protected ModuleDefinition module;
- protected MethodDefinition getManifestResourceStream1Method;
- protected MethodDefinition getManifestResourceStream2Method;
- protected MethodDefinition getManifestResourceNamesMethod;
- protected MethodReference Assembly_GetManifestResourceStream1;
- protected MethodReference Assembly_GetManifestResourceStream2;
- protected MethodReference Assembly_GetManifestResourceNames;
-
- public MethodDefinition GetStream1Method {
- set { getManifestResourceStream1Method = value; }
- }
-
- public MethodDefinition GetStream2Method {
- set { getManifestResourceStream2Method = value; }
- }
-
- public MethodDefinition GetNamesMethod {
- set { getManifestResourceNamesMethod = value; }
- }
-
- public GetManifestResourceRestorerBase(ModuleDefinition module) {
- this.module = module;
- createGetManifestResourceStreamMethods();
- }
-
- void createGetManifestResourceStreamMethods() {
- var assemblyType = new TypeReference("System.Reflection", "Assembly", module, module.TypeSystem.Corlib);
- var typeType = new TypeReference("System", "Type", module, module.TypeSystem.Corlib);
- var streamType = new TypeReference("System.IO", "Stream", module, module.TypeSystem.Corlib);
- var stringArrayType = new ArrayType(module.TypeSystem.String);
-
- Assembly_GetManifestResourceStream1 = new MethodReference("GetManifestResourceStream", streamType, assemblyType);
- Assembly_GetManifestResourceStream1.HasThis = true;
- Assembly_GetManifestResourceStream1.Parameters.Add(new ParameterDefinition(module.TypeSystem.String));
-
- Assembly_GetManifestResourceStream2 = new MethodReference("GetManifestResourceStream", streamType, assemblyType);
- Assembly_GetManifestResourceStream2.HasThis = true;
- Assembly_GetManifestResourceStream2.Parameters.Add(new ParameterDefinition(typeType));
- Assembly_GetManifestResourceStream2.Parameters.Add(new ParameterDefinition(module.TypeSystem.String));
-
- Assembly_GetManifestResourceNames = new MethodReference("GetManifestResourceNames", stringArrayType, assemblyType);
- Assembly_GetManifestResourceNames.HasThis = true;
- }
-
- public void deobfuscate(Blocks blocks) {
- foreach (var block in blocks.MethodBlocks.getAllBlocks()) {
- var instrs = block.Instructions;
- for (int i = 0; i < instrs.Count; i++) {
- var call = instrs[i];
- if (call.OpCode.Code != Code.Call)
- continue;
- var calledMethod = call.Operand as MethodDefinition;
- if (calledMethod == null)
- continue;
-
- MethodReference newMethod = null;
- if (calledMethod == getManifestResourceStream1Method)
- newMethod = Assembly_GetManifestResourceStream1;
- else if (calledMethod == getManifestResourceStream2Method)
- newMethod = Assembly_GetManifestResourceStream2;
- else if (calledMethod == getManifestResourceNamesMethod)
- newMethod = Assembly_GetManifestResourceNames;
- if (newMethod == null)
- continue;
-
- instrs[i] = new Instr(Instruction.Create(OpCodes.Callvirt, newMethod));
- }
- }
- }
- }
-}
diff --git a/de4dot.code/deobfuscators/MemberReferenceBuilder.cs b/de4dot.code/deobfuscators/MemberReferenceBuilder.cs
new file mode 100644
index 00000000..623945e0
--- /dev/null
+++ b/de4dot.code/deobfuscators/MemberReferenceBuilder.cs
@@ -0,0 +1,192 @@
+/*
+ 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 System;
+using System.Collections.Generic;
+using Mono.Cecil;
+using de4dot.blocks;
+
+namespace de4dot.code.deobfuscators {
+ class MemberReferenceBuilder {
+ ModuleDefinition module;
+ Dictionary createdTypes = new Dictionary();
+
+ public MemberReferenceBuilder(ModuleDefinition module) {
+ this.module = module;
+ }
+
+ public IMetadataScope CorLib {
+ get { return module.TypeSystem.Corlib; }
+ }
+
+ public TypeReference Object {
+ get { return module.TypeSystem.Object; }
+ }
+
+ public TypeReference Void {
+ get { return module.TypeSystem.Void; }
+ }
+
+ public TypeReference Boolean {
+ get { return module.TypeSystem.Boolean; }
+ }
+
+ public TypeReference Char {
+ get { return module.TypeSystem.Char; }
+ }
+
+ public TypeReference SByte {
+ get { return module.TypeSystem.SByte; }
+ }
+
+ public TypeReference Byte {
+ get { return module.TypeSystem.Byte; }
+ }
+
+ public TypeReference Int16 {
+ get { return module.TypeSystem.Int16; }
+ }
+
+ public TypeReference UInt16 {
+ get { return module.TypeSystem.UInt16; }
+ }
+
+ public TypeReference Int32 {
+ get { return module.TypeSystem.Int32; }
+ }
+
+ public TypeReference UInt32 {
+ get { return module.TypeSystem.UInt32; }
+ }
+
+ public TypeReference Int64 {
+ get { return module.TypeSystem.Int64; }
+ }
+
+ public TypeReference UInt64 {
+ get { return module.TypeSystem.UInt64; }
+ }
+
+ public TypeReference Single {
+ get { return module.TypeSystem.Single; }
+ }
+
+ public TypeReference Double {
+ get { return module.TypeSystem.Double; }
+ }
+
+ public TypeReference IntPtr {
+ get { return module.TypeSystem.IntPtr; }
+ }
+
+ public TypeReference UIntPtr {
+ get { return module.TypeSystem.UIntPtr; }
+ }
+
+ public TypeReference String {
+ get { return module.TypeSystem.String; }
+ }
+
+ public TypeReference TypedReference {
+ get { return module.TypeSystem.TypedReference; }
+ }
+
+ public TypeReference type(string ns, string name, string asmSimpleName) {
+ return type(ns, name, findAssemblyReference(asmSimpleName));
+ }
+
+ public TypeReference type(string ns, string name) {
+ return type(ns, name, CorLib);
+ }
+
+ public TypeReference type(string ns, string name, IMetadataScope asmRef) {
+ return type(false, ns, name, asmRef);
+ }
+
+ public TypeReference valueType(string ns, string name, string asmSimpleName) {
+ return valueType(ns, name, findAssemblyReference(asmSimpleName));
+ }
+
+ public TypeReference valueType(string ns, string name) {
+ return valueType(ns, name, CorLib);
+ }
+
+ public TypeReference valueType(string ns, string name, IMetadataScope asmRef) {
+ return type(true, ns, name, asmRef);
+ }
+
+ public TypeReference type(bool isValueType, string ns, string name, IMetadataScope asmRef) {
+ var typeRef = new TypeReference(ns, name, module, asmRef);
+ typeRef.IsValueType = isValueType;
+ return add(isValueType, typeRef);
+ }
+
+ public TypeReference array(TypeReference typeRef) {
+ return add(false, new ArrayType(typeRef));
+ }
+
+ TypeReference add(bool isValueType, TypeReference typeRef) {
+ var key = new TypeReferenceKey(typeRef);
+ TypeReference createdTypeRef;
+ if (createdTypes.TryGetValue(key, out createdTypeRef)) {
+ if (createdTypeRef.IsValueType != isValueType)
+ throw new ApplicationException(string.Format("Type {0}'s IsValueType is not correct", createdTypeRef));
+ return createdTypeRef;
+ }
+ createdTypes[key] = typeRef;
+ return typeRef;
+ }
+
+ public MethodReference instanceMethod(string name, TypeReference declaringType, TypeReference returnType, params TypeReference[] args) {
+ return method(true, name, declaringType, returnType, args);
+ }
+
+ public MethodReference staticMethod(string name, TypeReference declaringType, TypeReference returnType, params TypeReference[] args) {
+ return method(false, name, declaringType, returnType, args);
+ }
+
+ public MethodReference method(bool isInstance, string name, TypeReference declaringType, TypeReference returnType, params TypeReference[] args) {
+ var method = new MethodReference(name, returnType, declaringType);
+ method.HasThis = isInstance;
+ foreach (var arg in args)
+ method.Parameters.Add(new ParameterDefinition(arg));
+ return method;
+ }
+
+ AssemblyNameReference findAssemblyReference(string asmSimpleName) {
+ AssemblyNameReference asmRef = null;
+ foreach (var asmRef2 in findAssemblyReferences(asmSimpleName)) {
+ if (asmRef == null || asmRef.Version == null || (asmRef2.Version != null && asmRef2.Version > asmRef.Version))
+ asmRef = asmRef2;
+ }
+ if (asmRef == null)
+ throw new ApplicationException(string.Format("Could not find assembly {0} in assembly references", asmSimpleName));
+ return asmRef;
+ }
+
+ List findAssemblyReferences(string asmSimpleName) {
+ var asmRefs = new List();
+ foreach (var asmRef in module.AssemblyReferences) {
+ if (asmRef.Name == asmSimpleName)
+ asmRefs.Add(asmRef);
+ }
+ return asmRefs;
+ }
+ }
+}
diff --git a/de4dot.code/deobfuscators/ResourceMethodsRestorerBase.cs b/de4dot.code/deobfuscators/ResourceMethodsRestorerBase.cs
new file mode 100644
index 00000000..ce42c453
--- /dev/null
+++ b/de4dot.code/deobfuscators/ResourceMethodsRestorerBase.cs
@@ -0,0 +1,85 @@
+/*
+ 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 System.Collections.Generic;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using de4dot.blocks;
+
+namespace de4dot.code.deobfuscators {
+ class ResourceMethodsRestorerBase {
+ protected MemberReferenceBuilder builder;
+ protected ModuleDefinition module;
+
+ MethodDefinitionAndDeclaringTypeDict oldToNewMethod = new MethodDefinitionAndDeclaringTypeDict();
+
+ public ResourceMethodsRestorerBase(ModuleDefinition module) {
+ this.module = module;
+ this.builder = new MemberReferenceBuilder(module);
+ }
+
+ public void createGetManifestResourceStream1(MethodDefinition oldMethod) {
+ var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
+ var streamType = builder.type("System.IO", "Stream", builder.CorLib);
+ var newMethod = builder.instanceMethod("GetManifestResourceStream", assemblyType, streamType, builder.String);
+ add(oldMethod, newMethod);
+ }
+
+ public void createGetManifestResourceStream2(MethodDefinition oldMethod) {
+ var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
+ var typeType = builder.type("System", "Type", builder.CorLib);
+ var streamType = builder.type("System.IO", "Stream", builder.CorLib);
+ var newMethod = builder.instanceMethod("GetManifestResourceStream", assemblyType, streamType, typeType, builder.String);
+ add(oldMethod, newMethod);
+ }
+
+ public void createGetManifestResourceNames(MethodDefinition oldMethod) {
+ var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
+ var stringArrayType = builder.array(builder.String);
+ var newMethod = builder.instanceMethod("GetManifestResourceNames", assemblyType, stringArrayType);
+ add(oldMethod, newMethod);
+ }
+
+ void add(MethodDefinition oldMethod, MethodReference newMethod) {
+ if (oldMethod == null)
+ return;
+ oldToNewMethod.add(oldMethod, newMethod);
+ }
+
+ public void deobfuscate(Blocks blocks) {
+ foreach (var block in blocks.MethodBlocks.getAllBlocks()) {
+ var instrs = block.Instructions;
+ for (int i = 0; i < instrs.Count; i++) {
+ var call = instrs[i];
+ if (call.OpCode.Code != Code.Call)
+ continue;
+ var calledMethod = call.Operand as MethodDefinition;
+ if (calledMethod == null)
+ continue;
+
+ var newMethod = oldToNewMethod.find(calledMethod);
+ if (newMethod == null)
+ continue;
+
+ instrs[i] = new Instr(Instruction.Create(OpCodes.Callvirt, newMethod));
+ }
+ }
+ }
+ }
+}