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

View File

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

View File

@ -19,7 +19,7 @@
using System;
using System.Collections.Generic;
using Mono.Cecil;
using dot10.DotNet;
using de4dot.blocks;
namespace de4dot.code {
@ -48,6 +48,7 @@ namespace de4dot.code {
dataDict.Remove(name);
}
#if PORT
static TypeReference getNonGenericTypeReference(TypeReference typeReference) {
if (typeReference == null)
return null;
@ -104,5 +105,6 @@ namespace de4dot.code {
return null;
}
#endif
}
}

View File

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

View File

@ -17,7 +17,7 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using Mono.Cecil;
using dot10.DotNet;
namespace de4dot.code {
public interface IDeobfuscatorContext {
@ -25,8 +25,10 @@ namespace de4dot.code {
void setData(string name, object data);
object getData(string name);
void clearData(string name);
TypeDefinition resolve(TypeReference type);
MethodDefinition resolve(MethodReference method);
FieldDefinition resolve(FieldReference field);
#if PORT
TypeDef resolve(TypeRef type);
MethodDef resolve(IMethod method);
FieldDef resolve(IField field);
#endif
}
}

View File

@ -19,8 +19,8 @@
using System.Collections.Generic;
using System.Text;
using Mono.Cecil;
using Mono.Cecil.Cil;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code {
@ -83,7 +83,7 @@ namespace de4dot.code {
}
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++)
labels[sortedTargets[i]] = string.Format("label_{0}", i);
}
@ -131,13 +131,13 @@ namespace de4dot.code {
ExInfo exInfo;
if (exInfos.TryGetValue(instr, out exInfo))
printExInfo(exInfo);
var instrString = instr.GetOpCodeString();
var instrString = instr.OpCode.Name;
var operandString = getOperandString(instr);
var memberReference = instr.Operand as MemberReference;
var memberReference = instr.Operand as ITokenOperand;
if (operandString == "")
Log.log(logLevel, "{0}", instrString);
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
Log.log(logLevel, "{0,-9} {1}", instrString, Utils.removeNewlines(operandString));
}
@ -160,12 +160,12 @@ namespace de4dot.code {
}
else if (instr.Operand is string)
return Utils.toCsharpString((string)instr.Operand);
else if (instr.Operand is ParameterDefinition) {
var arg = (ParameterDefinition)instr.Operand;
else if (instr.Operand is Parameter) {
var arg = (Parameter)instr.Operand;
var s = instr.GetOperandString();
if (s != "")
return s;
return string.Format("<arg_{0}>", DotNetUtils.getArgIndex(arg));
return string.Format("<arg_{0}>", arg.Index);
}
else
return instr.GetOperandString();

View File

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

View File

@ -432,26 +432,28 @@ namespace de4dot.code {
if (typeString != null && typeString != type.FullName)
continue;
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;
if (methodName != null && methodName != method.Name)
continue;
if (argsStrings == null) {
if (method.Parameters.Count == 0)
if (method.Parameters.Length == 0)
continue;
}
else {
if (argsStrings.Length != method.Parameters.Count)
if (argsStrings.Length != method.Parameters.Length)
continue;
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;
}
}
Log.v("Adding string decrypter; token: {0:X8}, method: {1}", method.MetadataToken.ToInt32(), Utils.removeNewlines(method.FullName));
tokens.Add(method.MetadataToken.ToInt32());
Log.v("Adding string decrypter; token: {0:X8}, method: {1}", method.MDToken.ToInt32(), Utils.removeNewlines(method.FullName));
tokens.Add(method.MDToken.ToInt32());
}
}
@ -530,30 +532,26 @@ namespace de4dot.code {
Log.v("Deobfuscating methods");
var methodPrinter = new MethodPrinter();
#if PORT
var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators);
#endif
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();
int oldIndentLevel = Log.indentLevel;
try {
#if PORT
deobfuscate(method, cflowDeobfuscator, methodPrinter);
#endif
}
catch (ApplicationException) {
throw;
}
catch (Exception ex) {
if (!canLoadMethodBody(method)) {
Log.v("Invalid method body. {0:X8}", method.MetadataToken.ToInt32());
method.CilBody = new MethodBody(method);
Log.v("Invalid method body. {0:X8}", method.MDToken.ToInt32());
method.CilBody = new CilBody();
}
else {
Log.w("Could not deobfuscate method {0:X8}. Hello, E.T.: {1}", // E.T. = exception type
method.MetadataToken.ToInt32(),
method.MDToken.ToInt32(),
ex.GetType());
}
}
@ -576,7 +574,6 @@ namespace de4dot.code {
}
}
#if PORT
void deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter) {
if (!hasNonEmptyBody(method))
return;
@ -621,10 +618,9 @@ namespace de4dot.code {
Log.deIndent();
}
}
#endif
bool hasNonEmptyBody(MethodDef method) {
return method.HasBody && method.CilBody.Instructions.Count > 0;
return method.HasCilBody && method.CilBody.Instructions.Count > 0;
}
void deobfuscateStrings(Blocks blocks) {
@ -647,10 +643,10 @@ namespace de4dot.code {
}
void removeNoInliningAttribute(MethodDef method) {
method.ImplAttributes = method.ImplAttributes & ~MethodImplAttributes.NoInlining;
method.IsNoInlining = false;
for (int i = 0; i < method.CustomAttributes.Count; i++) {
var cattr = method.CustomAttributes[i];
if (cattr.AttributeType.FullName != "System.Runtime.CompilerServices.MethodImplAttribute")
if (cattr.TypeFullName != "System.Runtime.CompilerServices.MethodImplAttribute")
continue;
int options = 0;
if (!getMethodImplOptions(cattr, ref options))
@ -663,13 +659,13 @@ namespace de4dot.code {
}
static bool getMethodImplOptions(CustomAttribute cattr, ref int value) {
if (cattr.ConstructorArguments.Count != 1)
if (cattr.Arguments.Count != 1)
return false;
if (cattr.ConstructorArguments[0].Type.FullName != "System.Int16" &&
cattr.ConstructorArguments[0].Type.FullName != "System.Runtime.CompilerServices.MethodImplOptions")
if (cattr.Arguments[0].Type.ElementType != ElementType.I2 &&
cattr.Arguments[0].Type.FullName != "System.Runtime.CompilerServices.MethodImplOptions")
return false;
var arg = cattr.ConstructorArguments[0].Value;
var arg = cattr.Arguments[0].Value;
if (arg is short) {
value = (short)arg;
return true;
@ -704,7 +700,7 @@ namespace de4dot.code {
if (savedMethodBodies != null)
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();
if (hasNonEmptyBody(method)) {
@ -719,7 +715,7 @@ namespace de4dot.code {
DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
}
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.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.code.AssemblyClient;
using de4dot.blocks;
@ -49,7 +49,7 @@ namespace de4dot.code {
if (ldstrIndex + 1 < block.Instructions.Count) {
var instr = block.Instructions[ldstrIndex + 1];
if (instr.OpCode.Code == Code.Call) {
var calledMethod = instr.Operand as MethodReference;
var calledMethod = instr.Operand as IMethod;
if (calledMethod != null &&
calledMethod.FullName == "System.String System.String::Intern(System.String)") {
block.remove(ldstrIndex + 1, 1);
@ -68,8 +68,8 @@ namespace de4dot.code {
class MyCallResult : CallResult {
public int methodId;
public GenericInstanceMethod gim;
public MyCallResult(Block block, int callEndIndex, int methodId, GenericInstanceMethod gim)
public MethodSpec gim;
public MyCallResult(Block block, int callEndIndex, int methodId, MethodSpec gim)
: base(block, callEndIndex) {
this.methodId = methodId;
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;
if (!methodTokenToId.TryGetValue(method.MetadataToken.ToInt32(), out methodId))
if (!methodTokenToId.TryGetValue(method.MDToken.ToInt32(), out methodId))
return null;
return new MyCallResult(block, callInstrIndex, methodId, gim);
}
@ -117,7 +117,7 @@ namespace de4dot.code {
AssemblyData.SimpleData.pack(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)
throw new ApplicationException("Invalid decrypted strings array length");
AssemblyData.SimpleData.unpack(decryptedStrings);
@ -128,27 +128,27 @@ namespace de4dot.code {
}
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 {
get { return stringDecrypters.Count != 0; }
}
public IEnumerable<MethodDefinition> Methods {
public IEnumerable<MethodDef> Methods {
get { return stringDecrypters.getKeys(); }
}
class MyCallResult : CallResult {
public MethodReference methodReference;
public GenericInstanceMethod gim;
public MyCallResult(Block block, int callEndIndex, MethodReference method, GenericInstanceMethod gim)
public IMethod IMethod;
public MethodSpec gim;
public MyCallResult(Block block, int callEndIndex, IMethod method, MethodSpec gim)
: base(block, callEndIndex) {
this.methodReference = method;
this.IMethod = method;
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)
stringDecrypters.add(method, handler);
}
@ -156,12 +156,12 @@ namespace de4dot.code {
protected override void inlineAllCalls() {
foreach (var tmp in callResults) {
var callResult = (MyCallResult)tmp;
var handler = stringDecrypters.find(callResult.methodReference);
callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.gim, callResult.args);
var handler = stringDecrypters.find(callResult.IMethod);
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)
return null;
return new MyCallResult(block, callInstrIndex, method, gim);

View File

@ -214,12 +214,6 @@ namespace de4dot.code {
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) {
// 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.

View File

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

View File

@ -120,7 +120,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return false;
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;
}

View File

@ -392,7 +392,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm {
static Instruction ldc_read(BinaryReader reader) {
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.R4: return Instruction.Create(OpCodes.Ldc_R4, reader.ReadSingle());
case ElementType.R8: return Instruction.Create(OpCodes.Ldc_R8, reader.ReadDouble());

View File

@ -115,7 +115,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return false;
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;
}
@ -140,7 +140,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return false;
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;
}

View File

@ -18,8 +18,8 @@
*/
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code.deobfuscators {
@ -28,7 +28,7 @@ namespace de4dot.code.deobfuscators {
public int NumRemovedExceptionLoggers { get; set; }
public void add(MethodDefinition exceptionLogger) {
public void add(MethodDef exceptionLogger) {
exceptionLoggerMethods.add(exceptionLogger, true);
}
@ -42,7 +42,7 @@ namespace de4dot.code.deobfuscators {
if (tryBlock.TryHandlerBlocks.Count != 1)
continue;
var catchBlock = tryBlock.TryHandlerBlocks[0];
if (catchBlock.HandlerType != ExceptionHandlerType.Catch ||
if (catchBlock.HandlerType != ExceptionClause.Catch ||
catchBlock.CatchType.FullName != "System.Exception") {
continue;
}
@ -74,7 +74,7 @@ namespace de4dot.code.deobfuscators {
}
if (failed || calls != 1 || callInstr.OpCode.Code != Code.Call)
continue;
var calledMethod = callInstr.Operand as MethodReference;
var calledMethod = callInstr.Operand as IMethod;
if (calledMethod == null)
continue;
if (!isExceptionLogger(calledMethod))
@ -86,7 +86,7 @@ namespace de4dot.code.deobfuscators {
return false;
}
protected virtual bool isExceptionLogger(MethodReference method) {
protected virtual bool isExceptionLogger(IMethod method) {
return exceptionLoggerMethods.find(method);
}

View File

@ -19,8 +19,7 @@
using System;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.MyStuff;
using dot10.DotNet;
using de4dot.blocks;
using de4dot.blocks.cflow;
#if PORT
@ -78,7 +77,7 @@ namespace de4dot.code.deobfuscators {
// Returns null or the unpacked .NET PE file
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).
// 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
// 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
void deobfuscateBegin();

View File

@ -17,12 +17,12 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using Mono.Cecil;
using dot10.DotNet;
namespace de4dot.code.deobfuscators {
public interface ISimpleDeobfuscator {
void deobfuscate(MethodDefinition method);
void deobfuscate(MethodDefinition method, bool force);
void decryptStrings(MethodDefinition method, IDeobfuscator deob);
void deobfuscate(MethodDef method);
void deobfuscate(MethodDef method, bool force);
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 Mono.Cecil;
using Mono.Cecil.Cil;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code.deobfuscators {
class MethodCallRestorerBase {
protected MemberReferenceBuilder builder;
protected ModuleDefinition module;
protected ModuleDefMD module;
MethodDefinitionAndDeclaringTypeDict<NewMethodInfo> oldToNewMethod = new MethodDefinitionAndDeclaringTypeDict<NewMethodInfo>();
class NewMethodInfo {
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.method = method;
}
}
public MethodCallRestorerBase(ModuleDefinition module) {
public MethodCallRestorerBase(ModuleDefMD module) {
this.module = module;
this.builder = new MemberReferenceBuilder(module);
}
public void createGetManifestResourceStream1(MethodDefinition oldMethod) {
public void createGetManifestResourceStream1(MethodDef oldMethod) {
if (oldMethod == null)
return;
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
@ -52,7 +52,7 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Callvirt);
}
public void createGetManifestResourceStream2(MethodDefinition oldMethod) {
public void createGetManifestResourceStream2(MethodDef oldMethod) {
if (oldMethod == null)
return;
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Callvirt);
}
public void createGetManifestResourceNames(MethodDefinition oldMethod) {
public void createGetManifestResourceNames(MethodDef oldMethod) {
if (oldMethod == null)
return;
var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib);
@ -71,7 +71,7 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Callvirt);
}
public void createBitmapCtor(MethodDefinition oldMethod) {
public void createBitmapCtor(MethodDef oldMethod) {
if (oldMethod == null)
return;
var bitmapType = builder.type("System.Drawing", "Bitmap", "System.Drawing");
@ -80,7 +80,7 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Newobj);
}
public void createIconCtor(MethodDefinition oldMethod) {
public void createIconCtor(MethodDef oldMethod) {
if (oldMethod == null)
return;
var iconType = builder.type("System.Drawing", "Icon", "System.Drawing");
@ -89,11 +89,11 @@ namespace de4dot.code.deobfuscators {
add(oldMethod, newMethod, OpCodes.Newobj);
}
protected void add(MethodDefinition oldMethod, MethodReference newMethod) {
protected void add(MethodDef oldMethod, IMethod newMethod) {
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)
return;
oldToNewMethod.add(oldMethod, new NewMethodInfo(opCode, newMethod));
@ -106,7 +106,7 @@ namespace de4dot.code.deobfuscators {
var call = instrs[i];
if (call.OpCode.Code != Code.Call)
continue;
var calledMethod = call.Operand as MethodDefinition;
var calledMethod = call.Operand as MethodDef;
if (calledMethod == null)
continue;

View File

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

View File

@ -17,7 +17,7 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using Mono.MyStuff;
using dot10.DotNet;
using de4dot.code.AssemblyClient;
using de4dot.mdecrypt;

View File

@ -19,8 +19,8 @@
using System;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using dot10.DotNet;
using dot10.DotNet.Emit;
namespace de4dot.code.deobfuscators {
class StringCounts {
@ -66,37 +66,37 @@ namespace de4dot.code.deobfuscators {
}
class FieldTypes : StringCounts {
public FieldTypes(TypeDefinition type) {
public FieldTypes(TypeDef type) {
init(type.Fields);
}
public FieldTypes(IEnumerable<FieldDefinition> fields) {
public FieldTypes(IEnumerable<FieldDef> fields) {
init(fields);
}
void init(IEnumerable<FieldDefinition> fields) {
void init(IEnumerable<FieldDef> fields) {
if (fields == null)
return;
foreach (var field in fields)
add(field.FieldType.FullName);
add(field.FieldSig.Type.FullName);
}
}
class LocalTypes : StringCounts {
public LocalTypes(MethodDefinition method) {
if (method != null && method.Body != null)
init(method.Body.Variables);
public LocalTypes(MethodDef method) {
if (method != null && method.CilBody != null)
init(method.CilBody.LocalList);
}
public LocalTypes(IEnumerable<VariableDefinition> locals) {
public LocalTypes(IEnumerable<Local> locals) {
init(locals);
}
void init(IEnumerable<VariableDefinition> locals) {
void init(IEnumerable<Local> locals) {
if (locals == null)
return;
foreach (var local in locals)
add(local.VariableType.FullName);
add(local.Type.FullName);
}
}
}

View File

@ -186,7 +186,7 @@ namespace de4dot.code.deobfuscators {
return;
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();
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());
@ -199,7 +199,7 @@ namespace de4dot.code.deobfuscators {
return;
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();
foreach (var updatedMethod in methods) {
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;
return Utils.compareInt32(a.arg.Sequence, b.arg.Sequence);
return a.arg.Sequence.CompareTo(b.arg.Sequence);
}
void deobfuscateMethod(MethodDef method) {

View File

@ -19,19 +19,19 @@
using System;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code.deobfuscators {
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;
class MyCallResult : CallResult {
public MethodReference methodReference;
public GenericInstanceMethod gim;
public MyCallResult(Block block, int callEndIndex, MethodReference method, GenericInstanceMethod gim)
public IMethod methodReference;
public MethodSpec gim;
public MyCallResult(Block block, int callEndIndex, IMethod method, MethodSpec gim)
: base(block, callEndIndex) {
this.methodReference = method;
this.gim = gim;
@ -47,15 +47,15 @@ namespace de4dot.code.deobfuscators {
get { return decrypterMethods.Count != 0; }
}
public IEnumerable<MethodDefinition> Methods {
public IEnumerable<MethodDef> Methods {
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)
return;
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)
decrypterMethods.add(method, handler);
}
@ -64,11 +64,11 @@ namespace de4dot.code.deobfuscators {
foreach (var tmp in callResults) {
var callResult = (MyCallResult)tmp;
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)
return null;
return new MyCallResult(block, callInstrIndex, method, gim);
@ -83,7 +83,7 @@ namespace de4dot.code.deobfuscators {
var unbox = instrs[index];
if (unbox.OpCode.Code != Code.Unbox_Any)
return false;
var type = unbox.Operand as TypeReference;
var type = unbox.Operand as ITypeDefOrRef;
if (type == null || type.FullName != unboxType)
return false;
block.remove(index, 1);
@ -97,7 +97,7 @@ namespace de4dot.code.deobfuscators {
var block = callResult.block;
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");
Log.v("Decrypted boolean: {0}", callResult.returnValue);
}
@ -110,7 +110,7 @@ namespace de4dot.code.deobfuscators {
var block = callResult.block;
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");
Log.v("Decrypted int32: {0}", callResult.returnValue);
}

View File

@ -227,7 +227,7 @@ namespace de4dot.code.resources {
public List<UserResourceType> getSortedTypes() {
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;
}
}

View File

@ -109,7 +109,7 @@ namespace de4dot.code.resources {
}
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 {

2
dot10

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