Port more code

This commit is contained in:
de4dot 2012-11-01 16:42:02 +01:00
parent 3b6ef4fa1f
commit 1341cc7199
27 changed files with 223 additions and 511 deletions

View File

@ -933,11 +933,11 @@ namespace de4dot.blocks {
return args; return args;
} }
public static List<DN.IType> getArgs(DN.IMethod method) { public static List<DN.TypeSig> getArgs(DN.IMethod method) {
var sig = method.MethodSig; var sig = method.MethodSig;
var args = new List<DN.IType>(sig.Params.Count + 1); var args = new List<DN.TypeSig>(sig.Params.Count + 1);
if (sig.HasThis && !sig.ExplicitThis) if (sig.ImplicitThis)
args.Add(method.DeclaringType); args.Add(DN.Extensions.ToTypeSig(method.DeclaringType));
foreach (var arg in sig.Params) foreach (var arg in sig.Params)
args.Add(arg); args.Add(arg);
return args; return args;
@ -969,7 +969,7 @@ namespace de4dot.blocks {
if (sig == null) if (sig == null)
return 0; return 0;
int count = sig.Params.Count; int count = sig.Params.Count;
if (sig.HasThis && !sig.ExplicitThis) if (sig.ImplicitThis)
count++; count++;
return count; return count;
} }

View File

@ -198,7 +198,7 @@ namespace de4dot.blocks.cflow {
protected bool checkSameMethods(IMethod method, MethodDef methodToInline, int ignoreLastMethodToInlineArgs) { protected bool checkSameMethods(IMethod method, MethodDef methodToInline, int ignoreLastMethodToInlineArgs) {
var methodToInlineArgs = methodToInline.Parameters; var methodToInlineArgs = methodToInline.Parameters;
var methodArgs = DotNetUtils.getArgs(method); var methodArgs = DotNetUtils.getArgs(method);
bool hasImplicitThis = method.MethodSig.HasThis && !method.MethodSig.ExplicitThis; bool hasImplicitThis = method.MethodSig.ImplicitThis;
if (methodToInlineArgs.Length - ignoreLastMethodToInlineArgs != methodArgs.Count) if (methodToInlineArgs.Length - ignoreLastMethodToInlineArgs != methodArgs.Count)
return false; return false;
for (int i = 0; i < methodArgs.Count; i++) { for (int i = 0; i < methodArgs.Count; i++) {

View File

@ -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 { namespace de4dot.code {
@ -48,6 +48,7 @@ namespace de4dot.code {
dataDict.Remove(name); dataDict.Remove(name);
} }
#if PORT
static TypeReference getNonGenericTypeReference(TypeReference typeReference) { static TypeReference getNonGenericTypeReference(TypeReference typeReference) {
if (typeReference == null) if (typeReference == null)
return null; return null;
@ -104,5 +105,6 @@ namespace de4dot.code {
return null; return null;
} }
#endif
} }
} }

View File

@ -19,20 +19,20 @@
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 { namespace de4dot.code {
class ExternalAssembly { class ExternalAssembly {
AssemblyDefinition asmDef; AssemblyDef asmDef;
public ExternalAssembly(AssemblyDefinition asmDef) { public ExternalAssembly(AssemblyDef asmDef) {
this.asmDef = asmDef; this.asmDef = asmDef;
} }
public TypeDefinition resolve(TypeReference type) { public TypeDef resolve(ITypeDefOrRef type) {
foreach (var module in asmDef.Modules) { foreach (var module in asmDef.Modules) {
var typeDef = DotNetUtils.getType(module, type); var typeDef = module.Find(type);
if (typeDef != null) if (typeDef != null)
return typeDef; return typeDef;
} }
@ -42,7 +42,7 @@ namespace de4dot.code {
public void unload(string asmFullName) { public void unload(string asmFullName) {
foreach (var module in asmDef.Modules) { foreach (var module in asmDef.Modules) {
DotNetUtils.typeCaches.invalidate(module); //TODO: DotNetUtils.typeCaches.invalidate(module);
AssemblyResolver.Instance.removeModule(module); AssemblyResolver.Instance.removeModule(module);
} }
AssemblyResolver.Instance.removeModule(asmFullName); AssemblyResolver.Instance.removeModule(asmFullName);
@ -54,45 +54,38 @@ namespace de4dot.code {
Dictionary<string, ExternalAssembly> assemblies = new Dictionary<string, ExternalAssembly>(StringComparer.Ordinal); Dictionary<string, ExternalAssembly> assemblies = new Dictionary<string, ExternalAssembly>(StringComparer.Ordinal);
Dictionary<string, bool> failedLoads = new Dictionary<string, bool>(StringComparer.Ordinal); Dictionary<string, bool> failedLoads = new Dictionary<string, bool>(StringComparer.Ordinal);
ExternalAssembly load(TypeReference type) { ExternalAssembly load(TypeRef type) {
var asmFullName = DotNetUtils.getFullAssemblyName(type); if (type == null || type.DefinitionAssembly == null)
if (asmFullName == null)
return null; return null;
var asmFullName = type.DefinitionAssembly.FullName;
ExternalAssembly asm; ExternalAssembly asm;
if (assemblies.TryGetValue(asmFullName, out asm)) if (assemblies.TryGetValue(asmFullName, out asm))
return asm; return asm;
AssemblyDefinition asmDef = null; var asmDef = AssemblyResolver.Instance.Resolve(type.DefinitionAssembly, type.OwnerModule);
try {
asmDef = AssemblyResolver.Instance.Resolve(asmFullName);
}
catch (ResolutionException) {
}
catch (AssemblyResolutionException) {
}
if (asmDef == null) { if (asmDef == null) {
if (!failedLoads.ContainsKey(asmFullName)) if (!failedLoads.ContainsKey(asmFullName))
Log.w("Could not load assembly {0}", asmFullName); Log.w("Could not load assembly {0}", asmFullName);
failedLoads[asmFullName] = true; failedLoads[asmFullName] = true;
return null; return null;
} }
if (assemblies.ContainsKey(asmDef.Name.FullName)) { if (assemblies.ContainsKey(asmDef.FullName)) {
assemblies[asmFullName] = assemblies[asmDef.Name.FullName]; assemblies[asmFullName] = assemblies[asmDef.FullName];
return assemblies[asmDef.Name.FullName]; return assemblies[asmDef.FullName];
} }
if (asmFullName == asmDef.Name.FullName) if (asmFullName == asmDef.FullName)
Log.v("Loaded assembly {0}", asmFullName); Log.v("Loaded assembly {0}", asmFullName);
else else
Log.v("Loaded assembly {0} (but wanted {1})", asmDef.Name.FullName, asmFullName); Log.v("Loaded assembly {0} (but wanted {1})", asmDef.FullName, asmFullName);
asm = new ExternalAssembly(asmDef); asm = new ExternalAssembly(asmDef);
assemblies[asmFullName] = asm; assemblies[asmFullName] = asm;
assemblies[asmDef.Name.FullName] = asm; assemblies[asmDef.FullName] = asm;
return asm; return asm;
} }
public TypeDefinition resolve(TypeReference type) { public TypeDef resolve(TypeRef type) {
if (type == null) if (type == null)
return null; return null;
var asm = load(type); var asm = load(type);

View File

@ -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 { namespace de4dot.code {
public interface IDeobfuscatorContext { public interface IDeobfuscatorContext {
@ -25,8 +25,10 @@ namespace de4dot.code {
void setData(string name, object data); void setData(string name, object data);
object getData(string name); object getData(string name);
void clearData(string name); void clearData(string name);
TypeDefinition resolve(TypeReference type); #if PORT
MethodDefinition resolve(MethodReference method); TypeDef resolve(TypeRef type);
FieldDefinition resolve(FieldReference field); MethodDef resolve(IMethod method);
FieldDef resolve(IField field);
#endif
} }
} }

View File

@ -19,8 +19,8 @@
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 { namespace de4dot.code {
@ -83,7 +83,7 @@ namespace de4dot.code {
} }
var sortedTargets = new List<Instruction>(targets.Keys); var sortedTargets = new List<Instruction>(targets.Keys);
sortedTargets.Sort((a, b) => Utils.compareInt32(a.Offset, b.Offset)); sortedTargets.Sort((a, b) => a.Offset.CompareTo(b.Offset));
for (int i = 0; i < sortedTargets.Count; i++) for (int i = 0; i < sortedTargets.Count; i++)
labels[sortedTargets[i]] = string.Format("label_{0}", i); labels[sortedTargets[i]] = string.Format("label_{0}", i);
} }
@ -131,13 +131,13 @@ namespace de4dot.code {
ExInfo exInfo; ExInfo exInfo;
if (exInfos.TryGetValue(instr, out exInfo)) if (exInfos.TryGetValue(instr, out exInfo))
printExInfo(exInfo); printExInfo(exInfo);
var instrString = instr.GetOpCodeString(); var instrString = instr.OpCode.Name;
var operandString = getOperandString(instr); var operandString = getOperandString(instr);
var memberReference = instr.Operand as MemberReference; var memberReference = instr.Operand as ITokenOperand;
if (operandString == "") if (operandString == "")
Log.log(logLevel, "{0}", instrString); Log.log(logLevel, "{0}", instrString);
else if (memberReference != null) else if (memberReference != null)
Log.log(logLevel, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberReference.MetadataToken.ToUInt32()); Log.log(logLevel, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberReference.MDToken.ToUInt32());
else else
Log.log(logLevel, "{0,-9} {1}", instrString, Utils.removeNewlines(operandString)); Log.log(logLevel, "{0,-9} {1}", instrString, Utils.removeNewlines(operandString));
} }
@ -160,12 +160,12 @@ namespace de4dot.code {
} }
else if (instr.Operand is string) else if (instr.Operand is string)
return Utils.toCsharpString((string)instr.Operand); return Utils.toCsharpString((string)instr.Operand);
else if (instr.Operand is ParameterDefinition) { else if (instr.Operand is Parameter) {
var arg = (ParameterDefinition)instr.Operand; var arg = (Parameter)instr.Operand;
var s = instr.GetOperandString(); var s = instr.GetOperandString();
if (s != "") if (s != "")
return s; return s;
return string.Format("<arg_{0}>", DotNetUtils.getArgIndex(arg)); return string.Format("<arg_{0}>", arg.Index);
} }
else else
return instr.GetOperandString(); return instr.GetOperandString();

View File

@ -19,17 +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 Mono.Cecil.Metadata;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code { namespace de4dot.code {
// A simple class that statically detects the values of some local variables // A simple class that statically detects the values of some local variables
class VariableValues { class VariableValues {
IList<Block> allBlocks; IList<Block> allBlocks;
IList<VariableDefinition> locals; IList<Local> locals;
Dictionary<VariableDefinition, Variable> variableToValue = new Dictionary<VariableDefinition, Variable>(); Dictionary<Local, Variable> variableToValue = new Dictionary<Local, Variable>();
public class Variable { public class Variable {
int writes = 0; int writes = 0;
@ -58,7 +57,7 @@ namespace de4dot.code {
} }
} }
public VariableValues(IList<VariableDefinition> locals, IList<Block> allBlocks) { public VariableValues(IList<Local> locals, IList<Block> allBlocks) {
this.locals = locals; this.locals = locals;
this.allBlocks = allBlocks; this.allBlocks = allBlocks;
init(); init();
@ -136,7 +135,7 @@ namespace de4dot.code {
} }
} }
public Variable getValue(VariableDefinition variable) { public Variable getValue(Local variable) {
return variableToValue[variable]; return variableToValue[variable];
} }
} }
@ -144,7 +143,7 @@ namespace de4dot.code {
abstract class MethodReturnValueInliner { abstract class MethodReturnValueInliner {
protected List<CallResult> callResults; protected List<CallResult> callResults;
List<Block> allBlocks; List<Block> allBlocks;
MethodDefinition theMethod; MethodDef theMethod;
VariableValues variableValues; VariableValues variableValues;
int errors = 0; int errors = 0;
bool useUnknownArgs = false; bool useUnknownArgs = false;
@ -166,8 +165,8 @@ namespace de4dot.code {
this.callEndIndex = callEndIndex; this.callEndIndex = callEndIndex;
} }
public MethodReference getMethodReference() { public IMethod getMethodReference() {
return (MethodReference)block.Instructions[callEndIndex].Operand; return (IMethod)block.Instructions[callEndIndex].Operand;
} }
} }
@ -177,14 +176,14 @@ namespace de4dot.code {
public abstract bool HasHandlers { get; } public abstract bool HasHandlers { get; }
public MethodDefinition Method { public MethodDef Method {
get { return theMethod; } get { return theMethod; }
} }
protected abstract void inlineAllCalls(); protected abstract void inlineAllCalls();
// Returns null if method is not a method we should inline // Returns null if method is not a method we should inline
protected abstract CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex); protected abstract CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex);
public int decrypt(Blocks blocks) { public int decrypt(Blocks blocks) {
if (!HasHandlers) if (!HasHandlers)
@ -192,7 +191,7 @@ namespace de4dot.code {
return decrypt(blocks.Method, blocks.MethodBlocks.getAllBlocks()); return decrypt(blocks.Method, blocks.MethodBlocks.getAllBlocks());
} }
public int decrypt(MethodDefinition method, List<Block> allBlocks) { public int decrypt(MethodDef method, List<Block> allBlocks) {
if (!HasHandlers) if (!HasHandlers)
return 0; return 0;
try { try {
@ -217,9 +216,9 @@ namespace de4dot.code {
} }
} }
bool getLocalVariableValue(VariableDefinition variable, out object value) { bool getLocalVariableValue(Local variable, out object value) {
if (variableValues == null) if (variableValues == null)
variableValues = new VariableValues(theMethod.Body.Variables, allBlocks); variableValues = new VariableValues(theMethod.CilBody.LocalList, allBlocks);
var val = variableValues.getValue(variable); var val = variableValues.getValue(variable);
if (!val.isValid()) { if (!val.isValid()) {
value = null; value = null;
@ -239,14 +238,14 @@ namespace de4dot.code {
var instr = block.Instructions[i]; var instr = block.Instructions[i];
if (instr.OpCode != OpCodes.Call) if (instr.OpCode != OpCodes.Call)
continue; continue;
var method = instr.Operand as MethodReference; var method = instr.Operand as IMethod;
if (method == null) if (method == null)
continue; continue;
MethodReference elementMethod = method; IMethod elementMethod = method;
var gim = method as GenericInstanceMethod; var gim = method as MethodSpec;
if (gim != null) if (gim != null)
elementMethod = gim.ElementMethod; elementMethod = gim.Method;
var callResult = createCallResult(elementMethod, gim, block, i); var callResult = createCallResult(elementMethod, gim, block, i);
if (callResult == null) if (callResult == null)
continue; continue;
@ -259,7 +258,7 @@ namespace de4dot.code {
bool findArgs(CallResult callResult) { bool findArgs(CallResult callResult) {
var block = callResult.block; var block = callResult.block;
var method = callResult.getMethodReference(); var method = callResult.getMethodReference();
var methodArgs = DotNetUtils.getParameters(method); var methodArgs = DotNetUtils.getArgs(method);
int numArgs = methodArgs.Count; int numArgs = methodArgs.Count;
var args = new object[numArgs]; var args = new object[numArgs];
@ -269,9 +268,9 @@ namespace de4dot.code {
if (!getArg(method, block, ref arg, ref instrIndex)) if (!getArg(method, block, ref arg, ref instrIndex))
return false; return false;
if (arg is int) if (arg is int)
arg = fixIntArg(methodArgs[i].ParameterType, (int)arg); arg = fixIntArg(methodArgs[i], (int)arg);
else if (arg is long) else if (arg is long)
arg = fixIntArg(methodArgs[i].ParameterType, (long)arg); arg = fixIntArg(methodArgs[i], (long)arg);
args[i] = arg; args[i] = arg;
} }
@ -280,8 +279,8 @@ namespace de4dot.code {
return true; return true;
} }
object fixIntArg(TypeReference type, long value) { object fixIntArg(TypeSig type, long value) {
switch (type.EType) { switch (type.ElementType) {
case ElementType.Boolean: return value != 0; case ElementType.Boolean: return value != 0;
case ElementType.Char: return (char)value; case ElementType.Char: return (char)value;
case ElementType.I1: return (sbyte)value; case ElementType.I1: return (sbyte)value;
@ -296,7 +295,7 @@ namespace de4dot.code {
throw new ApplicationException(string.Format("Wrong type {0}", type)); throw new ApplicationException(string.Format("Wrong type {0}", type));
} }
bool getArg(MethodReference method, Block block, ref object arg, ref int instrIndex) { bool getArg(IMethod method, Block block, ref object arg, ref int instrIndex) {
while (true) { while (true) {
if (instrIndex < 0) { if (instrIndex < 0) {
// We're here if there were no cflow deobfuscation, or if there are two or // We're here if there were no cflow deobfuscation, or if there are two or
@ -304,7 +303,7 @@ namespace de4dot.code {
// merged because one is outside the exception handler (eg. buggy obfuscator). // merged because one is outside the exception handler (eg. buggy obfuscator).
Log.w("Could not find all arguments to method {0} ({1:X8})", Log.w("Could not find all arguments to method {0} ({1:X8})",
Utils.removeNewlines(method), Utils.removeNewlines(method),
method.MetadataToken.ToInt32()); method.MDToken.ToInt32());
errors++; errors++;
return false; return false;
} }
@ -343,7 +342,7 @@ namespace de4dot.code {
case Code.Ldloc_1: case Code.Ldloc_1:
case Code.Ldloc_2: case Code.Ldloc_2:
case Code.Ldloc_3: case Code.Ldloc_3:
getLocalVariableValue(Instr.getLocalVar(theMethod.Body.Variables, instr), out arg); getLocalVariableValue(instr.Instruction.GetLocal(theMethod.CilBody.LocalList), out arg);
break; break;
case Code.Ldfld: case Code.Ldfld:
@ -353,11 +352,11 @@ namespace de4dot.code {
default: default:
int pushes, pops; int pushes, pops;
DotNetUtils.calculateStackUsage(instr.Instruction, false, out pushes, out pops); instr.Instruction.CalculateStackUsage(false, out pushes, out pops);
if (!useUnknownArgs || pushes != 1) { if (!useUnknownArgs || pushes != 1) {
Log.w("Could not find all arguments to method {0} ({1:X8}), instr: {2}", Log.w("Could not find all arguments to method {0} ({1:X8}), instr: {2}",
Utils.removeNewlines(method), Utils.removeNewlines(method),
method.MetadataToken.ToInt32(), method.MDToken.ToInt32(),
instr); instr);
errors++; errors++;
return false; return false;
@ -381,10 +380,10 @@ namespace de4dot.code {
callResults.Sort((a, b) => { callResults.Sort((a, b) => {
int i1 = allBlocks.FindIndex((x) => a.block == x); int i1 = allBlocks.FindIndex((x) => a.block == x);
int i2 = allBlocks.FindIndex((x) => b.block == x); int i2 = allBlocks.FindIndex((x) => b.block == x);
if (i1 < i2) return -1; if (i1 != i2)
if (i1 > i2) return 1; return i1.CompareTo(i2);
return Utils.compareInt32(a.callStartIndex, b.callStartIndex); return a.callStartIndex.CompareTo(b.callStartIndex);
}); });
callResults.Reverse(); callResults.Reverse();
inlineReturnValues(callResults); inlineReturnValues(callResults);

View File

@ -432,26 +432,28 @@ namespace de4dot.code {
if (typeString != null && typeString != type.FullName) if (typeString != null && typeString != type.FullName)
continue; continue;
foreach (var method in type.Methods) { foreach (var method in type.Methods) {
if (!method.IsStatic || method.MethodReturnType.ReturnType.FullName != "System.String") if (!method.IsStatic)
continue;
if (method.MethodSig.RetType.ElementType != ElementType.String && method.MethodSig.RetType.ElementType != ElementType.Object)
continue; continue;
if (methodName != null && methodName != method.Name) if (methodName != null && methodName != method.Name)
continue; continue;
if (argsStrings == null) { if (argsStrings == null) {
if (method.Parameters.Count == 0) if (method.Parameters.Length == 0)
continue; continue;
} }
else { else {
if (argsStrings.Length != method.Parameters.Count) if (argsStrings.Length != method.Parameters.Length)
continue; continue;
for (int i = 0; i < argsStrings.Length; i++) { for (int i = 0; i < argsStrings.Length; i++) {
if (argsStrings[i] != method.Parameters[i].ParameterType.FullName) if (argsStrings[i] != method.Parameters[i].Type.FullName)
continue; continue;
} }
} }
Log.v("Adding string decrypter; token: {0:X8}, method: {1}", method.MetadataToken.ToInt32(), Utils.removeNewlines(method.FullName)); Log.v("Adding string decrypter; token: {0:X8}, method: {1}", method.MDToken.ToInt32(), Utils.removeNewlines(method.FullName));
tokens.Add(method.MetadataToken.ToInt32()); tokens.Add(method.MDToken.ToInt32());
} }
} }
@ -530,30 +532,26 @@ namespace de4dot.code {
Log.v("Deobfuscating methods"); Log.v("Deobfuscating methods");
var methodPrinter = new MethodPrinter(); var methodPrinter = new MethodPrinter();
#if PORT
var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators); var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators);
#endif
foreach (var method in getAllMethods()) { foreach (var method in getAllMethods()) {
Log.v("Deobfuscating {0} ({1:X8})", Utils.removeNewlines(method), method.MetadataToken.ToUInt32()); Log.v("Deobfuscating {0} ({1:X8})", Utils.removeNewlines(method), method.MDToken.ToUInt32());
Log.indent(); Log.indent();
int oldIndentLevel = Log.indentLevel; int oldIndentLevel = Log.indentLevel;
try { try {
#if PORT
deobfuscate(method, cflowDeobfuscator, methodPrinter); deobfuscate(method, cflowDeobfuscator, methodPrinter);
#endif
} }
catch (ApplicationException) { catch (ApplicationException) {
throw; throw;
} }
catch (Exception ex) { catch (Exception ex) {
if (!canLoadMethodBody(method)) { if (!canLoadMethodBody(method)) {
Log.v("Invalid method body. {0:X8}", method.MetadataToken.ToInt32()); Log.v("Invalid method body. {0:X8}", method.MDToken.ToInt32());
method.CilBody = new MethodBody(method); method.CilBody = new CilBody();
} }
else { else {
Log.w("Could not deobfuscate method {0:X8}. Hello, E.T.: {1}", // E.T. = exception type Log.w("Could not deobfuscate method {0:X8}. Hello, E.T.: {1}", // E.T. = exception type
method.MetadataToken.ToInt32(), method.MDToken.ToInt32(),
ex.GetType()); ex.GetType());
} }
} }
@ -576,7 +574,6 @@ namespace de4dot.code {
} }
} }
#if PORT
void deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter) { void deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter) {
if (!hasNonEmptyBody(method)) if (!hasNonEmptyBody(method))
return; return;
@ -621,10 +618,9 @@ namespace de4dot.code {
Log.deIndent(); Log.deIndent();
} }
} }
#endif
bool hasNonEmptyBody(MethodDef method) { bool hasNonEmptyBody(MethodDef method) {
return method.HasBody && method.CilBody.Instructions.Count > 0; return method.HasCilBody && method.CilBody.Instructions.Count > 0;
} }
void deobfuscateStrings(Blocks blocks) { void deobfuscateStrings(Blocks blocks) {
@ -647,10 +643,10 @@ namespace de4dot.code {
} }
void removeNoInliningAttribute(MethodDef method) { void removeNoInliningAttribute(MethodDef method) {
method.ImplAttributes = method.ImplAttributes & ~MethodImplAttributes.NoInlining; method.IsNoInlining = false;
for (int i = 0; i < method.CustomAttributes.Count; i++) { for (int i = 0; i < method.CustomAttributes.Count; i++) {
var cattr = method.CustomAttributes[i]; var cattr = method.CustomAttributes[i];
if (cattr.AttributeType.FullName != "System.Runtime.CompilerServices.MethodImplAttribute") if (cattr.TypeFullName != "System.Runtime.CompilerServices.MethodImplAttribute")
continue; continue;
int options = 0; int options = 0;
if (!getMethodImplOptions(cattr, ref options)) if (!getMethodImplOptions(cattr, ref options))
@ -663,13 +659,13 @@ namespace de4dot.code {
} }
static bool getMethodImplOptions(CustomAttribute cattr, ref int value) { static bool getMethodImplOptions(CustomAttribute cattr, ref int value) {
if (cattr.ConstructorArguments.Count != 1) if (cattr.Arguments.Count != 1)
return false; return false;
if (cattr.ConstructorArguments[0].Type.FullName != "System.Int16" && if (cattr.Arguments[0].Type.ElementType != ElementType.I2 &&
cattr.ConstructorArguments[0].Type.FullName != "System.Runtime.CompilerServices.MethodImplOptions") cattr.Arguments[0].Type.FullName != "System.Runtime.CompilerServices.MethodImplOptions")
return false; return false;
var arg = cattr.ConstructorArguments[0].Value; var arg = cattr.Arguments[0].Value;
if (arg is short) { if (arg is short) {
value = (short)arg; value = (short)arg;
return true; return true;
@ -704,7 +700,7 @@ namespace de4dot.code {
if (savedMethodBodies != null) if (savedMethodBodies != null)
savedMethodBodies.save(method); savedMethodBodies.save(method);
Log.v("{0}: {1} ({2:X8})", msg, Utils.removeNewlines(method), method.MetadataToken.ToUInt32()); Log.v("{0}: {1} ({2:X8})", msg, Utils.removeNewlines(method), method.MDToken.ToUInt32());
Log.indent(); Log.indent();
if (hasNonEmptyBody(method)) { if (hasNonEmptyBody(method)) {
@ -719,7 +715,7 @@ namespace de4dot.code {
DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers); DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
} }
catch { catch {
Log.v("Could not deobfuscate {0:X8}", method.MetadataToken.ToInt32()); Log.v("Could not deobfuscate {0:X8}", method.MDToken.ToInt32());
} }
} }

View File

@ -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.code.AssemblyClient; using de4dot.code.AssemblyClient;
using de4dot.blocks; using de4dot.blocks;
@ -49,7 +49,7 @@ namespace de4dot.code {
if (ldstrIndex + 1 < block.Instructions.Count) { if (ldstrIndex + 1 < block.Instructions.Count) {
var instr = block.Instructions[ldstrIndex + 1]; var instr = block.Instructions[ldstrIndex + 1];
if (instr.OpCode.Code == Code.Call) { if (instr.OpCode.Code == Code.Call) {
var calledMethod = instr.Operand as MethodReference; var calledMethod = instr.Operand as IMethod;
if (calledMethod != null && if (calledMethod != null &&
calledMethod.FullName == "System.String System.String::Intern(System.String)") { calledMethod.FullName == "System.String System.String::Intern(System.String)") {
block.remove(ldstrIndex + 1, 1); block.remove(ldstrIndex + 1, 1);
@ -68,8 +68,8 @@ namespace de4dot.code {
class MyCallResult : CallResult { class MyCallResult : CallResult {
public int methodId; public int methodId;
public GenericInstanceMethod gim; public MethodSpec gim;
public MyCallResult(Block block, int callEndIndex, int methodId, GenericInstanceMethod gim) public MyCallResult(Block block, int callEndIndex, int methodId, MethodSpec gim)
: base(block, callEndIndex) { : base(block, callEndIndex) {
this.methodId = methodId; this.methodId = methodId;
this.gim = gim; this.gim = gim;
@ -93,9 +93,9 @@ namespace de4dot.code {
} }
} }
protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) { protected override CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) {
int methodId; int methodId;
if (!methodTokenToId.TryGetValue(method.MetadataToken.ToInt32(), out methodId)) if (!methodTokenToId.TryGetValue(method.MDToken.ToInt32(), out methodId))
return null; return null;
return new MyCallResult(block, callInstrIndex, methodId, gim); return new MyCallResult(block, callInstrIndex, methodId, gim);
} }
@ -117,7 +117,7 @@ namespace de4dot.code {
AssemblyData.SimpleData.pack(list[i].args); AssemblyData.SimpleData.pack(list[i].args);
args[i] = list[i].args; args[i] = list[i].args;
} }
var decryptedStrings = assemblyClient.Service.decryptStrings(methodId, args, Method.MetadataToken.ToInt32()); var decryptedStrings = assemblyClient.Service.decryptStrings(methodId, args, Method.MDToken.ToInt32());
if (decryptedStrings.Length != args.Length) if (decryptedStrings.Length != args.Length)
throw new ApplicationException("Invalid decrypted strings array length"); throw new ApplicationException("Invalid decrypted strings array length");
AssemblyData.SimpleData.unpack(decryptedStrings); AssemblyData.SimpleData.unpack(decryptedStrings);
@ -128,27 +128,27 @@ namespace de4dot.code {
} }
class StaticStringInliner : StringInlinerBase { class StaticStringInliner : StringInlinerBase {
MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, GenericInstanceMethod, object[], string>> stringDecrypters = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, GenericInstanceMethod, object[], string>>(); MethodDefinitionAndDeclaringTypeDict<Func<MethodDef, MethodSpec, object[], string>> stringDecrypters = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDef, MethodSpec, object[], string>>();
public override bool HasHandlers { public override bool HasHandlers {
get { return stringDecrypters.Count != 0; } get { return stringDecrypters.Count != 0; }
} }
public IEnumerable<MethodDefinition> Methods { public IEnumerable<MethodDef> Methods {
get { return stringDecrypters.getKeys(); } get { return stringDecrypters.getKeys(); }
} }
class MyCallResult : CallResult { class MyCallResult : CallResult {
public MethodReference methodReference; public IMethod IMethod;
public GenericInstanceMethod gim; public MethodSpec gim;
public MyCallResult(Block block, int callEndIndex, MethodReference method, GenericInstanceMethod gim) public MyCallResult(Block block, int callEndIndex, IMethod method, MethodSpec gim)
: base(block, callEndIndex) { : base(block, callEndIndex) {
this.methodReference = method; this.IMethod = method;
this.gim = gim; this.gim = gim;
} }
} }
public void add(MethodDefinition method, Func<MethodDefinition, GenericInstanceMethod, object[], string> handler) { public void add(MethodDef method, Func<MethodDef, MethodSpec, object[], string> handler) {
if (method != null) if (method != null)
stringDecrypters.add(method, handler); stringDecrypters.add(method, handler);
} }
@ -156,12 +156,12 @@ namespace de4dot.code {
protected override void inlineAllCalls() { protected override void inlineAllCalls() {
foreach (var tmp in callResults) { foreach (var tmp in callResults) {
var callResult = (MyCallResult)tmp; var callResult = (MyCallResult)tmp;
var handler = stringDecrypters.find(callResult.methodReference); var handler = stringDecrypters.find(callResult.IMethod);
callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.gim, callResult.args); callResult.returnValue = handler((MethodDef)callResult.IMethod, callResult.gim, callResult.args);
} }
} }
protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) { protected override CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) {
if (stringDecrypters.find(method) == null) if (stringDecrypters.find(method) == null)
return null; return null;
return new MyCallResult(block, callInstrIndex, method, gim); return new MyCallResult(block, callInstrIndex, method, gim);

View File

@ -214,12 +214,6 @@ namespace de4dot.code {
return true; return true;
} }
public static int compareInt32(int a, int b) {
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
public static byte[] readFile(string filename) { public static byte[] readFile(string filename) {
// If the file is on the network, and we read more than 2MB, we'll read from the wrong // If the file is on the network, and we read more than 2MB, we'll read from the wrong
// offset in the file! Tested: VMware 8, Win7 x64. // offset in the file! Tested: VMware 8, Win7 x64.

View File

@ -219,7 +219,6 @@
<None Include="deobfuscators\MaxtoCode\StringDecrypter.cs" /> <None Include="deobfuscators\MaxtoCode\StringDecrypter.cs" />
<Compile Include="deobfuscators\MemberReferenceBuilder.cs" /> <Compile Include="deobfuscators\MemberReferenceBuilder.cs" />
<Compile Include="deobfuscators\MethodBodyParser.cs" /> <Compile Include="deobfuscators\MethodBodyParser.cs" />
<Compile Include="deobfuscators\MethodBodyReaderBase.cs" />
<Compile Include="deobfuscators\MethodCallRestorerBase.cs" /> <Compile Include="deobfuscators\MethodCallRestorerBase.cs" />
<Compile Include="deobfuscators\MethodCollection.cs" /> <Compile Include="deobfuscators\MethodCollection.cs" />
<Compile Include="deobfuscators\MethodsDecrypter.cs" /> <Compile Include="deobfuscators\MethodsDecrypter.cs" />

View File

@ -120,7 +120,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return false; return false;
block.Instructions[instrIndex - 1] = new Instr(Instruction.Create(OpCodes.Nop)); block.Instructions[instrIndex - 1] = new Instr(Instruction.Create(OpCodes.Nop));
block.Instructions[instrIndex] = new Instr(DotNetUtils.createLdci4(newValue)); block.Instructions[instrIndex] = new Instr(Instruction.CreateLdcI4(newValue));
return true; return true;
} }

View File

@ -392,7 +392,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
static Instruction ldc_read(BinaryReader reader) { static Instruction ldc_read(BinaryReader reader) {
switch ((ElementType)reader.ReadByte()) { switch ((ElementType)reader.ReadByte()) {
case ElementType.I4: return DotNetUtils.createLdci4(reader.ReadInt32()); case ElementType.I4: return Instruction.CreateLdcI4(reader.ReadInt32());
case ElementType.I8: return Instruction.Create(OpCodes.Ldc_I8, reader.ReadInt64()); case ElementType.I8: return Instruction.Create(OpCodes.Ldc_I8, reader.ReadInt64());
case ElementType.R4: return Instruction.Create(OpCodes.Ldc_R4, reader.ReadSingle()); case ElementType.R4: return Instruction.Create(OpCodes.Ldc_R4, reader.ReadSingle());
case ElementType.R8: return Instruction.Create(OpCodes.Ldc_R8, reader.ReadDouble()); case ElementType.R8: return Instruction.Create(OpCodes.Ldc_R8, reader.ReadDouble());

View File

@ -115,7 +115,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return false; return false;
block.remove(i, 3 - 1); block.remove(i, 3 - 1);
instrs[i] = new Instr(DotNetUtils.createLdci4(info.array[ldci4.getLdcI4Value()])); instrs[i] = new Instr(Instruction.CreateLdcI4(info.array[ldci4.getLdcI4Value()]));
return true; return true;
} }
@ -140,7 +140,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return false; return false;
block.remove(i, 3 - 1); block.remove(i, 3 - 1);
instrs[i] = new Instr(DotNetUtils.createLdci4(info.array[ldci4.getLdcI4Value()])); instrs[i] = new Instr(Instruction.CreateLdcI4(info.array[ldci4.getLdcI4Value()]));
return true; return true;
} }

View File

@ -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 { namespace de4dot.code.deobfuscators {
@ -28,7 +28,7 @@ namespace de4dot.code.deobfuscators {
public int NumRemovedExceptionLoggers { get; set; } public int NumRemovedExceptionLoggers { get; set; }
public void add(MethodDefinition exceptionLogger) { public void add(MethodDef exceptionLogger) {
exceptionLoggerMethods.add(exceptionLogger, true); exceptionLoggerMethods.add(exceptionLogger, true);
} }
@ -42,7 +42,7 @@ namespace de4dot.code.deobfuscators {
if (tryBlock.TryHandlerBlocks.Count != 1) if (tryBlock.TryHandlerBlocks.Count != 1)
continue; continue;
var catchBlock = tryBlock.TryHandlerBlocks[0]; var catchBlock = tryBlock.TryHandlerBlocks[0];
if (catchBlock.HandlerType != ExceptionHandlerType.Catch || if (catchBlock.HandlerType != ExceptionClause.Catch ||
catchBlock.CatchType.FullName != "System.Exception") { catchBlock.CatchType.FullName != "System.Exception") {
continue; continue;
} }
@ -74,7 +74,7 @@ namespace de4dot.code.deobfuscators {
} }
if (failed || calls != 1 || callInstr.OpCode.Code != Code.Call) if (failed || calls != 1 || callInstr.OpCode.Code != Code.Call)
continue; continue;
var calledMethod = callInstr.Operand as MethodReference; var calledMethod = callInstr.Operand as IMethod;
if (calledMethod == null) if (calledMethod == null)
continue; continue;
if (!isExceptionLogger(calledMethod)) if (!isExceptionLogger(calledMethod))
@ -86,7 +86,7 @@ namespace de4dot.code.deobfuscators {
return false; return false;
} }
protected virtual bool isExceptionLogger(MethodReference method) { protected virtual bool isExceptionLogger(IMethod method) {
return exceptionLoggerMethods.find(method); return exceptionLoggerMethods.find(method);
} }

View File

@ -19,8 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Mono.Cecil; using dot10.DotNet;
using Mono.MyStuff;
using de4dot.blocks; using de4dot.blocks;
using de4dot.blocks.cflow; using de4dot.blocks.cflow;
#if PORT #if PORT
@ -78,7 +77,7 @@ namespace de4dot.code.deobfuscators {
// 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(ModuleDefinition module); void init(ModuleDefMD module);
// Returns 0 if it's not detected, or > 0 if detected (higher value => more likely true). // Returns 0 if it's not detected, or > 0 if detected (higher value => more likely true).
// This method is always called. // This method is always called.
@ -90,7 +89,7 @@ namespace de4dot.code.deobfuscators {
// This is only called if getDecryptedModule() != null, and after the module has been // This is only called if getDecryptedModule() != null, and after the module has been
// reloaded. Should return a new IDeobfuscator with the same options and the new module. // reloaded. Should return a new IDeobfuscator with the same options and the new module.
IDeobfuscator moduleReloaded(ModuleDefinition module); IDeobfuscator moduleReloaded(ModuleDefMD module);
// Called before all other deobfuscation methods // Called before all other deobfuscation methods
void deobfuscateBegin(); void deobfuscateBegin();

View File

@ -17,12 +17,12 @@
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 { namespace de4dot.code.deobfuscators {
public interface ISimpleDeobfuscator { public interface ISimpleDeobfuscator {
void deobfuscate(MethodDefinition method); void deobfuscate(MethodDef method);
void deobfuscate(MethodDefinition method, bool force); void deobfuscate(MethodDef method, bool force);
void decryptStrings(MethodDefinition method, IDeobfuscator deob); void decryptStrings(MethodDef method, IDeobfuscator deob);
} }
} }

View File

@ -1,279 +0,0 @@
/*
Copyright (C) 2011-2012 de4dot@gmail.com
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Cil;
using de4dot.blocks;
namespace de4dot.code.deobfuscators {
abstract class MethodBodyReaderBase {
protected BinaryReader reader;
public IList<VariableDefinition> Locals { get; set; }
public IList<Instruction> Instructions { get; set; }
public IList<ExceptionHandler> ExceptionHandlers { get; set; }
protected IList<ParameterDefinition> parameters;
int currentOffset;
public MethodBodyReaderBase(BinaryReader reader) {
this.reader = reader;
}
protected void setLocals(IList<TypeReference> types) {
Locals = new List<VariableDefinition>(types.Count);
foreach (var type in types)
Locals.Add(new VariableDefinition(type));
}
protected void readInstructions(int numInstrs) {
Instructions = new Instruction[numInstrs];
currentOffset = 0;
for (int i = 0; i < Instructions.Count; i++)
Instructions[i] = readOneInstruction();
fixBranches();
}
protected void readInstructionsNumBytes(uint codeSize) {
var instrs = new List<Instruction>();
long endOffs = reader.BaseStream.Position + codeSize;
while (reader.BaseStream.Position < endOffs)
instrs.Add(readOneInstruction());
if (reader.BaseStream.Position != endOffs)
throw new ApplicationException("Could not read all instructions");
Instructions = instrs;
fixBranches();
}
Instruction readOneInstruction() {
var instr = readInstruction();
if (instr.OpCode.Code == Code.Switch) {
int[] targets = (int[])instr.Operand;
currentOffset += instr.OpCode.Size + 4 + 4 * targets.Length;
}
else
currentOffset += instr.GetSize();
return instr;
}
void fixBranches() {
foreach (var instr in Instructions) {
switch (instr.OpCode.OperandType) {
case OperandType.InlineBrTarget:
case OperandType.ShortInlineBrTarget:
instr.Operand = getInstruction((int)instr.Operand);
break;
case OperandType.InlineSwitch:
var intTargets = (int[])instr.Operand;
var targets = new Instruction[intTargets.Length];
for (int i = 0; i < intTargets.Length; i++)
targets[i] = getInstruction(intTargets[i]);
instr.Operand = targets;
break;
}
}
}
protected Instruction getInstructionOrNull(int offset) {
foreach (var instr in Instructions) {
if (instr.Offset == offset)
return instr;
}
return null;
}
protected Instruction getInstruction(int offset) {
var instr = getInstructionOrNull(offset);
if (instr != null)
return instr;
throw new ApplicationException(string.Format("No instruction found at offset {0:X4}", offset));
}
Instruction readInstruction() {
int offset = currentOffset;
var opcode = readOpCode();
var instr = new Instruction {
OpCode = opcode,
Offset = offset,
};
instr.Operand = readOperand(instr);
return instr;
}
object readOperand(Instruction instr) {
switch (instr.OpCode.OperandType) {
case OperandType.InlineBrTarget:
return readInlineBrTarget(instr);
case OperandType.InlineField:
return readInlineField(instr);
case OperandType.InlineI:
return readInlineI(instr);
case OperandType.InlineI8:
return readInlineI8(instr);
case OperandType.InlineMethod:
return readInlineMethod(instr);
case OperandType.InlineNone:
return readInlineNone(instr);
case OperandType.InlinePhi:
return readInlinePhi(instr);
case OperandType.InlineR:
return readInlineR(instr);
case OperandType.InlineSig:
return readInlineSig(instr);
case OperandType.InlineString:
return readInlineString(instr);
case OperandType.InlineSwitch:
return readInlineSwitch(instr);
case OperandType.InlineTok:
return readInlineTok(instr);
case OperandType.InlineType:
return readInlineType(instr);
case OperandType.InlineVar:
return readInlineVar(instr);
case OperandType.InlineArg:
return readInlineArg(instr);
case OperandType.ShortInlineBrTarget:
return readShortInlineBrTarget(instr);
case OperandType.ShortInlineI:
return readShortInlineI(instr);
case OperandType.ShortInlineR:
return readShortInlineR(instr);
case OperandType.ShortInlineVar:
return readShortInlineVar(instr);
case OperandType.ShortInlineArg:
return readShortInlineArg(instr);
default:
throw new ApplicationException(string.Format("Unknown operand type {0}", instr.OpCode.OperandType));
}
}
protected virtual int readInlineBrTarget(Instruction instr) {
return currentOffset + instr.GetSize() + reader.ReadInt32();
}
protected abstract FieldReference readInlineField(Instruction instr);
protected virtual int readInlineI(Instruction instr) {
return reader.ReadInt32();
}
protected virtual long readInlineI8(Instruction instr) {
return reader.ReadInt64();
}
protected abstract MethodReference readInlineMethod(Instruction instr);
protected virtual object readInlineNone(Instruction instr) {
return null;
}
protected virtual object readInlinePhi(Instruction instr) {
return null;
}
protected virtual double readInlineR(Instruction instr) {
return reader.ReadDouble();
}
protected abstract CallSite readInlineSig(Instruction instr);
protected abstract string readInlineString(Instruction instr);
protected virtual int[] readInlineSwitch(Instruction instr) {
var targets = new int[reader.ReadInt32()];
int offset = currentOffset + instr.OpCode.Size + 4 + 4 * targets.Length;
for (int i = 0; i < targets.Length; i++)
targets[i] = offset + reader.ReadInt32();
return targets;
}
protected abstract MemberReference readInlineTok(Instruction instr);
protected abstract TypeReference readInlineType(Instruction instr);
protected virtual VariableDefinition readInlineVar(Instruction instr) {
return Locals[reader.ReadUInt16()];
}
protected virtual ParameterDefinition readInlineArg(Instruction instr) {
return parameters[reader.ReadUInt16()];
}
protected virtual int readShortInlineBrTarget(Instruction instr) {
return currentOffset + instr.GetSize() + reader.ReadSByte();
}
protected virtual object readShortInlineI(Instruction instr) {
if (instr.OpCode.Code == Code.Ldc_I4_S)
return reader.ReadSByte();
return reader.ReadByte();
}
protected virtual float readShortInlineR(Instruction instr) {
return reader.ReadSingle();
}
protected virtual VariableDefinition readShortInlineVar(Instruction instr) {
return Locals[reader.ReadByte()];
}
protected virtual ParameterDefinition readShortInlineArg(Instruction instr) {
return parameters[reader.ReadByte()];
}
OpCode readOpCode() {
var op = reader.ReadByte();
if (op != 0xFE)
return OpCodes.OneByteOpCode[op];
return OpCodes.TwoBytesOpCode[reader.ReadByte()];
}
protected void readExceptionHandlers(int numExceptionHandlers) {
ExceptionHandlers = new ExceptionHandler[numExceptionHandlers];
for (int i = 0; i < ExceptionHandlers.Count; i++)
ExceptionHandlers[i] = readExceptionHandler();
}
protected abstract ExceptionHandler readExceptionHandler();
public virtual void restoreMethod(MethodDefinition method) {
var body = method.Body;
body.Variables.Clear();
if (Locals != null) {
foreach (var local in Locals)
body.Variables.Add(local);
}
body.Instructions.Clear();
if (Instructions != null) {
foreach (var instr in Instructions)
body.Instructions.Add(instr);
}
body.ExceptionHandlers.Clear();
if (ExceptionHandlers != null) {
foreach (var eh in ExceptionHandlers)
body.ExceptionHandlers.Add(eh);
}
}
}
}

View File

@ -18,32 +18,32 @@
*/ */
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 { namespace de4dot.code.deobfuscators {
class MethodCallRestorerBase { class MethodCallRestorerBase {
protected MemberReferenceBuilder builder; protected MemberReferenceBuilder builder;
protected ModuleDefinition module; protected ModuleDefMD module;
MethodDefinitionAndDeclaringTypeDict<NewMethodInfo> oldToNewMethod = new MethodDefinitionAndDeclaringTypeDict<NewMethodInfo>(); MethodDefinitionAndDeclaringTypeDict<NewMethodInfo> oldToNewMethod = new MethodDefinitionAndDeclaringTypeDict<NewMethodInfo>();
class NewMethodInfo { class NewMethodInfo {
public OpCode opCode; public OpCode opCode;
public MethodReference method; public IMethod method;
public NewMethodInfo(OpCode opCode, MethodReference method) { public NewMethodInfo(OpCode opCode, IMethod method) {
this.opCode = opCode; this.opCode = opCode;
this.method = method; this.method = method;
} }
} }
public MethodCallRestorerBase(ModuleDefinition module) { public MethodCallRestorerBase(ModuleDefMD module) {
this.module = module; this.module = module;
this.builder = new MemberReferenceBuilder(module); this.builder = new MemberReferenceBuilder(module);
} }
public void createGetManifestResourceStream1(MethodDefinition oldMethod) { public void createGetManifestResourceStream1(MethodDef oldMethod) {
if (oldMethod == null) if (oldMethod == null)
return; return;
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
@ -52,7 +52,7 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Callvirt); add(oldMethod, newMethod, OpCodes.Callvirt);
} }
public void createGetManifestResourceStream2(MethodDefinition oldMethod) { public void createGetManifestResourceStream2(MethodDef oldMethod) {
if (oldMethod == null) if (oldMethod == null)
return; return;
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Callvirt); add(oldMethod, newMethod, OpCodes.Callvirt);
} }
public void createGetManifestResourceNames(MethodDefinition oldMethod) { public void createGetManifestResourceNames(MethodDef oldMethod) {
if (oldMethod == null) if (oldMethod == null)
return; return;
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
@ -71,7 +71,7 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Callvirt); add(oldMethod, newMethod, OpCodes.Callvirt);
} }
public void createBitmapCtor(MethodDefinition oldMethod) { public void createBitmapCtor(MethodDef oldMethod) {
if (oldMethod == null) if (oldMethod == null)
return; return;
var bitmapType = builder.type("System.Drawing", "Bitmap", "System.Drawing"); var bitmapType = builder.type("System.Drawing", "Bitmap", "System.Drawing");
@ -80,7 +80,7 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Newobj); add(oldMethod, newMethod, OpCodes.Newobj);
} }
public void createIconCtor(MethodDefinition oldMethod) { public void createIconCtor(MethodDef oldMethod) {
if (oldMethod == null) if (oldMethod == null)
return; return;
var iconType = builder.type("System.Drawing", "Icon", "System.Drawing"); var iconType = builder.type("System.Drawing", "Icon", "System.Drawing");
@ -89,11 +89,11 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Newobj); add(oldMethod, newMethod, OpCodes.Newobj);
} }
protected void add(MethodDefinition oldMethod, MethodReference newMethod) { protected void add(MethodDef oldMethod, IMethod newMethod) {
add(oldMethod, newMethod, OpCodes.Callvirt); add(oldMethod, newMethod, OpCodes.Callvirt);
} }
protected void add(MethodDefinition oldMethod, MethodReference newMethod, OpCode opCode) { protected void add(MethodDef oldMethod, IMethod newMethod, OpCode opCode) {
if (oldMethod == null) if (oldMethod == null)
return; return;
oldToNewMethod.add(oldMethod, new NewMethodInfo(opCode, newMethod)); oldToNewMethod.add(oldMethod, new NewMethodInfo(opCode, newMethod));
@ -106,7 +106,7 @@ namespace de4dot.code.deobfuscators {
var call = instrs[i]; var call = instrs[i];
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;

View File

@ -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 { namespace de4dot.code.deobfuscators {
@ -79,7 +79,7 @@ namespace de4dot.code.deobfuscators {
public static PushedArgs getPushedArgInstructions(IList<Instruction> instructions, int index) { public static PushedArgs getPushedArgInstructions(IList<Instruction> instructions, int index) {
try { try {
int pushes, pops; int pushes, pops;
DotNetUtils.calculateStackUsage(instructions[index], false, out pushes, out pops); instructions[index].CalculateStackUsage(false, out pushes, out pops);
if (pops != -1) if (pops != -1)
return getPushedArgInstructions(instructions, index, pops); return getPushedArgInstructions(instructions, index, pops);
} }
@ -101,7 +101,7 @@ namespace de4dot.code.deobfuscators {
break; break;
int pushes, pops; int pushes, pops;
DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops); instr.CalculateStackUsage(false, out pushes, out pops);
if (pops == -1) if (pops == -1)
break; break;
if (instr.OpCode.Code == Code.Dup) { if (instr.OpCode.Code == Code.Dup) {
@ -128,7 +128,7 @@ namespace de4dot.code.deobfuscators {
instr = getPreviousInstruction(instructions, ref index); instr = getPreviousInstruction(instructions, ref index);
if (instr != null) { if (instr != null) {
int pushes, pops; int pushes, pops;
DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops); instr.CalculateStackUsage(false, out pushes, out pops);
if (pushes == 1 && pops == 0) if (pushes == 1 && pops == 0)
pushedArgs.set(0, instr); pushedArgs.set(0, instr);
} }
@ -138,96 +138,97 @@ namespace de4dot.code.deobfuscators {
return pushedArgs; return pushedArgs;
} }
public static TypeReference getLoadedType(MethodDefinition method, IList<Instruction> instructions, int instrIndex) { public static TypeSig getLoadedType(MethodDef method, IList<Instruction> instructions, int instrIndex) {
bool wasNewobj; bool wasNewobj;
return getLoadedType(method, instructions, instrIndex, 0, out wasNewobj); return getLoadedType(method, instructions, instrIndex, 0, out wasNewobj);
} }
public static TypeReference getLoadedType(MethodDefinition method, IList<Instruction> instructions, int instrIndex, int argIndexFromEnd) { public static TypeSig getLoadedType(MethodDef method, IList<Instruction> instructions, int instrIndex, int argIndexFromEnd) {
bool wasNewobj; bool wasNewobj;
return getLoadedType(method, instructions, instrIndex, argIndexFromEnd, out wasNewobj); return getLoadedType(method, instructions, instrIndex, argIndexFromEnd, out wasNewobj);
} }
public static TypeReference getLoadedType(MethodDefinition method, IList<Instruction> instructions, int instrIndex, out bool wasNewobj) { public static TypeSig getLoadedType(MethodDef method, IList<Instruction> instructions, int instrIndex, out bool wasNewobj) {
return getLoadedType(method, instructions, instrIndex, 0, out wasNewobj); return getLoadedType(method, instructions, instrIndex, 0, out wasNewobj);
} }
public static TypeReference getLoadedType(MethodDefinition method, IList<Instruction> instructions, int instrIndex, int argIndexFromEnd, out bool wasNewobj) { public static TypeSig getLoadedType(MethodDef method, IList<Instruction> instructions, int instrIndex, int argIndexFromEnd, out bool wasNewobj) {
wasNewobj = false; wasNewobj = false;
var pushedArgs = MethodStack.getPushedArgInstructions(instructions, instrIndex); var pushedArgs = MethodStack.getPushedArgInstructions(instructions, instrIndex);
var pushInstr = pushedArgs.getEnd(argIndexFromEnd); var pushInstr = pushedArgs.getEnd(argIndexFromEnd);
if (pushInstr == null) if (pushInstr == null)
return null; return null;
TypeReference type; TypeSig type;
VariableDefinition local; Local local;
var corLibTypes = method.DeclaringType.OwnerModule.CorLibTypes;
switch (pushInstr.OpCode.Code) { switch (pushInstr.OpCode.Code) {
case Code.Ldstr: case Code.Ldstr:
type = method.Module.TypeSystem.String; type = corLibTypes.String;
break; break;
case Code.Conv_I: case Code.Conv_I:
case Code.Conv_Ovf_I: case Code.Conv_Ovf_I:
case Code.Conv_Ovf_I_Un: case Code.Conv_Ovf_I_Un:
type = method.Module.TypeSystem.IntPtr; type = corLibTypes.IntPtr;
break; break;
case Code.Conv_U: case Code.Conv_U:
case Code.Conv_Ovf_U: case Code.Conv_Ovf_U:
case Code.Conv_Ovf_U_Un: case Code.Conv_Ovf_U_Un:
type = method.Module.TypeSystem.UIntPtr; type = corLibTypes.UIntPtr;
break; break;
case Code.Conv_I8: case Code.Conv_I8:
case Code.Conv_Ovf_I8: case Code.Conv_Ovf_I8:
case Code.Conv_Ovf_I8_Un: case Code.Conv_Ovf_I8_Un:
type = method.Module.TypeSystem.Int64; type = corLibTypes.Int64;
break; break;
case Code.Conv_U8: case Code.Conv_U8:
case Code.Conv_Ovf_U8: case Code.Conv_Ovf_U8:
case Code.Conv_Ovf_U8_Un: case Code.Conv_Ovf_U8_Un:
type = method.Module.TypeSystem.UInt64; type = corLibTypes.UInt64;
break; break;
case Code.Conv_R8: case Code.Conv_R8:
case Code.Ldc_R8: case Code.Ldc_R8:
case Code.Ldelem_R8: case Code.Ldelem_R8:
case Code.Ldind_R8: case Code.Ldind_R8:
type = method.Module.TypeSystem.Double; type = corLibTypes.Double;
break; break;
case Code.Call: case Code.Call:
case Code.Calli: case Code.Calli:
case Code.Callvirt: case Code.Callvirt:
var calledMethod = pushInstr.Operand as MethodReference; var calledMethod = pushInstr.Operand as IMethod;
if (calledMethod == null) if (calledMethod == null)
return null; return null;
type = calledMethod.MethodReturnType.ReturnType; type = calledMethod.MethodSig.RetType;
break; break;
case Code.Newarr: case Code.Newarr:
type = pushInstr.Operand as TypeReference; var type2 = pushInstr.Operand as ITypeDefOrRef;
if (type == null) if (type2 == null)
return null; return null;
type = new ArrayType(type); type = new SZArraySig(type2.ToTypeSig());
wasNewobj = true; wasNewobj = true;
break; break;
case Code.Newobj: case Code.Newobj:
var ctor = pushInstr.Operand as MethodReference; var ctor = pushInstr.Operand as IMethod;
if (ctor == null) if (ctor == null)
return null; return null;
type = ctor.DeclaringType; type = ctor.DeclaringType.ToTypeSig();
wasNewobj = true; wasNewobj = true;
break; break;
case Code.Castclass: case Code.Castclass:
case Code.Isinst: case Code.Isinst:
case Code.Unbox_Any: case Code.Unbox_Any:
case Code.Ldelem_Any: case Code.Ldelem:
case Code.Ldobj: case Code.Ldobj:
type = pushInstr.Operand as TypeReference; type = (pushInstr.Operand as ITypeDefOrRef).ToTypeSig();
break; break;
case Code.Ldarg: case Code.Ldarg:
@ -236,7 +237,7 @@ 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:
type = DotNetUtils.getArgType(method, pushInstr); type = pushInstr.GetArgumentType(method.MethodSig, method.DeclaringType);
break; break;
case Code.Ldloc: case Code.Ldloc:
@ -245,44 +246,44 @@ namespace de4dot.code.deobfuscators {
case Code.Ldloc_1: case Code.Ldloc_1:
case Code.Ldloc_2: case Code.Ldloc_2:
case Code.Ldloc_3: case Code.Ldloc_3:
local = DotNetUtils.getLocalVar(method.Body.Variables, pushInstr); local = pushInstr.GetLocal(method.CilBody.LocalList);
if (local == null) if (local == null)
return null; return null;
type = local.VariableType; type = local.Type.RemovePinned();
break; break;
case Code.Ldloca: case Code.Ldloca:
case Code.Ldloca_S: case Code.Ldloca_S:
local = pushInstr.Operand as VariableDefinition; local = pushInstr.Operand as Local;
if (local == null) if (local == null)
return null; return null;
type = createByReferenceType(local.VariableType); type = createByReferenceType(local.Type.RemovePinned());
break; break;
case Code.Ldarga: case Code.Ldarga:
case Code.Ldarga_S: case Code.Ldarga_S:
type = createByReferenceType(DotNetUtils.getArgType(method, pushInstr)); type = createByReferenceType(pushInstr.GetArgumentType(method.MethodSig, method.DeclaringType));
break; break;
case Code.Ldfld: case Code.Ldfld:
case Code.Ldsfld: case Code.Ldsfld:
var field = pushInstr.Operand as FieldReference; var field = pushInstr.Operand as IField;
if (field == null) if (field == null || field.FieldSig == null)
return null; return null;
type = field.FieldType; type = field.FieldSig.Type;
break; break;
case Code.Ldflda: case Code.Ldflda:
case Code.Ldsflda: case Code.Ldsflda:
var field2 = pushInstr.Operand as FieldReference; var field2 = pushInstr.Operand as IField;
if (field2 == null) if (field2 == null || field2.FieldSig == null)
return null; return null;
type = createByReferenceType(field2.FieldType); type = createByReferenceType(field2.FieldSig.Type);
break; break;
case Code.Ldelema: case Code.Ldelema:
case Code.Unbox: case Code.Unbox:
type = createByReferenceType(pushInstr.Operand as TypeReference); type = createByReferenceType(pushInstr.Operand as ITypeDefOrRef);
break; break;
default: default:
@ -292,10 +293,16 @@ namespace de4dot.code.deobfuscators {
return type; return type;
} }
static ByReferenceType createByReferenceType(TypeReference elementType) { static ByRefSig createByReferenceType(ITypeDefOrRef elementType) {
if (elementType == null) if (elementType == null)
return null; return null;
return new ByReferenceType(elementType); return new ByRefSig(elementType.ToTypeSig());
}
static ByRefSig createByReferenceType(TypeSig elementType) {
if (elementType == null)
return null;
return new ByRefSig(elementType);
} }
static Instruction getPreviousInstruction(IList<Instruction> instructions, ref int instrIndex) { static Instruction getPreviousInstruction(IList<Instruction> instructions, ref int instrIndex) {

View File

@ -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.MyStuff; using dot10.DotNet;
using de4dot.code.AssemblyClient; using de4dot.code.AssemblyClient;
using de4dot.mdecrypt; using de4dot.mdecrypt;

View File

@ -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;
namespace de4dot.code.deobfuscators { namespace de4dot.code.deobfuscators {
class StringCounts { class StringCounts {
@ -66,37 +66,37 @@ namespace de4dot.code.deobfuscators {
} }
class FieldTypes : StringCounts { class FieldTypes : StringCounts {
public FieldTypes(TypeDefinition type) { public FieldTypes(TypeDef type) {
init(type.Fields); init(type.Fields);
} }
public FieldTypes(IEnumerable<FieldDefinition> fields) { public FieldTypes(IEnumerable<FieldDef> fields) {
init(fields); init(fields);
} }
void init(IEnumerable<FieldDefinition> fields) { void init(IEnumerable<FieldDef> fields) {
if (fields == null) if (fields == null)
return; return;
foreach (var field in fields) foreach (var field in fields)
add(field.FieldType.FullName); add(field.FieldSig.Type.FullName);
} }
} }
class LocalTypes : StringCounts { class LocalTypes : StringCounts {
public LocalTypes(MethodDefinition method) { public LocalTypes(MethodDef method) {
if (method != null && method.Body != null) if (method != null && method.CilBody != null)
init(method.Body.Variables); init(method.CilBody.LocalList);
} }
public LocalTypes(IEnumerable<VariableDefinition> locals) { public LocalTypes(IEnumerable<Local> locals) {
init(locals); init(locals);
} }
void init(IEnumerable<VariableDefinition> locals) { void init(IEnumerable<Local> locals) {
if (locals == null) if (locals == null)
return; return;
foreach (var local in locals) foreach (var local in locals)
add(local.VariableType.FullName); add(local.Type.FullName);
} }
} }
} }

View File

@ -186,7 +186,7 @@ namespace de4dot.code.deobfuscators {
return; return;
Log.v("Changing field types to real type"); Log.v("Changing field types to real type");
fields.Sort((a, b) => Utils.compareInt32(a.token, b.token)); fields.Sort((a, b) => a.token.CompareTo(b.token));
Log.indent(); Log.indent();
foreach (var updatedField in fields) foreach (var updatedField in fields)
Log.v("Field {0:X8}: type {1} ({2:X8})", updatedField.token, Utils.removeNewlines(updatedField.newFieldType.FullName), updatedField.newFieldType.MDToken.ToInt32()); Log.v("Field {0:X8}: type {1} ({2:X8})", updatedField.token, Utils.removeNewlines(updatedField.newFieldType.FullName), updatedField.newFieldType.MDToken.ToInt32());
@ -199,7 +199,7 @@ namespace de4dot.code.deobfuscators {
return; return;
Log.v("Changing method args and return types to real type"); Log.v("Changing method args and return types to real type");
methods.Sort((a, b) => Utils.compareInt32(a.token, b.token)); methods.Sort((a, b) => a.token.CompareTo(b.token));
Log.indent(); Log.indent();
foreach (var updatedMethod in methods) { foreach (var updatedMethod in methods) {
Log.v("Method {0:X8}", updatedMethod.token); Log.v("Method {0:X8}", updatedMethod.token);
@ -250,7 +250,7 @@ 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 Utils.compareInt32(a.arg.Sequence, b.arg.Sequence); return a.arg.Sequence.CompareTo(b.arg.Sequence);
} }
void deobfuscateMethod(MethodDef method) { void deobfuscateMethod(MethodDef method) {

View File

@ -19,19 +19,19 @@
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 { namespace de4dot.code.deobfuscators {
abstract class ValueInlinerBase<TValue> : MethodReturnValueInliner { abstract class ValueInlinerBase<TValue> : MethodReturnValueInliner {
MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, GenericInstanceMethod, object[], object>> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, GenericInstanceMethod, object[], object>>(); MethodDefinitionAndDeclaringTypeDict<Func<MethodDef, MethodSpec, object[], object>> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDef, MethodSpec, object[], object>>();
bool removeUnbox = false; bool removeUnbox = false;
class MyCallResult : CallResult { class MyCallResult : CallResult {
public MethodReference methodReference; public IMethod methodReference;
public GenericInstanceMethod gim; public MethodSpec gim;
public MyCallResult(Block block, int callEndIndex, MethodReference method, GenericInstanceMethod gim) public MyCallResult(Block block, int callEndIndex, IMethod method, MethodSpec gim)
: base(block, callEndIndex) { : base(block, callEndIndex) {
this.methodReference = method; this.methodReference = method;
this.gim = gim; this.gim = gim;
@ -47,15 +47,15 @@ namespace de4dot.code.deobfuscators {
get { return decrypterMethods.Count != 0; } get { return decrypterMethods.Count != 0; }
} }
public IEnumerable<MethodDefinition> Methods { public IEnumerable<MethodDef> Methods {
get { return decrypterMethods.getKeys(); } get { return decrypterMethods.getKeys(); }
} }
public void add(MethodDefinition method, Func<MethodDefinition, GenericInstanceMethod, object[], object> handler) { public void add(MethodDef method, Func<MethodDef, MethodSpec, object[], object> handler) {
if (method == null) if (method == null)
return; return;
if (decrypterMethods.find(method) != null) if (decrypterMethods.find(method) != null)
throw new ApplicationException(string.Format("Handler for method {0:X8} has already been added", method.MetadataToken.ToInt32())); throw new ApplicationException(string.Format("Handler for method {0:X8} has already been added", method.MDToken.ToInt32()));
if (method != null) if (method != null)
decrypterMethods.add(method, handler); decrypterMethods.add(method, handler);
} }
@ -64,11 +64,11 @@ namespace de4dot.code.deobfuscators {
foreach (var tmp in callResults) { foreach (var tmp in callResults) {
var callResult = (MyCallResult)tmp; var callResult = (MyCallResult)tmp;
var handler = decrypterMethods.find(callResult.methodReference); var handler = decrypterMethods.find(callResult.methodReference);
callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.gim, callResult.args); callResult.returnValue = handler((MethodDef)callResult.methodReference, callResult.gim, callResult.args);
} }
} }
protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) { protected override CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) {
if (decrypterMethods.find(method) == null) if (decrypterMethods.find(method) == null)
return null; return null;
return new MyCallResult(block, callInstrIndex, method, gim); return new MyCallResult(block, callInstrIndex, method, gim);
@ -83,7 +83,7 @@ namespace de4dot.code.deobfuscators {
var unbox = instrs[index]; var unbox = instrs[index];
if (unbox.OpCode.Code != Code.Unbox_Any) if (unbox.OpCode.Code != Code.Unbox_Any)
return false; return false;
var type = unbox.Operand as TypeReference; var type = unbox.Operand as ITypeDefOrRef;
if (type == null || type.FullName != unboxType) if (type == null || type.FullName != unboxType)
return false; return false;
block.remove(index, 1); block.remove(index, 1);
@ -97,7 +97,7 @@ namespace de4dot.code.deobfuscators {
var block = callResult.block; var block = callResult.block;
int num = callResult.callEndIndex - callResult.callStartIndex + 1; int num = callResult.callEndIndex - callResult.callStartIndex + 1;
block.replace(callResult.callStartIndex, num, DotNetUtils.createLdci4((bool)callResult.returnValue ? 1 : 0)); block.replace(callResult.callStartIndex, num, Instruction.CreateLdcI4((bool)callResult.returnValue ? 1 : 0));
removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Boolean"); removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Boolean");
Log.v("Decrypted boolean: {0}", callResult.returnValue); Log.v("Decrypted boolean: {0}", callResult.returnValue);
} }
@ -110,7 +110,7 @@ namespace de4dot.code.deobfuscators {
var block = callResult.block; var block = callResult.block;
int num = callResult.callEndIndex - callResult.callStartIndex + 1; int num = callResult.callEndIndex - callResult.callStartIndex + 1;
block.replace(callResult.callStartIndex, num, DotNetUtils.createLdci4((int)callResult.returnValue)); block.replace(callResult.callStartIndex, num, Instruction.CreateLdcI4((int)callResult.returnValue));
removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Int32"); removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Int32");
Log.v("Decrypted int32: {0}", callResult.returnValue); Log.v("Decrypted int32: {0}", callResult.returnValue);
} }

View File

@ -227,7 +227,7 @@ namespace de4dot.code.resources {
public List<UserResourceType> getSortedTypes() { public List<UserResourceType> getSortedTypes() {
var list = new List<UserResourceType>(dict.Values); var list = new List<UserResourceType>(dict.Values);
list.Sort((a, b) => Utils.compareInt32((int)a.Code, (int)b.Code)); list.Sort((a, b) => ((int)a.Code).CompareTo((int)b.Code));
return list; return list;
} }
} }

View File

@ -109,7 +109,7 @@ namespace de4dot.code.resources {
} }
static int sortResourceInfo(ResourceInfo a, ResourceInfo b) { static int sortResourceInfo(ResourceInfo a, ResourceInfo b) {
return Utils.compareInt32((int)a.offset, (int)b.offset); return ((int)a.offset).CompareTo((int)b.offset);
} }
class ResourceInfo { class ResourceInfo {

2
dot10

@ -1 +1 @@
Subproject commit 7eb0fb7e6e47c79eebbef0ea9ea404f9b81fde51 Subproject commit 3b128874ff6bd531f588c487e9aeb76fb62acfec