Port Spices.Net deobfuscator
This commit is contained in:
parent
445b68f4f5
commit
475c597a60
|
@ -250,11 +250,11 @@
|
||||||
<None Include="deobfuscators\SmartAssembly\StringDecrypterInfo.cs" />
|
<None Include="deobfuscators\SmartAssembly\StringDecrypterInfo.cs" />
|
||||||
<None Include="deobfuscators\SmartAssembly\StringEncoderClassFinder.cs" />
|
<None Include="deobfuscators\SmartAssembly\StringEncoderClassFinder.cs" />
|
||||||
<None Include="deobfuscators\SmartAssembly\TamperProtectionRemover.cs" />
|
<None Include="deobfuscators\SmartAssembly\TamperProtectionRemover.cs" />
|
||||||
<None Include="deobfuscators\Spices_Net\Deobfuscator.cs" />
|
<Compile Include="deobfuscators\Spices_Net\Deobfuscator.cs" />
|
||||||
<None Include="deobfuscators\Spices_Net\QclzDecompressor.cs" />
|
<Compile Include="deobfuscators\Spices_Net\QclzDecompressor.cs" />
|
||||||
<None Include="deobfuscators\Spices_Net\ResourceNamesRestorer.cs" />
|
<Compile Include="deobfuscators\Spices_Net\ResourceNamesRestorer.cs" />
|
||||||
<None Include="deobfuscators\Spices_Net\SpicesMethodCallInliner.cs" />
|
<Compile Include="deobfuscators\Spices_Net\SpicesMethodCallInliner.cs" />
|
||||||
<None Include="deobfuscators\Spices_Net\StringDecrypter.cs" />
|
<Compile Include="deobfuscators\Spices_Net\StringDecrypter.cs" />
|
||||||
<Compile Include="deobfuscators\StringCounts.cs" />
|
<Compile Include="deobfuscators\StringCounts.cs" />
|
||||||
<Compile Include="deobfuscators\TypesRestorer.cs" />
|
<Compile Include="deobfuscators\TypesRestorer.cs" />
|
||||||
<Compile Include="deobfuscators\Unknown\Deobfuscator.cs" />
|
<Compile Include="deobfuscators\Unknown\Deobfuscator.cs" />
|
||||||
|
|
|
@ -24,11 +24,11 @@ using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Spices_Net {
|
namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
class ResourceNamesRestorer {
|
class ResourceNamesRestorer {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
TypeDef resourceManagerType;
|
TypeDef resourceManagerType;
|
||||||
TypeDef componentResourceManagerType;
|
TypeDef componentResourceManagerType;
|
||||||
MethodDefinitionAndDeclaringTypeDict<MethodReference> resourceManagerCtors = new MethodDefinitionAndDeclaringTypeDict<MethodReference>();
|
MethodDefinitionAndDeclaringTypeDict<IMethod> resourceManagerCtors = new MethodDefinitionAndDeclaringTypeDict<IMethod>();
|
||||||
MethodDefinitionAndDeclaringTypeDict<MethodReference> componentManagerCtors = new MethodDefinitionAndDeclaringTypeDict<MethodReference>();
|
MethodDefinitionAndDeclaringTypeDict<IMethod> componentManagerCtors = new MethodDefinitionAndDeclaringTypeDict<IMethod>();
|
||||||
|
|
||||||
public TypeDef ResourceManagerType {
|
public TypeDef ResourceManagerType {
|
||||||
get { return resourceManagerType; }
|
get { return resourceManagerType; }
|
||||||
|
@ -38,7 +38,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
get { return componentResourceManagerType; }
|
get { return componentResourceManagerType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceNamesRestorer(ModuleDefinition module) {
|
public ResourceNamesRestorer(ModuleDefMD module) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
initializeCtors(componentResourceManagerType, componentManagerCtors);
|
initializeCtors(componentResourceManagerType, componentManagerCtors);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initializeCtors(TypeDef manager, MethodDefinitionAndDeclaringTypeDict<MethodReference> ctors) {
|
void initializeCtors(TypeDef manager, MethodDefinitionAndDeclaringTypeDict<IMethod> ctors) {
|
||||||
if (manager == null)
|
if (manager == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -62,10 +62,8 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
if (ctor.Name != ".ctor")
|
if (ctor.Name != ".ctor")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var newCtor = new MethodReference(ctor.Name, ctor.MethodReturnType.ReturnType, manager.BaseType);
|
var newCtor = new MemberRefUser(module, ctor.Name, ctor.MethodSig.Clone(), manager.BaseType);
|
||||||
newCtor.HasThis = true;
|
module.UpdateRowId(newCtor);
|
||||||
foreach (var param in ctor.Parameters)
|
|
||||||
newCtor.Parameters.Add(new ParameterDefinition(param.ParameterType));
|
|
||||||
ctors.add(ctor, newCtor);
|
ctors.add(ctor, newCtor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,9 +73,9 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
return false;
|
return false;
|
||||||
if (type.HasProperties || type.HasEvents || type.HasFields)
|
if (type.HasProperties || type.HasEvents || type.HasFields)
|
||||||
return false;
|
return false;
|
||||||
if (type.Interfaces.Count > 0)
|
if (type.InterfaceImpls.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
var method = DotNetUtils.getMethod(type, "GetResourceFileName");
|
var method = type.FindMethod("GetResourceFileName");
|
||||||
if (!DotNetUtils.isMethod(method, "System.String", "(System.Globalization.CultureInfo)"))
|
if (!DotNetUtils.isMethod(method, "System.String", "(System.Globalization.CultureInfo)"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -90,7 +88,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
|
|
||||||
var numToResource = new Dictionary<uint, Resource>(module.Resources.Count);
|
var numToResource = new Dictionary<uint, Resource>(module.Resources.Count);
|
||||||
foreach (var resource in module.Resources) {
|
foreach (var resource in module.Resources) {
|
||||||
var name = resource.Name;
|
var name = resource.Name.String;
|
||||||
int index = name.LastIndexOf('.');
|
int index = name.LastIndexOf('.');
|
||||||
string ext;
|
string ext;
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
|
@ -106,12 +104,12 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
foreach (var type in module.GetTypes()) {
|
foreach (var type in module.GetTypes()) {
|
||||||
rename(numToResource, "", type.FullName);
|
rename(numToResource, "", type.FullName);
|
||||||
rename(numToResource, "", type.FullName + ".g");
|
rename(numToResource, "", type.FullName + ".g");
|
||||||
rename(numToResource, type.Namespace, type.Name);
|
rename(numToResource, type.Namespace.String, type.Name.String);
|
||||||
rename(numToResource, type.Namespace, type.Name + ".g");
|
rename(numToResource, type.Namespace.String, type.Name.String + ".g");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module.Assembly != null)
|
if (module.Assembly != null)
|
||||||
rename(numToResource, "", module.Assembly.Name.Name + ".g");
|
rename(numToResource, "", module.Assembly.Name.String + ".g");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rename(Dictionary<uint, Resource> numToResource, string ns, string name) {
|
static void rename(Dictionary<uint, Resource> numToResource, string ns, string name) {
|
||||||
|
@ -121,14 +119,14 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
if (!numToResource.TryGetValue(hash, out resource))
|
if (!numToResource.TryGetValue(hash, out resource))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int index = resource.Name.LastIndexOf('.');
|
int index = resource.Name.String.LastIndexOf('.');
|
||||||
string resourceNamespace, newName;
|
string resourceNamespace, newName;
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
resourceNamespace = "";
|
resourceNamespace = "";
|
||||||
newName = resourceName;
|
newName = resourceName;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
resourceNamespace = resource.Name.Substring(0, index);
|
resourceNamespace = resource.Name.String.Substring(0, index);
|
||||||
newName = resourceNamespace + "." + resourceName;
|
newName = resourceNamespace + "." + resourceName;
|
||||||
}
|
}
|
||||||
if (resourceNamespace != ns)
|
if (resourceNamespace != ns)
|
||||||
|
@ -137,7 +135,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
Logger.v("Restoring resource name: '{0}' => '{1}'",
|
Logger.v("Restoring resource name: '{0}' => '{1}'",
|
||||||
Utils.removeNewlines(resource.Name),
|
Utils.removeNewlines(resource.Name),
|
||||||
Utils.removeNewlines(newName));
|
Utils.removeNewlines(newName));
|
||||||
resource.Name = newName;
|
resource.Name = new UTF8String(newName);
|
||||||
numToResource.Remove(hash);
|
numToResource.Remove(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,13 +151,16 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deobfuscate(Blocks blocks) {
|
public void deobfuscate(Blocks blocks) {
|
||||||
|
if (resourceManagerType == null && componentResourceManagerType == null)
|
||||||
|
return;
|
||||||
|
|
||||||
foreach (var block in blocks.MethodBlocks.getAllBlocks()) {
|
foreach (var block in blocks.MethodBlocks.getAllBlocks()) {
|
||||||
var instrs = block.Instructions;
|
var instrs = block.Instructions;
|
||||||
for (int i = 0; i < instrs.Count; i++) {
|
for (int i = 0; i < instrs.Count; i++) {
|
||||||
var instr = instrs[i];
|
var instr = instrs[i];
|
||||||
if (instr.OpCode.Code != Code.Newobj)
|
if (instr.OpCode.Code != Code.Newobj)
|
||||||
continue;
|
continue;
|
||||||
var ctor = instr.Operand as MethodReference;
|
var ctor = instr.Operand as IMethod;
|
||||||
if (ctor == null)
|
if (ctor == null)
|
||||||
continue;
|
continue;
|
||||||
var newCtor = resourceManagerCtors.find(ctor);
|
var newCtor = resourceManagerCtors.find(ctor);
|
||||||
|
|
|
@ -20,29 +20,28 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Spices_Net {
|
namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
class SpicesMethodCallInliner : MethodCallInliner {
|
class SpicesMethodCallInliner : MethodCallInliner {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
TypeDefinitionDict<bool> methodsTypes = new TypeDefinitionDict<bool>();
|
TypeDefinitionDict<bool> methodsTypes = new TypeDefinitionDict<bool>();
|
||||||
MethodDefinitionAndDeclaringTypeDict<MethodDef> classMethods = new MethodDefinitionAndDeclaringTypeDict<MethodDef>();
|
MethodDefinitionAndDeclaringTypeDict<MethodDef> classMethods = new MethodDefinitionAndDeclaringTypeDict<MethodDef>();
|
||||||
|
|
||||||
public SpicesMethodCallInliner(ModuleDefinition module)
|
public SpicesMethodCallInliner(ModuleDefMD module)
|
||||||
: base(false) {
|
: base(false) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool isCompatibleType(int paramIndex, TypeReference origType, TypeReference newType) {
|
protected override bool isCompatibleType(int paramIndex, IType origType, IType newType) {
|
||||||
if (MemberReferenceHelper.compareTypes(origType, newType))
|
if (new SigComparer().Equals(origType, newType))
|
||||||
return true;
|
return true;
|
||||||
if (paramIndex == -1) {
|
if (paramIndex == -1) {
|
||||||
if (newType.IsValueType || origType.IsValueType)
|
if (isValueType(newType) || isValueType(origType))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return newType.EType == ElementType.Object;
|
return newType.FullName == "System.Object";
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool checkCanInline(MethodDef method) {
|
public bool checkCanInline(MethodDef method) {
|
||||||
|
@ -61,7 +60,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
void restoreMethodBodies() {
|
void restoreMethodBodies() {
|
||||||
var methodToOrigMethods = new MethodDefinitionAndDeclaringTypeDict<List<MethodDef>>();
|
var methodToOrigMethods = new MethodDefinitionAndDeclaringTypeDict<List<MethodDef>>();
|
||||||
foreach (var t in module.Types) {
|
foreach (var t in module.Types) {
|
||||||
var types = new List<TypeDef>(TypeDef.GetTypes(new List<TypeDef> { t }));
|
var types = new List<TypeDef>(AllTypesHelper.Types(new List<TypeDef> { t }));
|
||||||
foreach (var type in types) {
|
foreach (var type in types) {
|
||||||
if (methodsTypes.find(type))
|
if (methodsTypes.find(type))
|
||||||
continue;
|
continue;
|
||||||
|
@ -103,7 +102,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
calledMethod = null;
|
calledMethod = null;
|
||||||
if (method.Body == null)
|
if (method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
if (method.Body.Variables.Count > 0)
|
if (method.Body.LocalList.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
if (method.Body.ExceptionHandlers.Count > 0)
|
if (method.Body.ExceptionHandlers.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -114,7 +113,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
return false;
|
return false;
|
||||||
if (!calledMethod.IsStatic)
|
if (!calledMethod.IsStatic)
|
||||||
return false;
|
return false;
|
||||||
if (calledMethod.GenericParameters.Count > 0)
|
if (calledMethod.GenericParams.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
if (calledMethod.Body == null || calledMethod.Body.Instructions.Count == 0)
|
if (calledMethod.Body == null || calledMethod.Body.Instructions.Count == 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -128,7 +127,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
var instrs = instanceMethod.Body.Instructions;
|
var instrs = instanceMethod.Body.Instructions;
|
||||||
int index;
|
int index;
|
||||||
for (index = 0; index < instrs.Count; index++) {
|
for (index = 0; index < instrs.Count; index++) {
|
||||||
if (DotNetUtils.getArgIndex(instrs[index]) != index)
|
if (instrs[index].GetParameterIndex() != index)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var call = instrs[index++];
|
var call = instrs[index++];
|
||||||
|
@ -155,17 +154,17 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
static bool checkMethodsType(TypeDef type) {
|
static bool checkMethodsType(TypeDef type) {
|
||||||
if (!type.IsNested)
|
if (!type.IsNested)
|
||||||
return false;
|
return false;
|
||||||
if ((type.Attributes & ~TypeAttributes.BeforeFieldInit) != TypeAttributes.NestedAssembly)
|
if ((type.Flags & ~TypeAttributes.BeforeFieldInit) != TypeAttributes.NestedAssembly)
|
||||||
return false;
|
return false;
|
||||||
if (type.HasProperties || type.HasEvents || type.HasFields || type.HasNestedTypes)
|
if (type.HasProperties || type.HasEvents || type.HasFields || type.HasNestedTypes)
|
||||||
return false;
|
return false;
|
||||||
if (type.GenericParameters.Count > 0)
|
if (type.GenericParams.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
if (type.IsValueType || type.IsInterface)
|
if (type.IsValueType || type.IsInterface)
|
||||||
return false;
|
return false;
|
||||||
if (type.BaseType == null || type.BaseType.EType != ElementType.Object)
|
if (type.BaseType == null || type.BaseType.FullName != "System.Object")
|
||||||
return false;
|
return false;
|
||||||
if (type.Interfaces.Count > 0)
|
if (type.InterfaceImpls.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
if (!checkMethods(type))
|
if (!checkMethods(type))
|
||||||
return false;
|
return false;
|
||||||
|
@ -181,16 +180,16 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
if (method.Name == ".cctor")
|
if (method.Name == ".cctor")
|
||||||
return false;
|
return false;
|
||||||
if (method.Name == ".ctor") {
|
if (method.Name == ".ctor") {
|
||||||
if (method.Parameters.Count != 0)
|
if (method.MethodSig.GetParamCount() != 0)
|
||||||
return false;
|
return false;
|
||||||
foundCtor = true;
|
foundCtor = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (method.Attributes != (MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.HideBySig))
|
if (method.Flags != (MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.HideBySig))
|
||||||
return false;
|
return false;
|
||||||
if (method.HasPInvokeInfo || method.PInvokeInfo != null)
|
if (method.ImplMap != null)
|
||||||
return false;
|
return false;
|
||||||
if (method.GenericParameters.Count > 0)
|
if (method.GenericParams.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
numMethods++;
|
numMethods++;
|
||||||
|
@ -236,7 +235,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
var call = instrs[i];
|
var call = instrs[i];
|
||||||
if (call.OpCode.Code != Code.Call)
|
if (call.OpCode.Code != Code.Call)
|
||||||
continue;
|
continue;
|
||||||
var realInstanceMethod = classMethods.find(call.Operand as MethodReference);
|
var realInstanceMethod = classMethods.find(call.Operand as IMethod);
|
||||||
if (realInstanceMethod == null)
|
if (realInstanceMethod == null)
|
||||||
continue;
|
continue;
|
||||||
call.Operand = realInstanceMethod;
|
call.Operand = realInstanceMethod;
|
||||||
|
|
|
@ -22,12 +22,11 @@ using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Metadata;
|
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Spices_Net {
|
namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
class StringDecrypter {
|
class StringDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
TypeDef decrypterType;
|
TypeDef decrypterType;
|
||||||
FieldDef encryptedDataField;
|
FieldDef encryptedDataField;
|
||||||
StringDataFlags stringDataFlags;
|
StringDataFlags stringDataFlags;
|
||||||
|
@ -60,12 +59,12 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
get {
|
get {
|
||||||
if (encryptedDataField == null)
|
if (encryptedDataField == null)
|
||||||
return null;
|
return null;
|
||||||
var type = encryptedDataField.FieldType as TypeDef;
|
var type = encryptedDataField.FieldSig.GetFieldType().TryGetTypeDef();
|
||||||
if (type == null || type.Fields.Count != 1 || type.Fields[0] != encryptedDataField)
|
if (type == null || type.Fields.Count != 1 || type.Fields[0] != encryptedDataField)
|
||||||
return null;
|
return null;
|
||||||
if (type.HasMethods || type.HasEvents || type.HasProperties || type.HasNestedTypes)
|
if (type.HasMethods || type.HasEvents || type.HasProperties || type.HasNestedTypes)
|
||||||
return null;
|
return null;
|
||||||
if (type.Interfaces.Count > 0)
|
if (type.InterfaceImpls.Count > 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
|
@ -84,7 +83,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
get { return methodToInfo.getValues(); }
|
get { return methodToInfo.getValues(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringDecrypter(ModuleDefinition module) {
|
public StringDecrypter(ModuleDefMD module) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,13 +95,13 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
continue;
|
continue;
|
||||||
if (type.Fields.Count != 2)
|
if (type.Fields.Count != 2)
|
||||||
continue;
|
continue;
|
||||||
if ((type.Attributes & ~TypeAttributes.Sealed) != 0)
|
if ((type.Flags & ~TypeAttributes.Sealed) != 0)
|
||||||
continue;
|
continue;
|
||||||
if (type.BaseType == null || type.BaseType.FullName != "System.Object")
|
if (type.BaseType == null || type.BaseType.FullName != "System.Object")
|
||||||
continue;
|
continue;
|
||||||
if (hasInstanceMethods(type))
|
if (hasInstanceMethods(type))
|
||||||
continue;
|
continue;
|
||||||
var cctor = DotNetUtils.getMethod(type, ".cctor");
|
var cctor = type.FindClassConstructor();
|
||||||
if (cctor == null)
|
if (cctor == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -125,7 +124,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic)
|
if (!method.IsStatic)
|
||||||
return true;
|
return true;
|
||||||
if (method.PInvokeInfo != null)
|
if (method.ImplMap != null)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -136,7 +135,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
var instructions = cctor.Body.Instructions;
|
var instructions = cctor.Body.Instructions;
|
||||||
for (int i = 0; i < instructions.Count; i++) {
|
for (int i = 0; i < instructions.Count; i++) {
|
||||||
var ldci4 = instructions[i];
|
var ldci4 = instructions[i];
|
||||||
if (!DotNetUtils.isLdcI4(ldci4))
|
if (!ldci4.IsLdcI4())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var instrs = DotNetUtils.getInstructions(instructions, i + 1, OpCodes.Newarr, OpCodes.Dup, OpCodes.Ldtoken, OpCodes.Call);
|
var instrs = DotNetUtils.getInstructions(instructions, i + 1, OpCodes.Newarr, OpCodes.Dup, OpCodes.Ldtoken, OpCodes.Call);
|
||||||
|
@ -166,11 +165,12 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
StringDataFlags getStringDataFlags(MethodDef method) {
|
StringDataFlags getStringDataFlags(MethodDef method) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return 0;
|
return 0;
|
||||||
if (method.Parameters.Count != 1)
|
var sig = method.MethodSig;
|
||||||
|
if (sig == null || sig.Params.Count != 1)
|
||||||
return 0;
|
return 0;
|
||||||
if (!checkClass(method.Parameters[0].ParameterType, "System.Byte[]"))
|
if (!checkClass(sig.Params[0], "System.Byte[]"))
|
||||||
return 0;
|
return 0;
|
||||||
if (!checkClass(method.MethodReturnType.ReturnType, "System.Byte[]"))
|
if (!checkClass(sig.RetType, "System.Byte[]"))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
StringDataFlags flags = 0;
|
StringDataFlags flags = 0;
|
||||||
|
@ -194,9 +194,10 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
var calledMethod = instr.Operand as MethodDef;
|
var calledMethod = instr.Operand as MethodDef;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
if (calledMethod.MethodReturnType.ReturnType.EType == ElementType.Void)
|
var sig = calledMethod.MethodSig;
|
||||||
|
if (sig == null || sig.RetType.GetElementType() == ElementType.Void)
|
||||||
continue;
|
continue;
|
||||||
if (calledMethod.Parameters.Count != 0)
|
if (sig.Params.Count != 0)
|
||||||
continue;
|
continue;
|
||||||
if (!get3DesKeyIv(calledMethod, ref key, ref iv))
|
if (!get3DesKeyIv(calledMethod, ref key, ref iv))
|
||||||
continue;
|
continue;
|
||||||
|
@ -211,13 +212,15 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
var arrays = ArrayFinder.getArrays(method, module.TypeSystem.Byte);
|
var arrays = ArrayFinder.getArrays(method, module.CorLibTypes.Byte);
|
||||||
if (arrays.Count != 1 && arrays.Count != 2)
|
if (arrays.Count != 1 && arrays.Count != 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
key = arrays[0];
|
key = arrays[0];
|
||||||
if (arrays.Count == 1)
|
if (arrays.Count == 1) {
|
||||||
iv = module.Assembly.Name.PublicKeyToken;
|
var pkt = PublicKeyBase.ToPublicKeyToken(module.Assembly.PublicKey);
|
||||||
|
iv = pkt == null ? null : pkt.Data;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
iv = arrays[1];
|
iv = arrays[1];
|
||||||
return true;
|
return true;
|
||||||
|
@ -230,18 +233,21 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
var called = instr.Operand as MethodDef;
|
var called = instr.Operand as MethodDef;
|
||||||
if (called == null)
|
if (called == null)
|
||||||
continue;
|
continue;
|
||||||
if (called.MethodReturnType.ReturnType.EType != ElementType.I4)
|
var sig = called.MethodSig;
|
||||||
|
if (sig == null)
|
||||||
continue;
|
continue;
|
||||||
var parameters = called.Parameters;
|
if (sig.RetType.GetElementType() != ElementType.I4)
|
||||||
|
continue;
|
||||||
|
var parameters = sig.Params;
|
||||||
if (parameters.Count != 4)
|
if (parameters.Count != 4)
|
||||||
continue;
|
continue;
|
||||||
if (!checkClass(parameters[0].ParameterType, "System.Byte[]"))
|
if (!checkClass(parameters[0], "System.Byte[]"))
|
||||||
continue;
|
continue;
|
||||||
if (parameters[1].ParameterType.EType != ElementType.I4)
|
if (parameters[1].GetElementType() != ElementType.I4)
|
||||||
continue;
|
continue;
|
||||||
if (!checkClass(parameters[2].ParameterType, "System.Byte[]"))
|
if (!checkClass(parameters[2], "System.Byte[]"))
|
||||||
continue;
|
continue;
|
||||||
if (parameters[3].ParameterType.EType != ElementType.I4)
|
if (parameters[3].GetElementType() != ElementType.I4)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -257,21 +263,24 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkClass(TypeReference type, string fullName) {
|
static bool checkClass(TypeSig type, string fullName) {
|
||||||
return type != null && (type.EType == ElementType.Object || type.FullName == fullName);
|
return type != null && (type.ElementType == ElementType.Object || type.FullName == fullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isStringType(TypeReference type) {
|
static bool isStringType(TypeSig type) {
|
||||||
return type != null && (type.EType == ElementType.Object || type.EType == ElementType.String);
|
return type != null && (type.ElementType == ElementType.Object || type.ElementType == ElementType.String);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeDecrypterInfos(TypeDef type) {
|
bool initializeDecrypterInfos(TypeDef type) {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
if (method.Parameters.Count != 0)
|
var sig = method.MethodSig;
|
||||||
|
if (sig == null)
|
||||||
continue;
|
continue;
|
||||||
if (!isStringType(method.MethodReturnType.ReturnType))
|
if (sig.Params.Count != 0)
|
||||||
|
continue;
|
||||||
|
if (!isStringType(sig.RetType))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var info = createInfo(method);
|
var info = createInfo(method);
|
||||||
|
@ -289,11 +298,11 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var ldci4_1 = instrs[i];
|
var ldci4_1 = instrs[i];
|
||||||
var ldci4_2 = instrs[i + 1];
|
var ldci4_2 = instrs[i + 1];
|
||||||
if (!DotNetUtils.isLdcI4(ldci4_1) || !DotNetUtils.isLdcI4(ldci4_2))
|
if (!ldci4_1.IsLdcI4() || !ldci4_2.IsLdcI4())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int offset = DotNetUtils.getLdcI4Value(ldci4_1);
|
int offset = ldci4_1.GetLdcI4Value();
|
||||||
int length = DotNetUtils.getLdcI4Value(ldci4_2);
|
int length = ldci4_2.GetLdcI4Value();
|
||||||
return new DecrypterInfo(method, offset, length);
|
return new DecrypterInfo(method, offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +322,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((stringDataFlags & StringDataFlags.Encrypted2) != 0) {
|
if ((stringDataFlags & StringDataFlags.Encrypted2) != 0) {
|
||||||
var k = module.Assembly.Name.PublicKey;
|
var k = module.Assembly.PublicKey.Data;
|
||||||
int mask = (byte)(~k.Length);
|
int mask = (byte)(~k.Length);
|
||||||
for (int i = 0; i < decryptedData.Length; i++)
|
for (int i = 0; i < decryptedData.Length; i++)
|
||||||
decryptedData[i] ^= k[i & mask];
|
decryptedData[i] ^= k[i & mask];
|
||||||
|
@ -331,7 +340,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
encryptedDataField.InitialValue = new byte[1];
|
encryptedDataField.InitialValue = new byte[1];
|
||||||
encryptedDataField.FieldType = module.TypeSystem.Byte;
|
encryptedDataField.FieldSig.Type = module.CorLibTypes.Byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string decrypt(MethodDef method) {
|
public string decrypt(MethodDef method) {
|
||||||
|
|
|
@ -59,8 +59,8 @@ namespace de4dot.cui {
|
||||||
new de4dot.code.deobfuscators.Skater_NET.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.Skater_NET.DeobfuscatorInfo(),
|
||||||
#if PORT
|
#if PORT
|
||||||
new de4dot.code.deobfuscators.SmartAssembly.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.SmartAssembly.DeobfuscatorInfo(),
|
||||||
new de4dot.code.deobfuscators.Spices_Net.DeobfuscatorInfo(),
|
|
||||||
#endif
|
#endif
|
||||||
|
new de4dot.code.deobfuscators.Spices_Net.DeobfuscatorInfo(),
|
||||||
new de4dot.code.deobfuscators.Xenocode.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.Xenocode.DeobfuscatorInfo(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user