Port DeepSea deobfuscator

This commit is contained in:
de4dot 2012-11-09 00:21:45 +01:00
parent 5d25a499aa
commit 3b740a4106
14 changed files with 201 additions and 202 deletions

View File

@ -552,8 +552,9 @@ namespace de4dot.blocks {
newGp.GenericParamConstraints.Add(new GenericParamConstraintUser(gpc.Constraint));
newMethod.GenericParams.Add(newGp);
}
newMethod.Body = new CilBody();
copyBodyFromTo(method, newMethod);
return method;
return newMethod;
}
#if PORT
@ -1303,7 +1304,6 @@ namespace de4dot.blocks {
return false;
}
#if PORT
public static IList<Instruction> getArgPushes(IList<Instruction> instrs, int index) {
return getArgPushes(instrs, ref index);
}
@ -1313,7 +1313,7 @@ namespace de4dot.blocks {
return null;
var startInstr = instrs[index];
int pushes, pops;
calculateStackUsage(startInstr, false, out pushes, out pops);
startInstr.CalculateStackUsage(false, out pushes, out pops);
index--;
int numArgs = pops;
@ -1321,7 +1321,7 @@ namespace de4dot.blocks {
int stackSize = numArgs;
while (index >= 0 && args.Count != numArgs) {
var instr = instrs[index--];
calculateStackUsage(instr, false, out pushes, out pops);
instr.CalculateStackUsage(false, out pushes, out pops);
if (instr.OpCode.Code == Code.Dup) {
args.Add(instr);
stackSize--;
@ -1349,6 +1349,7 @@ namespace de4dot.blocks {
return args;
}
#if PORT
public static AssemblyNameReference addAssemblyReference(ModuleDefinition module, AssemblyNameReference asmRef) {
foreach (var modAsmRef in module.AssemblyReferences) {
if (modAsmRef.FullName == asmRef.FullName)

View File

@ -135,19 +135,19 @@
<Compile Include="deobfuscators\CryptoObfuscator\ResourceResolver.cs" />
<Compile Include="deobfuscators\CryptoObfuscator\StringDecrypter.cs" />
<Compile Include="deobfuscators\CryptoObfuscator\TamperDetection.cs" />
<None Include="deobfuscators\DeepSea\ArrayBlockDeobfuscator.cs" />
<None Include="deobfuscators\DeepSea\ArrayBlockState.cs" />
<None Include="deobfuscators\DeepSea\AssemblyResolver.cs" />
<None Include="deobfuscators\DeepSea\CastDeobfuscator.cs" />
<None Include="deobfuscators\DeepSea\Deobfuscator.cs" />
<None Include="deobfuscators\DeepSea\DsConstantsReader.cs" />
<None Include="deobfuscators\DeepSea\DsInlinedMethodsFinder.cs" />
<None Include="deobfuscators\DeepSea\DsMethodCallInliner.cs" />
<None Include="deobfuscators\DeepSea\DsUtils.cs" />
<None Include="deobfuscators\DeepSea\FieldsRestorer.cs" />
<None Include="deobfuscators\DeepSea\ResolverBase.cs" />
<None Include="deobfuscators\DeepSea\ResourceResolver.cs" />
<None Include="deobfuscators\DeepSea\StringDecrypter.cs" />
<Compile Include="deobfuscators\DeepSea\ArrayBlockDeobfuscator.cs" />
<Compile Include="deobfuscators\DeepSea\ArrayBlockState.cs" />
<Compile Include="deobfuscators\DeepSea\AssemblyResolver.cs" />
<Compile Include="deobfuscators\DeepSea\CastDeobfuscator.cs" />
<Compile Include="deobfuscators\DeepSea\Deobfuscator.cs" />
<Compile Include="deobfuscators\DeepSea\DsConstantsReader.cs" />
<Compile Include="deobfuscators\DeepSea\DsInlinedMethodsFinder.cs" />
<Compile Include="deobfuscators\DeepSea\DsMethodCallInliner.cs" />
<Compile Include="deobfuscators\DeepSea\DsUtils.cs" />
<Compile Include="deobfuscators\DeepSea\FieldsRestorer.cs" />
<Compile Include="deobfuscators\DeepSea\ResolverBase.cs" />
<Compile Include="deobfuscators\DeepSea\ResourceResolver.cs" />
<Compile Include="deobfuscators\DeepSea\StringDecrypter.cs" />
<Compile Include="deobfuscators\DeobfuscatorBase.cs" />
<Compile Include="deobfuscators\DeobfuscatorInfoBase.cs" />
<Compile Include="deobfuscators\DeobUtils.cs" />

View File

@ -26,7 +26,7 @@ using de4dot.blocks.cflow;
namespace de4dot.code.deobfuscators.DeepSea {
class ArrayBlockDeobfuscator : BlockDeobfuscator {
ArrayBlockState arrayBlockState;
Dictionary<VariableDefinition, ArrayBlockState.FieldInfo> localToInfo = new Dictionary<VariableDefinition, ArrayBlockState.FieldInfo>();
Dictionary<Local, ArrayBlockState.FieldInfo> localToInfo = new Dictionary<Local, ArrayBlockState.FieldInfo>();
DsConstantsReader constantsReader;
public ArrayBlockDeobfuscator(ArrayBlockState arrayBlockState) {
@ -51,10 +51,10 @@ namespace de4dot.code.deobfuscators.DeepSea {
if (!stloc.isStloc())
continue;
var info = arrayBlockState.getFieldInfo((FieldReference)ldsfld.Operand);
var info = arrayBlockState.getFieldInfo((IField)ldsfld.Operand);
if (info == null)
continue;
var local = DotNetUtils.getLocalVar(blocks.Locals, stloc.Instruction);
var local = stloc.Instruction.GetLocal(blocks.Locals);
if (local == null)
continue;
@ -99,7 +99,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var ldloc = instrs[i];
if (!ldloc.isLdloc())
return false;
var local = DotNetUtils.getLocalVar(blocks.Locals, ldloc.Instruction);
var local = ldloc.Instruction.GetLocal(blocks.Locals);
if (local == null)
return false;
ArrayBlockState.FieldInfo info;
@ -127,7 +127,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var ldsfld = instrs[i];
if (ldsfld.OpCode.Code != Code.Ldsfld)
return false;
var info = arrayBlockState.getFieldInfo(ldsfld.Operand as FieldReference);
var info = arrayBlockState.getFieldInfo(ldsfld.Operand as IField);
if (info == null)
return false;
@ -153,7 +153,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var ldsfld = instrs[i];
if (ldsfld.OpCode.Code != Code.Ldsfld)
return false;
var info = arrayBlockState.getFieldInfo(ldsfld.Operand as FieldReference);
var info = arrayBlockState.getFieldInfo(ldsfld.Operand as IField);
if (info == null)
return false;

View File

@ -20,12 +20,11 @@
using System.Collections.Generic;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Cecil.Metadata;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.DeepSea {
class ArrayBlockState {
ModuleDefinition module;
ModuleDefMD module;
FieldDefinitionAndDeclaringTypeDict<FieldInfo> fieldToInfo = new FieldDefinitionAndDeclaringTypeDict<FieldInfo>();
public class FieldInfo {
@ -44,7 +43,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
get { return fieldToInfo.Count != 0; }
}
public ArrayBlockState(ModuleDefinition module) {
public ArrayBlockState(ModuleDefMD module) {
this.module = module;
}
@ -65,22 +64,22 @@ namespace de4dot.code.deobfuscators.DeepSea {
var instructions = method.Body.Instructions;
for (int i = 0; i < instructions.Count; i++) {
var ldci4 = instructions[i];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
i++;
var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Newarr, OpCodes.Dup, OpCodes.Ldtoken, OpCodes.Call, OpCodes.Stsfld);
if (instrs == null)
continue;
var arrayType = instrs[0].Operand as TypeReference;
if (arrayType == null || arrayType.EType != ElementType.U1)
var arrayType = instrs[0].Operand as ITypeDefOrRef;
if (arrayType == null || (arrayType.FullName != "System.Byte" && !arrayType.DefinitionAssembly.IsCorLib()))
continue;
var arrayInitField = instrs[2].Operand as FieldDef;
if (arrayInitField == null || arrayInitField.InitialValue == null || arrayInitField.InitialValue.Length == 0)
continue;
var calledMethod = instrs[3].Operand as MethodReference;
var calledMethod = instrs[3].Operand as IMethod;
if (calledMethod == null || calledMethod.FullName != "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
continue;
@ -96,7 +95,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return foundField;
}
public FieldInfo getFieldInfo(FieldReference fieldRef) {
public FieldInfo getFieldInfo(IField fieldRef) {
if (fieldRef == null)
return null;
return fieldToInfo.find(fieldRef);
@ -118,7 +117,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
removedFields.Add(fieldInfo.arrayInitField);
}
fieldInfo.arrayInitField.InitialValue = new byte[1];
fieldInfo.arrayInitField.FieldType = module.TypeSystem.Byte;
fieldInfo.arrayInitField.FieldSig.Type = module.CorLibTypes.Byte;
}
IList<Instruction> allInstructions;
@ -148,7 +147,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var call = instrs[i + 4];
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.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
continue;
var stsfld = instrs[i + 5];
@ -174,7 +173,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
continue;
foreach (var instr in method.Body.Instructions) {
var field = instr.Operand as FieldReference;
var field = instr.Operand as IField;
if (field == null)
continue;
var fieldInfo = fieldToInfo.find(field);

View File

@ -75,7 +75,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
get { return decryptMethod; }
}
public AssemblyResolver(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob)
public AssemblyResolver(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob)
: base(module, simpleDeobfuscator, deob) {
}
@ -128,11 +128,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
static bool isV3SL(MethodDef handler) {
var instrs = handler.Body.Instructions;
for (int i = 0; i < instrs.Count - 3; i++) {
if (!DotNetUtils.isLdloc(instrs[i]))
if (!instrs[i].IsLdloc())
continue;
if (instrs[i + 1].OpCode.Code != Code.Add)
continue;
if (!DotNetUtils.isLdcI4(instrs[i + 2]))
if (!instrs[i + 2].IsLdcI4())
continue;
if (instrs[i + 3].OpCode.Code != Code.And)
continue;
@ -144,11 +144,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
static bool isV41SL(MethodDef handler) {
var instrs = handler.Body.Instructions;
for (int i = 0; i < instrs.Count; i++) {
if (!DotNetUtils.isLdcI4(instrs[i]) || DotNetUtils.getLdcI4Value(instrs[i]) != 5)
if (!instrs[i].IsLdcI4() || instrs[i].GetLdcI4Value() != 5)
continue;
if (instrs[i + 1].OpCode.Code != Code.And)
continue;
if (!DotNetUtils.isLdcI4(instrs[i + 2]) || DotNetUtils.getLdcI4Value(instrs[i + 2]) != 0x1F)
if (!instrs[i + 2].IsLdcI4() || instrs[i + 2].GetLdcI4Value() != 0x1F)
continue;
if (instrs[i + 3].OpCode.Code != Code.And)
continue;
@ -237,18 +237,18 @@ namespace de4dot.code.deobfuscators.DeepSea {
return false;
var ldci4_len = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4_len))
if (!ldci4_len.IsLdcI4())
return false;
if (DotNetUtils.getLdcI4Value(ldci4_len) != field.InitialValue.Length)
if (ldci4_len.GetLdcI4Value() != field.InitialValue.Length)
return false;
var ldci4_magic = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4_magic))
if (!ldci4_magic.IsLdcI4())
return false;
int magic = DotNetUtils.getLdcI4Value(ldci4_magic);
int magic = ldci4_magic.GetLdcI4Value();
var call = instrs[index++];
if (call.OpCode.Code == Code.Tail)
if (call.OpCode.Code == Code.Tailcall)
call = instrs[index++];
if (call.OpCode.Code != Code.Call)
return false;
@ -274,13 +274,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
int index = i;
var ldci4_len = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4_len))
if (!ldci4_len.IsLdcI4())
continue;
if (instrs[index++].OpCode.Code != Code.Newarr)
continue;
if (!DotNetUtils.isStloc(instrs[index++]))
if (!instrs[index++].IsStloc())
continue;
if (!DotNetUtils.isLdloc(instrs[index++]))
if (!instrs[index++].IsLdloc())
continue;
var ldtoken = instrs[index++];
@ -293,7 +293,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var call1 = instrs[index++];
if (call1.OpCode.Code != Code.Call)
continue;
if (!DotNetUtils.isMethod(call1.Operand as MethodReference, "System.Void", "(System.Array,System.RuntimeFieldHandle)"))
if (!DotNetUtils.isMethod(call1.Operand as IMethod, "System.Void", "(System.Array,System.RuntimeFieldHandle)"))
continue;
int callIndex = getCallDecryptMethodIndex(instrs, index);
@ -351,19 +351,19 @@ namespace de4dot.code.deobfuscators.DeepSea {
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 ldarg = instrs[index++];
if (!DotNetUtils.isLdarg(ldarg))
if (!ldarg.IsLdarg())
continue;
if (instrs[index++].OpCode.Code != Code.Add)
continue;
var ldci4 = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
if (DotNetUtils.getLdcI4Value(ldci4) != 0xFF)
if (ldci4.GetLdcI4Value() != 0xFF)
continue;
return DotNetUtils.getArgIndex(ldarg);
return ldarg.GetParameterIndex();
}
return -1;
}
@ -375,16 +375,16 @@ namespace de4dot.code.deobfuscators.DeepSea {
if (instrs[index++].OpCode.Code != Code.Div)
continue;
var ldarg = instrs[index++];
if (!DotNetUtils.isLdarg(ldarg))
if (!ldarg.IsLdarg())
continue;
if (instrs[index++].OpCode.Code != Code.Add)
continue;
var ldci4 = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
if (DotNetUtils.getLdcI4Value(ldci4) != 0xFF)
if (ldci4.GetLdcI4Value() != 0xFF)
continue;
return DotNetUtils.getArgIndex(ldarg);
return ldarg.GetParameterIndex();
}
return -1;
}
@ -399,8 +399,8 @@ namespace de4dot.code.deobfuscators.DeepSea {
break;
if (instr.OpCode.Code != Code.Call)
continue;
var calledMethod = instr.Operand as MethodReference;
if (calledMethod == null || calledMethod.Parameters.Count < 2)
var calledMethod = instr.Operand as IMethod;
if (calledMethod == null || calledMethod.MethodSig.GetParamCount() < 2)
continue;
return i;
@ -457,7 +457,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var resource = tmp as EmbeddedResource;
if (resource == null)
continue;
if (!Regex.IsMatch(resource.Name, @"^[0-9A-F]{40}$"))
if (!Regex.IsMatch(resource.Name.String, @"^[0-9A-F]{40}$"))
continue;
var info = getAssemblyInfo(resource, decrypter);
if (info == null)
@ -479,9 +479,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
AssemblyInfo getAssemblyInfo(byte[] decryptedData, EmbeddedResource resource) {
var asm = AssemblyDefinition.ReadAssembly(new MemoryStream(decryptedData));
var fullName = asm.Name.FullName;
var simpleName = asm.Name.Name;
var asm = AssemblyDef.Load(decryptedData);
var fullName = asm.FullName;
var simpleName = asm.Name.String;
var extension = DeobUtils.getExtension(asm.Modules[0].Kind);
return new AssemblyInfo(decryptedData, fullName, simpleName, extension, resource);
}
@ -496,7 +496,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var decrypted = decrypter(fieldInfo.field.InitialValue, fieldInfo.magic);
infos.Add(getAssemblyInfo(decrypted, null));
fieldInfo.field.InitialValue = new byte[1];
fieldInfo.field.FieldType = module.TypeSystem.Byte;
fieldInfo.field.FieldSig.Type = module.CorLibTypes.Byte;
}
return infos;

View File

@ -27,14 +27,14 @@ using dot10.DotNet.Emit;
namespace de4dot.code.deobfuscators.DeepSea {
class CastDeobfuscator : IBlocksDeobfuscator {
Blocks blocks;
Dictionary<VariableDefinition, LocalInfo> localInfos = new Dictionary<VariableDefinition, LocalInfo>();
Dictionary<Local, LocalInfo> localInfos = new Dictionary<Local, LocalInfo>();
class LocalInfo {
public readonly VariableDefinition local;
TypeReference type;
public readonly Local local;
ITypeDefOrRef type;
bool isValid;
public TypeReference CastType {
public ITypeDefOrRef CastType {
get { return type; }
set {
if (!isValid)
@ -45,7 +45,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return;
}
if (type != null && !MemberReferenceHelper.compareTypes(type, value)) {
if (type != null && !new SigComparer().Equals(type, value)) {
invalid();
return;
}
@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
}
public LocalInfo(VariableDefinition local) {
public LocalInfo(Local local) {
this.local = local;
this.isValid = true;
}
@ -92,13 +92,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
for (int i = 0; i < instrs.Count - 1; i++) {
var instr = instrs[i];
if (instr.OpCode.Code == Code.Ldloca || instr.OpCode.Code == Code.Ldloca_S) {
var local = instr.Operand as VariableDefinition;
var local = instr.Operand as Local;
if (local == null)
continue;
localInfos[local].invalid();
}
else if (instr.isLdloc()) {
var local = DotNetUtils.getLocalVar(blocks.Locals, instr.Instruction);
var local = instr.Instruction.GetLocal(blocks.Locals);
if (local == null)
continue;
var localInfo = localInfos[local];
@ -120,7 +120,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
foreach (var info in localInfos.Values) {
if (info.CastType == null)
continue;
info.local.VariableType = info.CastType;
info.local.Type = info.CastType.ToTypeSig();
}
if (changed) {
@ -137,18 +137,18 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
if (instr.isLdarg())
addCast(block, castIndex, i + 1, DotNetUtils.getArgType(blocks.Method, instr.Instruction));
addCast(block, castIndex, i + 1, instr.Instruction.GetArgumentType(blocks.Method.MethodSig, blocks.Method.DeclaringType));
else if (instr.OpCode.Code == Code.Ldfld || instr.OpCode.Code == Code.Ldsfld) {
var field = instr.Operand as FieldReference;
var field = instr.Operand as IField;
if (field == null)
continue;
addCast(block, castIndex, i + 1, field.FieldType);
addCast(block, castIndex, i + 1, field.FieldSig.GetFieldType());
}
else if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) {
var calledMethod = instr.Operand as MethodReference;
var calledMethod = instr.Operand as IMethod;
if (calledMethod == null || !DotNetUtils.hasReturnValue(calledMethod))
continue;
addCast(block, castIndex, i + 1, calledMethod.MethodReturnType.ReturnType);
addCast(block, castIndex, i + 1, calledMethod.MethodSig.GetRetType());
}
}
}
@ -157,7 +157,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return changed;
}
bool addCast(Block block, int castIndex, int index, TypeReference type) {
bool addCast(Block block, int castIndex, int index, TypeSig type) {
if (type == null)
return false;
if (castIndex >= block.Instructions.Count || index >= block.Instructions.Count)
@ -165,14 +165,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
var stloc = block.Instructions[index];
if (!stloc.isStloc())
return false;
var local = DotNetUtils.getLocalVar(blocks.Locals, stloc.Instruction);
var local = stloc.Instruction.GetLocal(blocks.Locals);
if (local == null)
return false;
var localInfo = localInfos[local];
if (localInfo.CastType == null)
return false;
if (!MemberReferenceHelper.compareTypes(localInfo.CastType, type))
if (!new SigComparer().Equals(localInfo.CastType, type))
block.insert(castIndex, new Instruction(OpCodes.Castclass, localInfo.CastType));
return true;
}
@ -190,7 +190,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var ldloc = instrs[i];
if (!ldloc.isLdloc())
continue;
var local = DotNetUtils.getLocalVar(blocks.Locals, ldloc.Instruction);
var local = ldloc.Instruction.GetLocal(blocks.Locals);
if (local == null)
continue;
var localInfo = localInfos[local];
@ -204,10 +204,10 @@ namespace de4dot.code.deobfuscators.DeepSea {
return instr.OpCode.Code == Code.Castclass || instr.OpCode.Code == Code.Isinst;
}
static TypeReference getCastType(Instr instr) {
static ITypeDefOrRef getCastType(Instr instr) {
if (!isCast(instr))
return null;
return instr.Operand as TypeReference;
return instr.Operand as ITypeDefOrRef;
}
}
}

View File

@ -22,7 +22,7 @@ using dot10.DotNet;
namespace de4dot.code.deobfuscators.DeepSea {
static class DsInlinedMethodsFinder {
public static List<MethodDef> find(ModuleDefinition module, IEnumerable<MethodDef> notInlinedMethods) {
public static List<MethodDef> find(ModuleDefMD module, IEnumerable<MethodDef> notInlinedMethods) {
var notInlinedMethodsDict = new Dictionary<MethodDef, bool>();
foreach (var method in notInlinedMethods)
notInlinedMethodsDict[method] = true;

View File

@ -20,15 +20,14 @@
using System.Collections.Generic;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Cecil.Metadata;
using de4dot.blocks;
using de4dot.blocks.cflow;
namespace de4dot.code.deobfuscators.DeepSea {
class DsMethodCallInliner : MethodCallInlinerBase {
InstructionEmulator instructionEmulator = new InstructionEmulator();
List<ParameterDefinition> parameters;
ParameterDefinition arg1, arg2;
IList<Parameter> parameters;
Parameter arg1, arg2;
Value returnValue;
MethodDef methodToInline;
CachedCflowDeobfuscator cflowDeobfuscator;
@ -73,14 +72,16 @@ namespace de4dot.code.deobfuscators.DeepSea {
bool inlineMethod(MethodDef methodToInline, int instrIndex, int const1, int const2) {
this.methodToInline = methodToInline = cflowDeobfuscator.deobfuscate(methodToInline);
parameters = DotNetUtils.getParameters(methodToInline);
parameters = methodToInline.Parameters;
arg1 = parameters[parameters.Count - 2];
arg2 = parameters[parameters.Count - 1];
returnValue = null;
instructionEmulator.init(methodToInline);
foreach (var arg in parameters) {
if (arg.ParameterType.EType >= ElementType.Boolean && arg.ParameterType.EType <= ElementType.U4)
if (!arg.IsNormalMethodParameter)
continue;
if (arg.Type.ElementType >= ElementType.Boolean && arg.Type.ElementType <= ElementType.U4)
instructionEmulator.setArg(arg, new Int32Value(0));
}
instructionEmulator.setArg(arg1, new Int32Value(const1));
@ -157,7 +158,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
case Code.Ldarg_1:
case Code.Ldarg_2:
case Code.Ldarg_3:
var arg = DotNetUtils.getParameter(parameters, instr);
var arg = instr.GetParameter(parameters);
if (arg != arg1 && arg != arg2) {
if (!allowUnknownArgs)
goto done;
@ -269,7 +270,7 @@ done:
bool emulateToReturn(int index, Instruction lastInstr) {
int pushes, pops;
DotNetUtils.calculateStackUsage(lastInstr, false, out pushes, out pops);
lastInstr.CalculateStackUsage(false, out pushes, out pops);
for (int i = 0; i < pops; i++)
instructionEmulator.pop();
@ -297,22 +298,22 @@ done:
public static bool canInline(MethodDef method) {
if (method == null || method.Body == null)
return false;
if (method.Attributes != (MethodAttributes.Assembly | MethodAttributes.Static))
if (method.Flags != (MethodAttributes.Assembly | MethodAttributes.Static))
return false;
if (method.GenericParameters.Count > 0)
if (method.GenericParams.Count > 0)
return false;
if (method.Body.ExceptionHandlers.Count > 0)
return false;
var parameters = method.Parameters;
var parameters = method.MethodSig.GetParams();
int paramCount = parameters.Count;
if (paramCount < 2)
return false;
var param1 = parameters[paramCount - 1];
var param2 = parameters[paramCount - 2];
if (!isIntType(param1.ParameterType.EType))
if (!isIntType(param1.ElementType))
return false;
if (!isIntType(param2.ParameterType.EType))
if (!isIntType(param2.ElementType))
return false;
return true;

View File

@ -21,13 +21,12 @@ using System;
using System.Collections.Generic;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Cecil.Metadata;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.DeepSea {
// DS 4.x can move fields from a class to a struct. This class restores the fields.
class FieldsRestorer {
ModuleDefinition module;
ModuleDefMD module;
TypeDefinitionDict<List<TypeDef>> structToOwners = new TypeDefinitionDict<List<TypeDef>>();
FieldDefinitionAndDeclaringTypeDict<bool> structFieldsToFix = new FieldDefinitionAndDeclaringTypeDict<bool>();
TypeDefinitionDict<FieldDefinitionAndDeclaringTypeDict<FieldDef>> typeToFieldsDict = new TypeDefinitionDict<FieldDefinitionAndDeclaringTypeDict<FieldDef>>();
@ -50,17 +49,17 @@ namespace de4dot.code.deobfuscators.DeepSea {
return true;
if (type.BaseType == null)
return false;
if (type.BaseType.EType != ElementType.Object)
if (type.BaseType.FullName != "System.Object")
return false;
if (type.Methods.Count != 1)
return false;
var ctor = type.Methods[0];
if (ctor.Name != ".ctor" || ctor.Parameters.Count != 0)
if (ctor.Name != ".ctor" || ctor.MethodSig.GetParamCount() != 0)
return false;
return true;
}
public FieldsRestorer(ModuleDefinition module) {
public FieldsRestorer(ModuleDefMD module) {
this.module = module;
}
@ -71,7 +70,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
foreach (var ownerType in kv.Value) {
foreach (var ownerField in ownerType.Fields) {
if (DotNetUtils.getType(module, ownerField.FieldType) != structType)
if (DotNetUtils.getType(module, ownerField.FieldSig.GetFieldType()) != structType)
continue;
structFieldsToFix.add(ownerField, true);
break;
@ -80,7 +79,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var fieldsDict = new FieldDefinitionAndDeclaringTypeDict<FieldDef>();
typeToFieldsDict.add(ownerType, fieldsDict);
foreach (var structField in structType.Fields) {
var newField = DotNetUtils.createFieldDefinition(structField.Name, structField.Attributes, structField.FieldType);
var newField = module.UpdateRowId(new FieldDefUser(structField.Name, structField.FieldSig.Clone(), structField.Flags));
ownerType.Fields.Add(newField);
fieldsDict.add(structField, newField);
}
@ -93,16 +92,16 @@ namespace de4dot.code.deobfuscators.DeepSea {
var typeToStruct = new Dictionary<TypeDef, TypeDef>();
foreach (var type in module.GetTypes()) {
foreach (var field in getPossibleFields(type)) {
var fieldType = DotNetUtils.getType(module, field.FieldType);
var fieldType = DotNetUtils.getType(module, field.FieldSig.GetFieldType());
if (fieldType == null)
continue;
if (!checkBaseType(fieldType))
continue;
if ((fieldType.Attributes & ~TypeAttributes.Sealed) != TypeAttributes.NestedAssembly)
if ((fieldType.Flags & ~TypeAttributes.Sealed) != TypeAttributes.NestedAssembly)
continue;
if (fieldType.NestedTypes.Count > 0)
continue;
if (fieldType.GenericParameters.Count > 0)
if (fieldType.GenericParams.Count > 0)
continue;
if (fieldType.Fields.Count == 0)
continue;
@ -127,16 +126,16 @@ namespace de4dot.code.deobfuscators.DeepSea {
typeToStruct.TryGetValue(type, out structType);
foreach (var field in type.Fields) {
if (field.IsStatic || field.FieldType != structType)
removeType(candidates, field.FieldType);
if (field.IsStatic || field.FieldSig.GetFieldType().TryGetTypeDef() != structType)
removeType(candidates, field.FieldSig.GetFieldType());
}
foreach (var method in type.Methods) {
removeType(candidates, method.MethodReturnType.ReturnType);
foreach (var parameter in method.Parameters)
removeType(candidates, parameter.ParameterType);
removeType(candidates, method.MethodSig.GetRetType());
foreach (var parameter in method.MethodSig.GetParams())
removeType(candidates, parameter);
if (method.Body != null) {
foreach (var local in method.Body.Variables)
removeType(candidates, local.VariableType);
foreach (var local in method.Body.LocalList)
removeType(candidates, local.Type);
}
}
}
@ -147,9 +146,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
IEnumerable<FieldDef> getPossibleFields(TypeDef type) {
var typeToFields = new TypeDefinitionDict<List<FieldDef>>();
foreach (var field in type.Fields) {
if (field.Attributes != FieldAttributes.Private)
if (field.Flags != FieldAttributes.Private)
continue;
var fieldType = DotNetUtils.getType(module, field.FieldType);
var fieldType = DotNetUtils.getType(module, field.FieldSig.GetFieldType());
if (fieldType == null)
continue;
if (!checkBaseType(fieldType))
@ -169,10 +168,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
static bool checkBaseType(TypeDef type) {
if (type == null || type.BaseType == null)
return false;
return type.BaseType.FullName == "System.ValueType" || type.BaseType.EType == ElementType.Object;
var fn = type.BaseType.FullName;
return fn == "System.ValueType" || fn == "System.Object";
}
void removeType(Dictionary<TypeDef, List<TypeDef>> candidates, TypeReference type) {
void removeType(Dictionary<TypeDef, List<TypeDef>> candidates, TypeSig type) {
var typeDef = DotNetUtils.getType(module, type);
if (typeDef == null)
return;
@ -183,15 +183,15 @@ namespace de4dot.code.deobfuscators.DeepSea {
foreach (var method in type.Methods) {
if (method.Name == ".cctor")
continue;
if (type.BaseType != null && type.BaseType.EType == ElementType.Object && method.Name == ".ctor" && method.Parameters.Count == 0)
if (type.BaseType != null && type.BaseType.FullName == "System.Object" && method.Name == ".ctor" && method.MethodSig.GetParamCount() == 0)
continue;
if (!method.IsStatic)
return true;
if (method.GenericParameters.Count > 0)
if (method.GenericParams.Count > 0)
return true;
if (method.Body == null)
return true;
if (method.HasPInvokeInfo || method.PInvokeInfo != null)
if (method.ImplMap != null)
return true;
}
return false;
@ -223,12 +223,12 @@ namespace de4dot.code.deobfuscators.DeepSea {
var instr = instrs[i];
if (instr.OpCode.Code != Code.Ldflda && instr.OpCode.Code != Code.Ldfld)
continue;
var structField = instr.Operand as FieldReference;
var structField = instr.Operand as IField;
if (structField == null || !structFieldsToFix.find(structField))
continue;
var ldStFld = instrs[findLdStFieldIndex(instrs, i + 1)];
ldStFld.Operand = getNewField(structField, ldStFld.Operand as FieldReference);
ldStFld.Operand = getNewField(structField, ldStFld.Operand as IField);
instrsToRemove.Add(i);
}
if (instrsToRemove.Count > 0)
@ -246,7 +246,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var stfld = instrs[i];
if (stfld.OpCode.Code != Code.Stfld)
continue;
var field = stfld.Operand as FieldReference;
var field = stfld.Operand as IField;
if (field == null)
continue;
if (!structFieldsToFix.find(field))
@ -270,7 +270,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return newInstrs;
}
FieldDef getNewField(FieldReference structField, FieldReference oldFieldRef) {
FieldDef getNewField(IField structField, IField oldFieldRef) {
var fieldsDict = typeToFieldsDict.find(structField.DeclaringType);
if (fieldsDict == null)
throw new ApplicationException("Could not find structField declaringType");
@ -291,7 +291,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return i;
int pushes, pops;
DotNetUtils.calculateStackUsage(instr.Instruction, false, out pushes, out pops);
instr.Instruction.CalculateStackUsage(false, out pushes, out pops);
stack -= pops;
if (stack < 0)
break;

View File

@ -25,7 +25,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.DeepSea {
abstract class ResolverBase {
protected ModuleDefinition module;
protected ModuleDefMD module;
protected ISimpleDeobfuscator simpleDeobfuscator;
protected IDeobfuscator deob;
protected MethodDef initMethod;
@ -44,7 +44,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
get { return initMethod != null; }
}
public ResolverBase(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
public ResolverBase(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
this.module = module;
this.frameworkType = DotNetUtils.getFrameworkType(module);
this.simpleDeobfuscator = simpleDeobfuscator;

View File

@ -83,7 +83,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
get { return data30 != null ? data30.resource : null; }
}
public ResourceResolver(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob)
public ResourceResolver(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob)
: base(module, simpleDeobfuscator, deob) {
}
@ -145,7 +145,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
magicArgIndex = getMagicArgIndex41Trial(info.handler);
data41.isTrial = true;
}
var asmVer = module.Assembly.Name.Version;
var asmVer = module.Assembly.Version;
if (magicArgIndex < 0 || magicArgIndex >= info.args.Count)
return false;
var val = info.args[magicArgIndex];
@ -165,16 +165,16 @@ namespace de4dot.code.deobfuscators.DeepSea {
if (add.OpCode.Code != Code.Add)
continue;
var ldarg = instrs[i + 1];
if (!DotNetUtils.isLdarg(ldarg))
if (!ldarg.IsLdarg())
continue;
var sub = instrs[i + 2];
if (sub.OpCode.Code != Code.Sub)
continue;
var ldci4 = instrs[i + 3];
if (!DotNetUtils.isLdcI4(ldci4) || DotNetUtils.getLdcI4Value(ldci4) != 0xFF)
if (!ldci4.IsLdcI4() || ldci4.GetLdcI4Value() != 0xFF)
continue;
return DotNetUtils.getArgIndex(ldarg);
return ldarg.GetParameterIndex();
}
return -1;
}
@ -183,14 +183,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) {
var ldarg = instrs[i];
if (!DotNetUtils.isLdarg(ldarg))
if (!ldarg.IsLdarg())
continue;
if (!DotNetUtils.isLdcI4(instrs[i + 1]))
if (!instrs[i + 1].IsLdcI4())
continue;
if (instrs[i + 2].OpCode.Code != Code.Shr)
continue;
return DotNetUtils.getArgIndex(ldarg);
return ldarg.GetParameterIndex();
}
return -1;
}
@ -255,21 +255,21 @@ namespace de4dot.code.deobfuscators.DeepSea {
continue;
var ldci4_len = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4_len))
if (!ldci4_len.IsLdcI4())
continue;
if (DotNetUtils.getLdcI4Value(ldci4_len) != field.InitialValue.Length)
if (ldci4_len.GetLdcI4Value() != field.InitialValue.Length)
continue;
if (instrs[index++].OpCode.Code != Code.Ldstr)
continue;
var ldci4_magic = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4_magic))
if (!ldci4_magic.IsLdcI4())
continue;
data40.magic = DotNetUtils.getLdcI4Value(ldci4_magic);
data40.magic = ldci4_magic.GetLdcI4Value();
var call = instrs[index++];
if (call.OpCode.Code == Code.Tail)
if (call.OpCode.Code == Code.Tailcall)
call = instrs[index++];
if (call.OpCode.Code != Code.Call)
continue;
@ -322,7 +322,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
if (data30.resource == null)
return false;
DeobUtils.decryptAndAddResources(module, data30.resource.Name, () => decryptResourceV3(data30.resource));
DeobUtils.decryptAndAddResources(module, data30.resource.Name.String, () => decryptResourceV3(data30.resource));
rsrc = data30.resource;
return true;
@ -341,10 +341,10 @@ namespace de4dot.code.deobfuscators.DeepSea {
if (resourceField == null)
return false;
string name = string.Format("Embedded data field {0:X8} RVA {1:X8}", resourceField.MDToken.ToInt32(), resourceField.RVA);
string name = string.Format("Embedded data field {0:X8} RVA {1:X8}", resourceField.MDToken.ToInt32(), (uint)resourceField.RVA);
DeobUtils.decryptAndAddResources(module, name, () => decryptResourceV4(resourceField.InitialValue, magic));
resourceField.InitialValue = new byte[1];
resourceField.FieldType = module.TypeSystem.Byte;
resourceField.FieldSig.Type = module.CorLibTypes.Byte;
return true;
}
}

View File

@ -22,12 +22,11 @@ using System.Collections.Generic;
using System.Text;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Cecil.Metadata;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.DeepSea {
class StringDecrypter {
ModuleDefinition module;
ModuleDefMD module;
MethodDefinitionAndDeclaringTypeDict<IDecrypterInfo> methodToInfo = new MethodDefinitionAndDeclaringTypeDict<IDecrypterInfo>();
DecrypterVersion version = DecrypterVersion.Unknown;
@ -55,7 +54,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var instrs = initMethod.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) {
var ldci4 = instrs[i];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
var newarr = instrs[i + 1];
if (newarr.OpCode.Code != Code.Newarr)
@ -64,13 +63,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
continue;
var stloc = instrs[i + 2];
if (!DotNetUtils.isStloc(stloc))
if (!stloc.IsStloc())
continue;
var local = DotNetUtils.getLocalVar(initMethod.Body.Variables, stloc);
var local = stloc.GetLocal(initMethod.Body.LocalList);
int startInitIndex = i;
i++;
var array = ArrayFinder.getInitializedInt16Array(DotNetUtils.getLdcI4Value(ldci4), initMethod, ref i);
var array = ArrayFinder.getInitializedInt16Array(ldci4.GetLdcI4Value(), initMethod, ref i);
if (array == null)
continue;
@ -84,13 +83,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
return null;
}
static FieldDef getStoreField(MethodDef method, int startIndex, VariableDefinition local) {
static FieldDef getStoreField(MethodDef method, int startIndex, Local local) {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) {
var ldloc = instrs[i];
if (!DotNetUtils.isLdloc(ldloc))
if (!ldloc.IsLdloc())
continue;
if (DotNetUtils.getLocalVar(method.Body.Variables, ldloc) != local)
if (ldloc.GetLocal(method.Body.LocalList) != local)
continue;
var stsfld = instrs[i + 1];
@ -110,16 +109,16 @@ namespace de4dot.code.deobfuscators.DeepSea {
static bool findMagic(MethodDef method, out int arg1, out int arg2, out int magic) {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 3; i++) {
if ((arg1 = DotNetUtils.getArgIndex(instrs[i])) < 0)
if ((arg1 = instrs[i].GetParameterIndex()) < 0)
continue;
var ldci4 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
if (instrs[i + 2].OpCode.Code != Code.Xor)
continue;
if ((arg2 = DotNetUtils.getArgIndex(instrs[i + 3])) < 0)
if ((arg2 = instrs[i + 3].GetParameterIndex()) < 0)
continue;
magic = DotNetUtils.getLdcI4Value(ldci4);
magic = ldci4.GetLdcI4Value();
return true;
}
arg1 = arg2 = 0;
@ -139,7 +138,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
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 (calledMethod.ToString() != "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
@ -163,11 +162,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
class ArrayInfo {
public int sizeInElems;
public TypeReference elementType;
public ITypeDefOrRef elementType;
public FieldDef initField;
public FieldDef field;
public ArrayInfo(int sizeInElems, TypeReference elementType, FieldDef initField, FieldDef field) {
public ArrayInfo(int sizeInElems, ITypeDefOrRef elementType, FieldDef initField, FieldDef field) {
this.sizeInElems = sizeInElems;
this.elementType = elementType;
this.initField = initField;
@ -197,11 +196,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
static bool checkMethodSignature(MethodDef method) {
if (method.MethodReturnType.ReturnType.EType != ElementType.String)
if (method.MethodSig.GetRetType().GetElementType() != ElementType.String)
return false;
int count = 0;
foreach (var arg in method.Parameters) {
if (arg.ParameterType.EType == ElementType.I4)
foreach (var arg in method.MethodSig.GetParams()) {
if (arg.ElementType == ElementType.I4)
count++;
}
return count >= 2;
@ -254,9 +253,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
int index = i;
var ldci4 = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
if (DotNetUtils.getLdcI4Value(ldci4) != 0xFF)
if (ldci4.GetLdcI4Value() != 0xFF)
continue;
if (instrs[index++].OpCode.Code != Code.And)
@ -265,13 +264,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
continue;
var ldci4_2 = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4_2))
if (!ldci4_2.IsLdcI4())
continue;
if (findNextFieldUse(method, index) < 0)
continue;
return DotNetUtils.getLdcI4Value(ldci4_2);
return ldci4_2.GetLdcI4Value();
}
return -1;
}
@ -282,7 +281,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
var instr = instrs[i];
if (instr.OpCode.Code != Code.Ldsfld && instr.OpCode.Code != Code.Stsfld)
continue;
var field = instr.Operand as FieldReference;
var field = instr.Operand as IField;
if (!fields.find(field))
return -1;
@ -295,15 +294,15 @@ namespace de4dot.code.deobfuscators.DeepSea {
var instructions = method.Body.Instructions;
for (int i = 0; i < instructions.Count; i++) {
var ldci4_arraySizeInBytes = instructions[i];
if (!DotNetUtils.isLdcI4(ldci4_arraySizeInBytes))
if (!ldci4_arraySizeInBytes.IsLdcI4())
continue;
i++;
var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Newarr, OpCodes.Dup, OpCodes.Ldtoken, OpCodes.Call, OpCodes.Stsfld);
if (instrs == null)
continue;
int sizeInBytes = DotNetUtils.getLdcI4Value(ldci4_arraySizeInBytes);
var elementType = instrs[0].Operand as TypeReference;
int sizeInBytes = ldci4_arraySizeInBytes.GetLdcI4Value();
var elementType = instrs[0].Operand as ITypeDefOrRef;
var initField = instrs[2].Operand as FieldDef;
var field = instrs[4].Operand as FieldDef;
if (elementType == null)
@ -319,11 +318,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
short[] findKey() {
if (cctor.Module.Assembly == null)
if (cctor.OwnerModule.Assembly == null)
return null;
var pkt = cctor.Module.Assembly.Name.PublicKeyToken;
if (pkt != null && pkt.Length > 0)
return getPublicKeyTokenKey(pkt);
var pkt = cctor.OwnerModule.Assembly.PublicKeyToken;
if (!PublicKeyBase.IsNullOrEmpty2(pkt))
return getPublicKeyTokenKey(pkt.Data);
return findKey(cctor);
}
@ -380,7 +379,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
public void cleanup() {
arrayInfo.initField.InitialValue = new byte[1];
arrayInfo.initField.FieldType = arrayInfo.initField.Module.TypeSystem.Byte;
arrayInfo.initField.FieldSig.Type = arrayInfo.initField.OwnerModule.CorLibTypes.Byte;
removeInitializeArrayCall(cctor, arrayInfo.initField);
}
}
@ -447,9 +446,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
var field = instr.Operand as FieldDef;
if (field == null)
continue;
if (!MemberReferenceHelper.compareTypes(Method.DeclaringType, field.DeclaringType))
if (!new SigComparer().Equals(Method.DeclaringType, field.DeclaringType))
continue;
switch (field.FieldType.FullName) {
switch (field.FieldSig.GetFieldType().GetFullName()) {
case "System.Char[]":
if (!charArrayFields.Contains(field))
charArrayFields.Add(field);
@ -493,20 +492,20 @@ namespace de4dot.code.deobfuscators.DeepSea {
return null;
}
static bool matches(IEnumerable<FieldDef> ourFields, FieldReference field) {
static bool matches(IEnumerable<FieldDef> ourFields, FieldDef field) {
foreach (var ourField in ourFields) {
if (MemberReferenceHelper.compareFieldReferenceAndDeclaringType(ourField, field))
if (FieldEqualityComparer.CompareDeclaringTypes.Equals(ourField, field))
return true;
}
return false;
}
short[] findKey() {
if (cctor.Module.Assembly == null)
if (cctor.OwnerModule.Assembly == null)
return null;
var pkt = cctor.Module.Assembly.Name.PublicKeyToken;
if (pkt != null && pkt.Length > 0)
return getPublicKeyTokenKey(pkt);
var pkt = cctor.OwnerModule.Assembly.PublicKeyToken;
if (!PublicKeyBase.IsNullOrEmpty2(pkt))
return getPublicKeyTokenKey(pkt.Data);
return findKey(cctor);
}
@ -539,7 +538,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
public void cleanup() {
encryptedDataField.InitialValue = new byte[1];
encryptedDataField.FieldType = encryptedDataField.Module.TypeSystem.Byte;
encryptedDataField.FieldSig.Type = encryptedDataField.OwnerModule.CorLibTypes.Byte;
removeInitializeArrayCall(cctor, encryptedDataField);
}
}
@ -605,9 +604,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
var field = instr.Operand as FieldDef;
if (field == null)
continue;
if (!MemberReferenceHelper.compareTypes(Method.DeclaringType, field.DeclaringType))
if (!new SigComparer().Equals(Method.DeclaringType, field.DeclaringType))
continue;
switch (field.FieldType.FullName) {
switch (field.FieldSig.GetFieldType().GetFullName()) {
case "System.Char[]":
if (keyField != null && keyField != field)
return false;
@ -629,11 +628,11 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
short[] findKey() {
if (cctor.Module.Assembly == null)
if (cctor.OwnerModule.Assembly == null)
return null;
var pkt = cctor.Module.Assembly.Name.PublicKeyToken;
if (pkt != null && pkt.Length > 0)
return getPublicKeyTokenKey(pkt);
var pkt = cctor.OwnerModule.Assembly.PublicKeyToken;
if (!PublicKeyBase.IsNullOrEmpty2(pkt))
return getPublicKeyTokenKey(pkt.Data);
return findKey(cctor);
}
@ -654,14 +653,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) {
var ldarg = instrs[i];
if (DotNetUtils.getArgIndex(ldarg) < 0)
if (ldarg.GetParameterIndex() < 0)
continue;
var ldci4 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
if (instrs[i + 2].OpCode.Code != Code.Xor)
continue;
magic = DotNetUtils.getLdcI4Value(ldci4);
magic = ldci4.GetLdcI4Value();
return true;
}
magic = 0;
@ -720,7 +719,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
}
public StringDecrypter(ModuleDefinition module) {
public StringDecrypter(ModuleDefMD module) {
this.module = module;
}
@ -728,9 +727,10 @@ namespace de4dot.code.deobfuscators.DeepSea {
if (module.Assembly == null)
return;
bool hasPublicKeyToken = module.Assembly.Name.PublicKeyToken != null && module.Assembly.Name.PublicKeyToken.Length != 0;
var pkt = module.Assembly.PublicKeyToken;
bool hasPublicKeyToken = !PublicKeyBase.IsNullOrEmpty2(pkt);
foreach (var type in module.GetTypes()) {
var cctor = DotNetUtils.getMethod(type, ".cctor");
var cctor = type.FindClassConstructor();
if (cctor == null)
continue;
@ -777,7 +777,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
foreach (var field in fields) {
if (foundCharAry && foundStringAry)
break;
switch (field.FieldType.FullName) {
switch (field.FieldSig.GetFieldType().GetFullName()) {
case "System.Char[]":
foundCharAry = true;
break;
@ -810,7 +810,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
return info;
}
public string decrypt(MethodReference method, object[] args) {
public string decrypt(IMethod method, object[] args) {
var info = methodToInfo.find(method);
return info.decrypt(args);
}

View File

@ -43,9 +43,7 @@ namespace de4dot.cui {
new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CryptoObfuscator.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.DeepSea.DeobfuscatorInfo(),
#endif
new de4dot.code.deobfuscators.Dotfuscator.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.dotNET_Reactor.v3.DeobfuscatorInfo(),

2
dot10

@ -1 +1 @@
Subproject commit ba1fa2135fec435ecee2ea041c9a7dae56e5dd47
Subproject commit acae785a75c91f9ddabbf6e78d831febcbef16b3