diff --git a/AssemblyData/Properties/AssemblyInfo.cs b/AssemblyData/Properties/AssemblyInfo.cs
index 99a902f6..78293473 100644
--- a/AssemblyData/Properties/AssemblyInfo.cs
+++ b/AssemblyData/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/AssemblyServer-x64/Properties/AssemblyInfo.cs b/AssemblyServer-x64/Properties/AssemblyInfo.cs
index 9cb5bb5b..c4330fb8 100644
--- a/AssemblyServer-x64/Properties/AssemblyInfo.cs
+++ b/AssemblyServer-x64/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/AssemblyServer/Properties/AssemblyInfo.cs b/AssemblyServer/Properties/AssemblyInfo.cs
index 2795ab9f..815629e1 100644
--- a/AssemblyServer/Properties/AssemblyInfo.cs
+++ b/AssemblyServer/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/Test.Rename.Dll/Properties/AssemblyInfo.cs b/Test.Rename.Dll/Properties/AssemblyInfo.cs
index 9486df2f..d3e69b3b 100644
--- a/Test.Rename.Dll/Properties/AssemblyInfo.cs
+++ b/Test.Rename.Dll/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/Test.Rename/Properties/AssemblyInfo.cs b/Test.Rename/Properties/AssemblyInfo.cs
index 8df4d981..85be43f6 100644
--- a/Test.Rename/Properties/AssemblyInfo.cs
+++ b/Test.Rename/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/blocks/Properties/AssemblyInfo.cs b/blocks/Properties/AssemblyInfo.cs
index d748da5e..81934537 100644
--- a/blocks/Properties/AssemblyInfo.cs
+++ b/blocks/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/cecil b/cecil
index c8f4f6bc..86e21d47 160000
--- a/cecil
+++ b/cecil
@@ -1 +1 @@
-Subproject commit c8f4f6bcaaa45804631a805c3840517888dcb0bd
+Subproject commit 86e21d470a0232f6b746ee2b8b7a9483c1842fea
diff --git a/de4dot-x64/Properties/AssemblyInfo.cs b/de4dot-x64/Properties/AssemblyInfo.cs
index f1c5a35f..5a109bcc 100644
--- a/de4dot-x64/Properties/AssemblyInfo.cs
+++ b/de4dot-x64/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/de4dot.code/Properties/AssemblyInfo.cs b/de4dot.code/Properties/AssemblyInfo.cs
index 244d1c0e..fbdb9ad5 100644
--- a/de4dot.code/Properties/AssemblyInfo.cs
+++ b/de4dot.code/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj
index c601dd14..d373674f 100644
--- a/de4dot.code/de4dot.code.csproj
+++ b/de4dot.code/de4dot.code.csproj
@@ -96,6 +96,9 @@
+
+
+
diff --git a/de4dot.code/deobfuscators/Babel_NET/MethodReferenceReader.cs b/de4dot.code/deobfuscators/Babel_NET/MethodReferenceReader.cs
index e1f1b33a..5988c41d 100644
--- a/de4dot.code/deobfuscators/Babel_NET/MethodReferenceReader.cs
+++ b/de4dot.code/deobfuscators/Babel_NET/MethodReferenceReader.cs
@@ -60,9 +60,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
public int Flags2 { get; set; }
public short MaxStack { get; set; }
- public List Locals { get; set; }
- public Instruction[] Instructions { get; set; }
- public ExceptionHandler[] ExceptionHandlers { get; set; }
+ public IList Locals { get; set; }
+ public IList Instructions { get; set; }
+ public IList ExceptionHandlers { get; set; }
public bool IsStatic {
get { return (Flags2 & 0x10) != 0; }
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs b/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs
index 1f9cf645..1704aa20 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs
@@ -65,7 +65,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (!containsString(method, "debugger is activ") &&
!containsString(method, "debugger is running") &&
!containsString(method, "run under a debugger") &&
- !containsString(method, "Debugger detected"))
+ !containsString(method, "run under debugger") &&
+ !containsString(method, "Debugger detected") &&
+ !containsString(method, "Debugger was detected"))
continue;
antiDebuggerType = type;
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/AssemblyResolver.cs b/de4dot.code/deobfuscators/CryptoObfuscator/AssemblyResolver.cs
index 1cad1e19..1dcfc324 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/AssemblyResolver.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/AssemblyResolver.cs
@@ -46,6 +46,10 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
}
}
+ public bool Detected {
+ get { return resolverType != null; }
+ }
+
public List AssemblyInfos {
get { return assemblyInfos; }
}
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/CoUtils.cs b/de4dot.code/deobfuscators/CryptoObfuscator/CoUtils.cs
new file mode 100644
index 00000000..d3f37981
--- /dev/null
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/CoUtils.cs
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2011-2012 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Mono.Cecil;
+using de4dot.blocks;
+
+namespace de4dot.code.deobfuscators.CryptoObfuscator {
+ static class CoUtils {
+ public static EmbeddedResource getResource(ModuleDefinition module, MethodDefinition method) {
+ if (method == null || method.Body == null)
+ return null;
+ return getResource(module, DotNetUtils.getCodeStrings(method));
+ }
+
+ public static EmbeddedResource getResource(ModuleDefinition module, IEnumerable names) {
+ foreach (var name in names) {
+ var resource = DotNetUtils.getResource(module, name) as EmbeddedResource;
+ if (resource != null)
+ return resource;
+ try {
+ resource = DotNetUtils.getResource(module, Encoding.UTF8.GetString(Convert.FromBase64String(name))) as EmbeddedResource;
+ if (resource != null)
+ return resource;
+ }
+ catch {
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ConstantsDecrypter.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ConstantsDecrypter.cs
index 6b3940a2..2240e431 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/ConstantsDecrypter.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/ConstantsDecrypter.cs
@@ -82,7 +82,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
bool checkType(TypeDefinition type) {
if (type.Methods.Count != 7)
return false;
- if (type.Fields.Count != 1)
+ if (type.Fields.Count < 1 || type.Fields.Count > 2)
return false;
if (!new FieldTypes(type).all(requiredTypes))
return false;
@@ -106,26 +106,10 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (decrypterType == null)
return;
- encryptedResource = getResource(module, DotNetUtils.getCodeStrings(DotNetUtils.getMethod(decrypterType, ".cctor")));
+ encryptedResource = CoUtils.getResource(module, DotNetUtils.getCodeStrings(DotNetUtils.getMethod(decrypterType, ".cctor")));
constantsData = resourceDecrypter.decrypt(encryptedResource.GetResourceStream());
}
- static EmbeddedResource getResource(ModuleDefinition module, IEnumerable names) {
- foreach (var name in names) {
- var resource = DotNetUtils.getResource(module, name) as EmbeddedResource;
- if (resource != null)
- return resource;
- try {
- resource = DotNetUtils.getResource(module, Encoding.UTF8.GetString(Convert.FromBase64String(name))) as EmbeddedResource;
- if (resource != null)
- return resource;
- }
- catch {
- }
- }
- return null;
- }
-
public int decryptInt32(int index) {
return BitConverter.ToInt32(constantsData, index);
}
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/Deobfuscator.cs b/de4dot.code/deobfuscators/CryptoObfuscator/Deobfuscator.cs
index cdceaa12..6d440bad 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/Deobfuscator.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/Deobfuscator.cs
@@ -68,6 +68,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
bool foundObfuscatedSymbols = false;
bool foundObfuscatorUserString = false;
+ MethodsDecrypter methodsDecrypter;
ProxyCallFixer proxyCallFixer;
ResourceDecrypter resourceDecrypter;
ResourceResolver resourceResolver;
@@ -111,7 +112,8 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
protected override int detectInternal() {
int val = 0;
- int sum = toInt32(stringDecrypter.Detected) +
+ int sum = toInt32(methodsDecrypter.Detected) +
+ toInt32(stringDecrypter.Detected) +
toInt32(tamperDetection.Detected) +
toInt32(proxyCallFixer.Detected) +
toInt32(constantsDecrypter.Detected);
@@ -134,6 +136,8 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (checkCryptoObfuscator())
foundObfuscatedSymbols = true;
+ methodsDecrypter = new MethodsDecrypter(module);
+ methodsDecrypter.find();
proxyCallFixer = new ProxyCallFixer(module);
proxyCallFixer.findDelegateCreator();
stringDecrypter = new StringDecrypter(module);
@@ -190,6 +194,14 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
DeobfuscatedFile.stringDecryptersAdded();
}
+ methodsDecrypter.decrypt(resourceDecrypter);
+
+ if (methodsDecrypter.Detected) {
+ if (!assemblyResolver.Detected)
+ assemblyResolver.find();
+ if (!tamperDetection.Detected)
+ tamperDetection.find();
+ }
antiDebugger = new AntiDebugger(module, DeobfuscatedFile, this);
antiDebugger.find();
@@ -217,6 +229,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
addTypeToBeRemoved(assemblyResolver.Type, "Assembly resolver type");
addTypeToBeRemoved(tamperDetection.Type, "Tamper detection type");
addTypeToBeRemoved(antiDebugger.Type, "Anti-debugger type");
+ addTypeToBeRemoved(methodsDecrypter.Type, "Methods decrypter type");
+ addTypesToBeRemoved(methodsDecrypter.DelegateTypes, "Methods decrypter delegate type");
+ addResourceToBeRemoved(methodsDecrypter.Resource, "Encrypted methods");
proxyCallFixer.find();
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/MethodBodyReader.cs b/de4dot.code/deobfuscators/CryptoObfuscator/MethodBodyReader.cs
new file mode 100644
index 00000000..22860f01
--- /dev/null
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/MethodBodyReader.cs
@@ -0,0 +1,123 @@
+/*
+ Copyright (C) 2011-2012 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using de4dot.blocks;
+
+namespace de4dot.code.deobfuscators.CryptoObfuscator {
+ class MethodBodyReader : MethodBodyReaderBase {
+ ModuleDefinition module;
+ ushort maxStackSize;
+
+ public MethodBodyReader(ModuleDefinition module, BinaryReader reader)
+ : base(reader) {
+ this.module = module;
+ }
+
+ public void read(MethodDefinition method) {
+ this.parameters = getParameters(method);
+ this.Locals = getLocals(method);
+
+ maxStackSize = (ushort)reader.ReadInt32();
+ readInstructionsNumBytes(reader.ReadUInt32());
+ readExceptionHandlers();
+ }
+
+ void readExceptionHandlers() {
+ int totalSize = reader.ReadInt32();
+ if (totalSize == 0)
+ return;
+ reader.ReadInt32();
+ readExceptionHandlers((totalSize - 4) / 24);
+ }
+
+ static IList getParameters(MethodReference method) {
+ return DotNetUtils.getParameters(method);
+ }
+
+ static IList getLocals(MethodDefinition method) {
+ if (method.Body == null)
+ return new List();
+ return new List(method.Body.Variables);
+ }
+
+ protected override FieldReference readInlineField(Instruction instr) {
+ return (FieldReference)module.LookupToken(reader.ReadInt32());
+ }
+
+ protected override MethodReference readInlineMethod(Instruction instr) {
+ return (MethodReference)module.LookupToken(reader.ReadInt32());
+ }
+
+ protected override CallSite readInlineSig(Instruction instr) {
+ return module.ReadCallSite(new MetadataToken(reader.ReadUInt32()));
+ }
+
+ protected override string readInlineString(Instruction instr) {
+ return module.GetUserString(reader.ReadUInt32());
+ }
+
+ protected override MemberReference readInlineTok(Instruction instr) {
+ return (MemberReference)module.LookupToken(reader.ReadInt32());
+ }
+
+ protected override TypeReference readInlineType(Instruction instr) {
+ return (TypeReference)module.LookupToken(reader.ReadInt32());
+ }
+
+ protected override ExceptionHandler readExceptionHandler() {
+ var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadInt32());
+
+ int tryOffset = reader.ReadInt32();
+ eh.TryStart = getInstruction(tryOffset);
+ eh.TryEnd = getInstructionOrNull(tryOffset + reader.ReadInt32());
+
+ int handlerOffset = reader.ReadInt32();
+ eh.HandlerStart = getInstruction(handlerOffset);
+ eh.HandlerEnd = getInstructionOrNull(handlerOffset + reader.ReadInt32());
+
+ switch (eh.HandlerType) {
+ case ExceptionHandlerType.Catch:
+ eh.CatchType = (TypeReference)module.LookupToken(reader.ReadInt32());
+ break;
+
+ case ExceptionHandlerType.Filter:
+ eh.FilterStart = getInstruction(reader.ReadInt32());
+ break;
+
+ case ExceptionHandlerType.Finally:
+ case ExceptionHandlerType.Fault:
+ default:
+ reader.ReadInt32();
+ break;
+ }
+
+ return eh;
+ }
+
+ public override void restoreMethod(MethodDefinition method) {
+ base.restoreMethod(method);
+ method.Body.MaxStackSize = maxStackSize;
+ }
+ }
+}
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/MethodsDecrypter.cs b/de4dot.code/deobfuscators/CryptoObfuscator/MethodsDecrypter.cs
new file mode 100644
index 00000000..d55cd744
--- /dev/null
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/MethodsDecrypter.cs
@@ -0,0 +1,205 @@
+/*
+ Copyright (C) 2011-2012 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using de4dot.blocks;
+
+namespace de4dot.code.deobfuscators.CryptoObfuscator {
+ class MethodsDecrypter {
+ ModuleDefinition module;
+ TypeDefinition decrypterType;
+ MethodDefinition decryptMethod;
+ MethodDefinition decrypterCctor;
+ EmbeddedResource resource;
+ List delegateTypes = new List();
+
+ public TypeDefinition Type {
+ get { return decrypterType; }
+ }
+
+ public IEnumerable DelegateTypes {
+ get { return delegateTypes; }
+ }
+
+ public EmbeddedResource Resource {
+ get { return resource; }
+ }
+
+ public bool Detected {
+ get { return decrypterType != null; }
+ }
+
+ public MethodsDecrypter(ModuleDefinition module) {
+ this.module = module;
+ }
+
+ public void find() {
+ foreach (var type in module.Types) {
+ if (check(type))
+ break;
+ }
+ }
+
+ static readonly string[] requiredFields = new string[] {
+ "System.Byte[]",
+ "System.Collections.Generic.Dictionary`2",
+ "System.ModuleHandle",
+ };
+ bool check(TypeDefinition type) {
+ if (type.NestedTypes.Count != 1)
+ return false;
+ if (type.Fields.Count != 3)
+ return false;
+ if (!new FieldTypes(type).all(requiredFields))
+ return false;
+
+ var cctor = DotNetUtils.getMethod(type, ".cctor");
+ if (cctor == null)
+ return false;
+ var decryptMethodTmp = findDecryptMethod(type);
+ if (decryptMethodTmp == null)
+ return false;
+
+ decryptMethod = decryptMethodTmp;
+ decrypterCctor = cctor;
+ decrypterType = type;
+ return true;
+ }
+
+ static readonly string[] requiredLocals = new string[] {
+ "System.Delegate",
+ "System.ModuleHandle",
+ "System.Reflection.Emit.DynamicILInfo",
+ "System.Reflection.Emit.DynamicMethod",
+ "System.Reflection.FieldInfo",
+ "System.Reflection.FieldInfo[]",
+ "System.Reflection.MethodBase",
+ "System.Reflection.MethodBody",
+ "System.Type",
+ "System.Type[]",
+ };
+ static MethodDefinition findDecryptMethod(TypeDefinition type) {
+ foreach (var method in type.Methods) {
+ if (!method.IsStatic || method.Body == null)
+ continue;
+ if (!new LocalTypes(method).all(requiredLocals))
+ continue;
+ if (!DotNetUtils.isMethod(method, "System.Void", "(System.Int32,System.Int32,System.Int32)"))
+ continue;
+
+ return method;
+ }
+ return null;
+ }
+
+ public void decrypt(ResourceDecrypter resourceDecrypter) {
+ if (decryptMethod == null)
+ return;
+
+ resource = CoUtils.getResource(module, decrypterCctor);
+ if (resource == null)
+ return;
+ var decrypted = resourceDecrypter.decrypt(resource.GetResourceStream());
+ var reader = new BinaryReader(new MemoryStream(decrypted));
+ int numEncrypted = reader.ReadInt32();
+ Log.v("Restoring {0} encrypted methods", numEncrypted);
+ Log.indent();
+ for (int i = 0; i < numEncrypted; i++) {
+ int delegateTypeToken = reader.ReadInt32();
+ uint codeOffset = reader.ReadUInt32();
+ var origOffset = reader.BaseStream.Position;
+ reader.BaseStream.Position = codeOffset;
+ decrypt(reader, delegateTypeToken);
+ reader.BaseStream.Position = origOffset;
+ }
+ Log.deIndent();
+ }
+
+ void decrypt(BinaryReader reader, int delegateTypeToken) {
+ var delegateType = module.LookupToken(delegateTypeToken) as TypeDefinition;
+ if (delegateType == null)
+ throw new ApplicationException("Couldn't find delegate type");
+
+ int delToken, encMethToken, encDeclToken;
+ if (!getTokens(delegateType, out delToken, out encMethToken, out encDeclToken))
+ throw new ApplicationException("Could not find encrypted method tokens");
+ if (delToken != delegateTypeToken)
+ throw new ApplicationException("Invalid delegate type token");
+ var encType = module.LookupToken(encDeclToken) as TypeReference;
+ if (encType == null)
+ throw new ApplicationException("Invalid declaring type token");
+ var encMethod = module.LookupToken(encMethToken) as MethodDefinition;
+ if (encMethod == null)
+ throw new ApplicationException("Invalid encrypted method token");
+
+ var bodyReader = new MethodBodyReader(module, reader);
+ bodyReader.read(encMethod);
+ bodyReader.restoreMethod(encMethod);
+ Log.v("Restored method {0} ({1:X8}). Instrs:{2}, Locals:{3}, Exceptions:{4}",
+ Utils.removeNewlines(encMethod.FullName),
+ encMethod.MetadataToken.ToInt32(),
+ encMethod.Body.Instructions.Count,
+ encMethod.Body.Variables.Count,
+ encMethod.Body.ExceptionHandlers.Count);
+ delegateTypes.Add(delegateType);
+ }
+
+ bool getTokens(TypeDefinition delegateType, out int delegateToken, out int encMethodToken, out int encDeclaringTypeToken) {
+ delegateToken = 0;
+ encMethodToken = 0;
+ encDeclaringTypeToken = 0;
+
+ var cctor = DotNetUtils.getMethod(delegateType, ".cctor");
+ if (cctor == null)
+ return false;
+
+ var instrs = cctor.Body.Instructions;
+ for (int i = 0; i < instrs.Count - 3; i++) {
+ var ldci4_1 = instrs[i];
+ if (!DotNetUtils.isLdcI4(ldci4_1))
+ continue;
+ var ldci4_2 = instrs[i + 1];
+ if (!DotNetUtils.isLdcI4(ldci4_2))
+ continue;
+ var ldci4_3 = instrs[i + 2];
+ if (!DotNetUtils.isLdcI4(ldci4_3))
+ continue;
+ var call = instrs[i + 3];
+ if (call.OpCode.Code != Code.Call)
+ continue;
+ var calledMethod = call.Operand as MethodDefinition;
+ if (calledMethod == null)
+ continue;
+ if (calledMethod != decryptMethod)
+ continue;
+
+ delegateToken = DotNetUtils.getLdcI4Value(ldci4_1);
+ encMethodToken = DotNetUtils.getLdcI4Value(ldci4_2);
+ encDeclaringTypeToken = DotNetUtils.getLdcI4Value(ldci4_3);
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs
index 9fb4f2cb..52288048 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs
@@ -110,7 +110,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
MethodDefinition getProxyCreateMethod(TypeDefinition type) {
if (DotNetUtils.findFieldType(type, "System.ModuleHandle", true) == null)
return null;
- if (type.Fields.Count < 1 || type.Fields.Count > 8)
+ if (type.Fields.Count < 1 || type.Fields.Count > 10)
return null;
MethodDefinition createMethod = null;
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs
index 32bada9f..0e84de0d 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs
@@ -304,8 +304,12 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
return method;
if (DotNetUtils.isMethod(method, "System.Byte[]", "(System.Byte,System.IO.Stream)"))
return method;
+ if (DotNetUtils.isMethod(method, "System.Byte[]", "(System.SByte,System.IO.Stream)"))
+ return method;
if (DotNetUtils.isMethod(method, "System.Byte[]", "(System.Byte,System.IO.Stream,System.Int32)"))
return method;
+ if (DotNetUtils.isMethod(method, "System.Byte[]", "(System.SByte,System.IO.Stream,System.UInt32)"))
+ return method;
}
return null;
}
diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs b/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs
index 67dde72a..e2512da4 100644
--- a/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs
+++ b/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs
@@ -84,7 +84,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()"))
return false;
- if (type.Methods.Count < 3 || type.Methods.Count > 10)
+ if (type.Methods.Count < 3 || type.Methods.Count > 12)
return false;
if (DotNetUtils.getPInvokeMethod(type, "mscoree", "StrongNameSignatureVerificationEx") != null) {
}
diff --git a/de4dot.code/deobfuscators/ILProtector/MethodsDecrypter.cs b/de4dot.code/deobfuscators/ILProtector/MethodsDecrypter.cs
index 201c8dda..15324013 100644
--- a/de4dot.code/deobfuscators/ILProtector/MethodsDecrypter.cs
+++ b/de4dot.code/deobfuscators/ILProtector/MethodsDecrypter.cs
@@ -241,28 +241,9 @@ namespace de4dot.code.deobfuscators.ILProtector {
}
static void restoreMethod(MethodDefinition method, MethodReader methodReader) {
- var body = method.Body;
-
// body.MaxStackSize =
- body.InitLocals = methodReader.InitLocals;
-
- body.Variables.Clear();
- if (methodReader.Locals != null) {
- foreach (var local in methodReader.Locals)
- body.Variables.Add(local);
- }
-
- body.Instructions.Clear();
- if (methodReader.Instructions != null) {
- foreach (var instr in methodReader.Instructions)
- body.Instructions.Add(instr);
- }
-
- body.ExceptionHandlers.Clear();
- if (methodReader.ExceptionHandlers != null) {
- foreach (var eh in methodReader.ExceptionHandlers)
- body.ExceptionHandlers.Add(eh);
- }
+ method.Body.InitLocals = methodReader.InitLocals;
+ methodReader.restoreMethod(method);
}
int getMethodId(MethodDefinition method) {
diff --git a/de4dot.code/deobfuscators/MethodBodyReaderBase.cs b/de4dot.code/deobfuscators/MethodBodyReaderBase.cs
index 962e4abf..7c3fe0ea 100644
--- a/de4dot.code/deobfuscators/MethodBodyReaderBase.cs
+++ b/de4dot.code/deobfuscators/MethodBodyReaderBase.cs
@@ -27,9 +27,9 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators {
abstract class MethodBodyReaderBase {
protected BinaryReader reader;
- public List Locals { get; set; }
- public Instruction[] Instructions { get; set; }
- public ExceptionHandler[] ExceptionHandlers { get; set; }
+ public IList Locals { get; set; }
+ public IList Instructions { get; set; }
+ public IList ExceptionHandlers { get; set; }
protected IList parameters;
int currentOffset;
@@ -46,17 +46,34 @@ namespace de4dot.code.deobfuscators {
protected void readInstructions(int numInstrs) {
Instructions = new Instruction[numInstrs];
currentOffset = 0;
- for (int i = 0; i < Instructions.Length; i++) {
- var instr = readInstruction();
- Instructions[i] = instr;
- if (instr.OpCode.Code == Code.Switch) {
- int[] targets = (int[])instr.Operand;
- currentOffset += instr.OpCode.Size + 4 + 4 * targets.Length;
- }
- else
- currentOffset += Instructions[i].GetSize();
- }
+ for (int i = 0; i < Instructions.Count; i++)
+ Instructions[i] = readOneInstruction();
+ fixBranches();
+ }
+ protected void readInstructionsNumBytes(uint codeSize) {
+ var instrs = new List();
+ long endOffs = reader.BaseStream.Position + codeSize;
+ while (reader.BaseStream.Position < endOffs)
+ instrs.Add(readOneInstruction());
+ if (reader.BaseStream.Position != endOffs)
+ throw new ApplicationException("Could not read all instructions");
+ Instructions = instrs;
+ fixBranches();
+ }
+
+ Instruction readOneInstruction() {
+ var instr = readInstruction();
+ if (instr.OpCode.Code == Code.Switch) {
+ int[] targets = (int[])instr.Operand;
+ currentOffset += instr.OpCode.Size + 4 + 4 * targets.Length;
+ }
+ else
+ currentOffset += instr.GetSize();
+ return instr;
+ }
+
+ void fixBranches() {
foreach (var instr in Instructions) {
switch (instr.OpCode.OperandType) {
case OperandType.InlineBrTarget:
@@ -231,10 +248,32 @@ namespace de4dot.code.deobfuscators {
protected void readExceptionHandlers(int numExceptionHandlers) {
ExceptionHandlers = new ExceptionHandler[numExceptionHandlers];
- for (int i = 0; i < ExceptionHandlers.Length; i++)
+ for (int i = 0; i < ExceptionHandlers.Count; i++)
ExceptionHandlers[i] = readExceptionHandler();
}
protected abstract ExceptionHandler readExceptionHandler();
+
+ public virtual void restoreMethod(MethodDefinition method) {
+ var body = method.Body;
+
+ body.Variables.Clear();
+ if (Locals != null) {
+ foreach (var local in Locals)
+ body.Variables.Add(local);
+ }
+
+ body.Instructions.Clear();
+ if (Instructions != null) {
+ foreach (var instr in Instructions)
+ body.Instructions.Add(instr);
+ }
+
+ body.ExceptionHandlers.Clear();
+ if (ExceptionHandlers != null) {
+ foreach (var eh in ExceptionHandlers)
+ body.ExceptionHandlers.Add(eh);
+ }
+ }
}
}
diff --git a/de4dot.cui/Properties/AssemblyInfo.cs b/de4dot.cui/Properties/AssemblyInfo.cs
index f823ad03..f1fbc90a 100644
--- a/de4dot.cui/Properties/AssemblyInfo.cs
+++ b/de4dot.cui/Properties/AssemblyInfo.cs
@@ -30,7 +30,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
[assembly: InternalsVisibleTo("de4dot, PublicKey=00240000048000009400000006020000002400005253413100040000010001007b5ffd8f48f1397cd4e21c9e30a5cb36b2c013d6f20688c90e3f0c2d24e6d67cbeea7a6ec3faf9ba081f3d6b6fbe389677adbb8337d3a16187cd13b16a34008a22b89089da41c4a08fd35615c77de0827adcca6d49b08c0ed3e0404a1c44b7d083be614acb1779e4fb275e14427f3687f375d03f3b465c8a6cdeebd1f8c7f4ea")]
[assembly: InternalsVisibleTo("de4dot-x64, PublicKey=00240000048000009400000006020000002400005253413100040000010001007b5ffd8f48f1397cd4e21c9e30a5cb36b2c013d6f20688c90e3f0c2d24e6d67cbeea7a6ec3faf9ba081f3d6b6fbe389677adbb8337d3a16187cd13b16a34008a22b89089da41c4a08fd35615c77de0827adcca6d49b08c0ed3e0404a1c44b7d083be614acb1779e4fb275e14427f3687f375d03f3b465c8a6cdeebd1f8c7f4ea")]
diff --git a/de4dot.mdecrypt/Properties/AssemblyInfo.cs b/de4dot.mdecrypt/Properties/AssemblyInfo.cs
index 2ac21271..1b403a44 100644
--- a/de4dot.mdecrypt/Properties/AssemblyInfo.cs
+++ b/de4dot.mdecrypt/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]
diff --git a/de4dot/Properties/AssemblyInfo.cs b/de4dot/Properties/AssemblyInfo.cs
index 474bbe57..36dd1633 100644
--- a/de4dot/Properties/AssemblyInfo.cs
+++ b/de4dot/Properties/AssemblyInfo.cs
@@ -21,7 +21,7 @@ using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("de4dot")]
-[assembly: AssemblyDescription("Deobfuscates obfuscated .NET applications - AnyCpu")]
+[assembly: AssemblyDescription("Deobfuscates obfuscated .NET applications - x86")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("de4dot")]
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.9.0.3405")]
-[assembly: AssemblyFileVersion("1.9.0.3405")]
+[assembly: AssemblyVersion("1.9.1.3405")]
+[assembly: AssemblyFileVersion("1.9.1.3405")]