diff --git a/blocks/DotNetUtils.cs b/blocks/DotNetUtils.cs
index 96f066fa..350f5251 100644
--- a/blocks/DotNetUtils.cs
+++ b/blocks/DotNetUtils.cs
@@ -202,7 +202,7 @@ namespace de4dot.blocks {
var sig = method.MethodSig;
if (sig == null || !method.HasBody || !sig.IsDefault)
continue;
- if (method.IsStatic != isStatic || method.Parameters.Count != argsTypes.Length)
+ if (method.IsStatic != isStatic || sig.Params.Count != argsTypes.Length)
continue;
if (sig.GenParamCount > 0)
continue;
@@ -248,23 +248,24 @@ namespace de4dot.blocks {
return dll;
}
-#if PORT
- public static bool hasPinvokeMethod(TypeDefinition type, string methodName) {
+ public static bool hasPinvokeMethod(TypeDef type, string methodName) {
return getPInvokeMethod(type, methodName) != null;
}
- public static MethodDef getPInvokeMethod(TypeDefinition type, string methodName) {
+ public static MethodDef getPInvokeMethod(TypeDef type, string methodName) {
if (type == null)
return null;
+ var mname = new UTF8String(methodName);
foreach (var method in type.Methods) {
- if (method.PInvokeInfo == null)
+ if (method.ImplMap == null)
continue;
- if (method.PInvokeInfo.EntryPoint == methodName)
+ if (UTF8String.Equals(method.ImplMap.Name, mname))
return method;
}
return null;
}
+#if PORT
public static MethodDef getPInvokeMethod(TypeDefinition type, string dll, string funcName) {
foreach (var method in type.Methods) {
if (isPinvokeMethod(method, dll, funcName))
diff --git a/blocks/cflow/MethodCallInlinerBase.cs b/blocks/cflow/MethodCallInlinerBase.cs
index e647890b..970d87b1 100644
--- a/blocks/cflow/MethodCallInlinerBase.cs
+++ b/blocks/cflow/MethodCallInlinerBase.cs
@@ -165,10 +165,10 @@ namespace de4dot.blocks.cflow {
var methodArgs = methodToInline.Parameters;
var calledMethodArgs = DotNetUtils.getArgs(ctor);
- if (methodArgs.Count + 1 - popLastArgs != calledMethodArgs.Count)
+ if (methodArgs.Count - popLastArgs != calledMethodArgs.Count)
return null;
for (int i = 1; i < calledMethodArgs.Count; i++) {
- if (!isCompatibleType(i, calledMethodArgs[i], methodArgs[i - 1].Type))
+ if (!isCompatibleType(i, calledMethodArgs[i], methodArgs[i].Type))
return null;
}
diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj
index a5f5fc42..2480c28d 100644
--- a/de4dot.code/de4dot.code.csproj
+++ b/de4dot.code/de4dot.code.csproj
@@ -57,25 +57,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/de4dot.code/deobfuscators/Agile_NET/CliSecureRtType.cs b/de4dot.code/deobfuscators/Agile_NET/CliSecureRtType.cs
index 0a712abb..cb92be22 100644
--- a/de4dot.code/deobfuscators/Agile_NET/CliSecureRtType.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/CliSecureRtType.cs
@@ -26,7 +26,7 @@ using de4dot.PE;
namespace de4dot.code.deobfuscators.Agile_NET {
class CliSecureRtType {
- ModuleDefinition module;
+ ModuleDefMD module;
TypeDef cliSecureRtType;
MethodDef postInitializeMethod;
MethodDef initializeMethod;
@@ -58,27 +58,11 @@ namespace de4dot.code.deobfuscators.Agile_NET {
get { return loadMethod; }
}
- public IEnumerable DecryptModuleReferences {
- get {
- var list = new List();
- addModuleReference(list, "_Initialize");
- addModuleReference(list, "_Initialize64");
- return list;
- }
- }
-
- void addModuleReference(List list, string methodName) {
- var method = DotNetUtils.getPInvokeMethod(cliSecureRtType, methodName);
- if (method == null)
- return;
- list.Add(method.PInvokeInfo.Module);
- }
-
- public CliSecureRtType(ModuleDefinition module) {
+ public CliSecureRtType(ModuleDefMD module) {
this.module = module;
}
- public CliSecureRtType(ModuleDefinition module, CliSecureRtType oldOne) {
+ public CliSecureRtType(ModuleDefMD module, CliSecureRtType oldOne) {
this.module = module;
cliSecureRtType = lookup(oldOne.cliSecureRtType, "Could not find CliSecureRt type");
postInitializeMethod = lookup(oldOne.postInitializeMethod, "Could not find postInitializeMethod method");
@@ -88,7 +72,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
foundSig = oldOne.foundSig;
}
- T lookup(T def, string errorMessage) where T : MemberReference {
+ T lookup(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.lookup(module, def, errorMessage);
}
@@ -147,13 +131,13 @@ namespace de4dot.code.deobfuscators.Agile_NET {
foreach (var type in module.Types) {
if (type.Fields.Count != 1)
continue;
- if (type.Fields[0].FieldType.FullName != "System.Byte[]")
+ if (type.Fields[0].FieldSig.GetFieldType().GetFullName() != "System.Byte[]")
continue;
if (type.Methods.Count != 2)
continue;
- if (DotNetUtils.getMethod(type, ".cctor") == null)
+ if (type.FindClassConstructor() == null)
continue;
- var cs = DotNetUtils.getMethod(type, "cs");
+ var cs = type.FindMethod("cs");
if (cs == null)
continue;
@@ -196,12 +180,13 @@ namespace de4dot.code.deobfuscators.Agile_NET {
var method = DotNetUtils.getPInvokeMethod(type, name);
if (method == null)
return false;
- if (method.Parameters.Count != 1)
+ var sig = method.MethodSig;
+ if (sig.Params.Count != 1)
return false;
- if (method.Parameters[0].ParameterType.FullName != "System.IntPtr")
+ if (sig.Params[0].GetElementType() != ElementType.I)
return false;
- var retType = method.MethodReturnType.ReturnType.FullName;
- if (retType != "System.Void" && retType != "System.Int32")
+ var retType = sig.RetType.GetElementType();
+ if (retType != ElementType.Void && retType != ElementType.I4)
return false;
return true;
}
@@ -209,7 +194,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
bool findNativeCode(byte[] moduleBytes) {
var stream = moduleBytes != null ?
(Stream)new MemoryStream(moduleBytes) :
- (Stream)new FileStream(module.FullyQualifiedName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ (Stream)new FileStream(module.Location, FileMode.Open, FileAccess.Read, FileShare.Read);
using (stream) {
var peImage = new PeImage(stream);
return foundSig = MethodsDecrypter.detect(peImage);
diff --git a/de4dot.code/deobfuscators/Agile_NET/Deobfuscator.cs b/de4dot.code/deobfuscators/Agile_NET/Deobfuscator.cs
index 52af594e..216bbfc5 100644
--- a/de4dot.code/deobfuscators/Agile_NET/Deobfuscator.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/Deobfuscator.cs
@@ -19,8 +19,9 @@
using System;
using System.Collections.Generic;
+using dot10.PE;
using dot10.DotNet;
-using Mono.MyStuff;
+using dot10.DotNet.MD;
using de4dot.blocks;
using de4dot.PE;
@@ -112,16 +113,17 @@ namespace de4dot.code.deobfuscators.Agile_NET {
this.options = options;
}
- public override void init(ModuleDefinition module) {
+ public override void init(ModuleDefMD module) {
base.init(module);
}
- public override byte[] unpackNativeFile(PeImage peImage) {
+ public override byte[] unpackNativeFile(PEImage peImage) {
return unpackNativeFile1(peImage) ?? unpackNativeFile2(peImage);
}
// Old CS versions
- byte[] unpackNativeFile1(PeImage peImage) {
+ byte[] unpackNativeFile1(PEImage peImage) {
+#if PORT
const int dataDirNum = 6; // debug dir
const int dotNetDirNum = 14;
@@ -139,10 +141,14 @@ namespace de4dot.code.deobfuscators.Agile_NET {
writeUInt32(fileData, dataDir + 4, 0);
ModuleBytes = fileData;
return fileData;
+#else
+ return null;
+#endif
}
// CS 1.x
- byte[] unpackNativeFile2(PeImage peImage) {
+ byte[] unpackNativeFile2(PEImage peImage) {
+#if PORT
var dir = peImage.Resources.getRoot();
if ((dir = dir.getDirectory("ASSEMBLY")) == null)
return null;
@@ -153,6 +159,9 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return null;
return ModuleBytes = peImage.readBytes(data.RVA, (int)data.Size);
+#else
+ return null;
+#endif
}
static void writeUInt32(byte[] data, int offset, uint value) {
@@ -221,7 +230,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return true;
}
- public override IDeobfuscator moduleReloaded(ModuleDefinition module) {
+ public override IDeobfuscator moduleReloaded(ModuleDefMD module) {
var newOne = new Deobfuscator(options);
newOne.setModule(module);
newOne.cliSecureAttributes = lookup(module, cliSecureAttributes, "Could not find CliSecure attribute");
@@ -233,7 +242,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return newOne;
}
- static List lookup(ModuleDefinition module, List types, string errorMsg) {
+ static List lookup(ModuleDefMD module, List types, string errorMsg) {
var list = new List(types.Count);
foreach (var type in types)
list.Add(DeobUtils.lookup(module, type, errorMsg));
@@ -274,7 +283,6 @@ namespace de4dot.code.deobfuscators.Agile_NET {
if (options.RestoreVmCode) {
csvm.restore();
- addAssemblyReferenceToBeRemoved(csvm.VmAssemblyReference, "CSVM assembly reference");
addResourceToBeRemoved(csvm.Resource, "CSVM data resource");
}
}
@@ -308,11 +316,9 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
if (options.DecryptMethods) {
addResources("Obfuscator protection files");
- addModuleReferencesToBeRemoved(cliSecureRtType.DecryptModuleReferences, "Obfuscator protection files");
- addModuleReferences("Obfuscator protection files");
}
- module.Attributes |= ModuleAttributes.ILOnly;
+ module.Cor20HeaderFlags |= ComImageFlags.ILOnly;
base.deobfuscateEnd();
}
diff --git a/de4dot.code/deobfuscators/Agile_NET/MethodsDecrypter.cs b/de4dot.code/deobfuscators/Agile_NET/MethodsDecrypter.cs
index 9a05b472..2e07f7e2 100644
--- a/de4dot.code/deobfuscators/Agile_NET/MethodsDecrypter.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/MethodsDecrypter.cs
@@ -20,7 +20,8 @@
using System;
using System.Collections.Generic;
using System.IO;
-using Mono.MyStuff;
+using dot10.DotNet;
+using dot10.DotNet.MD;
using de4dot.PE;
using de4dot.blocks;
@@ -62,7 +63,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
PeImage peImage;
- Mono.Cecil.ModuleDefinition module;
+ ModuleDefMD module;
CliSecureRtType csRtType;
CodeHeader codeHeader = new CodeHeader();
IDecrypter decrypter;
@@ -155,7 +156,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
public Decrypter5(PeImage peImage, CodeHeader codeHeader, uint codeHeaderSize)
: base(peImage, codeHeader) {
- this.codeHeaderSize = codeHeaderSize;
+ this.codeHeaderSize = codeHeaderSize;
}
public override MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
@@ -434,7 +435,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
Error,
}
- public bool decrypt(PeImage peImage, Mono.Cecil.ModuleDefinition module, CliSecureRtType csRtType, ref DumpedMethods dumpedMethods) {
+ public bool decrypt(PeImage peImage, ModuleDefMD module, CliSecureRtType csRtType, ref DumpedMethods dumpedMethods) {
this.peImage = peImage;
this.csRtType = csRtType;
this.module = module;
@@ -446,7 +447,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
case DecryptResult.Error:
Log.w("Using dynamic method decryption");
byte[] moduleCctorBytes = getModuleCctorBytes(csRtType);
- dumpedMethods = de4dot.code.deobfuscators.MethodsDecrypter.decrypt(module.FullyQualifiedName, moduleCctorBytes);
+ dumpedMethods = de4dot.code.deobfuscators.MethodsDecrypter.decrypt(module.Location, moduleCctorBytes);
return true;
default:
@@ -542,7 +543,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
var dm = new DumpedMethod();
dm.token = 0x06000001 + (uint)i;
- var method = (Mono.Cecil.MethodDef)module.LookupToken((int)dm.token);
+ var method = (MethodDef)module.ResolveMethod(MDToken.ToRID(dm.token));
if (method == null || method.DeclaringType == DotNetUtils.getModuleType(module))
continue;
diff --git a/de4dot.code/deobfuscators/Agile_NET/ProxyCallFixer.cs b/de4dot.code/deobfuscators/Agile_NET/ProxyCallFixer.cs
index 1883e78f..09aaaae5 100644
--- a/de4dot.code/deobfuscators/Agile_NET/ProxyCallFixer.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/ProxyCallFixer.cs
@@ -25,13 +25,11 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET {
class ProxyCallFixer : ProxyCallFixer1 {
- IList memberReferences;
-
- public ProxyCallFixer(ModuleDefinition module)
+ public ProxyCallFixer(ModuleDefMD module)
: base(module) {
}
- public ProxyCallFixer(ModuleDefinition module, ProxyCallFixer oldOne)
+ public ProxyCallFixer(ModuleDefMD module, ProxyCallFixer oldOne)
: base(module) {
foreach (var method in oldOne.delegateCreatorMethods)
setDelegateCreatorMethod(lookup(method, "Could not find delegate creator method"));
@@ -53,14 +51,14 @@ namespace de4dot.code.deobfuscators.Agile_NET {
var instrs = cctor.Body.Instructions;
if (instrs.Count != 3)
return null;
- if (!DotNetUtils.isLdcI4(instrs[0].OpCode.Code))
+ if (!instrs[0].IsLdcI4())
return null;
if (instrs[1].OpCode != OpCodes.Call || !isDelegateCreatorMethod(instrs[1].Operand as MethodDef))
return null;
if (instrs[2].OpCode != OpCodes.Ret)
return null;
- int delegateToken = 0x02000001 + DotNetUtils.getLdcI4Value(instrs[0]);
+ int delegateToken = 0x02000001 + instrs[0].GetLdcI4Value();
if (type.MDToken.ToInt32() != delegateToken) {
Log.w("Delegate token is not current type");
return null;
@@ -69,11 +67,8 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return new object();
}
- protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
- if (memberReferences == null)
- memberReferences = new List(module.GetMemberReferences());
-
- var name = field.Name;
+ protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
+ var name = field.Name.String;
callOpcode = OpCodes.Call;
if (name.EndsWith("%", StringComparison.Ordinal)) {
callOpcode = OpCodes.Callvirt;
@@ -81,9 +76,10 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
byte[] value = Convert.FromBase64String(name);
int methodIndex = BitConverter.ToInt32(value, 0); // 0-based memberRef index
- if (methodIndex >= memberReferences.Count)
- throw new ApplicationException(string.Format("methodIndex ({0}) >= memberReferences.Count ({1})", methodIndex, memberReferences.Count));
- calledMethod = memberReferences[methodIndex] as MethodReference;
+ var mr = module.ResolveMemberRef((uint)methodIndex + 1);
+ if (mr == null || !mr.IsMethodRef)
+ throw new ApplicationException(string.Format("Invalid MemberRef index: {0}", methodIndex));
+ calledMethod = mr;
}
}
}
diff --git a/de4dot.code/deobfuscators/Agile_NET/ResourceDecrypter.cs b/de4dot.code/deobfuscators/Agile_NET/ResourceDecrypter.cs
index 9f4b5166..3766aff1 100644
--- a/de4dot.code/deobfuscators/Agile_NET/ResourceDecrypter.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/ResourceDecrypter.cs
@@ -20,12 +20,13 @@
using System.IO;
using System.Security.Cryptography;
using System.Text;
+using dot10.IO;
using dot10.DotNet;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET {
class ResourceDecrypter {
- ModuleDefinition module;
+ ModuleDefMD module;
TypeDef rsrcType;
MethodDef rsrcRrrMethod;
MethodDef rsrcResolveMethod;
@@ -42,18 +43,18 @@ namespace de4dot.code.deobfuscators.Agile_NET {
get { return rsrcRrrMethod; }
}
- public ResourceDecrypter(ModuleDefinition module) {
+ public ResourceDecrypter(ModuleDefMD module) {
this.module = module;
}
- public ResourceDecrypter(ModuleDefinition module, ResourceDecrypter oldOne) {
+ public ResourceDecrypter(ModuleDefMD module, ResourceDecrypter oldOne) {
this.module = module;
rsrcType = lookup(oldOne.rsrcType, "Could not find rsrcType");
rsrcRrrMethod = lookup(oldOne.rsrcRrrMethod, "Could not find rsrcRrrMethod");
rsrcResolveMethod = lookup(oldOne.rsrcResolveMethod, "Could not find rsrcResolveMethod");
}
- T lookup(T def, string errorMessage) where T : MemberReference {
+ T lookup(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.lookup(module, def, errorMessage);
}
@@ -99,23 +100,21 @@ namespace de4dot.code.deobfuscators.Agile_NET {
var resource = DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(rsrcResolveMethod)) as EmbeddedResource;
if (resource == null)
return null;
- DeobUtils.decryptAndAddResources(module, resource.Name, () => decryptResource(resource));
+ DeobUtils.decryptAndAddResources(module, resource.Name.String, () => decryptResource(resource));
return resource;
}
byte[] decryptResource(EmbeddedResource resource) {
- using (var rsrcStream = resource.GetResourceStream()) {
- using (var reader = new BinaryReader(rsrcStream)) {
- var key = reader.ReadString();
- var data = reader.ReadBytes((int)(rsrcStream.Length - rsrcStream.Position));
- var cryptoTransform = new DESCryptoServiceProvider {
- Key = Encoding.ASCII.GetBytes(key),
- IV = Encoding.ASCII.GetBytes(key),
- }.CreateDecryptor();
- var memStream = new MemoryStream(data);
- using (var reader2 = new BinaryReader(new CryptoStream(memStream, cryptoTransform, CryptoStreamMode.Read))) {
- return reader2.ReadBytes((int)memStream.Length);
- }
+ using (var reader = resource.Data) {
+ var key = reader.ReadString();
+ var data = reader.ReadBytes((int)(reader.Length - reader.Position));
+ var cryptoTransform = new DESCryptoServiceProvider {
+ Key = Encoding.ASCII.GetBytes(key),
+ IV = Encoding.ASCII.GetBytes(key),
+ }.CreateDecryptor();
+ var memStream = new MemoryStream(data);
+ using (var reader2 = new BinaryReader(new CryptoStream(memStream, cryptoTransform, CryptoStreamMode.Read))) {
+ return reader2.ReadBytes((int)memStream.Length);
}
}
}
diff --git a/de4dot.code/deobfuscators/Agile_NET/StackFrameHelper.cs b/de4dot.code/deobfuscators/Agile_NET/StackFrameHelper.cs
index f4ef0696..7313c5e9 100644
--- a/de4dot.code/deobfuscators/Agile_NET/StackFrameHelper.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/StackFrameHelper.cs
@@ -23,7 +23,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET {
class StackFrameHelper {
- ModuleDefinition module;
+ ModuleDefMD module;
TypeDef stackFrameHelperType;
ExceptionLoggerRemover exceptionLoggerRemover = new ExceptionLoggerRemover();
@@ -35,7 +35,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
get { return exceptionLoggerRemover; }
}
- public StackFrameHelper(ModuleDefinition module) {
+ public StackFrameHelper(ModuleDefMD module) {
this.module = module;
}
@@ -48,17 +48,16 @@ namespace de4dot.code.deobfuscators.Agile_NET {
MethodDef errorMethod = null;
foreach (var method in type.Methods) {
- if (method.IsRuntimeSpecialName && method.Name == ".ctor" && !method.HasParameters)
+ if (method.Name == ".ctor")
continue; // .ctor is allowed
- if (method.IsRuntimeSpecialName && method.Name == ".cctor" && !method.HasParameters)
+ if (method.Name == ".cctor")
continue; // .cctor is allowed
- if (method.IsStatic && method.CallingConvention == MethodCallingConvention.Default &&
- method.ExplicitThis == false && method.HasThis == false &&
- method.HasBody && method.IsManaged && method.IsIL && method.HasParameters &&
- method.Parameters.Count == 2 && !method.HasGenericParameters &&
+ var sig = method.MethodSig;
+ if (sig != null && method.IsStatic && method.HasBody &&
+ sig.Params.Count == 2 && !method.HasGenericParameters &&
!DotNetUtils.hasReturnValue(method) &&
- method.Parameters[0].ParameterType.FullName == "System.Exception" &&
- method.Parameters[1].ParameterType.FullName == "System.Object[]") {
+ sig.Params[0].GetFullName() == "System.Exception" &&
+ sig.Params[1].GetFullName() == "System.Object[]") {
errorMethod = method;
}
else
diff --git a/de4dot.code/deobfuscators/Agile_NET/StringDecrypter.cs b/de4dot.code/deobfuscators/Agile_NET/StringDecrypter.cs
index 1d67c966..c7b858d6 100644
--- a/de4dot.code/deobfuscators/Agile_NET/StringDecrypter.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/StringDecrypter.cs
@@ -23,7 +23,7 @@ using dot10.DotNet;
namespace de4dot.code.deobfuscators.Agile_NET {
class StringDecrypter {
- ModuleDefinition module;
+ ModuleDefMD module;
TypeDef stringDecrypterType;
MethodDef stringDecrypterMethod;
byte[] stringDecrypterKey;
@@ -41,19 +41,19 @@ namespace de4dot.code.deobfuscators.Agile_NET {
set { stringDecrypterMethod = value; }
}
- public StringDecrypter(ModuleDefinition module, MethodDef stringDecrypterMethod) {
+ public StringDecrypter(ModuleDefMD module, MethodDef stringDecrypterMethod) {
this.module = module;
this.stringDecrypterMethod = stringDecrypterMethod;
}
- public StringDecrypter(ModuleDefinition module, StringDecrypter oldOne) {
+ public StringDecrypter(ModuleDefMD module, StringDecrypter oldOne) {
this.module = module;
stringDecrypterType = lookup(oldOne.stringDecrypterType, "Could not find stringDecrypterType");
stringDecrypterMethod = lookup(oldOne.stringDecrypterMethod, "Could not find stringDecrypterMethod");
stringDecrypterKey = oldOne.stringDecrypterKey;
}
- T lookup(T def, string errorMessage) where T : MemberReference {
+ T lookup(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.lookup(module, def, errorMessage);
}
diff --git a/de4dot.code/deobfuscators/Agile_NET/vm/CilOperandInstructionRestorer.cs b/de4dot.code/deobfuscators/Agile_NET/vm/CilOperandInstructionRestorer.cs
index 65465f7a..4a5e9d4d 100644
--- a/de4dot.code/deobfuscators/Agile_NET/vm/CilOperandInstructionRestorer.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/vm/CilOperandInstructionRestorer.cs
@@ -19,7 +19,6 @@
using dot10.DotNet;
using dot10.DotNet.Emit;
-using Mono.Cecil.Metadata;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET.vm {
@@ -43,13 +42,13 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
if (instr.Operand != null)
continue;
- TypeReference operandType = null;
+ TypeSig operandType = null;
switch (instr.OpCode.Code) {
case Code.Ldelema:
- var arrayType = MethodStack.getLoadedType(method, instrs, i, 1) as ArrayType;
+ var arrayType = MethodStack.getLoadedType(method, instrs, i, 1) as SZArraySig;
if (arrayType == null)
break;
- operandType = arrayType.ElementType;
+ operandType = arrayType.Next;
break;
case Code.Ldobj:
@@ -70,58 +69,58 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
continue;
}
- instr.Operand = operandType;
+ instr.Operand = operandType.ToTypeDefOrRef();
}
return !atLeastOneFailed;
}
- static TypeReference getPtrElementType(TypeReference type) {
+ static TypeSig getPtrElementType(TypeSig type) {
if (type == null)
return null;
- var pt = type as PointerType;
- if (pt != null)
- return pt.ElementType;
- var bt = type as ByReferenceType;
- if (bt != null)
- return bt.ElementType;
+ if (type.IsPointer || type.IsByRef)
+ return type.Next;
return null;
}
- bool isValidType(TypeReference type) {
+ bool isValidType(TypeSig type) {
+ type = type.RemovePinnedAndModifiers();
if (type == null)
return false;
- if (type.EType == ElementType.Void)
+ if (type.ElementType == ElementType.Void)
return false;
while (type != null) {
- switch (MemberReferenceHelper.getMemberReferenceType(type)) {
- case CecilType.ArrayType:
- case CecilType.GenericInstanceType:
- case CecilType.PointerType:
- case CecilType.TypeDef:
- case CecilType.TypeReference:
- case CecilType.FunctionPointerType:
+ switch (type.ElementType) {
+ case ElementType.SZArray:
+ case ElementType.Array:
+ case ElementType.GenericInst:
+ case ElementType.Ptr:
+ case ElementType.Class:
+ case ElementType.ValueType:
+ case ElementType.FnPtr:
break;
- case CecilType.GenericParam:
- var gp = (GenericParam)type;
- if (method.DeclaringType != gp.Owner && method != gp.Owner)
+ case ElementType.MVar:
+ var gmvar = (GenericMVar)type;
+ if (gmvar.Number >= method.MethodSig.GetGenParamCount())
return false;
break;
- case CecilType.ByReferenceType:
- case CecilType.OptionalModifierType:
- case CecilType.PinnedType:
- case CecilType.RequiredModifierType:
- case CecilType.SentinelType:
+ case ElementType.Var:
+ var gvar = (GenericVar)type;
+ var dt = method.DeclaringType;
+ if (dt == null || gvar.Number >= dt.GenericParams.Count)
+ return false;
+ break;
+
+ case ElementType.ByRef:
default:
return false;
}
-
- if (!(type is TypeSpecification))
+ if (type.Next == null)
break;
- type = ((TypeSpecification)type).ElementType;
+ type = type.Next;
}
return type != null;
diff --git a/de4dot.code/deobfuscators/Agile_NET/vm/Csvm.cs b/de4dot.code/deobfuscators/Agile_NET/vm/Csvm.cs
index 44bbe92f..5d22f5b4 100644
--- a/de4dot.code/deobfuscators/Agile_NET/vm/Csvm.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/vm/Csvm.cs
@@ -26,9 +26,9 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET.vm {
class Csvm {
IDeobfuscatorContext deobfuscatorContext;
- ModuleDefinition module;
+ ModuleDefMD module;
EmbeddedResource resource;
- AssemblyNameReference vmAssemblyReference;
+ AssemblyRef vmAssemblyReference;
public bool Detected {
get { return resource != null && vmAssemblyReference != null; }
@@ -38,22 +38,22 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
get { return Detected ? resource : null; }
}
- public AssemblyNameReference VmAssemblyReference {
+ public AssemblyRef VmAssemblyReference {
get { return Detected ? vmAssemblyReference : null; }
}
- public Csvm(IDeobfuscatorContext deobfuscatorContext, ModuleDefinition module) {
+ public Csvm(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module) {
this.deobfuscatorContext = deobfuscatorContext;
this.module = module;
}
- public Csvm(IDeobfuscatorContext deobfuscatorContext, ModuleDefinition module, Csvm oldOne) {
+ public Csvm(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module, Csvm oldOne) {
this.deobfuscatorContext = deobfuscatorContext;
this.module = module;
if (oldOne.resource != null)
this.resource = (EmbeddedResource)module.Resources[oldOne.module.Resources.IndexOf(oldOne.resource)];
if (oldOne.vmAssemblyReference != null)
- this.vmAssemblyReference = module.AssemblyReferences[oldOne.module.AssemblyReferences.IndexOf(oldOne.vmAssemblyReference)];
+ this.vmAssemblyReference = module.ResolveAssemblyRef(oldOne.vmAssemblyReference.Rid);
}
public void find() {
@@ -61,13 +61,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
vmAssemblyReference = findVmAssemblyReference();
}
- AssemblyNameReference findVmAssemblyReference() {
- foreach (var memberRef in module.GetMemberReferences()) {
- var method = memberRef as MethodReference;
- if (method == null)
+ AssemblyRef findVmAssemblyReference() {
+ foreach (var memberRef in module.GetMemberRefs()) {
+ if (!memberRef.IsMethodRef)
continue;
- if (method.FullName == "System.Object VMRuntime.Libraries.CSVMRuntime::RunMethod(System.String,System.Object[])")
- return method.DeclaringType.Scope as AssemblyNameReference;
+ if (memberRef.FullName == "System.Object VMRuntime.Libraries.CSVMRuntime::RunMethod(System.String,System.Object[])")
+ return memberRef.DeclaringType.Scope as AssemblyRef;
}
return null;
}
@@ -94,11 +93,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
Log.indent();
var opcodeDetector = getVmOpCodeHandlerDetector();
- var csvmMethods = new CsvmDataReader(resource.GetResourceStream()).read();
+ var csvmMethods = new CsvmDataReader(resource.Data).read();
var converter = new CsvmToCilMethodConverter(deobfuscatorContext, module, opcodeDetector);
var methodPrinter = new MethodPrinter();
foreach (var csvmMethod in csvmMethods) {
- var cilMethod = module.LookupToken(csvmMethod.Token) as MethodDef;
+ var cilMethod = module.ResolveToken(csvmMethod.Token) as MethodDef;
if (cilMethod == null)
throw new ApplicationException(string.Format("Could not find method {0:X8}", csvmMethod.Token));
converter.convert(cilMethod, csvmMethod);
@@ -117,8 +116,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
Log.v("Locals:");
Log.indent();
- for (int i = 0; i < method.Body.Variables.Count; i++)
- Log.v("#{0}: {1}", i, method.Body.Variables[i].VariableType);
+ for (int i = 0; i < method.Body.LocalList.Count; i++)
+ Log.v("#{0}: {1}", i, method.Body.LocalList[i].Type);
Log.deIndent();
Log.v("Code:");
@@ -131,7 +130,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
VmOpCodeHandlerDetector getVmOpCodeHandlerDetector() {
var vmFilename = vmAssemblyReference.Name + ".dll";
- var vmModulePath = Path.Combine(Path.GetDirectoryName(module.FullyQualifiedName), vmFilename);
+ var vmModulePath = Path.Combine(Path.GetDirectoryName(module.Location), vmFilename);
Log.v("CSVM filename: {0}", vmFilename);
var dataKey = "cs cached VmOpCodeHandlerDetector";
@@ -141,7 +140,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
VmOpCodeHandlerDetector detector;
if (dict.TryGetValue(vmModulePath, out detector))
return detector;
- dict[vmModulePath] = detector = new VmOpCodeHandlerDetector(ModuleDefinition.ReadModule(vmModulePath));
+ dict[vmModulePath] = detector = new VmOpCodeHandlerDetector(ModuleDefMD.Load(vmModulePath));
detector.findHandlers();
Log.v("CSVM opcodes:");
diff --git a/de4dot.code/deobfuscators/Agile_NET/vm/CsvmDataReader.cs b/de4dot.code/deobfuscators/Agile_NET/vm/CsvmDataReader.cs
index 1efea978..c4201947 100644
--- a/de4dot.code/deobfuscators/Agile_NET/vm/CsvmDataReader.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/vm/CsvmDataReader.cs
@@ -20,15 +20,16 @@
using System;
using System.Collections.Generic;
using System.IO;
+using dot10.IO;
using dot10.DotNet;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET.vm {
class CsvmDataReader {
- BinaryReader reader;
+ IBinaryReader reader;
- public CsvmDataReader(Stream stream) {
- reader = new BinaryReader(stream);
+ public CsvmDataReader(IBinaryReader reader) {
+ this.reader = reader;
}
public List read() {
diff --git a/de4dot.code/deobfuscators/Agile_NET/vm/CsvmToCilMethodConverter.cs b/de4dot.code/deobfuscators/Agile_NET/vm/CsvmToCilMethodConverter.cs
index 227bb866..ce8aa469 100644
--- a/de4dot.code/deobfuscators/Agile_NET/vm/CsvmToCilMethodConverter.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/vm/CsvmToCilMethodConverter.cs
@@ -22,17 +22,16 @@ using System.Collections.Generic;
using System.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
-using Mono.Cecil.Metadata;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET.vm {
class CsvmToCilMethodConverter {
IDeobfuscatorContext deobfuscatorContext;
- ModuleDefinition module;
+ ModuleDefMD module;
VmOpCodeHandlerDetector opCodeDetector;
CilOperandInstructionRestorer operandRestorer = new CilOperandInstructionRestorer();
- public CsvmToCilMethodConverter(IDeobfuscatorContext deobfuscatorContext, ModuleDefinition module, VmOpCodeHandlerDetector opCodeDetector) {
+ public CsvmToCilMethodConverter(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module, VmOpCodeHandlerDetector opCodeDetector) {
this.deobfuscatorContext = deobfuscatorContext;
this.module = module;
this.opCodeDetector = opCodeDetector;
@@ -44,7 +43,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
var newExceptions = readExceptions(cilMethod, csvmMethod, newInstructions);
fixInstructionOperands(newInstructions);
- fixLocals(newInstructions, cilMethod.Body.Variables);
+ fixLocals(newInstructions, cilMethod.Body.LocalList);
fixArgs(newInstructions, cilMethod);
DotNetUtils.restoreBody(cilMethod, newInstructions, newExceptions);
@@ -54,7 +53,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
restoreConstrainedPrefix(cilMethod);
}
- void fixLocals(IList instrs, IList locals) {
+ void fixLocals(IList instrs, IList locals) {
foreach (var instr in instrs) {
var op = instr.Operand as LocalOperand;
if (op == null)
@@ -64,7 +63,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
}
- static void updateLocalInstruction(Instruction instr, VariableDefinition local, int index) {
+ static void updateLocalInstruction(Instruction instr, Local local, int index) {
object operand = null;
OpCode opcode;
@@ -135,19 +134,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
if (op == null)
continue;
- int argIndex = op.arg;
- if (method.HasImplicitThis)
- argIndex--;
- ParameterDefinition arg;
- if (argIndex == -1)
- arg = method.Body.ThisParameter;
- else
- arg = method.Parameters[argIndex];
- updateArgInstruction(instr, arg, op.arg);
+ updateArgInstruction(instr, method.Parameters[op.arg], op.arg);
}
}
- static void updateArgInstruction(Instruction instr, ParameterDefinition arg, int index) {
+ static void updateArgInstruction(Instruction instr, Parameter arg, int index) {
switch (instr.OpCode.Code) {
case Code.Ldarg:
case Code.Ldarg_S:
@@ -209,12 +200,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
List readInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) {
var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions));
var instrs = new List();
- int offset = 0;
+ uint offset = 0;
while (reader.BaseStream.Position < reader.BaseStream.Length) {
int vmOpCode = reader.ReadUInt16();
var instr = opCodeDetector.Handlers[vmOpCode].Read(reader);
instr.Offset = offset;
- offset += getInstructionSize(instr);
+ offset += (uint)getInstructionSize(instr);
instrs.Add(instr);
}
return instrs;
@@ -230,8 +221,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return instr.OpCode.Size + (op.targetDisplacements.Length + 1) * 4;
}
- List readLocals(MethodDef cilMethod, CsvmMethodData csvmMethod) {
- var locals = new List();
+ List readLocals(MethodDef cilMethod, CsvmMethodData csvmMethod) {
+ var locals = new List();
var reader = new BinaryReader(new MemoryStream(csvmMethod.Locals));
if (csvmMethod.Locals.Length == 0)
@@ -243,63 +234,58 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
throw new ApplicationException("Invalid number of locals");
for (int i = 0; i < numLocals; i++)
- locals.Add(new VariableDefinition(readTypeReference(reader)));
+ locals.Add(new Local(readTypeReference(reader)));
return locals;
}
- TypeReference readTypeReference(BinaryReader reader) {
+ TypeSig readTypeReference(BinaryReader reader) {
var etype = (ElementType)reader.ReadInt32();
switch (etype) {
- case ElementType.Void: return module.TypeSystem.Void;
- case ElementType.Boolean: return module.TypeSystem.Boolean;
- case ElementType.Char: return module.TypeSystem.Char;
- case ElementType.I1: return module.TypeSystem.SByte;
- case ElementType.U1: return module.TypeSystem.Byte;
- case ElementType.I2: return module.TypeSystem.Int16;
- case ElementType.U2: return module.TypeSystem.UInt16;
- case ElementType.I4: return module.TypeSystem.Int32;
- case ElementType.U4: return module.TypeSystem.UInt32;
- case ElementType.I8: return module.TypeSystem.Int64;
- case ElementType.U8: return module.TypeSystem.UInt64;
- case ElementType.R4: return module.TypeSystem.Single;
- case ElementType.R8: return module.TypeSystem.Double;
- case ElementType.String: return module.TypeSystem.String;
- case ElementType.TypedByRef: return module.TypeSystem.TypedReference;
- case ElementType.I: return module.TypeSystem.IntPtr;
- case ElementType.U: return module.TypeSystem.UIntPtr;
- case ElementType.Object: return module.TypeSystem.Object;
+ case ElementType.Void: return module.CorLibTypes.Void;
+ case ElementType.Boolean: return module.CorLibTypes.Boolean;
+ case ElementType.Char: return module.CorLibTypes.Char;
+ case ElementType.I1: return module.CorLibTypes.SByte;
+ case ElementType.U1: return module.CorLibTypes.Byte;
+ case ElementType.I2: return module.CorLibTypes.Int16;
+ case ElementType.U2: return module.CorLibTypes.UInt16;
+ case ElementType.I4: return module.CorLibTypes.Int32;
+ case ElementType.U4: return module.CorLibTypes.UInt32;
+ case ElementType.I8: return module.CorLibTypes.Int64;
+ case ElementType.U8: return module.CorLibTypes.UInt64;
+ case ElementType.R4: return module.CorLibTypes.Single;
+ case ElementType.R8: return module.CorLibTypes.Double;
+ case ElementType.String: return module.CorLibTypes.String;
+ case ElementType.TypedByRef: return module.CorLibTypes.TypedReference;
+ case ElementType.I: return module.CorLibTypes.IntPtr;
+ case ElementType.U: return module.CorLibTypes.UIntPtr;
+ case ElementType.Object: return module.CorLibTypes.Object;
case ElementType.ValueType:
case ElementType.Var:
case ElementType.MVar:
- return (TypeReference)module.LookupToken(reader.ReadInt32());
+ return (module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef).ToTypeSig();
case ElementType.GenericInst:
etype = (ElementType)reader.ReadInt32();
if (etype == ElementType.ValueType)
- return (TypeReference)module.LookupToken(reader.ReadInt32());
+ return (module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef).ToTypeSig();
// ElementType.Class
- return module.TypeSystem.Object;
+ return module.CorLibTypes.Object;
case ElementType.Ptr:
case ElementType.Class:
case ElementType.Array:
case ElementType.FnPtr:
- case ElementType.SzArray:
+ case ElementType.SZArray:
case ElementType.ByRef:
- case ElementType.CModReqD:
+ case ElementType.CModReqd:
case ElementType.CModOpt:
case ElementType.Internal:
- case ElementType.Modifier:
case ElementType.Sentinel:
case ElementType.Pinned:
- case ElementType.Type:
- case ElementType.Boxed:
- case ElementType.Enum:
- case ElementType.None:
default:
- return module.TypeSystem.Object;
+ return module.CorLibTypes.Object;
}
}
@@ -321,7 +307,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
eh.HandlerStart = getInstruction(cilInstructions, reader.ReadInt32());
eh.HandlerEnd = getInstructionEnd(cilInstructions, reader.ReadInt32());
if (eh.HandlerType == ExceptionHandlerType.Catch)
- eh.CatchType = (TypeReference)module.LookupToken(reader.ReadInt32());
+ eh.CatchType = module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
else if (eh.HandlerType == ExceptionHandlerType.Filter)
eh.FilterStart = getInstruction(cilInstructions, reader.ReadInt32());
@@ -387,9 +373,9 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
throw new ApplicationException(string.Format("Unknown operand type: {0}", vmOperand.GetType()));
}
- FieldReference fixLoadStoreFieldInstruction(Instruction instr, int token, OpCode staticInstr, OpCode instanceInstr) {
- var fieldRef = (FieldReference)module.LookupToken(token);
- var field = deobfuscatorContext.resolve(fieldRef);
+ IField fixLoadStoreFieldInstruction(Instruction instr, int token, OpCode staticInstr, OpCode instanceInstr) {
+ var fieldRef = module.ResolveToken(token) as IField;
+ var field = deobfuscatorContext.resolveField(fieldRef);
bool isStatic;
if (field == null) {
Log.w("Could not resolve field {0:X8}. Assuming it's not static.", token);
@@ -401,8 +387,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return fieldRef;
}
- MemberReference getMemberReference(int token) {
- var memberRef = module.LookupToken(token) as MemberReference;
+ ITokenOperand getMemberReference(int token) {
+ var memberRef = module.ResolveToken(token) as ITokenOperand;
if (memberRef == null)
throw new ApplicationException(string.Format("Could not find member ref: {0:X8}", token));
return memberRef;
@@ -418,15 +404,18 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
if (instr.OpCode.Code != Code.Callvirt)
continue;
- var calledMethod = instr.Operand as MethodReference;
- if (calledMethod == null || !calledMethod.HasThis)
+ var calledMethod = instr.Operand as IMethod;
+ if (calledMethod == null)
continue;
- var thisType = MethodStack.getLoadedType(method, instrs, i, calledMethod.Parameters.Count) as ByReferenceType;
+ var sig = calledMethod.MethodSig;
+ if (sig == null || !sig.HasThis)
+ continue;
+ var thisType = MethodStack.getLoadedType(method, instrs, i, sig.Params.Count) as ByRefSig;
if (thisType == null)
continue;
if (hasPrefix(instrs, i, Code.Constrained))
continue;
- instrs.Insert(i, Instruction.Create(OpCodes.Constrained, thisType.ElementType));
+ instrs.Insert(i, Instruction.Create(OpCodes.Constrained, thisType.Next.ToTypeDefOrRef()));
i++;
}
}
diff --git a/de4dot.code/deobfuscators/Agile_NET/vm/FieldsInfo.cs b/de4dot.code/deobfuscators/Agile_NET/vm/FieldsInfo.cs
index cb96c93b..1d12513c 100644
--- a/de4dot.code/deobfuscators/Agile_NET/vm/FieldsInfo.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/vm/FieldsInfo.cs
@@ -33,11 +33,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
public FieldsInfo(IEnumerable fields) {
foreach (var field in fields) {
- var fieldTypeDef = field.FieldType as TypeDef;
+ var fieldTypeDef = field.FieldSig.GetFieldType().TryGetTypeDef();
if (fieldTypeDef != null && fieldTypeDef.IsEnum)
addEnum();
else
- add(field.FieldType);
+ add(field.FieldSig.GetFieldType());
}
}
@@ -50,8 +50,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
}
- void add(TypeReference type) {
- add(type.FullName);
+ void add(TypeSig type) {
+ add(type.GetFullName());
}
void add(string typeFullName) {
diff --git a/de4dot.code/deobfuscators/Agile_NET/vm/OpCodeHandler.cs b/de4dot.code/deobfuscators/Agile_NET/vm/OpCodeHandler.cs
index 016d51eb..b9cc6b31 100644
--- a/de4dot.code/deobfuscators/Agile_NET/vm/OpCodeHandler.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/vm/OpCodeHandler.cs
@@ -23,7 +23,6 @@ using System.IO;
using de4dot.blocks;
using dot10.DotNet;
using dot10.DotNet.Emit;
-using Mono.Cecil.Metadata;
namespace de4dot.code.deobfuscators.Agile_NET.vm {
partial class OpCodeHandler {
@@ -248,7 +247,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
new InstructionInfo2 { First = false, Second = true, Value = 12, OpCode = OpCodes.Stelem_R4 },
new InstructionInfo2 { First = false, Second = true, Value = 13, OpCode = OpCodes.Stelem_R8 },
new InstructionInfo2 { First = false, Second = true, Value = 28, OpCode = OpCodes.Stelem_Ref },
- new InstructionInfo2 { First = false, Second = false, Value = 0, OpCode = OpCodes.Stelem_Any },
+ new InstructionInfo2 { First = false, Second = false, Value = 0, OpCode = OpCodes.Stelem },
new InstructionInfo2 { First = true, Second = true, Value = 24, OpCode = OpCodes.Ldelem_I },
new InstructionInfo2 { First = true, Second = true, Value = 4, OpCode = OpCodes.Ldelem_I1 },
@@ -261,7 +260,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
new InstructionInfo2 { First = true, Second = true, Value = 12, OpCode = OpCodes.Ldelem_R4 },
new InstructionInfo2 { First = true, Second = true, Value = 13, OpCode = OpCodes.Ldelem_R8 },
new InstructionInfo2 { First = true, Second = true, Value = 28, OpCode = OpCodes.Ldelem_Ref },
- new InstructionInfo2 { First = true, Second = false, Value = 0, OpCode = OpCodes.Ldelem_Any },
+ new InstructionInfo2 { First = true, Second = false, Value = 0, OpCode = OpCodes.Ldelem },
};
static Instruction ldelem_read(BinaryReader reader) {
Instruction instr = null;
@@ -463,7 +462,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool rethrow_check(UnknownHandlerInfo info) {
- return info.ExecuteMethod.Body.Variables.Count == 0;
+ return info.ExecuteMethod.Body.LocalList.Count == 0;
}
static Instruction rethrow_read(BinaryReader reader) {
diff --git a/de4dot.code/deobfuscators/Agile_NET/vm/UnknownHandlerInfo.cs b/de4dot.code/deobfuscators/Agile_NET/vm/UnknownHandlerInfo.cs
index ac2127a0..f2d923e1 100644
--- a/de4dot.code/deobfuscators/Agile_NET/vm/UnknownHandlerInfo.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/vm/UnknownHandlerInfo.cs
@@ -83,7 +83,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
if (method.Body == null)
continue;
foreach (var instr in method.Body.Instructions) {
- var fieldRef = instr.Operand as FieldReference;
+ var fieldRef = instr.Operand as IField;
if (fieldRef == null)
continue;
var field = typeFields.find(fieldRef);
@@ -119,7 +119,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
throw new ApplicationException("Found another read method");
readMethod = method;
}
- else if (!DotNetUtils.hasReturnValue(method) && method.Parameters.Count == 1) {
+ else if (!DotNetUtils.hasReturnValue(method) && method.MethodSig.GetParamCount() == 1) {
if (executeMethod != null)
throw new ApplicationException("Found another execute method");
executeMethod = method;
@@ -146,8 +146,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
foreach (var instr in method.Body.Instructions) {
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
continue;
- var calledMethod = instr.Operand as MethodReference;
- if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(calledMethod, csvmInfo.PopMethod))
+ var calledMethod = instr.Operand as IMethod;
+ if (!MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod, csvmInfo.PopMethod))
continue;
count++;
diff --git a/de4dot.code/deobfuscators/Agile_NET/vm/VmOpCodeHandlerDetector.cs b/de4dot.code/deobfuscators/Agile_NET/vm/VmOpCodeHandlerDetector.cs
index 6b556be2..dafb6917 100644
--- a/de4dot.code/deobfuscators/Agile_NET/vm/VmOpCodeHandlerDetector.cs
+++ b/de4dot.code/deobfuscators/Agile_NET/vm/VmOpCodeHandlerDetector.cs
@@ -44,14 +44,14 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
class VmOpCodeHandlerDetector {
- ModuleDefinition module;
+ ModuleDefMD module;
List opCodeHandlers;
public List Handlers {
get { return opCodeHandlers; }
}
- public VmOpCodeHandlerDetector(ModuleDefinition module) {
+ public VmOpCodeHandlerDetector(ModuleDefMD module) {
this.module = module;
}
@@ -88,10 +88,10 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
int enumTypes = 0;
int objectTypes = 0;
foreach (var field in type.Fields) {
- var fieldType = field.FieldType as TypeDef;
+ var fieldType = field.FieldSig.GetFieldType().TryGetTypeDef();
if (fieldType != null && fieldType.IsEnum)
enumTypes++;
- if (field.FieldType.FullName == "System.Object")
+ if (field.FieldSig.GetFieldType().GetElementType() == ElementType.Object)
objectTypes++;
}
if (enumTypes != 1 || objectTypes != 1)
@@ -109,7 +109,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
bool isStackType(TypeDef type, TypeDef stackValueType) {
- if (type.Interfaces.Count != 2)
+ if (type.InterfaceImpls.Count != 2)
return false;
if (!implementsInterface(type, "System.Collections.ICollection"))
return false;
@@ -124,11 +124,14 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
foreach (var field in type.Fields) {
if (field.IsLiteral)
continue;
- if (field.FieldType is ArrayType && ((ArrayType)field.FieldType).ElementType == stackValueType)
+ var fieldType = field.FieldSig.GetFieldType();
+ if (fieldType == null)
+ continue;
+ if (fieldType.IsSZArray && fieldType.Next.TryGetTypeDef() == stackValueType)
stackValueTypes++;
- if (field.FieldType.FullName == "System.Int32")
+ if (fieldType.ElementType == ElementType.I4)
int32Types++;
- if (field.FieldType.FullName == "System.Object")
+ if (fieldType.ElementType == ElementType.Object)
objectTypes++;
}
if (stackValueTypes != 2 || int32Types != 2 || objectTypes != 1)
@@ -138,8 +141,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool implementsInterface(TypeDef type, string ifaceName) {
- foreach (var iface in type.Interfaces) {
- if (iface.FullName == ifaceName)
+ foreach (var iface in type.InterfaceImpls) {
+ if (iface.Interface.FullName == ifaceName)
return true;
}
return false;
@@ -147,7 +150,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
void initStackTypeMethods(CsvmInfo csvmInfo) {
foreach (var method in csvmInfo.Stack.Methods) {
- if (method.Parameters.Count == 0 && method.MethodReturnType.ReturnType == csvmInfo.StackValue) {
+ var sig = method.MethodSig;
+ if (sig != null && sig.Params.Count == 0 && sig.RetType.TryGetTypeDef() == csvmInfo.StackValue) {
if (hasAdd(method))
csvmInfo.PopMethod = method;
else
@@ -172,7 +176,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
};
var cflowDeobfuscator = new CflowDeobfuscator();
foreach (var type in module.Types) {
- var cctor = DotNetUtils.getMethod(type, ".cctor");
+ var cctor = type.FindClassConstructor();
if (cctor == null)
continue;
requiredFields[0] = type.FullName;
diff --git a/de4dot.cui/Program.cs b/de4dot.cui/Program.cs
index 1f8340a5..a487156a 100644
--- a/de4dot.cui/Program.cs
+++ b/de4dot.cui/Program.cs
@@ -37,9 +37,9 @@ namespace de4dot.cui {
static IList createDeobfuscatorInfos() {
return new List {
new de4dot.code.deobfuscators.Unknown.DeobfuscatorInfo(),
+ new de4dot.code.deobfuscators.Agile_NET.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.Babel_NET.DeobfuscatorInfo(),
- new de4dot.code.deobfuscators.Agile_NET.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(),
diff --git a/dot10 b/dot10
index cf50ec12..13f15527 160000
--- a/dot10
+++ b/dot10
@@ -1 +1 @@
-Subproject commit cf50ec12f7cc258eb23cad730eee638b65e8dfc8
+Subproject commit 13f15527e9b8f99c2fddfd386714835a0f4b9d0b