Port Agile.NET deobfuscator

This commit is contained in:
de4dot 2012-11-07 05:17:45 +01:00
parent cc1e36389d
commit 583d4201f5
20 changed files with 235 additions and 257 deletions

View File

@ -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))

View File

@ -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;
}

View File

@ -57,25 +57,25 @@
<Compile Include="AssemblyResolver.cs" />
<Compile Include="DeobfuscatorContext.cs" />
<Compile Include="deobfuscators\ArrayFinder.cs" />
<None Include="deobfuscators\Agile_NET\CliSecureRtType.cs" />
<None Include="deobfuscators\Agile_NET\CsBlowfish.cs" />
<None Include="deobfuscators\Agile_NET\Deobfuscator.cs" />
<None Include="deobfuscators\Agile_NET\MethodsDecrypter.cs" />
<None Include="deobfuscators\Agile_NET\ProxyCallFixer.cs" />
<None Include="deobfuscators\Agile_NET\ResourceDecrypter.cs" />
<None Include="deobfuscators\Agile_NET\StackFrameHelper.cs" />
<None Include="deobfuscators\Agile_NET\StringDecrypter.cs" />
<None Include="deobfuscators\Agile_NET\vm\CilOperandInstructionRestorer.cs" />
<None Include="deobfuscators\Agile_NET\vm\Csvm.cs" />
<None Include="deobfuscators\Agile_NET\vm\CsvmDataReader.cs" />
<None Include="deobfuscators\Agile_NET\vm\CsvmMethodData.cs" />
<None Include="deobfuscators\Agile_NET\vm\CsvmToCilMethodConverter.cs" />
<None Include="deobfuscators\Agile_NET\vm\FieldsInfo.cs" />
<None Include="deobfuscators\Agile_NET\vm\OpCodeHandler.cs" />
<None Include="deobfuscators\Agile_NET\vm\OpCodeHandlers.cs" />
<None Include="deobfuscators\Agile_NET\vm\UnknownHandlerInfo.cs" />
<None Include="deobfuscators\Agile_NET\vm\VmOpCodeHandlerDetector.cs" />
<None Include="deobfuscators\Agile_NET\vm\VmOperands.cs" />
<Compile Include="deobfuscators\Agile_NET\CliSecureRtType.cs" />
<Compile Include="deobfuscators\Agile_NET\CsBlowfish.cs" />
<Compile Include="deobfuscators\Agile_NET\Deobfuscator.cs" />
<Compile Include="deobfuscators\Agile_NET\MethodsDecrypter.cs" />
<Compile Include="deobfuscators\Agile_NET\ProxyCallFixer.cs" />
<Compile Include="deobfuscators\Agile_NET\ResourceDecrypter.cs" />
<Compile Include="deobfuscators\Agile_NET\StackFrameHelper.cs" />
<Compile Include="deobfuscators\Agile_NET\StringDecrypter.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\CilOperandInstructionRestorer.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\Csvm.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\CsvmDataReader.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\CsvmMethodData.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\CsvmToCilMethodConverter.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\FieldsInfo.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\OpCodeHandler.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\OpCodeHandlers.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\UnknownHandlerInfo.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\VmOpCodeHandlerDetector.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\VmOperands.cs" />
<None Include="deobfuscators\Babel_NET\AssemblyResolver.cs" />
<None Include="deobfuscators\Babel_NET\BabelInflater.cs" />
<None Include="deobfuscators\Babel_NET\BabelMethodCallInliner.cs" />

View File

@ -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<ModuleReference> DecryptModuleReferences {
get {
var list = new List<ModuleReference>();
addModuleReference(list, "_Initialize");
addModuleReference(list, "_Initialize64");
return list;
}
}
void addModuleReference(List<ModuleReference> 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>(T def, string errorMessage) where T : MemberReference {
T lookup<T>(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);

View File

@ -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<TypeDef> lookup(ModuleDefinition module, List<TypeDef> types, string errorMsg) {
static List<TypeDef> lookup(ModuleDefMD module, List<TypeDef> types, string errorMsg) {
var list = new List<TypeDef>(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();
}

View File

@ -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;

View File

@ -25,13 +25,11 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET {
class ProxyCallFixer : ProxyCallFixer1 {
IList<MemberReference> 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<MemberReference>(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;
}
}
}

View File

@ -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>(T def, string errorMessage) where T : MemberReference {
T lookup<T>(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);
}
}
}

View File

@ -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

View File

@ -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>(T def, string errorMessage) where T : MemberReference {
T lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.lookup(module, def, errorMessage);
}

View File

@ -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;

View File

@ -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:");

View File

@ -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<CsvmMethodData> read() {

View File

@ -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<Instruction> instrs, IList<VariableDefinition> locals) {
void fixLocals(IList<Instruction> instrs, IList<Local> 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<Instruction> readInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) {
var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions));
var instrs = new List<Instruction>();
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<VariableDefinition> readLocals(MethodDef cilMethod, CsvmMethodData csvmMethod) {
var locals = new List<VariableDefinition>();
List<Local> readLocals(MethodDef cilMethod, CsvmMethodData csvmMethod) {
var locals = new List<Local>();
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++;
}
}

View File

@ -33,11 +33,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
public FieldsInfo(IEnumerable<FieldDef> 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) {

View File

@ -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) {

View File

@ -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++;

View File

@ -44,14 +44,14 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
class VmOpCodeHandlerDetector {
ModuleDefinition module;
ModuleDefMD module;
List<OpCodeHandler> opCodeHandlers;
public List<OpCodeHandler> 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;

View File

@ -37,9 +37,9 @@ namespace de4dot.cui {
static IList<IDeobfuscatorInfo> createDeobfuscatorInfos() {
return new List<IDeobfuscatorInfo> {
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(),

2
dot10

@ -1 +1 @@
Subproject commit cf50ec12f7cc258eb23cad730eee638b65e8dfc8
Subproject commit 13f15527e9b8f99c2fddfd386714835a0f4b9d0b