2012-02-11 23:46:39 +08:00
|
|
|
|
/*
|
2013-01-02 00:03:16 +08:00
|
|
|
|
Copyright (C) 2011-2013 de4dot@gmail.com
|
2012-02-11 23:46:39 +08:00
|
|
|
|
|
|
|
|
|
This file is part of de4dot.
|
|
|
|
|
|
|
|
|
|
de4dot is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
de4dot is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
2012-12-20 09:06:09 +08:00
|
|
|
|
using dnlib.IO;
|
|
|
|
|
using dnlib.DotNet;
|
|
|
|
|
using dnlib.DotNet.Emit;
|
2012-02-12 06:12:42 +08:00
|
|
|
|
using de4dot.blocks;
|
2012-02-11 23:46:39 +08:00
|
|
|
|
|
|
|
|
|
namespace de4dot.code.deobfuscators.CodeVeil {
|
|
|
|
|
class ResourceDecrypter {
|
2012-11-08 16:48:05 +08:00
|
|
|
|
ModuleDefMD module;
|
2012-11-02 22:57:11 +08:00
|
|
|
|
TypeDef encryptedResourceStreamType;
|
|
|
|
|
TypeDef encryptedResourceSetType;
|
|
|
|
|
MethodDef encryptedResourceSet_GetDefaultReader;
|
|
|
|
|
TypeDef encryptedResourceReaderType;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
GenericInstSig encryptedResourceReaderTypeDict;
|
2012-11-02 22:57:11 +08:00
|
|
|
|
TypeDef resType;
|
|
|
|
|
MethodDef resTypeCtor;
|
|
|
|
|
TypeDef resourceFlagsType;
|
|
|
|
|
TypeDef resourceEnumeratorType;
|
2012-04-29 06:56:17 +08:00
|
|
|
|
MethodCallRestorerBase methodsRestorer;
|
2012-02-12 06:12:42 +08:00
|
|
|
|
|
|
|
|
|
public bool CanRemoveTypes {
|
|
|
|
|
get {
|
|
|
|
|
return EncryptedResourceStreamType != null &&
|
|
|
|
|
EncryptedResourceSetType != null &&
|
|
|
|
|
EncryptedResourceReaderType != null &&
|
|
|
|
|
ResType != null &&
|
|
|
|
|
ResourceFlagsType != null &&
|
|
|
|
|
ResourceEnumeratorType != null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-02 22:57:11 +08:00
|
|
|
|
public TypeDef EncryptedResourceStreamType {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
get { return encryptedResourceStreamType; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-02 22:57:11 +08:00
|
|
|
|
public TypeDef EncryptedResourceSetType {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
get { return encryptedResourceSetType; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-02 22:57:11 +08:00
|
|
|
|
public TypeDef EncryptedResourceReaderType {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
get { return encryptedResourceReaderType; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-02 22:57:11 +08:00
|
|
|
|
public TypeDef ResType {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
get { return resType; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-02 22:57:11 +08:00
|
|
|
|
public TypeDef ResourceFlagsType {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
get { return resourceFlagsType; }
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-02 22:57:11 +08:00
|
|
|
|
public TypeDef ResourceEnumeratorType {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
get { return resourceEnumeratorType; }
|
|
|
|
|
}
|
2012-02-11 23:46:39 +08:00
|
|
|
|
|
2012-11-08 16:48:05 +08:00
|
|
|
|
public ResourceDecrypter(ModuleDefMD module) {
|
2012-02-11 23:46:39 +08:00
|
|
|
|
this.module = module;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public void Initialize() {
|
2012-04-29 06:56:17 +08:00
|
|
|
|
methodsRestorer = new MethodCallRestorerBase(module);
|
2013-01-19 20:03:57 +08:00
|
|
|
|
FindEncryptedResourceStreamType();
|
|
|
|
|
FindEncryptedResourceSet();
|
|
|
|
|
FindEncryptedResourceReader();
|
|
|
|
|
FindResType();
|
|
|
|
|
FindResourceFlags();
|
|
|
|
|
FindResourceEnumerator();
|
2012-02-12 06:12:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
void FindResourceEnumerator() {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (encryptedResourceReaderType == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var resourceEnumeratorType_fields = new string[] {
|
|
|
|
|
"System.Collections.DictionaryEntry",
|
|
|
|
|
"System.Collections.IDictionaryEnumerator",
|
|
|
|
|
"System.Boolean",
|
|
|
|
|
encryptedResourceReaderType.FullName,
|
|
|
|
|
};
|
|
|
|
|
foreach (var type in module.Types) {
|
|
|
|
|
if (type.Namespace != "")
|
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
if (type.BaseType == null || type.BaseType.FullName != "System.Object")
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!HasInterface(type, "System.Collections.IDictionaryEnumerator"))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!new FieldTypes(type).All(resourceEnumeratorType_fields))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var ctor = type.FindMethod(".ctor");
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (ctor == null)
|
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var sig = ctor.MethodSig;
|
|
|
|
|
if (sig == null || sig.Params.Count != 1)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
if (sig.Params[0].TryGetTypeDef() != encryptedResourceReaderType)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
resourceEnumeratorType = type;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
void FindResourceFlags() {
|
2012-11-08 16:48:05 +08:00
|
|
|
|
if (resTypeCtor == null)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
return;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var sig = resTypeCtor.MethodSig;
|
|
|
|
|
if (sig == null || sig.Params.Count != 4)
|
|
|
|
|
return;
|
|
|
|
|
var type = sig.Params[2].TryGetTypeDef();
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (type == null || !type.IsEnum)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
resourceFlagsType = type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static string[] resType_fields = new string[] {
|
|
|
|
|
"System.Int32",
|
|
|
|
|
"System.Object",
|
|
|
|
|
"System.String",
|
|
|
|
|
};
|
2013-01-19 20:03:57 +08:00
|
|
|
|
void FindResType() {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (encryptedResourceReaderTypeDict == null)
|
|
|
|
|
return;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var type = encryptedResourceReaderTypeDict.GenericArguments[1].TryGetTypeDef();
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (type == null)
|
|
|
|
|
return;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
if (type.BaseType == null || type.BaseType.FullName != "System.Object")
|
|
|
|
|
return;
|
|
|
|
|
var ctor = type.FindMethod(".ctor");
|
|
|
|
|
if (ctor == null)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
return;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var sig = ctor.MethodSig;
|
|
|
|
|
if (sig == null || sig.Params.Count != 4)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
resTypeCtor = ctor;
|
|
|
|
|
resType = type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static string[] encryptedResourceReaderType_fields = new string[] {
|
|
|
|
|
"System.Boolean",
|
|
|
|
|
"System.Int32",
|
|
|
|
|
"System.Int64",
|
|
|
|
|
"System.IO.BinaryReader",
|
|
|
|
|
"System.Runtime.Serialization.Formatters.Binary.BinaryFormatter",
|
|
|
|
|
};
|
2013-01-19 20:03:57 +08:00
|
|
|
|
void FindEncryptedResourceReader() {
|
|
|
|
|
var type = GetTypeFromCode(encryptedResourceSet_GetDefaultReader);
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (type == null)
|
|
|
|
|
return;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (type.BaseType == null || !HasInterface(type, "System.Resources.IResourceReader"))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
return;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!new FieldTypes(type).All(encryptedResourceReaderType_fields))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
return;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
var dictType = GetDlxResDict(type);
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (dictType == null)
|
|
|
|
|
return;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (FindXxteaMethod(type) == null)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
encryptedResourceReaderType = type;
|
|
|
|
|
encryptedResourceReaderTypeDict = dictType;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
static bool HasInterface(TypeDef type, string interfaceFullName) {
|
2012-11-17 06:50:52 +08:00
|
|
|
|
foreach (var iface in type.Interfaces) {
|
2012-11-08 16:48:05 +08:00
|
|
|
|
if (iface.Interface.FullName == interfaceFullName)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
static GenericInstSig GetDlxResDict(TypeDef type) {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
foreach (var field in type.Fields) {
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var fieldType = field.FieldSig.GetFieldType().ToGenericInstSig();
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (fieldType == null)
|
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
if (fieldType.GenericType.FullName != "System.Collections.Generic.Dictionary`2")
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
|
|
|
|
if (fieldType.GenericArguments.Count != 2)
|
|
|
|
|
continue;
|
|
|
|
|
if (fieldType.GenericArguments[0].FullName != "System.String")
|
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
if (fieldType.GenericArguments[1].TryGetTypeDef() == null)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
|
|
|
|
return fieldType;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
static TypeDef GetTypeFromCode(MethodDef method) {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (method == null || method.Body == null)
|
|
|
|
|
return null;
|
|
|
|
|
foreach (var instr in method.Body.Instructions) {
|
|
|
|
|
if (instr.OpCode.Code != Code.Ldtoken)
|
|
|
|
|
continue;
|
2012-11-02 22:57:11 +08:00
|
|
|
|
var type = instr.Operand as TypeDef;
|
2012-02-12 06:12:42 +08:00
|
|
|
|
if (type != null)
|
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
void FindEncryptedResourceSet() {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
foreach (var type in module.Types) {
|
|
|
|
|
if (type.Namespace != "")
|
|
|
|
|
continue;
|
|
|
|
|
if (type.BaseType == null || type.BaseType.FullName != "System.Resources.ResourceSet")
|
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var ctor = type.FindMethod(".ctor");
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!DotNetUtils.IsMethod(ctor, "System.Void", "(System.Resources.IResourceReader)"))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var method = type.FindMethod("GetDefaultReader");
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!DotNetUtils.IsMethod(method, "System.Type", "()"))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
|
|
|
|
if (method.Body == null || method.IsStatic || !method.IsVirtual)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
encryptedResourceSet_GetDefaultReader = method;
|
|
|
|
|
encryptedResourceSetType = type;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static string[] encryptedResourceStreamType_fields = new string[] {
|
|
|
|
|
"System.Byte",
|
|
|
|
|
"System.Byte[]",
|
|
|
|
|
"System.Boolean",
|
|
|
|
|
"System.Int32",
|
|
|
|
|
"System.Int64",
|
|
|
|
|
"System.IO.MemoryStream",
|
|
|
|
|
"System.IO.Stream",
|
|
|
|
|
"System.UInt32[]",
|
|
|
|
|
};
|
2013-01-19 20:03:57 +08:00
|
|
|
|
void FindEncryptedResourceStreamType() {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
foreach (var type in module.Types) {
|
|
|
|
|
if (type.Namespace != "")
|
|
|
|
|
continue;
|
|
|
|
|
if (type.BaseType == null || type.BaseType.FullName != "System.IO.Stream")
|
|
|
|
|
continue;
|
2012-11-08 16:48:05 +08:00
|
|
|
|
var ctor = type.FindMethod(".ctor");
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!DotNetUtils.IsMethod(ctor, "System.Void", "(System.IO.Stream)"))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!new FieldTypes(type).All(encryptedResourceStreamType_fields))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (FindXxteaMethod(type) == null)
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
2012-11-02 22:57:11 +08:00
|
|
|
|
MethodDef getManifestResourceStreamMethodTmp1, getManifestResourceStreamMethodTmp2;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!FindManifestResourceStreamMethods(type, out getManifestResourceStreamMethodTmp1, out getManifestResourceStreamMethodTmp2))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
methodsRestorer.CreateGetManifestResourceStream1(getManifestResourceStreamMethodTmp1);
|
|
|
|
|
methodsRestorer.CreateGetManifestResourceStream2(getManifestResourceStreamMethodTmp2);
|
2012-02-12 06:12:42 +08:00
|
|
|
|
encryptedResourceStreamType = type;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
static MethodDef FindXxteaMethod(TypeDef type) {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
foreach (var method in type.Methods) {
|
|
|
|
|
if (!method.IsPrivate || method.IsStatic || method.Body == null)
|
|
|
|
|
continue;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (DotNetUtils.IsMethod(method, "System.Void", "(System.UInt32[],System.UInt32[])")) {
|
|
|
|
|
if (!DeobUtils.HasInteger(method, 0x9E3779B9))
|
2012-02-12 06:39:37 +08:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2013-01-19 20:03:57 +08:00
|
|
|
|
else if (DotNetUtils.IsMethod(method, "System.Void", "(System.UInt32[],System.UInt32[],System.UInt32,System.UInt32,System.UInt32,System.UInt32,System.UInt32,System.UInt32,System.UInt32,System.UInt32,System.UInt32)")) {
|
2012-02-12 06:39:37 +08:00
|
|
|
|
// Here if 5.0. 0x9E3779B9 is passed to it as the last arg.
|
|
|
|
|
}
|
|
|
|
|
else
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (!DeobUtils.HasInteger(method, 52))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
return method;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
static bool FindManifestResourceStreamMethods(TypeDef type, out MethodDef getManifestResourceStreamMethodTmp1, out MethodDef getManifestResourceStreamMethodTmp2) {
|
2012-02-12 06:12:42 +08:00
|
|
|
|
getManifestResourceStreamMethodTmp1 = null;
|
|
|
|
|
getManifestResourceStreamMethodTmp2 = null;
|
|
|
|
|
foreach (var method in type.Methods) {
|
2012-02-13 18:11:08 +08:00
|
|
|
|
if (!method.IsStatic || method.Body == null)
|
|
|
|
|
continue;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (DotNetUtils.IsMethod(method, "System.IO.Stream", "(System.Reflection.Assembly,System.String)"))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
getManifestResourceStreamMethodTmp1 = method;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
else if (DotNetUtils.IsMethod(method, "System.IO.Stream", "(System.Reflection.Assembly,System.Type,System.String)"))
|
2012-02-12 06:12:42 +08:00
|
|
|
|
getManifestResourceStreamMethodTmp2 = method;
|
|
|
|
|
}
|
|
|
|
|
return getManifestResourceStreamMethodTmp1 != null && getManifestResourceStreamMethodTmp2 != null;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public void Decrypt() {
|
2012-02-11 23:46:39 +08:00
|
|
|
|
for (int i = 0; i < module.Resources.Count; i++) {
|
|
|
|
|
var resource = module.Resources[i] as EmbeddedResource;
|
|
|
|
|
if (resource == null)
|
|
|
|
|
continue;
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
var decrypted = Decrypt(resource.Data);
|
2012-02-11 23:46:39 +08:00
|
|
|
|
if (decrypted == null)
|
|
|
|
|
continue;
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
Logger.v("Decrypted resource {0}", Utils.ToCsharpString(resource.Name));
|
2012-11-17 06:50:52 +08:00
|
|
|
|
module.Resources[i] = new EmbeddedResource(resource.Name, decrypted, resource.Attributes);
|
2012-02-11 23:46:39 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
byte[] Decrypt(IBinaryReader reader) {
|
2012-02-11 23:46:39 +08:00
|
|
|
|
try {
|
2012-11-08 16:48:05 +08:00
|
|
|
|
reader.Position = 0;
|
2012-02-11 23:46:39 +08:00
|
|
|
|
uint sig = reader.ReadUInt32();
|
2012-11-08 16:48:05 +08:00
|
|
|
|
reader.Position = 0;
|
2012-02-11 23:46:39 +08:00
|
|
|
|
if (sig == 0xBEEFCACE)
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return DecryptBeefcace(reader);
|
2012-02-12 21:28:53 +08:00
|
|
|
|
if (sig == 0x58455245)
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return DecryptErex(reader);
|
2012-02-11 23:46:39 +08:00
|
|
|
|
return null;
|
|
|
|
|
}
|
2012-02-12 04:49:22 +08:00
|
|
|
|
catch (InvalidDataException) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2012-02-11 23:46:39 +08:00
|
|
|
|
catch (Exception ex) {
|
2012-11-11 12:31:11 +08:00
|
|
|
|
Logger.w("Got an exception when decrypting resources: {0} - {1}", ex.GetType(), ex.Message);
|
2012-02-11 23:46:39 +08:00
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
byte[] DecryptBeefcace(IBinaryReader reader) {
|
2012-02-11 23:46:39 +08:00
|
|
|
|
var resourceReader = new ResourceReader(reader);
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return new ResourceConverter(module, resourceReader.Read()).Convert();
|
2012-02-11 23:46:39 +08:00
|
|
|
|
}
|
2012-02-12 06:12:42 +08:00
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
byte[] DecryptErex(IBinaryReader reader) {
|
|
|
|
|
return new ErexResourceReader(reader).Decrypt();
|
2012-02-12 21:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public void Deobfuscate(Blocks blocks) {
|
2012-02-29 01:14:41 +08:00
|
|
|
|
if (encryptedResourceStreamType == null)
|
|
|
|
|
return;
|
2012-02-12 06:12:42 +08:00
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
methodsRestorer.Deobfuscate(blocks);
|
2012-02-12 06:12:42 +08:00
|
|
|
|
}
|
2012-02-11 23:46:39 +08:00
|
|
|
|
}
|
|
|
|
|
}
|