Port some more code

This commit is contained in:
de4dot 2012-11-01 21:09:09 +01:00
parent 1341cc7199
commit 24c43d5a66
12 changed files with 129 additions and 138 deletions

View File

@ -713,6 +713,13 @@ namespace de4dot.blocks {
return type.EType != ElementType.Void; return type.EType != ElementType.Void;
} }
public static bool hasReturnValue(DN.IMethod method) {
if (method == null || method.MethodSig == null)
return false;
//TODO: Also remove modifiers from RetType before comparing etype
return method.MethodSig.RetType.ElementType != DN.ElementType.Void;
}
public static void updateStack(Instruction instr, ref int stack, bool methodHasReturnValue) { public static void updateStack(Instruction instr, ref int stack, bool methodHasReturnValue) {
int pushes, pops; int pushes, pops;
calculateStackUsage(instr, methodHasReturnValue, out pushes, out pops); calculateStackUsage(instr, methodHasReturnValue, out pushes, out pops);
@ -924,6 +931,12 @@ namespace de4dot.blocks {
return null; return null;
} }
public static DN.Parameter getParameter(IList<DN.Parameter> parameters, int index) {
if (0 <= index && index < parameters.Count)
return parameters[index];
return null;
}
public static List<TypeReference> getArgs(MethodReference method) { public static List<TypeReference> getArgs(MethodReference method) {
var args = new List<TypeReference>(method.Parameters.Count + 1); var args = new List<TypeReference>(method.Parameters.Count + 1);
if (method.HasImplicitThis) if (method.HasImplicitThis)

View File

@ -19,14 +19,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using de4dot.code.deobfuscators; using de4dot.code.deobfuscators;
using Mono.Cecil; using dot10.DotNet;
#if PORT #if PORT
using de4dot.code.renamer; using de4dot.code.renamer;
#endif #endif
namespace de4dot.code { namespace de4dot.code {
public interface IObfuscatedFile { public interface IObfuscatedFile {
ModuleDefinition ModuleDefinition { get; } ModuleDefMD ModuleDefMD { get; }
IDeobfuscator Deobfuscator { get; } IDeobfuscator Deobfuscator { get; }
IDeobfuscatorContext DeobfuscatorContext { get; set; } IDeobfuscatorContext DeobfuscatorContext { get; set; }
string Filename { get; } string Filename { get; }

View File

@ -24,6 +24,7 @@ using System.IO;
using System.Text; using System.Text;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using dot10.PE;
using de4dot.code.deobfuscators; using de4dot.code.deobfuscators;
using de4dot.blocks; using de4dot.blocks;
using de4dot.blocks.cflow; using de4dot.blocks.cflow;
@ -31,7 +32,6 @@ using de4dot.code.AssemblyClient;
#if PORT #if PORT
using de4dot.code.renamer; using de4dot.code.renamer;
#endif #endif
using de4dot.PE;
namespace de4dot.code { namespace de4dot.code {
public class ObfuscatedFile : IObfuscatedFile, IDeobfuscatedFile { public class ObfuscatedFile : IObfuscatedFile, IDeobfuscatedFile {
@ -185,7 +185,7 @@ namespace de4dot.code {
} }
bool unpackNativeImage(IEnumerable<IDeobfuscator> deobfuscators) { bool unpackNativeImage(IEnumerable<IDeobfuscator> deobfuscators) {
var peImage = new PeImage(Utils.readFile(Filename)); var peImage = new PEImage(Filename);
foreach (var deob in deobfuscators) { foreach (var deob in deobfuscators) {
byte[] unpackedData = null; byte[] unpackedData = null;
@ -731,11 +731,9 @@ namespace de4dot.code {
return; return;
deobfuscate(method, "Deobfuscating control flow", (blocks) => { deobfuscate(method, "Deobfuscating control flow", (blocks) => {
#if PORT
var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators); var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators);
cflowDeobfuscator.init(blocks); cflowDeobfuscator.init(blocks);
cflowDeobfuscator.deobfuscate(); cflowDeobfuscator.deobfuscate();
#endif
}); });
} }

View File

@ -20,12 +20,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using dot10.DotNet; using dot10.DotNet;
using dot10.PE;
using de4dot.blocks; using de4dot.blocks;
using de4dot.blocks.cflow; using de4dot.blocks.cflow;
#if PORT #if PORT
using de4dot.code.renamer; using de4dot.code.renamer;
#endif #endif
using de4dot.PE;
namespace de4dot.code.deobfuscators { namespace de4dot.code.deobfuscators {
public interface IDeobfuscatorOptions { public interface IDeobfuscatorOptions {
@ -67,15 +67,13 @@ namespace de4dot.code.deobfuscators {
StringFeatures StringFeatures { get; } StringFeatures StringFeatures { get; }
RenamingOptions RenamingOptions { get; } RenamingOptions RenamingOptions { get; }
DecrypterType DefaultDecrypterType { get; } DecrypterType DefaultDecrypterType { get; }
#if PORT
IEnumerable<IBlocksDeobfuscator> BlocksDeobfuscators { get; } IEnumerable<IBlocksDeobfuscator> BlocksDeobfuscators { get; }
#endif
// This is non-null only in detect() and deobfuscateBegin(). // This is non-null only in detect() and deobfuscateBegin().
IDeobfuscatedFile DeobfuscatedFile { get; set; } IDeobfuscatedFile DeobfuscatedFile { get; set; }
// Returns null or the unpacked .NET PE file // Returns null or the unpacked .NET PE file
byte[] unpackNativeFile(PeImage peImage); byte[] unpackNativeFile(PEImage peImage);
void init(ModuleDefMD module); void init(ModuleDefMD module);

View File

@ -24,7 +24,7 @@ using dot10.DotNet.MD;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.deobfuscators { namespace de4dot.code.deobfuscators {
class MemberReferenceBuilder : ICorLibTypes { class MemberReferenceBuilder {
ModuleDefMD module; ModuleDefMD module;
Dictionary<TypeSig, TypeSig> createdTypes = new Dictionary<TypeSig, TypeSig>(TypeEqualityComparer.Instance); Dictionary<TypeSig, TypeSig> createdTypes = new Dictionary<TypeSig, TypeSig>(TypeEqualityComparer.Instance);
@ -36,10 +36,6 @@ namespace de4dot.code.deobfuscators {
get { return module.CorLibTypes.AssemblyRef; } get { return module.CorLibTypes.AssemblyRef; }
} }
public AssemblyRef AssemblyRef {
get { return module.CorLibTypes.AssemblyRef; }
}
public CorLibTypeSig Object { public CorLibTypeSig Object {
get { return module.CorLibTypes.Object; } get { return module.CorLibTypes.Object; }
} }

View File

@ -48,7 +48,7 @@ namespace de4dot.code.deobfuscators {
return; return;
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
var streamType = builder.type("System.IO", "Stream", builder.CorLib); var streamType = builder.type("System.IO", "Stream", builder.CorLib);
var newMethod = builder.instanceMethod("GetManifestResourceStream", assemblyType, streamType, builder.String); var newMethod = builder.instanceMethod("GetManifestResourceStream", assemblyType.TypeDefOrRef, streamType, builder.String);
add(oldMethod, newMethod, OpCodes.Callvirt); add(oldMethod, newMethod, OpCodes.Callvirt);
} }
@ -58,7 +58,7 @@ namespace de4dot.code.deobfuscators {
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
var typeType = builder.type("System", "Type", builder.CorLib); var typeType = builder.type("System", "Type", builder.CorLib);
var streamType = builder.type("System.IO", "Stream", builder.CorLib); var streamType = builder.type("System.IO", "Stream", builder.CorLib);
var newMethod = builder.instanceMethod("GetManifestResourceStream", assemblyType, streamType, typeType, builder.String); var newMethod = builder.instanceMethod("GetManifestResourceStream", assemblyType.TypeDefOrRef, streamType, typeType, builder.String);
add(oldMethod, newMethod, OpCodes.Callvirt); add(oldMethod, newMethod, OpCodes.Callvirt);
} }
@ -67,7 +67,7 @@ namespace de4dot.code.deobfuscators {
return; return;
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
var stringArrayType = builder.array(builder.String); var stringArrayType = builder.array(builder.String);
var newMethod = builder.instanceMethod("GetManifestResourceNames", assemblyType, stringArrayType); var newMethod = builder.instanceMethod("GetManifestResourceNames", assemblyType.TypeDefOrRef, stringArrayType);
add(oldMethod, newMethod, OpCodes.Callvirt); add(oldMethod, newMethod, OpCodes.Callvirt);
} }
@ -76,7 +76,7 @@ namespace de4dot.code.deobfuscators {
return; return;
var bitmapType = builder.type("System.Drawing", "Bitmap", "System.Drawing"); var bitmapType = builder.type("System.Drawing", "Bitmap", "System.Drawing");
var typeType = builder.type("System", "Type", builder.CorLib); var typeType = builder.type("System", "Type", builder.CorLib);
var newMethod = builder.instanceMethod(".ctor", bitmapType, builder.Void, typeType, builder.String); var newMethod = builder.instanceMethod(".ctor", bitmapType.TypeDefOrRef, builder.Void, typeType, builder.String);
add(oldMethod, newMethod, OpCodes.Newobj); add(oldMethod, newMethod, OpCodes.Newobj);
} }
@ -85,7 +85,7 @@ namespace de4dot.code.deobfuscators {
return; return;
var iconType = builder.type("System.Drawing", "Icon", "System.Drawing"); var iconType = builder.type("System.Drawing", "Icon", "System.Drawing");
var typeType = builder.type("System", "Type", builder.CorLib); var typeType = builder.type("System", "Type", builder.CorLib);
var newMethod = builder.instanceMethod(".ctor", iconType, builder.Void, typeType, builder.String); var newMethod = builder.instanceMethod(".ctor", iconType.TypeDefOrRef, builder.Void, typeType, builder.String);
add(oldMethod, newMethod, OpCodes.Newobj); add(oldMethod, newMethod, OpCodes.Newobj);
} }

View File

@ -57,12 +57,12 @@ namespace de4dot.code.deobfuscators {
} }
class TypeInfo<T> { class TypeInfo<T> {
Dictionary<TypeReferenceKey, bool> types = new Dictionary<TypeReferenceKey, bool>(); Dictionary<TypeSig, bool> types = new Dictionary<TypeSig, bool>(TypeEqualityComparer.Instance);
public TypeReference newType = null; public TypeSig newType = null;
public T arg; public T arg;
bool newobjTypes; bool newobjTypes;
public Dictionary<TypeReferenceKey, bool> Types { public Dictionary<TypeSig, bool> Types {
get { return types; } get { return types; }
} }
@ -70,11 +70,11 @@ namespace de4dot.code.deobfuscators {
this.arg = arg; this.arg = arg;
} }
public void add(TypeReference type) { public void add(TypeSig type) {
add(type, false); add(type, false);
} }
public void add(TypeReference type, bool wasNewobj) { public void add(TypeSig type, bool wasNewobj) {
if (wasNewobj) { if (wasNewobj) {
if (!newobjTypes) if (!newobjTypes)
clear(); clear();
@ -82,7 +82,7 @@ namespace de4dot.code.deobfuscators {
} }
else if (newobjTypes) else if (newobjTypes)
return; return;
types[new TypeReferenceKey(type)] = true; types[type] = true;
} }
public void clear() { public void clear() {
@ -93,19 +93,19 @@ namespace de4dot.code.deobfuscators {
if (types.Count == 0) if (types.Count == 0)
return false; return false;
TypeReference theNewType = null; TypeSig theNewType = null;
foreach (var key in types.Keys) { foreach (var key in types.Keys) {
if (theNewType == null) { if (theNewType == null) {
theNewType = key.TypeReference; theNewType = key;
continue; continue;
} }
theNewType = getCommonBaseClass(module, theNewType, key.TypeReference); theNewType = getCommonBaseClass(module, theNewType, key);
if (theNewType == null) if (theNewType == null)
break; break;
} }
if (theNewType == null) if (theNewType == null)
return false; return false;
if (MemberReferenceHelper.compareTypes(theNewType, newType)) if (new SigComparer().Equals(theNewType, newType))
return false; return false;
newType = theNewType; newType = theNewType;
@ -226,19 +226,19 @@ namespace de4dot.code.deobfuscators {
bool deobfuscateMethods() { bool deobfuscateMethods() {
bool changed = false; bool changed = false;
foreach (var method in allMethods) { foreach (var method in allMethods) {
methodReturnInfo = new TypeInfo<Parameter>(method.MethodReturnType.Parameter2); methodReturnInfo = new TypeInfo<Parameter>(method.Parameters.ReturnParameter);
deobfuscateMethod(method); deobfuscateMethod(method);
if (methodReturnInfo.updateNewType(module)) { if (methodReturnInfo.updateNewType(module)) {
getUpdatedMethod(method).newReturnType = methodReturnInfo.newType; getUpdatedMethod(method).newReturnType = methodReturnInfo.newType;
method.MethodReturnType.ReturnType = methodReturnInfo.newType; method.MethodSig.RetType = methodReturnInfo.newType;
changed = true; changed = true;
} }
foreach (var info in argInfos.Values) { foreach (var info in argInfos.Values) {
if (info.updateNewType(module)) { if (info.updateNewType(module)) {
getUpdatedMethod(method).newArgTypes[DotNetUtils.getArgIndex(info.arg)] = info.newType; getUpdatedMethod(method).newArgTypes[info.arg.Index] = info.newType;
info.arg.ParameterType = info.newType; info.arg.Type = info.newType;
changed = true; changed = true;
} }
} }
@ -250,14 +250,14 @@ namespace de4dot.code.deobfuscators {
if (a.arg.Method.MDToken.ToInt32() < b.arg.Method.MDToken.ToInt32()) return -1; if (a.arg.Method.MDToken.ToInt32() < b.arg.Method.MDToken.ToInt32()) return -1;
if (a.arg.Method.MDToken.ToInt32() > b.arg.Method.MDToken.ToInt32()) return 1; if (a.arg.Method.MDToken.ToInt32() > b.arg.Method.MDToken.ToInt32()) return 1;
return a.arg.Sequence.CompareTo(b.arg.Sequence); return a.arg.Index.CompareTo(b.arg.Index);
} }
void deobfuscateMethod(MethodDef method) { void deobfuscateMethod(MethodDef method) {
if (!method.IsStatic || method.Body == null) if (!method.IsStatic || method.CilBody == null)
return; return;
bool fixReturnType = isUnknownType(method.MethodReturnType); bool fixReturnType = isUnknownType(method.MethodSig.RetType);
argInfos.Clear(); argInfos.Clear();
foreach (var arg in method.Parameters) { foreach (var arg in method.Parameters) {
@ -268,9 +268,9 @@ namespace de4dot.code.deobfuscators {
if (argInfos.Count == 0 && !fixReturnType) if (argInfos.Count == 0 && !fixReturnType)
return; return;
var methodParams = DotNetUtils.getParameters(method); var methodParams = method.Parameters;
PushedArgs pushedArgs; PushedArgs pushedArgs;
var instructions = method.Body.Instructions; var instructions = method.CilBody.Instructions;
for (int i = 0; i < instructions.Count; i++) { for (int i = 0; i < instructions.Count; i++) {
var instr = instructions[i]; var instr = instructions[i];
switch (instr.OpCode.Code) { switch (instr.OpCode.Code) {
@ -289,7 +289,7 @@ namespace de4dot.code.deobfuscators {
case Code.Callvirt: case Code.Callvirt:
case Code.Newobj: case Code.Newobj:
pushedArgs = MethodStack.getPushedArgInstructions(instructions, i); pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
var calledMethod = instr.Operand as MethodReference; var calledMethod = instr.Operand as IMethod;
if (calledMethod == null) if (calledMethod == null)
break; break;
var calledMethodParams = DotNetUtils.getParameters(calledMethod); var calledMethodParams = DotNetUtils.getParameters(calledMethod);
@ -316,7 +316,7 @@ namespace de4dot.code.deobfuscators {
pushedArgs = MethodStack.getPushedArgInstructions(instructions, i); pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
if (pushedArgs.NumValidArgs < 1) if (pushedArgs.NumValidArgs < 1)
break; break;
addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as TypeReference); addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as ITypeDefOrRef);
break; break;
case Code.Stloc: case Code.Stloc:
@ -328,20 +328,20 @@ namespace de4dot.code.deobfuscators {
pushedArgs = MethodStack.getPushedArgInstructions(instructions, i); pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
if (pushedArgs.NumValidArgs < 1) if (pushedArgs.NumValidArgs < 1)
break; break;
addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), DotNetUtils.getLocalVar(method.Body.Variables, instr)); addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.GetLocal(method.CilBody.LocalList));
break; break;
case Code.Stsfld: case Code.Stsfld:
pushedArgs = MethodStack.getPushedArgInstructions(instructions, i); pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
if (pushedArgs.NumValidArgs < 1) if (pushedArgs.NumValidArgs < 1)
break; break;
addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as FieldReference); addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as IField);
break; break;
case Code.Stfld: case Code.Stfld:
pushedArgs = MethodStack.getPushedArgInstructions(instructions, i); pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
if (pushedArgs.NumValidArgs >= 1) { if (pushedArgs.NumValidArgs >= 1) {
var field = instr.Operand as FieldReference; var field = instr.Operand as IField;
addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), field); addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), field);
if (pushedArgs.NumValidArgs >= 2 && field != null) if (pushedArgs.NumValidArgs >= 2 && field != null)
addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(1)), field.DeclaringType); addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(1)), field.DeclaringType);
@ -353,7 +353,7 @@ namespace de4dot.code.deobfuscators {
pushedArgs = MethodStack.getPushedArgInstructions(instructions, i); pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
if (pushedArgs.NumValidArgs < 1) if (pushedArgs.NumValidArgs < 1)
break; break;
addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as FieldReference); addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as IField);
break; break;
//TODO: For better results, these should be checked: //TODO: For better results, these should be checked:
@ -422,32 +422,36 @@ namespace de4dot.code.deobfuscators {
case Code.Ldarg_1: case Code.Ldarg_1:
case Code.Ldarg_2: case Code.Ldarg_2:
case Code.Ldarg_3: case Code.Ldarg_3:
return DotNetUtils.getParameter(parameters, instr); return instr.GetParameter(parameters);
default: default:
return null; return null;
} }
} }
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, FieldReference field) { bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, IField field) {
if (field == null) if (field == null || field.FieldSig == null)
return false; return false;
return addMethodArgType(gpp, methodParam, field.FieldType); return addMethodArgType(gpp, methodParam, field.FieldSig.Type);
} }
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, VariableDefinition otherLocal) { bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, Local otherLocal) {
if (otherLocal == null) if (otherLocal == null)
return false; return false;
return addMethodArgType(gpp, methodParam, otherLocal.VariableType); return addMethodArgType(gpp, methodParam, otherLocal.Type);
} }
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, Parameter otherParam) { bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, Parameter otherParam) {
if (otherParam == null) if (otherParam == null)
return false; return false;
return addMethodArgType(gpp, methodParam, otherParam.ParameterType); return addMethodArgType(gpp, methodParam, otherParam.Type);
} }
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, TypeReference type) { bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, ITypeDefOrRef type) {
return addMethodArgType(gpp, methodParam, type.ToTypeSig());
}
bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, TypeSig type) {
if (methodParam == null || type == null) if (methodParam == null || type == null)
return false; return false;
@ -457,7 +461,7 @@ namespace de4dot.code.deobfuscators {
TypeInfo<Parameter> info; TypeInfo<Parameter> info;
if (!argInfos.TryGetValue(methodParam, out info)) if (!argInfos.TryGetValue(methodParam, out info))
return false; return false;
if (info.Types.ContainsKey(new TypeReferenceKey(type))) if (info.Types.ContainsKey(type))
return false; return false;
info.add(type); info.add(type);
@ -469,18 +473,18 @@ namespace de4dot.code.deobfuscators {
info.clear(); info.clear();
foreach (var method in allMethods) { foreach (var method in allMethods) {
if (method.Body == null) if (method.CilBody == null)
continue; continue;
var instructions = method.Body.Instructions; var instructions = method.CilBody.Instructions;
for (int i = 0; i < instructions.Count; i++) { for (int i = 0; i < instructions.Count; i++) {
var instr = instructions[i]; var instr = instructions[i];
TypeReference fieldType = null; TypeSig fieldType = null;
TypeInfo<FieldDef> info = null; TypeInfo<FieldDef> info = null;
FieldReference field; IField field;
switch (instr.OpCode.Code) { switch (instr.OpCode.Code) {
case Code.Stfld: case Code.Stfld:
case Code.Stsfld: case Code.Stsfld:
field = instr.Operand as FieldReference; field = instr.Operand as IField;
if (field == null) if (field == null)
continue; continue;
if (!fieldWrites.TryGetValue(new FieldReferenceAndDeclaringTypeKey(field), out info)) if (!fieldWrites.TryGetValue(new FieldReferenceAndDeclaringTypeKey(field), out info))
@ -497,17 +501,17 @@ namespace de4dot.code.deobfuscators {
case Code.Callvirt: case Code.Callvirt:
case Code.Newobj: case Code.Newobj:
var pushedArgs = MethodStack.getPushedArgInstructions(instructions, i); var pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
var calledMethod = instr.Operand as MethodReference; var calledMethod = instr.Operand as IMethod;
if (calledMethod == null) if (calledMethod == null)
continue; continue;
IList<TypeReference> calledMethodArgs = DotNetUtils.getArgs(calledMethod); IList<TypeSig> calledMethodArgs = DotNetUtils.getArgs(calledMethod);
calledMethodArgs = DotNetUtils.replaceGenericParameters(calledMethod.DeclaringType as GenericInstanceType, calledMethod as GenericInstanceMethod, calledMethodArgs); calledMethodArgs = DotNetUtils.replaceGenericParameters(calledMethod.DeclaringType as GenericInstanceType, calledMethod as GenericInstanceMethod, calledMethodArgs);
for (int j = 0; j < pushedArgs.NumValidArgs; j++) { for (int j = 0; j < pushedArgs.NumValidArgs; j++) {
var pushInstr = pushedArgs.getEnd(j); var pushInstr = pushedArgs.getEnd(j);
if (pushInstr.OpCode.Code != Code.Ldfld && pushInstr.OpCode.Code != Code.Ldsfld) if (pushInstr.OpCode.Code != Code.Ldfld && pushInstr.OpCode.Code != Code.Ldsfld)
continue; continue;
field = pushInstr.Operand as FieldReference; field = pushInstr.Operand as IField;
if (field == null) if (field == null)
continue; continue;
if (!fieldWrites.TryGetValue(new FieldReferenceAndDeclaringTypeKey(field), out info)) if (!fieldWrites.TryGetValue(new FieldReferenceAndDeclaringTypeKey(field), out info))
@ -531,7 +535,7 @@ namespace de4dot.code.deobfuscators {
if (info.updateNewType(module)) { if (info.updateNewType(module)) {
removeThese.Add(info.arg); removeThese.Add(info.arg);
getUpdatedField(info.arg).newFieldType = info.newType; getUpdatedField(info.arg).newFieldType = info.newType;
info.arg.FieldType = info.newType; info.arg.FieldSig.Type = info.newType;
changed = true; changed = true;
} }
} }
@ -540,63 +544,52 @@ namespace de4dot.code.deobfuscators {
return changed; return changed;
} }
TypeReference getLoadedType(IGenericParameterProvider gpp, MethodDef method, IList<Instruction> instructions, int instrIndex, out bool wasNewobj) { TypeSig getLoadedType(IGenericParameterProvider gpp, MethodDef method, IList<Instruction> instructions, int instrIndex, out bool wasNewobj) {
var fieldType = MethodStack.getLoadedType(method, instructions, instrIndex, out wasNewobj); var fieldType = MethodStack.getLoadedType(method, instructions, instrIndex, out wasNewobj);
if (fieldType == null || !isValidType(gpp, fieldType)) if (fieldType == null || !isValidType(gpp, fieldType))
return null; return null;
return fieldType; return fieldType;
} }
protected virtual bool isValidType(IGenericParameterProvider gpp, TypeReference type) { protected virtual bool isValidType(IGenericParameterProvider gpp, TypeSig type) {
if (type == null) if (type == null)
return false; return false;
if (type.EType == ElementType.Void) if (type.ElementType == ElementType.Void)
return false; return false;
while (type != null) { while (type != null) {
switch (MemberReferenceHelper.getMemberReferenceType(type)) { switch (type.ElementType) {
case CecilType.GenericInstanceType: case ElementType.GenericInst:
foreach (var ga in ((GenericInstanceType)type).GenericArguments) { foreach (var ga in ((GenericInstSig)type).GenericArguments) {
if (!isValidType(gpp, ga)) if (!isValidType(gpp, ga))
return false; return false;
} }
break; break;
case CecilType.ArrayType: case ElementType.SZArray:
case CecilType.PointerType: case ElementType.Array:
case CecilType.TypeDefinition: case ElementType.Ptr:
case CecilType.TypeReference: case ElementType.Class:
case ElementType.ValueType:
break; break;
case CecilType.GenericParameter: case ElementType.Var:
var gp = (GenericParameter)type; case ElementType.MVar:
var methodRef = gpp as MethodReference; // TODO: Return false for now. We don't know whether the Var is a Var in
var typeRef = gpp as TypeReference; // this type or from some other type.
if (methodRef != null) { return false;
if (methodRef.DeclaringType != gp.Owner && methodRef != gp.Owner)
return false;
}
else if (typeRef != null) {
if (typeRef != gp.Owner)
return false;
}
else
return false;
break;
case CecilType.ByReferenceType: case ElementType.ByRef:
case CecilType.FunctionPointerType: case ElementType.FnPtr:
case CecilType.OptionalModifierType: case ElementType.CModOpt:
case CecilType.PinnedType: case ElementType.CModReqd:
case CecilType.RequiredModifierType: case ElementType.Pinned:
case CecilType.SentinelType: case ElementType.Sentinel:
default: default:
return false; return false;
} }
if (!(type is TypeSpecification)) type = type.Next;
break;
type = ((TypeSpecification)type).ElementType;
} }
return type != null; return type != null;
@ -604,10 +597,10 @@ namespace de4dot.code.deobfuscators {
protected abstract bool isUnknownType(object o); protected abstract bool isUnknownType(object o);
static TypeReference getCommonBaseClass(ModuleDef module, TypeReference a, TypeReference b) { static TypeSig getCommonBaseClass(ModuleDef module, TypeSig a, TypeSig b) {
if (DotNetUtils.isDelegate(a) && DotNetUtils.derivesFromDelegate(DotNetUtils.getType(module, b))) if (DotNetUtils.isDelegate(a) && DotNetUtils.derivesFromDelegate(module.Find(b.ToTypeDefOrRef())))
return b; return b;
if (DotNetUtils.isDelegate(b) && DotNetUtils.derivesFromDelegate(DotNetUtils.getType(module, a))) if (DotNetUtils.isDelegate(b) && DotNetUtils.derivesFromDelegate(module.Find(a.ToTypeDefOrRef())))
return a; return a;
return null; //TODO: return null; //TODO:
} }
@ -618,12 +611,12 @@ namespace de4dot.code.deobfuscators {
: base(module) { : base(module) {
} }
protected override bool isValidType(IGenericParameterProvider gpp, TypeReference type) { protected override bool isValidType(IGenericParameterProvider gpp, TypeSig type) {
if (type == null) if (type == null)
return false; return false;
if (type.IsValueType) if (type.ElementType == ElementType.ValueType)
return false; return false;
if (MemberReferenceHelper.isSystemObject(type)) if (type.ElementType == ElementType.Object)
return false; return false;
return base.isValidType(gpp, type); return base.isValidType(gpp, type);
} }
@ -631,15 +624,11 @@ namespace de4dot.code.deobfuscators {
protected override bool isUnknownType(object o) { protected override bool isUnknownType(object o) {
var arg = o as Parameter; var arg = o as Parameter;
if (arg != null) if (arg != null)
return MemberReferenceHelper.isSystemObject(arg.ParameterType); return arg.Type != null && arg.Type.ElementType == ElementType.Object;
var field = o as FieldDef; var field = o as FieldDef;
if (field != null) if (field != null)
return MemberReferenceHelper.isSystemObject(field.FieldType); return field.FieldSig != null && field.FieldSig.Type != null && field.FieldSig.Type.ElementType == ElementType.Object;
var retType = o as MethodReturnType;
if (retType != null)
return MemberReferenceHelper.isSystemObject(retType.ReturnType);
throw new ApplicationException(string.Format("Unknown type: {0}", o.GetType())); throw new ApplicationException(string.Format("Unknown type: {0}", o.GetType()));
} }

View File

@ -86,15 +86,16 @@ namespace de4dot.code.deobfuscators.Unknown {
string scanTypes() { string scanTypes() {
foreach (var type in module.Types) { foreach (var type in module.Types) {
if (type.FullName == "ConfusedByAttribute") var fn = type.FullName;
if (fn == "ConfusedByAttribute")
return "Confuser"; return "Confuser";
if (type.FullName == "ZYXDNGuarder") if (fn == "ZYXDNGuarder")
return "DNGuard HVM"; return "DNGuard HVM";
if (type.Name.Contains("();\t")) if (type.Name.String.Contains("();\t"))
return "Manco .NET Obfuscator"; return "Manco .NET Obfuscator";
if (Regex.IsMatch(type.FullName, @"^EMyPID_\d+_$")) if (Regex.IsMatch(fn, @"^EMyPID_\d+_$"))
return "BitHelmet Obfuscator"; return "BitHelmet Obfuscator";
if (type.FullName == "YanoAttribute") if (fn == "YanoAttribute")
return "Yano Obfuscator"; return "Yano Obfuscator";
} }
return null; return null;

View File

@ -22,15 +22,16 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Formatters.Binary;
using Mono.Cecil; using dot10.DotNet;
using dot10.DotNet.MD;
namespace de4dot.code.resources { namespace de4dot.code.resources {
class ResourceDataCreator { class ResourceDataCreator {
ModuleDefinition module; ModuleDefMD module;
Dictionary<string, UserResourceType> dict = new Dictionary<string, UserResourceType>(StringComparer.Ordinal); Dictionary<string, UserResourceType> dict = new Dictionary<string, UserResourceType>(StringComparer.Ordinal);
Dictionary<string, string> asmNameToAsmFullName = new Dictionary<string, string>(StringComparer.Ordinal); Dictionary<string, string> asmNameToAsmFullName = new Dictionary<string, string>(StringComparer.Ordinal);
public ResourceDataCreator(ModuleDefinition module) { public ResourceDataCreator(ModuleDefMD module) {
this.module = module; this.module = module;
} }
@ -210,19 +211,14 @@ namespace de4dot.code.resources {
string tryGetRealAssemblyName(string assemblyName) { string tryGetRealAssemblyName(string assemblyName) {
var simpleName = Utils.getAssemblySimpleName(assemblyName); var simpleName = Utils.getAssemblySimpleName(assemblyName);
foreach (var asmRef in module.AssemblyReferences) { var name = new UTF8String(simpleName);
if (asmRef.Name == simpleName) foreach (var asmRef in module.GetAssemblyRefs()) {
if (asmRef.Name == name)
return asmRef.FullName; return asmRef.FullName;
} }
try { var asm = AssemblyResolver.Instance.Resolve(new AssemblyNameInfo(simpleName), module);
return AssemblyResolver.Instance.Resolve(simpleName).FullName; return asm == null ? null : asm.FullName;
}
catch (ResolutionException) {
}
catch (AssemblyResolutionException) {
}
return null;
} }
public List<UserResourceType> getSortedTypes() { public List<UserResourceType> getSortedTypes() {

View File

@ -22,7 +22,7 @@ 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;
namespace de4dot.code.resources { namespace de4dot.code.resources {
[Serializable] [Serializable]
@ -33,17 +33,17 @@ namespace de4dot.code.resources {
} }
class ResourceReader { class ResourceReader {
ModuleDefinition module; ModuleDefMD module;
BinaryReader reader; BinaryReader reader;
ResourceDataCreator resourceDataCreator; ResourceDataCreator resourceDataCreator;
ResourceReader(ModuleDefinition module, Stream stream) { ResourceReader(ModuleDefMD module, Stream stream) {
this.module = module; this.module = module;
this.reader = new BinaryReader(stream); this.reader = new BinaryReader(stream);
this.resourceDataCreator = new ResourceDataCreator(module); this.resourceDataCreator = new ResourceDataCreator(module);
} }
public static ResourceElementSet read(ModuleDefinition module, Stream stream) { public static ResourceElementSet read(ModuleDefMD module, Stream stream) {
return new ResourceReader(module, stream).read(); return new ResourceReader(module, stream).read();
} }

View File

@ -23,24 +23,24 @@ using System.IO;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Formatters.Binary;
using System.Text; using System.Text;
using Mono.Cecil; using dot10.DotNet;
namespace de4dot.code.resources { namespace de4dot.code.resources {
class ResourceWriter { class ResourceWriter {
ModuleDefinition module; ModuleDefMD module;
BinaryWriter writer; BinaryWriter writer;
ResourceElementSet resources; ResourceElementSet resources;
ResourceDataCreator typeCreator; ResourceDataCreator typeCreator;
Dictionary<UserResourceData, UserResourceType> dataToNewType = new Dictionary<UserResourceData, UserResourceType>(); Dictionary<UserResourceData, UserResourceType> dataToNewType = new Dictionary<UserResourceData, UserResourceType>();
ResourceWriter(ModuleDefinition module, Stream stream, ResourceElementSet resources) { ResourceWriter(ModuleDefMD module, Stream stream, ResourceElementSet resources) {
this.module = module; this.module = module;
this.typeCreator = new ResourceDataCreator(module); this.typeCreator = new ResourceDataCreator(module);
this.writer = new BinaryWriter(stream); this.writer = new BinaryWriter(stream);
this.resources = resources; this.resources = resources;
} }
public static void write(ModuleDefinition module, Stream stream, ResourceElementSet resources) { public static void write(ModuleDefMD module, Stream stream, ResourceElementSet resources) {
new ResourceWriter(module, stream, resources).write(); new ResourceWriter(module, stream, resources).write();
} }
@ -138,8 +138,8 @@ namespace de4dot.code.resources {
} }
string getMscorlibFullname() { string getMscorlibFullname() {
AssemblyNameReference mscorlibRef = null; AssemblyRef mscorlibRef = null;
foreach (var asmRef in module.AssemblyReferences) { foreach (var asmRef in module.GetAssemblyRefs()) {
if (asmRef.Name != "mscorlib") if (asmRef.Name != "mscorlib")
continue; continue;
if (mscorlibRef == null || mscorlibRef.Version == null || (asmRef.Version != null && asmRef.Version >= mscorlibRef.Version)) if (mscorlibRef == null || mscorlibRef.Version == null || (asmRef.Version != null && asmRef.Version >= mscorlibRef.Version))

2
dot10

@ -1 +1 @@
Subproject commit 3b128874ff6bd531f588c487e9aeb76fb62acfec Subproject commit 4030f90eb8d1a71793dfd1772efc7b5e5513dff4