de4dot-cex/de4dot.code/deobfuscators/Agile_NET/ResourceDecrypter.cs
2015-10-29 22:45:26 +01:00

130 lines
4.0 KiB
C#

/*
Copyright (C) 2011-2015 de4dot@gmail.com
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.IO;
using System.Security.Cryptography;
using System.Text;
using dnlib.IO;
using dnlib.DotNet;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Agile_NET {
class ResourceDecrypter {
ModuleDefMD module;
TypeDef rsrcType;
MethodDef rsrcRrrMethod;
MethodDef rsrcResolveMethod;
public bool Detected {
get { return rsrcType != null; }
}
public TypeDef Type {
get { return rsrcType; }
}
public MethodDef RsrcRrrMethod {
get { return rsrcRrrMethod; }
}
public ResourceDecrypter(ModuleDefMD module) {
this.module = module;
}
public ResourceDecrypter(ModuleDefMD module, ResourceDecrypter oldOne) {
this.module = module;
rsrcType = Lookup(oldOne.rsrcType, "Could not find rsrcType");
rsrcRrrMethod = Lookup(oldOne.rsrcRrrMethod, "Could not find rsrcRrrMethod");
rsrcResolveMethod = Lookup(oldOne.rsrcResolveMethod, "Could not find rsrcResolveMethod");
}
T Lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.Lookup(module, def, errorMessage);
}
public void Find() {
FindResourceType();
}
static readonly string[] requiredFields1 = new string[] {
"System.Reflection.Assembly",
"System.String[]",
};
static readonly string[] requiredFields2 = new string[] {
"System.Reflection.Assembly",
"System.String[]",
"System.Collections.Hashtable",
};
void FindResourceType() {
var cctor = DotNetUtils.GetModuleTypeCctor(module);
if (cctor == null)
return;
foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, cctor)) {
if (!calledMethod.IsStatic || calledMethod.Body == null)
continue;
if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()"))
continue;
var type = calledMethod.DeclaringType;
var fieldTypes = new FieldTypes(type);
if (!fieldTypes.Exactly(requiredFields1) &&
!fieldTypes.Exactly(requiredFields2))
continue;
var resolveHandler = DotNetUtils.GetMethod(type, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)");
var decryptMethod = DotNetUtils.GetMethod(type, "System.Byte[]", "(System.IO.Stream)");
if (resolveHandler == null || !resolveHandler.IsStatic)
continue;
if (decryptMethod == null || !decryptMethod.IsStatic)
continue;
rsrcType = type;
rsrcRrrMethod = calledMethod;
rsrcResolveMethod = resolveHandler;
return;
}
}
public EmbeddedResource MergeResources() {
if (rsrcResolveMethod == null)
return null;
var resource = DotNetUtils.GetResource(module, DotNetUtils.GetCodeStrings(rsrcResolveMethod)) as EmbeddedResource;
if (resource == null)
return null;
DeobUtils.DecryptAndAddResources(module, resource.Name.String, () => DecryptResource(resource));
return resource;
}
byte[] DecryptResource(EmbeddedResource resource) {
var reader = resource.Data;
reader.Position = 0;
var key = reader.ReadString();
var data = reader.ReadRemainingBytes();
var cryptoTransform = new DESCryptoServiceProvider {
Key = Encoding.ASCII.GetBytes(key),
IV = Encoding.ASCII.GetBytes(key),
}.CreateDecryptor();
var memStream = new MemoryStream(data);
using (var reader2 = new BinaryReader(new CryptoStream(memStream, cryptoTransform, CryptoStreamMode.Read))) {
return reader2.ReadBytes((int)memStream.Length);
}
}
}
}