Port CodeVeil deobfuscator

This commit is contained in:
de4dot 2012-11-08 09:48:05 +01:00
parent 10e83acebc
commit f6b5a3117f
18 changed files with 189 additions and 169 deletions

View File

@ -265,8 +265,7 @@ namespace de4dot.blocks {
return null;
}
#if PORT
public static MethodDef getPInvokeMethod(TypeDefinition type, string dll, string funcName) {
public static MethodDef getPInvokeMethod(TypeDef type, string dll, string funcName) {
foreach (var method in type.Methods) {
if (isPinvokeMethod(method, dll, funcName))
return method;
@ -277,11 +276,12 @@ namespace de4dot.blocks {
public static bool isPinvokeMethod(MethodDef method, string dll, string funcName) {
if (method == null)
return false;
if (method.PInvokeInfo == null || method.PInvokeInfo.EntryPoint != funcName)
if (method.ImplMap == null || method.ImplMap.Name.String != funcName)
return false;
return getDllName(dll).Equals(getDllName(method.PInvokeInfo.Module.Name), StringComparison.OrdinalIgnoreCase);
return getDllName(dll).Equals(getDllName(method.ImplMap.Scope.Name.String), StringComparison.OrdinalIgnoreCase);
}
#if PORT
public static MethodDef getMethod(TypeDefinition type, string name) {
if (type == null)
return null;
@ -418,17 +418,17 @@ namespace de4dot.blocks {
return type.FindField(fieldReference.Name, fieldReference.FieldSig);
}
#if PORT
public static FieldDefinition getField(TypeDefinition type, string typeFullName) {
public static FieldDef getField(TypeDef type, string typeFullName) {
if (type == null)
return null;
foreach (var field in type.Fields) {
if (field.FieldType.FullName == typeFullName)
if (field.FieldSig.GetFieldType().GetFullName() == typeFullName)
return field;
}
return null;
}
#if PORT
public static FieldDefinition getFieldByName(TypeDefinition type, string name) {
if (type == null)
return null;

View File

@ -100,21 +100,21 @@
<Compile Include="deobfuscators\CodeFort\PasswordFinder.cs" />
<Compile Include="deobfuscators\CodeFort\ProxyCallFixer.cs" />
<Compile Include="deobfuscators\CodeFort\StringDecrypter.cs" />
<None Include="deobfuscators\CodeVeil\AssemblyResolver.cs" />
<None Include="deobfuscators\CodeVeil\Deobfuscator.cs" />
<None Include="deobfuscators\CodeVeil\ErexResourceReader.cs" />
<None Include="deobfuscators\CodeVeil\InvalidDataException.cs" />
<None Include="deobfuscators\CodeVeil\InvalidMethodsFinder.cs" />
<None Include="deobfuscators\CodeVeil\MainType.cs" />
<None Include="deobfuscators\CodeVeil\MethodsDecrypter.cs" />
<None Include="deobfuscators\CodeVeil\ObfuscatorVersion.cs" />
<None Include="deobfuscators\CodeVeil\ProxyCallFixer.cs" />
<None Include="deobfuscators\CodeVeil\ResourceConverter.cs" />
<None Include="deobfuscators\CodeVeil\ResourceDecrypter.cs" />
<None Include="deobfuscators\CodeVeil\ResourceInfo.cs" />
<None Include="deobfuscators\CodeVeil\ResourceReader.cs" />
<None Include="deobfuscators\CodeVeil\StringDecrypter.cs" />
<None Include="deobfuscators\CodeVeil\TamperDetection.cs" />
<Compile Include="deobfuscators\CodeVeil\AssemblyResolver.cs" />
<Compile Include="deobfuscators\CodeVeil\Deobfuscator.cs" />
<Compile Include="deobfuscators\CodeVeil\ErexResourceReader.cs" />
<Compile Include="deobfuscators\CodeVeil\InvalidDataException.cs" />
<Compile Include="deobfuscators\CodeVeil\InvalidMethodsFinder.cs" />
<Compile Include="deobfuscators\CodeVeil\MainType.cs" />
<Compile Include="deobfuscators\CodeVeil\MethodsDecrypter.cs" />
<Compile Include="deobfuscators\CodeVeil\ObfuscatorVersion.cs" />
<Compile Include="deobfuscators\CodeVeil\ProxyCallFixer.cs" />
<Compile Include="deobfuscators\CodeVeil\ResourceConverter.cs" />
<Compile Include="deobfuscators\CodeVeil\ResourceDecrypter.cs" />
<Compile Include="deobfuscators\CodeVeil\ResourceInfo.cs" />
<Compile Include="deobfuscators\CodeVeil\ResourceReader.cs" />
<Compile Include="deobfuscators\CodeVeil\StringDecrypter.cs" />
<Compile Include="deobfuscators\CodeVeil\TamperDetection.cs" />
<None Include="deobfuscators\CodeWall\AssemblyDecrypter.cs" />
<None Include="deobfuscators\CodeWall\Deobfuscator.cs" />
<None Include="deobfuscators\CodeWall\KeyGenerator.cs" />

View File

@ -20,13 +20,14 @@
using System.Collections.Generic;
using System.IO;
using System.Xml;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeVeil {
class AssemblyResolver {
ModuleDefinition module;
ModuleDefMD module;
EmbeddedResource bundleData;
EmbeddedResource bundleXmlFile;
TypeDef bundleType;
@ -95,7 +96,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
get { return bundleXmlFile; }
}
public AssemblyResolver(ModuleDefinition module) {
public AssemblyResolver(ModuleDefMD module) {
this.module = module;
}
@ -124,10 +125,10 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
void findEmbeddedAssemblies() {
var data = bundleData.GetResourceData();
var data = bundleData.Data.ReadAllBytes();
var doc = new XmlDocument();
doc.Load(XmlReader.Create(bundleXmlFile.GetResourceStream()));
doc.Load(XmlReader.Create(new MemoryStream(bundleXmlFile.Data.ReadAllBytes())));
var manifest = doc.DocumentElement;
if (manifest.Name.ToLowerInvariant() != "manifest") {
Log.w("Could not find Manifest element");
@ -150,7 +151,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
var assemblyData = DeobUtils.inflate(data, offset, data.Length - offset, true);
var mod = ModuleDefinition.ReadModule(new MemoryStream(assemblyData));
var mod = ModuleDefMD.Load(assemblyData);
infos.Add(new AssemblyInfo(mod.Assembly.FullName, DeobUtils.getExtension(mod.Kind), assemblyData));
}
}
@ -174,7 +175,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (type.Fields.Count != 2)
continue;
var ctor = DotNetUtils.getMethod(type, ".ctor");
var ctor = type.FindMethod(".ctor");
if (ctor == null || !ctor.IsPrivate)
continue;
if (!DotNetUtils.isMethod(ctor, "System.Void", "(System.Reflection.Assembly)"))
@ -234,7 +235,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
return;
foreach (var field in bundleType.Fields) {
var type = field.FieldType as TypeDef;
var type = field.FieldSig.GetFieldType().TryGetTypeDef();
if (type == null)
continue;
if (type == bundleType)
@ -242,10 +243,13 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (type.Fields.Count != 2)
continue;
var ctor = DotNetUtils.getMethod(type, ".ctor");
if (ctor == null || ctor.Parameters.Count != 2)
var ctor = type.FindMethod(".ctor");
if (ctor == null)
continue;
var iface = ctor.Parameters[1].ParameterType as TypeDef;
var sig = ctor.MethodSig;
if (sig == null || sig.Params.Count != 2)
continue;
var iface = sig.Params[1].TryGetTypeDef();
if (iface == null || !iface.IsInterface)
continue;
@ -259,22 +263,22 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (assemblyManagerType == null)
return;
foreach (var field in assemblyManagerType.Fields) {
var type = field.FieldType as TypeDef;
var type = field.FieldSig.GetFieldType().TryGetTypeDef();
if (type == null || type.IsInterface)
continue;
var ctor = DotNetUtils.getMethod(type, ".ctor");
var ctor = type.FindMethod(".ctor");
if (!DotNetUtils.isMethod(ctor, "System.Void", "()"))
continue;
if (type.Fields.Count != 1)
continue;
var git = type.Fields[0].FieldType as GenericInstanceType;
var git = type.Fields[0].FieldSig.GetFieldType().ToGenericInstSig();
if (git == null)
continue;
if (git.ElementType.FullName != "System.Collections.Generic.List`1")
if (git.GenericType.FullName != "System.Collections.Generic.List`1")
continue;
if (git.GenericArguments.Count != 1)
continue;
var type2 = git.GenericArguments[0] as TypeDef;
var type2 = git.GenericArguments[0].TryGetTypeDef();
if (type2 == null)
continue;
@ -287,7 +291,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
void findStreamProviderType() {
if (bundleType == null)
return;
var ctor = DotNetUtils.getMethod(bundleType, ".ctor");
var ctor = bundleType.FindMethod(".ctor");
if (!DotNetUtils.isMethod(ctor, "System.Void", "(System.Reflection.Assembly)"))
return;
foreach (var instr in ctor.Body.Instructions) {
@ -301,9 +305,9 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (!DotNetUtils.isMethod(newobjCtor, "System.Void", "(System.Reflection.Assembly,System.String)"))
continue;
var type = newobjCtor.DeclaringType;
if (type.Interfaces.Count != 1)
if (type.InterfaceImpls.Count != 1)
continue;
if (type.Interfaces[0] != bundleStreamProviderIFace)
if (type.InterfaceImpls[0].Interface != bundleStreamProviderIFace)
continue;
streamProviderType = type;

View File

@ -20,7 +20,6 @@
using System;
using System.Collections.Generic;
using dot10.DotNet;
using Mono.MyStuff;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeVeil {
@ -161,7 +160,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
return true;
}
public override IDeobfuscator moduleReloaded(ModuleDefinition module) {
public override IDeobfuscator moduleReloaded(ModuleDefMD module) {
var newOne = new Deobfuscator(options);
newOne.setModule(module);
newOne.mainType = new MainType(module, mainType);

View File

@ -19,14 +19,15 @@
using System;
using System.IO;
using dot10.IO;
namespace de4dot.code.deobfuscators.CodeVeil {
class ErexResourceReader {
BinaryReader reader;
IBinaryReader reader;
uint[] key;
public ErexResourceReader(Stream stream) {
reader = new BinaryReader(stream);
public ErexResourceReader(IBinaryReader reader) {
this.reader = reader;
}
public byte[] decrypt() {
@ -47,10 +48,10 @@ namespace de4dot.code.deobfuscators.CodeVeil {
readKey();
if (isDeflated)
reader = new BinaryReader(inflate(length));
reader = inflate(length);
if (isEncrypted)
reader = new BinaryReader(decrypt(length));
reader = decrypt(length);
return reader.ReadBytes(length);
}
@ -61,17 +62,17 @@ namespace de4dot.code.deobfuscators.CodeVeil {
key[i] = reader.ReadUInt32();
}
Stream inflate(int length) {
var data = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
return new MemoryStream(DeobUtils.inflate(data, true));
IBinaryReader inflate(int length) {
var data = reader.ReadRemainingBytes();
return MemoryImageStream.Create(DeobUtils.inflate(data, true));
}
Stream decrypt(int length) {
IBinaryReader decrypt(int length) {
var block = new uint[4];
var decrypted = new byte[16];
var outStream = new MemoryStream(length);
while (reader.BaseStream.Position < reader.BaseStream.Length) {
while (reader.Position < reader.Length) {
block[0] = reader.ReadUInt32();
block[1] = reader.ReadUInt32();
block[2] = reader.ReadUInt32();
@ -81,8 +82,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
outStream.Write(decrypted, 0, decrypted.Length);
}
outStream.Position = 0;
return outStream;
return MemoryImageStream.Create(outStream.ToArray());
}
}
}

View File

@ -22,7 +22,7 @@ using dot10.DotNet;
namespace de4dot.code.deobfuscators.CodeVeil {
class InvalidMethodsFinder {
public static List<MethodDef> findAll(ModuleDefinition module) {
public static List<MethodDef> findAll(ModuleDefMD module) {
var list = new List<MethodDef>();
foreach (var type in module.GetTypes()) {
foreach (var method in type.Methods) {
@ -34,17 +34,19 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
public static bool isInvalidMethod(MethodDef method) {
if (method == null)
if (method == null || method.IsStatic)
return false;
if (method.IsStatic)
var sig = method.MethodSig;
if (sig == null || sig.Params.Count != 0)
return false;
if (method.Parameters.Count != 0)
return false;
var retType = method.MethodReturnType.ReturnType as GenericParam;
var retType = sig.RetType as GenericSig;
if (retType == null)
return false;
return retType.Owner == null;
if (retType.IsMethodVar)
return retType.Number >= sig.GenParamCount;
var dt = method.DeclaringType;
return dt == null || retType.Number >= dt.GenericParams.Count;
}
}
}

View File

@ -20,18 +20,17 @@
using System.Collections.Generic;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Cecil.Metadata;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeVeil {
// Detects the type CV adds to the assembly that gets called from <Module>::.cctor.
class MainType {
ModuleDefinition module;
ModuleDefMD module;
TypeDef theType;
MethodDef initMethod;
MethodDef tamperCheckMethod;
ObfuscatorVersion obfuscatorVersion = ObfuscatorVersion.Unknown;
List<int> rvas = new List<int>(); // _stub and _executive
List<uint> rvas = new List<uint>(); // _stub and _executive
List<MethodDef> otherInitMethods = new List<MethodDef>();
public bool Detected {
@ -58,15 +57,15 @@ namespace de4dot.code.deobfuscators.CodeVeil {
get { return tamperCheckMethod; }
}
public List<int> Rvas {
public List<uint> Rvas {
get { return rvas; }
}
public MainType(ModuleDefinition module) {
public MainType(ModuleDefMD module) {
this.module = module;
}
public MainType(ModuleDefinition module, MainType oldOne) {
public MainType(ModuleDefMD module, MainType oldOne) {
this.module = module;
this.theType = lookup(oldOne.theType, "Could not find main type");
this.initMethod = lookup(oldOne.initMethod, "Could not find main type init method");
@ -89,11 +88,11 @@ namespace de4dot.code.deobfuscators.CodeVeil {
var instrs = cctor.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) {
var ldci4_1 = instrs[i];
if (!DotNetUtils.isLdcI4(ldci4_1))
if (!ldci4_1.IsLdcI4())
continue;
var ldci4_2 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4_2))
if (!ldci4_2.IsLdcI4())
continue;
var call = instrs[i + 2];
@ -155,21 +154,22 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
bool checkMethodsType(TypeDef type) {
rvas = new List<int>();
rvas = new List<uint>();
var fields = getRvaFields(type);
if (fields.Count < 2) // RVAs for executive and stub are always present if encrypted methods
return true;
foreach (var field in fields)
rvas.Add(field.RVA);
rvas.Add((uint)field.RVA);
return true;
}
static List<FieldDef> getRvaFields(TypeDef type) {
var fields = new List<FieldDef>();
foreach (var field in type.Fields) {
if (field.FieldType.EType != ElementType.U1 && field.FieldType.EType != ElementType.U4)
var etype = field.FieldSig.GetFieldType().GetElementType();
if (etype != ElementType.U1 && etype != ElementType.U4)
continue;
if (field.RVA == 0)
continue;

View File

@ -22,8 +22,6 @@ using System.Collections.Generic;
using System.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Cecil.Metadata;
using Mono.MyStuff;
using de4dot.blocks;
using de4dot.PE;
@ -226,7 +224,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
return null;
// rva is 0 when the assembly has been embedded
int rva = BitConverter.ToInt32(fileData, offset + RVA_EXECUTIVE_OFFSET);
uint rva = BitConverter.ToUInt32(fileData, offset + RVA_EXECUTIVE_OFFSET);
if (rva != 0 && mainType.Rvas.IndexOf(rva) < 0)
continue;

View File

@ -20,16 +20,16 @@
using System;
using System.Collections.Generic;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Cecil.Metadata;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeVeil {
class ProxyCallFixer : ProxyCallFixer1 {
MainType mainType;
Info info = new Info();
BinaryReader reader;
IBinaryReader reader;
class Info {
public TypeDef proxyType;
@ -73,12 +73,12 @@ namespace de4dot.code.deobfuscators.CodeVeil {
get { return info.methodInfoType; }
}
public ProxyCallFixer(ModuleDefinition module, MainType mainType)
public ProxyCallFixer(ModuleDefMD module, MainType mainType)
: base(module) {
this.mainType = mainType;
}
public ProxyCallFixer(ModuleDefinition module, MainType mainType, ProxyCallFixer oldOne)
public ProxyCallFixer(ModuleDefMD module, MainType mainType, ProxyCallFixer oldOne)
: base(module, oldOne) {
this.mainType = mainType;
info.proxyType = lookup(oldOne.info.proxyType, "Could not find proxyType");
@ -93,7 +93,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
var instrs = cctor.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) {
var ldci4 = instrs[i];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
var call = instrs[i + 1];
@ -102,24 +102,24 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (call.Operand != info.initMethod)
continue;
int offset = DotNetUtils.getLdcI4Value(ldci4);
reader.BaseStream.Position = offset;
int rid = DeobUtils.readVariableLengthInt32(reader);
if (rid != type.MDToken.RID)
int offset = ldci4.GetLdcI4Value();
reader.Position = offset;
uint rid = reader.ReadCompressedUInt32();
if (rid != type.Rid)
throw new ApplicationException("Invalid RID");
return string.Empty; // It's non-null
}
return null;
}
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
byte flags = reader.ReadByte();
int methodToken = 0x06000000 + ((flags & 0x3F) << 24) + DeobUtils.readVariableLengthInt32(reader);
int genericTypeToken = (flags & 0x40) == 0 ? -1 : 0x1B000000 + DeobUtils.readVariableLengthInt32(reader);
int methodToken = 0x06000000 + ((flags & 0x3F) << 24) + (int)reader.ReadCompressedUInt32();
int genericTypeToken = (flags & 0x40) == 0 ? -1 : 0x1B000000 + (int)reader.ReadCompressedUInt32();
callOpcode = (flags & 0x80) != 0 ? OpCodes.Callvirt : OpCodes.Call;
calledMethod = module.LookupToken(methodToken) as MethodReference;
calledMethod = module.ResolveToken(methodToken) as IMethod;
if (calledMethod == null)
throw new ApplicationException("Could not find method");
if (genericTypeToken != -1 && calledMethod.DeclaringType.MDToken.ToInt32() != genericTypeToken)
@ -140,7 +140,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
bool initializeInfo(Info infoTmp, TypeDef type) {
foreach (var dtype in type.NestedTypes) {
var cctor = DotNetUtils.getMethod(dtype, ".cctor");
var cctor = dtype.FindMethod(".cctor");
if (cctor == null)
continue;
if (!initProxyType(infoTmp, cctor))
@ -186,7 +186,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (fields.Count != 1)
return false;
var field = fields[0];
var fieldType = DotNetUtils.getType(module, field.FieldType);
var fieldType = DotNetUtils.getType(module, field.FieldSig.GetFieldType());
if (type.NestedTypes.IndexOf(fieldType) < 0)
return false;
if (field.InitialValue == null || field.InitialValue.Length == 0)
@ -218,8 +218,8 @@ namespace de4dot.code.deobfuscators.CodeVeil {
findOtherTypes();
var decompressed = DeobUtils.inflate(info.dataField.InitialValue, true);
reader = new BinaryReader(new MemoryStream(decompressed));
info.dataField.FieldType = module.TypeSystem.Byte;
reader = MemoryImageStream.Create(decompressed);
info.dataField.FieldSig.Type = module.CorLibTypes.Byte;
info.dataField.InitialValue = new byte[1];
}
@ -228,14 +228,15 @@ namespace de4dot.code.deobfuscators.CodeVeil {
return;
foreach (var method in info.proxyType.Methods) {
if (method.Parameters.Count != 4)
var sig = method.MethodSig;
if (sig == null || sig.Params.Count != 4)
continue;
if (method.Parameters[2].ParameterType.FullName != "System.Type[]")
if (sig.Params[2].GetFullName() != "System.Type[]")
continue;
var methodType = method.Parameters[0].ParameterType as TypeDef;
var fieldType = method.Parameters[1].ParameterType as TypeDef;
var ilgType = method.Parameters[3].ParameterType as TypeDef;
var methodType = sig.Params[0].TryGetTypeDef();
var fieldType = sig.Params[1].TryGetTypeDef();
var ilgType = sig.Params[3].TryGetTypeDef();
if (!checkMethodType(methodType))
continue;
if (!checkFieldType(fieldType))
@ -250,7 +251,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
bool checkMethodType(TypeDef type) {
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
if (type == null || type.BaseType == null || type.BaseType.FullName != "System.Object")
return false;
if (type.Fields.Count != 1)
return false;
@ -261,7 +262,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
bool checkFieldType(TypeDef type) {
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
if (type == null || type.BaseType == null || type.BaseType.FullName != "System.Object")
return false;
if (DotNetUtils.getField(type, "System.Reflection.FieldInfo") == null)
return false;
@ -270,7 +271,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
bool checkIlGeneratorType(TypeDef type) {
if (type == null || type.BaseType == null || type.BaseType.EType != ElementType.Object)
if (type == null || type.BaseType == null || type.BaseType.FullName != "System.Object")
return false;
if (type.Fields.Count != 1)
return false;

View File

@ -19,16 +19,17 @@
using System;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using de4dot.code.resources;
namespace de4dot.code.deobfuscators.CodeVeil {
class ResourceConverter {
ModuleDefinition module;
ModuleDefMD module;
ResourceInfo[] infos;
ResourceDataCreator dataCreator;
public ResourceConverter(ModuleDefinition module, ResourceInfo[] infos) {
public ResourceConverter(ModuleDefMD module, ResourceInfo[] infos) {
this.module = module;
this.dataCreator = new ResourceDataCreator(module);
this.infos = infos;
@ -46,7 +47,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
ResourceElement convert(ResourceInfo info) {
var reader = info.dataReader;
reader.BaseStream.Position = info.offset;
reader.Position = info.offset;
IResourceData resourceData;
int type = (info.flags & 0x7F);

View File

@ -19,19 +19,19 @@
using System;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Cecil.Metadata;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeVeil {
class ResourceDecrypter {
ModuleDefinition module;
ModuleDefMD module;
TypeDef encryptedResourceStreamType;
TypeDef encryptedResourceSetType;
MethodDef encryptedResourceSet_GetDefaultReader;
TypeDef encryptedResourceReaderType;
GenericInstanceType encryptedResourceReaderTypeDict;
GenericInstSig encryptedResourceReaderTypeDict;
TypeDef resType;
MethodDef resTypeCtor;
TypeDef resourceFlagsType;
@ -73,7 +73,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
get { return resourceEnumeratorType; }
}
public ResourceDecrypter(ModuleDefinition module) {
public ResourceDecrypter(ModuleDefMD module) {
this.module = module;
}
@ -100,18 +100,19 @@ namespace de4dot.code.deobfuscators.CodeVeil {
foreach (var type in module.Types) {
if (type.Namespace != "")
continue;
if (type.BaseType == null || type.BaseType.EType != ElementType.Object)
if (type.BaseType == null || type.BaseType.FullName != "System.Object")
continue;
if (!hasInterface(type, "System.Collections.IDictionaryEnumerator"))
continue;
if (!new FieldTypes(type).all(resourceEnumeratorType_fields))
continue;
var ctor = DotNetUtils.getMethod(type, ".ctor");
var ctor = type.FindMethod(".ctor");
if (ctor == null)
continue;
if (ctor.Parameters.Count != 1)
var sig = ctor.MethodSig;
if (sig == null || sig.Params.Count != 1)
continue;
if (ctor.Parameters[0].ParameterType != encryptedResourceReaderType)
if (sig.Params[0].TryGetTypeDef() != encryptedResourceReaderType)
continue;
resourceEnumeratorType = type;
@ -120,9 +121,12 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
void findResourceFlags() {
if (resTypeCtor == null || resTypeCtor.Parameters.Count != 4)
if (resTypeCtor == null)
return;
var type = resTypeCtor.Parameters[2].ParameterType as TypeDef;
var sig = resTypeCtor.MethodSig;
if (sig == null || sig.Params.Count != 4)
return;
var type = sig.Params[2].TryGetTypeDef();
if (type == null || !type.IsEnum)
return;
@ -137,13 +141,16 @@ namespace de4dot.code.deobfuscators.CodeVeil {
void findResType() {
if (encryptedResourceReaderTypeDict == null)
return;
var type = encryptedResourceReaderTypeDict.GenericArguments[1] as TypeDef;
var type = encryptedResourceReaderTypeDict.GenericArguments[1].TryGetTypeDef();
if (type == null)
return;
if (type.BaseType == null || type.BaseType.EType != ElementType.Object)
if (type.BaseType == null || type.BaseType.FullName != "System.Object")
return;
var ctor = DotNetUtils.getMethod(type, ".ctor");
if (ctor == null || ctor.Parameters.Count != 4)
var ctor = type.FindMethod(".ctor");
if (ctor == null)
return;
var sig = ctor.MethodSig;
if (sig == null || sig.Params.Count != 4)
return;
resTypeCtor = ctor;
@ -176,25 +183,25 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
static bool hasInterface(TypeDef type, string interfaceFullName) {
foreach (var iface in type.Interfaces) {
if (iface.FullName == interfaceFullName)
foreach (var iface in type.InterfaceImpls) {
if (iface.Interface.FullName == interfaceFullName)
return true;
}
return false;
}
static GenericInstanceType getDlxResDict(TypeDef type) {
static GenericInstSig getDlxResDict(TypeDef type) {
foreach (var field in type.Fields) {
var fieldType = field.FieldType as GenericInstanceType;
var fieldType = field.FieldSig.GetFieldType().ToGenericInstSig();
if (fieldType == null)
continue;
if (fieldType.ElementType.FullName != "System.Collections.Generic.Dictionary`2")
if (fieldType.GenericType.FullName != "System.Collections.Generic.Dictionary`2")
continue;
if (fieldType.GenericArguments.Count != 2)
continue;
if (fieldType.GenericArguments[0].FullName != "System.String")
continue;
if (!(fieldType.GenericArguments[1] is TypeDef))
if (fieldType.GenericArguments[1].TryGetTypeDef() == null)
continue;
return fieldType;
}
@ -221,10 +228,10 @@ namespace de4dot.code.deobfuscators.CodeVeil {
continue;
if (type.BaseType == null || type.BaseType.FullName != "System.Resources.ResourceSet")
continue;
var ctor = DotNetUtils.getMethod(type, ".ctor");
var ctor = type.FindMethod(".ctor");
if (!DotNetUtils.isMethod(ctor, "System.Void", "(System.Resources.IResourceReader)"))
continue;
var method = DotNetUtils.getMethod(type, "GetDefaultReader");
var method = type.FindMethod("GetDefaultReader");
if (!DotNetUtils.isMethod(method, "System.Type", "()"))
continue;
if (method.Body == null || method.IsStatic || !method.IsVirtual)
@ -252,7 +259,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
continue;
if (type.BaseType == null || type.BaseType.FullName != "System.IO.Stream")
continue;
var ctor = DotNetUtils.getMethod(type, ".ctor");
var ctor = type.FindMethod(".ctor");
if (!DotNetUtils.isMethod(ctor, "System.Void", "(System.IO.Stream)"))
continue;
if (!new FieldTypes(type).all(encryptedResourceStreamType_fields))
@ -312,21 +319,20 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (resource == null)
continue;
var decrypted = decrypt(resource.GetResourceStream());
var decrypted = decrypt(resource.Data);
if (decrypted == null)
continue;
Log.v("Decrypted resource {0}", Utils.toCsharpString(resource.Name));
module.Resources[i] = new EmbeddedResource(resource.Name, resource.Attributes, decrypted);
module.Resources[i] = new EmbeddedResource(resource.Name, decrypted, resource.Flags);
}
}
byte[] decrypt(Stream stream) {
byte[] decrypt(IBinaryReader reader) {
try {
stream.Position = 0;
var reader = new BinaryReader(stream);
reader.Position = 0;
uint sig = reader.ReadUInt32();
stream.Position = 0;
reader.Position = 0;
if (sig == 0xBEEFCACE)
return decryptBeefcace(reader);
if (sig == 0x58455245)
@ -342,13 +348,13 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
}
byte[] decryptBeefcace(BinaryReader reader) {
byte[] decryptBeefcace(IBinaryReader reader) {
var resourceReader = new ResourceReader(reader);
return new ResourceConverter(module, resourceReader.read()).convert();
}
byte[] decryptErex(BinaryReader reader) {
return new ErexResourceReader(reader.BaseStream).decrypt();
byte[] decryptErex(IBinaryReader reader) {
return new ErexResourceReader(reader).decrypt();
}
public void deobfuscate(Blocks blocks) {

View File

@ -18,7 +18,7 @@
*/
using System;
using System.IO;
using dot10.IO;
namespace de4dot.code.deobfuscators.CodeVeil {
class ResourceInfo {
@ -26,7 +26,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
public byte flags;
public int offset;
public int length;
public BinaryReader dataReader;
public IBinaryReader dataReader;
public ResourceInfo(string name, byte flags, int offset, int length) {
this.name = name;
this.flags = flags;

View File

@ -21,10 +21,11 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using dot10.IO;
namespace de4dot.code.deobfuscators.CodeVeil {
class ResourceReader {
BinaryReader reader;
IBinaryReader reader;
string resourceReader;
string resourceSet;
@ -36,12 +37,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
get { return resourceSet; }
}
public ResourceReader(Stream stream) {
stream.Position = 0;
reader = new BinaryReader(stream);
}
public ResourceReader(BinaryReader reader) {
public ResourceReader(IBinaryReader reader) {
this.reader = reader;
}
@ -93,13 +89,13 @@ namespace de4dot.code.deobfuscators.CodeVeil {
DeobUtils.xxteaDecrypt(encryptedData, key);
byte[] decryptedData = new byte[encryptedData.Length * 4];
Buffer.BlockCopy(encryptedData, 0, decryptedData, 0, decryptedData.Length);
dataReader = new BinaryReader(new MemoryStream(decryptedData));
dataReader = MemoryImageStream.Create(decryptedData);
}
if (inflateData) {
var data = dataReader.ReadBytes((int)(dataReader.BaseStream.Length - dataReader.BaseStream.Position));
var data = dataReader.ReadRemainingBytes();
data = DeobUtils.inflate(data, true);
dataReader = new BinaryReader(new MemoryStream(data));
dataReader = MemoryImageStream.Create(data);
}
foreach (var info in infos)
@ -108,7 +104,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
return infos;
}
static string readResourceName(BinaryReader reader, bool encrypted) {
static string readResourceName(IBinaryReader reader, bool encrypted) {
if (!encrypted)
return reader.ReadString();

View File

@ -19,13 +19,14 @@
using System;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeVeil {
class StringDecrypter {
ModuleDefinition module;
ModuleDefMD module;
MainType mainType;
TypeDef decrypterType;
FieldDef stringDataField;
@ -49,12 +50,12 @@ namespace de4dot.code.deobfuscators.CodeVeil {
get { return decrypterMethod; }
}
public StringDecrypter(ModuleDefinition module, MainType mainType) {
public StringDecrypter(ModuleDefMD module, MainType mainType) {
this.module = module;
this.mainType = mainType;
}
public StringDecrypter(ModuleDefinition module, MainType mainType, StringDecrypter oldOne) {
public StringDecrypter(ModuleDefMD module, MainType mainType, StringDecrypter oldOne) {
this.module = module;
this.mainType = mainType;
this.decrypterType = lookup(oldOne.decrypterType, "Could not find string decrypter type");
@ -121,7 +122,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
var stringDataFieldTmp = checkFields(type);
if (stringDataFieldTmp == null)
return false;
var fieldType = DotNetUtils.getType(module, stringDataFieldTmp.FieldType);
var fieldType = DotNetUtils.getType(module, stringDataFieldTmp.FieldSig.GetFieldType());
if (fieldType == null || type.NestedTypes.IndexOf(fieldType) < 0)
return false;
@ -189,7 +190,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
decryptStrings(key);
stringDataField.FieldType = module.TypeSystem.Byte;
stringDataField.FieldSig.Type = module.CorLibTypes.Byte;
stringDataField.InitialValue = new byte[1];
}
@ -197,9 +198,9 @@ namespace de4dot.code.deobfuscators.CodeVeil {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) {
var ldci4 = instrs[i];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
if (DotNetUtils.getLdcI4Value(ldci4) != 4)
if (ldci4.GetLdcI4Value() != 4)
continue;
if (instrs[i + 1].OpCode.Code != Code.Newarr)
@ -225,16 +226,16 @@ namespace de4dot.code.deobfuscators.CodeVeil {
Buffer.BlockCopy(encryptedData, 0, decryptedData, 0, data.Length);
var inflated = DeobUtils.inflate(decryptedData, 0, decryptedData.Length, true);
var reader = new BinaryReader(new MemoryStream(inflated));
int deflatedLength = DeobUtils.readVariableLengthInt32(reader);
int numStrings = DeobUtils.readVariableLengthInt32(reader);
var reader = MemoryImageStream.Create(inflated);
int deflatedLength = (int)reader.ReadCompressedUInt32();
int numStrings = (int)reader.ReadCompressedUInt32();
decryptedStrings = new string[numStrings];
var offsets = new int[numStrings];
for (int i = 0; i < numStrings; i++)
offsets[i] = DeobUtils.readVariableLengthInt32(reader);
int startOffset = (int)reader.BaseStream.Position;
offsets[i] = (int)reader.ReadCompressedUInt32();
int startOffset = (int)reader.Position;
for (int i = 0; i < numStrings; i++) {
reader.BaseStream.Position = startOffset + offsets[i];
reader.Position = startOffset + offsets[i];
decryptedStrings[i] = reader.ReadString();
}
}

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.CodeVeil {
class TamperDetection {
ModuleDefinition module;
ModuleDefMD module;
MainType mainType;
TypeDef tamperDetectionType;
List<MethodDef> tamperDetectionMethods = new List<MethodDef>();
@ -38,7 +37,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
get { return tamperDetectionMethods; }
}
public TamperDetection(ModuleDefinition module, MainType mainType) {
public TamperDetection(ModuleDefMD module, MainType mainType) {
this.module = module;
this.mainType = mainType;
}
@ -57,7 +56,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
foreach (var type in module.Types) {
if (!type.HasNestedTypes)
continue;
if ((type.Attributes & ~TypeAttributes.Sealed) != 0)
if ((type.Flags & ~TypeAttributes.Sealed) != 0)
continue;
if (!checkTamperDetectionClasses(type.NestedTypes))
@ -91,9 +90,9 @@ namespace de4dot.code.deobfuscators.CodeVeil {
}
bool isTamperDetectionClass(TypeDef type) {
if (type.BaseType == null || type.BaseType.EType != ElementType.Object)
if (type.BaseType == null || type.BaseType.FullName != "System.Object")
return false;
if ((type.Attributes & ~TypeAttributes.Sealed) != TypeAttributes.NestedAssembly)
if ((type.Flags & ~TypeAttributes.Sealed) != TypeAttributes.NestedAssembly)
return false;
MethodDef cctor = null, initMethod = null;

View File

@ -189,6 +189,19 @@ namespace de4dot.code.deobfuscators {
return null;
}
//TODO: Remove this method
public static int readVariableLengthInt32(BinaryReader reader) {
byte b = reader.ReadByte();
if ((b & 0x80) == 0)
return b;
if ((b & 0x40) == 0)
return (((int)b & 0x3F) << 8) + reader.ReadByte();
return (((int)b & 0x3F) << 24) +
((int)reader.ReadByte() << 16) +
((int)reader.ReadByte() << 8) +
reader.ReadByte();
}
public static int readVariableLengthInt32(byte[] data, ref int index) {
byte b = data[index++];
if ((b & 0x80) == 0)

View File

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

2
dot10

@ -1 +1 @@
Subproject commit 5844915b880f422af17a3bcd234829ba32dcb6e5
Subproject commit 8cd1f845241489cfafd6011c91e6516910600979