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

View File

@ -25,55 +25,55 @@ using Mono.Cecil.Cil;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.deobfuscators.SmartAssembly { 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 { class AssemblyResolverInfo : ResolverInfoBase {
TypeDefinition simpleZipType; TypeDefinition simpleZipType;
List<EmbeddedAssemblyInfo> embeddedAssemblyInfos = new List<EmbeddedAssemblyInfo>(); 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 { public TypeDefinition SimpleZipType {
get { return simpleZipType; } get { return simpleZipType; }
} }
@ -166,5 +166,14 @@ namespace de4dot.deobfuscators.SmartAssembly {
return; 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() { protected override void scanForObfuscator() {
proxyDelegateFinder = new ProxyDelegateFinder(module); proxyDelegateFinder = new ProxyDelegateFinder(module, DeobfuscatedFile);
findSmartAssemblyAttributes(); findSmartAssemblyAttributes();
findAutomatedErrorReportingType(); findAutomatedErrorReportingType();
memoryManagerInfo = new MemoryManagerInfo(module); memoryManagerInfo = new MemoryManagerInfo(module);
@ -305,8 +305,10 @@ namespace de4dot.deobfuscators.SmartAssembly {
void initDecrypters() { void initDecrypters() {
assemblyResolverInfo = new AssemblyResolverInfo(module, DeobfuscatedFile, this); assemblyResolverInfo = new AssemblyResolverInfo(module, DeobfuscatedFile, this);
assemblyResolverInfo.findTypes();
resourceDecrypterInfo = new ResourceDecrypterInfo(module, assemblyResolverInfo.SimpleZipType, DeobfuscatedFile); 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); resourceDecrypter = new ResourceDecrypter(resourceDecrypterInfo);
assemblyResolver = new AssemblyResolver(resourceDecrypter, assemblyResolverInfo); assemblyResolver = new AssemblyResolver(resourceDecrypter, assemblyResolverInfo);
resourceResolver = new ResourceResolver(module, assemblyResolver, resourceResolverInfo); resourceResolver = new ResourceResolver(module, assemblyResolver, resourceResolverInfo);
@ -337,10 +339,10 @@ namespace de4dot.deobfuscators.SmartAssembly {
bool decryptResources() { bool decryptResources() {
if (!resourceResolver.canDecryptResource()) if (!resourceResolver.canDecryptResource())
return false; return false;
var rsrc = resourceResolver.mergeResources(); var info = resourceResolver.mergeResources();
if (rsrc == null) if (info == null)
return true; return true;
addResourceToBeRemoved(rsrc, "Encrypted resources"); addResourceToBeRemoved(info.resource, "Encrypted resources");
assemblyResolver.resolveResources(); assemblyResolver.resolveResources();
return true; return true;
} }

View File

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

View File

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

View File

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

View File

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