Port Confuser deobfuscator
This commit is contained in:
parent
ff86ca6d24
commit
6e7ac2a3bc
|
@ -452,6 +452,7 @@ namespace de4dot.blocks {
|
|||
methodCalls.addMethodCalls(method);
|
||||
return methodCalls;
|
||||
}
|
||||
#endif
|
||||
|
||||
public static bool hasString(MethodDef method, string s) {
|
||||
if (method == null || method.Body == null)
|
||||
|
@ -463,6 +464,7 @@ namespace de4dot.blocks {
|
|||
return false;
|
||||
}
|
||||
|
||||
#if PORT
|
||||
public static IList<string> getCodeStrings(MethodDef method) {
|
||||
var strings = new List<string>();
|
||||
if (method != null && method.Body != null) {
|
||||
|
|
|
@ -18,14 +18,14 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class AntiDebugger : IVersionProvider {
|
||||
ModuleDefinition module;
|
||||
MethodDefinition initMethod;
|
||||
ModuleDefMD module;
|
||||
MethodDef initMethod;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
|
||||
enum ConfuserVersion {
|
||||
|
@ -42,11 +42,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
v19_r76119_safe,
|
||||
}
|
||||
|
||||
public MethodDefinition InitMethod {
|
||||
public MethodDef InitMethod {
|
||||
get { return initMethod; }
|
||||
}
|
||||
|
||||
public TypeDefinition Type {
|
||||
public TypeDef Type {
|
||||
get { return initMethod != null ? initMethod.DeclaringType : null; }
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return initMethod != null; }
|
||||
}
|
||||
|
||||
public AntiDebugger(ModuleDefinition module) {
|
||||
public AntiDebugger(ModuleDefMD module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
|
@ -63,14 +63,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return;
|
||||
}
|
||||
|
||||
bool checkMethod(MethodDefinition method) {
|
||||
bool checkMethod(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
if (instr.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = instr.Operand as MethodDefinition;
|
||||
var calledMethod = instr.Operand as MethodDef;
|
||||
if (calledMethod == null || !calledMethod.IsStatic)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
|
||||
|
@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool checkProfilerStrings1(MethodDefinition method) {
|
||||
static bool checkProfilerStrings1(MethodDef method) {
|
||||
if (!DotNetUtils.hasString(method, "COR_ENABLE_PROFILING"))
|
||||
return false;
|
||||
if (!DotNetUtils.hasString(method, "COR_PROFILER"))
|
||||
|
@ -97,7 +97,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool checkProfilerStrings2(MethodDefinition method) {
|
||||
static bool checkProfilerStrings2(MethodDef method) {
|
||||
if (!DotNetUtils.hasString(method, "COR_"))
|
||||
return false;
|
||||
if (!DotNetUtils.hasString(method, "ENABLE_PROFILING"))
|
||||
|
@ -108,7 +108,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static MethodDefinition getAntiDebugMethod(TypeDefinition type, MethodDefinition initMethod) {
|
||||
static MethodDef getAntiDebugMethod(TypeDef type, MethodDef initMethod) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (method.Body == null || method == initMethod)
|
||||
continue;
|
||||
|
@ -124,7 +124,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
bool checkMethod_normal(TypeDefinition type, MethodDefinition initMethod) {
|
||||
bool checkMethod_normal(TypeDef type, MethodDef initMethod) {
|
||||
var ntQueryInformationProcess = DotNetUtils.getPInvokeMethod(type, "ntdll", "NtQueryInformationProcess");
|
||||
if (ntQueryInformationProcess == null)
|
||||
return false;
|
||||
|
@ -184,7 +184,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool checkMethod_safe(TypeDefinition type, MethodDefinition initMethod) {
|
||||
bool checkMethod_safe(TypeDef type, MethodDef initMethod) {
|
||||
if (type == DotNetUtils.getModuleType(module)) {
|
||||
if (!DotNetUtils.hasString(initMethod, "Debugger detected (Managed)"))
|
||||
return false;
|
||||
|
|
|
@ -18,14 +18,14 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class AntiDumping : IVersionProvider {
|
||||
ModuleDefinition module;
|
||||
MethodDefinition initMethod;
|
||||
ModuleDefMD module;
|
||||
MethodDef initMethod;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
|
||||
enum ConfuserVersion {
|
||||
|
@ -39,11 +39,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
v19_r76186,
|
||||
}
|
||||
|
||||
public MethodDefinition InitMethod {
|
||||
public MethodDef InitMethod {
|
||||
get { return initMethod; }
|
||||
}
|
||||
|
||||
public TypeDefinition Type {
|
||||
public TypeDef Type {
|
||||
get { return initMethod != null ? initMethod.DeclaringType : null; }
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return initMethod != null; }
|
||||
}
|
||||
|
||||
public AntiDumping(ModuleDefinition module) {
|
||||
public AntiDumping(ModuleDefMD module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
|
@ -60,14 +60,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return;
|
||||
}
|
||||
|
||||
bool checkMethod(ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition method) {
|
||||
bool checkMethod(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
if (instr.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = instr.Operand as MethodDefinition;
|
||||
var calledMethod = instr.Operand as MethodDef;
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
if (calledMethod == null || !calledMethod.IsStatic)
|
||||
|
@ -87,12 +87,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool checkType(TypeDefinition type, MethodDefinition initMethod) {
|
||||
bool checkType(TypeDef type, MethodDef initMethod) {
|
||||
return checkType_v14_r58564(type, initMethod) ||
|
||||
checkType_v14_r58852(type, initMethod);
|
||||
}
|
||||
|
||||
bool checkType_v14_r58564(TypeDefinition type, MethodDefinition initMethod) {
|
||||
bool checkType_v14_r58564(TypeDef type, MethodDef initMethod) {
|
||||
var virtualProtect = DotNetUtils.getPInvokeMethod(type, "VirtualProtect");
|
||||
if (virtualProtect == null)
|
||||
return false;
|
||||
|
@ -111,7 +111,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool checkType_v14_r58852(TypeDefinition type, MethodDefinition initMethod) {
|
||||
bool checkType_v14_r58852(TypeDef type, MethodDef initMethod) {
|
||||
var virtualProtect = DotNetUtils.getPInvokeMethod(type, "VirtualProtect");
|
||||
if (virtualProtect == null)
|
||||
return false;
|
||||
|
@ -156,40 +156,40 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool isRev75725(MethodDefinition method) {
|
||||
static bool isRev75725(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 9; i++) {
|
||||
if (!DotNetUtils.isLdcI4(instrs[i]) || DotNetUtils.getLdcI4Value(instrs[i]) != 8)
|
||||
if (!instrs[i].IsLdcI4() || instrs[i].GetLdcI4Value() != 8)
|
||||
continue;
|
||||
if (!DotNetUtils.isLdcI4(instrs[i + 1]) || DotNetUtils.getLdcI4Value(instrs[i + 1]) != 64)
|
||||
if (!instrs[i + 1].IsLdcI4() || instrs[i + 1].GetLdcI4Value() != 64)
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Ldloca && instrs[i + 2].OpCode.Code != Code.Ldloca_S)
|
||||
continue;
|
||||
var call = instrs[i + 3];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodDefinition;
|
||||
if (calledMethod == null || calledMethod.PInvokeInfo == null || calledMethod.PInvokeInfo.EntryPoint != "VirtualProtect")
|
||||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || calledMethod.ImplMap == null || calledMethod.ImplMap.Name != "VirtualProtect")
|
||||
continue;
|
||||
if (instrs[i + 4].OpCode.Code != Code.Pop)
|
||||
continue;
|
||||
|
||||
var ldloc = instrs[i + 5];
|
||||
if (!DotNetUtils.isLdloc(ldloc))
|
||||
if (!ldloc.IsLdloc())
|
||||
continue;
|
||||
var local = DotNetUtils.getLocalVar(method.Body.Variables, ldloc);
|
||||
var local = ldloc.GetLocal(method.Body.LocalList);
|
||||
if (local == null)
|
||||
continue;
|
||||
|
||||
if (!DotNetUtils.isLdcI4(instrs[i + 6]) || DotNetUtils.getLdcI4Value(instrs[i + 6]) != 0)
|
||||
if (!instrs[i + 6].IsLdcI4() || instrs[i + 6].GetLdcI4Value() != 0)
|
||||
continue;
|
||||
if (instrs[i + 7].OpCode.Code != Code.Stind_I4)
|
||||
continue;
|
||||
|
||||
ldloc = instrs[i + 8];
|
||||
if (!DotNetUtils.isLdloc(ldloc) || local != DotNetUtils.getLocalVar(method.Body.Variables, ldloc))
|
||||
if (!ldloc.IsLdloc() || local != ldloc.GetLocal(method.Body.LocalList))
|
||||
continue;
|
||||
if (!DotNetUtils.isLdcI4(instrs[i + 9]) || DotNetUtils.getLdcI4Value(instrs[i + 9]) != 4)
|
||||
if (!instrs[i + 9].IsLdcI4() || instrs[i + 9].GetLdcI4Value() != 4)
|
||||
continue;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet.Emit;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class Arg64ConstantsReader : ConstantsReader {
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.IO;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
|
@ -49,19 +49,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public static bool isCallMethod(Instruction instr, Code callCode, string methodFullName) {
|
||||
if (instr.OpCode.Code != callCode)
|
||||
return false;
|
||||
var calledMethod = instr.Operand as MethodReference;
|
||||
var calledMethod = instr.Operand as IMethod;
|
||||
return calledMethod != null && calledMethod.FullName == methodFullName;
|
||||
}
|
||||
|
||||
public static bool removeResourceHookCode(Blocks blocks, MethodDefinition handler) {
|
||||
public static bool removeResourceHookCode(Blocks blocks, MethodDef handler) {
|
||||
return removeResolveHandlerCode(blocks, handler, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)");
|
||||
}
|
||||
|
||||
public static bool removeAssemblyHookCode(Blocks blocks, MethodDefinition handler) {
|
||||
public static bool removeAssemblyHookCode(Blocks blocks, MethodDef handler) {
|
||||
return removeResolveHandlerCode(blocks, handler, "System.Void System.AppDomain::add_AssemblyResolve(System.ResolveEventHandler)");
|
||||
}
|
||||
|
||||
static bool removeResolveHandlerCode(Blocks blocks, MethodDefinition handler, string installHandlerMethod) {
|
||||
static bool removeResolveHandlerCode(Blocks blocks, MethodDef handler, string installHandlerMethod) {
|
||||
bool modified = false;
|
||||
foreach (var block in blocks.MethodBlocks.getAllBlocks()) {
|
||||
var instrs = block.Instructions;
|
||||
|
@ -69,7 +69,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var call = instrs[i];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodReference;
|
||||
var calledMethod = call.Operand as IMethod;
|
||||
if (calledMethod == null || calledMethod.FullName != "System.AppDomain System.AppDomain::get_CurrentDomain()")
|
||||
continue;
|
||||
|
||||
|
@ -85,14 +85,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var newobj = instrs[i + 3];
|
||||
if (newobj.OpCode.Code != Code.Newobj)
|
||||
continue;
|
||||
var ctor = newobj.Operand as MethodReference;
|
||||
var ctor = newobj.Operand as IMethod;
|
||||
if (ctor == null || ctor.FullName != "System.Void System.ResolveEventHandler::.ctor(System.Object,System.IntPtr)")
|
||||
continue;
|
||||
|
||||
var callvirt = instrs[i + 4];
|
||||
if (callvirt.OpCode.Code != Code.Callvirt)
|
||||
continue;
|
||||
calledMethod = callvirt.Operand as MethodReference;
|
||||
calledMethod = callvirt.Operand as IMethod;
|
||||
if (calledMethod == null || calledMethod.FullName != installHandlerMethod)
|
||||
continue;
|
||||
|
||||
|
@ -103,9 +103,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return modified;
|
||||
}
|
||||
|
||||
public static byte[] decryptCompressedInt32Data(Arg64ConstantsReader constReader, int exprStart, int exprEnd, BinaryReader reader, byte[] decrypted) {
|
||||
public static byte[] decryptCompressedInt32Data(Arg64ConstantsReader constReader, int exprStart, int exprEnd, IBinaryReader reader, byte[] decrypted) {
|
||||
for (int i = 0; i < decrypted.Length; i++) {
|
||||
constReader.Arg = Utils.readEncodedInt32(reader);
|
||||
constReader.Arg = reader.Read7BitEncodedInt32();
|
||||
int index = exprStart;
|
||||
long result;
|
||||
if (!constReader.getInt64(ref index, out result) || index != exprEnd)
|
||||
|
@ -133,21 +133,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return decrypted;
|
||||
}
|
||||
|
||||
public static int countCalls(MethodDefinition method, string methodFullName) {
|
||||
public static int countCalls(MethodDef method, string methodFullName) {
|
||||
if (method == null || method.Body == null)
|
||||
return 0;
|
||||
int count = 0;
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt && instr.OpCode.Code != Code.Newobj)
|
||||
continue;
|
||||
var calledMethod = instr.Operand as MethodReference;
|
||||
var calledMethod = instr.Operand as IMethod;
|
||||
if (calledMethod != null && calledMethod.FullName == methodFullName)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static int countCalls(MethodDefinition method, MethodDefinition calledMethod) {
|
||||
public static int countCalls(MethodDef method, MethodDef calledMethod) {
|
||||
if (method == null || method.Body == null)
|
||||
return 0;
|
||||
int count = 0;
|
||||
|
@ -160,7 +160,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return count;
|
||||
}
|
||||
|
||||
public static int countOpCode(MethodDefinition method, Code code) {
|
||||
public static int countOpCode(MethodDef method, Code code) {
|
||||
if (method == null || method.Body == null)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -19,26 +19,26 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.IO;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
using de4dot.PE;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
abstract class ConstantsDecrypterBase : IVersionProvider {
|
||||
protected ModuleDefinition module;
|
||||
protected ModuleDefMD module;
|
||||
protected byte[] fileData;
|
||||
protected ISimpleDeobfuscator simpleDeobfuscator;
|
||||
protected MethodDefinition nativeMethod;
|
||||
protected MethodDef nativeMethod;
|
||||
MethodDefinitionAndDeclaringTypeDict<DecrypterInfo> methodToDecrypterInfo = new MethodDefinitionAndDeclaringTypeDict<DecrypterInfo>();
|
||||
FieldDefinitionAndDeclaringTypeDict<bool> fields = new FieldDefinitionAndDeclaringTypeDict<bool>();
|
||||
protected EmbeddedResource resource;
|
||||
protected BinaryReader reader;
|
||||
protected IBinaryReader reader;
|
||||
|
||||
public class DecrypterInfo {
|
||||
public MethodDefinition decryptMethod;
|
||||
public MethodDef decryptMethod;
|
||||
public uint key0, key1, key2, key3;
|
||||
public byte doubleType, singleType, int32Type, int64Type, stringType;
|
||||
|
||||
|
@ -60,31 +60,31 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected static bool findKey0(MethodDefinition method, out uint key) {
|
||||
protected static bool findKey0(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
if (!DotNetUtils.isLdloc(instrs[i]))
|
||||
if (!instrs[i].IsLdloc())
|
||||
continue;
|
||||
if (instrs[i + 1].OpCode.Code != Code.Or)
|
||||
continue;
|
||||
var ldci4 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 3].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
if (instrs[i + 4].OpCode.Code != Code.Add)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 5]))
|
||||
if (!instrs[i + 5].IsStloc())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findKey1(MethodDefinition method, out uint key) {
|
||||
static bool findKey1(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.Reflection.MemberInfo::get_MetadataToken()");
|
||||
|
@ -92,35 +92,35 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
break;
|
||||
if (index + 2 > instrs.Count)
|
||||
break;
|
||||
if (!DotNetUtils.isStloc(instrs[index + 1]))
|
||||
if (!instrs[index + 1].IsStloc())
|
||||
continue;
|
||||
var ldci4 = instrs[index + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static bool findKey2Key3(MethodDefinition method, out uint key2, out uint key3) {
|
||||
protected static bool findKey2Key3(MethodDef method, out uint key2, out uint key3) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1))
|
||||
if (!ldci4_1.IsLdcI4())
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsStloc())
|
||||
continue;
|
||||
var ldci4_2 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2))
|
||||
if (!ldci4_2.IsLdcI4())
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsStloc())
|
||||
continue;
|
||||
|
||||
key2 = (uint)DotNetUtils.getLdcI4Value(ldci4_1);
|
||||
key3 = (uint)DotNetUtils.getLdcI4Value(ldci4_2);
|
||||
key2 = (uint)ldci4_1.GetLdcI4Value();
|
||||
key3 = (uint)ldci4_2.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key2 = 0;
|
||||
|
@ -186,12 +186,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
numCeq++;
|
||||
continue;
|
||||
}
|
||||
if (!DotNetUtils.isLdcI4(instr.Instruction))
|
||||
if (!instr.Instruction.IsLdcI4())
|
||||
continue;
|
||||
if (numCeq != 0 && numCeq != 2)
|
||||
continue;
|
||||
|
||||
typeCode = (byte)DotNetUtils.getLdcI4Value(instr.Instruction);
|
||||
typeCode = (byte)instr.Instruction.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
typeCode = 0;
|
||||
|
@ -232,7 +232,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
public abstract bool Detected { get; }
|
||||
|
||||
public MethodDefinition NativeMethod {
|
||||
public MethodDef NativeMethod {
|
||||
get { return nativeMethod; }
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return resource; }
|
||||
}
|
||||
|
||||
public IEnumerable<FieldDefinition> Fields {
|
||||
public IEnumerable<FieldDef> Fields {
|
||||
get { return fields.getKeys(); }
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return methodToDecrypterInfo.getValues(); }
|
||||
}
|
||||
|
||||
public ConstantsDecrypterBase(ModuleDefinition module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
public ConstantsDecrypterBase(ModuleDefMD module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
this.module = module;
|
||||
this.fileData = fileData;
|
||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
|
@ -265,7 +265,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
methodToDecrypterInfo.add(info.decryptMethod, info);
|
||||
}
|
||||
|
||||
protected bool add(FieldDefinition field) {
|
||||
protected bool add(FieldDef field) {
|
||||
if (field == null)
|
||||
return false;
|
||||
fields.add(field, true);
|
||||
|
@ -280,20 +280,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
protected void setConstantsData(byte[] constants) {
|
||||
reader = new BinaryReader(new MemoryStream(constants));
|
||||
reader = MemoryImageStream.Create(constants);
|
||||
}
|
||||
|
||||
protected EmbeddedResource findResource(MethodDefinition method) {
|
||||
protected EmbeddedResource findResource(MethodDef method) {
|
||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||
}
|
||||
|
||||
protected static MethodDefinition findNativeMethod(MethodDefinition method) {
|
||||
protected static MethodDef findNativeMethod(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
var call = instrs[i];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodDefinition;
|
||||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || !calledMethod.IsStatic || !calledMethod.IsNative)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.Int32", "(System.Int32)"))
|
||||
|
@ -304,50 +304,50 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static VariableDefinition getDynamicLocal_v17_r73740(MethodDefinition method) {
|
||||
static Local getDynamicLocal_v17_r73740(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Byte System.IO.BinaryReader::ReadByte()");
|
||||
if (i < 0 || i + 5 >= instrs.Count)
|
||||
break;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsStloc())
|
||||
continue;
|
||||
var ldloc = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdloc(ldloc))
|
||||
if (!ldloc.IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsLdloc())
|
||||
continue;
|
||||
var ldci4 = instrs[i + 4];
|
||||
if (!DotNetUtils.isLdcI4(ldci4) || DotNetUtils.getLdcI4Value(ldci4) != 0x7F)
|
||||
if (!ldci4.IsLdcI4() || ldci4.GetLdcI4Value() != 0x7F)
|
||||
continue;
|
||||
if (instrs[i + 5].OpCode.Code != Code.And)
|
||||
continue;
|
||||
|
||||
return DotNetUtils.getLocalVar(method.Body.Variables, ldloc);
|
||||
return ldloc.GetLocal(method.Body.LocalList);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static int getDynamicEndIndex_v17_r73740(MethodDefinition method, VariableDefinition local) {
|
||||
static int getDynamicEndIndex_v17_r73740(MethodDef method, Local local) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
int index = i;
|
||||
var stloc = instrs[index++];
|
||||
if (!DotNetUtils.isStloc(stloc) || DotNetUtils.getLocalVar(method.Body.Variables, stloc) != local)
|
||||
if (!stloc.IsStloc() || stloc.GetLocal(method.Body.LocalList) != local)
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[index++]))
|
||||
if (!instrs[index++].IsLdloc())
|
||||
continue;
|
||||
if (instrs[index].OpCode.Code == Code.Call) {
|
||||
if (i + 7 >= instrs.Count)
|
||||
continue;
|
||||
index++;
|
||||
if (!DotNetUtils.isLdloc(instrs[index++]))
|
||||
if (!instrs[index++].IsLdloc())
|
||||
continue;
|
||||
}
|
||||
if (!DotNetUtils.isLdloc(instrs[index++]))
|
||||
if (!instrs[index++].IsLdloc())
|
||||
continue;
|
||||
var ldloc = instrs[index++];
|
||||
if (!DotNetUtils.isLdloc(ldloc) || DotNetUtils.getLocalVar(method.Body.Variables, ldloc) != local)
|
||||
if (!ldloc.IsLdloc() || ldloc.GetLocal(method.Body.LocalList) != local)
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Conv_U1)
|
||||
continue;
|
||||
|
@ -359,24 +359,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int getDynamicEndIndex_v17_r74788(MethodDefinition method, VariableDefinition local) {
|
||||
static int getDynamicEndIndex_v17_r74788(MethodDef method, Local local) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 11; i++) {
|
||||
var stloc = instrs[i];
|
||||
if (!DotNetUtils.isStloc(stloc) || DotNetUtils.getLocalVar(method.Body.Variables, stloc) != local)
|
||||
if (!stloc.IsStloc() || stloc.GetLocal(method.Body.LocalList) != local)
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 2]))
|
||||
if (!instrs[i + 2].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 4]))
|
||||
if (!instrs[i + 4].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 5]))
|
||||
if (!instrs[i + 5].IsLdloc())
|
||||
continue;
|
||||
var ldci4 = instrs[i + 6];
|
||||
if (!DotNetUtils.isLdcI4(ldci4) || (DotNetUtils.getLdcI4Value(ldci4) != 8 && DotNetUtils.getLdcI4Value(ldci4) != 16))
|
||||
if (!ldci4.IsLdcI4() || (ldci4.GetLdcI4Value() != 8 && ldci4.GetLdcI4Value() != 16))
|
||||
continue;
|
||||
if (instrs[i + 7].OpCode.Code != Code.Rem)
|
||||
continue;
|
||||
|
@ -394,7 +394,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int getDynamicStartIndex_v17_r73740(MethodDefinition method, int endIndex) {
|
||||
static int getDynamicStartIndex_v17_r73740(MethodDef method, int endIndex) {
|
||||
if (endIndex < 0)
|
||||
return -1;
|
||||
var instrs = method.Body.Instructions;
|
||||
|
@ -446,17 +446,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
static byte[] decrypt(byte[] encrypted, uint key, Func<uint, int, byte> decryptFunc) {
|
||||
var reader = new BinaryReader(new MemoryStream(encrypted));
|
||||
var reader = MemoryImageStream.Create(encrypted);
|
||||
var decrypted = new byte[reader.ReadInt32() ^ key];
|
||||
for (int i = 0; i < decrypted.Length; i++) {
|
||||
uint magic = Utils.readEncodedUInt32(reader);
|
||||
uint magic = reader.Read7BitEncodedUInt32();
|
||||
decrypted[i] = decryptFunc(magic, i);
|
||||
}
|
||||
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
public object decryptInt32(MethodDefinition caller, MethodDefinition decryptMethod, object[] args) {
|
||||
public object decryptInt32(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
|
@ -467,7 +467,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return BitConverter.ToInt32(data, 0);
|
||||
}
|
||||
|
||||
public object decryptInt64(MethodDefinition caller, MethodDefinition decryptMethod, object[] args) {
|
||||
public object decryptInt64(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
|
@ -478,7 +478,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return BitConverter.ToInt64(data, 0);
|
||||
}
|
||||
|
||||
public object decryptSingle(MethodDefinition caller, MethodDefinition decryptMethod, object[] args) {
|
||||
public object decryptSingle(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
|
@ -489,7 +489,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return BitConverter.ToSingle(data, 0);
|
||||
}
|
||||
|
||||
public object decryptDouble(MethodDefinition caller, MethodDefinition decryptMethod, object[] args) {
|
||||
public object decryptDouble(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
|
@ -500,7 +500,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return BitConverter.ToDouble(data, 0);
|
||||
}
|
||||
|
||||
public string decryptString(MethodDefinition caller, MethodDefinition decryptMethod, object[] args) {
|
||||
public string decryptString(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
|
@ -509,6 +509,6 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return Encoding.UTF8.GetString(data);
|
||||
}
|
||||
|
||||
protected abstract byte[] decryptData(DecrypterInfo info, MethodDefinition caller, object[] args, out byte typeCode);
|
||||
protected abstract byte[] decryptData(DecrypterInfo info, MethodDef caller, object[] args, out byte typeCode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,25 +17,25 @@
|
|||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
static class ConstantsDecrypterUtils {
|
||||
public static FieldDefinition findDictField(MethodDefinition method, TypeDefinition declaringType) {
|
||||
public static FieldDef findDictField(MethodDef method, TypeDef declaringType) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var newobj = instrs[i];
|
||||
if (newobj.OpCode.Code != Code.Newobj)
|
||||
continue;
|
||||
var ctor = newobj.Operand as MethodReference;
|
||||
var ctor = newobj.Operand as IMethod;
|
||||
if (ctor == null || ctor.FullName != "System.Void System.Collections.Generic.Dictionary`2<System.UInt32,System.Object>::.ctor()")
|
||||
continue;
|
||||
|
||||
var stsfld = instrs[i + 1];
|
||||
if (stsfld.OpCode.Code != Code.Stsfld)
|
||||
continue;
|
||||
var field = stsfld.Operand as FieldDefinition;
|
||||
var field = stsfld.Operand as FieldDef;
|
||||
if (field == null || field.DeclaringType != declaringType)
|
||||
continue;
|
||||
if (field.FieldType.FullName != "System.Collections.Generic.Dictionary`2<System.UInt32,System.Object>")
|
||||
|
@ -46,20 +46,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static FieldDefinition findDataField(MethodDefinition method, TypeDefinition declaringType) {
|
||||
public static FieldDef findDataField(MethodDef method, TypeDef declaringType) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var callvirt = instrs[i];
|
||||
if (callvirt.OpCode.Code != Code.Callvirt)
|
||||
continue;
|
||||
var calledMethod = callvirt.Operand as MethodReference;
|
||||
var calledMethod = callvirt.Operand as IMethod;
|
||||
if (calledMethod == null || calledMethod.FullName != "System.Byte[] System.IO.MemoryStream::ToArray()")
|
||||
continue;
|
||||
|
||||
var stsfld = instrs[i + 1];
|
||||
if (stsfld.OpCode.Code != Code.Stsfld)
|
||||
continue;
|
||||
var field = stsfld.Operand as FieldDefinition;
|
||||
var field = stsfld.Operand as FieldDef;
|
||||
if (field == null || field.DeclaringType != declaringType)
|
||||
continue;
|
||||
if (field.FieldType.FullName != "System.Byte[]")
|
||||
|
@ -70,28 +70,28 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static FieldDefinition findStreamField(MethodDefinition method, TypeDefinition declaringType) {
|
||||
public static FieldDef findStreamField(MethodDef method, TypeDef declaringType) {
|
||||
return findStreamField(method, declaringType, "System.IO.Stream");
|
||||
}
|
||||
|
||||
public static FieldDefinition findMemoryStreamField(MethodDefinition method, TypeDefinition declaringType) {
|
||||
public static FieldDef findMemoryStreamField(MethodDef method, TypeDef declaringType) {
|
||||
return findStreamField(method, declaringType, "System.IO.MemoryStream");
|
||||
}
|
||||
|
||||
public static FieldDefinition findStreamField(MethodDefinition method, TypeDefinition declaringType, string fieldTypeName) {
|
||||
public static FieldDef findStreamField(MethodDef method, TypeDef declaringType, string fieldTypeName) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var newobj = instrs[i];
|
||||
if (newobj.OpCode.Code != Code.Newobj)
|
||||
continue;
|
||||
var ctor = newobj.Operand as MethodReference;
|
||||
var ctor = newobj.Operand as IMethod;
|
||||
if (ctor == null || ctor.FullName != "System.Void System.IO.MemoryStream::.ctor()")
|
||||
continue;
|
||||
|
||||
var stsfld = instrs[i + 1];
|
||||
if (stsfld.OpCode.Code != Code.Stsfld)
|
||||
continue;
|
||||
var field = stsfld.Operand as FieldDefinition;
|
||||
var field = stsfld.Operand as FieldDef;
|
||||
if (field == null || field.DeclaringType != declaringType)
|
||||
continue;
|
||||
if (field.FieldType.FullName != fieldTypeName)
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.IO;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
|
@ -51,7 +51,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return theDecrypterInfo != null; }
|
||||
}
|
||||
|
||||
public ConstantsDecrypterV15(ModuleDefinition module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
public ConstantsDecrypterV15(ModuleDefMD module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
: base(module, fileData, simpleDeobfuscator) {
|
||||
}
|
||||
|
||||
|
@ -164,9 +164,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected override byte[] decryptData(DecrypterInfo info, MethodDefinition caller, object[] args, out byte typeCode) {
|
||||
uint offs = info.calcHash(caller.MetadataToken.ToUInt32()) ^ (uint)args[0];
|
||||
reader.BaseStream.Position = offs;
|
||||
protected override byte[] decryptData(DecrypterInfo info, MethodDef caller, object[] args, out byte typeCode) {
|
||||
uint offs = info.calcHash(caller.MDToken.ToUInt32()) ^ (uint)args[0];
|
||||
reader.Position = offs;
|
||||
typeCode = reader.ReadByte();
|
||||
if (typeCode != info.int32Type && typeCode != info.int64Type &&
|
||||
typeCode != info.singleType && typeCode != info.doubleType &&
|
||||
|
@ -211,7 +211,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (endIndex < 0)
|
||||
throw new ApplicationException("Could not find start/endIndex");
|
||||
|
||||
var dataReader = new BinaryReader(new MemoryStream(encrypted));
|
||||
var dataReader = MemoryImageStream.Create(encrypted);
|
||||
var decrypted = new byte[dataReader.ReadInt32()];
|
||||
var constReader = new Arg64ConstantsReader(instrs, false);
|
||||
ConfuserUtils.decryptCompressedInt32Data(constReader, startIndex, endIndex, dataReader, decrypted);
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
// From v1.7 r74708 to v1.8 r75349
|
||||
class ConstantsDecrypterV17 : ConstantsDecrypterBase {
|
||||
MethodDefinition initMethod;
|
||||
MethodDef initMethod;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
string resourceName;
|
||||
int keyArraySize = 8;
|
||||
|
@ -57,7 +57,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public readonly ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
public uint key4, key5;
|
||||
|
||||
public DecrypterInfoV17(ConfuserVersion version, MethodDefinition decryptMethod) {
|
||||
public DecrypterInfoV17(ConfuserVersion version, MethodDef decryptMethod) {
|
||||
this.version = version;
|
||||
this.decryptMethod = decryptMethod;
|
||||
}
|
||||
|
@ -77,33 +77,33 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool findKey1_v17(MethodDefinition method, out uint key) {
|
||||
static bool findKey1_v17(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
var stloc = instrs[i];
|
||||
if (!DotNetUtils.isStloc(stloc))
|
||||
if (!stloc.IsStloc())
|
||||
continue;
|
||||
var ldci4 = instrs[i + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
var ldcloc = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdloc(ldcloc))
|
||||
if (!ldcloc.IsLdloc())
|
||||
continue;
|
||||
if (DotNetUtils.getLocalVar(method.Body.Variables, stloc) != DotNetUtils.getLocalVar(method.Body.Variables, ldcloc))
|
||||
if (stloc.GetLocal(method.Body.LocalList) != ldcloc.GetLocal(method.Body.LocalList))
|
||||
continue;
|
||||
if (instrs[i + 3].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 4]))
|
||||
if (!instrs[i + 4].IsStloc())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool findKey4(MethodDefinition method, out uint key) {
|
||||
bool findKey4(MethodDef method, out uint key) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r74708_normal:
|
||||
case ConfuserVersion.v17_r74788_normal:
|
||||
|
@ -127,31 +127,31 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
static bool findKey4_normal(MethodDefinition method, out uint key) {
|
||||
static bool findKey4_normal(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
if (!DotNetUtils.isLdloc(instrs[i]))
|
||||
if (!instrs[i].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsLdloc())
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Add)
|
||||
continue;
|
||||
var ldci4 = instrs[i + 3];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 4].OpCode.Code != Code.Mul)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 5]))
|
||||
if (!instrs[i + 5].IsStloc())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findKey4_other(MethodDefinition method, out uint key) {
|
||||
static bool findKey4_other(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()");
|
||||
|
@ -160,17 +160,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index + 1 >= instrs.Count)
|
||||
break;
|
||||
var ldci4 = instrs[index + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool findKey5(MethodDefinition method, out uint key) {
|
||||
bool findKey5(MethodDef method, out uint key) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r74788_normal:
|
||||
case ConfuserVersion.v17_r74788_dynamic:
|
||||
|
@ -191,7 +191,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
static bool findKey5_v17_r74788(MethodDefinition method, out uint key) {
|
||||
static bool findKey5_v17_r74788(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.Assembly::GetModule(System.String)");
|
||||
|
@ -200,10 +200,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (i + 1 >= instrs.Count)
|
||||
break;
|
||||
var ldci4 = instrs[i + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
|
@ -215,7 +215,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return initMethod != null; }
|
||||
}
|
||||
|
||||
public ConstantsDecrypterV17(ModuleDefinition module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
public ConstantsDecrypterV17(ModuleDefMD module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
: base(module, fileData, simpleDeobfuscator) {
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
initMethod = cctor;
|
||||
}
|
||||
|
||||
void initVersion(MethodDefinition method, ConfuserVersion normal, ConfuserVersion dynamic, ConfuserVersion native) {
|
||||
void initVersion(MethodDef method, ConfuserVersion normal, ConfuserVersion dynamic, ConfuserVersion native) {
|
||||
if (DeobUtils.hasInteger(method, 0x100) &&
|
||||
DeobUtils.hasInteger(method, 0x10000) &&
|
||||
DeobUtils.hasInteger(method, 0xFFFF))
|
||||
|
@ -275,7 +275,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
version = native;
|
||||
}
|
||||
|
||||
MethodDefinition getDecryptMethod() {
|
||||
MethodDef getDecryptMethod() {
|
||||
foreach (var type in module.Types) {
|
||||
if (type.Attributes != (TypeAttributes.Abstract | TypeAttributes.Sealed))
|
||||
continue;
|
||||
|
@ -291,10 +291,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected override byte[] decryptData(DecrypterInfo info2, MethodDefinition caller, object[] args, out byte typeCode) {
|
||||
protected override byte[] decryptData(DecrypterInfo info2, MethodDef caller, object[] args, out byte typeCode) {
|
||||
var info = (DecrypterInfoV17)info2;
|
||||
uint offs = info.calcHash(info2.decryptMethod.MetadataToken.ToUInt32() ^ (info2.decryptMethod.DeclaringType.MetadataToken.ToUInt32() * (uint)args[0])) ^ (uint)args[1];
|
||||
reader.BaseStream.Position = offs;
|
||||
uint offs = info.calcHash(info2.decryptMethod.MDToken.ToUInt32() ^ (info2.decryptMethod.DeclaringType.MDToken.ToUInt32() * (uint)args[0])) ^ (uint)args[1];
|
||||
reader.Position = offs;
|
||||
typeCode = reader.ReadByte();
|
||||
if (typeCode != info.int32Type && typeCode != info.int64Type &&
|
||||
typeCode != info.singleType && typeCode != info.doubleType &&
|
||||
|
@ -352,7 +352,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
byte[] getKey_v17_r74788(DecrypterInfoV17 info) {
|
||||
var key = module.GetSignatureBlob(info.decryptMethod.MetadataToken.ToUInt32() ^ info.key5);
|
||||
var key = module.ReadBlob(info.decryptMethod.MDToken.ToUInt32() ^ info.key5);
|
||||
if (key.Length != keyArraySize)
|
||||
throw new ApplicationException("Invalid key size");
|
||||
return key;
|
||||
|
@ -388,7 +388,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
static bool checkMethods(IEnumerable<MethodDefinition> methods) {
|
||||
static bool checkMethods(IEnumerable<MethodDef> methods) {
|
||||
int numMethods = 0;
|
||||
foreach (var method in methods) {
|
||||
if (method.Name == ".ctor" || method.Name == ".cctor")
|
||||
|
@ -403,7 +403,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return numMethods > 0;
|
||||
}
|
||||
|
||||
static string getResourceName(MethodDefinition method) {
|
||||
static string getResourceName(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Byte[] System.BitConverter::GetBytes(System.Int32)");
|
||||
|
@ -412,29 +412,29 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (i == 0)
|
||||
continue;
|
||||
var ldci4 = instrs[i - 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
return Encoding.UTF8.GetString(BitConverter.GetBytes(DotNetUtils.getLdcI4Value(ldci4)));
|
||||
return Encoding.UTF8.GetString(BitConverter.GetBytes(ldci4.GetLdcI4Value()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static int getKeyArraySize(MethodDefinition method) {
|
||||
static int getKeyArraySize(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (!DotNetUtils.isLdloc(instrs[i]))
|
||||
if (!instrs[i].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsLdloc())
|
||||
continue;
|
||||
var ldci4 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 3].OpCode.Code != Code.Rem)
|
||||
continue;
|
||||
if (instrs[i + 4].OpCode.Code != Code.Ldelem_U1)
|
||||
continue;
|
||||
|
||||
return DotNetUtils.getLdcI4Value(ldci4);
|
||||
return ldci4.GetLdcI4Value();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -21,23 +21,24 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Cecil.Metadata;
|
||||
using dot10.IO;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.MD;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
using de4dot.PE;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
// Since v1.8 r75367
|
||||
class ConstantsDecrypterV18 : IVersionProvider {
|
||||
ModuleDefinition module;
|
||||
ModuleDefMD module;
|
||||
byte[] fileData;
|
||||
ISimpleDeobfuscator simpleDeobfuscator;
|
||||
FieldDefinition dictField, dataField;
|
||||
MethodDefinition installMethod;
|
||||
FieldDef dictField, dataField;
|
||||
MethodDef installMethod;
|
||||
MethodDefinitionAndDeclaringTypeDict<DecrypterInfo> decrypters = new MethodDefinitionAndDeclaringTypeDict<DecrypterInfo>();
|
||||
uint key0, key0d;
|
||||
MethodDefinition nativeMethod;
|
||||
MethodDef nativeMethod;
|
||||
EmbeddedResource resource;
|
||||
byte[] constants;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
|
@ -54,12 +55,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
public class DecrypterInfo {
|
||||
readonly ConstantsDecrypterV18 constantsDecrypter;
|
||||
public readonly MethodDefinition method;
|
||||
public readonly MethodDef method;
|
||||
public ulong key0l, key1l, key2l;
|
||||
public uint key0, key0d;
|
||||
readonly ConfuserVersion version;
|
||||
|
||||
public DecrypterInfo(ConstantsDecrypterV18 constantsDecrypter, MethodDefinition method, ConfuserVersion version) {
|
||||
public DecrypterInfo(ConstantsDecrypterV18 constantsDecrypter, MethodDef method, ConfuserVersion version) {
|
||||
this.constantsDecrypter = constantsDecrypter;
|
||||
this.method = method;
|
||||
this.version = version;
|
||||
|
@ -86,11 +87,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
byte[] decrypt(uint magic1, ulong magic2) {
|
||||
ulong info = hash(method.DeclaringType.MetadataToken.ToUInt32() * magic1) ^ magic2;
|
||||
ulong info = hash(method.DeclaringType.MDToken.ToUInt32() * magic1) ^ magic2;
|
||||
int offset = (int)(info >> 32);
|
||||
int len = (int)info;
|
||||
var decrypted = new byte[len];
|
||||
byte[] key = BitConverter.GetBytes(method.MetadataToken.ToUInt32() ^ key0d);
|
||||
byte[] key = BitConverter.GetBytes(method.MDToken.ToUInt32() ^ key0d);
|
||||
for (int i = 0; i < len; i++)
|
||||
decrypted[i] = (byte)(constantsDecrypter.constants[offset + i] ^ key[(offset + i) & 3]);
|
||||
return decrypted;
|
||||
|
@ -129,25 +130,25 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
public IEnumerable<TypeDefinition> Types {
|
||||
public IEnumerable<TypeDef> Types {
|
||||
get {
|
||||
var types = new List<TypeDefinition>();
|
||||
var types = new List<TypeDef>();
|
||||
foreach (var info in decrypters.getValues())
|
||||
types.Add(info.method.DeclaringType);
|
||||
return types;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<FieldDefinition> Fields {
|
||||
public IEnumerable<FieldDef> Fields {
|
||||
get {
|
||||
return new List<FieldDefinition> {
|
||||
return new List<FieldDef> {
|
||||
dataField,
|
||||
dictField,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public MethodDefinition NativeMethod {
|
||||
public MethodDef NativeMethod {
|
||||
get { return nativeMethod; }
|
||||
}
|
||||
|
||||
|
@ -163,7 +164,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return installMethod != null; }
|
||||
}
|
||||
|
||||
public ConstantsDecrypterV18(ModuleDefinition module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
public ConstantsDecrypterV18(ModuleDefMD module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
this.module = module;
|
||||
this.fileData = fileData;
|
||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
|
@ -197,7 +198,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
installMethod = cctor;
|
||||
}
|
||||
|
||||
void initVersion(MethodDefinition installMethod, ConfuserVersion normal, ConfuserVersion dynamic, ConfuserVersion native) {
|
||||
void initVersion(MethodDef installMethod, ConfuserVersion normal, ConfuserVersion dynamic, ConfuserVersion native) {
|
||||
if (nativeMethod != null)
|
||||
version = native;
|
||||
else if (DeobUtils.hasInteger(installMethod, 0x10000))
|
||||
|
@ -234,7 +235,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool findKey0(MethodDefinition method, out uint key) {
|
||||
static bool findKey0(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Text.Encoding System.Text.Encoding::get_UTF8()");
|
||||
|
@ -244,10 +245,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index2 - index != 2)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -255,7 +256,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0d(MethodDefinition method, out uint key) {
|
||||
static bool findKey0d(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
|
@ -265,12 +266,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index2 - index != 3)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[index + 2]))
|
||||
if (!instrs[index + 2].IsLdloc())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -278,15 +279,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static MethodDefinition findNativeMethod(MethodDefinition method, TypeDefinition declaringType) {
|
||||
static MethodDef findNativeMethod(MethodDef method, TypeDef declaringType) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
if (!DotNetUtils.isLdloc(instrs[i]))
|
||||
if (!instrs[i].IsLdloc())
|
||||
continue;
|
||||
var call = instrs[i + 1];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodDefinition;
|
||||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || !calledMethod.IsStatic || !calledMethod.IsNative)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.Int32", "(System.Int32)"))
|
||||
|
@ -297,7 +298,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
MethodDefinition getDecryptMethod() {
|
||||
MethodDef getDecryptMethod() {
|
||||
foreach (var type in module.Types) {
|
||||
if (type.Attributes != (TypeAttributes.Abstract | TypeAttributes.Sealed))
|
||||
continue;
|
||||
|
@ -311,7 +312,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool checkMethods(IEnumerable<MethodDefinition> methods) {
|
||||
static bool checkMethods(IEnumerable<MethodDef> methods) {
|
||||
int numMethods = 0;
|
||||
foreach (var method in methods) {
|
||||
if (method.Name == ".ctor" || method.Name == ".cctor")
|
||||
|
@ -324,20 +325,23 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return numMethods > 0;
|
||||
}
|
||||
|
||||
static bool isDecryptMethodSignature(MethodDefinition method) {
|
||||
static bool isDecryptMethodSignature(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
if (method.Attributes != (MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.CompilerControlled))
|
||||
return false;
|
||||
if (method.Parameters.Count != 2)
|
||||
var sig = method.MethodSig;
|
||||
if (sig == null)
|
||||
return false;
|
||||
if (method.Parameters[0].ParameterType.EType != ElementType.U4)
|
||||
if (sig.Params.Count != 2)
|
||||
return false;
|
||||
if (method.Parameters[1].ParameterType.EType != ElementType.U8)
|
||||
if (sig.Params[0].GetElementType() != ElementType.U4)
|
||||
return false;
|
||||
if (!(method.MethodReturnType.ReturnType is GenericParameter))
|
||||
if (sig.Params[1].GetElementType() != ElementType.U8)
|
||||
return false;
|
||||
if (method.GenericParameters.Count != 1)
|
||||
if (!(sig.RetType.RemovePinnedAndModifiers() is GenericMVar))
|
||||
return false;
|
||||
if (sig.GenParamCount != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -356,7 +360,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
DecrypterInfo createDecrypterInfo(MethodDefinition method) {
|
||||
DecrypterInfo createDecrypterInfo(MethodDef method) {
|
||||
if (!isDecryptMethodSignature(method))
|
||||
return null;
|
||||
|
||||
|
@ -407,34 +411,34 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var instrs = info.method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 10; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1))
|
||||
if (!ldci4_1.IsLdcI4())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsLdloc())
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
if (instrs[i + 3].OpCode.Code != Code.Conv_U8)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 4]))
|
||||
if (!instrs[i + 4].IsStloc())
|
||||
continue;
|
||||
var ldci4_2 = instrs[i + 5];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2))
|
||||
if (!ldci4_2.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 6].OpCode.Code != Code.Conv_I8)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 7]))
|
||||
if (!instrs[i + 7].IsStloc())
|
||||
continue;
|
||||
var ldci4_3 = instrs[i + 8];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_3))
|
||||
if (!ldci4_3.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 9].OpCode.Code != Code.Conv_I8)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 10]))
|
||||
if (!instrs[i + 10].IsStloc())
|
||||
continue;
|
||||
|
||||
info.key0l = (uint)DotNetUtils.getLdcI4Value(ldci4_1);
|
||||
info.key1l = (uint)DotNetUtils.getLdcI4Value(ldci4_2);
|
||||
info.key2l = (uint)DotNetUtils.getLdcI4Value(ldci4_3);
|
||||
info.key0l = (uint)ldci4_1.GetLdcI4Value();
|
||||
info.key1l = (uint)ldci4_2.GetLdcI4Value();
|
||||
info.key2l = (uint)ldci4_3.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -446,7 +450,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (instrs[i].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
var ldci4 = instrs[i + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Conv_I8)
|
||||
continue;
|
||||
|
@ -455,7 +459,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (instrs[i + 4].OpCode.Code != Code.Add)
|
||||
continue;
|
||||
|
||||
info.key0 = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
info.key0 = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -473,12 +477,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index2 - index != 3)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index + 2].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
|
||||
info.key0d = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
info.key0d = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -490,23 +494,23 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var ldci8_1 = instrs[i];
|
||||
if (ldci8_1.OpCode.Code != Code.Ldc_I8)
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsLdloc())
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Conv_U8)
|
||||
continue;
|
||||
if (instrs[i + 3].OpCode.Code != Code.Mul)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 4]))
|
||||
if (!instrs[i + 4].IsStloc())
|
||||
continue;
|
||||
var ldci8_2 = instrs[i + 5];
|
||||
if (ldci8_2.OpCode.Code != Code.Ldc_I8)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 6]))
|
||||
if (!instrs[i + 6].IsStloc())
|
||||
continue;
|
||||
var ldci8_3 = instrs[i + 7];
|
||||
if (ldci8_3.OpCode.Code != Code.Ldc_I8)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 8]))
|
||||
if (!instrs[i + 8].IsStloc())
|
||||
continue;
|
||||
|
||||
info.key0l = (ulong)(long)ldci8_1.Operand;
|
||||
|
@ -520,19 +524,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
static bool findKey0_v18_r75369(DecrypterInfo info) {
|
||||
var instrs = info.method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (!DotNetUtils.isLdloc(instrs[i]))
|
||||
if (!instrs[i].IsLdloc())
|
||||
continue;
|
||||
if (instrs[i + 1].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
var ldci4 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 3].OpCode.Code != Code.Conv_U8)
|
||||
continue;
|
||||
if (instrs[i + 4].OpCode.Code != Code.Mul)
|
||||
continue;
|
||||
|
||||
info.key0 = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
info.key0 = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -558,10 +562,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
byte[] getSigKey() {
|
||||
uint sigToken = key0d ^ installMethod.MetadataToken.ToUInt32();
|
||||
if ((sigToken & 0xFF000000) != 0x11000000)
|
||||
throw new ApplicationException("Invalid sig token");
|
||||
return module.GetSignatureBlob(sigToken);
|
||||
return module.ReadBlob(key0d ^ installMethod.MDToken.ToUInt32());
|
||||
}
|
||||
|
||||
byte[] decryptResource_v18_r75367_normal(byte[] encrypted) {
|
||||
|
@ -578,19 +579,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int getDynamicEndIndex(int startIndex, VariableDefinition local) {
|
||||
int getDynamicEndIndex(int startIndex, Local local) {
|
||||
if (startIndex < 0)
|
||||
return -1;
|
||||
var instrs = installMethod.Body.Instructions;
|
||||
for (int i = startIndex; i < instrs.Count; i++) {
|
||||
var instr = instrs[i];
|
||||
if (DotNetUtils.isStloc(instr) && DotNetUtils.getLocalVar(installMethod.Body.Variables, instr) == local)
|
||||
if (instr.IsStloc() && instr.GetLocal(installMethod.Body.LocalList) == local)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
VariableDefinition getDynamicLocal(out int instrIndex) {
|
||||
Local getDynamicLocal(out int instrIndex) {
|
||||
var instrs = installMethod.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Void System.IO.BinaryWriter::Write(System.Byte)");
|
||||
|
@ -600,13 +601,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index < 0)
|
||||
continue;
|
||||
var ldloc = instrs[index];
|
||||
if (!DotNetUtils.isLdloc(ldloc))
|
||||
if (!ldloc.IsLdloc())
|
||||
continue;
|
||||
if (instrs[index + 1].OpCode.Code != Code.Conv_U1)
|
||||
continue;
|
||||
|
||||
instrIndex = index;
|
||||
return DotNetUtils.getLocalVar(installMethod.Body.Variables, ldloc);
|
||||
return ldloc.GetLocal(installMethod.Body.LocalList);
|
||||
}
|
||||
instrIndex = 0;
|
||||
return null;
|
||||
|
@ -648,52 +649,55 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var decrypted = DeobUtils.aesDecrypt(encrypted, key, DeobUtils.md5Sum(key));
|
||||
decrypted = DeobUtils.inflate(decrypted, true);
|
||||
|
||||
var reader = new BinaryReader(new MemoryStream(decrypted));
|
||||
var reader = MemoryImageStream.Create(decrypted);
|
||||
var result = new MemoryStream();
|
||||
var writer = new BinaryWriter(result);
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length) {
|
||||
uint magic = Utils.readEncodedUInt32(reader);
|
||||
while (reader.Position < reader.Length) {
|
||||
uint magic = reader.Read7BitEncodedUInt32();
|
||||
writer.Write(decryptFunc(magic));
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
static bool verifyGenericArg(GenericInstanceMethod gim, ElementType etype) {
|
||||
if (gim == null || gim.GenericArguments.Count != 1)
|
||||
static bool verifyGenericArg(MethodSpec gim, ElementType etype) {
|
||||
if (gim == null)
|
||||
return false;
|
||||
return gim.GenericArguments[0].EType == etype;
|
||||
var gims = gim.GenericInstMethodSig;
|
||||
if (gims == null || gims.GenericArguments.Count != 1)
|
||||
return false;
|
||||
return gims.GenericArguments[0].GetElementType() == etype;
|
||||
}
|
||||
|
||||
public string decryptString(MethodDefinition method, GenericInstanceMethod gim, uint magic1, ulong magic2) {
|
||||
public string decryptString(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.String))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptString(magic1, magic2);
|
||||
}
|
||||
|
||||
public object decryptInt32(MethodDefinition method, GenericInstanceMethod gim, uint magic1, ulong magic2) {
|
||||
public object decryptInt32(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.I4))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptInt32(magic1, magic2);
|
||||
}
|
||||
|
||||
public object decryptInt64(MethodDefinition method, GenericInstanceMethod gim, uint magic1, ulong magic2) {
|
||||
public object decryptInt64(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.I8))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptInt64(magic1, magic2);
|
||||
}
|
||||
|
||||
public object decryptSingle(MethodDefinition method, GenericInstanceMethod gim, uint magic1, ulong magic2) {
|
||||
public object decryptSingle(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.R4))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptSingle(magic1, magic2);
|
||||
}
|
||||
|
||||
public object decryptDouble(MethodDefinition method, GenericInstanceMethod gim, uint magic1, ulong magic2) {
|
||||
public object decryptDouble(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.R8))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
using de4dot.blocks.cflow;
|
||||
|
||||
|
@ -38,7 +38,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
int val;
|
||||
if (!constantsReader.getInt32(ref index, out val))
|
||||
continue;
|
||||
newInstr = DotNetUtils.createLdci4(val);
|
||||
newInstr = Instruction.CreateLdcI4(val);
|
||||
}
|
||||
else if (constantsReader.isLoadConstantInt64(instr.Instruction)) {
|
||||
index = i;
|
||||
|
@ -73,22 +73,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
ulong valu64 = instr.OpCode.Code == Code.Ldc_R4 ? (ulong)(float)instr.Operand : (ulong)(double)instr.Operand;
|
||||
switch (conv.OpCode.Code) {
|
||||
case Code.Conv_I1:
|
||||
newInstr = DotNetUtils.createLdci4(instr.OpCode.Code == Code.Ldc_R4 ? (sbyte)(float)instr.Operand : (sbyte)(double)instr.Operand);
|
||||
newInstr = Instruction.CreateLdcI4(instr.OpCode.Code == Code.Ldc_R4 ? (sbyte)(float)instr.Operand : (sbyte)(double)instr.Operand);
|
||||
break;
|
||||
case Code.Conv_U1:
|
||||
newInstr = DotNetUtils.createLdci4(instr.OpCode.Code == Code.Ldc_R4 ? (byte)(float)instr.Operand : (byte)(double)instr.Operand);
|
||||
newInstr = Instruction.CreateLdcI4(instr.OpCode.Code == Code.Ldc_R4 ? (byte)(float)instr.Operand : (byte)(double)instr.Operand);
|
||||
break;
|
||||
case Code.Conv_I2:
|
||||
newInstr = DotNetUtils.createLdci4(instr.OpCode.Code == Code.Ldc_R4 ? (short)(float)instr.Operand : (short)(double)instr.Operand);
|
||||
newInstr = Instruction.CreateLdcI4(instr.OpCode.Code == Code.Ldc_R4 ? (short)(float)instr.Operand : (short)(double)instr.Operand);
|
||||
break;
|
||||
case Code.Conv_U2:
|
||||
newInstr = DotNetUtils.createLdci4(instr.OpCode.Code == Code.Ldc_R4 ? (ushort)(float)instr.Operand : (ushort)(double)instr.Operand);
|
||||
newInstr = Instruction.CreateLdcI4(instr.OpCode.Code == Code.Ldc_R4 ? (ushort)(float)instr.Operand : (ushort)(double)instr.Operand);
|
||||
break;
|
||||
case Code.Conv_I4:
|
||||
newInstr = DotNetUtils.createLdci4(instr.OpCode.Code == Code.Ldc_R4 ? (int)(float)instr.Operand : (int)(double)instr.Operand);
|
||||
newInstr = Instruction.CreateLdcI4(instr.OpCode.Code == Code.Ldc_R4 ? (int)(float)instr.Operand : (int)(double)instr.Operand);
|
||||
break;
|
||||
case Code.Conv_U4:
|
||||
newInstr = DotNetUtils.createLdci4(instr.OpCode.Code == Code.Ldc_R4 ? (int)(uint)(float)instr.Operand : (int)(uint)(double)instr.Operand);
|
||||
newInstr = Instruction.CreateLdcI4(instr.OpCode.Code == Code.Ldc_R4 ? (int)(uint)(float)instr.Operand : (int)(uint)(double)instr.Operand);
|
||||
break;
|
||||
case Code.Conv_I8:
|
||||
newInstr = Instruction.Create(OpCodes.Ldc_I8, instr.OpCode.Code == Code.Ldc_R4 ? (long)(float)instr.Operand : (long)(double)instr.Operand);
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
using Mono.MyStuff;
|
||||
using dot10.DotNet;
|
||||
using dot10.IO;
|
||||
using de4dot.blocks;
|
||||
using de4dot.blocks.cflow;
|
||||
using de4dot.PE;
|
||||
|
@ -66,7 +66,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
class Deobfuscator : DeobfuscatorBase {
|
||||
class Deobfuscator : DeobfuscatorBase, IStringDecrypter {
|
||||
Options options;
|
||||
string obfuscatorName = DeobfuscatorInfo.THE_NAME;
|
||||
Version approxVersion;
|
||||
|
@ -240,9 +240,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
int minRev, maxRev;
|
||||
if (versionProvider.getRevisionRange(out minRev, out maxRev)) {
|
||||
if (maxRev == int.MaxValue)
|
||||
Log.v("r{0}-latest : {1}", minRev, versionProvider.GetType().Name);
|
||||
Logger.v("r{0}-latest : {1}", minRev, versionProvider.GetType().Name);
|
||||
else
|
||||
Log.v("r{0}-r{1} : {2}", minRev, maxRev, versionProvider.GetType().Name);
|
||||
Logger.v("r{0}-r{1} : {2}", minRev, maxRev, versionProvider.GetType().Name);
|
||||
vd.addRevs(minRev, maxRev);
|
||||
}
|
||||
}
|
||||
|
@ -317,16 +317,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
public override IDeobfuscator moduleReloaded(ModuleDefinition module) {
|
||||
public override IDeobfuscator moduleReloaded(ModuleDefMD module) {
|
||||
if (module.Assembly != null)
|
||||
realAssemblyInfo = null;
|
||||
if (realAssemblyInfo != null) {
|
||||
module.Assembly = realAssemblyInfo.realAssembly;
|
||||
module.Assembly.MainModule = module;
|
||||
realAssemblyInfo.realAssembly.Modules.Insert(0, module);
|
||||
if (realAssemblyInfo.entryPointToken != 0)
|
||||
module.EntryPoint = (MethodDefinition)module.LookupToken((int)realAssemblyInfo.entryPointToken);
|
||||
module.EntryPoint = module.ResolveToken((int)realAssemblyInfo.entryPointToken) as MethodDef;
|
||||
module.Kind = realAssemblyInfo.kind;
|
||||
module.Name = realAssemblyInfo.moduleName;
|
||||
module.Name = new UTF8String(realAssemblyInfo.moduleName);
|
||||
}
|
||||
|
||||
var newOne = new Deobfuscator(options);
|
||||
|
@ -363,7 +362,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public override void deobfuscateBegin() {
|
||||
base.deobfuscateBegin();
|
||||
|
||||
Log.v("Detected {0}", obfuscatorName);
|
||||
Logger.v("Detected {0}", obfuscatorName);
|
||||
|
||||
initializeConstantsDecrypterV18();
|
||||
initializeConstantsDecrypterV17();
|
||||
|
@ -396,7 +395,6 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
proxyCallFixer.find();
|
||||
|
||||
removeInvalidResources();
|
||||
removeInvalidAssemblyReferences();
|
||||
dumpEmbeddedAssemblies();
|
||||
|
||||
startedDeobfuscating = true;
|
||||
|
@ -405,12 +403,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
void dumpEmbeddedAssemblies() {
|
||||
if (mainAsmInfo != null) {
|
||||
var asm = module.Assembly;
|
||||
var name = asm == null ? module.Name : asm.Name.Name;
|
||||
var name = (asm == null ? module.Name : asm.Name).String;
|
||||
DeobfuscatedFile.createAssemblyFile(mainAsmInfo.data, name + "_real", mainAsmInfo.extension);
|
||||
addResourceToBeRemoved(mainAsmInfo.resource, string.Format("Embedded assembly: {0}", mainAsmInfo.asmFullName));
|
||||
}
|
||||
foreach (var info in embeddedAssemblyInfos) {
|
||||
if (module.Assembly == null || info.asmFullName != module.Assembly.Name.FullName)
|
||||
if (module.Assembly == null || info.asmFullName != module.Assembly.FullName)
|
||||
DeobfuscatedFile.createAssemblyFile(info.data, info.asmSimpleName, info.extension);
|
||||
addResourceToBeRemoved(info.resource, string.Format("Embedded assembly: {0}", info.asmFullName));
|
||||
}
|
||||
|
@ -428,28 +426,6 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
void removeInvalidAssemblyReferences() {
|
||||
// Confuser 1.7 r73764 adds an invalid assembly reference:
|
||||
// version: 0.0.0.0
|
||||
// attrs: SideBySideCompatible
|
||||
// key: 0 (cecil sets pkt to zero length array)
|
||||
// name: 0xFFFF
|
||||
// culture: 0
|
||||
// hash: 0xFFFF
|
||||
foreach (var asmRef in module.AssemblyReferences) {
|
||||
if (asmRef.Attributes != AssemblyAttributes.SideBySideCompatible)
|
||||
continue;
|
||||
if (asmRef.Version != null && asmRef.Version != new Version(0, 0, 0, 0))
|
||||
continue;
|
||||
if (asmRef.PublicKeyToken == null || asmRef.PublicKeyToken.Length != 0)
|
||||
continue;
|
||||
if (asmRef.Culture.Length != 0)
|
||||
continue;
|
||||
|
||||
addAssemblyReferenceToBeRemoved(asmRef, "Invalid assembly reference");
|
||||
}
|
||||
}
|
||||
|
||||
bool hasInitializedStringDecrypter = false;
|
||||
void initializeStringDecrypter() {
|
||||
if (hasInitializedStringDecrypter || (stringDecrypter== null || !stringDecrypter.Detected))
|
||||
|
@ -552,7 +528,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
void setConfuserVersion(TypeDefinition type) {
|
||||
void setConfuserVersion(TypeDef type) {
|
||||
var s = DotNetUtils.getCustomArgAsString(getModuleAttribute(type) ?? getAssemblyAttribute(type), 0);
|
||||
if (s == null)
|
||||
return;
|
||||
|
@ -595,7 +571,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
module.Attributes |= ModuleAttributes.ILOnly;
|
||||
module.IsILOnly = true;
|
||||
|
||||
base.deobfuscateEnd();
|
||||
}
|
||||
|
@ -603,20 +579,26 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||
var list = new List<int>();
|
||||
if (stringDecrypter != null && stringDecrypter.Method != null)
|
||||
list.Add(stringDecrypter.Method.MetadataToken.ToInt32());
|
||||
list.Add(stringDecrypter.Method.MDToken.ToInt32());
|
||||
if (constantsDecrypterV15 != null) {
|
||||
foreach (var info in constantsDecrypterV15.DecrypterInfos)
|
||||
list.Add(info.decryptMethod.MetadataToken.ToInt32());
|
||||
list.Add(info.decryptMethod.MDToken.ToInt32());
|
||||
}
|
||||
if (constantsDecrypterV17 != null) {
|
||||
foreach (var info in constantsDecrypterV17.DecrypterInfos)
|
||||
list.Add(info.decryptMethod.MetadataToken.ToInt32());
|
||||
list.Add(info.decryptMethod.MDToken.ToInt32());
|
||||
}
|
||||
if (constantsDecrypterV18 != null) {
|
||||
foreach (var info in constantsDecrypterV18.Decrypters)
|
||||
list.Add(info.method.MetadataToken.ToInt32());
|
||||
list.Add(info.method.MDToken.ToInt32());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
string IStringDecrypter.ReadUserString(uint token) {
|
||||
if (jitMethodsDecrypter == null)
|
||||
return null;
|
||||
return ((IStringDecrypter)jitMethodsDecrypter).ReadUserString(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,17 +21,16 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Cecil.Metadata;
|
||||
using Mono.MyStuff;
|
||||
using dot10.IO;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
using de4dot.PE;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class JitMethodsDecrypter : MethodsDecrypterBase, IStringDecrypter {
|
||||
MethodDefinition compileMethod;
|
||||
MethodDefinition hookConstructStr;
|
||||
MethodDef compileMethod;
|
||||
MethodDef hookConstructStr;
|
||||
MethodDataIndexes methodDataIndexes;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
|
||||
|
@ -57,17 +56,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public int options;
|
||||
}
|
||||
|
||||
public JitMethodsDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
public JitMethodsDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
: base(module, simpleDeobfuscator) {
|
||||
}
|
||||
|
||||
public JitMethodsDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, JitMethodsDecrypter other)
|
||||
public JitMethodsDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, JitMethodsDecrypter other)
|
||||
: base(module, simpleDeobfuscator, other) {
|
||||
if (other != null)
|
||||
this.version = other.version;
|
||||
}
|
||||
|
||||
protected override bool checkType(TypeDefinition type, MethodDefinition initMethod) {
|
||||
protected override bool checkType(TypeDef type, MethodDef initMethod) {
|
||||
if (type == null)
|
||||
return false;
|
||||
|
||||
|
@ -132,32 +131,33 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static int countInt32s(MethodDefinition method, int val) {
|
||||
static int countInt32s(MethodDef method, int val) {
|
||||
int count = 0;
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
if (!DotNetUtils.isLdcI4(instr))
|
||||
if (!instr.IsLdcI4())
|
||||
continue;
|
||||
if (DotNetUtils.getLdcI4Value(instr) == val)
|
||||
if (instr.GetLdcI4Value() == val)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static MethodDefinition findCompileMethod(TypeDefinition type) {
|
||||
static MethodDef findCompileMethod(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
if (method.Parameters.Count != 6)
|
||||
var sig = method.MethodSig;
|
||||
if (sig == null || sig.Params.Count != 6)
|
||||
continue;
|
||||
if (method.MethodReturnType.ReturnType.EType != ElementType.U4)
|
||||
if (sig.RetType.GetElementType() != ElementType.U4)
|
||||
continue;
|
||||
if (method.Parameters[0].ParameterType.EType != ElementType.I)
|
||||
if (sig.Params[0].GetElementType() != ElementType.I)
|
||||
continue;
|
||||
if (method.Parameters[3].ParameterType.EType != ElementType.U4)
|
||||
if (sig.Params[3].GetElementType() != ElementType.U4)
|
||||
continue;
|
||||
if (method.Parameters[4].ParameterType.FullName != "System.Byte**")
|
||||
if (sig.Params[4].GetFullName() != "System.Byte**")
|
||||
continue;
|
||||
if (method.Parameters[5].ParameterType.FullName != "System.UInt32*")
|
||||
if (sig.Params[5].GetFullName() != "System.UInt32*")
|
||||
continue;
|
||||
|
||||
return method;
|
||||
|
@ -165,22 +165,23 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static MethodDefinition findHookConstructStr(TypeDefinition type) {
|
||||
static MethodDef findHookConstructStr(TypeDef type) {
|
||||
foreach (var nested in type.NestedTypes) {
|
||||
if (nested.Fields.Count != 8 && nested.Fields.Count != 10)
|
||||
continue;
|
||||
foreach (var method in nested.Methods) {
|
||||
if (method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
if (method.Parameters.Count != 4)
|
||||
var sig = method.MethodSig;
|
||||
if (sig == null || sig.Params.Count != 4)
|
||||
continue;
|
||||
if (method.Parameters[0].ParameterType.EType != ElementType.I)
|
||||
if (sig.Params[0].GetElementType() != ElementType.I)
|
||||
continue;
|
||||
if (method.Parameters[1].ParameterType.EType != ElementType.I)
|
||||
if (sig.Params[1].GetElementType() != ElementType.I)
|
||||
continue;
|
||||
if (method.Parameters[2].ParameterType.EType != ElementType.U4)
|
||||
if (sig.Params[2].GetElementType() != ElementType.U4)
|
||||
continue;
|
||||
if (method.Parameters[3].ParameterType.EType != ElementType.I && method.Parameters[3].ParameterType.FullName != "System.IntPtr&")
|
||||
if (sig.Params[3].GetElementType() != ElementType.I && sig.Params[3].GetFullName() != "System.IntPtr&")
|
||||
continue;
|
||||
|
||||
return method;
|
||||
|
@ -258,7 +259,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool findKey4(MethodDefinition method, out uint key) {
|
||||
static bool findKey4(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = ConfuserUtils.findCallMethod(instrs, index, Code.Call, "System.Void System.Runtime.InteropServices.Marshal::Copy(System.Byte[],System.Int32,System.IntPtr,System.Int32)");
|
||||
|
@ -266,13 +267,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
break;
|
||||
if (index + 2 >= instrs.Count)
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[index + 1]))
|
||||
if (!instrs[index + 1].IsLdloc())
|
||||
continue;
|
||||
var ldci4 = instrs[index + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -280,24 +281,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey5(MethodDefinition method, out uint key) {
|
||||
static bool findKey5(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i + 4 < instrs.Count; i++) {
|
||||
int index = i;
|
||||
var ldci4_8 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_8) || DotNetUtils.getLdcI4Value(ldci4_8) != 8)
|
||||
if (!ldci4_8.IsLdcI4() || ldci4_8.GetLdcI4Value() != 8)
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Shl)
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Or)
|
||||
continue;
|
||||
var ldci4 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -305,7 +306,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool initializeMethodDataIndexes(MethodDefinition compileMethod) {
|
||||
bool initializeMethodDataIndexes(MethodDef compileMethod) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r73404: return true;
|
||||
case ConfuserVersion.v17_r73430: return true;
|
||||
|
@ -321,7 +322,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
bool initializeMethodDataIndexes_v17_r73477(MethodDefinition method) {
|
||||
bool initializeMethodDataIndexes_v17_r73477(MethodDef method) {
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
var methodDataType = findFirstThreeIndexes(method, out methodDataIndexes.maxStack, out methodDataIndexes.ehs, out methodDataIndexes.options);
|
||||
if (methodDataType == null)
|
||||
|
@ -336,7 +337,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static TypeDefinition findFirstThreeIndexes(MethodDefinition method, out int maxStackIndex, out int ehsIndex, out int optionsIndex) {
|
||||
static TypeDef findFirstThreeIndexes(MethodDef method, out int maxStackIndex, out int ehsIndex, out int optionsIndex) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index1 = findLdfldStind(instrs, i, false, true);
|
||||
|
@ -352,9 +353,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index3 < 0)
|
||||
continue;
|
||||
|
||||
var field1 = instrs[index1].Operand as FieldDefinition;
|
||||
var field2 = instrs[index2].Operand as FieldDefinition;
|
||||
var field3 = instrs[index3].Operand as FieldDefinition;
|
||||
var field1 = instrs[index1].Operand as FieldDef;
|
||||
var field2 = instrs[index2].Operand as FieldDef;
|
||||
var field3 = instrs[index3].Operand as FieldDef;
|
||||
if (field1 == null || field2 == null || field3 == null)
|
||||
continue;
|
||||
if (field1.DeclaringType != field2.DeclaringType || field1.DeclaringType != field3.DeclaringType)
|
||||
|
@ -372,20 +373,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool findLocalVarSigTokIndex(MethodDefinition method, TypeDefinition methodDataType, out int localVarSigTokIndex) {
|
||||
static bool findLocalVarSigTokIndex(MethodDef method, TypeDef methodDataType, out int localVarSigTokIndex) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var ldfld = instrs[i];
|
||||
if (ldfld.OpCode.Code != Code.Ldfld)
|
||||
continue;
|
||||
var field = ldfld.Operand as FieldDefinition;
|
||||
var field = ldfld.Operand as FieldDef;
|
||||
if (field == null || field.DeclaringType != methodDataType)
|
||||
continue;
|
||||
|
||||
var call = instrs[i + 1];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodDefinition;
|
||||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.DeclaringType != method.DeclaringType)
|
||||
continue;
|
||||
|
||||
|
@ -397,13 +398,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findCodeSizeIndex(MethodDefinition method, TypeDefinition methodDataType, out int codeSizeIndex) {
|
||||
static bool findCodeSizeIndex(MethodDef method, TypeDef methodDataType, out int codeSizeIndex) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var ldfld = instrs[i];
|
||||
if (ldfld.OpCode.Code != Code.Ldfld)
|
||||
continue;
|
||||
var field = ldfld.Operand as FieldDefinition;
|
||||
var field = ldfld.Operand as FieldDef;
|
||||
if (field == null || field.DeclaringType != methodDataType)
|
||||
continue;
|
||||
|
||||
|
@ -418,7 +419,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static int getInstanceFieldIndex(FieldDefinition field) {
|
||||
static int getInstanceFieldIndex(FieldDef field) {
|
||||
int i = 0;
|
||||
foreach (var f in field.DeclaringType.Fields) {
|
||||
if (f.IsStatic)
|
||||
|
@ -616,7 +617,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
DumpedMethods decrypt(PeImage peImage, byte[] fileData, DecryptMethodData decrypter) {
|
||||
var dumpedMethods = new DumpedMethods { StringDecrypter = this };
|
||||
var dumpedMethods = new DumpedMethods();
|
||||
|
||||
var metadataTables = peImage.Cor20Header.createMetadataTables();
|
||||
var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef);
|
||||
|
@ -724,11 +725,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return data;
|
||||
}
|
||||
|
||||
string IStringDecrypter.decrypt(uint token) {
|
||||
string IStringDecrypter.ReadUserString(uint token) {
|
||||
if ((token & 0xFF800000) != 0x70800000)
|
||||
return null;
|
||||
var reader = new BinaryReader(new MemoryStream(methodsData));
|
||||
reader.BaseStream.Position = (token & ~0xFF800000) + 2;
|
||||
using (var reader = MemoryImageStream.Create(methodsData)) {
|
||||
reader.Position = (token & ~0xFF800000) + 2;
|
||||
int len = reader.ReadInt32();
|
||||
if ((len & 1) != 1)
|
||||
throw new ApplicationException("Invalid string len");
|
||||
|
@ -738,6 +739,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
sb.Append((char)(reader.ReadUInt16() ^ key5));
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
|
|
|
@ -19,9 +19,8 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.MyStuff;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
using de4dot.PE;
|
||||
|
||||
|
@ -44,17 +43,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
v19_r75725,
|
||||
}
|
||||
|
||||
public MemoryMethodsDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
public MemoryMethodsDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
: base(module, simpleDeobfuscator) {
|
||||
}
|
||||
|
||||
public MemoryMethodsDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, MemoryMethodsDecrypter other)
|
||||
public MemoryMethodsDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, MemoryMethodsDecrypter other)
|
||||
: base(module, simpleDeobfuscator, other) {
|
||||
if (other != null)
|
||||
this.version = other.version;
|
||||
}
|
||||
|
||||
protected override bool checkType(TypeDefinition type, MethodDefinition initMethod) {
|
||||
protected override bool checkType(TypeDef type, MethodDef initMethod) {
|
||||
if (type == null)
|
||||
return false;
|
||||
if (type.Methods.Count != 3)
|
||||
|
@ -195,7 +194,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool findKey4(MethodDefinition method, out uint key) {
|
||||
static bool findKey4(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = findCallvirtReadUInt32(instrs, i);
|
||||
|
@ -209,20 +208,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
break;
|
||||
|
||||
var ldci4 = instrs[i + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
var stloc = instrs[i + 3];
|
||||
if (!DotNetUtils.isStloc(stloc))
|
||||
if (!stloc.IsStloc())
|
||||
continue;
|
||||
var ldloc = instrs[i + 4];
|
||||
if (!DotNetUtils.isLdloc(ldloc))
|
||||
if (!ldloc.IsLdloc())
|
||||
continue;
|
||||
if (DotNetUtils.getLocalVar(method.Body.Variables, ldloc) != DotNetUtils.getLocalVar(method.Body.Variables, stloc))
|
||||
if (ldloc.GetLocal(method.Body.LocalList) != stloc.GetLocal(method.Body.LocalList))
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -230,7 +229,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey5(MethodDefinition method, out uint key) {
|
||||
static bool findKey5(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = findCallvirtReadUInt32(instrs, i);
|
||||
|
@ -243,22 +242,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
|
||||
var ldci4 = instrs[i + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
var stloc = instrs[i + 3];
|
||||
if (!DotNetUtils.isStloc(stloc))
|
||||
if (!stloc.IsStloc())
|
||||
continue;
|
||||
var ldloc = instrs[i + 4];
|
||||
if (!DotNetUtils.isLdloc(ldloc))
|
||||
if (!ldloc.IsLdloc())
|
||||
continue;
|
||||
if (DotNetUtils.getLocalVar(method.Body.Variables, ldloc) == DotNetUtils.getLocalVar(method.Body.Variables, stloc))
|
||||
if (ldloc.GetLocal(method.Body.LocalList) == stloc.GetLocal(method.Body.LocalList))
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 5]))
|
||||
if (!instrs[i + 5].IsLdloc())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,26 +21,26 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
using de4dot.PE;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
abstract class MethodsDecrypterBase : IVersionProvider {
|
||||
protected ModuleDefinition module;
|
||||
protected ModuleDefMD module;
|
||||
protected ISimpleDeobfuscator simpleDeobfuscator;
|
||||
protected MethodDefinition initMethod;
|
||||
protected MethodDefinition decryptMethod;
|
||||
protected MethodDef initMethod;
|
||||
protected MethodDef decryptMethod;
|
||||
protected ulong lkey0;
|
||||
protected uint key0, key1, key2, key3, key4, key5, key6;
|
||||
protected byte[] methodsData;
|
||||
|
||||
public MethodDefinition InitMethod {
|
||||
public MethodDef InitMethod {
|
||||
get { return initMethod; }
|
||||
}
|
||||
|
||||
public TypeDefinition Type {
|
||||
public TypeDef Type {
|
||||
get { return initMethod != null ? initMethod.DeclaringType : null; }
|
||||
}
|
||||
|
||||
|
@ -48,19 +48,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return initMethod != null; }
|
||||
}
|
||||
|
||||
protected MethodsDecrypterBase(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
protected MethodsDecrypterBase(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
this.module = module;
|
||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
}
|
||||
|
||||
protected MethodsDecrypterBase(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, MethodsDecrypterBase other) {
|
||||
protected MethodsDecrypterBase(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, MethodsDecrypterBase other) {
|
||||
this.module = module;
|
||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
if (other != null)
|
||||
this.initMethod = lookup(other.initMethod, "Could not find initMethod");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -70,13 +70,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
find(DotNetUtils.getModuleTypeCctor(module));
|
||||
}
|
||||
|
||||
bool find(MethodDefinition method) {
|
||||
bool find(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
if (instr.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = instr.Operand as MethodDefinition;
|
||||
var calledMethod = instr.Operand as MethodDef;
|
||||
try {
|
||||
// If the body is encrypted, this could throw
|
||||
if (calledMethod == null || calledMethod.Body == null)
|
||||
|
@ -96,9 +96,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected abstract bool checkType(TypeDefinition type, MethodDefinition initMethod);
|
||||
protected abstract bool checkType(TypeDef type, MethodDef initMethod);
|
||||
|
||||
protected static MethodDefinition findDecryptMethod(TypeDefinition type) {
|
||||
protected static MethodDef findDecryptMethod(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
|
@ -110,7 +110,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected static bool findLKey0(MethodDefinition method, out ulong key) {
|
||||
protected static bool findLKey0(MethodDef method, out ulong key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = findCallvirtReadUInt64(instrs, index);
|
||||
|
@ -130,7 +130,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected static bool findKey0_v16_r71742(MethodDefinition method, out uint key) {
|
||||
protected static bool findKey0_v16_r71742(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i + 5 < instrs.Count; i++) {
|
||||
i = findCallvirtReadUInt32(instrs, i);
|
||||
|
@ -139,21 +139,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
int index = i + 1;
|
||||
var ldci4_1 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1))
|
||||
if (!ldci4_1.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[index++]))
|
||||
if (!instrs[index++].IsStloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[index++]))
|
||||
if (!instrs[index++].IsLdloc())
|
||||
continue;
|
||||
var ldci4_2 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2))
|
||||
if (!ldci4_2.IsLdcI4())
|
||||
continue;
|
||||
if (DotNetUtils.getLdcI4Value(ldci4_1) != DotNetUtils.getLdcI4Value(ldci4_2))
|
||||
if (ldci4_1.GetLdcI4Value() != ldci4_2.GetLdcI4Value())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4_1);
|
||||
key = (uint)ldci4_1.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected static bool findKey0_v14_r58564(MethodDefinition method, out uint key) {
|
||||
protected static bool findKey0_v14_r58564(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i + 5 < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()");
|
||||
|
@ -170,21 +170,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
int index = i + 1;
|
||||
var ldci4_1 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1))
|
||||
if (!ldci4_1.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[index++]))
|
||||
if (!instrs[index++].IsStloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[index++]))
|
||||
if (!instrs[index++].IsLdloc())
|
||||
continue;
|
||||
var ldci4_2 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2))
|
||||
if (!ldci4_2.IsLdcI4())
|
||||
continue;
|
||||
if (DotNetUtils.getLdcI4Value(ldci4_2) != 0 && DotNetUtils.getLdcI4Value(ldci4_1) != DotNetUtils.getLdcI4Value(ldci4_2))
|
||||
if (ldci4_2.GetLdcI4Value() != 0 && ldci4_1.GetLdcI4Value() != ldci4_2.GetLdcI4Value())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4_1);
|
||||
key = (uint)ldci4_1.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected static bool findKey1(MethodDefinition method, out uint key) {
|
||||
protected static bool findKey1(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = findCallvirtReadUInt32(instrs, index);
|
||||
|
@ -212,13 +212,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
if (i + 1 >= instrs.Count)
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i]))
|
||||
if (!instrs[i].IsLdloc())
|
||||
continue;
|
||||
var ldci4 = instrs[i + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -230,18 +230,18 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index + 2 >= instrs.Count)
|
||||
return false;
|
||||
|
||||
if (!DotNetUtils.isLdloc(instrs[index]))
|
||||
if (!instrs[index].IsLdloc())
|
||||
return false;
|
||||
if (!ConfuserUtils.isCallMethod(instrs[index + 1], Code.Callvirt, "System.UInt32 System.IO.BinaryReader::ReadUInt32()"))
|
||||
return false;
|
||||
if (!DotNetUtils.isStloc(instrs[index + 2]) && instrs[index + 2].OpCode.Code != Code.Pop)
|
||||
if (!instrs[index + 2].IsStloc() && instrs[index + 2].OpCode.Code != Code.Pop)
|
||||
return false;
|
||||
|
||||
index += 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static bool findKey2Key3(MethodDefinition method, out uint key2, out uint key3) {
|
||||
protected static bool findKey2Key3(MethodDef method, out uint key2, out uint key3) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = i;
|
||||
|
@ -263,46 +263,46 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index + 6 >= instrs.Count)
|
||||
return false;
|
||||
int i = index;
|
||||
if (!DotNetUtils.isLdloc(instrs[i++]))
|
||||
if (!instrs[i++].IsLdloc())
|
||||
return false;
|
||||
if (!DotNetUtils.isLdloc(instrs[i++]))
|
||||
if (!instrs[i++].IsLdloc())
|
||||
return false;
|
||||
if (!ConfuserUtils.isCallMethod(instrs[i++], Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()"))
|
||||
return false;
|
||||
var ldci4 = instrs[i++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
return false;
|
||||
if (instrs[i++].OpCode.Code != Code.Xor)
|
||||
return false;
|
||||
if (!ConfuserUtils.isCallMethod(instrs[i++], Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)"))
|
||||
return false;
|
||||
if (!DotNetUtils.isStloc(instrs[i++]))
|
||||
if (!instrs[i++].IsStloc())
|
||||
return false;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static bool findKey6(MethodDefinition method, out uint key) {
|
||||
protected static bool findKey6(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i + 4 < instrs.Count; i++) {
|
||||
int index = i;
|
||||
if (!DotNetUtils.isLdloc(instrs[index++]))
|
||||
if (!instrs[index++].IsLdloc())
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Sub)
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Ldelem_U1)
|
||||
continue;
|
||||
var ldci4 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Conv_U1)
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,15 +21,15 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
using de4dot.PE;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class ProxyCallFixer : ProxyCallFixer2, IVersionProvider {
|
||||
MethodDefinitionAndDeclaringTypeDict<ProxyCreatorInfo> methodToInfo = new MethodDefinitionAndDeclaringTypeDict<ProxyCreatorInfo>();
|
||||
FieldDefinitionAndDeclaringTypeDict<List<MethodDefinition>> fieldToMethods = new FieldDefinitionAndDeclaringTypeDict<List<MethodDefinition>>();
|
||||
FieldDefinitionAndDeclaringTypeDict<List<MethodDef>> fieldToMethods = new FieldDefinitionAndDeclaringTypeDict<List<MethodDef>>();
|
||||
string ourAsm;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
byte[] fileData;
|
||||
|
@ -70,14 +70,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
class ProxyCreatorInfo {
|
||||
public readonly MethodDefinition creatorMethod;
|
||||
public readonly MethodDef creatorMethod;
|
||||
public readonly ProxyCreatorType proxyCreatorType;
|
||||
public readonly ConfuserVersion version;
|
||||
public readonly uint magic;
|
||||
public readonly MethodDefinition nativeMethod;
|
||||
public readonly MethodDef nativeMethod;
|
||||
public readonly ushort callvirtChar;
|
||||
|
||||
public ProxyCreatorInfo(MethodDefinition creatorMethod, ProxyCreatorType proxyCreatorType, ConfuserVersion version, uint magic, MethodDefinition nativeMethod, ushort callvirtChar) {
|
||||
public ProxyCreatorInfo(MethodDef creatorMethod, ProxyCreatorType proxyCreatorType, ConfuserVersion version, uint magic, MethodDef nativeMethod, ushort callvirtChar) {
|
||||
this.creatorMethod = creatorMethod;
|
||||
this.proxyCreatorType = proxyCreatorType;
|
||||
this.version = version;
|
||||
|
@ -89,15 +89,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
class DelegateInitInfo {
|
||||
public readonly byte[] data;
|
||||
public readonly FieldDefinition field;
|
||||
public readonly MethodDefinition creatorMethod;
|
||||
public readonly FieldDef field;
|
||||
public readonly MethodDef creatorMethod;
|
||||
|
||||
public DelegateInitInfo(FieldDefinition field, MethodDefinition creatorMethod) {
|
||||
public DelegateInitInfo(FieldDef field, MethodDef creatorMethod) {
|
||||
this.field = field;
|
||||
this.creatorMethod = creatorMethod;
|
||||
}
|
||||
|
||||
public DelegateInitInfo(string data, FieldDefinition field, MethodDefinition creatorMethod) {
|
||||
public DelegateInitInfo(string data, FieldDef field, MethodDef creatorMethod) {
|
||||
this.data = Convert.FromBase64String(data);
|
||||
this.field = field;
|
||||
this.creatorMethod = creatorMethod;
|
||||
|
@ -108,13 +108,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return true; }
|
||||
}
|
||||
|
||||
public IEnumerable<FieldDefinition> Fields {
|
||||
public IEnumerable<FieldDef> Fields {
|
||||
get {
|
||||
var fields = new List<FieldDefinition>(fieldToMethods.getKeys());
|
||||
var fields = new List<FieldDef>(fieldToMethods.getKeys());
|
||||
var type = DotNetUtils.getModuleType(module);
|
||||
if (fields.Count > 0 && type != null) {
|
||||
foreach (var field in type.Fields) {
|
||||
var fieldType = field.FieldType as TypeDefinition;
|
||||
var fieldType = field.FieldType.TryGetTypeDef();
|
||||
if (fieldType != null && delegateTypesDict.ContainsKey(fieldType))
|
||||
fields.Add(field);
|
||||
}
|
||||
|
@ -123,22 +123,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<Tuple<MethodDefinition, string>> OtherMethods {
|
||||
public override IEnumerable<Tuple<MethodDef, string>> OtherMethods {
|
||||
get {
|
||||
var list = new List<Tuple<MethodDefinition, string>>();
|
||||
var list = new List<Tuple<MethodDef, string>>();
|
||||
foreach (var info in methodToInfo.getValues()) {
|
||||
list.Add(new Tuple<MethodDefinition, string> {
|
||||
list.Add(new Tuple<MethodDef, string> {
|
||||
Item1 = info.creatorMethod,
|
||||
Item2 = "Delegate creator method",
|
||||
});
|
||||
list.Add(new Tuple<MethodDefinition, string> {
|
||||
list.Add(new Tuple<MethodDef, string> {
|
||||
Item1 = info.nativeMethod,
|
||||
Item2 = "Calculate RID native method",
|
||||
});
|
||||
}
|
||||
foreach (var methods in fieldToMethods.getValues()) {
|
||||
foreach (var method in methods) {
|
||||
list.Add(new Tuple<MethodDefinition, string> {
|
||||
list.Add(new Tuple<MethodDef, string> {
|
||||
Item1 = method,
|
||||
Item2 = "Proxy delegate method",
|
||||
});
|
||||
|
@ -148,16 +148,16 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
public ProxyCallFixer(ModuleDefinition module, byte[] fileData)
|
||||
public ProxyCallFixer(ModuleDefMD module, byte[] fileData)
|
||||
: base(module) {
|
||||
this.fileData = fileData;
|
||||
if (module.Assembly == null || module.Assembly.Name == null)
|
||||
ourAsm = new AssemblyNameReference(" -1-1-1-1-1- ", new Version(1, 2, 3, 4)).FullName;
|
||||
if (module.Assembly == null)
|
||||
ourAsm = " -1-1-1-1-1- , Version=1.2.3.4, Culture=neutral, PublicKeyToken=null";
|
||||
else
|
||||
ourAsm = module.Assembly.FullName;
|
||||
}
|
||||
|
||||
protected override object checkCctor(TypeDefinition type, MethodDefinition cctor) {
|
||||
protected override object checkCctor(TypeDef type, MethodDef cctor) {
|
||||
// Here if 1.2 r54564 (almost 1.3) or later
|
||||
|
||||
var fieldToInfo = new FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo>();
|
||||
|
@ -167,14 +167,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var ldtoken = instrs[i];
|
||||
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
||||
continue;
|
||||
var field = ldtoken.Operand as FieldDefinition;
|
||||
var field = ldtoken.Operand as FieldDef;
|
||||
if (field == null || field.DeclaringType != cctor.DeclaringType)
|
||||
continue;
|
||||
|
||||
var call = instrs[i + 1];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodDefinition;
|
||||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
if (!isDelegateCreatorMethod(calledMethod))
|
||||
|
@ -189,7 +189,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return fieldToInfo.Count == 0 ? null : fieldToInfo;
|
||||
}
|
||||
|
||||
protected override void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||
protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var info = context as DelegateInitInfo;
|
||||
if (info == null) {
|
||||
var fieldToInfo = context as FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo>;
|
||||
|
@ -250,12 +250,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
if (calledMethod == null) {
|
||||
Log.w("Could not find real method. Proxy field: {0:X8}", info.field.MetadataToken.ToInt32());
|
||||
Logger.w("Could not find real method. Proxy field: {0:X8}", info.field.MDToken.ToInt32());
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
void getCallInfo_v10_r42915(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||
void getCallInfo_v10_r42915(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var reader = new BinaryReader(new MemoryStream(info.data));
|
||||
|
||||
bool isCallvirt = false;
|
||||
|
@ -269,14 +269,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException("Extra data");
|
||||
|
||||
if (asmRef.FullName == ourAsm)
|
||||
calledMethod = (MethodReference)module.LookupToken((int)token);
|
||||
calledMethod = module.ResolveToken(token) as IMethod;
|
||||
else
|
||||
calledMethod = createMethodReference(asmRef, token);
|
||||
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
void getCallInfo_v10_r48717(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||
void getCallInfo_v10_r48717(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
bool isNew = creatorInfo.version == ConfuserVersion.v14_r58802;
|
||||
|
||||
int offs = creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt ? 2 : 1;
|
||||
|
@ -287,42 +287,42 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
// This is an obfuscator bug. Field names are stored in the #Strings heap,
|
||||
// and strings in that heap are UTF8 zero terminated strings, but Confuser
|
||||
// can generate names with zeros in them. This was fixed in 1.4 58857.
|
||||
if (offs + 2 > info.field.Name.Length) {
|
||||
if (offs + 2 > info.field.Name.String.Length) {
|
||||
calledMethod = null;
|
||||
callOpcode = OpCodes.Call;
|
||||
return;
|
||||
}
|
||||
|
||||
uint token = BitConverter.ToUInt32(Encoding.Unicode.GetBytes(info.field.Name.ToCharArray(), offs, 2), 0) ^ creatorInfo.magic;
|
||||
uint token = BitConverter.ToUInt32(Encoding.Unicode.GetBytes(info.field.Name.String.ToCharArray(), offs, 2), 0) ^ creatorInfo.magic;
|
||||
uint table = token >> 24;
|
||||
if (table != 0 && table != 6 && table != 0x0A && table != 0x2B)
|
||||
throw new ApplicationException("Invalid method token");
|
||||
|
||||
// 1.3 r55346 now correctly uses method reference tokens and finally fixed the old
|
||||
// bug of using methoddef tokens to reference external methods.
|
||||
if (isNew || info.field.Name[0] == (char)1 || table != 0x06)
|
||||
calledMethod = (MethodReference)module.LookupToken((int)token);
|
||||
if (isNew || info.field.Name.String[0] == (char)1 || table != 0x06)
|
||||
calledMethod = module.ResolveToken(token) as IMethod;
|
||||
else {
|
||||
var asmRef = module.AssemblyReferences[info.field.Name[0] - 2];
|
||||
var asmRef = module.ResolveAssemblyRef((uint)info.field.Name.String[0] - 2 + 1);
|
||||
calledMethod = createMethodReference(asmRef, token);
|
||||
}
|
||||
|
||||
bool isCallvirt = false;
|
||||
if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && info.field.Name[callvirtOffs] == '\r')
|
||||
if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && info.field.Name.String[callvirtOffs] == '\r')
|
||||
isCallvirt = true;
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
void getCallInfo_v14_r58857(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||
void getCallInfo_v14_r58857(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
int offs = creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt ? 1 : 0;
|
||||
var nameInfo = decryptFieldName(info.field.Name);
|
||||
var nameInfo = decryptFieldName(info.field.Name.String);
|
||||
|
||||
uint token = BitConverter.ToUInt32(nameInfo, offs) ^ creatorInfo.magic;
|
||||
uint table = token >> 24;
|
||||
if (table != 6 && table != 0x0A && table != 0x2B)
|
||||
throw new ApplicationException("Invalid method token");
|
||||
|
||||
calledMethod = (MethodReference)module.LookupToken((int)token);
|
||||
calledMethod = module.ResolveToken(token) as IMethod;
|
||||
|
||||
bool isCallvirt = false;
|
||||
if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && nameInfo[0] == '\r')
|
||||
|
@ -356,19 +356,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
void getCallInfo_v17_r73740_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||
var nameInfo = decryptFieldName(info.field.Name);
|
||||
void getCallInfo_v17_r73740_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var nameInfo = decryptFieldName(info.field.Name.String);
|
||||
uint arg, table;
|
||||
bool isCallvirt;
|
||||
extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
|
||||
uint token = (arg ^ creatorInfo.magic) | table;
|
||||
|
||||
calledMethod = module.LookupToken((int)token) as MethodReference;
|
||||
calledMethod = module.ResolveToken((int)token) as IMethod;
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
void getCallInfo_v17_r73740_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||
var nameInfo = decryptFieldName(info.field.Name);
|
||||
void getCallInfo_v17_r73740_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var nameInfo = decryptFieldName(info.field.Name.String);
|
||||
uint arg, table;
|
||||
bool isCallvirt;
|
||||
extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
|
||||
|
@ -376,15 +376,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
x86emu = new x86Emulator(new PeImage(fileData));
|
||||
uint token = x86emu.emulate((uint)creatorInfo.nativeMethod.RVA, arg) | table;
|
||||
|
||||
calledMethod = module.LookupToken((int)token) as MethodReference;
|
||||
calledMethod = module.ResolveToken((int)token) as IMethod;
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
void getCallInfo_v18_r75367_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||
void getCallInfo_v18_r75367_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
getCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => creatorInfo2.magic ^ magic);
|
||||
}
|
||||
|
||||
void getCallInfo_v18_r75367_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out MethodReference calledMethod, out OpCode callOpcode) {
|
||||
void getCallInfo_v18_r75367_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
getCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => {
|
||||
if (x86emu == null)
|
||||
x86emu = new x86Emulator(new PeImage(fileData));
|
||||
|
@ -392,8 +392,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
});
|
||||
}
|
||||
|
||||
void getCallInfo_v18_r75367(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out MethodReference calledMethod, out OpCode callOpcode, Func<ProxyCreatorInfo, uint, uint> getRid) {
|
||||
var sig = module.GetSignatureBlob(info.field);
|
||||
void getCallInfo_v18_r75367(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode, Func<ProxyCreatorInfo, uint, uint> getRid) {
|
||||
var sig = module.ReadBlob(info.field.MDToken.Raw);
|
||||
int len = sig.Length;
|
||||
uint magic = (uint)((sig[len - 2] << 24) | (sig[len - 3] << 16) | (sig[len - 5] << 8) | sig[len - 6]);
|
||||
uint rid = getRid(creatorInfo, magic);
|
||||
|
@ -401,14 +401,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
uint table = (uint)token >> 24;
|
||||
if (table != 6 && table != 0x0A && table != 0x2B)
|
||||
throw new ApplicationException("Invalid method token");
|
||||
calledMethod = module.LookupToken(token) as MethodReference;
|
||||
calledMethod = module.ResolveToken(token) as IMethod;
|
||||
callOpcode = getCallOpCode(creatorInfo, info.field);
|
||||
}
|
||||
|
||||
static OpCode getCallOpCode(ProxyCreatorInfo info, FieldDefinition field) {
|
||||
static OpCode getCallOpCode(ProxyCreatorInfo info, FieldDef field) {
|
||||
switch (info.proxyCreatorType) {
|
||||
case ProxyCreatorType.CallOrCallvirt:
|
||||
if (field.Name.Length > 0 && field.Name[0] == info.callvirtChar)
|
||||
if (field.Name.String.Length > 0 && field.Name.String[0] == info.callvirtChar)
|
||||
return OpCodes.Callvirt;
|
||||
return OpCodes.Call;
|
||||
|
||||
|
@ -421,27 +421,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
// A method token is not a stable value so this method can fail to return the correct method!
|
||||
// There's nothing I can do about that. It's an obfuscator bug. It was fixed in 1.3 r55346.
|
||||
MethodReference createMethodReference(AssemblyNameReference asmRef, uint methodToken) {
|
||||
var asm = AssemblyResolver.Instance.Resolve(asmRef);
|
||||
IMethod createMethodReference(AssemblyRef asmRef, uint methodToken) {
|
||||
var asm = module.Context.AssemblyResolver.Resolve(asmRef, module);
|
||||
if (asm == null)
|
||||
return null;
|
||||
|
||||
var method = asm.MainModule.LookupToken((int)methodToken) as MethodDefinition;
|
||||
var method = ((ModuleDefMD)asm.ManifestModule).ResolveToken(methodToken) as MethodDef;
|
||||
if (method == null)
|
||||
return null;
|
||||
|
||||
return module.Import(method);
|
||||
}
|
||||
|
||||
static AssemblyNameReference readAssemblyNameReference(BinaryReader reader) {
|
||||
AssemblyRef readAssemblyNameReference(BinaryReader reader) {
|
||||
var name = readString(reader);
|
||||
var version = new Version(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16());
|
||||
var culture = readString(reader);
|
||||
byte[] pkt = reader.ReadBoolean() ? reader.ReadBytes(8) : null;
|
||||
return new AssemblyNameReference(name, version) {
|
||||
Culture = culture,
|
||||
PublicKeyToken = pkt,
|
||||
};
|
||||
return module.UpdateRowId(new AssemblyRefUser(name, version, pkt == null ? null : new PublicKeyToken(pkt), culture));
|
||||
}
|
||||
|
||||
static string readString(BinaryReader reader) {
|
||||
|
@ -485,7 +482,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
MethodDefinition nativeMethod = null;
|
||||
MethodDef nativeMethod = null;
|
||||
uint magic;
|
||||
if (findMagic_v14_r58564(method, out magic)) {
|
||||
if (!DotNetUtils.callsMethod(method, "System.Byte[] System.Convert::FromBase64String(System.String)")) {
|
||||
|
@ -556,9 +553,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
static bool hasFieldReference(MethodDefinition method, string fieldFullName) {
|
||||
static bool hasFieldReference(MethodDef method, string fieldFullName) {
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
var field = instr.Operand as FieldReference;
|
||||
var field = instr.Operand as IField;
|
||||
if (field == null)
|
||||
continue;
|
||||
if (field.FullName == fieldFullName)
|
||||
|
@ -567,7 +564,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool isMethodCreator_v14_r58802(MethodDefinition method, ProxyCreatorType proxyType) {
|
||||
static bool isMethodCreator_v14_r58802(MethodDef method, ProxyCreatorType proxyType) {
|
||||
int index = getFieldNameIndex(method);
|
||||
if (index < 0)
|
||||
throw new ApplicationException("Could not find field name index");
|
||||
|
@ -592,7 +589,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException("Could not find field name index");
|
||||
}
|
||||
|
||||
static int getFieldNameIndex(MethodDefinition method) {
|
||||
static int getFieldNameIndex(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.Text.Encoding::GetBytes(System.Char[],System.Int32,System.Int32)");
|
||||
|
@ -601,63 +598,63 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (i < 2)
|
||||
continue;
|
||||
var ldci4 = instrs[i - 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
|
||||
return DotNetUtils.getLdcI4Value(ldci4);
|
||||
return ldci4.GetLdcI4Value();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool findMagic_v19_r76101(MethodDefinition method, out uint magic) {
|
||||
static bool findMagic_v19_r76101(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 7; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1) || DotNetUtils.getLdcI4Value(ldci4_1) != 24)
|
||||
if (!ldci4_1.IsLdcI4() || ldci4_1.GetLdcI4Value() != 24)
|
||||
continue;
|
||||
if (instrs[i + 1].OpCode.Code != Code.Shl)
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Or)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsStloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 4]))
|
||||
if (!instrs[i + 4].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 5]))
|
||||
if (!instrs[i + 5].IsLdloc())
|
||||
continue;
|
||||
var ldci4_2 = instrs[i + 6];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2))
|
||||
if (!ldci4_2.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 7].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
|
||||
magic = (uint)DotNetUtils.getLdcI4Value(ldci4_2);
|
||||
magic = (uint)ldci4_2.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
magic = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static MethodDefinition findNativeMethod_v19_r76101(MethodDefinition method) {
|
||||
static MethodDef findNativeMethod_v19_r76101(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 6; i++) {
|
||||
var ldci4 = instrs[i];
|
||||
if (!DotNetUtils.isLdcI4(ldci4) || DotNetUtils.getLdcI4Value(ldci4) != 24)
|
||||
if (!ldci4.IsLdcI4() || ldci4.GetLdcI4Value() != 24)
|
||||
continue;
|
||||
if (instrs[i + 1].OpCode.Code != Code.Shl)
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Or)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsStloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 4]))
|
||||
if (!instrs[i + 4].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 5]))
|
||||
if (!instrs[i + 5].IsLdloc())
|
||||
continue;
|
||||
var call = instrs[i + 6];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodDefinition;
|
||||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || calledMethod.Body != null || !calledMethod.IsNative)
|
||||
continue;
|
||||
|
||||
|
@ -666,42 +663,42 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool findMagic_v18_r75367(MethodDefinition method, out uint magic) {
|
||||
static bool findMagic_v18_r75367(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
if (i < 0 || i + 3 >= instrs.Count)
|
||||
break;
|
||||
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsLdloc())
|
||||
continue;
|
||||
var ldci4 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i+3].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
|
||||
magic = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
magic = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
magic = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static MethodDefinition findNativeMethod_v18_r75367(MethodDefinition method) {
|
||||
static MethodDef findNativeMethod_v18_r75367(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
if (i < 0 || i + 2 >= instrs.Count)
|
||||
break;
|
||||
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsLdloc())
|
||||
continue;
|
||||
|
||||
var call = instrs[i + 2];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodDefinition;
|
||||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || calledMethod.Body != null || !calledMethod.IsNative)
|
||||
continue;
|
||||
|
||||
|
@ -710,7 +707,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool findMagic_v17_r73740(MethodDefinition method, out uint magic) {
|
||||
static bool findMagic_v17_r73740(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
|
@ -719,22 +716,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index < 1 || index + 2 >= instrs.Count)
|
||||
continue;
|
||||
|
||||
if (!DotNetUtils.isLdcI4(instrs[index - 1]))
|
||||
if (!instrs[index - 1].IsLdcI4())
|
||||
continue;
|
||||
var ldci4 = instrs[index + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index + 2].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
|
||||
magic = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
magic = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
magic = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static MethodDefinition findNativeMethod_v17_r73740(MethodDefinition method) {
|
||||
static MethodDef findNativeMethod_v17_r73740(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
|
@ -743,12 +740,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index < 1 || index + 1 >= instrs.Count)
|
||||
continue;
|
||||
|
||||
if (!DotNetUtils.isLdcI4(instrs[index - 1]))
|
||||
if (!instrs[index - 1].IsLdcI4())
|
||||
continue;
|
||||
var call = instrs[index + 1];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodDefinition;
|
||||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || calledMethod.Body != null || !calledMethod.IsNative)
|
||||
continue;
|
||||
|
||||
|
@ -757,7 +754,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool is_v17_r73740(MethodDefinition method) {
|
||||
static bool is_v17_r73740(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
|
||||
|
@ -768,7 +765,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
index -= 3;
|
||||
var ldci4 = instrs[index];
|
||||
if (!DotNetUtils.isLdcI4(ldci4) || DotNetUtils.getLdcI4Value(ldci4) != 24)
|
||||
if (!ldci4.IsLdcI4() || ldci4.GetLdcI4Value() != 24)
|
||||
continue;
|
||||
if (instrs[index + 1].OpCode.Code != Code.Shl)
|
||||
continue;
|
||||
|
@ -780,7 +777,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findMagic_v14_r58564(MethodDefinition method, out uint magic) {
|
||||
static bool findMagic_v14_r58564(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
|
@ -790,21 +787,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index2 < 0 || index2 - index != 3)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index + 2].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
|
||||
magic = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
magic = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
magic = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static ProxyCreatorType getProxyCreatorType(MethodDefinition method) {
|
||||
static ProxyCreatorType getProxyCreatorType(MethodDef method) {
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
var field = instr.Operand as FieldReference;
|
||||
var field = instr.Operand as IField;
|
||||
if (field == null)
|
||||
continue;
|
||||
switch (field.FullName) {
|
||||
|
@ -826,17 +823,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (cctor == null)
|
||||
return;
|
||||
|
||||
Log.v("Finding all proxy delegates");
|
||||
Logger.v("Finding all proxy delegates");
|
||||
|
||||
var delegateInfos = createDelegateInitInfos(cctor);
|
||||
fieldToMethods = createFieldToMethodsDictionary(cctor.DeclaringType);
|
||||
if (delegateInfos.Count < fieldToMethods.Count)
|
||||
throw new ApplicationException("Missing proxy delegates");
|
||||
var delegateToFields = new Dictionary<TypeDefinition, List<FieldDefinition>>();
|
||||
var delegateToFields = new Dictionary<TypeDef, List<FieldDef>>();
|
||||
foreach (var field in fieldToMethods.getKeys()) {
|
||||
List<FieldDefinition> list;
|
||||
if (!delegateToFields.TryGetValue((TypeDefinition)field.FieldType, out list))
|
||||
delegateToFields[(TypeDefinition)field.FieldType] = list = new List<FieldDefinition>();
|
||||
List<FieldDef> list;
|
||||
if (!delegateToFields.TryGetValue(field.FieldType.TryGetTypeDef(), out list))
|
||||
delegateToFields[field.FieldType.TryGetTypeDef()] = list = new List<FieldDef>();
|
||||
list.Add(field);
|
||||
}
|
||||
|
||||
|
@ -844,10 +841,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var type = kv.Key;
|
||||
var fields = kv.Value;
|
||||
|
||||
Log.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MetadataToken.ToInt32());
|
||||
Logger.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MDToken.ToInt32());
|
||||
RemovedDelegateCreatorCalls++;
|
||||
|
||||
Log.indent();
|
||||
Logger.Instance.indent();
|
||||
foreach (var field in fields) {
|
||||
var proxyMethods = fieldToMethods.find(field);
|
||||
if (proxyMethods == null)
|
||||
|
@ -856,7 +853,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (info == null)
|
||||
throw new ApplicationException("Missing proxy info");
|
||||
|
||||
MethodReference calledMethod;
|
||||
IMethod calledMethod;
|
||||
OpCode callOpcode;
|
||||
getCallInfo(info, field, out calledMethod, out callOpcode);
|
||||
|
||||
|
@ -864,14 +861,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
foreach (var proxyMethod in proxyMethods) {
|
||||
add(proxyMethod, new DelegateInfo(field, calledMethod, callOpcode));
|
||||
Log.v("Field: {0}, Opcode: {1}, Method: {2} ({3:X8})",
|
||||
Logger.v("Field: {0}, Opcode: {1}, Method: {2} ({3:X8})",
|
||||
Utils.removeNewlines(field.Name),
|
||||
callOpcode,
|
||||
Utils.removeNewlines(calledMethod),
|
||||
calledMethod.MetadataToken.ToUInt32());
|
||||
calledMethod.MDToken.ToUInt32());
|
||||
}
|
||||
}
|
||||
Log.deIndent();
|
||||
Logger.Instance.deIndent();
|
||||
delegateTypesDict[type] = true;
|
||||
}
|
||||
|
||||
|
@ -879,7 +876,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
find2();
|
||||
}
|
||||
|
||||
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos(MethodDefinition method) {
|
||||
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos(MethodDef method) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v10_r42915:
|
||||
case ConfuserVersion.v10_r42919:
|
||||
|
@ -889,7 +886,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r42915(MethodDefinition method) {
|
||||
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r42915(MethodDef method) {
|
||||
var infos = new FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo>();
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||
|
@ -903,17 +900,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var ldtoken = instrs[i + 1];
|
||||
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
||||
continue;
|
||||
var delegateField = ldtoken.Operand as FieldDefinition;
|
||||
var delegateField = ldtoken.Operand as FieldDef;
|
||||
if (delegateField == null)
|
||||
continue;
|
||||
var delegateType = delegateField.FieldType as TypeDefinition;
|
||||
var delegateType = delegateField.FieldType.TryGetTypeDef();
|
||||
if (!DotNetUtils.derivesFromDelegate(delegateType))
|
||||
continue;
|
||||
|
||||
var call = instrs[i + 2];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var delegateCreatorMethod = call.Operand as MethodDefinition;
|
||||
var delegateCreatorMethod = call.Operand as MethodDef;
|
||||
if (delegateCreatorMethod == null || !isDelegateCreatorMethod(delegateCreatorMethod))
|
||||
continue;
|
||||
|
||||
|
@ -923,24 +920,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return infos;
|
||||
}
|
||||
|
||||
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r48717(MethodDefinition method) {
|
||||
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r48717(MethodDef method) {
|
||||
var infos = new FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo>();
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var ldtoken = instrs[i];
|
||||
if (ldtoken.OpCode.Code != Code.Ldtoken)
|
||||
continue;
|
||||
var delegateField = ldtoken.Operand as FieldDefinition;
|
||||
var delegateField = ldtoken.Operand as FieldDef;
|
||||
if (delegateField == null)
|
||||
continue;
|
||||
var delegateType = delegateField.FieldType as TypeDefinition;
|
||||
var delegateType = delegateField.FieldType.TryGetTypeDef();
|
||||
if (!DotNetUtils.derivesFromDelegate(delegateType))
|
||||
continue;
|
||||
|
||||
var call = instrs[i + 1];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var delegateCreatorMethod = call.Operand as MethodDefinition;
|
||||
var delegateCreatorMethod = call.Operand as MethodDef;
|
||||
if (delegateCreatorMethod == null || !isDelegateCreatorMethod(delegateCreatorMethod))
|
||||
continue;
|
||||
|
||||
|
@ -950,8 +947,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return infos;
|
||||
}
|
||||
|
||||
static FieldDefinitionAndDeclaringTypeDict<List<MethodDefinition>> createFieldToMethodsDictionary(TypeDefinition type) {
|
||||
var dict = new FieldDefinitionAndDeclaringTypeDict<List<MethodDefinition>>();
|
||||
static FieldDefinitionAndDeclaringTypeDict<List<MethodDef>> createFieldToMethodsDictionary(TypeDef type) {
|
||||
var dict = new FieldDefinitionAndDeclaringTypeDict<List<MethodDef>>();
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null || method.Name == ".cctor")
|
||||
continue;
|
||||
|
@ -960,38 +957,38 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
var methods = dict.find(delegateField);
|
||||
if (methods == null)
|
||||
dict.add(delegateField, methods = new List<MethodDefinition>());
|
||||
dict.add(delegateField, methods = new List<MethodDef>());
|
||||
methods.Add(method);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
static FieldDefinition getDelegateField(MethodDefinition method) {
|
||||
static FieldDef getDelegateField(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return null;
|
||||
|
||||
FieldDefinition field = null;
|
||||
FieldDef field = null;
|
||||
bool foundInvoke = false;
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
if (instr.OpCode.Code == Code.Ldsfld) {
|
||||
var field2 = instr.Operand as FieldDefinition;
|
||||
var field2 = instr.Operand as FieldDef;
|
||||
if (field2 == null || field2.DeclaringType != method.DeclaringType)
|
||||
continue;
|
||||
if (field != null)
|
||||
return null;
|
||||
if (!DotNetUtils.derivesFromDelegate(field2.FieldType as TypeDefinition))
|
||||
if (!DotNetUtils.derivesFromDelegate(field2.FieldType.TryGetTypeDef()))
|
||||
continue;
|
||||
field = field2;
|
||||
}
|
||||
else if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) {
|
||||
var calledMethod = instr.Operand as MethodReference;
|
||||
var calledMethod = instr.Operand as IMethod;
|
||||
foundInvoke |= calledMethod != null && calledMethod.Name == "Invoke";
|
||||
}
|
||||
}
|
||||
return foundInvoke ? field : null;
|
||||
}
|
||||
|
||||
static bool findCallvirtChar(MethodDefinition method, out ushort callvirtChar) {
|
||||
static bool findCallvirtChar(MethodDef method, out ushort callvirtChar) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.Char System.String::get_Chars(System.Int32)");
|
||||
|
@ -1003,9 +1000,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
break;
|
||||
|
||||
var ldci4 = instrs[index];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
callvirtChar = (ushort)DotNetUtils.getLdcI4Value(ldci4);
|
||||
callvirtChar = (ushort)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
callvirtChar = 0;
|
||||
|
|
|
@ -20,18 +20,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class ResourceDecrypter : IVersionProvider {
|
||||
ModuleDefinition module;
|
||||
ModuleDefMD module;
|
||||
ISimpleDeobfuscator simpleDeobfuscator;
|
||||
MethodDefinition handler;
|
||||
MethodDefinition installMethod;
|
||||
MethodDef handler;
|
||||
MethodDef installMethod;
|
||||
EmbeddedResource resource;
|
||||
Dictionary<FieldDefinition, bool> fields = new Dictionary<FieldDefinition, bool>();
|
||||
Dictionary<FieldDef, bool> fields = new Dictionary<FieldDef, bool>();
|
||||
byte key0, key1;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
|
||||
|
@ -44,11 +44,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
v18_r75369,
|
||||
}
|
||||
|
||||
public IEnumerable<FieldDefinition> Fields {
|
||||
public IEnumerable<FieldDef> Fields {
|
||||
get { return fields.Keys; }
|
||||
}
|
||||
|
||||
public MethodDefinition Handler {
|
||||
public MethodDef Handler {
|
||||
get { return handler; }
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return handler != null; }
|
||||
}
|
||||
|
||||
public ResourceDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
this.module = module;
|
||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return;
|
||||
}
|
||||
|
||||
bool checkMethod(MethodDefinition method) {
|
||||
bool checkMethod(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
if (!DotNetUtils.callsMethod(method, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)"))
|
||||
|
@ -116,13 +116,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static MethodDefinition getHandler(MethodDefinition method) {
|
||||
static MethodDef getHandler(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||
var ldftn = instrs[i];
|
||||
if (ldftn.OpCode.Code != Code.Ldftn)
|
||||
continue;
|
||||
var handler = ldftn.Operand as MethodDefinition;
|
||||
var handler = ldftn.Operand as MethodDef;
|
||||
if (handler == null)
|
||||
continue;
|
||||
|
||||
|
@ -133,7 +133,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var callvirt = instrs[i + 2];
|
||||
if (callvirt.OpCode.Code != Code.Callvirt)
|
||||
continue;
|
||||
var calledMethod = callvirt.Operand as MethodReference;
|
||||
var calledMethod = callvirt.Operand as IMethod;
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
if (calledMethod.FullName != "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)")
|
||||
|
@ -144,7 +144,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
int addFields(IEnumerable<FieldDefinition> moreFields) {
|
||||
int addFields(IEnumerable<FieldDef> moreFields) {
|
||||
int count = 0;
|
||||
foreach (var field in moreFields) {
|
||||
if (addField(field))
|
||||
|
@ -153,7 +153,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return count;
|
||||
}
|
||||
|
||||
bool addField(FieldDefinition field) {
|
||||
bool addField(FieldDef field) {
|
||||
if (field == null)
|
||||
return false;
|
||||
if (fields.ContainsKey(field))
|
||||
|
@ -162,21 +162,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static IEnumerable<FieldDefinition> findFields(MethodDefinition method, TypeDefinition declaringType) {
|
||||
var fields = new List<FieldDefinition>();
|
||||
static IEnumerable<FieldDef> findFields(MethodDef method, TypeDef declaringType) {
|
||||
var fields = new List<FieldDef>();
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
var field = instr.Operand as FieldDefinition;
|
||||
var field = instr.Operand as FieldDef;
|
||||
if (field != null && field.DeclaringType == declaringType)
|
||||
fields.Add(field);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
EmbeddedResource findResource(MethodDefinition method) {
|
||||
EmbeddedResource findResource(MethodDef method) {
|
||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||
}
|
||||
|
||||
static bool findKey0_v18_r75367(MethodDefinition method, out byte key0) {
|
||||
static bool findKey0_v18_r75367(MethodDef method, out byte key0) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)");
|
||||
|
@ -188,12 +188,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (instrs[i + 1].OpCode.Code != Code.Pop)
|
||||
continue;
|
||||
var ldci4 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsStloc())
|
||||
continue;
|
||||
|
||||
key0 = (byte)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key0 = (byte)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0_v18_r75369(MethodDefinition method, out byte key0) {
|
||||
static bool findKey0_v18_r75369(MethodDef method, out byte key0) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)");
|
||||
|
@ -215,14 +215,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (instrs[index++].OpCode.Code != Code.Pop)
|
||||
continue;
|
||||
var ldci4 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Conv_U1)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[index++]))
|
||||
if (!instrs[index++].IsStloc())
|
||||
continue;
|
||||
|
||||
key0 = (byte)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key0 = (byte)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -230,24 +230,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey1_v18_r75369(MethodDefinition method, out byte key1) {
|
||||
static bool findKey1_v18_r75369(MethodDef method, out byte key1) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
int index = i;
|
||||
if (!DotNetUtils.isLdloc(instrs[index++]))
|
||||
if (!instrs[index++].IsLdloc())
|
||||
continue;
|
||||
var ldci4_1 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1))
|
||||
if (!ldci4_1.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Mul)
|
||||
continue;
|
||||
var ldci4_2 = instrs[index++];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2) || DotNetUtils.getLdcI4Value(ldci4_2) != 0x100)
|
||||
if (!ldci4_2.IsLdcI4() || ldci4_2.GetLdcI4Value() != 0x100)
|
||||
continue;
|
||||
if (instrs[index++].OpCode.Code != Code.Rem)
|
||||
continue;
|
||||
|
||||
key1 = (byte)DotNetUtils.getLdcI4Value(ldci4_1);
|
||||
key1 = (byte)ldci4_1.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -255,26 +255,26 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0Key1_v14_r55802(MethodDefinition method, out byte key0, out byte key1) {
|
||||
static bool findKey0Key1_v14_r55802(MethodDef method, out byte key0, out byte key1) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
if (!DotNetUtils.isLdcI4(instrs[i]))
|
||||
if (!instrs[i].IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 1].OpCode.Code != Code.Add)
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Ldelem_U1)
|
||||
continue;
|
||||
var ldci4_1 = instrs[i + 3];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1))
|
||||
if (!ldci4_1.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 4].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
var ldci4_2 = instrs[i + 5];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2))
|
||||
if (!ldci4_2.IsLdcI4())
|
||||
continue;
|
||||
|
||||
key0 = (byte)DotNetUtils.getLdcI4Value(ldci4_1);
|
||||
key1 = (byte)DotNetUtils.getLdcI4Value(ldci4_2);
|
||||
key0 = (byte)ldci4_1.GetLdcI4Value();
|
||||
key1 = (byte)ldci4_2.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key0 = 0;
|
||||
|
@ -282,7 +282,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0_v17_r73404(MethodDefinition method, out byte key) {
|
||||
static bool findKey0_v17_r73404(MethodDef method, out byte key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)");
|
||||
|
@ -291,36 +291,36 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (index + 3 >= instrs.Count)
|
||||
break;
|
||||
|
||||
if (!DotNetUtils.isStloc(instrs[index + 1]))
|
||||
if (!instrs[index + 1].IsStloc())
|
||||
continue;
|
||||
var ldci4 = instrs[index + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[index + 3]))
|
||||
if (!instrs[index + 3].IsStloc())
|
||||
continue;
|
||||
|
||||
key = (byte)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (byte)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findKey1_v17_r73404(MethodDefinition method, out byte key) {
|
||||
static bool findKey1_v17_r73404(MethodDef method, out byte key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1))
|
||||
if (!ldci4_1.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 1].OpCode.Code != Code.Mul)
|
||||
continue;
|
||||
var ldci4_2 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2) || DotNetUtils.getLdcI4Value(ldci4_2) != 0x100)
|
||||
if (!ldci4_2.IsLdcI4() || ldci4_2.GetLdcI4Value() != 0x100)
|
||||
continue;
|
||||
if (instrs[i + 3].OpCode.Code != Code.Rem)
|
||||
continue;
|
||||
|
||||
key = (byte)DotNetUtils.getLdcI4Value(ldci4_1);
|
||||
key = (byte)ldci4_1.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
|
@ -330,7 +330,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public EmbeddedResource mergeResources() {
|
||||
if (resource == null)
|
||||
return null;
|
||||
DeobUtils.decryptAndAddResources(module, resource.Name, () => decryptResource());
|
||||
DeobUtils.decryptAndAddResources(module, resource.Name.String, () => decryptResource());
|
||||
var tmpResource = resource;
|
||||
resource = null;
|
||||
return tmpResource;
|
||||
|
|
|
@ -19,19 +19,19 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using dot10.IO;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class StringDecrypter : IVersionProvider {
|
||||
ModuleDefinition module;
|
||||
MethodDefinition decryptMethod;
|
||||
ModuleDefMD module;
|
||||
MethodDef decryptMethod;
|
||||
EmbeddedResource resource;
|
||||
uint magic1, magic2, key1;
|
||||
BinaryReader reader;
|
||||
IBinaryReader reader;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
Decrypter decrypter;
|
||||
|
||||
|
@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.stringDecrypter = stringDecrypter;
|
||||
}
|
||||
|
||||
public abstract string decrypt(MethodDefinition caller, int magic);
|
||||
public abstract string decrypt(MethodDef caller, int magic);
|
||||
}
|
||||
|
||||
class Decrypter_v10_r42915 : Decrypter {
|
||||
|
@ -69,12 +69,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.key = key;
|
||||
}
|
||||
|
||||
public override string decrypt(MethodDefinition caller, int magic) {
|
||||
public override string decrypt(MethodDef caller, int magic) {
|
||||
var reader = stringDecrypter.reader;
|
||||
reader.BaseStream.Position = (caller.MetadataToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
reader.Position = (caller.MDToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
int len = reader.ReadInt32() ^ (int)~stringDecrypter.magic2;
|
||||
var bytes = reader.ReadBytes(len);
|
||||
var rand = new Random(key == null ? caller.MetadataToken.ToInt32() : key.Value);
|
||||
var rand = new Random(key == null ? caller.MDToken.ToInt32() : key.Value);
|
||||
|
||||
int mask = 0;
|
||||
for (int i = 0; i < bytes.Length; i++) {
|
||||
|
@ -93,11 +93,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
: base(stringDecrypter) {
|
||||
}
|
||||
|
||||
public override string decrypt(MethodDefinition caller, int magic) {
|
||||
public override string decrypt(MethodDef caller, int magic) {
|
||||
var reader = stringDecrypter.reader;
|
||||
reader.BaseStream.Position = (caller.MetadataToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
reader.Position = (caller.MDToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
int len = reader.ReadInt32() ^ (int)~stringDecrypter.magic2;
|
||||
var rand = new Random(caller.MetadataToken.ToInt32());
|
||||
var rand = new Random(caller.MDToken.ToInt32());
|
||||
|
||||
var instrs = stringDecrypter.decryptMethod.Body.Instructions;
|
||||
constReader = new PolyConstantsReader(instrs, false);
|
||||
|
@ -124,9 +124,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
: base(stringDecrypter) {
|
||||
}
|
||||
|
||||
public override string decrypt(MethodDefinition caller, int magic) {
|
||||
public override string decrypt(MethodDef caller, int magic) {
|
||||
var reader = stringDecrypter.reader;
|
||||
reader.BaseStream.Position = (caller.MetadataToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
reader.Position = (caller.MDToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
int len = reader.ReadInt32() ^ (int)~stringDecrypter.magic2;
|
||||
var decrypted = new byte[len];
|
||||
|
||||
|
@ -156,7 +156,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static VariableDefinition findLocal(MethodDefinition method) {
|
||||
static Local findLocal(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.And)
|
||||
|
@ -165,34 +165,34 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Or)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsStloc())
|
||||
continue;
|
||||
return DotNetUtils.getLocalVar(method.Body.Variables, instrs[i + 3]);
|
||||
return instrs[i + 3].GetLocal(method.Body.LocalList);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static int findEndIndex(MethodDefinition method) {
|
||||
static int findEndIndex(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Conv_U1)
|
||||
continue;
|
||||
if (instrs[i + 1].OpCode.Code != Code.Stelem_I1)
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 2]))
|
||||
if (!instrs[i + 2].IsLdloc())
|
||||
continue;
|
||||
if (!DotNetUtils.isLdcI4(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 4].OpCode.Code != Code.Add)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 5]))
|
||||
if (!instrs[i + 5].IsStloc())
|
||||
continue;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int findStartIndex(MethodDefinition method, int endIndex) {
|
||||
static int findStartIndex(MethodDef method, int endIndex) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = endIndex; i >= 0; i--) {
|
||||
var instr = instrs[i];
|
||||
|
@ -220,7 +220,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
protected override bool processInstructionInt64(ref int index, Stack<ConstantInfo<long>> stack) {
|
||||
int i = index;
|
||||
|
||||
if (DotNetUtils.isLdloc(instructions[i])) {
|
||||
if (instructions[i].IsLdloc()) {
|
||||
i++;
|
||||
if (i >= instructions.Count)
|
||||
return false;
|
||||
|
@ -228,7 +228,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var callvirt = instructions[i];
|
||||
if (callvirt.OpCode.Code != Code.Callvirt)
|
||||
return false;
|
||||
var calledMethod = callvirt.Operand as MethodReference;
|
||||
var calledMethod = callvirt.Operand as IMethod;
|
||||
if (calledMethod == null || calledMethod.FullName != "System.Int64 System.IO.BinaryReader::ReadInt64()")
|
||||
return false;
|
||||
|
||||
|
@ -242,7 +242,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return resource; }
|
||||
}
|
||||
|
||||
public MethodDefinition Method {
|
||||
public MethodDef Method {
|
||||
get { return decryptMethod; }
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return decryptMethod != null; }
|
||||
}
|
||||
|
||||
public StringDecrypter(ModuleDefinition module) {
|
||||
public StringDecrypter(ModuleDefMD module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
|
@ -314,11 +314,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
EmbeddedResource findResource(MethodDefinition method) {
|
||||
EmbeddedResource findResource(MethodDef method) {
|
||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||
}
|
||||
|
||||
static bool findMagic1(MethodDefinition method, out uint magic) {
|
||||
static bool findMagic1(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)");
|
||||
|
@ -328,24 +328,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
|
||||
index -= 4;
|
||||
if (!DotNetUtils.isLdarg(instrs[index]))
|
||||
if (!instrs[index].IsLdarg())
|
||||
continue;
|
||||
if (instrs[index + 1].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index + 3].OpCode.Code != Code.Sub)
|
||||
continue;
|
||||
|
||||
magic = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
magic = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
magic = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findNewMagic1(MethodDefinition method, out uint magic) {
|
||||
static bool findNewMagic1(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Ldarg_0)
|
||||
|
@ -353,21 +353,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (instrs[i + 1].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
var ldci4 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 3].OpCode.Code != Code.Sub)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 4]))
|
||||
if (!instrs[i + 4].IsStloc())
|
||||
continue;
|
||||
|
||||
magic = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
magic = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
magic = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findMagic2(MethodDefinition method, out uint magic) {
|
||||
static bool findMagic2(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.UInt32 System.IO.BinaryReader::ReadUInt32()");
|
||||
|
@ -379,21 +379,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (instrs[index + 1].OpCode.Code != Code.Not)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[index + 3].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[index + 4]))
|
||||
if (!instrs[index + 4].IsStloc())
|
||||
continue;
|
||||
|
||||
magic = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
magic = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
magic = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findSafeKey1(MethodDefinition method, out uint key) {
|
||||
static bool findSafeKey1(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Newobj, "System.Void System.Random::.ctor(System.Int32)");
|
||||
|
@ -403,10 +403,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
|
||||
var ldci4 = instrs[index - 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
|
@ -420,7 +420,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
resource = findResource(decryptMethod);
|
||||
if (resource == null)
|
||||
throw new ApplicationException("Could not find encrypted strings resource");
|
||||
reader = new BinaryReader(new MemoryStream(DeobUtils.inflate(resource.GetResourceData(), true)));
|
||||
reader = MemoryImageStream.Create(DeobUtils.inflate(resource.GetResourceData(), true));
|
||||
|
||||
switch (version) {
|
||||
case ConfuserVersion.v10_r42915:
|
||||
|
@ -446,7 +446,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
public string decrypt(MethodDefinition caller, int magic) {
|
||||
public string decrypt(MethodDef caller, int magic) {
|
||||
return decrypter.decrypt(caller, magic);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,24 +20,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Cecil.Metadata;
|
||||
using dot10.DotNet;
|
||||
using dot10.DotNet.Emit;
|
||||
using de4dot.blocks;
|
||||
using SevenZip.Compression.LZMA;
|
||||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class RealAssemblyInfo {
|
||||
public AssemblyDefinition realAssembly;
|
||||
public AssemblyDef realAssembly;
|
||||
public uint entryPointToken;
|
||||
public ModuleKind kind;
|
||||
public string moduleName;
|
||||
|
||||
public RealAssemblyInfo(AssemblyDefinition realAssembly, uint entryPointToken, ModuleKind kind) {
|
||||
public RealAssemblyInfo(AssemblyDef realAssembly, uint entryPointToken, ModuleKind kind) {
|
||||
this.realAssembly = realAssembly;
|
||||
this.entryPointToken = entryPointToken;
|
||||
this.kind = kind;
|
||||
this.moduleName = realAssembly.Name.Name + DeobUtils.getExtension(kind);
|
||||
this.moduleName = realAssembly.Name.String + DeobUtils.getExtension(kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,12 +64,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
class Unpacker : IVersionProvider {
|
||||
ModuleDefinition module;
|
||||
ModuleDefMD module;
|
||||
EmbeddedResource mainAsmResource;
|
||||
uint key0, key1;
|
||||
uint entryPointToken;
|
||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||
MethodDefinition asmResolverMethod;
|
||||
MethodDef asmResolverMethod;
|
||||
|
||||
enum ConfuserVersion {
|
||||
Unknown,
|
||||
|
@ -93,7 +92,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return mainAsmResource != null; }
|
||||
}
|
||||
|
||||
public Unpacker(ModuleDefinition module, Unpacker other) {
|
||||
public Unpacker(ModuleDefMD module, Unpacker other) {
|
||||
this.module = module;
|
||||
if (other != null)
|
||||
this.version = other.version;
|
||||
|
@ -118,7 +117,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return;
|
||||
|
||||
bool use7zip = type.NestedTypes.Count == 6;
|
||||
MethodDefinition decyptMethod;
|
||||
MethodDef decyptMethod;
|
||||
if (use7zip)
|
||||
decyptMethod = findDecryptMethod_7zip(type);
|
||||
else
|
||||
|
@ -139,7 +138,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
else
|
||||
theVersion = ConfuserVersion.v14_r58564;
|
||||
|
||||
var cctor = DotNetUtils.getMethod(type, ".cctor");
|
||||
var cctor = type.FindStaticConstructor();
|
||||
if (cctor == null)
|
||||
return;
|
||||
|
||||
|
@ -202,7 +201,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
version = theVersion;
|
||||
}
|
||||
|
||||
bool findEntryPointToken(ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition cctor, MethodDefinition entryPoint, out uint token) {
|
||||
bool findEntryPointToken(ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor, MethodDef entryPoint, out uint token) {
|
||||
token = 0;
|
||||
ulong @base;
|
||||
if (!findBase(cctor, out @base))
|
||||
|
@ -234,7 +233,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return m;
|
||||
}
|
||||
|
||||
static bool findMod(MethodDefinition method, out ulong mod) {
|
||||
static bool findMod(MethodDef method, out ulong mod) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var ldci8 = instrs[i];
|
||||
|
@ -244,7 +243,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var call = instrs[i + 1];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var calledMethod = call.Operand as MethodReference;
|
||||
var calledMethod = call.Operand as IMethod;
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.UInt64", "(System.UInt64,System.UInt64,System.UInt64)"))
|
||||
|
@ -257,7 +256,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findBase(MethodDefinition method, out ulong @base) {
|
||||
static bool findBase(MethodDef method, out ulong @base) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||
var ldci8 = instrs[i];
|
||||
|
@ -266,10 +265,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var stsfld = instrs[i + 1];
|
||||
if (stsfld.OpCode.Code != Code.Stsfld)
|
||||
continue;
|
||||
var field = stsfld.Operand as FieldDefinition;
|
||||
var field = stsfld.Operand as FieldDef;
|
||||
if (field == null || field.DeclaringType != method.DeclaringType)
|
||||
continue;
|
||||
if (field.FieldType.EType != ElementType.U8)
|
||||
if (field.FieldType.GetElementType() != ElementType.U8)
|
||||
continue;
|
||||
|
||||
@base = (ulong)(long)ldci8.Operand;
|
||||
|
@ -279,19 +278,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool isDecryptMethod_v17_r73404(MethodDefinition method) {
|
||||
static bool isDecryptMethod_v17_r73404(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
if (instrs.Count < 4)
|
||||
return false;
|
||||
if (!DotNetUtils.isLdarg(instrs[0]))
|
||||
if (!instrs[0].IsLdarg())
|
||||
return false;
|
||||
if (!isCallorNewobj(instrs[1]) && !isCallorNewobj(instrs[2]))
|
||||
return false;
|
||||
var stloc = instrs[3];
|
||||
if (!DotNetUtils.isStloc(stloc))
|
||||
if (!stloc.IsStloc())
|
||||
return false;
|
||||
var local = DotNetUtils.getLocalVar(method.Body.Variables, stloc);
|
||||
if (local == null || local.VariableType.FullName != "System.IO.BinaryReader")
|
||||
var local = stloc.GetLocal(method.Body.LocalList);
|
||||
if (local == null || local.Type.FullName != "System.IO.BinaryReader")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -301,7 +300,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Newobj;
|
||||
}
|
||||
|
||||
static MethodDefinition findAssemblyResolverMethod(TypeDefinition type) {
|
||||
static MethodDef findAssemblyResolverMethod(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
|
@ -313,68 +312,68 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool findKey0_v14_r58564(MethodDefinition method, out uint key) {
|
||||
static bool findKey0_v14_r58564(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
var ldci4 = instrs[i + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0_v14_r58852(MethodDefinition method, out uint key) {
|
||||
static bool findKey0_v14_r58852(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_1))
|
||||
if (!ldci4_1.IsLdcI4())
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 1]))
|
||||
if (!instrs[i + 1].IsStloc())
|
||||
continue;
|
||||
var ldci4_2 = instrs[i + 2];
|
||||
if (!DotNetUtils.isLdcI4(ldci4_2) && DotNetUtils.getLdcI4Value(ldci4_2) != 0)
|
||||
if (!ldci4_2.IsLdcI4() && ldci4_2.GetLdcI4Value() != 0)
|
||||
continue;
|
||||
if (!DotNetUtils.isStloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsStloc())
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4_1);
|
||||
key = (uint)ldci4_1.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool findKey1(MethodDefinition method, out uint key) {
|
||||
static bool findKey1(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Ldelem_U1)
|
||||
continue;
|
||||
var ldci4 = instrs[i + 1];
|
||||
if (!DotNetUtils.isLdcI4(ldci4))
|
||||
if (!ldci4.IsLdcI4())
|
||||
continue;
|
||||
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
if (!DotNetUtils.isLdloc(instrs[i + 3]))
|
||||
if (!instrs[i + 3].IsLdloc())
|
||||
continue;
|
||||
if (instrs[i + 4].OpCode.Code != Code.Xor)
|
||||
continue;
|
||||
|
||||
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
|
||||
key = (uint)ldci4.GetLdcI4Value();
|
||||
return true;
|
||||
}
|
||||
key = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
EmbeddedResource findResource(MethodDefinition method) {
|
||||
EmbeddedResource findResource(MethodDef method) {
|
||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||
}
|
||||
|
||||
|
@ -382,7 +381,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
"System.Byte[]",
|
||||
"System.IO.Compression.DeflateStream",
|
||||
};
|
||||
static MethodDefinition findDecryptMethod_inflate(TypeDefinition type) {
|
||||
static MethodDef findDecryptMethod_inflate(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
|
@ -403,7 +402,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
"System.Security.Cryptography.CryptoStream",
|
||||
"System.Security.Cryptography.RijndaelManaged",
|
||||
};
|
||||
static MethodDefinition findDecryptMethod_7zip(TypeDefinition type) {
|
||||
static MethodDef findDecryptMethod_7zip(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
|
@ -427,12 +426,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
info.extension = DeobUtils.getExtension(module.Kind);
|
||||
info.kind = module.Kind;
|
||||
|
||||
var realAsm = new AssemblyDefinition { Name = asm.Name };
|
||||
var realAsm = module.UpdateRowId(new AssemblyDefUser(asm.Name, new Version(0, 0, 0, 0)));
|
||||
info.realAssemblyInfo = new RealAssemblyInfo(realAsm, entryPointToken, info.kind);
|
||||
if (module.Name != "Stub.exe")
|
||||
info.realAssemblyInfo.moduleName = module.Name;
|
||||
info.asmFullName = realAsm.Name.FullName;
|
||||
info.asmSimpleName = realAsm.Name.Name;
|
||||
info.realAssemblyInfo.moduleName = module.Name.String;
|
||||
info.asmFullName = realAsm.FullName;
|
||||
info.asmSimpleName = realAsm.Name.String;
|
||||
}
|
||||
|
||||
return info;
|
||||
|
@ -454,8 +453,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
static EmbeddedAssemblyInfo createEmbeddedAssemblyInfo(EmbeddedResource resource, byte[] data) {
|
||||
var mod = ModuleDefinition.ReadModule(new MemoryStream(data));
|
||||
var asmFullName = mod.Assembly != null ? mod.Assembly.Name.FullName : mod.Name;
|
||||
var mod = ModuleDefMD.Load(data);
|
||||
var asmFullName = mod.Assembly != null ? mod.Assembly.FullName : mod.Name.String;
|
||||
return new EmbeddedAssemblyInfo(resource, data, asmFullName, mod.Kind);
|
||||
}
|
||||
|
||||
|
|
2
dot10
2
dot10
|
@ -1 +1 @@
|
|||
Subproject commit 2bad4b5692ecbb412e679bf1c01a4313d32b8856
|
||||
Subproject commit 9efe77cebda9b8d3b667fa6404c2805036b967cd
|
Loading…
Reference in New Issue
Block a user