Fix some problems with new assemblies

This commit is contained in:
de4dot 2011-11-12 21:04:24 +01:00
parent d3996b5152
commit cf6387a4c1
7 changed files with 92 additions and 88 deletions

View File

@ -35,14 +35,13 @@ namespace de4dot.deobfuscators.SmartAssembly {
return assemblyResolverInfo.resolveResources();
}
public bool canDecryptResource(EmbeddedResource resource) {
var info = getEmbeddedAssemblyInfo(resource);
public bool canDecryptResource(EmbeddedAssemblyInfo info) {
if (info == null || !info.isCompressed)
return true;
return resourceDecrypter.CanDecrypt;
}
public IEnumerable<Tuple<AssemblyResolverInfo.EmbeddedAssemblyInfo, byte[]>> getDecryptedResources() {
public IEnumerable<Tuple<EmbeddedAssemblyInfo, byte[]>> getDecryptedResources() {
var returned = new Dictionary<Resource, bool>();
foreach (var info in assemblyResolverInfo.EmbeddedAssemblyInfos) {
if (info.resource == null) {
@ -53,27 +52,14 @@ namespace de4dot.deobfuscators.SmartAssembly {
continue;
returned[info.resource] = true;
yield return new Tuple<AssemblyResolverInfo.EmbeddedAssemblyInfo, byte[]> {
yield return new Tuple<EmbeddedAssemblyInfo, byte[]> {
Item1 = info,
Item2 = decryptResource(info),
};
}
}
AssemblyResolverInfo.EmbeddedAssemblyInfo getEmbeddedAssemblyInfo(EmbeddedResource resource) {
foreach (var info in assemblyResolverInfo.EmbeddedAssemblyInfos) {
if (info.resource == resource)
return info;
}
return null;
}
public byte[] removeDecryptedResource(EmbeddedResource resource) {
if (resource == null)
return null;
var info = getEmbeddedAssemblyInfo(resource);
public byte[] removeDecryptedResource(EmbeddedAssemblyInfo info) {
if (info == null)
return null;
@ -83,7 +69,7 @@ namespace de4dot.deobfuscators.SmartAssembly {
return data;
}
byte[] decryptResource(AssemblyResolverInfo.EmbeddedAssemblyInfo info) {
byte[] decryptResource(EmbeddedAssemblyInfo info) {
if (info.isCompressed)
return resourceDecrypter.decrypt(info.resource);
else

View File

@ -25,55 +25,55 @@ using Mono.Cecil.Cil;
using de4dot.blocks;
namespace de4dot.deobfuscators.SmartAssembly {
public class EmbeddedAssemblyInfo {
public string assemblyName;
public string simpleName;
public string resourceName;
public EmbeddedResource resource;
public bool isCompressed = false;
public bool isTempFile = false;
public string flags = "";
public override string ToString() {
return assemblyName ?? base.ToString();
}
public static EmbeddedAssemblyInfo create(ModuleDefinition module, string encName, string rsrcName) {
var info = new EmbeddedAssemblyInfo();
try {
if (encName == "" || Convert.ToBase64String(Convert.FromBase64String(encName)) != encName)
return null;
}
catch (FormatException) {
return null;
}
if (rsrcName.Length > 0 && rsrcName[0] == '[') {
int i = rsrcName.IndexOf(']');
if (i < 0)
return null;
info.flags = rsrcName.Substring(1, i - 1);
info.isTempFile = info.flags.IndexOf('t') >= 0;
info.isCompressed = info.flags.IndexOf('z') >= 0;
rsrcName = rsrcName.Substring(i + 1);
}
if (rsrcName == "")
return null;
info.assemblyName = Encoding.UTF8.GetString(Convert.FromBase64String(encName));
info.resourceName = rsrcName;
info.resource = DotNetUtils.getResource(module, rsrcName) as EmbeddedResource;
info.simpleName = Utils.getAssemblySimpleName(info.assemblyName);
return info;
}
}
class AssemblyResolverInfo : ResolverInfoBase {
TypeDefinition simpleZipType;
List<EmbeddedAssemblyInfo> embeddedAssemblyInfos = new List<EmbeddedAssemblyInfo>();
public class EmbeddedAssemblyInfo {
public string assemblyName;
public string simpleName;
public string resourceName;
public EmbeddedResource resource;
public bool isCompressed = false;
public bool isTempFile = false;
public string flags = "";
public override string ToString() {
return assemblyName ?? base.ToString();
}
public static EmbeddedAssemblyInfo create(ModuleDefinition module, string encName, string rsrcName) {
var info = new EmbeddedAssemblyInfo();
try {
if (encName == "" || Convert.ToBase64String(Convert.FromBase64String(encName)) != encName)
return null;
}
catch (FormatException) {
return null;
}
if (rsrcName.Length > 0 && rsrcName[0] == '[') {
int i = rsrcName.IndexOf(']');
if (i < 0)
return null;
info.flags = rsrcName.Substring(1, i - 1);
info.isTempFile = info.flags.IndexOf('t') >= 0;
info.isCompressed = info.flags.IndexOf('z') >= 0;
rsrcName = rsrcName.Substring(i + 1);
}
if (rsrcName == "")
return null;
info.assemblyName = Encoding.UTF8.GetString(Convert.FromBase64String(encName));
info.resourceName = rsrcName;
info.resource = DotNetUtils.getResource(module, rsrcName) as EmbeddedResource;
info.simpleName = Utils.getAssemblySimpleName(info.assemblyName);
return info;
}
}
public TypeDefinition SimpleZipType {
get { return simpleZipType; }
}
@ -166,5 +166,14 @@ namespace de4dot.deobfuscators.SmartAssembly {
return;
}
}
public EmbeddedAssemblyInfo find(string simpleName) {
foreach (var info in embeddedAssemblyInfos) {
if (info.simpleName == simpleName)
return info;
}
return null;
}
}
}

View File

@ -146,7 +146,7 @@ namespace de4dot.deobfuscators.SmartAssembly {
}
protected override void scanForObfuscator() {
proxyDelegateFinder = new ProxyDelegateFinder(module);
proxyDelegateFinder = new ProxyDelegateFinder(module, DeobfuscatedFile);
findSmartAssemblyAttributes();
findAutomatedErrorReportingType();
memoryManagerInfo = new MemoryManagerInfo(module);
@ -305,8 +305,10 @@ namespace de4dot.deobfuscators.SmartAssembly {
void initDecrypters() {
assemblyResolverInfo = new AssemblyResolverInfo(module, DeobfuscatedFile, this);
assemblyResolverInfo.findTypes();
resourceDecrypterInfo = new ResourceDecrypterInfo(module, assemblyResolverInfo.SimpleZipType, DeobfuscatedFile);
resourceResolverInfo = new ResourceResolverInfo(module, DeobfuscatedFile, this);
resourceResolverInfo = new ResourceResolverInfo(module, DeobfuscatedFile, this, assemblyResolverInfo);
resourceResolverInfo.findTypes();
resourceDecrypter = new ResourceDecrypter(resourceDecrypterInfo);
assemblyResolver = new AssemblyResolver(resourceDecrypter, assemblyResolverInfo);
resourceResolver = new ResourceResolver(module, assemblyResolver, resourceResolverInfo);
@ -337,10 +339,10 @@ namespace de4dot.deobfuscators.SmartAssembly {
bool decryptResources() {
if (!resourceResolver.canDecryptResource())
return false;
var rsrc = resourceResolver.mergeResources();
if (rsrc == null)
var info = resourceResolver.mergeResources();
if (info == null)
return true;
addResourceToBeRemoved(rsrc, "Encrypted resources");
addResourceToBeRemoved(info.resource, "Encrypted resources");
assemblyResolver.resolveResources();
return true;
}

View File

@ -38,19 +38,25 @@ namespace de4dot.deobfuscators.SmartAssembly {
};
IList<MemberReference> memberReferences;
ISimpleDeobfuscator simpleDeobfuscator;
static ProxyDelegateFinder() {
for (int i = 0; i < specialChars.Length; i++)
specialCharsDict[specialChars[i]] = i;
}
public ProxyDelegateFinder(ModuleDefinition module)
public ProxyDelegateFinder(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator)
: base(module) {
this.memberReferences = new List<MemberReference>(module.GetMemberReferences());
this.simpleDeobfuscator = simpleDeobfuscator;
}
protected override object checkCctor(TypeDefinition type, MethodDefinition cctor) {
var instrs = cctor.Body.Instructions;
if (instrs.Count > 10)
return null;
if (instrs.Count != 3)
simpleDeobfuscator.deobfuscate(cctor);
if (instrs.Count != 3)
return null;
if (!DotNetUtils.isLdcI4(instrs[0].OpCode.Code))

View File

@ -47,7 +47,6 @@ namespace de4dot.deobfuscators.SmartAssembly {
this.module = module;
this.simpleDeobfuscator = simpleDeobfuscator;
this.deob = deob;
findTypes();
}
public bool findTypes() {
@ -106,7 +105,7 @@ namespace de4dot.deobfuscators.SmartAssembly {
resolverType = null;
if (!initMethod.HasBody)
return false;
if (type.Properties.Count > 0 || type.Events.Count > 0)
if (type.Properties.Count > 1 || type.Events.Count > 0)
return false;
if (!checkResolverType(type))
return false;

View File

@ -36,20 +36,20 @@ namespace de4dot.deobfuscators.SmartAssembly {
}
public bool canDecryptResource() {
return assemblyResolver.canDecryptResource(resourceResolverInfo.Resource);
return assemblyResolver.canDecryptResource(resourceResolverInfo.ResourceInfo);
}
public EmbeddedResource mergeResources() {
public EmbeddedAssemblyInfo mergeResources() {
if (mergedIt)
return null;
var resource = resourceResolverInfo.Resource;
if (resource == null)
var info = resourceResolverInfo.ResourceInfo;
if (info == null)
return null;
DeobUtils.decryptAndAddResources(module, resource.Name, () => assemblyResolver.removeDecryptedResource(resource));
DeobUtils.decryptAndAddResources(module, info.resourceName, () => assemblyResolver.removeDecryptedResource(info));
mergedIt = true;
return resource;
return info;
}
}
}

View File

@ -23,14 +23,16 @@ using de4dot.blocks;
namespace de4dot.deobfuscators.SmartAssembly {
class ResourceResolverInfo : ResolverInfoBase {
EmbeddedResource embeddedAssembliesResource;
EmbeddedAssemblyInfo resourceInfo;
AssemblyResolverInfo assemblyResolverInfo;
public EmbeddedResource Resource {
get { return embeddedAssembliesResource; }
public EmbeddedAssemblyInfo ResourceInfo {
get { return resourceInfo; }
}
public ResourceResolverInfo(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob)
public ResourceResolverInfo(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob, AssemblyResolverInfo assemblyResolverInfo)
: base(module, simpleDeobfuscator, deob) {
this.assemblyResolverInfo = assemblyResolverInfo;
}
protected override bool checkResolverType(TypeDefinition type) {
@ -41,7 +43,7 @@ namespace de4dot.deobfuscators.SmartAssembly {
if (!method.IsStatic || !method.HasBody)
return false;
EmbeddedResource resource = null;
EmbeddedAssemblyInfo info = null;
var instructions = method.Body.Instructions;
for (int i = 0; i < instructions.Count; i++) {
var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldstr, OpCodes.Call);
@ -53,15 +55,15 @@ namespace de4dot.deobfuscators.SmartAssembly {
if (s == null || calledMethod == null)
continue;
resource = DotNetUtils.getResource(module, Utils.getAssemblySimpleName(s)) as EmbeddedResource;
if (resource != null)
info = assemblyResolverInfo.find(Utils.getAssemblySimpleName(s));
if (info != null)
break;
}
if (resource == null)
if (info == null)
return false;
embeddedAssembliesResource = resource;
Log.v("Found embedded assemblies resource {0}", Utils.toCsharpString(embeddedAssembliesResource.Name));
resourceInfo = info;
Log.v("Found embedded assemblies resource {0}", Utils.toCsharpString(info.resourceName));
return true;
}
}