Port CryptoObfuscator deobfuscator

This commit is contained in:
de4dot 2012-11-08 22:24:13 +01:00
parent 472d57ed0f
commit 5d25a499aa
16 changed files with 154 additions and 152 deletions

View File

@ -181,17 +181,15 @@ namespace de4dot.blocks {
return true; return true;
} }
#if PORT public static FieldDef findFieldType(TypeDef typeDefinition, string typeName, bool isStatic) {
public static FieldDefinition findFieldType(TypeDefinition typeDefinition, string typeName, bool isStatic) {
if (typeDefinition == null) if (typeDefinition == null)
return null; return null;
foreach (var field in typeDefinition.Fields) { foreach (var field in typeDefinition.Fields) {
if (field.FieldType.FullName == typeName && field.IsStatic == isStatic) if (field.IsStatic == isStatic && field.FieldSig.GetFieldType().GetFullName() == typeName)
return field; return field;
} }
return null; return null;
} }
#endif
public static IEnumerable<MethodDef> findMethods(IEnumerable<MethodDef> methods, string returnType, string[] argsTypes) { public static IEnumerable<MethodDef> findMethods(IEnumerable<MethodDef> methods, string returnType, string[] argsTypes) {
return findMethods(methods, returnType, argsTypes, true); return findMethods(methods, returnType, argsTypes, true);
@ -1233,14 +1231,13 @@ namespace de4dot.blocks {
return new ClassSig(typeRef); return new ClassSig(typeRef);
} }
#if PORT public static FrameworkType getFrameworkType(ModuleDefMD module) {
public static FrameworkType getFrameworkType(ModuleDefinition module) { foreach (var modRef in module.GetAssemblyRefs()) {
foreach (var modRef in module.AssemblyReferences) {
if (modRef.Name != "mscorlib") if (modRef.Name != "mscorlib")
continue; continue;
if (modRef.PublicKeyToken == null || modRef.PublicKeyToken.Length == 0) if (PublicKeyBase.IsNullOrEmpty2(modRef.PublicKeyOrToken))
continue; continue;
switch (BitConverter.ToString(modRef.PublicKeyToken).Replace("-", "").ToLowerInvariant()) { switch (BitConverter.ToString(modRef.PublicKeyOrToken.Data).Replace("-", "").ToLowerInvariant()) {
case "b77a5c561934e089": case "b77a5c561934e089":
return FrameworkType.Desktop; return FrameworkType.Desktop;
case "7cec85d7bea7798e": case "7cec85d7bea7798e":
@ -1256,7 +1253,6 @@ namespace de4dot.blocks {
return FrameworkType.Unknown; return FrameworkType.Unknown;
} }
#endif
public static int getMethodCalls(MethodDef method, string methodFullName) { public static int getMethodCalls(MethodDef method, string methodFullName) {
if (method == null || method.Body == null) if (method == null || method.Body == null)
@ -1293,7 +1289,6 @@ namespace de4dot.blocks {
return false; return false;
} }
#if PORT
public static bool callsMethod(MethodDef method, string returnType, string parameters) { public static bool callsMethod(MethodDef method, string returnType, string parameters) {
if (method == null || method.Body == null) if (method == null || method.Body == null)
return false; return false;
@ -1301,13 +1296,14 @@ namespace de4dot.blocks {
foreach (var instr in method.Body.Instructions) { foreach (var instr in method.Body.Instructions) {
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt && instr.OpCode.Code != Code.Newobj) if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt && instr.OpCode.Code != Code.Newobj)
continue; continue;
if (isMethod(instr.Operand as MethodReference, returnType, parameters)) if (isMethod(instr.Operand as IMethod, returnType, parameters))
return true; return true;
} }
return false; return false;
} }
#if PORT
public static IList<Instruction> getArgPushes(IList<Instruction> instrs, int index) { public static IList<Instruction> getArgPushes(IList<Instruction> instrs, int index) {
return getArgPushes(instrs, ref index); return getArgPushes(instrs, ref index);
} }

View File

@ -123,18 +123,18 @@
<Compile Include="deobfuscators\CodeWall\randomc\CRandomMother.cs" /> <Compile Include="deobfuscators\CodeWall\randomc\CRandomMother.cs" />
<Compile Include="deobfuscators\CodeWall\StringDecrypter.cs" /> <Compile Include="deobfuscators\CodeWall\StringDecrypter.cs" />
<Compile Include="deobfuscators\ConstantsReader.cs" /> <Compile Include="deobfuscators\ConstantsReader.cs" />
<None Include="deobfuscators\CryptoObfuscator\AntiDebugger.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\AntiDebugger.cs" />
<None Include="deobfuscators\CryptoObfuscator\AssemblyResolver.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\AssemblyResolver.cs" />
<None Include="deobfuscators\CryptoObfuscator\ConstantsDecrypter.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\ConstantsDecrypter.cs" />
<None Include="deobfuscators\CryptoObfuscator\CoUtils.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\CoUtils.cs" />
<None Include="deobfuscators\CryptoObfuscator\Deobfuscator.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\Deobfuscator.cs" />
<None Include="deobfuscators\CryptoObfuscator\MethodBodyReader.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\MethodBodyReader.cs" />
<None Include="deobfuscators\CryptoObfuscator\MethodsDecrypter.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\MethodsDecrypter.cs" />
<None Include="deobfuscators\CryptoObfuscator\ProxyCallFixer.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\ProxyCallFixer.cs" />
<None Include="deobfuscators\CryptoObfuscator\ResourceDecrypter.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\ResourceDecrypter.cs" />
<None Include="deobfuscators\CryptoObfuscator\ResourceResolver.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\ResourceResolver.cs" />
<None Include="deobfuscators\CryptoObfuscator\StringDecrypter.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\StringDecrypter.cs" />
<None Include="deobfuscators\CryptoObfuscator\TamperDetection.cs" /> <Compile Include="deobfuscators\CryptoObfuscator\TamperDetection.cs" />
<None Include="deobfuscators\DeepSea\ArrayBlockDeobfuscator.cs" /> <None Include="deobfuscators\DeepSea\ArrayBlockDeobfuscator.cs" />
<None Include="deobfuscators\DeepSea\ArrayBlockState.cs" /> <None Include="deobfuscators\DeepSea\ArrayBlockState.cs" />
<None Include="deobfuscators\DeepSea\AssemblyResolver.cs" /> <None Include="deobfuscators\DeepSea\AssemblyResolver.cs" />

View File

@ -22,7 +22,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class AntiDebugger { class AntiDebugger {
ModuleDefinition module; ModuleDefMD module;
ISimpleDeobfuscator simpleDeobfuscator; ISimpleDeobfuscator simpleDeobfuscator;
IDeobfuscator deob; IDeobfuscator deob;
TypeDef antiDebuggerType; TypeDef antiDebuggerType;
@ -36,7 +36,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
get { return antiDebuggerMethod; } get { return antiDebuggerMethod; }
} }
public AntiDebugger(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { public AntiDebugger(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
this.module = module; this.module = module;
this.simpleDeobfuscator = simpleDeobfuscator; this.simpleDeobfuscator = simpleDeobfuscator;
this.deob = deob; this.deob = deob;

View File

@ -26,7 +26,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class AssemblyResolver { class AssemblyResolver {
ModuleDefinition module; ModuleDefMD module;
TypeDef resolverType; TypeDef resolverType;
MethodDef resolverMethod; MethodDef resolverMethod;
List<AssemblyInfo> assemblyInfos = new List<AssemblyInfo>(); List<AssemblyInfo> assemblyInfos = new List<AssemblyInfo>();
@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
get { return resolverMethod; } get { return resolverMethod; }
} }
public AssemblyResolver(ModuleDefinition module) { public AssemblyResolver(ModuleDefMD module) {
this.module = module; this.module = module;
} }
@ -112,15 +112,15 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (instrs == null) if (instrs == null)
continue; continue;
MethodReference methodRef; IMethod methodRef;
var ldftn = instrs[1]; var ldftn = instrs[1];
var newobj = instrs[2]; var newobj = instrs[2];
methodRef = ldftn.Operand as MethodReference; methodRef = ldftn.Operand as IMethod;
if (methodRef == null || !MemberReferenceHelper.compareTypes(initMethod.DeclaringType, methodRef.DeclaringType)) if (methodRef == null || !new SigComparer().Equals(initMethod.DeclaringType, methodRef.DeclaringType))
continue; continue;
methodRef = newobj.Operand as MethodReference; methodRef = newobj.Operand as IMethod;
if (methodRef == null || methodRef.FullName != "System.Void System.ResolveEventHandler::.ctor(System.Object,System.IntPtr)") if (methodRef == null || methodRef.FullName != "System.Void System.ResolveEventHandler::.ctor(System.Object,System.IntPtr)")
continue; continue;

View File

@ -25,13 +25,13 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
static class CoUtils { static class CoUtils {
public static EmbeddedResource getResource(ModuleDefinition module, MethodDef method) { public static EmbeddedResource getResource(ModuleDefMD module, MethodDef method) {
if (method == null || method.Body == null) if (method == null || method.Body == null)
return null; return null;
return getResource(module, DotNetUtils.getCodeStrings(method)); return getResource(module, DotNetUtils.getCodeStrings(method));
} }
public static EmbeddedResource getResource(ModuleDefinition module, IEnumerable<string> names) { public static EmbeddedResource getResource(ModuleDefMD module, IEnumerable<string> names) {
foreach (var name in names) { foreach (var name in names) {
var resource = DotNetUtils.getResource(module, name) as EmbeddedResource; var resource = DotNetUtils.getResource(module, name) as EmbeddedResource;
if (resource != null) if (resource != null)

View File

@ -20,12 +20,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using dot10.IO;
using dot10.DotNet; using dot10.DotNet;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class ConstantsDecrypter { class ConstantsDecrypter {
ModuleDefinition module; ModuleDefMD module;
TypeDef decrypterType; TypeDef decrypterType;
MethodDef methodI4; MethodDef methodI4;
MethodDef methodI8; MethodDef methodI8;
@ -62,7 +63,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
get { return decrypterType != null; } get { return decrypterType != null; }
} }
public ConstantsDecrypter(ModuleDefinition module) { public ConstantsDecrypter(ModuleDefMD module) {
this.module = module; this.module = module;
} }
@ -106,8 +107,8 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (decrypterType == null) if (decrypterType == null)
return; return;
encryptedResource = CoUtils.getResource(module, DotNetUtils.getCodeStrings(DotNetUtils.getMethod(decrypterType, ".cctor"))); encryptedResource = CoUtils.getResource(module, DotNetUtils.getCodeStrings(decrypterType.FindClassConstructor()));
constantsData = resourceDecrypter.decrypt(encryptedResource.GetResourceStream()); constantsData = resourceDecrypter.decrypt(encryptedResource.Data.CreateStream());
} }
public int decryptInt32(int index) { public int decryptInt32(int index) {

View File

@ -105,7 +105,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
StringFeatures = StringFeatures.AllowStaticDecryption | StringFeatures.AllowDynamicDecryption; StringFeatures = StringFeatures.AllowStaticDecryption | StringFeatures.AllowDynamicDecryption;
} }
public override void init(ModuleDefinition module) { public override void init(ModuleDefMD module) {
base.init(module); base.init(module);
} }
@ -146,7 +146,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
tamperDetection.find(); tamperDetection.find();
constantsDecrypter = new ConstantsDecrypter(module); constantsDecrypter = new ConstantsDecrypter(module);
constantsDecrypter.find(); constantsDecrypter.find();
foundObfuscatorUserString = Utils.StartsWith(module.GetUserString(0x70000001), "\u0011\"3D9B94A98B-76A8-4810-B1A0-4BE7C4F9C98D", StringComparison.Ordinal); foundObfuscatorUserString = Utils.StartsWith(module.ReadUserString(0x70000001), "\u0011\"3D9B94A98B-76A8-4810-B1A0-4BE7C4F9C98D", StringComparison.Ordinal);
} }
void initializeVersion(TypeDef attr) { void initializeVersion(TypeDef attr) {
@ -166,9 +166,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
foreach (var type in module.Types) { foreach (var type in module.Types) {
if (type.Namespace != "A") if (type.Namespace != "A")
continue; continue;
if (Regex.IsMatch(type.Name, "^c[0-9a-f]{32}$")) if (Regex.IsMatch(type.Name.String, "^c[0-9a-f]{32}$"))
return true; return true;
else if (Regex.IsMatch(type.Name, "^A[A-Z]*$")) { else if (Regex.IsMatch(type.Name.String, "^A[A-Z]*$")) {
if (++matched >= 10) if (++matched >= 10)
return true; return true;
} }

View File

@ -19,27 +19,28 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using dot10.IO;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.MD;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class MethodBodyReader : MethodBodyReaderBase { class MethodBodyReader : MethodBodyReaderBase {
ModuleDefinition module; ModuleDefMD module;
ushort maxStackSize; ushort maxStackSize;
public MethodBodyReader(ModuleDefinition module, BinaryReader reader) public MethodBodyReader(ModuleDefMD module, IBinaryReader reader)
: base(reader) { : base(reader) {
this.module = module; this.module = module;
} }
public void read(MethodDef method) { public void read(MethodDef method) {
this.parameters = getParameters(method); this.parameters = method.Parameters;
this.Locals = getLocals(method); this.locals = getLocals(method);
maxStackSize = (ushort)reader.ReadInt32(); maxStackSize = (ushort)reader.ReadInt32();
readInstructionsNumBytes(reader.ReadUInt32()); ReadInstructionsNumBytes(reader.ReadUInt32());
readExceptionHandlers(); readExceptionHandlers();
} }
@ -51,73 +52,76 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
readExceptionHandlers((totalSize - 4) / 24); readExceptionHandlers((totalSize - 4) / 24);
} }
static IList<ParameterDefinition> getParameters(MethodReference method) { static IList<Local> getLocals(MethodDef method) {
return DotNetUtils.getParameters(method);
}
static IList<VariableDefinition> getLocals(MethodDef method) {
if (method.Body == null) if (method.Body == null)
return new List<VariableDefinition>(); return new List<Local>();
return new List<VariableDefinition>(method.Body.Variables); return method.Body.LocalList;
} }
protected override FieldReference readInlineField(Instruction instr) { protected override IField ReadInlineField(Instruction instr) {
return (FieldReference)module.LookupToken(reader.ReadInt32()); return module.ResolveToken(reader.ReadUInt32()) as IField;
} }
protected override MethodReference readInlineMethod(Instruction instr) { protected override IMethod ReadInlineMethod(Instruction instr) {
return (MethodReference)module.LookupToken(reader.ReadInt32()); return module.ResolveToken(reader.ReadUInt32()) as IMethod;
} }
protected override CallSite readInlineSig(Instruction instr) { protected override MethodSig ReadInlineSig(Instruction instr) {
return module.ReadCallSite(new MetadataToken(reader.ReadUInt32())); var sas = module.ResolveStandAloneSig(MDToken.ToRID(reader.ReadUInt32()));
return sas == null ? null : sas.MethodSig;
} }
protected override string readInlineString(Instruction instr) { protected override string ReadInlineString(Instruction instr) {
return module.GetUserString(reader.ReadUInt32()); return module.ReadUserString(reader.ReadUInt32());
} }
protected override MemberReference readInlineTok(Instruction instr) { protected override ITokenOperand ReadInlineTok(Instruction instr) {
return (MemberReference)module.LookupToken(reader.ReadInt32()); return module.ResolveToken(reader.ReadUInt32()) as ITokenOperand;
} }
protected override TypeReference readInlineType(Instruction instr) { protected override ITypeDefOrRef ReadInlineType(Instruction instr) {
return (TypeReference)module.LookupToken(reader.ReadInt32()); return module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
} }
protected override ExceptionHandler readExceptionHandler() { void readExceptionHandlers(int numExceptionHandlers) {
var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadInt32()); exceptionHandlers = new ExceptionHandler[numExceptionHandlers];
for (int i = 0; i < exceptionHandlers.Count; i++)
exceptionHandlers[i] = readExceptionHandler();
}
int tryOffset = reader.ReadInt32(); ExceptionHandler readExceptionHandler() {
eh.TryStart = getInstruction(tryOffset); var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadUInt32());
eh.TryEnd = getInstructionOrNull(tryOffset + reader.ReadInt32());
int handlerOffset = reader.ReadInt32(); uint tryOffset = reader.ReadUInt32();
eh.HandlerStart = getInstruction(handlerOffset); eh.TryStart = GetInstructionThrow(tryOffset);
eh.HandlerEnd = getInstructionOrNull(handlerOffset + reader.ReadInt32()); eh.TryEnd = GetInstruction(tryOffset + reader.ReadUInt32());
uint handlerOffset = reader.ReadUInt32();
eh.HandlerStart = GetInstructionThrow(handlerOffset);
eh.HandlerEnd = GetInstruction(handlerOffset + reader.ReadUInt32());
switch (eh.HandlerType) { switch (eh.HandlerType) {
case ExceptionHandlerType.Catch: case ExceptionHandlerType.Catch:
eh.CatchType = (TypeReference)module.LookupToken(reader.ReadInt32()); eh.CatchType = module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
break; break;
case ExceptionHandlerType.Filter: case ExceptionHandlerType.Filter:
eh.FilterStart = getInstruction(reader.ReadInt32()); eh.FilterStart = GetInstructionThrow(reader.ReadUInt32());
break; break;
case ExceptionHandlerType.Finally: case ExceptionHandlerType.Finally:
case ExceptionHandlerType.Fault: case ExceptionHandlerType.Fault:
default: default:
reader.ReadInt32(); reader.ReadUInt32();
break; break;
} }
return eh; return eh;
} }
public override void restoreMethod(MethodDef method) { public new void RestoreMethod(MethodDef method) {
base.restoreMethod(method); base.RestoreMethod(method);
method.Body.MaxStackSize = maxStackSize; method.Body.MaxStack = maxStackSize;
} }
} }
} }

View File

@ -19,14 +19,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using dot10.IO;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class MethodsDecrypter { class MethodsDecrypter {
ModuleDefinition module; ModuleDefMD module;
TypeDef decrypterType; TypeDef decrypterType;
MethodDef decryptMethod; MethodDef decryptMethod;
MethodDef decrypterCctor; MethodDef decrypterCctor;
@ -49,7 +49,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
get { return decrypterType != null; } get { return decrypterType != null; }
} }
public MethodsDecrypter(ModuleDefinition module) { public MethodsDecrypter(ModuleDefMD module) {
this.module = module; this.module = module;
} }
@ -73,7 +73,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (!new FieldTypes(type).all(requiredFields)) if (!new FieldTypes(type).all(requiredFields))
return false; return false;
var cctor = DotNetUtils.getMethod(type, ".cctor"); var cctor = type.FindClassConstructor();
if (cctor == null) if (cctor == null)
return false; return false;
var decryptMethodTmp = findDecryptMethod(type); var decryptMethodTmp = findDecryptMethod(type);
@ -120,23 +120,23 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (resource == null) if (resource == null)
return; return;
var decrypted = resourceDecrypter.decrypt(resource.GetResourceStream()); var decrypted = resourceDecrypter.decrypt(resource.GetResourceStream());
var reader = new BinaryReader(new MemoryStream(decrypted)); var reader = MemoryImageStream.Create(decrypted);
int numEncrypted = reader.ReadInt32(); int numEncrypted = reader.ReadInt32();
Log.v("Restoring {0} encrypted methods", numEncrypted); Log.v("Restoring {0} encrypted methods", numEncrypted);
Log.indent(); Log.indent();
for (int i = 0; i < numEncrypted; i++) { for (int i = 0; i < numEncrypted; i++) {
int delegateTypeToken = reader.ReadInt32(); int delegateTypeToken = reader.ReadInt32();
uint codeOffset = reader.ReadUInt32(); uint codeOffset = reader.ReadUInt32();
var origOffset = reader.BaseStream.Position; var origOffset = reader.Position;
reader.BaseStream.Position = codeOffset; reader.Position = codeOffset;
decrypt(reader, delegateTypeToken); decrypt(reader, delegateTypeToken);
reader.BaseStream.Position = origOffset; reader.Position = origOffset;
} }
Log.deIndent(); Log.deIndent();
} }
void decrypt(BinaryReader reader, int delegateTypeToken) { void decrypt(IBinaryReader reader, int delegateTypeToken) {
var delegateType = module.LookupToken(delegateTypeToken) as TypeDef; var delegateType = module.ResolveToken(delegateTypeToken) as TypeDef;
if (delegateType == null) if (delegateType == null)
throw new ApplicationException("Couldn't find delegate type"); throw new ApplicationException("Couldn't find delegate type");
@ -145,21 +145,21 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
throw new ApplicationException("Could not find encrypted method tokens"); throw new ApplicationException("Could not find encrypted method tokens");
if (delToken != delegateTypeToken) if (delToken != delegateTypeToken)
throw new ApplicationException("Invalid delegate type token"); throw new ApplicationException("Invalid delegate type token");
var encType = module.LookupToken(encDeclToken) as TypeReference; var encType = module.ResolveToken(encDeclToken) as ITypeDefOrRef;
if (encType == null) if (encType == null)
throw new ApplicationException("Invalid declaring type token"); throw new ApplicationException("Invalid declaring type token");
var encMethod = module.LookupToken(encMethToken) as MethodDef; var encMethod = module.ResolveToken(encMethToken) as MethodDef;
if (encMethod == null) if (encMethod == null)
throw new ApplicationException("Invalid encrypted method token"); throw new ApplicationException("Invalid encrypted method token");
var bodyReader = new MethodBodyReader(module, reader); var bodyReader = new MethodBodyReader(module, reader);
bodyReader.read(encMethod); bodyReader.read(encMethod);
bodyReader.restoreMethod(encMethod); bodyReader.RestoreMethod(encMethod);
Log.v("Restored method {0} ({1:X8}). Instrs:{2}, Locals:{3}, Exceptions:{4}", Log.v("Restored method {0} ({1:X8}). Instrs:{2}, Locals:{3}, Exceptions:{4}",
Utils.removeNewlines(encMethod.FullName), Utils.removeNewlines(encMethod.FullName),
encMethod.MDToken.ToInt32(), encMethod.MDToken.ToInt32(),
encMethod.Body.Instructions.Count, encMethod.Body.Instructions.Count,
encMethod.Body.Variables.Count, encMethod.Body.LocalList.Count,
encMethod.Body.ExceptionHandlers.Count); encMethod.Body.ExceptionHandlers.Count);
delegateTypes.Add(delegateType); delegateTypes.Add(delegateType);
} }
@ -169,20 +169,20 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
encMethodToken = 0; encMethodToken = 0;
encDeclaringTypeToken = 0; encDeclaringTypeToken = 0;
var cctor = DotNetUtils.getMethod(delegateType, ".cctor"); var cctor = delegateType.FindClassConstructor();
if (cctor == null) if (cctor == null)
return false; return false;
var instrs = cctor.Body.Instructions; var instrs = cctor.Body.Instructions;
for (int i = 0; i < instrs.Count - 3; i++) { for (int i = 0; i < instrs.Count - 3; i++) {
var ldci4_1 = instrs[i]; var ldci4_1 = instrs[i];
if (!DotNetUtils.isLdcI4(ldci4_1)) if (!ldci4_1.IsLdcI4())
continue; continue;
var ldci4_2 = instrs[i + 1]; var ldci4_2 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4_2)) if (!ldci4_2.IsLdcI4())
continue; continue;
var ldci4_3 = instrs[i + 2]; var ldci4_3 = instrs[i + 2];
if (!DotNetUtils.isLdcI4(ldci4_3)) if (!ldci4_3.IsLdcI4())
continue; continue;
var call = instrs[i + 3]; var call = instrs[i + 3];
if (call.OpCode.Code != Code.Call) if (call.OpCode.Code != Code.Call)
@ -193,9 +193,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (calledMethod != decryptMethod) if (calledMethod != decryptMethod)
continue; continue;
delegateToken = DotNetUtils.getLdcI4Value(ldci4_1); delegateToken = ldci4_1.GetLdcI4Value();
encMethodToken = DotNetUtils.getLdcI4Value(ldci4_2); encMethodToken = ldci4_2.GetLdcI4Value();
encDeclaringTypeToken = DotNetUtils.getLdcI4Value(ldci4_3); encDeclaringTypeToken = ldci4_3.GetLdcI4Value();
return true; return true;
} }

View File

@ -27,7 +27,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
class ProxyCallFixer : ProxyCallFixer2 { class ProxyCallFixer : ProxyCallFixer2 {
Dictionary<MethodDef, ProxyCreatorType> methodToType = new Dictionary<MethodDef, ProxyCreatorType>(); Dictionary<MethodDef, ProxyCreatorType> methodToType = new Dictionary<MethodDef, ProxyCreatorType>();
public ProxyCallFixer(ModuleDefinition module) public ProxyCallFixer(ModuleDefMD module)
: base(module) { : base(module) {
} }
@ -39,11 +39,11 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
} }
class Context { class Context {
public int typeToken; public uint typeToken;
public int methodToken; public uint methodToken;
public int declaringTypeToken; public uint declaringTypeToken;
public ProxyCreatorType proxyCreatorType; public ProxyCreatorType proxyCreatorType;
public Context(int typeToken, int methodToken, int declaringTypeToken, ProxyCreatorType proxyCreatorType) { public Context(uint typeToken, uint methodToken, uint declaringTypeToken, ProxyCreatorType proxyCreatorType) {
this.typeToken = typeToken; this.typeToken = typeToken;
this.methodToken = methodToken; this.methodToken = methodToken;
this.declaringTypeToken = declaringTypeToken; this.declaringTypeToken = declaringTypeToken;
@ -58,9 +58,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (instrs == null) if (instrs == null)
continue; continue;
int typeToken = (int)instrs[0].Operand; uint typeToken = (uint)(int)instrs[0].Operand;
int methodToken = (int)instrs[1].Operand; uint methodToken = (uint)(int)instrs[1].Operand;
int declaringTypeToken = (int)instrs[2].Operand; uint declaringTypeToken = (uint)(int)instrs[2].Operand;
var createMethod = instrs[3].Operand as MethodDef; var createMethod = instrs[3].Operand as MethodDef;
ProxyCreatorType proxyCreatorType; ProxyCreatorType proxyCreatorType;
@ -73,12 +73,12 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
return null; return null;
} }
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) { protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
var ctx = (Context)context; var ctx = (Context)context;
switch (ctx.proxyCreatorType) { switch (ctx.proxyCreatorType) {
case ProxyCreatorType.CallOrCallvirt: case ProxyCreatorType.CallOrCallvirt:
callOpcode = field.IsFamilyOrAssembly ? OpCodes.Callvirt : OpCodes.Call; callOpcode = field.IsFamORAssem ? OpCodes.Callvirt : OpCodes.Call;
break; break;
case ProxyCreatorType.CallCtor: case ProxyCreatorType.CallCtor:
callOpcode = OpCodes.Call; callOpcode = OpCodes.Call;
@ -90,7 +90,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
throw new ApplicationException(string.Format("Invalid proxy creator type: {0}", ctx.proxyCreatorType)); throw new ApplicationException(string.Format("Invalid proxy creator type: {0}", ctx.proxyCreatorType));
} }
calledMethod = module.LookupToken(ctx.methodToken) as MethodReference; calledMethod = module.ResolveToken(ctx.methodToken) as IMethod;
} }
public void findDelegateCreator() { public void findDelegateCreator() {
@ -136,7 +136,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
foreach (var instr in createMethod.Body.Instructions) { foreach (var instr in createMethod.Body.Instructions) {
if (instr.OpCode.Code != Code.Ldsfld) if (instr.OpCode.Code != Code.Ldsfld)
continue; continue;
var field = instr.Operand as FieldReference; var field = instr.Operand as IField;
if (field == null) if (field == null)
continue; continue;
switch (field.FullName) { switch (field.FullName) {

View File

@ -29,7 +29,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class ResourceDecrypter { class ResourceDecrypter {
const int BUFLEN = 0x8000; const int BUFLEN = 0x8000;
ModuleDefinition module; ModuleDefMD module;
TypeDef resourceDecrypterType; TypeDef resourceDecrypterType;
byte[] buffer1 = new byte[BUFLEN]; byte[] buffer1 = new byte[BUFLEN];
byte[] buffer2 = new byte[BUFLEN]; byte[] buffer2 = new byte[BUFLEN];
@ -40,7 +40,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
bool flipFlagsBits; bool flipFlagsBits;
int skipBytes; int skipBytes;
public ResourceDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) { public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
this.module = module; this.module = module;
frameworkType = DotNetUtils.getFrameworkType(module); frameworkType = DotNetUtils.getFrameworkType(module);
find(simpleDeobfuscator); find(simpleDeobfuscator);
@ -49,7 +49,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
void find(ISimpleDeobfuscator simpleDeobfuscator) { void find(ISimpleDeobfuscator simpleDeobfuscator) {
switch (frameworkType) { switch (frameworkType) {
case FrameworkType.Desktop: case FrameworkType.Desktop:
if (module.Runtime >= TargetRuntime.Net_2_0) if (!module.IsClr1x)
findDesktopOrCompactFramework(); findDesktopOrCompactFramework();
else else
findDesktopOrCompactFrameworkV1(); findDesktopOrCompactFrameworkV1();
@ -60,7 +60,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
break; break;
case FrameworkType.CompactFramework: case FrameworkType.CompactFramework:
if (module.Runtime >= TargetRuntime.Net_2_0) { if (!module.IsClr1x) {
if (findDesktopOrCompactFramework()) if (findDesktopOrCompactFramework())
break; break;
} }
@ -84,7 +84,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (!new FieldTypes(type).exactly(requiredTypes)) if (!new FieldTypes(type).exactly(requiredTypes))
continue; continue;
var cctor = DotNetUtils.getMethod(type, ".cctor"); var cctor = type.FindClassConstructor();
if (cctor == null) if (cctor == null)
continue; continue;
@ -103,8 +103,8 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
int stsfldCount = 0; int stsfldCount = 0;
foreach (var instr in cctor.Body.Instructions) { foreach (var instr in cctor.Body.Instructions) {
if (instr.OpCode.Code == Code.Stsfld) { if (instr.OpCode.Code == Code.Stsfld) {
var field = instr.Operand as FieldReference; var field = instr.Operand as IField;
if (!MemberReferenceHelper.compareTypes(cctor.DeclaringType, field.DeclaringType)) if (!new SigComparer().Equals(cctor.DeclaringType, field.DeclaringType))
return false; return false;
stsfldCount++; stsfldCount++;
} }
@ -186,10 +186,10 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) { for (int i = 0; i < instrs.Count - 1; i++) {
var ldloc = instrs[i]; var ldloc = instrs[i];
if (!DotNetUtils.isLdloc(ldloc)) if (!ldloc.IsLdloc())
continue; continue;
var local = DotNetUtils.getLocalVar(method.Body.Variables, ldloc); var local = ldloc.GetLocal(method.Body.LocalList);
if (local == null || !local.VariableType.IsPrimitive) if (local == null || local.Type.GetElementType().GetPrimitiveSize() < 0)
continue; continue;
var not = instrs[i + 1]; var not = instrs[i + 1];
@ -214,16 +214,16 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (and.OpCode.Code != Code.And) if (and.OpCode.Code != Code.And)
continue; continue;
var ldci4 = instructions[i - 1]; var ldci4 = instructions[i - 1];
if (!DotNetUtils.isLdcI4(ldci4)) if (!ldci4.IsLdcI4())
continue; continue;
int flagValue = DotNetUtils.getLdcI4Value(ldci4); int flagValue = ldci4.GetLdcI4Value();
if (!isFlag(flagValue)) if (!isFlag(flagValue))
continue; continue;
var ldloc = instructions[i - 2]; var ldloc = instructions[i - 2];
if (!DotNetUtils.isLdloc(ldloc)) if (!ldloc.IsLdloc())
continue; continue;
var local = DotNetUtils.getLocalVar(method.Body.Variables, ldloc); var local = ldloc.GetLocal(method.Body.LocalList);
if (!local.VariableType.IsPrimitive) if (local.Type.GetElementType().GetPrimitiveSize() < 0)
continue; continue;
constants.Add(flagValue); constants.Add(flagValue);
} }
@ -233,7 +233,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
switch (frameworkType) { switch (frameworkType) {
case FrameworkType.Desktop: case FrameworkType.Desktop:
if (module.Runtime >= TargetRuntime.Net_2_0) { if (!module.IsClr1x) {
if (constants.Count == 2) { if (constants.Count == 2) {
desEncryptedFlag = (byte)constants[0]; desEncryptedFlag = (byte)constants[0];
deflatedFlag = (byte)constants[1]; deflatedFlag = (byte)constants[1];
@ -270,9 +270,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) { for (int i = 0; i < instrs.Count - 1; i++) {
var ldci4 = instrs[i]; var ldci4 = instrs[i];
if (!DotNetUtils.isLdcI4(ldci4)) if (!ldci4.IsLdcI4())
continue; continue;
int loopCount = DotNetUtils.getLdcI4Value(ldci4); int loopCount = ldci4.GetLdcI4Value();
if (loopCount < 2 || loopCount > 3) if (loopCount < 2 || loopCount > 3)
continue; continue;
var blt = instrs[i + 1]; var blt = instrs[i + 1];
@ -402,7 +402,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (key[i] != 0) if (key[i] != 0)
return key; return key;
} }
key = module.Assembly.Name.PublicKeyToken; key = PublicKeyBase.GetRawData(module.Assembly.PublicKeyToken);
if (key == null) if (key == null)
throw new ApplicationException("PublicKeyToken is null, can't decrypt resources"); throw new ApplicationException("PublicKeyToken is null, can't decrypt resources");
return key; return key;

View File

@ -19,13 +19,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using dot10.IO;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class ResourceResolver { class ResourceResolver {
ModuleDefinition module; ModuleDefMD module;
ResourceDecrypter resourceDecrypter; ResourceDecrypter resourceDecrypter;
TypeDef resolverType; TypeDef resolverType;
MethodDef resolverMethod; MethodDef resolverMethod;
@ -46,7 +47,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
get { return resolverMethod; } get { return resolverMethod; }
} }
public ResourceResolver(ModuleDefinition module, ResourceDecrypter resourceDecrypter) { public ResourceResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter) {
this.module = module; this.module = module;
this.resourceDecrypter = resourceDecrypter; this.resourceDecrypter = resourceDecrypter;
} }
@ -74,7 +75,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (resource == null) if (resource == null)
return null; return null;
DeobUtils.decryptAndAddResources(module, resource.Name, () => resourceDecrypter.decrypt(resource.GetResourceStream())); DeobUtils.decryptAndAddResources(module, resource.Name.String, () => resourceDecrypter.decrypt(resource.Data.CreateStream()));
mergedIt = true; mergedIt = true;
return resource; return resource;
} }
@ -84,12 +85,12 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
switch (resolverVersion) { switch (resolverVersion) {
case ResolverVersion.V1: case ResolverVersion.V1:
names.Add(module.Assembly.Name.Name); names.Add(module.Assembly.Name.String);
break; break;
case ResolverVersion.V2: case ResolverVersion.V2:
names.Add(string.Format("{0}{0}{0}", module.Assembly.Name.Name)); names.Add(string.Format("{0}{0}{0}", module.Assembly.Name.String));
names.Add(string.Format("{0}&", module.Assembly.Name.Name)); names.Add(string.Format("{0}&", module.Assembly.Name.String));
break; break;
default: default:
@ -107,7 +108,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
resolverVersion = checkSetupMethod(initMethod); resolverVersion = checkSetupMethod(initMethod);
if (resolverVersion == ResolverVersion.None) if (resolverVersion == ResolverVersion.None)
resolverVersion = checkSetupMethod(DotNetUtils.getMethod(initMethod.DeclaringType, ".cctor")); resolverVersion = checkSetupMethod(initMethod.DeclaringType.FindClassConstructor());
if (resolverVersion == ResolverVersion.None) if (resolverVersion == ResolverVersion.None)
return false; return false;
@ -124,15 +125,15 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (instrs == null) if (instrs == null)
continue; continue;
MethodReference methodRef; IMethod methodRef;
var ldftn = instrs[1]; var ldftn = instrs[1];
var newobj = instrs[2]; var newobj = instrs[2];
methodRef = ldftn.Operand as MethodReference; methodRef = ldftn.Operand as IMethod;
if (methodRef == null || !MemberReferenceHelper.compareTypes(setupMethod.DeclaringType, methodRef.DeclaringType)) if (methodRef == null || !new SigComparer().Equals(setupMethod.DeclaringType, methodRef.DeclaringType))
continue; continue;
methodRef = newobj.Operand as MethodReference; methodRef = newobj.Operand as IMethod;
if (methodRef == null || methodRef.FullName != "System.Void System.ResolveEventHandler::.ctor(System.Object,System.IntPtr)") if (methodRef == null || methodRef.FullName != "System.Void System.ResolveEventHandler::.ctor(System.Object,System.IntPtr)")
continue; continue;

View File

@ -24,7 +24,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class StringDecrypter { class StringDecrypter {
ModuleDefinition module; ModuleDefMD module;
EmbeddedResource stringResource; EmbeddedResource stringResource;
TypeDef stringDecrypterType; TypeDef stringDecrypterType;
MethodDef stringDecrypterMethod; MethodDef stringDecrypterMethod;
@ -46,7 +46,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
get { return stringResource; } get { return stringResource; }
} }
public StringDecrypter(ModuleDefinition module) { public StringDecrypter(ModuleDefMD module) {
this.module = module; this.module = module;
} }
@ -74,9 +74,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
} }
string getResourceName() { string getResourceName() {
var defaultName = module.Assembly.Name.Name + module.Assembly.Name.Name; var defaultName = module.Assembly.Name.String + module.Assembly.Name.String;
var cctor = DotNetUtils.getMethod(stringDecrypterType, ".cctor"); var cctor = stringDecrypterType.FindClassConstructor();
if (cctor == null) if (cctor == null)
return defaultName; return defaultName;

View File

@ -22,7 +22,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.CryptoObfuscator { namespace de4dot.code.deobfuscators.CryptoObfuscator {
class TamperDetection { class TamperDetection {
ModuleDefinition module; ModuleDefMD module;
TypeDef tamperType; TypeDef tamperType;
MethodDef tamperMethod; MethodDef tamperMethod;
FrameworkType frameworkType; FrameworkType frameworkType;
@ -39,7 +39,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
get { return tamperMethod; } get { return tamperMethod; }
} }
public TamperDetection(ModuleDefinition module) { public TamperDetection(ModuleDefMD module) {
this.module = module; this.module = module;
frameworkType = DotNetUtils.getFrameworkType(module); frameworkType = DotNetUtils.getFrameworkType(module);
} }

View File

@ -42,8 +42,8 @@ namespace de4dot.cui {
new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.CryptoObfuscator.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CryptoObfuscator.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.DeepSea.DeobfuscatorInfo(), new de4dot.code.deobfuscators.DeepSea.DeobfuscatorInfo(),
#endif #endif
new de4dot.code.deobfuscators.Dotfuscator.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Dotfuscator.DeobfuscatorInfo(),

2
dot10

@ -1 +1 @@
Subproject commit da98052a05288943bcb29e813b3c3ba448ae2101 Subproject commit ba1fa2135fec435ecee2ea041c9a7dae56e5dd47