Port more code
This commit is contained in:
parent
3b6ef4fa1f
commit
1341cc7199
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
2
dot10
|
@ -1 +1 @@
|
|||
Subproject commit 7eb0fb7e6e47c79eebbef0ea9ea404f9b81fde51
|
||||
Subproject commit 3b128874ff6bd531f588c487e9aeb76fb62acfec
|
Loading…
Reference in New Issue
Block a user