Rename cecil names; add new MemberRefFinder class
This commit is contained in:
parent
ab318e43e5
commit
00177034b9
|
@ -58,20 +58,20 @@ namespace de4dot.code {
|
||||||
return type.ElementType;
|
return type.ElementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition resolve(TypeReference type) {
|
public TypeDef resolve(TypeReference type) {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return null;
|
return null;
|
||||||
var typeDef = getNonGenericTypeReference(type) as TypeDefinition;
|
var typeDef = getNonGenericTypeReference(type) as TypeDef;
|
||||||
if (typeDef != null)
|
if (typeDef != null)
|
||||||
return typeDef;
|
return typeDef;
|
||||||
|
|
||||||
return externalAssemblies.resolve(type);
|
return externalAssemblies.resolve(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition resolve(MethodReference method) {
|
public MethodDef resolve(MethodReference method) {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return null;
|
return null;
|
||||||
var methodDef = method as MethodDefinition;
|
var methodDef = method as MethodDef;
|
||||||
if (methodDef != null)
|
if (methodDef != null)
|
||||||
return methodDef;
|
return methodDef;
|
||||||
|
|
||||||
|
@ -87,10 +87,10 @@ namespace de4dot.code {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldDefinition resolve(FieldReference field) {
|
public FieldDef resolve(FieldReference field) {
|
||||||
if (field == null)
|
if (field == null)
|
||||||
return null;
|
return null;
|
||||||
var fieldDef = field as FieldDefinition;
|
var fieldDef = field as FieldDef;
|
||||||
if (fieldDef != null)
|
if (fieldDef != null)
|
||||||
return fieldDef;
|
return fieldDef;
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,7 @@
|
||||||
<None Include="renamer\asmmodules\FieldDef.cs" />
|
<None Include="renamer\asmmodules\FieldDef.cs" />
|
||||||
<None Include="renamer\asmmodules\GenericParamDef.cs" />
|
<None Include="renamer\asmmodules\GenericParamDef.cs" />
|
||||||
<None Include="renamer\asmmodules\IResolver.cs" />
|
<None Include="renamer\asmmodules\IResolver.cs" />
|
||||||
<None Include="renamer\asmmodules\MemberRefFinder.cs" />
|
<Compile Include="renamer\asmmodules\MemberRefFinder.cs" />
|
||||||
<None Include="renamer\asmmodules\MethodDef.cs" />
|
<None Include="renamer\asmmodules\MethodDef.cs" />
|
||||||
<None Include="renamer\asmmodules\MethodNameGroups.cs" />
|
<None Include="renamer\asmmodules\MethodNameGroups.cs" />
|
||||||
<None Include="renamer\asmmodules\Module.cs" />
|
<None Include="renamer\asmmodules\Module.cs" />
|
||||||
|
|
|
@ -19,15 +19,15 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class AssemblyResolver {
|
class AssemblyResolver {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
TypeDefinition resolverType;
|
TypeDef resolverType;
|
||||||
MethodDefinition registerMethod;
|
MethodDef registerMethod;
|
||||||
EmbeddedResource encryptedResource;
|
EmbeddedResource encryptedResource;
|
||||||
EmbeddedAssemblyInfo[] embeddedAssemblyInfos = new EmbeddedAssemblyInfo[0];
|
EmbeddedAssemblyInfo[] embeddedAssemblyInfos = new EmbeddedAssemblyInfo[0];
|
||||||
|
|
||||||
|
@ -47,11 +47,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return resolverType != null; }
|
get { return resolverType != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return resolverType; }
|
get { return resolverType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitMethod {
|
public MethodDef InitMethod {
|
||||||
get { return registerMethod; }
|
get { return registerMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (!new FieldTypes(type).exactly(requiredTypes))
|
if (!new FieldTypes(type).exactly(requiredTypes))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MethodDefinition regMethod, handler;
|
MethodDef regMethod, handler;
|
||||||
if (!BabelUtils.findRegisterMethod(type, out regMethod, out handler))
|
if (!BabelUtils.findRegisterMethod(type, out regMethod, out handler))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findDecryptMethod(TypeDefinition type) {
|
static MethodDef findDecryptMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!DotNetUtils.isMethod(method, "System.Void", "(System.IO.Stream)"))
|
if (!DotNetUtils.isMethod(method, "System.Void", "(System.IO.Stream)"))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
|
||||||
|
@ -35,12 +35,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
branchEmulator = new BranchEmulator(emulator, this);
|
branchEmulator = new BranchEmulator(emulator, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<MethodDefinition> find(ModuleDefinition module, IEnumerable<MethodDefinition> notInlinedMethods) {
|
public static List<MethodDef> find(ModuleDefinition module, IEnumerable<MethodDef> notInlinedMethods) {
|
||||||
var notInlinedMethodsDict = new Dictionary<MethodDefinition, bool>();
|
var notInlinedMethodsDict = new Dictionary<MethodDef, bool>();
|
||||||
foreach (var method in notInlinedMethods)
|
foreach (var method in notInlinedMethods)
|
||||||
notInlinedMethodsDict[method] = true;
|
notInlinedMethodsDict[method] = true;
|
||||||
|
|
||||||
var inlinedMethods = new List<MethodDefinition>();
|
var inlinedMethods = new List<MethodDef>();
|
||||||
|
|
||||||
foreach (var type in module.GetTypes()) {
|
foreach (var type in module.GetTypes()) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
|
@ -83,7 +83,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool canInline(MethodDefinition method) {
|
static bool canInline(MethodDef method) {
|
||||||
if (!DotNetUtils.isMethod(method, "System.Int32", "(System.Int32)"))
|
if (!DotNetUtils.isMethod(method, "System.Int32", "(System.Int32)"))
|
||||||
return false;
|
return false;
|
||||||
if (!method.IsAssembly)
|
if (!method.IsAssembly)
|
||||||
|
@ -94,12 +94,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return method.IsStatic;
|
return method.IsStatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool canInline2(MethodDefinition method) {
|
bool canInline2(MethodDef method) {
|
||||||
return canInline(method) && method != blocks.Method;
|
return canInline(method) && method != blocks.Method;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inlineMethod(Instruction callInstr, int instrIndex) {
|
bool inlineMethod(Instruction callInstr, int instrIndex) {
|
||||||
var methodToInline = callInstr.Operand as MethodDefinition;
|
var methodToInline = callInstr.Operand as MethodDef;
|
||||||
if (methodToInline == null)
|
if (methodToInline == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getNewValue(MethodDefinition method, int arg, out int newValue) {
|
bool getNewValue(MethodDef method, int arg, out int newValue) {
|
||||||
newValue = 0;
|
newValue = 0;
|
||||||
emulator.init(method);
|
emulator.init(method);
|
||||||
emulator.setArg(method.Parameters[0], new Int32Value(arg));
|
emulator.setArg(method.Parameters[0], new Int32Value(arg));
|
||||||
|
|
|
@ -19,24 +19,24 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
static class BabelUtils {
|
static class BabelUtils {
|
||||||
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDefinition decrypterType) {
|
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType) {
|
||||||
return findEmbeddedResource(module, decrypterType, (method) => { });
|
return findEmbeddedResource(module, decrypterType, (method) => { });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDefinition decrypterType, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
|
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
|
||||||
return findEmbeddedResource(module, decrypterType, (method) => {
|
return findEmbeddedResource(module, decrypterType, (method) => {
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
simpleDeobfuscator.decryptStrings(method, deob);
|
simpleDeobfuscator.decryptStrings(method, deob);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDefinition decrypterType, Action<MethodDefinition> fixMethod) {
|
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType, Action<MethodDef> fixMethod) {
|
||||||
foreach (var method in decrypterType.Methods) {
|
foreach (var method in decrypterType.Methods) {
|
||||||
if (!DotNetUtils.isMethod(method, "System.String", "()"))
|
if (!DotNetUtils.isMethod(method, "System.String", "()"))
|
||||||
continue;
|
continue;
|
||||||
|
@ -50,7 +50,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EmbeddedResource findEmbeddedResource1(ModuleDefinition module, MethodDefinition method) {
|
static EmbeddedResource findEmbeddedResource1(ModuleDefinition module, MethodDef method) {
|
||||||
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
||||||
var resource = DotNetUtils.getResource(module, s) as EmbeddedResource;
|
var resource = DotNetUtils.getResource(module, s) as EmbeddedResource;
|
||||||
if (resource != null)
|
if (resource != null)
|
||||||
|
@ -59,7 +59,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EmbeddedResource findEmbeddedResource2(ModuleDefinition module, MethodDefinition method) {
|
static EmbeddedResource findEmbeddedResource2(ModuleDefinition module, MethodDef method) {
|
||||||
var strings = new List<string>(DotNetUtils.getCodeStrings(method));
|
var strings = new List<string>(DotNetUtils.getCodeStrings(method));
|
||||||
if (strings.Count != 1)
|
if (strings.Count != 1)
|
||||||
return null;
|
return null;
|
||||||
|
@ -75,7 +75,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return DotNetUtils.getResource(module, sb.ToString()) as EmbeddedResource;
|
return DotNetUtils.getResource(module, sb.ToString()) as EmbeddedResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool getXorKey2(MethodDefinition method, out int xorKey) {
|
static bool getXorKey2(MethodDef method, out int xorKey) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||||
var ldelem = instrs[i];
|
var ldelem = instrs[i];
|
||||||
|
@ -97,7 +97,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool findRegisterMethod(TypeDefinition type, out MethodDefinition regMethod, out MethodDefinition handler) {
|
public static bool findRegisterMethod(TypeDef type, out MethodDef regMethod, out MethodDef handler) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -21,8 +21,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Serialization.Formatters.Binary;
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
@ -30,12 +30,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
InitializedDataCreator initializedDataCreator;
|
InitializedDataCreator initializedDataCreator;
|
||||||
TypeDefinition decrypterType;
|
TypeDef decrypterType;
|
||||||
MethodDefinition int32Decrypter;
|
MethodDef int32Decrypter;
|
||||||
MethodDefinition int64Decrypter;
|
MethodDef int64Decrypter;
|
||||||
MethodDefinition singleDecrypter;
|
MethodDef singleDecrypter;
|
||||||
MethodDefinition doubleDecrypter;
|
MethodDef doubleDecrypter;
|
||||||
MethodDefinition arrayDecrypter;
|
MethodDef arrayDecrypter;
|
||||||
EmbeddedResource encryptedResource;
|
EmbeddedResource encryptedResource;
|
||||||
int[] decryptedInts;
|
int[] decryptedInts;
|
||||||
long[] decryptedLongs;
|
long[] decryptedLongs;
|
||||||
|
@ -54,27 +54,27 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return encryptedResource; }
|
get { return encryptedResource; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return decrypterType; }
|
get { return decrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Int32Decrypter {
|
public MethodDef Int32Decrypter {
|
||||||
get { return int32Decrypter; }
|
get { return int32Decrypter; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Int64Decrypter {
|
public MethodDef Int64Decrypter {
|
||||||
get { return int64Decrypter; }
|
get { return int64Decrypter; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition SingleDecrypter {
|
public MethodDef SingleDecrypter {
|
||||||
get { return singleDecrypter; }
|
get { return singleDecrypter; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition DoubleDecrypter {
|
public MethodDef DoubleDecrypter {
|
||||||
get { return doubleDecrypter; }
|
get { return doubleDecrypter; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition ArrayDecrypter {
|
public MethodDef ArrayDecrypter {
|
||||||
get { return arrayDecrypter; }
|
get { return arrayDecrypter; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isConstantDecrypter(TypeDefinition type) {
|
bool isConstantDecrypter(TypeDef type) {
|
||||||
if (type.HasEvents)
|
if (type.HasEvents)
|
||||||
return false;
|
return false;
|
||||||
if (type.NestedTypes.Count != 1)
|
if (type.NestedTypes.Count != 1)
|
||||||
|
@ -131,7 +131,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
"System.Single[]",
|
"System.Single[]",
|
||||||
"System.Double[]",
|
"System.Double[]",
|
||||||
};
|
};
|
||||||
bool checkNestedFields(TypeDefinition nested) {
|
bool checkNestedFields(TypeDef nested) {
|
||||||
if (!new FieldTypes(nested).all(requiredTypes))
|
if (!new FieldTypes(nested).all(requiredTypes))
|
||||||
return false;
|
return false;
|
||||||
foreach (var field in nested.Fields) {
|
foreach (var field in nested.Fields) {
|
||||||
|
@ -193,11 +193,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ArrayInfo {
|
struct ArrayInfo {
|
||||||
public FieldDefinition encryptedField;
|
public FieldDef encryptedField;
|
||||||
public ArrayType arrayType;
|
public ArrayType arrayType;
|
||||||
public int start, len;
|
public int start, len;
|
||||||
|
|
||||||
public ArrayInfo(int start, int len, FieldDefinition encryptedField, ArrayType arrayType) {
|
public ArrayInfo(int start, int len, FieldDef encryptedField, ArrayType arrayType) {
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.len = len;
|
this.len = len;
|
||||||
this.encryptedField = encryptedField;
|
this.encryptedField = encryptedField;
|
||||||
|
@ -232,7 +232,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
var ldtoken = instrs[index++];
|
var ldtoken = instrs[index++];
|
||||||
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
||||||
continue;
|
continue;
|
||||||
var field = ldtoken.Operand as FieldDefinition;
|
var field = ldtoken.Operand as FieldDef;
|
||||||
if (field == null)
|
if (field == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (arrayType == null)
|
if (arrayType == null)
|
||||||
continue;
|
continue;
|
||||||
if (arrayType.ElementType.GetPrimitiveSize() == -1) {
|
if (arrayType.ElementType.GetPrimitiveSize() == -1) {
|
||||||
Log.w("Can't decrypt non-primitive type array in method {0}", blocks.Method.MetadataToken.ToInt32());
|
Log.w("Can't decrypt non-primitive type array in method {0}", blocks.Method.MDToken.ToInt32());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkVersion(TypeDefinition attr) {
|
void checkVersion(TypeDef attr) {
|
||||||
var versionField = DotNetUtils.getFieldByName(attr, "Version");
|
var versionField = DotNetUtils.getFieldByName(attr, "Version");
|
||||||
if (versionField != null && versionField.IsLiteral && versionField.Constant != null && versionField.Constant is string) {
|
if (versionField != null && versionField.IsLiteral && versionField.Constant != null && versionField.Constant is string) {
|
||||||
var val = Regex.Match((string)versionField.Constant, @"^(\d+\.\d+\.\d+\.\d+)$");
|
var val = Regex.Match((string)versionField.Constant, @"^(\d+\.\d+\.\d+\.\d+)$");
|
||||||
|
@ -296,7 +296,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
if (stringDecrypter.DecryptMethod != null)
|
if (stringDecrypter.DecryptMethod != null)
|
||||||
list.Add(stringDecrypter.DecryptMethod.MetadataToken.ToInt32());
|
list.Add(stringDecrypter.DecryptMethod.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
@ -104,7 +104,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
initializeTypeReferences(typeReferencesOffset);
|
initializeTypeReferences(typeReferencesOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void restore(string name, MethodDefinition method) {
|
public void restore(string name, MethodDef method) {
|
||||||
var babelMethod = getMethod(name);
|
var babelMethod = getMethod(name);
|
||||||
var body = method.Body;
|
var body = method.Body;
|
||||||
|
|
||||||
|
@ -170,10 +170,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return memberReferenceConverter.convert(fields[0]);
|
return memberReferenceConverter.convert(fields[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<FieldDefinition> getFields(TypeDefinition type, string name) {
|
static List<FieldDef> getFields(TypeDef type, string name) {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return null;
|
return null;
|
||||||
var fields = new List<FieldDefinition>();
|
var fields = new List<FieldDef>();
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
if (field.Name == name)
|
if (field.Name == name)
|
||||||
fields.Add(field);
|
fields.Add(field);
|
||||||
|
@ -215,7 +215,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return methods[0];
|
return methods[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MethodReference> getMethods(TypeDefinition declaringType, BabelMethodreference babelMethodRef) {
|
List<MethodReference> getMethods(TypeDef declaringType, BabelMethodreference babelMethodRef) {
|
||||||
var methods = new List<MethodReference>();
|
var methods = new List<MethodReference>();
|
||||||
|
|
||||||
var git = babelMethodRef.DeclaringType as GenericInstanceType;
|
var git = babelMethodRef.DeclaringType as GenericInstanceType;
|
||||||
|
@ -257,9 +257,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinition resolve(TypeReference type) {
|
TypeDef resolve(TypeReference type) {
|
||||||
if (type is TypeDefinition)
|
if (type is TypeDef)
|
||||||
return (TypeDefinition)type;
|
return (TypeDef)type;
|
||||||
|
|
||||||
if (type.IsGenericInstance)
|
if (type.IsGenericInstance)
|
||||||
type = ((GenericInstanceType)type).ElementType;
|
type = ((GenericInstanceType)type).ElementType;
|
||||||
|
@ -400,7 +400,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValueType(TypeReference typeRef) {
|
bool isValueType(TypeReference typeRef) {
|
||||||
var typeDef = typeRef as TypeDefinition;
|
var typeDef = typeRef as TypeDef;
|
||||||
if (typeDef != null)
|
if (typeDef != null)
|
||||||
return typeDef.IsValueType;
|
return typeDef.IsValueType;
|
||||||
|
|
||||||
|
|
|
@ -18,17 +18,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using ICSharpCode.SharpZipLib.Zip.Compression;
|
using ICSharpCode.SharpZipLib.Zip.Compression;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class InflaterCreator {
|
class InflaterCreator {
|
||||||
public static Inflater create(MethodDefinition method, bool noHeader) {
|
public static Inflater create(MethodDef method, bool noHeader) {
|
||||||
return create(findInflaterType(method), noHeader);
|
return create(findInflaterType(method), noHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Inflater create(TypeDefinition inflaterType, bool noHeader) {
|
public static Inflater create(TypeDef inflaterType, bool noHeader) {
|
||||||
if (inflaterType == null)
|
if (inflaterType == null)
|
||||||
return createNormal(noHeader);
|
return createNormal(noHeader);
|
||||||
var initHeaderMethod = findInitHeaderMethod(inflaterType);
|
var initHeaderMethod = findInitHeaderMethod(inflaterType);
|
||||||
|
@ -50,13 +50,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return new Inflater(noHeader);
|
return new Inflater(noHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeDefinition findInflaterType(MethodDefinition method) {
|
static TypeDef findInflaterType(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return null;
|
return null;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null || !calledMethod.IsStatic)
|
if (calledMethod == null || !calledMethod.IsStatic)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findInitHeaderMethod(TypeDefinition inflaterType) {
|
static MethodDef findInitHeaderMethod(TypeDef inflaterType) {
|
||||||
foreach (var nested in inflaterType.NestedTypes) {
|
foreach (var nested in inflaterType.NestedTypes) {
|
||||||
var method = findInitHeaderMethod2(nested);
|
var method = findInitHeaderMethod2(nested);
|
||||||
if (method != null)
|
if (method != null)
|
||||||
|
@ -79,7 +79,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findInitHeaderMethod2(TypeDefinition nested) {
|
static MethodDef findInitHeaderMethod2(TypeDef nested) {
|
||||||
foreach (var method in nested.Methods) {
|
foreach (var method in nested.Methods) {
|
||||||
if (method.IsStatic || method.Body == null)
|
if (method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -92,7 +92,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int? getMagic(MethodDefinition method) {
|
static int? getMagic(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return null;
|
return null;
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
@ -35,7 +35,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
public TypeReference convert(TypeReference a) {
|
public TypeReference convert(TypeReference a) {
|
||||||
var newOne = update(a);
|
var newOne = update(a);
|
||||||
if (!(a is GenericParameter) && !MemberReferenceHelper.compareTypes(newOne, a))
|
if (!(a is GenericParam) && !MemberReferenceHelper.compareTypes(newOne, a))
|
||||||
throw new ApplicationException("Could not convert type reference");
|
throw new ApplicationException("Could not convert type reference");
|
||||||
return newOne;
|
return newOne;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
var newTypeRef = new TypeReference(a.Namespace, a.Name, Module, memberReferenceConverter.convert(a.Scope), a.IsValueType);
|
var newTypeRef = new TypeReference(a.Namespace, a.Name, Module, memberReferenceConverter.convert(a.Scope), a.IsValueType);
|
||||||
foreach (var gp in a.GenericParameters)
|
foreach (var gp in a.GenericParameters)
|
||||||
newTypeRef.GenericParameters.Add(new GenericParameter(gp.Name, newTypeRef));
|
newTypeRef.GenericParameters.Add(new GenericParam(gp.Name, newTypeRef));
|
||||||
newTypeRef.DeclaringType = update(a.DeclaringType);
|
newTypeRef.DeclaringType = update(a.DeclaringType);
|
||||||
newTypeRef.UpdateElementType();
|
newTypeRef.UpdateElementType();
|
||||||
return newTypeRef;
|
return newTypeRef;
|
||||||
|
@ -84,7 +84,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference convert(MethodReference methodRef) {
|
public MethodReference convert(MethodReference methodRef) {
|
||||||
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDefinition))
|
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDef))
|
||||||
throw new ApplicationException("Invalid method reference type");
|
throw new ApplicationException("Invalid method reference type");
|
||||||
if (isInOurModule(methodRef))
|
if (isInOurModule(methodRef))
|
||||||
return tryGetMethodDefinition(methodRef);
|
return tryGetMethodDefinition(methodRef);
|
||||||
|
@ -93,7 +93,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference copy(MethodReference methodRef) {
|
public MethodReference copy(MethodReference methodRef) {
|
||||||
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDefinition))
|
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDef))
|
||||||
throw new ApplicationException("Invalid method reference type");
|
throw new ApplicationException("Invalid method reference type");
|
||||||
|
|
||||||
var newMethodRef = new MethodReference(methodRef.Name, convert(methodRef.MethodReturnType.ReturnType), convert(methodRef.DeclaringType));
|
var newMethodRef = new MethodReference(methodRef.Name, convert(methodRef.MethodReturnType.ReturnType), convert(methodRef.DeclaringType));
|
||||||
|
@ -103,7 +103,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
foreach (var param in methodRef.Parameters)
|
foreach (var param in methodRef.Parameters)
|
||||||
newMethodRef.Parameters.Add(new ParameterDefinition(param.Name, param.Attributes, convert(param.ParameterType)));
|
newMethodRef.Parameters.Add(new ParameterDefinition(param.Name, param.Attributes, convert(param.ParameterType)));
|
||||||
foreach (var gp in methodRef.GenericParameters)
|
foreach (var gp in methodRef.GenericParameters)
|
||||||
newMethodRef.GenericParameters.Add(new GenericParameter(gp.Name, newMethodRef));
|
newMethodRef.GenericParameters.Add(new GenericParam(gp.Name, newMethodRef));
|
||||||
return newMethodRef;
|
return newMethodRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldReference tryGetFieldDefinition(FieldReference fieldRef) {
|
public FieldReference tryGetFieldDefinition(FieldReference fieldRef) {
|
||||||
var fieldDef = fieldRef as FieldDefinition;
|
var fieldDef = fieldRef as FieldDef;
|
||||||
if (fieldDef != null)
|
if (fieldDef != null)
|
||||||
return fieldDef;
|
return fieldDef;
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference tryGetMethodDefinition(MethodReference methodRef) {
|
public MethodReference tryGetMethodDefinition(MethodReference methodRef) {
|
||||||
var methodDef = methodRef as MethodDefinition;
|
var methodDef = methodRef as MethodDef;
|
||||||
if (methodDef != null)
|
if (methodDef != null)
|
||||||
return methodDef;
|
return methodDef;
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class MethodBodyReader : MethodBodyReaderBase {
|
class MethodBodyReader : MethodBodyReaderBase {
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Collections.Generic;
|
using Mono.Collections.Generic;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
@ -49,7 +49,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return new Collection<TypeReference>(GenericArguments); }
|
get { return new Collection<TypeReference>(GenericArguments); }
|
||||||
}
|
}
|
||||||
|
|
||||||
MetadataToken IMetadataTokenProvider.MetadataToken {
|
MetadataToken IMetadataTokenProvider.MDToken {
|
||||||
get { throw new NotImplementedException(); }
|
get { throw new NotImplementedException(); }
|
||||||
set { throw new NotImplementedException(); }
|
set { throw new NotImplementedException(); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
@ -30,9 +30,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
IDeobfuscatorContext deobfuscatorContext;
|
IDeobfuscatorContext deobfuscatorContext;
|
||||||
Dictionary<string, ImageReader> imageReaders = new Dictionary<string, ImageReader>(StringComparer.Ordinal);
|
Dictionary<string, ImageReader> imageReaders = new Dictionary<string, ImageReader>(StringComparer.Ordinal);
|
||||||
TypeDefinition methodsDecrypterCreator;
|
TypeDef methodsDecrypterCreator;
|
||||||
TypeDefinition methodsDecrypter;
|
TypeDef methodsDecrypter;
|
||||||
MethodDefinition decryptExecuteMethod;
|
MethodDef decryptExecuteMethod;
|
||||||
EmbeddedResource encryptedResource;
|
EmbeddedResource encryptedResource;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
|
@ -73,7 +73,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findDecryptMethod(TypeDefinition type) {
|
static MethodDef findDecryptMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
var decryptMethod = ResourceDecrypter.findDecrypterMethod(method);
|
var decryptMethod = ResourceDecrypter.findDecrypterMethod(method);
|
||||||
if (decryptMethod != null)
|
if (decryptMethod != null)
|
||||||
|
@ -82,7 +82,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinition findMethodsDecrypterType(TypeDefinition type) {
|
TypeDef findMethodsDecrypterType(TypeDef type) {
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
var fieldType = DotNetUtils.getType(module, field.FieldType);
|
var fieldType = DotNetUtils.getType(module, field.FieldType);
|
||||||
if (fieldType == null)
|
if (fieldType == null)
|
||||||
|
@ -124,7 +124,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class EncryptInfo {
|
class EncryptInfo {
|
||||||
public string encryptedMethodName;
|
public string encryptedMethodName;
|
||||||
public string feature;
|
public string feature;
|
||||||
public MethodDefinition method;
|
public MethodDef method;
|
||||||
|
|
||||||
public string FullName {
|
public string FullName {
|
||||||
get {
|
get {
|
||||||
|
@ -134,7 +134,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public EncryptInfo(string encryptedMethodName, string feature, MethodDefinition method) {
|
public EncryptInfo(string encryptedMethodName, string feature, MethodDef method) {
|
||||||
this.encryptedMethodName = encryptedMethodName;
|
this.encryptedMethodName = encryptedMethodName;
|
||||||
this.feature = feature;
|
this.feature = feature;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
@ -142,9 +142,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
if (feature != "")
|
if (feature != "")
|
||||||
return string.Format("{0}:{1} {2:X8}", feature, encryptedMethodName, method.MetadataToken.ToInt32());
|
return string.Format("{0}:{1} {2:X8}", feature, encryptedMethodName, method.MDToken.ToInt32());
|
||||||
else
|
else
|
||||||
return string.Format("{0} {1:X8}", encryptedMethodName, method.MetadataToken.ToInt32());
|
return string.Format("{0} {1:X8}", encryptedMethodName, method.MDToken.ToInt32());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
numNonDecryptedMethods++;
|
numNonDecryptedMethods++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Log.v("Decrypting method {0:X8}", info.method.MetadataToken.ToInt32());
|
Log.v("Decrypting method {0:X8}", info.method.MDToken.ToInt32());
|
||||||
imageReader.restore(info.FullName, info.method);
|
imageReader.restore(info.FullName, info.method);
|
||||||
}
|
}
|
||||||
if (numNonDecryptedMethods > 0)
|
if (numNonDecryptedMethods > 0)
|
||||||
|
@ -214,7 +214,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkEncryptedMethod(MethodDefinition method, out EncryptInfo info) {
|
bool checkEncryptedMethod(MethodDef method, out EncryptInfo info) {
|
||||||
info = null;
|
info = null;
|
||||||
if (method.Body == null)
|
if (method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -237,7 +237,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool callsExecuteMethod(MethodDefinition method) {
|
bool callsExecuteMethod(MethodDef method) {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override object checkCctor(TypeDefinition type, MethodDefinition cctor) {
|
protected override object checkCctor(TypeDef type, MethodDef cctor) {
|
||||||
var instructions = cctor.Body.Instructions;
|
var instructions = cctor.Body.Instructions;
|
||||||
for (int i = 0; i < instructions.Count; i++) {
|
for (int i = 0; i < instructions.Count; i++) {
|
||||||
TypeReference delegateType;
|
TypeReference delegateType;
|
||||||
|
@ -95,7 +95,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode) {
|
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||||
var ctx = (Context)context;
|
var ctx = (Context)context;
|
||||||
|
|
||||||
switch (ctx.proxyCreatorType) {
|
switch (ctx.proxyCreatorType) {
|
||||||
|
@ -141,7 +141,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyCreatorType getProxyCreatorType(MethodDefinition methodToCheck) {
|
ProxyCreatorType getProxyCreatorType(MethodDef methodToCheck) {
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, methodToCheck)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, methodToCheck)) {
|
||||||
if (!calledMethod.IsStatic || calledMethod.Body == null)
|
if (!calledMethod.IsStatic || calledMethod.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using ICSharpCode.SharpZipLib.Zip.Compression;
|
using ICSharpCode.SharpZipLib.Zip.Compression;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
@ -42,7 +42,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class ResourceDecrypter {
|
class ResourceDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
MethodDefinition decryptMethod;
|
MethodDef decryptMethod;
|
||||||
IDecrypter decrypter;
|
IDecrypter decrypter;
|
||||||
|
|
||||||
public ResourceDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
|
public ResourceDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
|
@ -155,7 +155,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
Inflater inflater;
|
Inflater inflater;
|
||||||
|
|
||||||
public Decrypter3(ModuleDefinition module, MethodDefinition decryptMethod) {
|
public Decrypter3(ModuleDefinition module, MethodDef decryptMethod) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.inflater = InflaterCreator.create(decryptMethod, true);
|
this.inflater = InflaterCreator.create(decryptMethod, true);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition DecryptMethod {
|
public MethodDef DecryptMethod {
|
||||||
set {
|
set {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return;
|
return;
|
||||||
|
@ -221,14 +221,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MethodDefinition findDecrypterMethod(MethodDefinition method) {
|
public static MethodDef findDecrypterMethod(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.Body == null)
|
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.Body == null)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(calledMethod, "System.IO.MemoryStream", "(System.IO.Stream)"))
|
if (!DotNetUtils.isMethod(calledMethod, "System.IO.MemoryStream", "(System.IO.Stream)"))
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
@ -29,8 +29,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
TypeDefinition resolverType;
|
TypeDef resolverType;
|
||||||
MethodDefinition registerMethod;
|
MethodDef registerMethod;
|
||||||
EmbeddedResource encryptedResource;
|
EmbeddedResource encryptedResource;
|
||||||
bool hasXorKeys;
|
bool hasXorKeys;
|
||||||
int xorKey1, xorKey2;
|
int xorKey1, xorKey2;
|
||||||
|
@ -39,11 +39,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return resolverType != null; }
|
get { return resolverType != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return resolverType; }
|
get { return resolverType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitMethod {
|
public MethodDef InitMethod {
|
||||||
get { return registerMethod; }
|
get { return registerMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (!new FieldTypes(type).all(requiredTypes))
|
if (!new FieldTypes(type).all(requiredTypes))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MethodDefinition regMethod, handler;
|
MethodDef regMethod, handler;
|
||||||
if (!BabelUtils.findRegisterMethod(type, out regMethod, out handler))
|
if (!BabelUtils.findRegisterMethod(type, out regMethod, out handler))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findDecryptMethod(TypeDefinition type) {
|
static MethodDef findDecryptMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!DotNetUtils.isMethod(method, "System.Reflection.Assembly", "(System.IO.Stream)"))
|
if (!DotNetUtils.isMethod(method, "System.Reflection.Assembly", "(System.IO.Stream)"))
|
||||||
continue;
|
continue;
|
||||||
|
@ -96,7 +96,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initXorKeys(MethodDefinition method) {
|
void initXorKeys(MethodDef method) {
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
var ints = new List<int>();
|
var ints = new List<int>();
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
|
|
|
@ -21,8 +21,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
|
||||||
|
@ -31,12 +31,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
TypeDefinition decrypterType;
|
TypeDef decrypterType;
|
||||||
EmbeddedResource encryptedResource;
|
EmbeddedResource encryptedResource;
|
||||||
IDecrypterInfo decrypterInfo;
|
IDecrypterInfo decrypterInfo;
|
||||||
|
|
||||||
interface IDecrypterInfo {
|
interface IDecrypterInfo {
|
||||||
MethodDefinition Decrypter { get; }
|
MethodDef Decrypter { get; }
|
||||||
bool NeedsResource { get; }
|
bool NeedsResource { get; }
|
||||||
void initialize(ModuleDefinition module, EmbeddedResource resource);
|
void initialize(ModuleDefinition module, EmbeddedResource resource);
|
||||||
string decrypt(object[] args);
|
string decrypt(object[] args);
|
||||||
|
@ -44,7 +44,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
// Babel .NET 2.x
|
// Babel .NET 2.x
|
||||||
class DecrypterInfoV1 : IDecrypterInfo {
|
class DecrypterInfoV1 : IDecrypterInfo {
|
||||||
public MethodDefinition Decrypter { get; set; }
|
public MethodDef Decrypter { get; set; }
|
||||||
public bool NeedsResource {
|
public bool NeedsResource {
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class DecrypterInfoV2 : IDecrypterInfo {
|
class DecrypterInfoV2 : IDecrypterInfo {
|
||||||
byte[] key;
|
byte[] key;
|
||||||
|
|
||||||
public MethodDefinition Decrypter { get; set; }
|
public MethodDef Decrypter { get; set; }
|
||||||
public bool NeedsResource {
|
public bool NeedsResource {
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
InstructionEmulator emulator = new InstructionEmulator();
|
InstructionEmulator emulator = new InstructionEmulator();
|
||||||
|
|
||||||
public IList<Instruction> OffsetCalcInstructions { get; set; }
|
public IList<Instruction> OffsetCalcInstructions { get; set; }
|
||||||
public MethodDefinition Decrypter { get; set; }
|
public MethodDef Decrypter { get; set; }
|
||||||
public bool NeedsResource {
|
public bool NeedsResource {
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
@ -113,12 +113,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
offsetToString[getOffset((int)reader.BaseStream.Position)] = reader.ReadString();
|
offsetToString[getOffset((int)reader.BaseStream.Position)] = reader.ReadString();
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition dummyMethod;
|
MethodDef dummyMethod;
|
||||||
int getOffset(int offset) {
|
int getOffset(int offset) {
|
||||||
if (OffsetCalcInstructions == null || OffsetCalcInstructions.Count == 0)
|
if (OffsetCalcInstructions == null || OffsetCalcInstructions.Count == 0)
|
||||||
return offset;
|
return offset;
|
||||||
if (dummyMethod == null) {
|
if (dummyMethod == null) {
|
||||||
dummyMethod = new MethodDefinition("", 0, new TypeReference("", "", null, null));
|
dummyMethod = new MethodDef("", 0, new TypeReference("", "", null, null));
|
||||||
dummyMethod.Body = new MethodBody(dummyMethod);
|
dummyMethod.Body = new MethodBody(dummyMethod);
|
||||||
}
|
}
|
||||||
emulator.init(dummyMethod);
|
emulator.init(dummyMethod);
|
||||||
|
@ -141,11 +141,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return decrypterType != null; }
|
get { return decrypterType != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return decrypterType; }
|
get { return decrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition DecryptMethod {
|
public MethodDef DecryptMethod {
|
||||||
get { return decrypterInfo == null ? null : decrypterInfo.Decrypter; }
|
get { return decrypterInfo == null ? null : decrypterInfo.Decrypter; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IDecrypterInfo checkDecrypterType(TypeDefinition type) {
|
IDecrypterInfo checkDecrypterType(TypeDef type) {
|
||||||
if (type.HasEvents)
|
if (type.HasEvents)
|
||||||
return null;
|
return null;
|
||||||
if (type.NestedTypes.Count > 2)
|
if (type.NestedTypes.Count > 2)
|
||||||
|
@ -188,7 +188,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return checkDecrypterTypeBabel2x(type);
|
return checkDecrypterTypeBabel2x(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDecrypterInfo checkDecrypterTypeBabel2x(TypeDefinition type) {
|
IDecrypterInfo checkDecrypterTypeBabel2x(TypeDef type) {
|
||||||
if (type.HasEvents || type.HasProperties || type.HasNestedTypes)
|
if (type.HasEvents || type.HasProperties || type.HasNestedTypes)
|
||||||
return null;
|
return null;
|
||||||
if (type.HasFields || type.Methods.Count != 1)
|
if (type.HasFields || type.Methods.Count != 1)
|
||||||
|
@ -200,7 +200,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return new DecrypterInfoV1 { Decrypter = decrypter };
|
return new DecrypterInfoV1 { Decrypter = decrypter };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkDecryptMethodBabel2x(MethodDefinition method) {
|
bool checkDecryptMethodBabel2x(MethodDef method) {
|
||||||
if (!method.IsStatic || !method.IsPublic)
|
if (!method.IsStatic || !method.IsPublic)
|
||||||
return false;
|
return false;
|
||||||
if (method.Body == null)
|
if (method.Body == null)
|
||||||
|
@ -242,7 +242,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return stringLength == 1 && stringToCharArray == 1 && stringCtor == 1;
|
return stringLength == 1 && stringToCharArray == 1 && stringCtor == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDecrypterInfo checkNested(TypeDefinition type, TypeDefinition nested) {
|
IDecrypterInfo checkNested(TypeDef type, TypeDef nested) {
|
||||||
if (nested.HasProperties || nested.HasEvents)
|
if (nested.HasProperties || nested.HasEvents)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReflectionToCecilMethodCreator {
|
class ReflectionToCecilMethodCreator {
|
||||||
MethodDefinition method;
|
MethodDef method;
|
||||||
List<Instruction> instructions = new List<Instruction>();
|
List<Instruction> instructions = new List<Instruction>();
|
||||||
InstructionEmulator emulator;
|
InstructionEmulator emulator;
|
||||||
int index;
|
int index;
|
||||||
|
@ -330,7 +330,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return instructions; }
|
get { return instructions; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReflectionToCecilMethodCreator(MethodDefinition method) {
|
public ReflectionToCecilMethodCreator(MethodDef method) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.emulator = new InstructionEmulator(method);
|
this.emulator = new InstructionEmulator(method);
|
||||||
}
|
}
|
||||||
|
@ -466,7 +466,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<Instruction> getOffsetCalcInstructions(MethodDefinition method) {
|
static List<Instruction> getOffsetCalcInstructions(MethodDef method) {
|
||||||
var creator = new ReflectionToCecilMethodCreator(method);
|
var creator = new ReflectionToCecilMethodCreator(method);
|
||||||
creator.create();
|
creator.create();
|
||||||
var instrs = creator.Instructions;
|
var instrs = creator.Instructions;
|
||||||
|
@ -499,7 +499,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasFieldType(IEnumerable<FieldDefinition> fields, TypeReference fieldType) {
|
static bool hasFieldType(IEnumerable<FieldDef> fields, TypeReference fieldType) {
|
||||||
foreach (var field in fields) {
|
foreach (var field in fields) {
|
||||||
if (MemberReferenceHelper.compareTypes(field.FieldType, fieldType))
|
if (MemberReferenceHelper.compareTypes(field.FieldType, fieldType))
|
||||||
return true;
|
return true;
|
||||||
|
@ -507,7 +507,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getOffsetMagic(MethodDefinition method) {
|
static int getOffsetMagic(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||||
int index = i;
|
int index = i;
|
||||||
|
@ -549,7 +549,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkFields(TypeDefinition type, string fieldType1, TypeDefinition fieldType2) {
|
bool checkFields(TypeDef type, string fieldType1, TypeDef fieldType2) {
|
||||||
if (type.Fields.Count != 2)
|
if (type.Fields.Count != 2)
|
||||||
return false;
|
return false;
|
||||||
if (type.Fields[0].FieldType.FullName != fieldType1 &&
|
if (type.Fields[0].FieldType.FullName != fieldType1 &&
|
||||||
|
|
|
@ -20,41 +20,41 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.PE;
|
using de4dot.PE;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure {
|
namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
class CliSecureRtType {
|
class CliSecureRtType {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition cliSecureRtType;
|
TypeDef cliSecureRtType;
|
||||||
MethodDefinition postInitializeMethod;
|
MethodDef postInitializeMethod;
|
||||||
MethodDefinition initializeMethod;
|
MethodDef initializeMethod;
|
||||||
MethodDefinition stringDecrypterMethod;
|
MethodDef stringDecrypterMethod;
|
||||||
MethodDefinition loadMethod;
|
MethodDef loadMethod;
|
||||||
bool foundSig;
|
bool foundSig;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return foundSig || cliSecureRtType != null; }
|
get { return foundSig || cliSecureRtType != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return cliSecureRtType; }
|
get { return cliSecureRtType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition StringDecrypterMethod {
|
public MethodDef StringDecrypterMethod {
|
||||||
get { return stringDecrypterMethod; }
|
get { return stringDecrypterMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition PostInitializeMethod {
|
public MethodDef PostInitializeMethod {
|
||||||
get { return postInitializeMethod; }
|
get { return postInitializeMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitializeMethod {
|
public MethodDef InitializeMethod {
|
||||||
get { return initializeMethod; }
|
get { return initializeMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition LoadMethod {
|
public MethodDef LoadMethod {
|
||||||
get { return loadMethod; }
|
get { return loadMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findStringDecrypterMethod(TypeDefinition type) {
|
static MethodDef findStringDecrypterMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Body == null || !method.IsStatic)
|
if (method.Body == null || !method.IsStatic)
|
||||||
continue;
|
continue;
|
||||||
|
@ -178,7 +178,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findMethod(TypeDefinition type, string returnType, string name, string parameters) {
|
static MethodDef findMethod(TypeDef type, string returnType, string name, string parameters) {
|
||||||
var methodName = returnType + " " + type.FullName + "::" + name + parameters;
|
var methodName = returnType + " " + type.FullName + "::" + name + parameters;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Body == null || !method.IsStatic)
|
if (method.Body == null || !method.IsStatic)
|
||||||
|
@ -192,7 +192,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasInitializeMethod(TypeDefinition type, string name) {
|
static bool hasInitializeMethod(TypeDef type, string name) {
|
||||||
var method = DotNetUtils.getPInvokeMethod(type, name);
|
var method = DotNetUtils.getPInvokeMethod(type, name);
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -239,7 +239,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isOldStringDecrypterMethod(MethodDefinition method) {
|
static bool isOldStringDecrypterMethod(MethodDef method) {
|
||||||
if (method == null || method.Body == null || !method.IsStatic)
|
if (method == null || method.Body == null || !method.IsStatic)
|
||||||
return false;
|
return false;
|
||||||
if (!DotNetUtils.isMethod(method, "System.String", "(System.String)"))
|
if (!DotNetUtils.isMethod(method, "System.String", "(System.String)"))
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.MyStuff;
|
using Mono.MyStuff;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.PE;
|
using de4dot.PE;
|
||||||
|
@ -78,7 +78,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
Options options;
|
Options options;
|
||||||
string obfuscatorName = DeobfuscatorInfo.THE_NAME;
|
string obfuscatorName = DeobfuscatorInfo.THE_NAME;
|
||||||
|
|
||||||
List<TypeDefinition> cliSecureAttributes = new List<TypeDefinition>();
|
List<TypeDef> cliSecureAttributes = new List<TypeDef>();
|
||||||
ProxyCallFixer proxyCallFixer;
|
ProxyCallFixer proxyCallFixer;
|
||||||
CliSecureRtType cliSecureRtType;
|
CliSecureRtType cliSecureRtType;
|
||||||
StringDecrypter stringDecrypter;
|
StringDecrypter stringDecrypter;
|
||||||
|
@ -233,8 +233,8 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
return newOne;
|
return newOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<TypeDefinition> lookup(ModuleDefinition module, List<TypeDefinition> types, string errorMsg) {
|
static List<TypeDef> lookup(ModuleDefinition module, List<TypeDef> types, string errorMsg) {
|
||||||
var list = new List<TypeDefinition>(types.Count);
|
var list = new List<TypeDef>(types.Count);
|
||||||
foreach (var type in types)
|
foreach (var type in types)
|
||||||
list.Add(DeobUtils.lookup(module, type, errorMsg));
|
list.Add(DeobUtils.lookup(module, type, errorMsg));
|
||||||
return list;
|
return list;
|
||||||
|
@ -320,7 +320,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
if (stringDecrypter.Method != null)
|
if (stringDecrypter.Method != null)
|
||||||
list.Add(stringDecrypter.Method.MetadataToken.ToInt32());
|
list.Add(stringDecrypter.Method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -458,7 +458,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
var initMethod = csRtType.InitializeMethod;
|
var initMethod = csRtType.InitializeMethod;
|
||||||
if (initMethod == null)
|
if (initMethod == null)
|
||||||
return null;
|
return null;
|
||||||
uint initToken = initMethod.MetadataToken.ToUInt32();
|
uint initToken = initMethod.MDToken.ToUInt32();
|
||||||
var moduleCctorBytes = new byte[6];
|
var moduleCctorBytes = new byte[6];
|
||||||
moduleCctorBytes[0] = 0x28; // call
|
moduleCctorBytes[0] = 0x28; // call
|
||||||
moduleCctorBytes[1] = (byte)initToken;
|
moduleCctorBytes[1] = (byte)initToken;
|
||||||
|
@ -542,7 +542,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
var dm = new DumpedMethod();
|
var dm = new DumpedMethod();
|
||||||
dm.token = 0x06000001 + (uint)i;
|
dm.token = 0x06000001 + (uint)i;
|
||||||
|
|
||||||
var method = (Mono.Cecil.MethodDefinition)module.LookupToken((int)dm.token);
|
var method = (Mono.Cecil.MethodDef)module.LookupToken((int)dm.token);
|
||||||
if (method == null || method.DeclaringType == DotNetUtils.getModuleType(module))
|
if (method == null || method.DeclaringType == DotNetUtils.getModuleType(module))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure {
|
namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
|
@ -49,19 +49,19 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override object checkCctor(ref TypeDefinition type, MethodDefinition cctor) {
|
protected override object checkCctor(ref TypeDef type, MethodDef cctor) {
|
||||||
var instrs = cctor.Body.Instructions;
|
var instrs = cctor.Body.Instructions;
|
||||||
if (instrs.Count != 3)
|
if (instrs.Count != 3)
|
||||||
return null;
|
return null;
|
||||||
if (!DotNetUtils.isLdcI4(instrs[0].OpCode.Code))
|
if (!DotNetUtils.isLdcI4(instrs[0].OpCode.Code))
|
||||||
return null;
|
return null;
|
||||||
if (instrs[1].OpCode != OpCodes.Call || !isDelegateCreatorMethod(instrs[1].Operand as MethodDefinition))
|
if (instrs[1].OpCode != OpCodes.Call || !isDelegateCreatorMethod(instrs[1].Operand as MethodDef))
|
||||||
return null;
|
return null;
|
||||||
if (instrs[2].OpCode != OpCodes.Ret)
|
if (instrs[2].OpCode != OpCodes.Ret)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
int delegateToken = 0x02000001 + DotNetUtils.getLdcI4Value(instrs[0]);
|
int delegateToken = 0x02000001 + DotNetUtils.getLdcI4Value(instrs[0]);
|
||||||
if (type.MetadataToken.ToInt32() != delegateToken) {
|
if (type.MDToken.ToInt32() != delegateToken) {
|
||||||
Log.w("Delegate token is not current type");
|
Log.w("Delegate token is not current type");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
return new object();
|
return new object();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode) {
|
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||||
if (memberReferences == null)
|
if (memberReferences == null)
|
||||||
memberReferences = new List<MemberReference>(module.GetMemberReferences());
|
memberReferences = new List<MemberReference>(module.GetMemberReferences());
|
||||||
|
|
||||||
|
|
|
@ -20,25 +20,25 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure {
|
namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
class ResourceDecrypter {
|
class ResourceDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition rsrcType;
|
TypeDef rsrcType;
|
||||||
MethodDefinition rsrcRrrMethod;
|
MethodDef rsrcRrrMethod;
|
||||||
MethodDefinition rsrcResolveMethod;
|
MethodDef rsrcResolveMethod;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return rsrcType != null; }
|
get { return rsrcType != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return rsrcType; }
|
get { return rsrcType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition RsrcRrrMethod {
|
public MethodDef RsrcRrrMethod {
|
||||||
get { return rsrcRrrMethod; }
|
get { return rsrcRrrMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure {
|
namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
class StackFrameHelper {
|
class StackFrameHelper {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition stackFrameHelperType;
|
TypeDef stackFrameHelperType;
|
||||||
ExceptionLoggerRemover exceptionLoggerRemover = new ExceptionLoggerRemover();
|
ExceptionLoggerRemover exceptionLoggerRemover = new ExceptionLoggerRemover();
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return stackFrameHelperType; }
|
get { return stackFrameHelperType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
if (type.Methods.Count > 3)
|
if (type.Methods.Count > 3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MethodDefinition errorMethod = null;
|
MethodDef errorMethod = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.IsRuntimeSpecialName && method.Name == ".ctor" && !method.HasParameters)
|
if (method.IsRuntimeSpecialName && method.Name == ".ctor" && !method.HasParameters)
|
||||||
continue; // .ctor is allowed
|
continue; // .ctor is allowed
|
||||||
|
|
|
@ -19,29 +19,29 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure {
|
namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
class StringDecrypter {
|
class StringDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition stringDecrypterType;
|
TypeDef stringDecrypterType;
|
||||||
MethodDefinition stringDecrypterMethod;
|
MethodDef stringDecrypterMethod;
|
||||||
byte[] stringDecrypterKey;
|
byte[] stringDecrypterKey;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return stringDecrypterMethod != null; }
|
get { return stringDecrypterMethod != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return stringDecrypterType; }
|
get { return stringDecrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return stringDecrypterMethod; }
|
get { return stringDecrypterMethod; }
|
||||||
set { stringDecrypterMethod = value; }
|
set { stringDecrypterMethod = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringDecrypter(ModuleDefinition module, MethodDefinition stringDecrypterMethod) {
|
public StringDecrypter(ModuleDefinition module, MethodDef stringDecrypterMethod) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.stringDecrypterMethod = stringDecrypterMethod;
|
this.stringDecrypterMethod = stringDecrypterMethod;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
// ldobj
|
// ldobj
|
||||||
// stobj
|
// stobj
|
||||||
class CilOperandInstructionRestorer {
|
class CilOperandInstructionRestorer {
|
||||||
MethodDefinition method;
|
MethodDef method;
|
||||||
|
|
||||||
public bool restore(MethodDefinition method) {
|
public bool restore(MethodDef method) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
bool atLeastOneFailed = false;
|
bool atLeastOneFailed = false;
|
||||||
|
|
||||||
|
@ -99,13 +99,13 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
case CecilType.ArrayType:
|
case CecilType.ArrayType:
|
||||||
case CecilType.GenericInstanceType:
|
case CecilType.GenericInstanceType:
|
||||||
case CecilType.PointerType:
|
case CecilType.PointerType:
|
||||||
case CecilType.TypeDefinition:
|
case CecilType.TypeDef:
|
||||||
case CecilType.TypeReference:
|
case CecilType.TypeReference:
|
||||||
case CecilType.FunctionPointerType:
|
case CecilType.FunctionPointerType:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CecilType.GenericParameter:
|
case CecilType.GenericParam:
|
||||||
var gp = (GenericParameter)type;
|
var gp = (GenericParam)type;
|
||||||
if (method.DeclaringType != gp.Owner && method != gp.Owner)
|
if (method.DeclaringType != gp.Owner && method != gp.Owner)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
|
@ -98,17 +98,17 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
var converter = new CsvmToCilMethodConverter(deobfuscatorContext, module, opcodeDetector);
|
var converter = new CsvmToCilMethodConverter(deobfuscatorContext, module, opcodeDetector);
|
||||||
var methodPrinter = new MethodPrinter();
|
var methodPrinter = new MethodPrinter();
|
||||||
foreach (var csvmMethod in csvmMethods) {
|
foreach (var csvmMethod in csvmMethods) {
|
||||||
var cilMethod = module.LookupToken(csvmMethod.Token) as MethodDefinition;
|
var cilMethod = module.LookupToken(csvmMethod.Token) as MethodDef;
|
||||||
if (cilMethod == null)
|
if (cilMethod == null)
|
||||||
throw new ApplicationException(string.Format("Could not find method {0:X8}", csvmMethod.Token));
|
throw new ApplicationException(string.Format("Could not find method {0:X8}", csvmMethod.Token));
|
||||||
converter.convert(cilMethod, csvmMethod);
|
converter.convert(cilMethod, csvmMethod);
|
||||||
Log.v("Restored method {0:X8}", cilMethod.MetadataToken.ToInt32());
|
Log.v("Restored method {0:X8}", cilMethod.MDToken.ToInt32());
|
||||||
printMethod(methodPrinter, cilMethod);
|
printMethod(methodPrinter, cilMethod);
|
||||||
}
|
}
|
||||||
Log.deIndent();
|
Log.deIndent();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printMethod(MethodPrinter methodPrinter, MethodDefinition method) {
|
static void printMethod(MethodPrinter methodPrinter, MethodDef method) {
|
||||||
const Log.LogLevel dumpLogLevel = Log.LogLevel.verbose;
|
const Log.LogLevel dumpLogLevel = Log.LogLevel.verbose;
|
||||||
if (!Log.isAtLeast(dumpLogLevel))
|
if (!Log.isAtLeast(dumpLogLevel))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
this.opCodeDetector = opCodeDetector;
|
this.opCodeDetector = opCodeDetector;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void convert(MethodDefinition cilMethod, CsvmMethodData csvmMethod) {
|
public void convert(MethodDef cilMethod, CsvmMethodData csvmMethod) {
|
||||||
var newInstructions = readInstructions(cilMethod, csvmMethod);
|
var newInstructions = readInstructions(cilMethod, csvmMethod);
|
||||||
var newLocals = readLocals(cilMethod, csvmMethod);
|
var newLocals = readLocals(cilMethod, csvmMethod);
|
||||||
var newExceptions = readExceptions(cilMethod, csvmMethod, newInstructions);
|
var newExceptions = readExceptions(cilMethod, csvmMethod, newInstructions);
|
||||||
|
@ -50,7 +50,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
DotNetUtils.restoreBody(cilMethod, newInstructions, newExceptions);
|
DotNetUtils.restoreBody(cilMethod, newInstructions, newExceptions);
|
||||||
|
|
||||||
if (!operandRestorer.restore(cilMethod))
|
if (!operandRestorer.restore(cilMethod))
|
||||||
Log.w("Failed to restore one or more instruction operands in CSVM method {0:X8}", cilMethod.MetadataToken.ToInt32());
|
Log.w("Failed to restore one or more instruction operands in CSVM method {0:X8}", cilMethod.MDToken.ToInt32());
|
||||||
restoreConstrainedPrefix(cilMethod);
|
restoreConstrainedPrefix(cilMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
instr.Operand = operand;
|
instr.Operand = operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixArgs(IList<Instruction> instrs, MethodDefinition method) {
|
void fixArgs(IList<Instruction> instrs, MethodDef method) {
|
||||||
foreach (var instr in instrs) {
|
foreach (var instr in instrs) {
|
||||||
var op = instr.Operand as ArgOperand;
|
var op = instr.Operand as ArgOperand;
|
||||||
if (op == null)
|
if (op == null)
|
||||||
|
@ -206,7 +206,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Instruction> readInstructions(MethodDefinition cilMethod, CsvmMethodData csvmMethod) {
|
List<Instruction> readInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) {
|
||||||
var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions));
|
var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions));
|
||||||
var instrs = new List<Instruction>();
|
var instrs = new List<Instruction>();
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
@ -230,7 +230,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return instr.OpCode.Size + (op.targetDisplacements.Length + 1) * 4;
|
return instr.OpCode.Size + (op.targetDisplacements.Length + 1) * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<VariableDefinition> readLocals(MethodDefinition cilMethod, CsvmMethodData csvmMethod) {
|
List<VariableDefinition> readLocals(MethodDef cilMethod, CsvmMethodData csvmMethod) {
|
||||||
var locals = new List<VariableDefinition>();
|
var locals = new List<VariableDefinition>();
|
||||||
var reader = new BinaryReader(new MemoryStream(csvmMethod.Locals));
|
var reader = new BinaryReader(new MemoryStream(csvmMethod.Locals));
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ExceptionHandler> readExceptions(MethodDefinition cilMethod, CsvmMethodData csvmMethod, List<Instruction> cilInstructions) {
|
List<ExceptionHandler> readExceptions(MethodDef cilMethod, CsvmMethodData csvmMethod, List<Instruction> cilInstructions) {
|
||||||
var reader = new BinaryReader(new MemoryStream(csvmMethod.Exceptions));
|
var reader = new BinaryReader(new MemoryStream(csvmMethod.Exceptions));
|
||||||
var ehs = new List<ExceptionHandler>();
|
var ehs = new List<ExceptionHandler>();
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return memberRef;
|
return memberRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restoreConstrainedPrefix(MethodDefinition method) {
|
static void restoreConstrainedPrefix(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
class FieldsInfo {
|
class FieldsInfo {
|
||||||
|
@ -27,13 +27,13 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
Dictionary<string, int> fieldTypes = new Dictionary<string, int>(StringComparer.Ordinal);
|
Dictionary<string, int> fieldTypes = new Dictionary<string, int>(StringComparer.Ordinal);
|
||||||
int numEnums = 0;
|
int numEnums = 0;
|
||||||
|
|
||||||
public FieldsInfo(TypeDefinition type)
|
public FieldsInfo(TypeDef type)
|
||||||
: this(type.Fields) {
|
: this(type.Fields) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldsInfo(IEnumerable<FieldDefinition> fields) {
|
public FieldsInfo(IEnumerable<FieldDef> fields) {
|
||||||
foreach (var field in fields) {
|
foreach (var field in fields) {
|
||||||
var fieldTypeDef = field.FieldType as TypeDefinition;
|
var fieldTypeDef = field.FieldType as TypeDef;
|
||||||
if (fieldTypeDef != null && fieldTypeDef.IsEnum)
|
if (fieldTypeDef != null && fieldTypeDef.IsEnum)
|
||||||
addEnum();
|
addEnum();
|
||||||
else
|
else
|
||||||
|
|
|
@ -21,8 +21,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
|
@ -439,7 +439,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return isEmptyMethod(info.ReadMethod) && isEmptyMethod(info.ExecuteMethod);
|
return isEmptyMethod(info.ReadMethod) && isEmptyMethod(info.ExecuteMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isEmptyMethod(MethodDefinition method) {
|
static bool isEmptyMethod(MethodDef method) {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code == Code.Ret)
|
if (instr.OpCode.Code == Code.Ret)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -19,24 +19,24 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
class UnknownHandlerInfo {
|
class UnknownHandlerInfo {
|
||||||
TypeDefinition type;
|
TypeDef type;
|
||||||
CsvmInfo csvmInfo;
|
CsvmInfo csvmInfo;
|
||||||
FieldsInfo fieldsInfo;
|
FieldsInfo fieldsInfo;
|
||||||
MethodDefinition readMethod, executeMethod;
|
MethodDef readMethod, executeMethod;
|
||||||
int numStaticMethods, numInstanceMethods, numVirtualMethods, numCtors;
|
int numStaticMethods, numInstanceMethods, numVirtualMethods, numCtors;
|
||||||
int executeMethodThrows, executeMethodPops;
|
int executeMethodThrows, executeMethodPops;
|
||||||
|
|
||||||
public MethodDefinition ReadMethod {
|
public MethodDef ReadMethod {
|
||||||
get { return readMethod; }
|
get { return readMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition ExecuteMethod {
|
public MethodDef ExecuteMethod {
|
||||||
get { return executeMethod; }
|
get { return executeMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
get { return numCtors; }
|
get { return numCtors; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnknownHandlerInfo(TypeDefinition type, CsvmInfo csvmInfo) {
|
public UnknownHandlerInfo(TypeDef type, CsvmInfo csvmInfo) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.csvmInfo = csvmInfo;
|
this.csvmInfo = csvmInfo;
|
||||||
fieldsInfo = new FieldsInfo(getFields(type));
|
fieldsInfo = new FieldsInfo(getFields(type));
|
||||||
|
@ -74,11 +74,11 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
executeMethodPops = countPops(executeMethod);
|
executeMethodPops = countPops(executeMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
static internal IEnumerable<FieldDefinition> getFields(TypeDefinition type) {
|
static internal IEnumerable<FieldDef> getFields(TypeDef type) {
|
||||||
var typeFields = new FieldDefinitionAndDeclaringTypeDict<FieldDefinition>();
|
var typeFields = new FieldDefinitionAndDeclaringTypeDict<FieldDef>();
|
||||||
foreach (var field in type.Fields)
|
foreach (var field in type.Fields)
|
||||||
typeFields.add(field, field);
|
typeFields.add(field, field);
|
||||||
var realFields = new Dictionary<FieldDefinition, bool>();
|
var realFields = new Dictionary<FieldDef, bool>();
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Body == null)
|
if (method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -132,7 +132,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
throw new ApplicationException("Could not find execute method");
|
throw new ApplicationException("Could not find execute method");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int countThrows(MethodDefinition method) {
|
static int countThrows(MethodDef method) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code == Code.Throw)
|
if (instr.OpCode.Code == Code.Throw)
|
||||||
|
@ -141,7 +141,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int countPops(MethodDefinition method) {
|
int countPops(MethodDef method) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
|
||||||
|
@ -37,10 +37,10 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CsvmInfo {
|
class CsvmInfo {
|
||||||
public TypeDefinition StackValue { get; set; }
|
public TypeDef StackValue { get; set; }
|
||||||
public TypeDefinition Stack { get; set; }
|
public TypeDef Stack { get; set; }
|
||||||
public MethodDefinition PopMethod { get; set; }
|
public MethodDef PopMethod { get; set; }
|
||||||
public MethodDefinition PeekMethod { get; set; }
|
public MethodDef PeekMethod { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
class VmOpCodeHandlerDetector {
|
class VmOpCodeHandlerDetector {
|
||||||
|
@ -73,7 +73,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return csvmInfo;
|
return csvmInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinition findStackValueType() {
|
TypeDef findStackValueType() {
|
||||||
foreach (var type in module.Types) {
|
foreach (var type in module.Types) {
|
||||||
if (isStackType(type))
|
if (isStackType(type))
|
||||||
return type;
|
return type;
|
||||||
|
@ -81,14 +81,14 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isStackType(TypeDefinition type) {
|
static bool isStackType(TypeDef type) {
|
||||||
if (type.Fields.Count != 2)
|
if (type.Fields.Count != 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int enumTypes = 0;
|
int enumTypes = 0;
|
||||||
int objectTypes = 0;
|
int objectTypes = 0;
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
var fieldType = field.FieldType as TypeDefinition;
|
var fieldType = field.FieldType as TypeDef;
|
||||||
if (fieldType != null && fieldType.IsEnum)
|
if (fieldType != null && fieldType.IsEnum)
|
||||||
enumTypes++;
|
enumTypes++;
|
||||||
if (field.FieldType.FullName == "System.Object")
|
if (field.FieldType.FullName == "System.Object")
|
||||||
|
@ -100,7 +100,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinition findStackType(TypeDefinition stackValueType) {
|
TypeDef findStackType(TypeDef stackValueType) {
|
||||||
foreach (var type in module.Types) {
|
foreach (var type in module.Types) {
|
||||||
if (isStackType(type, stackValueType))
|
if (isStackType(type, stackValueType))
|
||||||
return type;
|
return type;
|
||||||
|
@ -108,7 +108,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isStackType(TypeDefinition type, TypeDefinition stackValueType) {
|
bool isStackType(TypeDef type, TypeDef stackValueType) {
|
||||||
if (type.Interfaces.Count != 2)
|
if (type.Interfaces.Count != 2)
|
||||||
return false;
|
return false;
|
||||||
if (!implementsInterface(type, "System.Collections.ICollection"))
|
if (!implementsInterface(type, "System.Collections.ICollection"))
|
||||||
|
@ -137,7 +137,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool implementsInterface(TypeDefinition type, string ifaceName) {
|
static bool implementsInterface(TypeDef type, string ifaceName) {
|
||||||
foreach (var iface in type.Interfaces) {
|
foreach (var iface in type.Interfaces) {
|
||||||
if (iface.FullName == ifaceName)
|
if (iface.FullName == ifaceName)
|
||||||
return true;
|
return true;
|
||||||
|
@ -156,7 +156,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasAdd(MethodDefinition method) {
|
static bool hasAdd(MethodDef method) {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code == Code.Add)
|
if (instr.OpCode.Code == Code.Add)
|
||||||
return true;
|
return true;
|
||||||
|
@ -164,7 +164,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TypeDefinition> findVmHandlerTypes() {
|
List<TypeDef> findVmHandlerTypes() {
|
||||||
var requiredFields = new string[] {
|
var requiredFields = new string[] {
|
||||||
null,
|
null,
|
||||||
"System.Collections.Generic.Dictionary`2<System.UInt16,System.Type>",
|
"System.Collections.Generic.Dictionary`2<System.UInt16,System.Type>",
|
||||||
|
@ -190,13 +190,13 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<TypeDefinition> findVmHandlerTypes(MethodDefinition method) {
|
static List<TypeDef> findVmHandlerTypes(MethodDef method) {
|
||||||
var list = new List<TypeDefinition>();
|
var list = new List<TypeDef>();
|
||||||
|
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Ldtoken)
|
if (instr.OpCode.Code != Code.Ldtoken)
|
||||||
continue;
|
continue;
|
||||||
var type = instr.Operand as TypeDefinition;
|
var type = instr.Operand as TypeDef;
|
||||||
if (type == null)
|
if (type == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void detectHandlers(List<TypeDefinition> handlerTypes, CsvmInfo csvmInfo) {
|
void detectHandlers(List<TypeDef> handlerTypes, CsvmInfo csvmInfo) {
|
||||||
opCodeHandlers = new List<OpCodeHandler>();
|
opCodeHandlers = new List<OpCodeHandler>();
|
||||||
var detected = new List<OpCodeHandler>();
|
var detected = new List<OpCodeHandler>();
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeFort {
|
namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
|
@ -32,8 +32,8 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
EmbeddedResource assemblyEncryptedResource;
|
EmbeddedResource assemblyEncryptedResource;
|
||||||
PasswordInfo embedPassword;
|
PasswordInfo embedPassword;
|
||||||
MethodDefinition embedInitMethod;
|
MethodDef embedInitMethod;
|
||||||
MethodDefinition embedResolverMethod;
|
MethodDef embedResolverMethod;
|
||||||
|
|
||||||
public class AssemblyInfo {
|
public class AssemblyInfo {
|
||||||
public readonly byte[] data;
|
public readonly byte[] data;
|
||||||
|
@ -67,11 +67,11 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
get { return EncryptedDetected || MainAssemblyHasAssemblyResolver; }
|
get { return EncryptedDetected || MainAssemblyHasAssemblyResolver; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return embedInitMethod != null ? embedInitMethod.DeclaringType : null; }
|
get { return embedInitMethod != null ? embedInitMethod.DeclaringType : null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitMethod {
|
public MethodDef InitMethod {
|
||||||
get { return embedInitMethod; }
|
get { return embedInitMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,10 +118,10 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition checkCalledMethods(MethodDefinition method) {
|
MethodDef checkCalledMethods(MethodDef method) {
|
||||||
int calls = 0;
|
int calls = 0;
|
||||||
TypeDefinition type = null;
|
TypeDef type = null;
|
||||||
MethodDefinition initMethod = null;
|
MethodDef initMethod = null;
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
||||||
calls++;
|
calls++;
|
||||||
if (type != null && calledMethod.DeclaringType != type)
|
if (type != null && calledMethod.DeclaringType != type)
|
||||||
|
@ -144,7 +144,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
findEmbedded(module.EntryPoint);
|
findEmbedded(module.EntryPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findEmbedded(MethodDefinition method) {
|
bool findEmbedded(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
||||||
|
@ -162,7 +162,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition checkInitMethod(MethodDefinition method) {
|
MethodDef checkInitMethod(MethodDef method) {
|
||||||
if (method == null || !method.IsStatic || method.Body == null)
|
if (method == null || !method.IsStatic || method.Body == null)
|
||||||
return null;
|
return null;
|
||||||
if (!DotNetUtils.isMethod(method, "System.Void", "()"))
|
if (!DotNetUtils.isMethod(method, "System.Void", "()"))
|
||||||
|
@ -175,7 +175,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
return resolver;
|
return resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkType(TypeDefinition type) {
|
bool checkType(TypeDef type) {
|
||||||
if (DotNetUtils.getMethod(type, "System.Byte[]", "(System.Byte[],System.String,System.String,System.Int32,System.String,System.Int32)") == null)
|
if (DotNetUtils.getMethod(type, "System.Byte[]", "(System.Byte[],System.String,System.String,System.Int32,System.String,System.Int32)") == null)
|
||||||
return false;
|
return false;
|
||||||
if (DotNetUtils.getMethod(type, "System.String", "(System.String)") == null)
|
if (DotNetUtils.getMethod(type, "System.String", "(System.String)") == null)
|
||||||
|
@ -246,7 +246,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PasswordInfo getEmbedPassword(MethodDefinition method) {
|
static PasswordInfo getEmbedPassword(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||||
int index = i;
|
int index = i;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
this.proxyCallFixer = proxyCallFixer;
|
this.proxyCallFixer = proxyCallFixer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool canInline(MethodDefinition method) {
|
protected override bool canInline(MethodDef method) {
|
||||||
return proxyCallFixer.isProxyTargetMethod(method);
|
return proxyCallFixer.isProxyTargetMethod(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.MyStuff;
|
using Mono.MyStuff;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.PE;
|
using de4dot.PE;
|
||||||
|
@ -173,7 +173,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
if (stringDecrypter.Method != null)
|
if (stringDecrypter.Method != null)
|
||||||
list.Add(stringDecrypter.Method.MetadataToken.ToInt32());
|
list.Add(stringDecrypter.Method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeFort {
|
namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
class PasswordInfo {
|
class PasswordInfo {
|
||||||
|
|
|
@ -19,17 +19,17 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeFort {
|
namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
class ProxyCallFixer : ProxyCallFixer3 {
|
class ProxyCallFixer : ProxyCallFixer3 {
|
||||||
IList<MemberReference> memberReferences;
|
IList<MemberReference> memberReferences;
|
||||||
MethodDefinitionAndDeclaringTypeDict<bool> proxyTargetMethods = new MethodDefinitionAndDeclaringTypeDict<bool>();
|
MethodDefinitionAndDeclaringTypeDict<bool> proxyTargetMethods = new MethodDefinitionAndDeclaringTypeDict<bool>();
|
||||||
TypeDefinition proxyMethodsType;
|
TypeDef proxyMethodsType;
|
||||||
|
|
||||||
public TypeDefinition ProxyMethodsType {
|
public TypeDef ProxyMethodsType {
|
||||||
get { return proxyMethodsType; }
|
get { return proxyMethodsType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition checkType(TypeDefinition type) {
|
static MethodDef checkType(TypeDef type) {
|
||||||
if (type.Fields.Count != 1)
|
if (type.Fields.Count != 1)
|
||||||
return null;
|
return null;
|
||||||
if (type.Fields[0].FieldType.FullName != "System.Reflection.Module")
|
if (type.Fields[0].FieldType.FullName != "System.Reflection.Module")
|
||||||
|
@ -60,11 +60,11 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
return checkMethods(type);
|
return checkMethods(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition checkMethods(TypeDefinition type) {
|
static MethodDef checkMethods(TypeDef type) {
|
||||||
if (type.Methods.Count != 3)
|
if (type.Methods.Count != 3)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
MethodDefinition creatorMethod = null;
|
MethodDef creatorMethod = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Name == ".cctor")
|
if (method.Name == ".cctor")
|
||||||
continue;
|
continue;
|
||||||
|
@ -80,7 +80,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
return creatorMethod;
|
return creatorMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override object checkCctor(ref TypeDefinition type, MethodDefinition cctor) {
|
protected override object checkCctor(ref TypeDef type, MethodDef cctor) {
|
||||||
var instrs = cctor.Body.Instructions;
|
var instrs = cctor.Body.Instructions;
|
||||||
if (instrs.Count != 3)
|
if (instrs.Count != 3)
|
||||||
return null;
|
return null;
|
||||||
|
@ -90,15 +90,15 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
var call = instrs[1];
|
var call = instrs[1];
|
||||||
if (call.OpCode.Code != Code.Call)
|
if (call.OpCode.Code != Code.Call)
|
||||||
return null;
|
return null;
|
||||||
if (!isDelegateCreatorMethod(call.Operand as MethodDefinition))
|
if (!isDelegateCreatorMethod(call.Operand as MethodDef))
|
||||||
return null;
|
return null;
|
||||||
int rid = DotNetUtils.getLdcI4Value(ldci4);
|
int rid = DotNetUtils.getLdcI4Value(ldci4);
|
||||||
if (cctor.DeclaringType.MetadataToken.RID != rid)
|
if (cctor.DeclaringType.MDToken.RID != rid)
|
||||||
throw new ApplicationException("Invalid rid");
|
throw new ApplicationException("Invalid rid");
|
||||||
return rid;
|
return rid;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode) {
|
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||||
if (memberReferences == null)
|
if (memberReferences == null)
|
||||||
memberReferences = new List<MemberReference>(module.GetMemberReferences());
|
memberReferences = new List<MemberReference>(module.GetMemberReferences());
|
||||||
|
|
||||||
|
|
|
@ -18,24 +18,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeFort {
|
namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
class StringDecrypter {
|
class StringDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
MethodDefinition decryptMethod;
|
MethodDef decryptMethod;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return decryptMethod != null; }
|
get { return decryptMethod != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return decryptMethod; }
|
get { return decryptMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return decryptMethod == null ? null : decryptMethod.DeclaringType; }
|
get { return decryptMethod == null ? null : decryptMethod.DeclaringType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,14 +53,14 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition checkType(TypeDefinition type) {
|
static MethodDef checkType(TypeDef type) {
|
||||||
if (type.HasFields)
|
if (type.HasFields)
|
||||||
return null;
|
return null;
|
||||||
return checkMethods(type);
|
return checkMethods(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition checkMethods(TypeDefinition type) {
|
static MethodDef checkMethods(TypeDef type) {
|
||||||
MethodDefinition decryptMethod = null;
|
MethodDef decryptMethod = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Name == ".cctor")
|
if (method.Name == ".cctor")
|
||||||
continue;
|
continue;
|
||||||
|
@ -76,7 +76,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
return decryptMethod;
|
return decryptMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasDouble(MethodDefinition method, double value) {
|
static bool hasDouble(MethodDef method, double value) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeVeil {
|
namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
|
@ -29,12 +29,12 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
EmbeddedResource bundleData;
|
EmbeddedResource bundleData;
|
||||||
EmbeddedResource bundleXmlFile;
|
EmbeddedResource bundleXmlFile;
|
||||||
TypeDefinition bundleType;
|
TypeDef bundleType;
|
||||||
TypeDefinition assemblyManagerType;
|
TypeDef assemblyManagerType;
|
||||||
TypeDefinition bundleStreamProviderIFace;
|
TypeDef bundleStreamProviderIFace;
|
||||||
TypeDefinition xmlParserType;
|
TypeDef xmlParserType;
|
||||||
TypeDefinition bundledAssemblyType;
|
TypeDef bundledAssemblyType;
|
||||||
TypeDefinition streamProviderType;
|
TypeDef streamProviderType;
|
||||||
List<AssemblyInfo> infos = new List<AssemblyInfo>();
|
List<AssemblyInfo> infos = new List<AssemblyInfo>();
|
||||||
|
|
||||||
public class AssemblyInfo {
|
public class AssemblyInfo {
|
||||||
|
@ -66,9 +66,9 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<TypeDefinition> BundleTypes {
|
public IEnumerable<TypeDef> BundleTypes {
|
||||||
get {
|
get {
|
||||||
var list = new List<TypeDefinition>();
|
var list = new List<TypeDef>();
|
||||||
if (!CanRemoveTypes)
|
if (!CanRemoveTypes)
|
||||||
return list;
|
return list;
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinition findBundleType() {
|
TypeDef findBundleType() {
|
||||||
foreach (var type in module.Types) {
|
foreach (var type in module.Types) {
|
||||||
if (type.Namespace != "")
|
if (type.Namespace != "")
|
||||||
continue;
|
continue;
|
||||||
|
@ -193,7 +193,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition findInitMethod(TypeDefinition type) {
|
MethodDef findInitMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -208,7 +208,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition findGetTempFilenameMethod(TypeDefinition type) {
|
MethodDef findGetTempFilenameMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.IsStatic || method.Body == null)
|
if (method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -234,7 +234,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var field in bundleType.Fields) {
|
foreach (var field in bundleType.Fields) {
|
||||||
var type = field.FieldType as TypeDefinition;
|
var type = field.FieldType as TypeDef;
|
||||||
if (type == null)
|
if (type == null)
|
||||||
continue;
|
continue;
|
||||||
if (type == bundleType)
|
if (type == bundleType)
|
||||||
|
@ -245,7 +245,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
var ctor = DotNetUtils.getMethod(type, ".ctor");
|
var ctor = DotNetUtils.getMethod(type, ".ctor");
|
||||||
if (ctor == null || ctor.Parameters.Count != 2)
|
if (ctor == null || ctor.Parameters.Count != 2)
|
||||||
continue;
|
continue;
|
||||||
var iface = ctor.Parameters[1].ParameterType as TypeDefinition;
|
var iface = ctor.Parameters[1].ParameterType as TypeDef;
|
||||||
if (iface == null || !iface.IsInterface)
|
if (iface == null || !iface.IsInterface)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
if (assemblyManagerType == null)
|
if (assemblyManagerType == null)
|
||||||
return;
|
return;
|
||||||
foreach (var field in assemblyManagerType.Fields) {
|
foreach (var field in assemblyManagerType.Fields) {
|
||||||
var type = field.FieldType as TypeDefinition;
|
var type = field.FieldType as TypeDef;
|
||||||
if (type == null || type.IsInterface)
|
if (type == null || type.IsInterface)
|
||||||
continue;
|
continue;
|
||||||
var ctor = DotNetUtils.getMethod(type, ".ctor");
|
var ctor = DotNetUtils.getMethod(type, ".ctor");
|
||||||
|
@ -274,7 +274,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
continue;
|
continue;
|
||||||
if (git.GenericArguments.Count != 1)
|
if (git.GenericArguments.Count != 1)
|
||||||
continue;
|
continue;
|
||||||
var type2 = git.GenericArguments[0] as TypeDefinition;
|
var type2 = git.GenericArguments[0] as TypeDef;
|
||||||
if (type2 == null)
|
if (type2 == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
foreach (var instr in ctor.Body.Instructions) {
|
foreach (var instr in ctor.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Newobj)
|
if (instr.OpCode.Code != Code.Newobj)
|
||||||
continue;
|
continue;
|
||||||
var newobjCtor = instr.Operand as MethodDefinition;
|
var newobjCtor = instr.Operand as MethodDef;
|
||||||
if (newobjCtor == null)
|
if (newobjCtor == null)
|
||||||
continue;
|
continue;
|
||||||
if (newobjCtor.DeclaringType == assemblyManagerType)
|
if (newobjCtor.DeclaringType == assemblyManagerType)
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.MyStuff;
|
using Mono.MyStuff;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
ProxyCallFixer proxyCallFixer;
|
ProxyCallFixer proxyCallFixer;
|
||||||
StringDecrypter stringDecrypter;
|
StringDecrypter stringDecrypter;
|
||||||
AssemblyResolver assemblyResolver;
|
AssemblyResolver assemblyResolver;
|
||||||
TypeDefinition killType;
|
TypeDef killType;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
|
|
||||||
internal class Options : OptionsBase {
|
internal class Options : OptionsBase {
|
||||||
|
@ -279,7 +279,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
if (stringDecrypter.DecryptMethod != null)
|
if (stringDecrypter.DecryptMethod != null)
|
||||||
list.Add(stringDecrypter.DecryptMethod.MetadataToken.ToInt32());
|
list.Add(stringDecrypter.DecryptMethod.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeVeil {
|
namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
class InvalidMethodsFinder {
|
class InvalidMethodsFinder {
|
||||||
public static List<MethodDefinition> findAll(ModuleDefinition module) {
|
public static List<MethodDef> findAll(ModuleDefinition module) {
|
||||||
var list = new List<MethodDefinition>();
|
var list = new List<MethodDef>();
|
||||||
foreach (var type in module.GetTypes()) {
|
foreach (var type in module.GetTypes()) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (isInvalidMethod(method))
|
if (isInvalidMethod(method))
|
||||||
|
@ -33,14 +33,14 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool isInvalidMethod(MethodDefinition method) {
|
public static bool isInvalidMethod(MethodDef method) {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return false;
|
return false;
|
||||||
if (method.IsStatic)
|
if (method.IsStatic)
|
||||||
return false;
|
return false;
|
||||||
if (method.Parameters.Count != 0)
|
if (method.Parameters.Count != 0)
|
||||||
return false;
|
return false;
|
||||||
var retType = method.MethodReturnType.ReturnType as GenericParameter;
|
var retType = method.MethodReturnType.ReturnType as GenericParam;
|
||||||
if (retType == null)
|
if (retType == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -27,12 +27,12 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
// Detects the type CV adds to the assembly that gets called from <Module>::.cctor.
|
// Detects the type CV adds to the assembly that gets called from <Module>::.cctor.
|
||||||
class MainType {
|
class MainType {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition theType;
|
TypeDef theType;
|
||||||
MethodDefinition initMethod;
|
MethodDef initMethod;
|
||||||
MethodDefinition tamperCheckMethod;
|
MethodDef tamperCheckMethod;
|
||||||
ObfuscatorVersion obfuscatorVersion = ObfuscatorVersion.Unknown;
|
ObfuscatorVersion obfuscatorVersion = ObfuscatorVersion.Unknown;
|
||||||
List<int> rvas = new List<int>(); // _stub and _executive
|
List<int> rvas = new List<int>(); // _stub and _executive
|
||||||
List<MethodDefinition> otherInitMethods = new List<MethodDefinition>();
|
List<MethodDef> otherInitMethods = new List<MethodDef>();
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return theType != null; }
|
get { return theType != null; }
|
||||||
|
@ -42,19 +42,19 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
get { return obfuscatorVersion; }
|
get { return obfuscatorVersion; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return theType; }
|
get { return theType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitMethod {
|
public MethodDef InitMethod {
|
||||||
get { return initMethod; }
|
get { return initMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MethodDefinition> OtherInitMethods {
|
public List<MethodDef> OtherInitMethods {
|
||||||
get { return otherInitMethods; }
|
get { return otherInitMethods; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition TamperCheckMethod {
|
public MethodDef TamperCheckMethod {
|
||||||
get { return tamperCheckMethod; }
|
get { return tamperCheckMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
var call = instrs[i + 2];
|
var call = instrs[i + 2];
|
||||||
if (call.OpCode.Code != Code.Call)
|
if (call.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var initMethodTmp = call.Operand as MethodDefinition;
|
var initMethodTmp = call.Operand as MethodDef;
|
||||||
ObfuscatorVersion obfuscatorVersionTmp;
|
ObfuscatorVersion obfuscatorVersionTmp;
|
||||||
if (!checkInitMethod(initMethodTmp, out obfuscatorVersionTmp))
|
if (!checkInitMethod(initMethodTmp, out obfuscatorVersionTmp))
|
||||||
continue;
|
continue;
|
||||||
|
@ -118,7 +118,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
"System.Collections.Generic.List`1<System.Delegate>",
|
"System.Collections.Generic.List`1<System.Delegate>",
|
||||||
"System.Runtime.InteropServices.GCHandle",
|
"System.Runtime.InteropServices.GCHandle",
|
||||||
};
|
};
|
||||||
bool checkInitMethod(MethodDefinition initMethod, out ObfuscatorVersion obfuscatorVersionTmp) {
|
bool checkInitMethod(MethodDef initMethod, out ObfuscatorVersion obfuscatorVersionTmp) {
|
||||||
obfuscatorVersionTmp = ObfuscatorVersion.Unknown;
|
obfuscatorVersionTmp = ObfuscatorVersion.Unknown;
|
||||||
|
|
||||||
if (initMethod == null)
|
if (initMethod == null)
|
||||||
|
@ -146,7 +146,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasCodeString(MethodDefinition method, string str) {
|
static bool hasCodeString(MethodDef method, string str) {
|
||||||
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
||||||
if (s == str)
|
if (s == str)
|
||||||
return true;
|
return true;
|
||||||
|
@ -154,7 +154,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkMethodsType(TypeDefinition type) {
|
bool checkMethodsType(TypeDef type) {
|
||||||
rvas = new List<int>();
|
rvas = new List<int>();
|
||||||
|
|
||||||
var fields = getRvaFields(type);
|
var fields = getRvaFields(type);
|
||||||
|
@ -166,8 +166,8 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<FieldDefinition> getRvaFields(TypeDefinition type) {
|
static List<FieldDef> getRvaFields(TypeDef type) {
|
||||||
var fields = new List<FieldDefinition>();
|
var fields = new List<FieldDef>();
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
if (field.FieldType.EType != ElementType.U1 && field.FieldType.EType != ElementType.U4)
|
if (field.FieldType.EType != ElementType.U1 && field.FieldType.EType != ElementType.U4)
|
||||||
continue;
|
continue;
|
||||||
|
@ -187,7 +187,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
otherInitMethods = findOtherInitMethods();
|
otherInitMethods = findOtherInitMethods();
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition findTamperCheckMethod() {
|
MethodDef findTamperCheckMethod() {
|
||||||
foreach (var method in theType.Methods) {
|
foreach (var method in theType.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -200,8 +200,8 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MethodDefinition> findOtherInitMethods() {
|
List<MethodDef> findOtherInitMethods() {
|
||||||
var list = new List<MethodDefinition>();
|
var list = new List<MethodDef>();
|
||||||
foreach (var method in theType.Methods) {
|
foreach (var method in theType.Methods) {
|
||||||
if (!method.IsStatic)
|
if (!method.IsStatic)
|
||||||
continue;
|
continue;
|
||||||
|
@ -215,7 +215,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition getInitStringDecrypterMethod(MethodDefinition stringDecrypterInitMethod) {
|
public MethodDef getInitStringDecrypterMethod(MethodDef stringDecrypterInitMethod) {
|
||||||
if (stringDecrypterInitMethod == null)
|
if (stringDecrypterInitMethod == null)
|
||||||
return null;
|
return null;
|
||||||
if (theType == null)
|
if (theType == null)
|
||||||
|
@ -230,7 +230,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool callsMethod(MethodDefinition methodToCheck, MethodDefinition calledMethod) {
|
bool callsMethod(MethodDef methodToCheck, MethodDef calledMethod) {
|
||||||
foreach (var method in DotNetUtils.getCalledMethods(module, methodToCheck)) {
|
foreach (var method in DotNetUtils.getCalledMethods(module, methodToCheck)) {
|
||||||
if (method == calledMethod)
|
if (method == calledMethod)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using Mono.MyStuff;
|
using Mono.MyStuff;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -32,12 +32,12 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
BinaryReader reader;
|
BinaryReader reader;
|
||||||
|
|
||||||
class Info {
|
class Info {
|
||||||
public TypeDefinition proxyType;
|
public TypeDef proxyType;
|
||||||
public MethodDefinition initMethod;
|
public MethodDef initMethod;
|
||||||
public FieldDefinition dataField;
|
public FieldDef dataField;
|
||||||
public TypeDefinition ilgeneratorType;
|
public TypeDef ilgeneratorType;
|
||||||
public TypeDefinition fieldInfoType;
|
public TypeDef fieldInfoType;
|
||||||
public TypeDefinition methodInfoType;
|
public TypeDef methodInfoType;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
|
@ -61,15 +61,15 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition IlGeneratorType {
|
public TypeDef IlGeneratorType {
|
||||||
get { return info.ilgeneratorType; }
|
get { return info.ilgeneratorType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition FieldInfoType {
|
public TypeDef FieldInfoType {
|
||||||
get { return info.fieldInfoType; }
|
get { return info.fieldInfoType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition MethodInfoType {
|
public TypeDef MethodInfoType {
|
||||||
get { return info.methodInfoType; }
|
get { return info.methodInfoType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
info.methodInfoType = lookup(oldOne.info.methodInfoType, "Could not find methodInfoType");
|
info.methodInfoType = lookup(oldOne.info.methodInfoType, "Could not find methodInfoType");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override object checkCctor(ref TypeDefinition type, MethodDefinition cctor) {
|
protected override object checkCctor(ref TypeDef type, MethodDef cctor) {
|
||||||
var instrs = cctor.Body.Instructions;
|
var instrs = cctor.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldci4 = instrs[i];
|
var ldci4 = instrs[i];
|
||||||
|
@ -105,14 +105,14 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
int offset = DotNetUtils.getLdcI4Value(ldci4);
|
int offset = DotNetUtils.getLdcI4Value(ldci4);
|
||||||
reader.BaseStream.Position = offset;
|
reader.BaseStream.Position = offset;
|
||||||
int rid = DeobUtils.readVariableLengthInt32(reader);
|
int rid = DeobUtils.readVariableLengthInt32(reader);
|
||||||
if (rid != type.MetadataToken.RID)
|
if (rid != type.MDToken.RID)
|
||||||
throw new ApplicationException("Invalid RID");
|
throw new ApplicationException("Invalid RID");
|
||||||
return string.Empty; // It's non-null
|
return string.Empty; // It's non-null
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode) {
|
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||||
byte flags = reader.ReadByte();
|
byte flags = reader.ReadByte();
|
||||||
|
|
||||||
int methodToken = 0x06000000 + ((flags & 0x3F) << 24) + DeobUtils.readVariableLengthInt32(reader);
|
int methodToken = 0x06000000 + ((flags & 0x3F) << 24) + DeobUtils.readVariableLengthInt32(reader);
|
||||||
|
@ -122,7 +122,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
calledMethod = module.LookupToken(methodToken) as MethodReference;
|
calledMethod = module.LookupToken(methodToken) as MethodReference;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
throw new ApplicationException("Could not find method");
|
throw new ApplicationException("Could not find method");
|
||||||
if (genericTypeToken != -1 && calledMethod.DeclaringType.MetadataToken.ToInt32() != genericTypeToken)
|
if (genericTypeToken != -1 && calledMethod.DeclaringType.MDToken.ToInt32() != genericTypeToken)
|
||||||
throw new ApplicationException("Invalid declaring type token");
|
throw new ApplicationException("Invalid declaring type token");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
setDelegateCreatorMethod(info.initMethod);
|
setDelegateCreatorMethod(info.initMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeInfo(Info infoTmp, TypeDefinition type) {
|
bool initializeInfo(Info infoTmp, TypeDef type) {
|
||||||
foreach (var dtype in type.NestedTypes) {
|
foreach (var dtype in type.NestedTypes) {
|
||||||
var cctor = DotNetUtils.getMethod(dtype, ".cctor");
|
var cctor = DotNetUtils.getMethod(dtype, ".cctor");
|
||||||
if (cctor == null)
|
if (cctor == null)
|
||||||
|
@ -152,7 +152,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initProxyType(Info infoTmp, MethodDefinition method) {
|
bool initProxyType(Info infoTmp, MethodDef method) {
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
||||||
if (!calledMethod.IsStatic)
|
if (!calledMethod.IsStatic)
|
||||||
continue;
|
continue;
|
||||||
|
@ -175,7 +175,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
"System.Reflection.Emit.OpCode",
|
"System.Reflection.Emit.OpCode",
|
||||||
"System.Reflection.Emit.OpCode[]",
|
"System.Reflection.Emit.OpCode[]",
|
||||||
};
|
};
|
||||||
bool checkProxyType(Info infoTmp, TypeDefinition type) {
|
bool checkProxyType(Info infoTmp, TypeDef type) {
|
||||||
if (type.NestedTypes.Count != 1)
|
if (type.NestedTypes.Count != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -196,8 +196,8 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<FieldDefinition> getRvaFields(TypeDefinition type) {
|
static List<FieldDef> getRvaFields(TypeDef type) {
|
||||||
var fields = new List<FieldDefinition>();
|
var fields = new List<FieldDef>();
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
if (field.RVA != 0)
|
if (field.RVA != 0)
|
||||||
fields.Add(field);
|
fields.Add(field);
|
||||||
|
@ -205,9 +205,9 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<TypeDefinition> getDelegateTypes() {
|
protected override IEnumerable<TypeDef> getDelegateTypes() {
|
||||||
if (!mainType.Detected)
|
if (!mainType.Detected)
|
||||||
return new List<TypeDefinition>();
|
return new List<TypeDef>();
|
||||||
return mainType.Type.NestedTypes;
|
return mainType.Type.NestedTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,9 +233,9 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
|
|
||||||
if (method.Parameters[2].ParameterType.FullName != "System.Type[]")
|
if (method.Parameters[2].ParameterType.FullName != "System.Type[]")
|
||||||
continue;
|
continue;
|
||||||
var methodType = method.Parameters[0].ParameterType as TypeDefinition;
|
var methodType = method.Parameters[0].ParameterType as TypeDef;
|
||||||
var fieldType = method.Parameters[1].ParameterType as TypeDefinition;
|
var fieldType = method.Parameters[1].ParameterType as TypeDef;
|
||||||
var ilgType = method.Parameters[3].ParameterType as TypeDefinition;
|
var ilgType = method.Parameters[3].ParameterType as TypeDef;
|
||||||
if (!checkMethodType(methodType))
|
if (!checkMethodType(methodType))
|
||||||
continue;
|
continue;
|
||||||
if (!checkFieldType(fieldType))
|
if (!checkFieldType(fieldType))
|
||||||
|
@ -249,7 +249,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkMethodType(TypeDefinition type) {
|
bool checkMethodType(TypeDef type) {
|
||||||
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
||||||
return false;
|
return false;
|
||||||
if (type.Fields.Count != 1)
|
if (type.Fields.Count != 1)
|
||||||
|
@ -260,7 +260,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkFieldType(TypeDefinition type) {
|
bool checkFieldType(TypeDef type) {
|
||||||
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
||||||
return false;
|
return false;
|
||||||
if (DotNetUtils.getField(type, "System.Reflection.FieldInfo") == null)
|
if (DotNetUtils.getField(type, "System.Reflection.FieldInfo") == null)
|
||||||
|
@ -269,7 +269,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkIlGeneratorType(TypeDefinition type) {
|
bool checkIlGeneratorType(TypeDef type) {
|
||||||
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
||||||
return false;
|
return false;
|
||||||
if (type.Fields.Count != 1)
|
if (type.Fields.Count != 1)
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.code.resources;
|
using de4dot.code.resources;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeVeil {
|
namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
|
|
|
@ -19,23 +19,23 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeVeil {
|
namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
class ResourceDecrypter {
|
class ResourceDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition encryptedResourceStreamType;
|
TypeDef encryptedResourceStreamType;
|
||||||
TypeDefinition encryptedResourceSetType;
|
TypeDef encryptedResourceSetType;
|
||||||
MethodDefinition encryptedResourceSet_GetDefaultReader;
|
MethodDef encryptedResourceSet_GetDefaultReader;
|
||||||
TypeDefinition encryptedResourceReaderType;
|
TypeDef encryptedResourceReaderType;
|
||||||
GenericInstanceType encryptedResourceReaderTypeDict;
|
GenericInstanceType encryptedResourceReaderTypeDict;
|
||||||
TypeDefinition resType;
|
TypeDef resType;
|
||||||
MethodDefinition resTypeCtor;
|
MethodDef resTypeCtor;
|
||||||
TypeDefinition resourceFlagsType;
|
TypeDef resourceFlagsType;
|
||||||
TypeDefinition resourceEnumeratorType;
|
TypeDef resourceEnumeratorType;
|
||||||
MethodCallRestorerBase methodsRestorer;
|
MethodCallRestorerBase methodsRestorer;
|
||||||
|
|
||||||
public bool CanRemoveTypes {
|
public bool CanRemoveTypes {
|
||||||
|
@ -49,27 +49,27 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition EncryptedResourceStreamType {
|
public TypeDef EncryptedResourceStreamType {
|
||||||
get { return encryptedResourceStreamType; }
|
get { return encryptedResourceStreamType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition EncryptedResourceSetType {
|
public TypeDef EncryptedResourceSetType {
|
||||||
get { return encryptedResourceSetType; }
|
get { return encryptedResourceSetType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition EncryptedResourceReaderType {
|
public TypeDef EncryptedResourceReaderType {
|
||||||
get { return encryptedResourceReaderType; }
|
get { return encryptedResourceReaderType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition ResType {
|
public TypeDef ResType {
|
||||||
get { return resType; }
|
get { return resType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition ResourceFlagsType {
|
public TypeDef ResourceFlagsType {
|
||||||
get { return resourceFlagsType; }
|
get { return resourceFlagsType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition ResourceEnumeratorType {
|
public TypeDef ResourceEnumeratorType {
|
||||||
get { return resourceEnumeratorType; }
|
get { return resourceEnumeratorType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
void findResourceFlags() {
|
void findResourceFlags() {
|
||||||
if (resTypeCtor == null || resTypeCtor.Parameters.Count != 4)
|
if (resTypeCtor == null || resTypeCtor.Parameters.Count != 4)
|
||||||
return;
|
return;
|
||||||
var type = resTypeCtor.Parameters[2].ParameterType as TypeDefinition;
|
var type = resTypeCtor.Parameters[2].ParameterType as TypeDef;
|
||||||
if (type == null || !type.IsEnum)
|
if (type == null || !type.IsEnum)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
void findResType() {
|
void findResType() {
|
||||||
if (encryptedResourceReaderTypeDict == null)
|
if (encryptedResourceReaderTypeDict == null)
|
||||||
return;
|
return;
|
||||||
var type = encryptedResourceReaderTypeDict.GenericArguments[1] as TypeDefinition;
|
var type = encryptedResourceReaderTypeDict.GenericArguments[1] as TypeDef;
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return;
|
return;
|
||||||
if (type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
if (type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
||||||
|
@ -175,7 +175,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
encryptedResourceReaderTypeDict = dictType;
|
encryptedResourceReaderTypeDict = dictType;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasInterface(TypeDefinition type, string interfaceFullName) {
|
static bool hasInterface(TypeDef type, string interfaceFullName) {
|
||||||
foreach (var iface in type.Interfaces) {
|
foreach (var iface in type.Interfaces) {
|
||||||
if (iface.FullName == interfaceFullName)
|
if (iface.FullName == interfaceFullName)
|
||||||
return true;
|
return true;
|
||||||
|
@ -183,7 +183,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GenericInstanceType getDlxResDict(TypeDefinition type) {
|
static GenericInstanceType getDlxResDict(TypeDef type) {
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
var fieldType = field.FieldType as GenericInstanceType;
|
var fieldType = field.FieldType as GenericInstanceType;
|
||||||
if (fieldType == null)
|
if (fieldType == null)
|
||||||
|
@ -194,20 +194,20 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
continue;
|
continue;
|
||||||
if (fieldType.GenericArguments[0].FullName != "System.String")
|
if (fieldType.GenericArguments[0].FullName != "System.String")
|
||||||
continue;
|
continue;
|
||||||
if (!(fieldType.GenericArguments[1] is TypeDefinition))
|
if (!(fieldType.GenericArguments[1] is TypeDef))
|
||||||
continue;
|
continue;
|
||||||
return fieldType;
|
return fieldType;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeDefinition getTypeFromCode(MethodDefinition method) {
|
static TypeDef getTypeFromCode(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return null;
|
return null;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Ldtoken)
|
if (instr.OpCode.Code != Code.Ldtoken)
|
||||||
continue;
|
continue;
|
||||||
var type = instr.Operand as TypeDefinition;
|
var type = instr.Operand as TypeDef;
|
||||||
if (type != null)
|
if (type != null)
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
if (findXxteaMethod(type) == null)
|
if (findXxteaMethod(type) == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MethodDefinition getManifestResourceStreamMethodTmp1, getManifestResourceStreamMethodTmp2;
|
MethodDef getManifestResourceStreamMethodTmp1, getManifestResourceStreamMethodTmp2;
|
||||||
if (!findManifestResourceStreamMethods(type, out getManifestResourceStreamMethodTmp1, out getManifestResourceStreamMethodTmp2))
|
if (!findManifestResourceStreamMethods(type, out getManifestResourceStreamMethodTmp1, out getManifestResourceStreamMethodTmp2))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findXxteaMethod(TypeDefinition type) {
|
static MethodDef findXxteaMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsPrivate || method.IsStatic || method.Body == null)
|
if (!method.IsPrivate || method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -292,7 +292,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findManifestResourceStreamMethods(TypeDefinition type, out MethodDefinition getManifestResourceStreamMethodTmp1, out MethodDefinition getManifestResourceStreamMethodTmp2) {
|
static bool findManifestResourceStreamMethods(TypeDef type, out MethodDef getManifestResourceStreamMethodTmp1, out MethodDef getManifestResourceStreamMethodTmp2) {
|
||||||
getManifestResourceStreamMethodTmp1 = null;
|
getManifestResourceStreamMethodTmp1 = null;
|
||||||
getManifestResourceStreamMethodTmp2 = null;
|
getManifestResourceStreamMethodTmp2 = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
|
|
|
@ -19,33 +19,33 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeVeil {
|
namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
class StringDecrypter {
|
class StringDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
MainType mainType;
|
MainType mainType;
|
||||||
TypeDefinition decrypterType;
|
TypeDef decrypterType;
|
||||||
FieldDefinition stringDataField;
|
FieldDef stringDataField;
|
||||||
MethodDefinition initMethod;
|
MethodDef initMethod;
|
||||||
MethodDefinition decrypterMethod;
|
MethodDef decrypterMethod;
|
||||||
string[] decryptedStrings;
|
string[] decryptedStrings;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return decrypterType != null; }
|
get { return decrypterType != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return decrypterType; }
|
get { return decrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitMethod {
|
public MethodDef InitMethod {
|
||||||
get { return initMethod; }
|
get { return initMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition DecryptMethod {
|
public MethodDef DecryptMethod {
|
||||||
get { return decrypterMethod; }
|
get { return decrypterMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
findV5(cctor);
|
findV5(cctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find(MethodDefinition method) {
|
bool find(MethodDef method) {
|
||||||
if (method == null || method.Body == null || !method.IsStatic)
|
if (method == null || method.Body == null || !method.IsStatic)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
var call = instrs[i];
|
var call = instrs[i];
|
||||||
if (call.OpCode.Code != Code.Call)
|
if (call.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var initMethodTmp = call.Operand as MethodDefinition;
|
var initMethodTmp = call.Operand as MethodDef;
|
||||||
if (initMethodTmp == null || initMethodTmp.Body == null || !initMethodTmp.IsStatic)
|
if (initMethodTmp == null || initMethodTmp.Body == null || !initMethodTmp.IsStatic)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(initMethodTmp, "System.Void", "()"))
|
if (!DotNetUtils.isMethod(initMethodTmp, "System.Void", "()"))
|
||||||
|
@ -105,7 +105,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The main decrypter type calls the string decrypter init method inside its init method
|
// The main decrypter type calls the string decrypter init method inside its init method
|
||||||
void findV5(MethodDefinition method) {
|
void findV5(MethodDef method) {
|
||||||
if (!mainType.Detected)
|
if (!mainType.Detected)
|
||||||
return;
|
return;
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, mainType.InitMethod)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, mainType.InitMethod)) {
|
||||||
|
@ -114,7 +114,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkType(TypeDefinition type) {
|
bool checkType(TypeDef type) {
|
||||||
if (!type.HasNestedTypes)
|
if (!type.HasNestedTypes)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -134,8 +134,8 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition getDecrypterMethod(TypeDefinition type) {
|
static MethodDef getDecrypterMethod(TypeDef type) {
|
||||||
MethodDefinition foundMethod = null;
|
MethodDef foundMethod = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Body == null || !method.IsStatic)
|
if (method.Body == null || !method.IsStatic)
|
||||||
continue;
|
continue;
|
||||||
|
@ -155,11 +155,11 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
"System.String[]",
|
"System.String[]",
|
||||||
"System.UInt32[]",
|
"System.UInt32[]",
|
||||||
};
|
};
|
||||||
FieldDefinition checkFields(TypeDefinition type) {
|
FieldDef checkFields(TypeDef type) {
|
||||||
if (!new FieldTypes(type).all(requiredFields))
|
if (!new FieldTypes(type).all(requiredFields))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
FieldDefinition stringData = null;
|
FieldDef stringData = null;
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
if (field.RVA != 0) {
|
if (field.RVA != 0) {
|
||||||
if (stringData != null)
|
if (stringData != null)
|
||||||
|
@ -193,7 +193,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
stringDataField.InitialValue = new byte[1];
|
stringDataField.InitialValue = new byte[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint[] getKey(MethodDefinition method) {
|
static uint[] getKey(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldci4 = instrs[i];
|
var ldci4 = instrs[i];
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -27,14 +27,14 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
class TamperDetection {
|
class TamperDetection {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
MainType mainType;
|
MainType mainType;
|
||||||
TypeDefinition tamperDetectionType;
|
TypeDef tamperDetectionType;
|
||||||
List<MethodDefinition> tamperDetectionMethods = new List<MethodDefinition>();
|
List<MethodDef> tamperDetectionMethods = new List<MethodDef>();
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return tamperDetectionType; }
|
get { return tamperDetectionType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MethodDefinition> Methods {
|
public List<MethodDef> Methods {
|
||||||
get { return tamperDetectionMethods; }
|
get { return tamperDetectionMethods; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkTamperDetectionClasses(IEnumerable<TypeDefinition> types) {
|
bool checkTamperDetectionClasses(IEnumerable<TypeDef> types) {
|
||||||
foreach (var type in types) {
|
foreach (var type in types) {
|
||||||
if (!isTamperDetectionClass(type))
|
if (!isTamperDetectionClass(type))
|
||||||
return false;
|
return false;
|
||||||
|
@ -90,13 +90,13 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTamperDetectionClass(TypeDefinition type) {
|
bool isTamperDetectionClass(TypeDef type) {
|
||||||
if (type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
if (type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
||||||
return false;
|
return false;
|
||||||
if ((type.Attributes & ~TypeAttributes.Sealed) != TypeAttributes.NestedAssembly)
|
if ((type.Attributes & ~TypeAttributes.Sealed) != TypeAttributes.NestedAssembly)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MethodDefinition cctor = null, initMethod = null;
|
MethodDef cctor = null, initMethod = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (InvalidMethodsFinder.isInvalidMethod(method))
|
if (InvalidMethodsFinder.isInvalidMethod(method))
|
||||||
continue;
|
continue;
|
||||||
|
@ -116,7 +116,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool callsMainTypeTamperCheckMethod(MethodDefinition method) {
|
bool callsMainTypeTamperCheckMethod(MethodDef method) {
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
||||||
if (calledMethod == mainType.TamperCheckMethod)
|
if (calledMethod == mainType.TamperCheckMethod)
|
||||||
return true;
|
return true;
|
||||||
|
@ -142,7 +142,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkInvokeCall(Instruction instr, string returnType, string parameters) {
|
static bool checkInvokeCall(Instruction instr, string returnType, string parameters) {
|
||||||
var method = instr.Operand as MethodDefinition;
|
var method = instr.Operand as MethodDef;
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return false;
|
return false;
|
||||||
if (method.Name != "Invoke")
|
if (method.Name != "Invoke")
|
||||||
|
|
|
@ -22,8 +22,8 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.code.resources;
|
using de4dot.code.resources;
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
if (!checkEntryPoint(method))
|
if (!checkEntryPoint(method))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MethodDefinition decryptAssemblyMethod;
|
MethodDef decryptAssemblyMethod;
|
||||||
var mainKey = getMainResourceKey(method, out decryptAssemblyMethod);
|
var mainKey = getMainResourceKey(method, out decryptAssemblyMethod);
|
||||||
if (mainKey == null)
|
if (mainKey == null)
|
||||||
return;
|
return;
|
||||||
|
@ -100,7 +100,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
"System.AppDomain",
|
"System.AppDomain",
|
||||||
"System.DateTime",
|
"System.DateTime",
|
||||||
};
|
};
|
||||||
bool checkEntryPoint(MethodDefinition method) {
|
bool checkEntryPoint(MethodDef method) {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return false;
|
return false;
|
||||||
if (!new LocalTypes(method).all(requiredLocals))
|
if (!new LocalTypes(method).all(requiredLocals))
|
||||||
|
@ -112,12 +112,12 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deobfuscateAll(MethodDefinition method) {
|
void deobfuscateAll(MethodDef method) {
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
simpleDeobfuscator.decryptStrings(method, deob);
|
simpleDeobfuscator.decryptStrings(method, deob);
|
||||||
}
|
}
|
||||||
|
|
||||||
string getMainResourceKey(MethodDefinition method, out MethodDefinition decryptAssemblyMethod) {
|
string getMainResourceKey(MethodDef method, out MethodDef decryptAssemblyMethod) {
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, method)) {
|
||||||
if (!calledMethod.IsStatic || calledMethod.Body == null)
|
if (!calledMethod.IsStatic || calledMethod.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -135,7 +135,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string getMainResourceKeyInfo(MethodDefinition method, out MethodDefinition decryptAssemblyMethod) {
|
string getMainResourceKeyInfo(MethodDef method, out MethodDef decryptAssemblyMethod) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldstr = instrs[i];
|
var ldstr = instrs[i];
|
||||||
|
@ -144,7 +144,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
var call = instrs[i + 1];
|
var call = instrs[i + 1];
|
||||||
if (call.OpCode.Code != Code.Call)
|
if (call.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = call.Operand as MethodDefinition;
|
var calledMethod = call.Operand as MethodDef;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbeddedResource getResource(MethodDefinition method, out ModuleDefinition theResourceModule) {
|
EmbeddedResource getResource(MethodDef method, out ModuleDefinition theResourceModule) {
|
||||||
string resourceDllFileName = null;
|
string resourceDllFileName = null;
|
||||||
theResourceModule = module;
|
theResourceModule = module;
|
||||||
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
||||||
|
@ -192,7 +192,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getPassword(MethodDefinition method, out string password, out string salt) {
|
bool getPassword(MethodDef method, out string password, out string salt) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldstr1 = instrs[i];
|
var ldstr1 = instrs[i];
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.MyStuff;
|
using Mono.MyStuff;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.PE;
|
using de4dot.PE;
|
||||||
|
@ -263,7 +263,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
foreach (var info in stringDecrypter.Infos)
|
foreach (var info in stringDecrypter.Infos)
|
||||||
list.Add(info.Method.MetadataToken.ToInt32());
|
list.Add(info.Method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.MyStuff;
|
using Mono.MyStuff;
|
||||||
using de4dot.PE;
|
using de4dot.PE;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
@ -51,7 +51,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkCctor(MethodDefinition method) {
|
bool checkCctor(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeWall {
|
namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
|
@ -38,13 +38,13 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StringEncrypterInfo {
|
public class StringEncrypterInfo {
|
||||||
MethodDefinition method;
|
MethodDef method;
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return method.DeclaringType; }
|
get { return method.DeclaringType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return method; }
|
get { return method; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
public int Magic3 { get; set; }
|
public int Magic3 { get; set; }
|
||||||
public BinaryReader Reader { get; set; }
|
public BinaryReader Reader { get; set; }
|
||||||
|
|
||||||
public StringEncrypterInfo(MethodDefinition method) {
|
public StringEncrypterInfo(MethodDef method) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return string.Format("{0:X8} M1:{1:X8} M2:{2:X8} M3:{3:X8}",
|
return string.Format("{0:X8} M1:{1:X8} M2:{2:X8} M3:{3:X8}",
|
||||||
Method.MetadataToken.ToInt32(),
|
Method.MDToken.ToInt32(),
|
||||||
Magic1, Magic2, Magic3);
|
Magic1, Magic2, Magic3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
|
|
||||||
public void find() {
|
public void find() {
|
||||||
foreach (var type in module.Types) {
|
foreach (var type in module.Types) {
|
||||||
MethodDefinition decrypterMethod;
|
MethodDef decrypterMethod;
|
||||||
var decrypterVersion = checkType(type, out decrypterMethod);
|
var decrypterVersion = checkType(type, out decrypterMethod);
|
||||||
if (decrypterVersion == Version.Unknown)
|
if (decrypterVersion == Version.Unknown)
|
||||||
continue;
|
continue;
|
||||||
|
@ -133,8 +133,8 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Version checkType(TypeDefinition type, out MethodDefinition decrypterMethod) {
|
Version checkType(TypeDef type, out MethodDef decrypterMethod) {
|
||||||
MethodDefinition method;
|
MethodDef method;
|
||||||
|
|
||||||
if ((method = checkType_v30(type)) != null) {
|
if ((method = checkType_v30(type)) != null) {
|
||||||
decrypterMethod = method;
|
decrypterMethod = method;
|
||||||
|
@ -161,8 +161,8 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
"System.Random",
|
"System.Random",
|
||||||
"System.String",
|
"System.String",
|
||||||
};
|
};
|
||||||
MethodDefinition checkType_v30(TypeDefinition type) {
|
MethodDef checkType_v30(TypeDef type) {
|
||||||
MethodDefinition decrypterMethod = checkMethods_v30(type);
|
MethodDef decrypterMethod = checkMethods_v30(type);
|
||||||
if (decrypterMethod == null)
|
if (decrypterMethod == null)
|
||||||
return null;
|
return null;
|
||||||
if (!new FieldTypes(type).exactly(requiredTypes_v30))
|
if (!new FieldTypes(type).exactly(requiredTypes_v30))
|
||||||
|
@ -173,12 +173,12 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
return decrypterMethod;
|
return decrypterMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition checkMethods_v30(TypeDefinition type) {
|
static MethodDef checkMethods_v30(TypeDef type) {
|
||||||
if (type.Methods.Count < 1 || type.Methods.Count > 2)
|
if (type.Methods.Count < 1 || type.Methods.Count > 2)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
MethodDefinition decrypterMethod = null;
|
MethodDef decrypterMethod = null;
|
||||||
MethodDefinition cctor = null;
|
MethodDef cctor = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Name == ".cctor") {
|
if (method.Name == ".cctor") {
|
||||||
cctor = method;
|
cctor = method;
|
||||||
|
@ -208,8 +208,8 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
"System.String",
|
"System.String",
|
||||||
"System.Object",
|
"System.Object",
|
||||||
};
|
};
|
||||||
MethodDefinition checkType_v36(TypeDefinition type) {
|
MethodDef checkType_v36(TypeDef type) {
|
||||||
MethodDefinition decrypterMethod = checkMethods_v36(type);
|
MethodDef decrypterMethod = checkMethods_v36(type);
|
||||||
if (decrypterMethod == null)
|
if (decrypterMethod == null)
|
||||||
return null;
|
return null;
|
||||||
if (!new FieldTypes(type).exactly(requiredTypes_v36))
|
if (!new FieldTypes(type).exactly(requiredTypes_v36))
|
||||||
|
@ -220,12 +220,12 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
return decrypterMethod;
|
return decrypterMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition checkMethods_v36(TypeDefinition type) {
|
static MethodDef checkMethods_v36(TypeDef type) {
|
||||||
if (type.Methods.Count != 2)
|
if (type.Methods.Count != 2)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
MethodDefinition decrypterMethod = null;
|
MethodDef decrypterMethod = null;
|
||||||
MethodDefinition cctor = null;
|
MethodDef cctor = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Name == ".cctor") {
|
if (method.Name == ".cctor") {
|
||||||
cctor = method;
|
cctor = method;
|
||||||
|
@ -249,7 +249,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
simpleDeobfuscator.deobfuscate(info.Method);
|
simpleDeobfuscator.deobfuscate(info.Method);
|
||||||
info.Resource = findResource(info.Method);
|
info.Resource = findResource(info.Method);
|
||||||
if (info.Resource == null) {
|
if (info.Resource == null) {
|
||||||
Log.w("Could not find encrypted strings resource (Method {0:X8})", info.Method.MetadataToken.ToInt32());
|
Log.w("Could not find encrypted strings resource (Method {0:X8})", info.Method.MDToken.ToInt32());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
info.Magic1 = findMagic1(info.Method);
|
info.Magic1 = findMagic1(info.Method);
|
||||||
|
@ -259,11 +259,11 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbeddedResource findResource(MethodDefinition method) {
|
EmbeddedResource findResource(MethodDef method) {
|
||||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findMagic1(MethodDefinition method) {
|
static int findMagic1(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||||
var ldarg = instrs[i];
|
var ldarg = instrs[i];
|
||||||
|
@ -279,7 +279,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
throw new ApplicationException("Could not find magic1");
|
throw new ApplicationException("Could not find magic1");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findMagic2(MethodDefinition method) {
|
static int findMagic2(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||||
var ldloc = instrs[i];
|
var ldloc = instrs[i];
|
||||||
|
@ -295,7 +295,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
throw new ApplicationException("Could not find magic2");
|
throw new ApplicationException("Could not find magic2");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findMagic3(MethodDefinition method) {
|
static int findMagic3(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||||
var ldarg = instrs[i];
|
var ldarg = instrs[i];
|
||||||
|
@ -311,7 +311,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
throw new ApplicationException("Could not find magic3");
|
throw new ApplicationException("Could not find magic3");
|
||||||
}
|
}
|
||||||
|
|
||||||
public string decrypt(MethodDefinition method, int magic1, int magic2, int magic3) {
|
public string decrypt(MethodDef method, int magic1, int magic2, int magic3) {
|
||||||
var info = stringEncrypterInfos.find(method);
|
var info = stringEncrypterInfos.find(method);
|
||||||
return info.decrypt(magic1, magic2, magic3);
|
return info.decrypt(magic1, magic2, magic3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
|
@ -25,14 +25,14 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
IDeobfuscator deob;
|
IDeobfuscator deob;
|
||||||
TypeDefinition antiDebuggerType;
|
TypeDef antiDebuggerType;
|
||||||
MethodDefinition antiDebuggerMethod;
|
MethodDef antiDebuggerMethod;
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return antiDebuggerType; }
|
get { return antiDebuggerType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return antiDebuggerMethod; }
|
get { return antiDebuggerMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find(MethodDefinition methodToCheck) {
|
bool find(MethodDef methodToCheck) {
|
||||||
if (methodToCheck == null)
|
if (methodToCheck == null)
|
||||||
return false;
|
return false;
|
||||||
foreach (var method in DotNetUtils.getCalledMethods(module, methodToCheck)) {
|
foreach (var method in DotNetUtils.getCalledMethods(module, methodToCheck)) {
|
||||||
|
@ -79,12 +79,12 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deobfuscate(MethodDefinition method) {
|
void deobfuscate(MethodDef method) {
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
simpleDeobfuscator.decryptStrings(method, deob);
|
simpleDeobfuscator.decryptStrings(method, deob);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool containsString(MethodDefinition method, string part) {
|
bool containsString(MethodDef method, string part) {
|
||||||
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
||||||
if (s.Contains(part))
|
if (s.Contains(part))
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -20,15 +20,15 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
class AssemblyResolver {
|
class AssemblyResolver {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition resolverType;
|
TypeDef resolverType;
|
||||||
MethodDefinition resolverMethod;
|
MethodDef resolverMethod;
|
||||||
List<AssemblyInfo> assemblyInfos = new List<AssemblyInfo>();
|
List<AssemblyInfo> assemblyInfos = new List<AssemblyInfo>();
|
||||||
|
|
||||||
public class AssemblyInfo {
|
public class AssemblyInfo {
|
||||||
|
@ -54,11 +54,11 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
get { return assemblyInfos; }
|
get { return assemblyInfos; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return resolverType; }
|
get { return resolverType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return resolverMethod; }
|
get { return resolverMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkType(TypeDefinition type, MethodDefinition initMethod) {
|
bool checkType(TypeDef type, MethodDef initMethod) {
|
||||||
if (DotNetUtils.findFieldType(type, "System.Collections.Hashtable", true) == null)
|
if (DotNetUtils.findFieldType(type, "System.Collections.Hashtable", true) == null)
|
||||||
return false;
|
return false;
|
||||||
if (!checkInitMethod(initMethod))
|
if (!checkInitMethod(initMethod))
|
||||||
|
@ -102,7 +102,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkInitMethod(MethodDefinition initMethod) {
|
bool checkInitMethod(MethodDef initMethod) {
|
||||||
if (!initMethod.HasBody)
|
if (!initMethod.HasBody)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
static class CoUtils {
|
static class CoUtils {
|
||||||
public static EmbeddedResource getResource(ModuleDefinition module, MethodDefinition method) {
|
public static EmbeddedResource getResource(ModuleDefinition module, MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return null;
|
return null;
|
||||||
return getResource(module, DotNetUtils.getCodeStrings(method));
|
return getResource(module, DotNetUtils.getCodeStrings(method));
|
||||||
|
|
|
@ -20,21 +20,21 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
class ConstantsDecrypter {
|
class ConstantsDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition decrypterType;
|
TypeDef decrypterType;
|
||||||
MethodDefinition methodI4;
|
MethodDef methodI4;
|
||||||
MethodDefinition methodI8;
|
MethodDef methodI8;
|
||||||
MethodDefinition methodR4;
|
MethodDef methodR4;
|
||||||
MethodDefinition methodR8;
|
MethodDef methodR8;
|
||||||
EmbeddedResource encryptedResource;
|
EmbeddedResource encryptedResource;
|
||||||
byte[] constantsData;
|
byte[] constantsData;
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return decrypterType; }
|
get { return decrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,19 +42,19 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
get { return encryptedResource; }
|
get { return encryptedResource; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Int32Decrypter {
|
public MethodDef Int32Decrypter {
|
||||||
get { return methodI4; }
|
get { return methodI4; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Int64Decrypter {
|
public MethodDef Int64Decrypter {
|
||||||
get { return methodI8; }
|
get { return methodI8; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition SingleDecrypter {
|
public MethodDef SingleDecrypter {
|
||||||
get { return methodR4; }
|
get { return methodR4; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition DoubleDecrypter {
|
public MethodDef DoubleDecrypter {
|
||||||
get { return methodR8; }
|
get { return methodR8; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
static readonly string[] requiredTypes = new string[] {
|
static readonly string[] requiredTypes = new string[] {
|
||||||
"System.Byte[]",
|
"System.Byte[]",
|
||||||
};
|
};
|
||||||
bool checkType(TypeDefinition type) {
|
bool checkType(TypeDef type) {
|
||||||
if (type.Methods.Count != 7)
|
if (type.Methods.Count != 7)
|
||||||
return false;
|
return false;
|
||||||
if (type.Fields.Count < 1 || type.Fields.Count > 2)
|
if (type.Fields.Count < 1 || type.Fields.Count > 2)
|
||||||
|
@ -92,7 +92,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkMethods(TypeDefinition type) {
|
bool checkMethods(TypeDef type) {
|
||||||
methodI4 = DotNetUtils.getMethod(type, "System.Int32", "(System.Int32)");
|
methodI4 = DotNetUtils.getMethod(type, "System.Int32", "(System.Int32)");
|
||||||
methodI8 = DotNetUtils.getMethod(type, "System.Int64", "(System.Int32)");
|
methodI8 = DotNetUtils.getMethod(type, "System.Int64", "(System.Int32)");
|
||||||
methodR4 = DotNetUtils.getMethod(type, "System.Single", "(System.Int32)");
|
methodR4 = DotNetUtils.getMethod(type, "System.Single", "(System.Int32)");
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
|
@ -149,7 +149,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
foundObfuscatorUserString = Utils.StartsWith(module.GetUserString(0x70000001), "\u0011\"3D9B94A98B-76A8-4810-B1A0-4BE7C4F9C98D", StringComparison.Ordinal);
|
foundObfuscatorUserString = Utils.StartsWith(module.GetUserString(0x70000001), "\u0011\"3D9B94A98B-76A8-4810-B1A0-4BE7C4F9C98D", StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeVersion(TypeDefinition attr) {
|
void initializeVersion(TypeDef attr) {
|
||||||
var s = DotNetUtils.getCustomArgAsString(getAssemblyAttribute(attr), 0);
|
var s = DotNetUtils.getCustomArgAsString(getAssemblyAttribute(attr), 0);
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return;
|
return;
|
||||||
|
@ -282,7 +282,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
if (stringDecrypter.Method != null)
|
if (stringDecrypter.Method != null)
|
||||||
list.Add(stringDecrypter.Method.MetadataToken.ToInt32());
|
list.Add(stringDecrypter.Method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
|
@ -34,7 +34,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void read(MethodDefinition method) {
|
public void read(MethodDef method) {
|
||||||
this.parameters = getParameters(method);
|
this.parameters = getParameters(method);
|
||||||
this.Locals = getLocals(method);
|
this.Locals = getLocals(method);
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return DotNetUtils.getParameters(method);
|
return DotNetUtils.getParameters(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
static IList<VariableDefinition> getLocals(MethodDefinition method) {
|
static IList<VariableDefinition> getLocals(MethodDef method) {
|
||||||
if (method.Body == null)
|
if (method.Body == null)
|
||||||
return new List<VariableDefinition>();
|
return new List<VariableDefinition>();
|
||||||
return new List<VariableDefinition>(method.Body.Variables);
|
return new List<VariableDefinition>(method.Body.Variables);
|
||||||
|
@ -115,7 +115,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return eh;
|
return eh;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void restoreMethod(MethodDefinition method) {
|
public override void restoreMethod(MethodDef method) {
|
||||||
base.restoreMethod(method);
|
base.restoreMethod(method);
|
||||||
method.Body.MaxStackSize = maxStackSize;
|
method.Body.MaxStackSize = maxStackSize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,24 +20,24 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
class MethodsDecrypter {
|
class MethodsDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition decrypterType;
|
TypeDef decrypterType;
|
||||||
MethodDefinition decryptMethod;
|
MethodDef decryptMethod;
|
||||||
MethodDefinition decrypterCctor;
|
MethodDef decrypterCctor;
|
||||||
EmbeddedResource resource;
|
EmbeddedResource resource;
|
||||||
List<TypeDefinition> delegateTypes = new List<TypeDefinition>();
|
List<TypeDef> delegateTypes = new List<TypeDef>();
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return decrypterType; }
|
get { return decrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<TypeDefinition> DelegateTypes {
|
public IEnumerable<TypeDef> DelegateTypes {
|
||||||
get { return delegateTypes; }
|
get { return delegateTypes; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
"System.Collections.Generic.Dictionary`2<System.Int32,System.Int32>",
|
"System.Collections.Generic.Dictionary`2<System.Int32,System.Int32>",
|
||||||
"System.ModuleHandle",
|
"System.ModuleHandle",
|
||||||
};
|
};
|
||||||
bool check(TypeDefinition type) {
|
bool check(TypeDef type) {
|
||||||
if (type.NestedTypes.Count != 1)
|
if (type.NestedTypes.Count != 1)
|
||||||
return false;
|
return false;
|
||||||
if (type.Fields.Count != 3)
|
if (type.Fields.Count != 3)
|
||||||
|
@ -98,7 +98,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
"System.Type",
|
"System.Type",
|
||||||
"System.Type[]",
|
"System.Type[]",
|
||||||
};
|
};
|
||||||
static MethodDefinition findDecryptMethod(TypeDefinition type) {
|
static MethodDef findDecryptMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -136,7 +136,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
}
|
}
|
||||||
|
|
||||||
void decrypt(BinaryReader reader, int delegateTypeToken) {
|
void decrypt(BinaryReader reader, int delegateTypeToken) {
|
||||||
var delegateType = module.LookupToken(delegateTypeToken) as TypeDefinition;
|
var delegateType = module.LookupToken(delegateTypeToken) as TypeDef;
|
||||||
if (delegateType == null)
|
if (delegateType == null)
|
||||||
throw new ApplicationException("Couldn't find delegate type");
|
throw new ApplicationException("Couldn't find delegate type");
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
var encType = module.LookupToken(encDeclToken) as TypeReference;
|
var encType = module.LookupToken(encDeclToken) as TypeReference;
|
||||||
if (encType == null)
|
if (encType == null)
|
||||||
throw new ApplicationException("Invalid declaring type token");
|
throw new ApplicationException("Invalid declaring type token");
|
||||||
var encMethod = module.LookupToken(encMethToken) as MethodDefinition;
|
var encMethod = module.LookupToken(encMethToken) as MethodDef;
|
||||||
if (encMethod == null)
|
if (encMethod == null)
|
||||||
throw new ApplicationException("Invalid encrypted method token");
|
throw new ApplicationException("Invalid encrypted method token");
|
||||||
|
|
||||||
|
@ -157,14 +157,14 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
bodyReader.restoreMethod(encMethod);
|
bodyReader.restoreMethod(encMethod);
|
||||||
Log.v("Restored method {0} ({1:X8}). Instrs:{2}, Locals:{3}, Exceptions:{4}",
|
Log.v("Restored method {0} ({1:X8}). Instrs:{2}, Locals:{3}, Exceptions:{4}",
|
||||||
Utils.removeNewlines(encMethod.FullName),
|
Utils.removeNewlines(encMethod.FullName),
|
||||||
encMethod.MetadataToken.ToInt32(),
|
encMethod.MDToken.ToInt32(),
|
||||||
encMethod.Body.Instructions.Count,
|
encMethod.Body.Instructions.Count,
|
||||||
encMethod.Body.Variables.Count,
|
encMethod.Body.Variables.Count,
|
||||||
encMethod.Body.ExceptionHandlers.Count);
|
encMethod.Body.ExceptionHandlers.Count);
|
||||||
delegateTypes.Add(delegateType);
|
delegateTypes.Add(delegateType);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getTokens(TypeDefinition delegateType, out int delegateToken, out int encMethodToken, out int encDeclaringTypeToken) {
|
bool getTokens(TypeDef delegateType, out int delegateToken, out int encMethodToken, out int encDeclaringTypeToken) {
|
||||||
delegateToken = 0;
|
delegateToken = 0;
|
||||||
encMethodToken = 0;
|
encMethodToken = 0;
|
||||||
encDeclaringTypeToken = 0;
|
encDeclaringTypeToken = 0;
|
||||||
|
@ -187,7 +187,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
var call = instrs[i + 3];
|
var call = instrs[i + 3];
|
||||||
if (call.OpCode.Code != Code.Call)
|
if (call.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = call.Operand as MethodDefinition;
|
var calledMethod = call.Operand as MethodDef;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
if (calledMethod != decryptMethod)
|
if (calledMethod != decryptMethod)
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
class ProxyCallFixer : ProxyCallFixer2 {
|
class ProxyCallFixer : ProxyCallFixer2 {
|
||||||
Dictionary<MethodDefinition, ProxyCreatorType> methodToType = new Dictionary<MethodDefinition, ProxyCreatorType>();
|
Dictionary<MethodDef, ProxyCreatorType> methodToType = new Dictionary<MethodDef, ProxyCreatorType>();
|
||||||
|
|
||||||
public ProxyCallFixer(ModuleDefinition module)
|
public ProxyCallFixer(ModuleDefinition module)
|
||||||
: base(module) {
|
: base(module) {
|
||||||
|
@ -51,7 +51,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override object checkCctor(TypeDefinition type, MethodDefinition cctor) {
|
protected override object checkCctor(TypeDef type, MethodDef cctor) {
|
||||||
var instructions = cctor.Body.Instructions;
|
var instructions = cctor.Body.Instructions;
|
||||||
for (int i = 0; i < instructions.Count; i++) {
|
for (int i = 0; i < instructions.Count; i++) {
|
||||||
var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldc_I4, OpCodes.Ldc_I4, OpCodes.Ldc_I4, OpCodes.Call);
|
var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldc_I4, OpCodes.Ldc_I4, OpCodes.Ldc_I4, OpCodes.Call);
|
||||||
|
@ -61,7 +61,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
int typeToken = (int)instrs[0].Operand;
|
int typeToken = (int)instrs[0].Operand;
|
||||||
int methodToken = (int)instrs[1].Operand;
|
int methodToken = (int)instrs[1].Operand;
|
||||||
int declaringTypeToken = (int)instrs[2].Operand;
|
int declaringTypeToken = (int)instrs[2].Operand;
|
||||||
var createMethod = instrs[3].Operand as MethodDefinition;
|
var createMethod = instrs[3].Operand as MethodDef;
|
||||||
|
|
||||||
ProxyCreatorType proxyCreatorType;
|
ProxyCreatorType proxyCreatorType;
|
||||||
if (!methodToType.TryGetValue(createMethod, out proxyCreatorType))
|
if (!methodToType.TryGetValue(createMethod, out proxyCreatorType))
|
||||||
|
@ -73,7 +73,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode) {
|
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||||
var ctx = (Context)context;
|
var ctx = (Context)context;
|
||||||
|
|
||||||
switch (ctx.proxyCreatorType) {
|
switch (ctx.proxyCreatorType) {
|
||||||
|
@ -107,13 +107,13 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition getProxyCreateMethod(TypeDefinition type) {
|
MethodDef getProxyCreateMethod(TypeDef type) {
|
||||||
if (DotNetUtils.findFieldType(type, "System.ModuleHandle", true) == null)
|
if (DotNetUtils.findFieldType(type, "System.ModuleHandle", true) == null)
|
||||||
return null;
|
return null;
|
||||||
if (type.Fields.Count < 1 || type.Fields.Count > 12)
|
if (type.Fields.Count < 1 || type.Fields.Count > 12)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
MethodDefinition createMethod = null;
|
MethodDef createMethod = null;
|
||||||
foreach (var m in type.Methods) {
|
foreach (var m in type.Methods) {
|
||||||
if (m.Name == ".ctor" || m.Name == ".cctor")
|
if (m.Name == ".ctor" || m.Name == ".cctor")
|
||||||
continue;
|
continue;
|
||||||
|
@ -131,7 +131,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return createMethod;
|
return createMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyCreatorType getProxyCreatorType(TypeDefinition type, MethodDefinition createMethod) {
|
ProxyCreatorType getProxyCreatorType(TypeDef type, MethodDef createMethod) {
|
||||||
int numCalls = 0, numCallvirts = 0, numNewobjs = 0;
|
int numCalls = 0, numCallvirts = 0, numNewobjs = 0;
|
||||||
foreach (var instr in createMethod.Body.Instructions) {
|
foreach (var instr in createMethod.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Ldsfld)
|
if (instr.OpCode.Code != Code.Ldsfld)
|
||||||
|
|
|
@ -22,15 +22,15 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
class ResourceDecrypter {
|
class ResourceDecrypter {
|
||||||
const int BUFLEN = 0x8000;
|
const int BUFLEN = 0x8000;
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition resourceDecrypterType;
|
TypeDef resourceDecrypterType;
|
||||||
byte[] buffer1 = new byte[BUFLEN];
|
byte[] buffer1 = new byte[BUFLEN];
|
||||||
byte[] buffer2 = new byte[BUFLEN];
|
byte[] buffer2 = new byte[BUFLEN];
|
||||||
byte desEncryptedFlag;
|
byte desEncryptedFlag;
|
||||||
|
@ -97,7 +97,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkCctor(MethodDefinition cctor) {
|
bool checkCctor(MethodDef cctor) {
|
||||||
if (cctor.Body == null)
|
if (cctor.Body == null)
|
||||||
return false;
|
return false;
|
||||||
int stsfldCount = 0;
|
int stsfldCount = 0;
|
||||||
|
@ -182,7 +182,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
bitwiseNotEncryptedFlag = 4;
|
bitwiseNotEncryptedFlag = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkFlipBits(MethodDefinition method) {
|
static bool checkFlipBits(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldloc = instrs[i];
|
var ldloc = instrs[i];
|
||||||
|
@ -202,7 +202,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updateFlags(MethodDefinition method, ISimpleDeobfuscator simpleDeobfuscator) {
|
bool updateFlags(MethodDef method, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getHeaderSkipBytes(MethodDefinition method) {
|
static int getHeaderSkipBytes(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldci4 = instrs[i];
|
var ldci4 = instrs[i];
|
||||||
|
@ -291,11 +291,11 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition getDecrypterMethod() {
|
MethodDef getDecrypterMethod() {
|
||||||
return getDecrypterMethod(resourceDecrypterType);
|
return getDecrypterMethod(resourceDecrypterType);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition getDecrypterMethod(TypeDefinition type) {
|
static MethodDef getDecrypterMethod(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (DotNetUtils.isMethod(method, "System.Byte[]", "(System.IO.Stream)"))
|
if (DotNetUtils.isMethod(method, "System.Byte[]", "(System.IO.Stream)"))
|
||||||
return method;
|
return method;
|
||||||
|
|
|
@ -19,16 +19,16 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
class ResourceResolver {
|
class ResourceResolver {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
TypeDefinition resolverType;
|
TypeDef resolverType;
|
||||||
MethodDefinition resolverMethod;
|
MethodDef resolverMethod;
|
||||||
ResolverVersion resolverVersion = ResolverVersion.V1;
|
ResolverVersion resolverVersion = ResolverVersion.V1;
|
||||||
bool mergedIt = false;
|
bool mergedIt = false;
|
||||||
|
|
||||||
|
@ -38,11 +38,11 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
V2,
|
V2,
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return resolverType; }
|
get { return resolverType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return resolverMethod; }
|
get { return resolverMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkType(MethodDefinition initMethod) {
|
bool checkType(MethodDef initMethod) {
|
||||||
if (!initMethod.HasBody)
|
if (!initMethod.HasBody)
|
||||||
return false;
|
return false;
|
||||||
if (DotNetUtils.findFieldType(initMethod.DeclaringType, "System.Reflection.Assembly", true) == null)
|
if (DotNetUtils.findFieldType(initMethod.DeclaringType, "System.Reflection.Assembly", true) == null)
|
||||||
|
@ -116,7 +116,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolverVersion checkSetupMethod(MethodDefinition setupMethod) {
|
ResolverVersion checkSetupMethod(MethodDef setupMethod) {
|
||||||
var instructions = setupMethod.Body.Instructions;
|
var instructions = setupMethod.Body.Instructions;
|
||||||
int foundCount = 0;
|
int foundCount = 0;
|
||||||
for (int i = 0; i < instructions.Count; i++) {
|
for (int i = 0; i < instructions.Count; i++) {
|
||||||
|
|
|
@ -19,26 +19,26 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
class StringDecrypter {
|
class StringDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
EmbeddedResource stringResource;
|
EmbeddedResource stringResource;
|
||||||
TypeDefinition stringDecrypterType;
|
TypeDef stringDecrypterType;
|
||||||
MethodDefinition stringDecrypterMethod;
|
MethodDef stringDecrypterMethod;
|
||||||
byte[] decryptedData;
|
byte[] decryptedData;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return stringDecrypterType != null; }
|
get { return stringDecrypterType != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return stringDecrypterType; }
|
get { return stringDecrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return stringDecrypterMethod; }
|
get { return stringDecrypterMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void find() {
|
public void find() {
|
||||||
TypeDefinition type;
|
TypeDef type;
|
||||||
MethodDefinition method;
|
MethodDef method;
|
||||||
if (!findStringDecrypterType(out type, out method))
|
if (!findStringDecrypterType(out type, out method))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return Encoding.Unicode.GetString(decryptedData, index, len);
|
return Encoding.Unicode.GetString(decryptedData, index, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findStringDecrypterType(out TypeDefinition theType, out MethodDefinition theMethod) {
|
bool findStringDecrypterType(out TypeDef theType, out MethodDef theMethod) {
|
||||||
theType = null;
|
theType = null;
|
||||||
theMethod = null;
|
theMethod = null;
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
if (type.NestedTypes.Count > 0)
|
if (type.NestedTypes.Count > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MethodDefinition method = null;
|
MethodDef method = null;
|
||||||
foreach (var m in type.Methods) {
|
foreach (var m in type.Methods) {
|
||||||
if (m.Name == ".ctor" || m.Name == ".cctor")
|
if (m.Name == ".ctor" || m.Name == ".cctor")
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -17,25 +17,25 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
class TamperDetection {
|
class TamperDetection {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition tamperType;
|
TypeDef tamperType;
|
||||||
MethodDefinition tamperMethod;
|
MethodDef tamperMethod;
|
||||||
FrameworkType frameworkType;
|
FrameworkType frameworkType;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return tamperMethod != null; }
|
get { return tamperMethod != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return tamperType; }
|
get { return tamperType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return tamperMethod; }
|
get { return tamperMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find(MethodDefinition methodToCheck) {
|
bool find(MethodDef methodToCheck) {
|
||||||
if (methodToCheck == null)
|
if (methodToCheck == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findDesktop(MethodDefinition method) {
|
bool findDesktop(MethodDef method) {
|
||||||
var type = method.DeclaringType;
|
var type = method.DeclaringType;
|
||||||
|
|
||||||
if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()"))
|
if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()"))
|
||||||
|
@ -107,7 +107,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
"System.Reflection.AssemblyName",
|
"System.Reflection.AssemblyName",
|
||||||
"System.String",
|
"System.String",
|
||||||
};
|
};
|
||||||
bool findSilverlight(MethodDefinition method) {
|
bool findSilverlight(MethodDef method) {
|
||||||
if (!new LocalTypes(method).exactly(requiredLocals_sl))
|
if (!new LocalTypes(method).exactly(requiredLocals_sl))
|
||||||
return false;
|
return false;
|
||||||
if (!DotNetUtils.callsMethod(method, "System.Int32 System.String::get_Length()"))
|
if (!DotNetUtils.callsMethod(method, "System.Int32 System.String::get_Length()"))
|
||||||
|
@ -136,7 +136,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
"System.Int32",
|
"System.Int32",
|
||||||
"System.String",
|
"System.String",
|
||||||
};
|
};
|
||||||
bool findCompactFramework(MethodDefinition method) {
|
bool findCompactFramework(MethodDef method) {
|
||||||
if (!new LocalTypes(method).exactly(requiredLocals_cf))
|
if (!new LocalTypes(method).exactly(requiredLocals_cf))
|
||||||
return false;
|
return false;
|
||||||
if (!DotNetUtils.callsMethod(method, "System.Int32 System.String::get_Length()"))
|
if (!DotNetUtils.callsMethod(method, "System.Int32 System.String::get_Length()"))
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -29,11 +29,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
FieldDefinitionAndDeclaringTypeDict<FieldInfo> fieldToInfo = new FieldDefinitionAndDeclaringTypeDict<FieldInfo>();
|
FieldDefinitionAndDeclaringTypeDict<FieldInfo> fieldToInfo = new FieldDefinitionAndDeclaringTypeDict<FieldInfo>();
|
||||||
|
|
||||||
public class FieldInfo {
|
public class FieldInfo {
|
||||||
public readonly FieldDefinition field;
|
public readonly FieldDef field;
|
||||||
public readonly FieldDefinition arrayInitField;
|
public readonly FieldDef arrayInitField;
|
||||||
public readonly byte[] array;
|
public readonly byte[] array;
|
||||||
|
|
||||||
public FieldInfo(FieldDefinition field, FieldDefinition arrayInitField) {
|
public FieldInfo(FieldDef field, FieldDef arrayInitField) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.arrayInitField = arrayInitField;
|
this.arrayInitField = arrayInitField;
|
||||||
this.array = (byte[])arrayInitField.InitialValue.Clone();
|
this.array = (byte[])arrayInitField.InitialValue.Clone();
|
||||||
|
@ -52,14 +52,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
initializeArrays(simpleDeobfuscator, DotNetUtils.getModuleTypeCctor(module));
|
initializeArrays(simpleDeobfuscator, DotNetUtils.getModuleTypeCctor(module));
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeArrays(ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition method) {
|
void initializeArrays(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return;
|
return;
|
||||||
while (initializeArrays2(simpleDeobfuscator, method)) {
|
while (initializeArrays2(simpleDeobfuscator, method)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeArrays2(ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition method) {
|
bool initializeArrays2(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) {
|
||||||
bool foundField = false;
|
bool foundField = false;
|
||||||
simpleDeobfuscator.deobfuscate(method, true);
|
simpleDeobfuscator.deobfuscate(method, true);
|
||||||
var instructions = method.Body.Instructions;
|
var instructions = method.Body.Instructions;
|
||||||
|
@ -76,7 +76,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
if (arrayType == null || arrayType.EType != ElementType.U1)
|
if (arrayType == null || arrayType.EType != ElementType.U1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var arrayInitField = instrs[2].Operand as FieldDefinition;
|
var arrayInitField = instrs[2].Operand as FieldDef;
|
||||||
if (arrayInitField == null || arrayInitField.InitialValue == null || arrayInitField.InitialValue.Length == 0)
|
if (arrayInitField == null || arrayInitField.InitialValue == null || arrayInitField.InitialValue.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
if (calledMethod == null || calledMethod.FullName != "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
|
if (calledMethod == null || calledMethod.FullName != "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var targetField = instrs[4].Operand as FieldDefinition;
|
var targetField = instrs[4].Operand as FieldDef;
|
||||||
if (targetField == null)
|
if (targetField == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -102,8 +102,8 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return fieldToInfo.find(fieldRef);
|
return fieldToInfo.find(fieldRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<FieldDefinition> cleanUp() {
|
public IEnumerable<FieldDef> cleanUp() {
|
||||||
var removedFields = new List<FieldDefinition>();
|
var removedFields = new List<FieldDef>();
|
||||||
var moduleCctor = DotNetUtils.getModuleTypeCctor(module);
|
var moduleCctor = DotNetUtils.getModuleTypeCctor(module);
|
||||||
if (moduleCctor == null)
|
if (moduleCctor == null)
|
||||||
return removedFields;
|
return removedFields;
|
||||||
|
|
|
@ -21,15 +21,15 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.DeepSea {
|
namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
class AssemblyResolver : ResolverBase {
|
class AssemblyResolver : ResolverBase {
|
||||||
Version version;
|
Version version;
|
||||||
List<FieldInfo> fieldInfos;
|
List<FieldInfo> fieldInfos;
|
||||||
MethodDefinition decryptMethod;
|
MethodDef decryptMethod;
|
||||||
|
|
||||||
enum Version {
|
enum Version {
|
||||||
Unknown,
|
Unknown,
|
||||||
|
@ -62,16 +62,16 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
|
|
||||||
class FieldInfo {
|
class FieldInfo {
|
||||||
public FieldDefinition field;
|
public FieldDef field;
|
||||||
public int magic;
|
public int magic;
|
||||||
|
|
||||||
public FieldInfo(FieldDefinition field, int magic) {
|
public FieldInfo(FieldDef field, int magic) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.magic = magic;
|
this.magic = magic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition DecryptMethod {
|
public MethodDef DecryptMethod {
|
||||||
get { return decryptMethod; }
|
get { return decryptMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
"System.Security.Cryptography.SHA1Managed",
|
"System.Security.Cryptography.SHA1Managed",
|
||||||
"System.Windows.AssemblyPart",
|
"System.Windows.AssemblyPart",
|
||||||
};
|
};
|
||||||
protected override bool checkResolverInitMethodSilverlight(MethodDefinition resolverInitMethod) {
|
protected override bool checkResolverInitMethodSilverlight(MethodDef resolverInitMethod) {
|
||||||
if (resolverInitMethod.Body.ExceptionHandlers.Count != 1)
|
if (resolverInitMethod.Body.ExceptionHandlers.Count != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateVersion(MethodDefinition handler) {
|
void updateVersion(MethodDef handler) {
|
||||||
if (isV3Old(handler)) {
|
if (isV3Old(handler)) {
|
||||||
version = Version.V3Old;
|
version = Version.V3Old;
|
||||||
return;
|
return;
|
||||||
|
@ -125,7 +125,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isV3SL(MethodDefinition handler) {
|
static bool isV3SL(MethodDef handler) {
|
||||||
var instrs = handler.Body.Instructions;
|
var instrs = handler.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||||
if (!DotNetUtils.isLdloc(instrs[i]))
|
if (!DotNetUtils.isLdloc(instrs[i]))
|
||||||
|
@ -141,7 +141,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isV41SL(MethodDefinition handler) {
|
static bool isV41SL(MethodDef handler) {
|
||||||
var instrs = handler.Body.Instructions;
|
var instrs = handler.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count; i++) {
|
for (int i = 0; i < instrs.Count; i++) {
|
||||||
if (!DotNetUtils.isLdcI4(instrs[i]) || DotNetUtils.getLdcI4Value(instrs[i]) != 5)
|
if (!DotNetUtils.isLdcI4(instrs[i]) || DotNetUtils.getLdcI4Value(instrs[i]) != 5)
|
||||||
|
@ -157,18 +157,18 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isV3Old(MethodDefinition method) {
|
static bool isV3Old(MethodDef method) {
|
||||||
return DotNetUtils.callsMethod(method, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)") &&
|
return DotNetUtils.callsMethod(method, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)") &&
|
||||||
!DotNetUtils.callsMethod(method, "System.Int32 System.IO.Stream::ReadByte()") &&
|
!DotNetUtils.callsMethod(method, "System.Int32 System.IO.Stream::ReadByte()") &&
|
||||||
// Obfuscated System.Int32 System.IO.Stream::ReadByte()
|
// Obfuscated System.Int32 System.IO.Stream::ReadByte()
|
||||||
!DotNetUtils.callsMethod(method, "System.Int32", "(System.IO.Stream,System.Int32,System.Int32)");
|
!DotNetUtils.callsMethod(method, "System.Int32", "(System.IO.Stream,System.Int32,System.Int32)");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool checkResolverInitMethodInternal(MethodDefinition resolverInitMethod) {
|
protected override bool checkResolverInitMethodInternal(MethodDef resolverInitMethod) {
|
||||||
return DotNetUtils.callsMethod(resolverInitMethod, "System.Void System.AppDomain::add_AssemblyResolve(System.ResolveEventHandler)");
|
return DotNetUtils.callsMethod(resolverInitMethod, "System.Void System.AppDomain::add_AssemblyResolve(System.ResolveEventHandler)");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool checkHandlerMethodDesktopInternal(MethodDefinition handler) {
|
protected override bool checkHandlerMethodDesktopInternal(MethodDef handler) {
|
||||||
if (checkHandlerV3(handler) || checkHandlerSL(handler)) {
|
if (checkHandlerV3(handler) || checkHandlerSL(handler)) {
|
||||||
updateVersion(handler);
|
updateVersion(handler);
|
||||||
return true;
|
return true;
|
||||||
|
@ -176,7 +176,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
|
|
||||||
simpleDeobfuscator.deobfuscate(handler);
|
simpleDeobfuscator.deobfuscate(handler);
|
||||||
List<FieldInfo> fieldInfosTmp;
|
List<FieldInfo> fieldInfosTmp;
|
||||||
MethodDefinition decryptMethodTmp;
|
MethodDef decryptMethodTmp;
|
||||||
if (checkHandlerV4(handler, out fieldInfosTmp, out decryptMethodTmp)) {
|
if (checkHandlerV4(handler, out fieldInfosTmp, out decryptMethodTmp)) {
|
||||||
version = Version.V4;
|
version = Version.V4;
|
||||||
fieldInfos = fieldInfosTmp;
|
fieldInfos = fieldInfosTmp;
|
||||||
|
@ -204,7 +204,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
"System.Security.Cryptography.SHA1CryptoServiceProvider",
|
"System.Security.Cryptography.SHA1CryptoServiceProvider",
|
||||||
"System.String",
|
"System.String",
|
||||||
};
|
};
|
||||||
static bool checkHandlerV3(MethodDefinition handler) {
|
static bool checkHandlerV3(MethodDef handler) {
|
||||||
return new LocalTypes(handler).all(handlerLocalTypes_NET);
|
return new LocalTypes(handler).all(handlerLocalTypes_NET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,12 +216,12 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
"System.String",
|
"System.String",
|
||||||
"System.Windows.AssemblyPart",
|
"System.Windows.AssemblyPart",
|
||||||
};
|
};
|
||||||
static bool checkHandlerSL(MethodDefinition handler) {
|
static bool checkHandlerSL(MethodDef handler) {
|
||||||
return new LocalTypes(handler).all(handlerLocalTypes_SL);
|
return new LocalTypes(handler).all(handlerLocalTypes_SL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4.0.1.18 .. 4.0.3
|
// 4.0.1.18 .. 4.0.3
|
||||||
bool checkHandlerV4(MethodDefinition handler, out List<FieldInfo> fieldInfos, out MethodDefinition decryptMethod) {
|
bool checkHandlerV4(MethodDef handler, out List<FieldInfo> fieldInfos, out MethodDef decryptMethod) {
|
||||||
fieldInfos = new List<FieldInfo>();
|
fieldInfos = new List<FieldInfo>();
|
||||||
decryptMethod = null;
|
decryptMethod = null;
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
var ldtoken = instrs[index++];
|
var ldtoken = instrs[index++];
|
||||||
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
||||||
continue;
|
continue;
|
||||||
var field = ldtoken.Operand as FieldDefinition;
|
var field = ldtoken.Operand as FieldDef;
|
||||||
if (field == null || field.InitialValue == null || field.InitialValue.Length == 0)
|
if (field == null || field.InitialValue == null || field.InitialValue.Length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
call = instrs[index++];
|
call = instrs[index++];
|
||||||
if (call.OpCode.Code != Code.Call)
|
if (call.OpCode.Code != Code.Call)
|
||||||
return false;
|
return false;
|
||||||
var decryptMethodTmp = call.Operand as MethodDefinition;
|
var decryptMethodTmp = call.Operand as MethodDef;
|
||||||
if (!DotNetUtils.isMethod(decryptMethodTmp, "System.Reflection.Assembly", "(System.RuntimeFieldHandle,System.Int32,System.Int32)"))
|
if (!DotNetUtils.isMethod(decryptMethodTmp, "System.Reflection.Assembly", "(System.RuntimeFieldHandle,System.Int32,System.Int32)"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4.0.4, 4.1+
|
// 4.0.4, 4.1+
|
||||||
Version checkHandlerV404_41(MethodDefinition handler, out List<FieldInfo> fieldInfos, out MethodDefinition decryptMethod) {
|
Version checkHandlerV404_41(MethodDef handler, out List<FieldInfo> fieldInfos, out MethodDef decryptMethod) {
|
||||||
Version version = Version.Unknown;
|
Version version = Version.Unknown;
|
||||||
fieldInfos = new List<FieldInfo>();
|
fieldInfos = new List<FieldInfo>();
|
||||||
decryptMethod = null;
|
decryptMethod = null;
|
||||||
|
@ -286,7 +286,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
var ldtoken = instrs[index++];
|
var ldtoken = instrs[index++];
|
||||||
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
||||||
continue;
|
continue;
|
||||||
var field = ldtoken.Operand as FieldDefinition;
|
var field = ldtoken.Operand as FieldDef;
|
||||||
if (field == null || field.InitialValue == null || field.InitialValue.Length == 0)
|
if (field == null || field.InitialValue == null || field.InitialValue.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
var args = DsUtils.getArgValues(instrs, callIndex);
|
var args = DsUtils.getArgValues(instrs, callIndex);
|
||||||
if (args == null)
|
if (args == null)
|
||||||
continue;
|
continue;
|
||||||
var decryptMethodTmp = instrs[callIndex].Operand as MethodDefinition;
|
var decryptMethodTmp = instrs[callIndex].Operand as MethodDef;
|
||||||
if (decryptMethodTmp == null)
|
if (decryptMethodTmp == null)
|
||||||
continue;
|
continue;
|
||||||
int magic;
|
int magic;
|
||||||
|
@ -317,7 +317,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool getMagic(MethodDefinition method, IList<object> args, out Version version, out int magic) {
|
static bool getMagic(MethodDef method, IList<object> args, out Version version, out int magic) {
|
||||||
magic = 0;
|
magic = 0;
|
||||||
int magicIndex = getMagicIndex(method, out version);
|
int magicIndex = getMagicIndex(method, out version);
|
||||||
if (magicIndex < 0 || magicIndex >= args.Count)
|
if (magicIndex < 0 || magicIndex >= args.Count)
|
||||||
|
@ -330,7 +330,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getMagicIndex(MethodDefinition method, out Version version) {
|
static int getMagicIndex(MethodDef method, out Version version) {
|
||||||
int magicIndex = getMagicIndex404(method);
|
int magicIndex = getMagicIndex404(method);
|
||||||
if (magicIndex >= 0) {
|
if (magicIndex >= 0) {
|
||||||
version = Version.V404;
|
version = Version.V404;
|
||||||
|
@ -347,7 +347,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getMagicIndex404(MethodDefinition method) {
|
static int getMagicIndex404(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||||
int index = i;
|
int index = i;
|
||||||
|
@ -368,7 +368,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getMagicIndex41Trial(MethodDefinition method) {
|
static int getMagicIndex41Trial(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||||
int index = i;
|
int index = i;
|
||||||
|
|
|
@ -21,8 +21,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.DeepSea {
|
namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
class CastDeobfuscator : IBlocksDeobfuscator {
|
class CastDeobfuscator : IBlocksDeobfuscator {
|
||||||
|
@ -67,7 +67,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return string.Format("{0} - INVALID", local);
|
return string.Format("{0} - INVALID", local);
|
||||||
return string.Format("{0} - {1:X8} {2}", local, type.MetadataToken.ToInt32(), type.FullName);
|
return string.Format("{0} - {1:X8} {2}", local, type.MDToken.ToInt32(), type.FullName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ done:
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
foreach (var method in stringDecrypter.DecrypterMethods)
|
foreach (var method in stringDecrypter.DecrypterMethods)
|
||||||
list.Add(method.MetadataToken.ToInt32());
|
list.Add(method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.DeepSea {
|
namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
|
|
|
@ -18,16 +18,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.DeepSea {
|
namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
static class DsInlinedMethodsFinder {
|
static class DsInlinedMethodsFinder {
|
||||||
public static List<MethodDefinition> find(ModuleDefinition module, IEnumerable<MethodDefinition> notInlinedMethods) {
|
public static List<MethodDef> find(ModuleDefinition module, IEnumerable<MethodDef> notInlinedMethods) {
|
||||||
var notInlinedMethodsDict = new Dictionary<MethodDefinition, bool>();
|
var notInlinedMethodsDict = new Dictionary<MethodDef, bool>();
|
||||||
foreach (var method in notInlinedMethods)
|
foreach (var method in notInlinedMethods)
|
||||||
notInlinedMethodsDict[method] = true;
|
notInlinedMethodsDict[method] = true;
|
||||||
|
|
||||||
var inlinedMethods = new List<MethodDefinition>();
|
var inlinedMethods = new List<MethodDef>();
|
||||||
|
|
||||||
foreach (var type in module.GetTypes()) {
|
foreach (var type in module.GetTypes()) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
@ -30,7 +30,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
List<ParameterDefinition> parameters;
|
List<ParameterDefinition> parameters;
|
||||||
ParameterDefinition arg1, arg2;
|
ParameterDefinition arg1, arg2;
|
||||||
Value returnValue;
|
Value returnValue;
|
||||||
MethodDefinition methodToInline;
|
MethodDef methodToInline;
|
||||||
CachedCflowDeobfuscator cflowDeobfuscator;
|
CachedCflowDeobfuscator cflowDeobfuscator;
|
||||||
|
|
||||||
public DsMethodCallInliner(CachedCflowDeobfuscator cflowDeobfuscator) {
|
public DsMethodCallInliner(CachedCflowDeobfuscator cflowDeobfuscator) {
|
||||||
|
@ -51,7 +51,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inlineMethod(Instruction callInstr, int instrIndex) {
|
bool inlineMethod(Instruction callInstr, int instrIndex) {
|
||||||
var method = callInstr.Operand as MethodDefinition;
|
var method = callInstr.Operand as MethodDef;
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return false;
|
return false;
|
||||||
if (!canInline(method))
|
if (!canInline(method))
|
||||||
|
@ -70,7 +70,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inlineMethod(MethodDefinition methodToInline, int instrIndex, int const1, int const2) {
|
bool inlineMethod(MethodDef methodToInline, int instrIndex, int const1, int const2) {
|
||||||
this.methodToInline = methodToInline = cflowDeobfuscator.deobfuscate(methodToInline);
|
this.methodToInline = methodToInline = cflowDeobfuscator.deobfuscate(methodToInline);
|
||||||
|
|
||||||
parameters = DotNetUtils.getParameters(methodToInline);
|
parameters = DotNetUtils.getParameters(methodToInline);
|
||||||
|
@ -294,7 +294,7 @@ done:
|
||||||
return instructionEmulator.stackSize() == 0;
|
return instructionEmulator.stackSize() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool canInline(MethodDefinition method) {
|
public static bool canInline(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
if (method.Attributes != (MethodAttributes.Assembly | MethodAttributes.Static))
|
if (method.Attributes != (MethodAttributes.Assembly | MethodAttributes.Static))
|
||||||
|
@ -322,7 +322,7 @@ done:
|
||||||
return etype == ElementType.Char || etype == ElementType.I2 || etype == ElementType.I4;
|
return etype == ElementType.Char || etype == ElementType.I2 || etype == ElementType.I4;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool isReturn(MethodDefinition methodToInline, int instrIndex) {
|
protected override bool isReturn(MethodDef methodToInline, int instrIndex) {
|
||||||
int oldIndex = instrIndex;
|
int oldIndex = instrIndex;
|
||||||
if (base.isReturn(methodToInline, oldIndex))
|
if (base.isReturn(methodToInline, oldIndex))
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.DeepSea {
|
namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
|
@ -40,7 +40,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool getArgValue(MethodDefinition method, int index, out object arg) {
|
public static bool getArgValue(MethodDef method, int index, out object arg) {
|
||||||
return getArgValue(method.Body.Instructions[index], out arg);
|
return getArgValue(method.Body.Instructions[index], out arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -28,13 +28,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
// DS 4.x can move fields from a class to a struct. This class restores the fields.
|
// DS 4.x can move fields from a class to a struct. This class restores the fields.
|
||||||
class FieldsRestorer {
|
class FieldsRestorer {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinitionDict<List<TypeDefinition>> structToOwners = new TypeDefinitionDict<List<TypeDefinition>>();
|
TypeDefinitionDict<List<TypeDef>> structToOwners = new TypeDefinitionDict<List<TypeDef>>();
|
||||||
FieldDefinitionAndDeclaringTypeDict<bool> structFieldsToFix = new FieldDefinitionAndDeclaringTypeDict<bool>();
|
FieldDefinitionAndDeclaringTypeDict<bool> structFieldsToFix = new FieldDefinitionAndDeclaringTypeDict<bool>();
|
||||||
TypeDefinitionDict<FieldDefinitionAndDeclaringTypeDict<FieldDefinition>> typeToFieldsDict = new TypeDefinitionDict<FieldDefinitionAndDeclaringTypeDict<FieldDefinition>>();
|
TypeDefinitionDict<FieldDefinitionAndDeclaringTypeDict<FieldDef>> typeToFieldsDict = new TypeDefinitionDict<FieldDefinitionAndDeclaringTypeDict<FieldDef>>();
|
||||||
|
|
||||||
public List<TypeDefinition> FieldStructs {
|
public List<TypeDef> FieldStructs {
|
||||||
get {
|
get {
|
||||||
var list = new List<TypeDefinition>(structToOwners.Count);
|
var list = new List<TypeDef>(structToOwners.Count);
|
||||||
foreach (var structType in structToOwners.getKeys()) {
|
foreach (var structType in structToOwners.getKeys()) {
|
||||||
if (!hasNoMethods(structType))
|
if (!hasNoMethods(structType))
|
||||||
continue;
|
continue;
|
||||||
|
@ -45,7 +45,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasNoMethods(TypeDefinition type) {
|
static bool hasNoMethods(TypeDef type) {
|
||||||
if (type.Methods.Count == 0)
|
if (type.Methods.Count == 0)
|
||||||
return true;
|
return true;
|
||||||
if (type.BaseType == null)
|
if (type.BaseType == null)
|
||||||
|
@ -77,7 +77,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fieldsDict = new FieldDefinitionAndDeclaringTypeDict<FieldDefinition>();
|
var fieldsDict = new FieldDefinitionAndDeclaringTypeDict<FieldDef>();
|
||||||
typeToFieldsDict.add(ownerType, fieldsDict);
|
typeToFieldsDict.add(ownerType, fieldsDict);
|
||||||
foreach (var structField in structType.Fields) {
|
foreach (var structField in structType.Fields) {
|
||||||
var newField = DotNetUtils.createFieldDefinition(structField.Name, structField.Attributes, structField.FieldType);
|
var newField = DotNetUtils.createFieldDefinition(structField.Name, structField.Attributes, structField.FieldType);
|
||||||
|
@ -88,9 +88,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<TypeDefinition, List<TypeDefinition>> getMovedTypes() {
|
Dictionary<TypeDef, List<TypeDef>> getMovedTypes() {
|
||||||
var candidates = new Dictionary<TypeDefinition, List<TypeDefinition>>();
|
var candidates = new Dictionary<TypeDef, List<TypeDef>>();
|
||||||
var typeToStruct = new Dictionary<TypeDefinition, TypeDefinition>();
|
var typeToStruct = new Dictionary<TypeDef, TypeDef>();
|
||||||
foreach (var type in module.GetTypes()) {
|
foreach (var type in module.GetTypes()) {
|
||||||
foreach (var field in getPossibleFields(type)) {
|
foreach (var field in getPossibleFields(type)) {
|
||||||
var fieldType = DotNetUtils.getType(module, field.FieldType);
|
var fieldType = DotNetUtils.getType(module, field.FieldType);
|
||||||
|
@ -113,9 +113,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
if (!checkFields(fieldType))
|
if (!checkFields(fieldType))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
List<TypeDefinition> list;
|
List<TypeDef> list;
|
||||||
if (!candidates.TryGetValue(fieldType, out list))
|
if (!candidates.TryGetValue(fieldType, out list))
|
||||||
candidates[fieldType] = list = new List<TypeDefinition>();
|
candidates[fieldType] = list = new List<TypeDef>();
|
||||||
list.Add(type);
|
list.Add(type);
|
||||||
typeToStruct[type] = fieldType;
|
typeToStruct[type] = fieldType;
|
||||||
break;
|
break;
|
||||||
|
@ -123,7 +123,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var type in module.GetTypes()) {
|
foreach (var type in module.GetTypes()) {
|
||||||
TypeDefinition structType;
|
TypeDef structType;
|
||||||
typeToStruct.TryGetValue(type, out structType);
|
typeToStruct.TryGetValue(type, out structType);
|
||||||
|
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
|
@ -144,8 +144,8 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<FieldDefinition> getPossibleFields(TypeDefinition type) {
|
IEnumerable<FieldDef> getPossibleFields(TypeDef type) {
|
||||||
var typeToFields = new TypeDefinitionDict<List<FieldDefinition>>();
|
var typeToFields = new TypeDefinitionDict<List<FieldDef>>();
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
if (field.Attributes != FieldAttributes.Private)
|
if (field.Attributes != FieldAttributes.Private)
|
||||||
continue;
|
continue;
|
||||||
|
@ -156,7 +156,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
continue;
|
continue;
|
||||||
var list = typeToFields.find(fieldType);
|
var list = typeToFields.find(fieldType);
|
||||||
if (list == null)
|
if (list == null)
|
||||||
typeToFields.add(fieldType, list = new List<FieldDefinition>());
|
typeToFields.add(fieldType, list = new List<FieldDef>());
|
||||||
list.Add(field);
|
list.Add(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,20 +166,20 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkBaseType(TypeDefinition type) {
|
static bool checkBaseType(TypeDef type) {
|
||||||
if (type == null || type.BaseType == null)
|
if (type == null || type.BaseType == null)
|
||||||
return false;
|
return false;
|
||||||
return type.BaseType.FullName == "System.ValueType" || type.BaseType.EType == ElementType.Object;
|
return type.BaseType.FullName == "System.ValueType" || type.BaseType.EType == ElementType.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeType(Dictionary<TypeDefinition, List<TypeDefinition>> candidates, TypeReference type) {
|
void removeType(Dictionary<TypeDef, List<TypeDef>> candidates, TypeReference type) {
|
||||||
var typeDef = DotNetUtils.getType(module, type);
|
var typeDef = DotNetUtils.getType(module, type);
|
||||||
if (typeDef == null)
|
if (typeDef == null)
|
||||||
return;
|
return;
|
||||||
candidates.Remove(typeDef);
|
candidates.Remove(typeDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkMethods(TypeDefinition type) {
|
static bool checkMethods(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (method.Name == ".cctor")
|
if (method.Name == ".cctor")
|
||||||
continue;
|
continue;
|
||||||
|
@ -197,7 +197,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkFields(TypeDefinition type) {
|
static bool checkFields(TypeDef type) {
|
||||||
if (type.Fields.Count == 0)
|
if (type.Fields.Count == 0)
|
||||||
return false;
|
return false;
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
|
@ -270,7 +270,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return newInstrs;
|
return newInstrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldDefinition getNewField(FieldReference structField, FieldReference oldFieldRef) {
|
FieldDef getNewField(FieldReference structField, FieldReference oldFieldRef) {
|
||||||
var fieldsDict = typeToFieldsDict.find(structField.DeclaringType);
|
var fieldsDict = typeToFieldsDict.find(structField.DeclaringType);
|
||||||
if (fieldsDict == null)
|
if (fieldsDict == null)
|
||||||
throw new ApplicationException("Could not find structField declaringType");
|
throw new ApplicationException("Could not find structField declaringType");
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.DeepSea {
|
namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
|
@ -28,15 +28,15 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
protected ModuleDefinition module;
|
protected ModuleDefinition module;
|
||||||
protected ISimpleDeobfuscator simpleDeobfuscator;
|
protected ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
protected IDeobfuscator deob;
|
protected IDeobfuscator deob;
|
||||||
protected MethodDefinition initMethod;
|
protected MethodDef initMethod;
|
||||||
protected MethodDefinition resolveHandler;
|
protected MethodDef resolveHandler;
|
||||||
protected FrameworkType frameworkType;
|
protected FrameworkType frameworkType;
|
||||||
|
|
||||||
public MethodDefinition InitMethod {
|
public MethodDef InitMethod {
|
||||||
get { return initMethod; }
|
get { return initMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition HandlerMethod {
|
public MethodDef HandlerMethod {
|
||||||
get { return resolveHandler; }
|
get { return resolveHandler; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkCalledMethods(MethodDefinition checkMethod) {
|
bool checkCalledMethods(MethodDef checkMethod) {
|
||||||
if (checkMethod == null || checkMethod.Body == null)
|
if (checkMethod == null || checkMethod.Body == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkResolverInitMethod(MethodDefinition resolverInitMethod) {
|
bool checkResolverInitMethod(MethodDef resolverInitMethod) {
|
||||||
if (resolverInitMethod == null || resolverInitMethod.Body == null)
|
if (resolverInitMethod == null || resolverInitMethod.Body == null)
|
||||||
return false;
|
return false;
|
||||||
if (resolverInitMethod.Body.ExceptionHandlers.Count != 1)
|
if (resolverInitMethod.Body.ExceptionHandlers.Count != 1)
|
||||||
|
@ -89,7 +89,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkResolverInitMethodDesktop(MethodDefinition resolverInitMethod) {
|
bool checkResolverInitMethodDesktop(MethodDef resolverInitMethod) {
|
||||||
simpleDeobfuscator.deobfuscate(resolverInitMethod);
|
simpleDeobfuscator.deobfuscate(resolverInitMethod);
|
||||||
if (!checkResolverInitMethodInternal(resolverInitMethod))
|
if (!checkResolverInitMethodInternal(resolverInitMethod))
|
||||||
return false;
|
return false;
|
||||||
|
@ -106,25 +106,25 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool checkResolverInitMethodSilverlight(MethodDefinition resolverInitMethod) {
|
protected virtual bool checkResolverInitMethodSilverlight(MethodDef resolverInitMethod) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract bool checkResolverInitMethodInternal(MethodDefinition resolverInitMethod);
|
protected abstract bool checkResolverInitMethodInternal(MethodDef resolverInitMethod);
|
||||||
|
|
||||||
IEnumerable<MethodDefinition> getLdftnMethods(MethodDefinition method) {
|
IEnumerable<MethodDef> getLdftnMethods(MethodDef method) {
|
||||||
var list = new List<MethodDefinition>();
|
var list = new List<MethodDef>();
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Ldftn)
|
if (instr.OpCode.Code != Code.Ldftn)
|
||||||
continue;
|
continue;
|
||||||
var loadedMethod = instr.Operand as MethodDefinition;
|
var loadedMethod = instr.Operand as MethodDef;
|
||||||
if (loadedMethod != null)
|
if (loadedMethod != null)
|
||||||
list.Add(loadedMethod);
|
list.Add(loadedMethod);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkHandlerMethodDesktop(MethodDefinition handler) {
|
bool checkHandlerMethodDesktop(MethodDef handler) {
|
||||||
if (handler == null || handler.Body == null || !handler.IsStatic)
|
if (handler == null || handler.Body == null || !handler.IsStatic)
|
||||||
return false;
|
return false;
|
||||||
if (!DotNetUtils.isMethod(handler, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"))
|
if (!DotNetUtils.isMethod(handler, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"))
|
||||||
|
@ -132,7 +132,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return checkHandlerMethodDesktopInternal(handler);
|
return checkHandlerMethodDesktopInternal(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract bool checkHandlerMethodDesktopInternal(MethodDefinition handler);
|
protected abstract bool checkHandlerMethodDesktopInternal(MethodDef handler);
|
||||||
|
|
||||||
// 3.0.3.41 - 3.0.4.44
|
// 3.0.3.41 - 3.0.4.44
|
||||||
protected static byte[] decryptResourceV3Old(EmbeddedResource resource) {
|
protected static byte[] decryptResourceV3Old(EmbeddedResource resource) {
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.DeepSea {
|
namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
|
@ -42,30 +42,30 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Data40 {
|
class Data40 {
|
||||||
public FieldDefinition resourceField;
|
public FieldDef resourceField;
|
||||||
public MethodDefinition resolveHandler2;
|
public MethodDef resolveHandler2;
|
||||||
public MethodDefinition getDataMethod;
|
public MethodDef getDataMethod;
|
||||||
public int magic;
|
public int magic;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Data41 {
|
class Data41 {
|
||||||
public FieldDefinition resourceField;
|
public FieldDef resourceField;
|
||||||
public MethodDefinition resolveHandler2;
|
public MethodDef resolveHandler2;
|
||||||
public int magic;
|
public int magic;
|
||||||
public bool isTrial;
|
public bool isTrial;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HandlerInfo {
|
class HandlerInfo {
|
||||||
public MethodDefinition handler;
|
public MethodDef handler;
|
||||||
public IList<object> args;
|
public IList<object> args;
|
||||||
|
|
||||||
public HandlerInfo(MethodDefinition handler, IList<object> args) {
|
public HandlerInfo(MethodDef handler, IList<object> args) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitMethod2 {
|
public MethodDef InitMethod2 {
|
||||||
get {
|
get {
|
||||||
if (data40 != null)
|
if (data40 != null)
|
||||||
return data40.resolveHandler2;
|
return data40.resolveHandler2;
|
||||||
|
@ -75,7 +75,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition GetDataMethod {
|
public MethodDef GetDataMethod {
|
||||||
get { return data40 != null ? data40.getDataMethod : null; }
|
get { return data40 != null ? data40.getDataMethod : null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,11 +87,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
: base(module, simpleDeobfuscator, deob) {
|
: base(module, simpleDeobfuscator, deob) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool checkResolverInitMethodInternal(MethodDefinition resolverInitMethod) {
|
protected override bool checkResolverInitMethodInternal(MethodDef resolverInitMethod) {
|
||||||
return DotNetUtils.callsMethod(resolverInitMethod, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)");
|
return DotNetUtils.callsMethod(resolverInitMethod, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool checkHandlerMethodDesktopInternal(MethodDefinition handler) {
|
protected override bool checkHandlerMethodDesktopInternal(MethodDef handler) {
|
||||||
if (checkHandlerV3(handler)) {
|
if (checkHandlerV3(handler)) {
|
||||||
version = ResourceVersion.V3;
|
version = ResourceVersion.V3;
|
||||||
return true;
|
return true;
|
||||||
|
@ -114,13 +114,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandlerInfo getHandlerArgs41(MethodDefinition handler) {
|
HandlerInfo getHandlerArgs41(MethodDef handler) {
|
||||||
var instrs = handler.Body.Instructions;
|
var instrs = handler.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count; i++) {
|
for (int i = 0; i < instrs.Count; i++) {
|
||||||
var instr = instrs[i];
|
var instr = instrs[i];
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
if (getLdtokenField(calledMethod) == null)
|
if (getLdtokenField(calledMethod) == null)
|
||||||
|
@ -158,7 +158,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getMagicArgIndex41Retail(MethodDefinition method) {
|
static int getMagicArgIndex41Retail(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||||
var add = instrs[i];
|
var add = instrs[i];
|
||||||
|
@ -179,7 +179,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getMagicArgIndex41Trial(MethodDefinition method) {
|
static int getMagicArgIndex41Trial(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||||
var ldarg = instrs[i];
|
var ldarg = instrs[i];
|
||||||
|
@ -195,11 +195,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FieldDefinition getLdtokenField(MethodDefinition method) {
|
static FieldDef getLdtokenField(MethodDef method) {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Ldtoken)
|
if (instr.OpCode.Code != Code.Ldtoken)
|
||||||
continue;
|
continue;
|
||||||
var field = instr.Operand as FieldDefinition;
|
var field = instr.Operand as FieldDef;
|
||||||
if (field == null || field.InitialValue == null || field.InitialValue.Length == 0)
|
if (field == null || field.InitialValue == null || field.InitialValue.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -219,11 +219,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
"System.String",
|
"System.String",
|
||||||
"System.String[]",
|
"System.String[]",
|
||||||
};
|
};
|
||||||
static bool checkHandlerV3(MethodDefinition handler) {
|
static bool checkHandlerV3(MethodDef handler) {
|
||||||
return new LocalTypes(handler).all(handlerLocalTypes_V3);
|
return new LocalTypes(handler).all(handlerLocalTypes_V3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Data40 checkHandlerV40(MethodDefinition handler) {
|
static Data40 checkHandlerV40(MethodDef handler) {
|
||||||
var data40 = new Data40();
|
var data40 = new Data40();
|
||||||
|
|
||||||
var instrs = handler.Body.Instructions;
|
var instrs = handler.Body.Instructions;
|
||||||
|
@ -236,10 +236,10 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
var ldtoken = instrs[index++];
|
var ldtoken = instrs[index++];
|
||||||
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
||||||
continue;
|
continue;
|
||||||
var field = ldtoken.Operand as FieldDefinition;
|
var field = ldtoken.Operand as FieldDef;
|
||||||
|
|
||||||
string methodSig = "(System.ResolveEventArgs,System.RuntimeFieldHandle,System.Int32,System.String,System.Int32)";
|
string methodSig = "(System.ResolveEventArgs,System.RuntimeFieldHandle,System.Int32,System.String,System.Int32)";
|
||||||
var method = ldtoken.Operand as MethodDefinition;
|
var method = ldtoken.Operand as MethodDef;
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
// >= 4.0.4
|
// >= 4.0.4
|
||||||
if (!DotNetUtils.isMethod(method, "System.Byte[]", "()"))
|
if (!DotNetUtils.isMethod(method, "System.Byte[]", "()"))
|
||||||
|
@ -273,7 +273,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
call = instrs[index++];
|
call = instrs[index++];
|
||||||
if (call.OpCode.Code != Code.Call)
|
if (call.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var resolveHandler2 = call.Operand as MethodDefinition;
|
var resolveHandler2 = call.Operand as MethodDef;
|
||||||
if (!DotNetUtils.isMethod(resolveHandler2, "System.Reflection.Assembly", methodSig))
|
if (!DotNetUtils.isMethod(resolveHandler2, "System.Reflection.Assembly", methodSig))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -286,11 +286,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FieldDefinition getResourceField(MethodDefinition method) {
|
static FieldDef getResourceField(MethodDef method) {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Ldtoken)
|
if (instr.OpCode.Code != Code.Ldtoken)
|
||||||
continue;
|
continue;
|
||||||
var field = instr.Operand as FieldDefinition;
|
var field = instr.Operand as FieldDef;
|
||||||
if (field == null || field.InitialValue == null || field.InitialValue.Length == 0)
|
if (field == null || field.InitialValue == null || field.InitialValue.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
return field;
|
return field;
|
||||||
|
@ -337,11 +337,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool decryptResource(FieldDefinition resourceField, int magic) {
|
bool decryptResource(FieldDef resourceField, int magic) {
|
||||||
if (resourceField == null)
|
if (resourceField == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string name = string.Format("Embedded data field {0:X8} RVA {1:X8}", resourceField.MetadataToken.ToInt32(), resourceField.RVA);
|
string name = string.Format("Embedded data field {0:X8} RVA {1:X8}", resourceField.MDToken.ToInt32(), resourceField.RVA);
|
||||||
DeobUtils.decryptAndAddResources(module, name, () => decryptResourceV4(resourceField.InitialValue, magic));
|
DeobUtils.decryptAndAddResources(module, name, () => decryptResourceV4(resourceField.InitialValue, magic));
|
||||||
resourceField.InitialValue = new byte[1];
|
resourceField.InitialValue = new byte[1];
|
||||||
resourceField.FieldType = module.TypeSystem.Byte;
|
resourceField.FieldType = module.TypeSystem.Byte;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
@ -40,18 +40,18 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
|
|
||||||
interface IDecrypterInfo {
|
interface IDecrypterInfo {
|
||||||
DecrypterVersion Version { get; }
|
DecrypterVersion Version { get; }
|
||||||
MethodDefinition Method { get; }
|
MethodDef Method { get; }
|
||||||
string decrypt(object[] args);
|
string decrypt(object[] args);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static short[] findKey(MethodDefinition initMethod, FieldDefinition keyField) {
|
static short[] findKey(MethodDef initMethod, FieldDef keyField) {
|
||||||
var fields = new FieldDefinitionAndDeclaringTypeDict<bool>();
|
var fields = new FieldDefinitionAndDeclaringTypeDict<bool>();
|
||||||
fields.add(keyField, true);
|
fields.add(keyField, true);
|
||||||
return findKey(initMethod, fields);
|
return findKey(initMethod, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
static short[] findKey(MethodDefinition initMethod, FieldDefinitionAndDeclaringTypeDict<bool> fields) {
|
static short[] findKey(MethodDef initMethod, FieldDefinitionAndDeclaringTypeDict<bool> fields) {
|
||||||
var instrs = initMethod.Body.Instructions;
|
var instrs = initMethod.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||||
var ldci4 = instrs[i];
|
var ldci4 = instrs[i];
|
||||||
|
@ -84,7 +84,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FieldDefinition getStoreField(MethodDefinition method, int startIndex, VariableDefinition local) {
|
static FieldDef getStoreField(MethodDef method, int startIndex, VariableDefinition local) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldloc = instrs[i];
|
var ldloc = instrs[i];
|
||||||
|
@ -96,18 +96,18 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
var stsfld = instrs[i + 1];
|
var stsfld = instrs[i + 1];
|
||||||
if (stsfld.OpCode.Code != Code.Stsfld)
|
if (stsfld.OpCode.Code != Code.Stsfld)
|
||||||
continue;
|
continue;
|
||||||
return stsfld.Operand as FieldDefinition;
|
return stsfld.Operand as FieldDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findMagic(MethodDefinition method, out int magic) {
|
static bool findMagic(MethodDef method, out int magic) {
|
||||||
int arg1, arg2;
|
int arg1, arg2;
|
||||||
return findMagic(method, out arg1, out arg2, out magic);
|
return findMagic(method, out arg1, out arg2, out magic);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findMagic(MethodDefinition method, out int arg1, out int arg2, out int magic) {
|
static bool findMagic(MethodDef method, out int arg1, out int arg2, out int magic) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||||
if ((arg1 = DotNetUtils.getArgIndex(instrs[i])) < 0)
|
if ((arg1 = DotNetUtils.getArgIndex(instrs[i])) < 0)
|
||||||
|
@ -127,7 +127,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removeInitializeArrayCall(MethodDefinition method, FieldDefinition field) {
|
static void removeInitializeArrayCall(MethodDef method, FieldDef field) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldtoken = instrs[i];
|
var ldtoken = instrs[i];
|
||||||
|
@ -151,7 +151,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DecrypterInfo41 : IDecrypterInfo {
|
class DecrypterInfo41 : IDecrypterInfo {
|
||||||
MethodDefinition cctor;
|
MethodDef cctor;
|
||||||
int magic;
|
int magic;
|
||||||
int arg1, arg2;
|
int arg1, arg2;
|
||||||
FieldDefinitionAndDeclaringTypeDict<bool> fields;
|
FieldDefinitionAndDeclaringTypeDict<bool> fields;
|
||||||
|
@ -164,10 +164,10 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
class ArrayInfo {
|
class ArrayInfo {
|
||||||
public int sizeInElems;
|
public int sizeInElems;
|
||||||
public TypeReference elementType;
|
public TypeReference elementType;
|
||||||
public FieldDefinition initField;
|
public FieldDef initField;
|
||||||
public FieldDefinition field;
|
public FieldDef field;
|
||||||
|
|
||||||
public ArrayInfo(int sizeInElems, TypeReference elementType, FieldDefinition initField, FieldDefinition field) {
|
public ArrayInfo(int sizeInElems, TypeReference elementType, FieldDef initField, FieldDef field) {
|
||||||
this.sizeInElems = sizeInElems;
|
this.sizeInElems = sizeInElems;
|
||||||
this.elementType = elementType;
|
this.elementType = elementType;
|
||||||
this.initField = initField;
|
this.initField = initField;
|
||||||
|
@ -179,14 +179,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
get { return DecrypterVersion.V4_1; }
|
get { return DecrypterVersion.V4_1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method { get; private set; }
|
public MethodDef Method { get; private set; }
|
||||||
|
|
||||||
public DecrypterInfo41(MethodDefinition cctor, MethodDefinition method) {
|
public DecrypterInfo41(MethodDef cctor, MethodDef method) {
|
||||||
this.cctor = cctor;
|
this.cctor = cctor;
|
||||||
Method = method;
|
Method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool isPossibleDecrypterMethod(MethodDefinition method) {
|
public static bool isPossibleDecrypterMethod(MethodDef method) {
|
||||||
if (!checkMethodSignature(method))
|
if (!checkMethodSignature(method))
|
||||||
return false;
|
return false;
|
||||||
var fields = getFields(method);
|
var fields = getFields(method);
|
||||||
|
@ -196,7 +196,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkMethodSignature(MethodDefinition method) {
|
static bool checkMethodSignature(MethodDef method) {
|
||||||
if (method.MethodReturnType.ReturnType.EType != ElementType.String)
|
if (method.MethodReturnType.ReturnType.EType != ElementType.String)
|
||||||
return false;
|
return false;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -207,12 +207,12 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return count >= 2;
|
return count >= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FieldDefinitionAndDeclaringTypeDict<bool> getFields(MethodDefinition method) {
|
static FieldDefinitionAndDeclaringTypeDict<bool> getFields(MethodDef method) {
|
||||||
var fields = new FieldDefinitionAndDeclaringTypeDict<bool>();
|
var fields = new FieldDefinitionAndDeclaringTypeDict<bool>();
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Ldsfld && instr.OpCode.Code != Code.Stsfld)
|
if (instr.OpCode.Code != Code.Ldsfld && instr.OpCode.Code != Code.Stsfld)
|
||||||
continue;
|
continue;
|
||||||
var field = instr.Operand as FieldDefinition;
|
var field = instr.Operand as FieldDef;
|
||||||
if (field == null)
|
if (field == null)
|
||||||
continue;
|
continue;
|
||||||
if (field.DeclaringType != method.DeclaringType)
|
if (field.DeclaringType != method.DeclaringType)
|
||||||
|
@ -248,7 +248,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int findKeyShift(MethodDefinition method) {
|
int findKeyShift(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||||
int index = i;
|
int index = i;
|
||||||
|
@ -276,7 +276,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int findNextFieldUse(MethodDefinition method, int index) {
|
int findNextFieldUse(MethodDef method, int index) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = index; i < instrs.Count; i++) {
|
for (int i = index; i < instrs.Count; i++) {
|
||||||
var instr = instrs[i];
|
var instr = instrs[i];
|
||||||
|
@ -291,7 +291,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayInfo getArrayInfo(MethodDefinition method) {
|
ArrayInfo getArrayInfo(MethodDef method) {
|
||||||
var instructions = method.Body.Instructions;
|
var instructions = method.Body.Instructions;
|
||||||
for (int i = 0; i < instructions.Count; i++) {
|
for (int i = 0; i < instructions.Count; i++) {
|
||||||
var ldci4_arraySizeInBytes = instructions[i];
|
var ldci4_arraySizeInBytes = instructions[i];
|
||||||
|
@ -304,8 +304,8 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
|
|
||||||
int sizeInBytes = DotNetUtils.getLdcI4Value(ldci4_arraySizeInBytes);
|
int sizeInBytes = DotNetUtils.getLdcI4Value(ldci4_arraySizeInBytes);
|
||||||
var elementType = instrs[0].Operand as TypeReference;
|
var elementType = instrs[0].Operand as TypeReference;
|
||||||
var initField = instrs[2].Operand as FieldDefinition;
|
var initField = instrs[2].Operand as FieldDef;
|
||||||
var field = instrs[4].Operand as FieldDefinition;
|
var field = instrs[4].Operand as FieldDef;
|
||||||
if (elementType == null)
|
if (elementType == null)
|
||||||
continue;
|
continue;
|
||||||
if (initField == null || initField.InitialValue == null || initField.InitialValue.Length == 0)
|
if (initField == null || initField.InitialValue == null || initField.InitialValue.Length == 0)
|
||||||
|
@ -327,7 +327,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return findKey(cctor);
|
return findKey(cctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
short[] findKey(MethodDefinition initMethod) {
|
short[] findKey(MethodDef initMethod) {
|
||||||
return StringDecrypter.findKey(initMethod, fields);
|
return StringDecrypter.findKey(initMethod, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,27 +386,27 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DecrypterInfo40 : IDecrypterInfo {
|
class DecrypterInfo40 : IDecrypterInfo {
|
||||||
MethodDefinition cctor;
|
MethodDef cctor;
|
||||||
int magic;
|
int magic;
|
||||||
FieldDefinition cachedStringsField;
|
FieldDef cachedStringsField;
|
||||||
FieldDefinition keyField;
|
FieldDef keyField;
|
||||||
FieldDefinition encryptedStringsField;
|
FieldDef encryptedStringsField;
|
||||||
FieldDefinition encryptedDataField;
|
FieldDef encryptedDataField;
|
||||||
short[] key;
|
short[] key;
|
||||||
ushort[] encryptedData;
|
ushort[] encryptedData;
|
||||||
|
|
||||||
public MethodDefinition Method { get; private set; }
|
public MethodDef Method { get; private set; }
|
||||||
|
|
||||||
public DecrypterVersion Version {
|
public DecrypterVersion Version {
|
||||||
get { return DecrypterVersion.V4_0; }
|
get { return DecrypterVersion.V4_0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public DecrypterInfo40(MethodDefinition cctor, MethodDefinition method) {
|
public DecrypterInfo40(MethodDef cctor, MethodDef method) {
|
||||||
this.cctor = cctor;
|
this.cctor = cctor;
|
||||||
this.Method = method;
|
this.Method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool isPossibleDecrypterMethod(MethodDefinition method) {
|
public static bool isPossibleDecrypterMethod(MethodDef method) {
|
||||||
if (!checkFields(method.DeclaringType.Fields))
|
if (!checkFields(method.DeclaringType.Fields))
|
||||||
return false;
|
return false;
|
||||||
return DotNetUtils.isMethod(method, "System.String", "(System.Int32,System.Int32)");
|
return DotNetUtils.isMethod(method, "System.String", "(System.Int32,System.Int32)");
|
||||||
|
@ -438,13 +438,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FieldDefinition> findFields() {
|
List<FieldDef> findFields() {
|
||||||
var charArrayFields = new List<FieldDefinition>();
|
var charArrayFields = new List<FieldDef>();
|
||||||
|
|
||||||
foreach (var instr in Method.Body.Instructions) {
|
foreach (var instr in Method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Stsfld && instr.OpCode.Code != Code.Ldsfld)
|
if (instr.OpCode.Code != Code.Stsfld && instr.OpCode.Code != Code.Ldsfld)
|
||||||
continue;
|
continue;
|
||||||
var field = instr.Operand as FieldDefinition;
|
var field = instr.Operand as FieldDef;
|
||||||
if (field == null)
|
if (field == null)
|
||||||
continue;
|
continue;
|
||||||
if (!MemberReferenceHelper.compareTypes(Method.DeclaringType, field.DeclaringType))
|
if (!MemberReferenceHelper.compareTypes(Method.DeclaringType, field.DeclaringType))
|
||||||
|
@ -472,17 +472,17 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return charArrayFields;
|
return charArrayFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FieldDefinition findEncryptedStrings(MethodDefinition initMethod, List<FieldDefinition> ourFields, out FieldDefinition dataField) {
|
static FieldDef findEncryptedStrings(MethodDef initMethod, List<FieldDef> ourFields, out FieldDef dataField) {
|
||||||
for (int i = 0; i < initMethod.Body.Instructions.Count; i++) {
|
for (int i = 0; i < initMethod.Body.Instructions.Count; i++) {
|
||||||
var instrs = DotNetUtils.getInstructions(initMethod.Body.Instructions, i, OpCodes.Ldtoken, OpCodes.Call, OpCodes.Stsfld);
|
var instrs = DotNetUtils.getInstructions(initMethod.Body.Instructions, i, OpCodes.Ldtoken, OpCodes.Call, OpCodes.Stsfld);
|
||||||
if (instrs == null)
|
if (instrs == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dataField = instrs[0].Operand as FieldDefinition;
|
dataField = instrs[0].Operand as FieldDef;
|
||||||
if (dataField == null || dataField.InitialValue == null || dataField.InitialValue.Length == 0)
|
if (dataField == null || dataField.InitialValue == null || dataField.InitialValue.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var savedField = instrs[2].Operand as FieldDefinition;
|
var savedField = instrs[2].Operand as FieldDef;
|
||||||
if (savedField == null || !matches(ourFields, savedField))
|
if (savedField == null || !matches(ourFields, savedField))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool matches(IEnumerable<FieldDefinition> ourFields, FieldReference field) {
|
static bool matches(IEnumerable<FieldDef> ourFields, FieldReference field) {
|
||||||
foreach (var ourField in ourFields) {
|
foreach (var ourField in ourFields) {
|
||||||
if (MemberReferenceHelper.compareFieldReferenceAndDeclaringType(ourField, field))
|
if (MemberReferenceHelper.compareFieldReferenceAndDeclaringType(ourField, field))
|
||||||
return true;
|
return true;
|
||||||
|
@ -510,7 +510,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return findKey(cctor);
|
return findKey(cctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
short[] findKey(MethodDefinition initMethod) {
|
short[] findKey(MethodDef initMethod) {
|
||||||
return StringDecrypter.findKey(initMethod, keyField);
|
return StringDecrypter.findKey(initMethod, keyField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,26 +545,26 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DecrypterInfo13 : IDecrypterInfo {
|
class DecrypterInfo13 : IDecrypterInfo {
|
||||||
MethodDefinition cctor;
|
MethodDef cctor;
|
||||||
FieldDefinition cachedStringsField;
|
FieldDef cachedStringsField;
|
||||||
FieldDefinition keyField;
|
FieldDef keyField;
|
||||||
int magic;
|
int magic;
|
||||||
string[] encryptedStrings;
|
string[] encryptedStrings;
|
||||||
short[] key;
|
short[] key;
|
||||||
|
|
||||||
public MethodDefinition Method { get; private set; }
|
public MethodDef Method { get; private set; }
|
||||||
|
|
||||||
public DecrypterVersion Version {
|
public DecrypterVersion Version {
|
||||||
get { return DecrypterVersion.V1_3; }
|
get { return DecrypterVersion.V1_3; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool isPossibleDecrypterMethod(MethodDefinition method) {
|
public static bool isPossibleDecrypterMethod(MethodDef method) {
|
||||||
if (!checkFields(method.DeclaringType.Fields))
|
if (!checkFields(method.DeclaringType.Fields))
|
||||||
return false;
|
return false;
|
||||||
return DotNetUtils.isMethod(method, "System.String", "(System.Int32)");
|
return DotNetUtils.isMethod(method, "System.String", "(System.Int32)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public DecrypterInfo13(MethodDefinition cctor, MethodDefinition method) {
|
public DecrypterInfo13(MethodDef cctor, MethodDef method) {
|
||||||
this.cctor = cctor;
|
this.cctor = cctor;
|
||||||
this.Method = method;
|
this.Method = method;
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
foreach (var instr in Method.Body.Instructions) {
|
foreach (var instr in Method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Stsfld && instr.OpCode.Code != Code.Ldsfld)
|
if (instr.OpCode.Code != Code.Stsfld && instr.OpCode.Code != Code.Ldsfld)
|
||||||
continue;
|
continue;
|
||||||
var field = instr.Operand as FieldDefinition;
|
var field = instr.Operand as FieldDef;
|
||||||
if (field == null)
|
if (field == null)
|
||||||
continue;
|
continue;
|
||||||
if (!MemberReferenceHelper.compareTypes(Method.DeclaringType, field.DeclaringType))
|
if (!MemberReferenceHelper.compareTypes(Method.DeclaringType, field.DeclaringType))
|
||||||
|
@ -637,7 +637,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return findKey(cctor);
|
return findKey(cctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
short[] findKey(MethodDefinition initMethod) {
|
short[] findKey(MethodDef initMethod) {
|
||||||
return StringDecrypter.findKey(initMethod, keyField);
|
return StringDecrypter.findKey(initMethod, keyField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findMagic(MethodDefinition method, out int magic) {
|
static bool findMagic(MethodDef method, out int magic) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||||
var ldarg = instrs[i];
|
var ldarg = instrs[i];
|
||||||
|
@ -668,7 +668,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findEncryptedStrings(MethodDefinition method) {
|
bool findEncryptedStrings(MethodDef method) {
|
||||||
var switchInstr = getOnlySwitchInstruction(method);
|
var switchInstr = getOnlySwitchInstruction(method);
|
||||||
if (switchInstr == null)
|
if (switchInstr == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -683,7 +683,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Instruction getOnlySwitchInstruction(MethodDefinition method) {
|
static Instruction getOnlySwitchInstruction(MethodDef method) {
|
||||||
Instruction switchInstr = null;
|
Instruction switchInstr = null;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Switch)
|
if (instr.OpCode.Code != Code.Switch)
|
||||||
|
@ -711,9 +711,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
get { return version; }
|
get { return version; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MethodDefinition> DecrypterMethods {
|
public List<MethodDef> DecrypterMethods {
|
||||||
get {
|
get {
|
||||||
var methods = new List<MethodDefinition>(methodToInfo.Count);
|
var methods = new List<MethodDef>(methodToInfo.Count);
|
||||||
foreach (var info in methodToInfo.getValues())
|
foreach (var info in methodToInfo.getValues())
|
||||||
methods.Add(info.Method);
|
methods.Add(info.Method);
|
||||||
return methods;
|
return methods;
|
||||||
|
@ -765,14 +765,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deobfuscateCctor(ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition cctor, ref bool deobfuscatedCctor, bool hasPublicKeyToken) {
|
static void deobfuscateCctor(ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor, ref bool deobfuscatedCctor, bool hasPublicKeyToken) {
|
||||||
if (deobfuscatedCctor || hasPublicKeyToken)
|
if (deobfuscatedCctor || hasPublicKeyToken)
|
||||||
return;
|
return;
|
||||||
simpleDeobfuscator.deobfuscate(cctor);
|
simpleDeobfuscator.deobfuscate(cctor);
|
||||||
deobfuscatedCctor = true;
|
deobfuscatedCctor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkFields(IEnumerable<FieldDefinition> fields) {
|
static bool checkFields(IEnumerable<FieldDef> fields) {
|
||||||
bool foundCharAry = false, foundStringAry = false;
|
bool foundCharAry = false, foundStringAry = false;
|
||||||
foreach (var field in fields) {
|
foreach (var field in fields) {
|
||||||
if (foundCharAry && foundStringAry)
|
if (foundCharAry && foundStringAry)
|
||||||
|
@ -789,21 +789,21 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
return foundCharAry && foundStringAry;
|
return foundCharAry && foundStringAry;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecrypterInfo13 getInfoV13(MethodDefinition cctor, MethodDefinition method) {
|
DecrypterInfo13 getInfoV13(MethodDef cctor, MethodDef method) {
|
||||||
var info = new DecrypterInfo13(cctor, method);
|
var info = new DecrypterInfo13(cctor, method);
|
||||||
if (!info.initialize())
|
if (!info.initialize())
|
||||||
return null;
|
return null;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecrypterInfo40 getInfoV40(MethodDefinition cctor, MethodDefinition method) {
|
DecrypterInfo40 getInfoV40(MethodDef cctor, MethodDef method) {
|
||||||
var info = new DecrypterInfo40(cctor, method);
|
var info = new DecrypterInfo40(cctor, method);
|
||||||
if (!info.initialize())
|
if (!info.initialize())
|
||||||
return null;
|
return null;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecrypterInfo41 getInfoV41(MethodDefinition cctor, MethodDefinition method) {
|
DecrypterInfo41 getInfoV41(MethodDef cctor, MethodDef method) {
|
||||||
var info = new DecrypterInfo41(cctor, method);
|
var info = new DecrypterInfo41(cctor, method);
|
||||||
if (!info.initialize())
|
if (!info.initialize())
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Dotfuscator {
|
namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
|
@ -101,7 +101,7 @@ namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeVersion(TypeDefinition attr) {
|
void initializeVersion(TypeDef attr) {
|
||||||
var s = DotNetUtils.getCustomArgAsString(getAssemblyAttribute(attr), 0);
|
var s = DotNetUtils.getCustomArgAsString(getAssemblyAttribute(attr), 0);
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return;
|
return;
|
||||||
|
@ -129,7 +129,7 @@ namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
foreach (var method in stringDecrypter.StringDecrypters)
|
foreach (var method in stringDecrypter.StringDecrypters)
|
||||||
list.Add(method.MetadataToken.ToInt32());
|
list.Add(method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Dotfuscator {
|
namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
|
@ -28,9 +28,9 @@ namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
Dictionary<MethodReference, StringDecrypterInfo> stringDecrypterMethods = new Dictionary<MethodReference, StringDecrypterInfo>();
|
Dictionary<MethodReference, StringDecrypterInfo> stringDecrypterMethods = new Dictionary<MethodReference, StringDecrypterInfo>();
|
||||||
|
|
||||||
public class StringDecrypterInfo {
|
public class StringDecrypterInfo {
|
||||||
public MethodDefinition method;
|
public MethodDef method;
|
||||||
public int magic;
|
public int magic;
|
||||||
public StringDecrypterInfo(MethodDefinition method, int magic) {
|
public StringDecrypterInfo(MethodDef method, int magic) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.magic = magic;
|
this.magic = magic;
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,9 @@ namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
get { return stringDecrypterMethods.Count > 0; }
|
get { return stringDecrypterMethods.Count > 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<MethodDefinition> StringDecrypters {
|
public IEnumerable<MethodDef> StringDecrypters {
|
||||||
get {
|
get {
|
||||||
var list = new List<MethodDefinition>(stringDecrypterMethods.Count);
|
var list = new List<MethodDef>(stringDecrypterMethods.Count);
|
||||||
foreach (var info in stringDecrypterMethods)
|
foreach (var info in stringDecrypterMethods)
|
||||||
list.Add(info.Value.method);
|
list.Add(info.Value.method);
|
||||||
return list;
|
return list;
|
||||||
|
@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
findStringDecrypterMethods(type, simpleDeobfuscator);
|
findStringDecrypterMethods(type, simpleDeobfuscator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void findStringDecrypterMethods(TypeDefinition type, ISimpleDeobfuscator simpleDeobfuscator) {
|
void findStringDecrypterMethods(TypeDef type, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
foreach (var method in DotNetUtils.findMethods(type.Methods, "System.String", new string[] { "System.String", "System.Int32" })) {
|
foreach (var method in DotNetUtils.findMethods(type.Methods, "System.String", new string[] { "System.String", "System.Int32" })) {
|
||||||
if (method.Body.HasExceptionHandlers)
|
if (method.Body.HasExceptionHandlers)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -22,19 +22,19 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
class AssemblyResolver {
|
class AssemblyResolver {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
DecrypterType decrypterType;
|
DecrypterType decrypterType;
|
||||||
TypeDefinition resolverType;
|
TypeDef resolverType;
|
||||||
MethodDefinition initMethod;
|
MethodDef initMethod;
|
||||||
MethodDefinition handlerMethod;
|
MethodDef handlerMethod;
|
||||||
MethodDefinition decryptMethod;
|
MethodDef decryptMethod;
|
||||||
TypeDefinition otherType;
|
TypeDef otherType;
|
||||||
List<AssemblyInfo> assemblyInfos = new List<AssemblyInfo>();
|
List<AssemblyInfo> assemblyInfos = new List<AssemblyInfo>();
|
||||||
FrameworkType frameworkType;
|
FrameworkType frameworkType;
|
||||||
byte[] decryptKey;
|
byte[] decryptKey;
|
||||||
|
@ -56,15 +56,15 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return resolverType; }
|
get { return resolverType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition OtherType {
|
public TypeDef OtherType {
|
||||||
get { return otherType; }
|
get { return otherType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitMethod {
|
public MethodDef InitMethod {
|
||||||
get { return initMethod; }
|
get { return initMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
checkCalledMethods(DotNetUtils.getModuleTypeCctor(module));
|
checkCalledMethods(DotNetUtils.getModuleTypeCctor(module));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkCalledMethods(MethodDefinition method) {
|
bool checkCalledMethods(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.Body == null)
|
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.Body == null)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
|
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
|
||||||
|
@ -119,7 +119,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkInitMethodSilverlight(MethodDefinition method) {
|
bool checkInitMethodSilverlight(MethodDef method) {
|
||||||
var type = method.DeclaringType;
|
var type = method.DeclaringType;
|
||||||
if (type.NestedTypes.Count != 2)
|
if (type.NestedTypes.Count != 2)
|
||||||
return false;
|
return false;
|
||||||
|
@ -134,11 +134,11 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition getResolveMethodSilverlight(MethodDefinition initMethod) {
|
static MethodDef getResolveMethodSilverlight(MethodDef initMethod) {
|
||||||
foreach (var instr in initMethod.Body.Instructions) {
|
foreach (var instr in initMethod.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
|
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
|
||||||
|
@ -153,7 +153,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkInitMethod(MethodDefinition method) {
|
bool checkInitMethod(MethodDef method) {
|
||||||
var type = method.DeclaringType;
|
var type = method.DeclaringType;
|
||||||
if (type.NestedTypes.Count < 2 || type.NestedTypes.Count > 6)
|
if (type.NestedTypes.Count < 2 || type.NestedTypes.Count > 6)
|
||||||
return false;
|
return false;
|
||||||
|
@ -173,7 +173,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition getDecryptMethod() {
|
MethodDef getDecryptMethod() {
|
||||||
foreach (var method in resolverType.Methods) {
|
foreach (var method in resolverType.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -198,14 +198,14 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
throw new ApplicationException("Could not initialize decrypterType");
|
throw new ApplicationException("Could not initialize decrypterType");
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinition getDecrypterType(MethodDefinition method) {
|
TypeDef getDecrypterType(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.DeclaringType == resolverType)
|
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.DeclaringType == resolverType)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "(System.Byte[])"))
|
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "(System.Byte[])"))
|
||||||
|
@ -467,8 +467,8 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition getTheOnlyMethod(TypeDefinition type, string typeName, string methodName, string returnType, string parameters) {
|
static MethodDef getTheOnlyMethod(TypeDef type, string typeName, string methodName, string returnType, string parameters) {
|
||||||
MethodDefinition foundMethod = null;
|
MethodDef foundMethod = null;
|
||||||
|
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null || method.HasGenericParameters)
|
if (!method.IsStatic || method.Body == null || method.HasGenericParameters)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
class CodeCompilerMethodCallRestorer : MethodCallRestorerBase {
|
class CodeCompilerMethodCallRestorer : MethodCallRestorerBase {
|
||||||
|
@ -63,55 +63,55 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
: base(module) {
|
: base(module) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_CodeDomProvider_CompileAssemblyFromDom(MethodDefinition oldMethod) {
|
public void add_CodeDomProvider_CompileAssemblyFromDom(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromDom", CodeDomProvider, CompilerResults, CompilerParameters, CodeCompileUnitArray));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromDom", CodeDomProvider, CompilerResults, CompilerParameters, CodeCompileUnitArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_CodeDomProvider_CompileAssemblyFromFile(MethodDefinition oldMethod) {
|
public void add_CodeDomProvider_CompileAssemblyFromFile(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromFile", CodeDomProvider, CompilerResults, CompilerParameters, StringArray));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromFile", CodeDomProvider, CompilerResults, CompilerParameters, StringArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_CodeDomProvider_CompileAssemblyFromSource(MethodDefinition oldMethod) {
|
public void add_CodeDomProvider_CompileAssemblyFromSource(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromSource", CodeDomProvider, CompilerResults, CompilerParameters, StringArray));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromSource", CodeDomProvider, CompilerResults, CompilerParameters, StringArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_ICodeCompiler_CompileAssemblyFromDom(MethodDefinition oldMethod) {
|
public void add_ICodeCompiler_CompileAssemblyFromDom(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromDom", ICodeCompiler, CompilerResults, CompilerParameters, CodeCompileUnit));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromDom", ICodeCompiler, CompilerResults, CompilerParameters, CodeCompileUnit));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_ICodeCompiler_CompileAssemblyFromDomBatch(MethodDefinition oldMethod) {
|
public void add_ICodeCompiler_CompileAssemblyFromDomBatch(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromDomBatch", ICodeCompiler, CompilerResults, CompilerParameters, CodeCompileUnitArray));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromDomBatch", ICodeCompiler, CompilerResults, CompilerParameters, CodeCompileUnitArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_ICodeCompiler_CompileAssemblyFromFile(MethodDefinition oldMethod) {
|
public void add_ICodeCompiler_CompileAssemblyFromFile(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromFile", ICodeCompiler, CompilerResults, CompilerParameters, builder.String));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromFile", ICodeCompiler, CompilerResults, CompilerParameters, builder.String));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_ICodeCompiler_CompileAssemblyFromFileBatch(MethodDefinition oldMethod) {
|
public void add_ICodeCompiler_CompileAssemblyFromFileBatch(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromFileBatch", ICodeCompiler, CompilerResults, CompilerParameters, StringArray));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromFileBatch", ICodeCompiler, CompilerResults, CompilerParameters, StringArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_ICodeCompiler_CompileAssemblyFromSource(MethodDefinition oldMethod) {
|
public void add_ICodeCompiler_CompileAssemblyFromSource(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromSource", ICodeCompiler, CompilerResults, CompilerParameters, builder.String));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromSource", ICodeCompiler, CompilerResults, CompilerParameters, builder.String));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_ICodeCompiler_CompileAssemblyFromSourceBatch(MethodDefinition oldMethod) {
|
public void add_ICodeCompiler_CompileAssemblyFromSourceBatch(MethodDef oldMethod) {
|
||||||
if (oldMethod == null)
|
if (oldMethod == null)
|
||||||
return;
|
return;
|
||||||
add(oldMethod, builder.instanceMethod("CompileAssemblyFromSourceBatch", ICodeCompiler, CompilerResults, CompilerParameters, StringArray));
|
add(oldMethod, builder.instanceMethod("CompileAssemblyFromSourceBatch", ICodeCompiler, CompilerResults, CompilerParameters, StringArray));
|
||||||
|
|
|
@ -20,23 +20,23 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
class DecrypterType {
|
class DecrypterType {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
TypeDefinition type;
|
TypeDef type;
|
||||||
MethodDefinition int64Method;
|
MethodDef int64Method;
|
||||||
bool initialized;
|
bool initialized;
|
||||||
ulong l1;
|
ulong l1;
|
||||||
int i1, i2, i3;
|
int i1, i2, i3;
|
||||||
int m1_i1, m2_i1, m2_i2, m3_i1;
|
int m1_i1, m2_i1, m2_i2, m3_i1;
|
||||||
MethodDefinition[] efConstMethods;
|
MethodDef[] efConstMethods;
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return type; }
|
get { return type; }
|
||||||
set {
|
set {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
|
@ -80,7 +80,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
efConstMethods = new MethodDefinition[6];
|
efConstMethods = new MethodDef[6];
|
||||||
|
|
||||||
efConstMethods[0] = findEfConstMethodCall(int64Method);
|
efConstMethods[0] = findEfConstMethodCall(int64Method);
|
||||||
efConstMethods[5] = findEfConstMethodCall(efConstMethods[0]);
|
efConstMethods[5] = findEfConstMethodCall(efConstMethods[0]);
|
||||||
|
@ -105,7 +105,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getNumberOfTypeofs(MethodDefinition method) {
|
static int getNumberOfTypeofs(MethodDef method) {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return 0;
|
return 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -116,21 +116,21 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition findEfConstMethodCall(MethodDefinition method) {
|
MethodDef findEfConstMethodCall(MethodDef method) {
|
||||||
var list = findEfConstMethodCalls(method);
|
var list = findEfConstMethodCalls(method);
|
||||||
if (list == null || list.Count != 1)
|
if (list == null || list.Count != 1)
|
||||||
return null;
|
return null;
|
||||||
return list[0];
|
return list[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MethodDefinition> findEfConstMethodCalls(MethodDefinition method) {
|
List<MethodDef> findEfConstMethodCalls(MethodDef method) {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return null;
|
return null;
|
||||||
var list = new List<MethodDefinition>();
|
var list = new List<MethodDef>();
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.Body == null)
|
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.Body == null)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(calledMethod, "System.Int32", "()"))
|
if (!DotNetUtils.isMethod(calledMethod, "System.Int32", "()"))
|
||||||
|
@ -143,7 +143,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition findInt64Method() {
|
MethodDef findInt64Method() {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return null;
|
return null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
|
@ -160,7 +160,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findInt64(MethodDefinition method) {
|
bool findInt64(MethodDef method) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldci8 = instrs[i];
|
var ldci8 = instrs[i];
|
||||||
|
@ -212,8 +212,8 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<MethodDefinition> getBinaryIntMethods(TypeDefinition type) {
|
static List<MethodDef> getBinaryIntMethods(TypeDef type) {
|
||||||
var list = new List<MethodDefinition>();
|
var list = new List<MethodDef>();
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -225,7 +225,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findMethod1Int(IEnumerable<MethodDefinition> methods) {
|
bool findMethod1Int(IEnumerable<MethodDef> methods) {
|
||||||
foreach (var method in methods) {
|
foreach (var method in methods) {
|
||||||
if (countInstructions(method, Code.Ldarg_0) != 1)
|
if (countInstructions(method, Code.Ldarg_0) != 1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -239,7 +239,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findMethod2Int(IEnumerable<MethodDefinition> methods) {
|
bool findMethod2Int(IEnumerable<MethodDef> methods) {
|
||||||
foreach (var method in methods) {
|
foreach (var method in methods) {
|
||||||
var constants = getConstants(method);
|
var constants = getConstants(method);
|
||||||
if (constants.Count != 2)
|
if (constants.Count != 2)
|
||||||
|
@ -252,7 +252,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findMethod3Int(IEnumerable<MethodDefinition> methods) {
|
bool findMethod3Int(IEnumerable<MethodDef> methods) {
|
||||||
foreach (var method in methods) {
|
foreach (var method in methods) {
|
||||||
if (countInstructions(method, Code.Ldarg_0) != 2)
|
if (countInstructions(method, Code.Ldarg_0) != 2)
|
||||||
continue;
|
continue;
|
||||||
|
@ -266,7 +266,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int countInstructions(MethodDefinition method, Code code) {
|
static int countInstructions(MethodDef method, Code code) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code == code)
|
if (instr.OpCode.Code == code)
|
||||||
|
@ -275,7 +275,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<int> getConstants(MethodDefinition method) {
|
static List<int> getConstants(MethodDef method) {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
|
|
||||||
if (method == null)
|
if (method == null)
|
||||||
|
@ -309,27 +309,27 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
int constMethod1() {
|
int constMethod1() {
|
||||||
return binOp3(binOp2(efConstMethods[1].DeclaringType.MetadataToken.ToInt32(), binOp3(efConstMethods[0].DeclaringType.MetadataToken.ToInt32(), efConstMethods[4].DeclaringType.MetadataToken.ToInt32())), constMethod6());
|
return binOp3(binOp2(efConstMethods[1].DeclaringType.MDToken.ToInt32(), binOp3(efConstMethods[0].DeclaringType.MDToken.ToInt32(), efConstMethods[4].DeclaringType.MDToken.ToInt32())), constMethod6());
|
||||||
}
|
}
|
||||||
|
|
||||||
int constMethod2() {
|
int constMethod2() {
|
||||||
return binOp1(efConstMethods[2].DeclaringType.MetadataToken.ToInt32(), efConstMethods[3].DeclaringType.MetadataToken.ToInt32() ^ binOp2(efConstMethods[1].DeclaringType.MetadataToken.ToInt32(), binOp3(efConstMethods[5].DeclaringType.MetadataToken.ToInt32(), constMethod4())));
|
return binOp1(efConstMethods[2].DeclaringType.MDToken.ToInt32(), efConstMethods[3].DeclaringType.MDToken.ToInt32() ^ binOp2(efConstMethods[1].DeclaringType.MDToken.ToInt32(), binOp3(efConstMethods[5].DeclaringType.MDToken.ToInt32(), constMethod4())));
|
||||||
}
|
}
|
||||||
|
|
||||||
int constMethod3() {
|
int constMethod3() {
|
||||||
return binOp3(binOp1(constMethod2() ^ i1, efConstMethods[3].DeclaringType.MetadataToken.ToInt32()), binOp2(efConstMethods[0].DeclaringType.MetadataToken.ToInt32() ^ efConstMethods[5].DeclaringType.MetadataToken.ToInt32(), i2));
|
return binOp3(binOp1(constMethod2() ^ i1, efConstMethods[3].DeclaringType.MDToken.ToInt32()), binOp2(efConstMethods[0].DeclaringType.MDToken.ToInt32() ^ efConstMethods[5].DeclaringType.MDToken.ToInt32(), i2));
|
||||||
}
|
}
|
||||||
|
|
||||||
int constMethod4() {
|
int constMethod4() {
|
||||||
return binOp3(efConstMethods[3].DeclaringType.MetadataToken.ToInt32(), binOp1(efConstMethods[0].DeclaringType.MetadataToken.ToInt32(), binOp2(efConstMethods[1].DeclaringType.MetadataToken.ToInt32(), binOp3(efConstMethods[2].DeclaringType.MetadataToken.ToInt32(), binOp1(efConstMethods[4].DeclaringType.MetadataToken.ToInt32(), efConstMethods[5].DeclaringType.MetadataToken.ToInt32())))));
|
return binOp3(efConstMethods[3].DeclaringType.MDToken.ToInt32(), binOp1(efConstMethods[0].DeclaringType.MDToken.ToInt32(), binOp2(efConstMethods[1].DeclaringType.MDToken.ToInt32(), binOp3(efConstMethods[2].DeclaringType.MDToken.ToInt32(), binOp1(efConstMethods[4].DeclaringType.MDToken.ToInt32(), efConstMethods[5].DeclaringType.MDToken.ToInt32())))));
|
||||||
}
|
}
|
||||||
|
|
||||||
int constMethod5() {
|
int constMethod5() {
|
||||||
return binOp2(binOp2(constMethod3(), binOp1(efConstMethods[4].DeclaringType.MetadataToken.ToInt32(), constMethod2())), efConstMethods[5].DeclaringType.MetadataToken.ToInt32());
|
return binOp2(binOp2(constMethod3(), binOp1(efConstMethods[4].DeclaringType.MDToken.ToInt32(), constMethod2())), efConstMethods[5].DeclaringType.MDToken.ToInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
int constMethod6() {
|
int constMethod6() {
|
||||||
return binOp1(efConstMethods[5].DeclaringType.MetadataToken.ToInt32(), binOp3(binOp2(efConstMethods[4].DeclaringType.MetadataToken.ToInt32(), efConstMethods[0].DeclaringType.MetadataToken.ToInt32()), binOp3(efConstMethods[2].DeclaringType.MetadataToken.ToInt32() ^ i3, constMethod5())));
|
return binOp1(efConstMethods[5].DeclaringType.MDToken.ToInt32(), binOp3(binOp2(efConstMethods[4].DeclaringType.MDToken.ToInt32(), efConstMethods[0].DeclaringType.MDToken.ToInt32()), binOp3(efConstMethods[2].DeclaringType.MDToken.ToInt32() ^ i3, constMethod5())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong getMagic() {
|
public ulong getMagic() {
|
||||||
|
@ -343,13 +343,13 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
bytes.AddRange(Encoding.Unicode.GetBytes(module.Assembly.Name.Name));
|
bytes.AddRange(Encoding.Unicode.GetBytes(module.Assembly.Name.Name));
|
||||||
}
|
}
|
||||||
int cm1 = constMethod1();
|
int cm1 = constMethod1();
|
||||||
bytes.Add((byte)(type.MetadataToken.ToInt32() >> 24));
|
bytes.Add((byte)(type.MDToken.ToInt32() >> 24));
|
||||||
bytes.Add((byte)(cm1 >> 16));
|
bytes.Add((byte)(cm1 >> 16));
|
||||||
bytes.Add((byte)(type.MetadataToken.ToInt32() >> 8));
|
bytes.Add((byte)(type.MDToken.ToInt32() >> 8));
|
||||||
bytes.Add((byte)cm1);
|
bytes.Add((byte)cm1);
|
||||||
bytes.Add((byte)(type.MetadataToken.ToInt32() >> 16));
|
bytes.Add((byte)(type.MDToken.ToInt32() >> 16));
|
||||||
bytes.Add((byte)(cm1 >> 8));
|
bytes.Add((byte)(cm1 >> 8));
|
||||||
bytes.Add((byte)type.MetadataToken.ToInt32());
|
bytes.Add((byte)type.MDToken.ToInt32());
|
||||||
bytes.Add((byte)(cm1 >> 24));
|
bytes.Add((byte)(cm1 >> 24));
|
||||||
|
|
||||||
ulong magic = 0;
|
ulong magic = 0;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
|
@ -167,7 +167,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
if (stringDecrypter.Method != null)
|
if (stringDecrypter.Method != null)
|
||||||
list.Add(stringDecrypter.Method.MetadataToken.ToInt32());
|
list.Add(stringDecrypter.Method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
class EfConstantsReader : ConstantsReader {
|
class EfConstantsReader : ConstantsReader {
|
||||||
public EfConstantsReader(MethodDefinition method)
|
public EfConstantsReader(MethodDef method)
|
||||||
: base(method) {
|
: base(method) {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
static class EfUtils {
|
static class EfUtils {
|
||||||
public static int findOpCodeIndex(MethodDefinition method, int index, Code code) {
|
public static int findOpCodeIndex(MethodDef method, int index, Code code) {
|
||||||
for (; index < method.Body.Instructions.Count; index++) {
|
for (; index < method.Body.Instructions.Count; index++) {
|
||||||
var instr = method.Body.Instructions[index];
|
var instr = method.Body.Instructions[index];
|
||||||
if (instr.OpCode.Code != code)
|
if (instr.OpCode.Code != code)
|
||||||
|
@ -35,7 +35,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int findOpCodeIndex(MethodDefinition method, int index, Code code, string operandString) {
|
public static int findOpCodeIndex(MethodDef method, int index, Code code, string operandString) {
|
||||||
while (index < method.Body.Instructions.Count) {
|
while (index < method.Body.Instructions.Count) {
|
||||||
index = findOpCodeIndex(method, index, code);
|
index = findOpCodeIndex(method, index, code);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
|
@ -49,7 +49,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Instruction getNextStore(MethodDefinition method, ref int index) {
|
public static Instruction getNextStore(MethodDef method, ref int index) {
|
||||||
for (; index < method.Body.Instructions.Count; index++) {
|
for (; index < method.Body.Instructions.Count; index++) {
|
||||||
var instr = method.Body.Instructions[index];
|
var instr = method.Body.Instructions[index];
|
||||||
|
|
||||||
|
|
|
@ -17,15 +17,15 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
class ResourceMethodsRestorer : MethodCallRestorerBase {
|
class ResourceMethodsRestorer : MethodCallRestorerBase {
|
||||||
TypeDefinition getManifestResourceStreamType;
|
TypeDef getManifestResourceStreamType;
|
||||||
EmbeddedResource getManifestResourceStreamTypeResource;
|
EmbeddedResource getManifestResourceStreamTypeResource;
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return getManifestResourceStreamType; }
|
get { return getManifestResourceStreamType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbeddedResource findGetManifestResourceStreamTypeResource(TypeDefinition type, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
|
EmbeddedResource findGetManifestResourceStreamTypeResource(TypeDef type, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsPrivate || !method.IsStatic || method.Body == null)
|
if (!method.IsPrivate || !method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -86,8 +86,8 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition getTheOnlyMethod(TypeDefinition type, string returnType, string parameters) {
|
static MethodDef getTheOnlyMethod(TypeDef type, string returnType, string parameters) {
|
||||||
MethodDefinition foundMethod = null;
|
MethodDef foundMethod = null;
|
||||||
|
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null || method.HasGenericParameters)
|
if (!method.IsStatic || method.Body == null || method.HasGenericParameters)
|
||||||
|
|
|
@ -20,24 +20,24 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
class ResourceResolver {
|
class ResourceResolver {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
AssemblyResolver assemblyResolver;
|
AssemblyResolver assemblyResolver;
|
||||||
TypeDefinition resolverType;
|
TypeDef resolverType;
|
||||||
MethodDefinition initMethod;
|
MethodDef initMethod;
|
||||||
MethodDefinition handlerMethod;
|
MethodDef handlerMethod;
|
||||||
List<string> resourceInfos = new List<string>();
|
List<string> resourceInfos = new List<string>();
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return resolverType; }
|
get { return resolverType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition InitMethod {
|
public MethodDef InitMethod {
|
||||||
get { return initMethod; }
|
get { return initMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,14 +56,14 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
checkCalledMethods(DotNetUtils.getModuleTypeCctor(module));
|
checkCalledMethods(DotNetUtils.getModuleTypeCctor(module));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkCalledMethods(MethodDefinition method) {
|
bool checkCalledMethods(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
if (!checkInitMethod(instr.Operand as MethodDefinition))
|
if (!checkInitMethod(instr.Operand as MethodDef))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -72,7 +72,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkInitMethod(MethodDefinition method) {
|
bool checkInitMethod(MethodDef method) {
|
||||||
if (method == null || !method.IsStatic || method.Body == null)
|
if (method == null || !method.IsStatic || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
if (!DotNetUtils.isMethod(method, "System.Void", "()"))
|
if (!DotNetUtils.isMethod(method, "System.Void", "()"))
|
||||||
|
@ -121,7 +121,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeInfos(MethodDefinition method) {
|
bool initializeInfos(MethodDef method) {
|
||||||
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
||||||
if (string.IsNullOrEmpty(s))
|
if (string.IsNullOrEmpty(s))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -21,17 +21,17 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
class StringDecrypter {
|
class StringDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition stringType;
|
TypeDef stringType;
|
||||||
MethodDefinition stringMethod;
|
MethodDef stringMethod;
|
||||||
TypeDefinition dataDecrypterType;
|
TypeDef dataDecrypterType;
|
||||||
short s1, s2, s3;
|
short s1, s2, s3;
|
||||||
int i1, i2, i3, i4, i5, i6;
|
int i1, i2, i3, i4, i5, i6;
|
||||||
bool checkMinus2;
|
bool checkMinus2;
|
||||||
|
@ -48,10 +48,10 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
bool isV32OrLater;
|
bool isV32OrLater;
|
||||||
|
|
||||||
class StreamHelperType {
|
class StreamHelperType {
|
||||||
public TypeDefinition type;
|
public TypeDef type;
|
||||||
public MethodDefinition readInt16Method;
|
public MethodDef readInt16Method;
|
||||||
public MethodDefinition readInt32Method;
|
public MethodDef readInt32Method;
|
||||||
public MethodDefinition readBytesMethod;
|
public MethodDef readBytesMethod;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get {
|
get {
|
||||||
|
@ -61,7 +61,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamHelperType(TypeDefinition type) {
|
public StreamHelperType(TypeDef type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
|
@ -77,7 +77,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return stringType; }
|
get { return stringType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,16 +85,16 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
get { return encryptedResource; }
|
get { return encryptedResource; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<TypeDefinition> Types {
|
public IEnumerable<TypeDef> Types {
|
||||||
get {
|
get {
|
||||||
return new List<TypeDefinition> {
|
return new List<TypeDef> {
|
||||||
stringType,
|
stringType,
|
||||||
dataDecrypterType,
|
dataDecrypterType,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDef Method {
|
||||||
get { return stringMethod; }
|
get { return stringMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
this.decrypterType = decrypterType;
|
this.decrypterType = decrypterType;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkIfV32OrLater(TypeDefinition type) {
|
static bool checkIfV32OrLater(TypeDef type) {
|
||||||
int numInts = 0;
|
int numInts = 0;
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
if (field.FieldType.EType == ElementType.I4)
|
if (field.FieldType.EType == ElementType.I4)
|
||||||
|
@ -137,7 +137,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
"System.Byte[]",
|
"System.Byte[]",
|
||||||
"System.Int16",
|
"System.Int16",
|
||||||
};
|
};
|
||||||
bool checkType(TypeDefinition type) {
|
bool checkType(TypeDef type) {
|
||||||
if (!new FieldTypes(type).all(requiredFieldTypes))
|
if (!new FieldTypes(type).all(requiredFieldTypes))
|
||||||
return false;
|
return false;
|
||||||
if (type.NestedTypes.Count == 0) {
|
if (type.NestedTypes.Count == 0) {
|
||||||
|
@ -159,9 +159,9 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
"System.IO.Stream",
|
"System.IO.Stream",
|
||||||
"System.Byte[]",
|
"System.Byte[]",
|
||||||
};
|
};
|
||||||
static StreamHelperType findStreamHelperType(TypeDefinition type) {
|
static StreamHelperType findStreamHelperType(TypeDef type) {
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
var nested = field.FieldType as TypeDefinition;
|
var nested = field.FieldType as TypeDef;
|
||||||
if (nested == null)
|
if (nested == null)
|
||||||
continue;
|
continue;
|
||||||
if (nested.DeclaringType != type)
|
if (nested.DeclaringType != type)
|
||||||
|
@ -186,7 +186,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
"System.Reflection.Assembly",
|
"System.Reflection.Assembly",
|
||||||
"System.String",
|
"System.String",
|
||||||
};
|
};
|
||||||
static bool checkDecrypterMethod(MethodDefinition method) {
|
static bool checkDecrypterMethod(MethodDef method) {
|
||||||
if (method == null || !method.IsStatic || method.Body == null)
|
if (method == null || !method.IsStatic || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
if (!DotNetUtils.isMethod(method, "System.String", "(System.Int32)"))
|
if (!DotNetUtils.isMethod(method, "System.String", "(System.Int32)"))
|
||||||
|
@ -344,7 +344,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getFlagsOffset(MethodDefinition method, int index, VariableDefinition local) {
|
static int getFlagsOffset(MethodDef method, int index, VariableDefinition local) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (; index < instrs.Count; index++) {
|
for (; index < instrs.Count; index++) {
|
||||||
var ldloc = instrs[index];
|
var ldloc = instrs[index];
|
||||||
|
@ -358,7 +358,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VariableDefinition getFlagsLocal(MethodDefinition method, int index) {
|
static VariableDefinition getFlagsLocal(MethodDef method, int index) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
if (index + 5 >= instrs.Count)
|
if (index + 5 >= instrs.Count)
|
||||||
return null;
|
return null;
|
||||||
|
@ -485,17 +485,17 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return lcg * 214013 + 2531011;
|
return lcg * 214013 + 2531011;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findResource(MethodDefinition method) {
|
bool findResource(MethodDef method) {
|
||||||
encryptedResource = findResourceFromCodeString(method) ??
|
encryptedResource = findResourceFromCodeString(method) ??
|
||||||
findResourceFromStringBuilder(method);
|
findResourceFromStringBuilder(method);
|
||||||
return encryptedResource != null;
|
return encryptedResource != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbeddedResource findResourceFromCodeString(MethodDefinition method) {
|
EmbeddedResource findResourceFromCodeString(MethodDef method) {
|
||||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbeddedResource findResourceFromStringBuilder(MethodDefinition method) {
|
EmbeddedResource findResourceFromStringBuilder(MethodDef method) {
|
||||||
int startIndex = EfUtils.findOpCodeIndex(method, 0, Code.Newobj, "System.Void System.Text.StringBuilder::.ctor()");
|
int startIndex = EfUtils.findOpCodeIndex(method, 0, Code.Newobj, "System.Void System.Text.StringBuilder::.ctor()");
|
||||||
if (startIndex < 0)
|
if (startIndex < 0)
|
||||||
return null;
|
return null;
|
||||||
|
@ -532,11 +532,11 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return DotNetUtils.getResource(module, sb.ToString()) as EmbeddedResource;
|
return DotNetUtils.getResource(module, sb.ToString()) as EmbeddedResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodDefinition findInt64Method(MethodDefinition method) {
|
static MethodDef findInt64Method(MethodDef method) {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(calledMethod, "System.Int64", "()"))
|
if (!DotNetUtils.isMethod(calledMethod, "System.Int64", "()"))
|
||||||
|
@ -547,11 +547,11 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeDefinition findDataDecrypterType(MethodDefinition method) {
|
static TypeDef findDataDecrypterType(MethodDef method) {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call)
|
if (instr.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = instr.Operand as MethodDefinition;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(calledMethod, "System.Byte[]", "(System.Byte[],System.Byte[])"))
|
if (!DotNetUtils.isMethod(calledMethod, "System.Byte[]", "(System.Byte[],System.Byte[])"))
|
||||||
|
@ -617,7 +617,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findInitIntsIndex(MethodDefinition method, out bool initializedAll) {
|
static int findInitIntsIndex(MethodDef method, out bool initializedAll) {
|
||||||
initializedAll = false;
|
initializedAll = false;
|
||||||
|
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
|
@ -630,13 +630,13 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
if (stsfld.OpCode.Code != Code.Stsfld)
|
if (stsfld.OpCode.Code != Code.Stsfld)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var storeField = stsfld.Operand as FieldDefinition;
|
var storeField = stsfld.Operand as FieldDef;
|
||||||
if (storeField == null || storeField.FieldType.FullName != "System.Byte[]")
|
if (storeField == null || storeField.FieldType.FullName != "System.Byte[]")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var instr = instrs[i + 2];
|
var instr = instrs[i + 2];
|
||||||
if (instr.OpCode.Code == Code.Ldsfld) {
|
if (instr.OpCode.Code == Code.Ldsfld) {
|
||||||
var loadField = instr.Operand as FieldDefinition;
|
var loadField = instr.Operand as FieldDef;
|
||||||
if (loadField == null || loadField.FieldType.EType != ElementType.I4)
|
if (loadField == null || loadField.FieldType.EType != ElementType.I4)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -652,7 +652,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findIntsCctor(MethodDefinition cctor) {
|
bool findIntsCctor(MethodDef cctor) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!findCallGetFrame(cctor, ref index))
|
if (!findCallGetFrame(cctor, ref index))
|
||||||
return findIntsCctor2(cctor);
|
return findIntsCctor2(cctor);
|
||||||
|
@ -683,7 +683,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compact Framework doesn't have StackFrame
|
// Compact Framework doesn't have StackFrame
|
||||||
bool findIntsCctor2(MethodDefinition cctor) {
|
bool findIntsCctor2(MethodDef cctor) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
var instrs = cctor.Body.Instructions;
|
var instrs = cctor.Body.Instructions;
|
||||||
var constantsReader = new EfConstantsReader(cctor);
|
var constantsReader = new EfConstantsReader(cctor);
|
||||||
|
@ -822,7 +822,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool callsGetPublicKeyToken(MethodDefinition method) {
|
static bool callsGetPublicKeyToken(MethodDef method) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
return findCall(method, ref index, "System.Byte[] System.Reflection.AssemblyName::GetPublicKeyToken()");
|
return findCall(method, ref index, "System.Byte[] System.Reflection.AssemblyName::GetPublicKeyToken()");
|
||||||
}
|
}
|
||||||
|
@ -839,11 +839,11 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return findCall(stringMethod, ref index, streamHelperType == null ? "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)" : streamHelperType.readBytesMethod.FullName);
|
return findCall(stringMethod, ref index, streamHelperType == null ? "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)" : streamHelperType.readBytesMethod.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findCallGetFrame(MethodDefinition method, ref int index) {
|
static bool findCallGetFrame(MethodDef method, ref int index) {
|
||||||
return findCall(method, ref index, "System.Diagnostics.StackFrame System.Diagnostics.StackTrace::GetFrame(System.Int32)");
|
return findCall(method, ref index, "System.Diagnostics.StackFrame System.Diagnostics.StackTrace::GetFrame(System.Int32)");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findCall(MethodDefinition method, ref int index, string methodFullName) {
|
static bool findCall(MethodDef method, ref int index, string methodFullName) {
|
||||||
for (; index < method.Body.Instructions.Count; index++) {
|
for (; index < method.Body.Instructions.Count; index++) {
|
||||||
if (!findCallvirt(method, ref index))
|
if (!findCallvirt(method, ref index))
|
||||||
return false;
|
return false;
|
||||||
|
@ -859,7 +859,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findCallvirt(MethodDefinition method, ref int index) {
|
static bool findCallvirt(MethodDef method, ref int index) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (; index < instrs.Count; index++) {
|
for (; index < instrs.Count; index++) {
|
||||||
var instr = instrs[index];
|
var instr = instrs[index];
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
|
@ -38,8 +38,8 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
if (decryptStringType == null || decryptStringMethod == null)
|
if (decryptStringType == null || decryptStringMethod == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var otherMethods = new List<MethodDefinition>();
|
var otherMethods = new List<MethodDef>();
|
||||||
MethodDefinition cctor = null;
|
MethodDef cctor = null;
|
||||||
foreach (var method in decryptStringType.Methods) {
|
foreach (var method in decryptStringType.Methods) {
|
||||||
if (method == decryptStringMethod)
|
if (method == decryptStringMethod)
|
||||||
continue;
|
continue;
|
||||||
|
@ -671,7 +671,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinition getNestedType(int n) {
|
TypeDef getNestedType(int n) {
|
||||||
var type = stringDecrypter.Type;
|
var type = stringDecrypter.Type;
|
||||||
|
|
||||||
int fieldIndex;
|
int fieldIndex;
|
||||||
|
@ -684,7 +684,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
|
|
||||||
if (fieldIndex >= type.Fields.Count)
|
if (fieldIndex >= type.Fields.Count)
|
||||||
return null;
|
return null;
|
||||||
var nestedType = type.Fields[fieldIndex].FieldType as TypeDefinition;
|
var nestedType = type.Fields[fieldIndex].FieldType as TypeDef;
|
||||||
if (nestedType == null || type.NestedTypes.IndexOf(nestedType) < 0)
|
if (nestedType == null || type.NestedTypes.IndexOf(nestedType) < 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
|
@ -31,15 +31,15 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
"System.Byte[]",
|
"System.Byte[]",
|
||||||
"System.Collections.Generic.Dictionary`2<System.Int32,System.Byte[]>",
|
"System.Collections.Generic.Dictionary`2<System.Int32,System.Byte[]>",
|
||||||
};
|
};
|
||||||
protected override bool checkDecrypterType(TypeDefinition type) {
|
protected override bool checkDecrypterType(TypeDef type) {
|
||||||
return new FieldTypes(type).exactly(requiredFields);
|
return new FieldTypes(type).exactly(requiredFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool checkDelegateInvokeMethod(MethodDefinition invokeMethod) {
|
protected override bool checkDelegateInvokeMethod(MethodDef invokeMethod) {
|
||||||
return DotNetUtils.isMethod(invokeMethod, "System.Byte[]", "(System.Int32)");
|
return DotNetUtils.isMethod(invokeMethod, "System.Byte[]", "(System.Int32)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] decrypt(MethodDefinition method) {
|
public byte[] decrypt(MethodDef method) {
|
||||||
var info = getInfo(method);
|
var info = getInfo(method);
|
||||||
decryptedReader.BaseStream.Position = info.offset;
|
decryptedReader.BaseStream.Position = info.offset;
|
||||||
return decryptedReader.ReadBytes(decryptedReader.ReadInt32());
|
return decryptedReader.ReadBytes(decryptedReader.ReadInt32());
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
|
|
|
@ -20,25 +20,25 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
abstract class DecrypterBase {
|
abstract class DecrypterBase {
|
||||||
protected ModuleDefinition module;
|
protected ModuleDefinition module;
|
||||||
EmbeddedResource encryptedResource;
|
EmbeddedResource encryptedResource;
|
||||||
TypeDefinition decrypterType;
|
TypeDef decrypterType;
|
||||||
TypeDefinition delegateType;
|
TypeDef delegateType;
|
||||||
TypeDefinition delegateInitType;
|
TypeDef delegateInitType;
|
||||||
protected BinaryReader decryptedReader;
|
protected BinaryReader decryptedReader;
|
||||||
MethodDefinitionAndDeclaringTypeDict<Info> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict<Info>();
|
MethodDefinitionAndDeclaringTypeDict<Info> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict<Info>();
|
||||||
|
|
||||||
protected class Info {
|
protected class Info {
|
||||||
public MethodDefinition method;
|
public MethodDef method;
|
||||||
public int offset;
|
public int offset;
|
||||||
public bool referenced = false;
|
public bool referenced = false;
|
||||||
public Info(MethodDefinition method, int offset) {
|
public Info(MethodDef method, int offset) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
@ -52,21 +52,21 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
get { return encryptedResource; }
|
get { return encryptedResource; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return decrypterType; }
|
get { return decrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition DelegateInitType {
|
public TypeDef DelegateInitType {
|
||||||
get { return delegateInitType ?? findDelegateInitType();}
|
get { return delegateInitType ?? findDelegateInitType();}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition DelegateType {
|
public TypeDef DelegateType {
|
||||||
get { return delegateType; }
|
get { return delegateType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<TypeDefinition> DecrypterTypes {
|
public IEnumerable<TypeDef> DecrypterTypes {
|
||||||
get {
|
get {
|
||||||
var types = new TypeDefinitionDict<TypeDefinition>();
|
var types = new TypeDefinitionDict<TypeDef>();
|
||||||
foreach (var info in decrypterMethods.getValues()) {
|
foreach (var info in decrypterMethods.getValues()) {
|
||||||
if (info.referenced)
|
if (info.referenced)
|
||||||
types.add(info.method.DeclaringType, info.method.DeclaringType);
|
types.add(info.method.DeclaringType, info.method.DeclaringType);
|
||||||
|
@ -79,7 +79,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Info getInfo(MethodDefinition method) {
|
protected Info getInfo(MethodDef method) {
|
||||||
var info = decrypterMethods.find(method);
|
var info = decrypterMethods.find(method);
|
||||||
if (info == null)
|
if (info == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -110,7 +110,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract bool checkDecrypterType(TypeDefinition type);
|
protected abstract bool checkDecrypterType(TypeDef type);
|
||||||
|
|
||||||
void splitTypeName(string fullName, out string ns, out string name) {
|
void splitTypeName(string fullName, out string ns, out string name) {
|
||||||
int index = fullName.LastIndexOf('.');
|
int index = fullName.LastIndexOf('.');
|
||||||
|
@ -171,13 +171,13 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info getDecrypterInfo(MethodDefinition method, FieldDefinition delegateField) {
|
Info getDecrypterInfo(MethodDef method, FieldDef delegateField) {
|
||||||
try {
|
try {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
if (instrs[index].OpCode.Code != Code.Ldsfld)
|
if (instrs[index].OpCode.Code != Code.Ldsfld)
|
||||||
return null;
|
return null;
|
||||||
var field = instrs[index++].Operand as FieldDefinition;
|
var field = instrs[index++].Operand as FieldDef;
|
||||||
if (field != delegateField)
|
if (field != delegateField)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -204,12 +204,12 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkCctor(MethodDefinition cctor) {
|
bool checkCctor(MethodDef cctor) {
|
||||||
var ldtokenType = getLdtokenType(cctor);
|
var ldtokenType = getLdtokenType(cctor);
|
||||||
if (!MemberReferenceHelper.compareTypes(ldtokenType, cctor.DeclaringType))
|
if (!MemberReferenceHelper.compareTypes(ldtokenType, cctor.DeclaringType))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MethodDefinition initMethod = null;
|
MethodDef initMethod = null;
|
||||||
foreach (var method in DotNetUtils.getCalledMethods(module, cctor)) {
|
foreach (var method in DotNetUtils.getCalledMethods(module, cctor)) {
|
||||||
if (DotNetUtils.isMethod(method, "System.Void", "(System.Type)")) {
|
if (DotNetUtils.isMethod(method, "System.Void", "(System.Type)")) {
|
||||||
initMethod = method;
|
initMethod = method;
|
||||||
|
@ -222,7 +222,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeReference getLdtokenType(MethodDefinition method) {
|
static TypeReference getLdtokenType(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return null;
|
return null;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
|
@ -233,7 +233,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkDelegateType(TypeDefinition type) {
|
bool checkDelegateType(TypeDef type) {
|
||||||
if (!DotNetUtils.derivesFromDelegate(type))
|
if (!DotNetUtils.derivesFromDelegate(type))
|
||||||
return false;
|
return false;
|
||||||
var invoke = DotNetUtils.getMethod(type, "Invoke");
|
var invoke = DotNetUtils.getMethod(type, "Invoke");
|
||||||
|
@ -242,7 +242,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
return checkDelegateInvokeMethod(invoke);
|
return checkDelegateInvokeMethod(invoke);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract bool checkDelegateInvokeMethod(MethodDefinition invokeMethod);
|
protected abstract bool checkDelegateInvokeMethod(MethodDef invokeMethod);
|
||||||
|
|
||||||
byte[] decrypt(byte[] encryptedData) {
|
byte[] decrypt(byte[] encryptedData) {
|
||||||
const int KEY_LEN = 0x100;
|
const int KEY_LEN = 0x100;
|
||||||
|
@ -265,7 +265,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
return decryptedData;
|
return decryptedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinition findDelegateInitType() {
|
TypeDef findDelegateInitType() {
|
||||||
if (delegateType == null)
|
if (delegateType == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -290,8 +290,8 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<MethodDefinition> getMethods() {
|
public IEnumerable<MethodDef> getMethods() {
|
||||||
var list = new List<MethodDefinition>(decrypterMethods.Count);
|
var list = new List<MethodDef>(decrypterMethods.Count);
|
||||||
foreach (var info in decrypterMethods.getValues())
|
foreach (var info in decrypterMethods.getValues())
|
||||||
list.Add(info.method);
|
list.Add(info.method);
|
||||||
return list;
|
return list;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
|
@ -162,7 +162,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeVersion(TypeDefinition attr) {
|
void initializeVersion(TypeDef attr) {
|
||||||
var s = DotNetUtils.getCustomArgAsString(getAssemblyAttribute(attr), 0);
|
var s = DotNetUtils.getCustomArgAsString(getAssemblyAttribute(attr), 0);
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return;
|
return;
|
||||||
|
@ -274,7 +274,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
foreach (var method in stringDecrypter.getMethods())
|
foreach (var method in stringDecrypter.getMethods())
|
||||||
list.Add(method.MetadataToken.ToInt32());
|
list.Add(method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
|
@ -31,15 +31,15 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
"System.Byte[]",
|
"System.Byte[]",
|
||||||
"System.Collections.Generic.Dictionary`2<System.Int32,System.Object>",
|
"System.Collections.Generic.Dictionary`2<System.Int32,System.Object>",
|
||||||
};
|
};
|
||||||
protected override bool checkDecrypterType(TypeDefinition type) {
|
protected override bool checkDecrypterType(TypeDef type) {
|
||||||
return new FieldTypes(type).exactly(requiredFields);
|
return new FieldTypes(type).exactly(requiredFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool checkDelegateInvokeMethod(MethodDefinition invokeMethod) {
|
protected override bool checkDelegateInvokeMethod(MethodDef invokeMethod) {
|
||||||
return DotNetUtils.isMethod(invokeMethod, "System.Object", "(System.Int32)");
|
return DotNetUtils.isMethod(invokeMethod, "System.Object", "(System.Int32)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public int decrypt(MethodDefinition method) {
|
public int decrypt(MethodDef method) {
|
||||||
var info = getInfo(method);
|
var info = getInfo(method);
|
||||||
decryptedReader.BaseStream.Position = info.offset;
|
decryptedReader.BaseStream.Position = info.offset;
|
||||||
int len = decryptedReader.ReadInt32();
|
int len = decryptedReader.ReadInt32();
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
|
@ -28,18 +28,18 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
TypeDefinitionDict<Info> typeToInfo = new TypeDefinitionDict<Info>();
|
TypeDefinitionDict<Info> typeToInfo = new TypeDefinitionDict<Info>();
|
||||||
|
|
||||||
class Info {
|
class Info {
|
||||||
public TypeDefinition type;
|
public TypeDef type;
|
||||||
public TypeReference localType;
|
public TypeReference localType;
|
||||||
public bool referenced = false;
|
public bool referenced = false;
|
||||||
public Info(TypeDefinition type, TypeReference localType) {
|
public Info(TypeDef type, TypeReference localType) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.localType = localType;
|
this.localType = localType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TypeDefinition> Types {
|
public List<TypeDef> Types {
|
||||||
get {
|
get {
|
||||||
var list = new List<TypeDefinition>(typeToInfo.Count);
|
var list = new List<TypeDef>(typeToInfo.Count);
|
||||||
foreach (var info in typeToInfo.getValues()) {
|
foreach (var info in typeToInfo.getValues()) {
|
||||||
if (info.referenced)
|
if (info.referenced)
|
||||||
list.Add(info.type);
|
list.Add(info.type);
|
||||||
|
@ -57,7 +57,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
initialize(type);
|
initialize(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize(TypeDefinition type) {
|
void initialize(TypeDef type) {
|
||||||
if (type.HasEvents || type.HasProperties)
|
if (type.HasEvents || type.HasProperties)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
|
@ -30,9 +30,9 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyInfo {
|
class MyInfo {
|
||||||
public MethodDefinition method;
|
public MethodDef method;
|
||||||
public DelegateInfo delegateInfo;
|
public DelegateInfo delegateInfo;
|
||||||
public MyInfo(MethodDefinition method, DelegateInfo delegateInfo) {
|
public MyInfo(MethodDef method, DelegateInfo delegateInfo) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.delegateInfo = delegateInfo;
|
this.delegateInfo = delegateInfo;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
if (infos.Count == 0)
|
if (infos.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Log.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MetadataToken.ToUInt32());
|
Log.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MDToken.ToUInt32());
|
||||||
RemovedDelegateCreatorCalls++;
|
RemovedDelegateCreatorCalls++;
|
||||||
Log.indent();
|
Log.indent();
|
||||||
foreach (var info in infos) {
|
foreach (var info in infos) {
|
||||||
|
@ -66,14 +66,14 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
Utils.removeNewlines(di.field.Name),
|
Utils.removeNewlines(di.field.Name),
|
||||||
di.callOpcode,
|
di.callOpcode,
|
||||||
Utils.removeNewlines(di.methodRef),
|
Utils.removeNewlines(di.methodRef),
|
||||||
di.methodRef.MetadataToken.ToUInt32());
|
di.methodRef.MDToken.ToUInt32());
|
||||||
}
|
}
|
||||||
Log.deIndent();
|
Log.deIndent();
|
||||||
delegateTypesDict[type] = true;
|
delegateTypesDict[type] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkProxyMethod(MethodDefinition method, out DelegateInfo info) {
|
bool checkProxyMethod(MethodDef method, out DelegateInfo info) {
|
||||||
info = null;
|
info = null;
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -86,7 +86,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
|
|
||||||
if (instrs[index].OpCode.Code != Code.Ldsfld)
|
if (instrs[index].OpCode.Code != Code.Ldsfld)
|
||||||
return false;
|
return false;
|
||||||
var field = instrs[index++].Operand as FieldDefinition;
|
var field = instrs[index++].Operand as FieldDef;
|
||||||
if (field == null || !field.IsStatic)
|
if (field == null || !field.IsStatic)
|
||||||
return false;
|
return false;
|
||||||
if (!MemberReferenceHelper.compareTypes(method.DeclaringType, field.DeclaringType))
|
if (!MemberReferenceHelper.compareTypes(method.DeclaringType, field.DeclaringType))
|
||||||
|
@ -132,11 +132,11 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override object checkCctor(TypeDefinition type, MethodDefinition cctor) {
|
protected override object checkCctor(TypeDef type, MethodDef cctor) {
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode) {
|
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,16 +19,16 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
class StringDecrypter : DecrypterBase {
|
class StringDecrypter : DecrypterBase {
|
||||||
TypeReference delegateReturnType;
|
TypeReference delegateReturnType;
|
||||||
FieldDefinition stringStructField;
|
FieldDef stringStructField;
|
||||||
|
|
||||||
public TypeDefinition StringStruct {
|
public TypeDef StringStruct {
|
||||||
get { return Detected && stringStructField != null ? stringStructField.DeclaringType : null; }
|
get { return Detected && stringStructField != null ? stringStructField.DeclaringType : null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
"System.Byte[]",
|
"System.Byte[]",
|
||||||
"System.Collections.Generic.Dictionary`2<System.Int32,System.String>",
|
"System.Collections.Generic.Dictionary`2<System.Int32,System.String>",
|
||||||
};
|
};
|
||||||
protected override bool checkDecrypterType(TypeDefinition type) {
|
protected override bool checkDecrypterType(TypeDef type) {
|
||||||
var fields = type.Fields;
|
var fields = type.Fields;
|
||||||
if (fields.Count != 2)
|
if (fields.Count != 2)
|
||||||
return false;
|
return false;
|
||||||
|
@ -80,11 +80,11 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool checkDelegateInvokeMethod(MethodDefinition invokeMethod) {
|
protected override bool checkDelegateInvokeMethod(MethodDef invokeMethod) {
|
||||||
return DotNetUtils.isMethod(invokeMethod, delegateReturnType.FullName, "(System.Int32)");
|
return DotNetUtils.isMethod(invokeMethod, delegateReturnType.FullName, "(System.Int32)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public string decrypt(MethodDefinition method) {
|
public string decrypt(MethodDef method) {
|
||||||
var info = getInfo(method);
|
var info = getInfo(method);
|
||||||
decryptedReader.BaseStream.Position = info.offset;
|
decryptedReader.BaseStream.Position = info.offset;
|
||||||
int len = decryptedReader.ReadInt32();
|
int len = decryptedReader.ReadInt32();
|
||||||
|
|
|
@ -17,25 +17,25 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Goliath_NET {
|
namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
class StrongNameChecker {
|
class StrongNameChecker {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
TypeDefinition strongNameType;
|
TypeDef strongNameType;
|
||||||
MethodDefinition strongNameCheckMethod;
|
MethodDef strongNameCheckMethod;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return strongNameType != null;}
|
get { return strongNameType != null;}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDef Type {
|
||||||
get { return strongNameType; }
|
get { return strongNameType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition CheckerMethod {
|
public MethodDef CheckerMethod {
|
||||||
get { return strongNameCheckMethod; }
|
get { return strongNameCheckMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDefinition getAntiTamperingDetectionMethod(TypeDefinition type) {
|
MethodDef getAntiTamperingDetectionMethod(TypeDef type) {
|
||||||
var requiredLocals = new string[] {
|
var requiredLocals = new string[] {
|
||||||
"System.Reflection.Assembly",
|
"System.Reflection.Assembly",
|
||||||
"System.Collections.Generic.Stack`1<System.Int32>",
|
"System.Collections.Generic.Stack`1<System.Int32>",
|
||||||
|
@ -85,7 +85,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasThrow(MethodDefinition method) {
|
static bool hasThrow(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.ILProtector {
|
namespace de4dot.code.deobfuscators.ILProtector {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user