Merge branch 'master' into newcode

This commit is contained in:
de4dot 2012-01-18 06:15:31 +01:00
commit ed31063b1b
24 changed files with 316 additions and 396 deletions

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

View File

@ -441,6 +441,8 @@ namespace de4dot.blocks {
} }
public static FieldDefinition getField(ModuleDefinition module, FieldReference field) { public static FieldDefinition getField(ModuleDefinition module, FieldReference field) {
if (field == null)
return null;
if (field is FieldDefinition) if (field is FieldDefinition)
return (FieldDefinition)field; return (FieldDefinition)field;
return getField(getType(module, field.DeclaringType), field); return getField(getType(module, field.DeclaringType), field);

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

2
cecil

@ -1 +1 @@
Subproject commit 188d7947ad6c9a260099f7b58e2595a13e9a5f07 Subproject commit 2bc3f2014c697f697e8bb09e5ca004e5e252fe06

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

View File

@ -553,13 +553,13 @@ namespace de4dot.code.deobfuscators {
} }
} }
protected void removeProxyDelegates(ProxyDelegateFinderBase proxyDelegateFinder) { protected void removeProxyDelegates(ProxyDelegateFinderBase proxyDelegateFinder, bool removeCreators = true) {
if (proxyDelegateFinder.Errors != 0) { if (proxyDelegateFinder.Errors != 0) {
Log.v("Not removing proxy delegates and creator type since errors were detected."); Log.v("Not removing proxy delegates and creator type since errors were detected.");
return; return;
} }
addTypesToBeRemoved(proxyDelegateFinder.DelegateTypes, "Proxy delegate type"); addTypesToBeRemoved(proxyDelegateFinder.DelegateTypes, "Proxy delegate type");
if (proxyDelegateFinder.RemovedDelegateCreatorCalls > 0) if (removeCreators && proxyDelegateFinder.RemovedDelegateCreatorCalls > 0)
addTypesToBeRemoved(proxyDelegateFinder.DelegateCreatorTypes, "Proxy delegate creator type"); addTypesToBeRemoved(proxyDelegateFinder.DelegateCreatorTypes, "Proxy delegate creator type");
} }

View File

@ -43,7 +43,7 @@ namespace de4dot.code.deobfuscators {
continue; continue;
var catchBlock = tryBlock.TryHandlerBlocks[0]; var catchBlock = tryBlock.TryHandlerBlocks[0];
if (catchBlock.HandlerType != ExceptionHandlerType.Catch || if (catchBlock.HandlerType != ExceptionHandlerType.Catch ||
!MemberReferenceHelper.verifyType(catchBlock.CatchType, "mscorlib", "System.Exception")) { catchBlock.CatchType.FullName != "System.Exception") {
continue; continue;
} }
if (catchBlock.BaseBlocks.Count != 1) if (catchBlock.BaseBlocks.Count != 1)
@ -77,7 +77,7 @@ namespace de4dot.code.deobfuscators {
var calledMethod = callInstr.Operand as MethodReference; var calledMethod = callInstr.Operand as MethodReference;
if (calledMethod == null) if (calledMethod == null)
continue; continue;
if (!exceptionLoggerMethods.ContainsKey(calledMethod)) if (!isExceptionLogger(calledMethod))
continue; continue;
return true; return true;
@ -86,8 +86,16 @@ namespace de4dot.code.deobfuscators {
return false; return false;
} }
protected virtual bool isExceptionLogger(MethodReference method) {
return exceptionLoggerMethods.ContainsKey(method);
}
protected virtual bool HasExceptionLoggers {
get { return exceptionLoggerMethods.Count != 0; }
}
public bool remove(Blocks blocks) { public bool remove(Blocks blocks) {
if (exceptionLoggerMethods.Count == 0) if (!HasExceptionLoggers)
return false; return false;
TryBlock tryBlock; TryBlock tryBlock;

View File

@ -71,11 +71,11 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
} }
class AssemblyResolverInfo : ResolverInfoBase { class AssemblyResolverInfo : ResolverInfoBase {
TypeDefinition simpleZipType; MethodDefinition simpleZipTypeMethod;
List<EmbeddedAssemblyInfo> embeddedAssemblyInfos = new List<EmbeddedAssemblyInfo>(); List<EmbeddedAssemblyInfo> embeddedAssemblyInfos = new List<EmbeddedAssemblyInfo>();
public TypeDefinition SimpleZipType { public MethodDefinition SimpleZipTypeMethod {
get { return simpleZipType; } get { return simpleZipTypeMethod; }
} }
public IList<EmbeddedAssemblyInfo> EmbeddedAssemblyInfos { public IList<EmbeddedAssemblyInfo> EmbeddedAssemblyInfos {
@ -163,7 +163,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
var calledMethod = call.Operand as MethodReference; var calledMethod = call.Operand as MethodReference;
if (calledMethod == null) if (calledMethod == null)
continue; continue;
if (!SimpleZipInfo.isSimpleZipDecryptMethod_QuickCheck(module, calledMethod, out simpleZipType)) if (!SimpleZipInfo.isSimpleZipDecryptMethod_QuickCheck(module, calledMethod, out simpleZipTypeMethod))
continue; continue;
return; return;

View File

@ -24,267 +24,127 @@ using Mono.Cecil.Cil;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.deobfuscators.SmartAssembly { namespace de4dot.code.deobfuscators.SmartAssembly {
class AutomatedErrorReportingFinder { class AutomatedErrorReportingFinder : ExceptionLoggerRemover {
ModuleDefinition module; ModuleDefinition module;
ExceptionLoggerRemover exceptionLoggerRemover = new ExceptionLoggerRemover(); bool enabled;
TypeDefinition automatedErrorReportingType;
int constantArgs;
AerVersion aerVersion;
enum AerVersion { protected override bool HasExceptionLoggers {
V0, get { return enabled; }
V1,
V2,
V3,
}
public ExceptionLoggerRemover ExceptionLoggerRemover {
get { return exceptionLoggerRemover; }
}
public TypeDefinition Type {
get { return automatedErrorReportingType; }
}
public bool Detected {
get { return automatedErrorReportingType != null; }
} }
public AutomatedErrorReportingFinder(ModuleDefinition module) { public AutomatedErrorReportingFinder(ModuleDefinition module) {
this.module = module; this.module = module;
} }
protected override bool isExceptionLogger(MethodReference method) {
return isExceptionLoggerMethod(method);
}
public void find() { public void find() {
foreach (var type in module.Types) { var entryPoint = module.EntryPoint;
if (detectAutomatedErrorReportingType(type)) if (entryPoint == null)
break; enabled = true;
}
}
bool detectAutomatedErrorReportingType(TypeDefinition type) {
if (automatedErrorReportingType != null)
return false;
const int MIN_HELPER_METHODS = 6;
constantArgs = 0;
var methods = new List<MethodDefinition>();
MethodDefinition mainMethod = null;
foreach (var method in type.Methods) {
if (isAutomatedErrorReportingMethodHelper(method))
methods.Add(method);
else if (isAutomatedErrorReportingMethod(method))
mainMethod = method;
else
continue;
initializeConstantArgs(method);
}
if (mainMethod == null)
return false;
if (isV0(type)) {
aerVersion = AerVersion.V0;
foreach (var method in type.Methods) {
if (method.IsStatic)
exceptionLoggerRemover.add(method);
}
}
else { else {
if (methods.Count < MIN_HELPER_METHODS) MethodDefinition exceptionMethod;
return false; enabled = checkMethod(entryPoint, out exceptionMethod);
}
}
if (isV1(mainMethod)) bool checkMethod(MethodDefinition method, out MethodDefinition exceptionMethod) {
aerVersion = AerVersion.V1; exceptionMethod = null;
else if (isV2(mainMethod))
aerVersion = AerVersion.V2;
else
aerVersion = AerVersion.V3;
methods.Sort((a, b) => Utils.compareInt32(a.Parameters.Count, b.Parameters.Count)); var body = method.Body;
for (int i = 0; i < methods.Count; i++) { if (body == null)
var method = methods[i]; return false;
if (method.Parameters.Count != i + constantArgs) var instrs = body.Instructions;
return false; if (instrs.Count < 1)
var methodCalls = DotNetUtils.getMethodCallCounts(method); return false;
if (methodCalls.count(mainMethod.FullName) != 1) if (body.ExceptionHandlers.Count == 0)
return false; return false;
var eh = body.ExceptionHandlers[body.ExceptionHandlers.Count - 1];
if (eh.HandlerType != ExceptionHandlerType.Catch)
return false;
if (eh.FilterStart != null)
return false;
if (eh.CatchType == null || eh.CatchType.FullName != "System.Exception")
return false;
if (eh.HandlerStart == null)
return false;
int handlerStart = instrs.IndexOf(eh.HandlerStart);
int handlerEnd = eh.HandlerEnd == null ? instrs.Count : instrs.IndexOf(eh.HandlerEnd);
exceptionMethod = DotNetUtils.getMethod(module, checkHandler(instrs, handlerStart, handlerEnd));
if (exceptionMethod == null || !exceptionMethod.IsStatic || exceptionMethod.Body == null)
return false;
return isExceptionLoggerMethod(exceptionMethod);
}
MethodReference checkHandler(IList<Instruction> instrs, int start, int end) {
MethodReference calledMethod = null;
for (int i = start; i < end; i++) {
var instr = instrs[i];
if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) {
if (calledMethod != null)
return null;
var method = instr.Operand as MethodReference;
if (method == null)
return null;
calledMethod = method;
} }
} }
exceptionLoggerRemover.add(mainMethod); return calledMethod;
foreach (var method in methods)
exceptionLoggerRemover.add(method);
automatedErrorReportingType = type;
if (aerVersion == AerVersion.V1) {
foreach (var method in type.Methods) {
if (DotNetUtils.isMethod(method, "System.Exception", "(System.Int32,System.Object[])"))
exceptionLoggerRemover.add(method);
}
}
initUnhandledExceptionFilterMethods();
return true;
} }
void initializeConstantArgs(MethodDefinition method) { static bool isExceptionLoggerMethod(MethodReference method) {
if (constantArgs > 0) if (method.Name == ".ctor" || method.Name == ".cctor")
return; return false;
constantArgs = getConstantArgs(method);
}
static int getConstantArgs(MethodDefinition method) { var parameters = method.Parameters;
if (method.Parameters.Count >= 2) { if (parameters.Count < 1)
if (isV1(method) || isV2(method)) return false;
return 2;
}
return 1;
}
static string[] v0Fields = new string[] { var rtype = method.MethodReturnType.ReturnType.FullName;
"System.Int32", var type0 = parameters[0].ParameterType.FullName;
"System.Object[]", var type1 = parameters.Count < 2 ? "" : parameters[1].ParameterType.FullName;
}; int index;
static bool isV0(TypeDefinition type) { if (rtype == "System.Void") {
if (!new FieldTypes(type).exactly(v0Fields)) if (type0 == "System.Exception" && type1 == "System.Int32")
return false; index = 2;
if (type.Methods.Count != 3) else if (type0 == "System.Object[]" && type1 == "System.Exception")
return false; return true;
if (type.HasEvents || type.HasProperties) else if (parameters.Count == 2 && type0 == "System.Int32" && type1 == "System.Object[]")
return false; return true;
MethodDefinition ctor = null, meth1 = null, meth2 = null; else if (type0 == "System.Exception")
foreach (var method in type.Methods) { index = 1;
if (method.Name == ".ctor") {
ctor = method;
continue;
}
if (!method.IsStatic)
return false;
if (DotNetUtils.isMethod(method, "System.Exception", "(System.Int32,System.Object[])"))
meth1 = method;
else if (DotNetUtils.isMethod(method, "System.Exception", "(System.Int32,System.Exception,System.Object[])"))
meth2 = method;
else else
return false; return false;
} }
else if (rtype == "System.Exception") {
return ctor != null && meth1 != null && meth2 != null; if (type0 == "System.Exception" && type1 == "System.Int32")
} index = 2;
else if (type0 == "System.Int32" && type1 == "System.Exception")
static bool isV1(MethodDefinition method) { index = 2;
if (method.Parameters.Count < 2) else if (parameters.Count == 2 && type0 == "System.Int32" && type1 == "System.Object[]")
return false; return true;
var p0 = method.Parameters[0].ParameterType.FullName; else if (type0 == "System.Exception")
var p1 = method.Parameters[1].ParameterType.FullName; index = 1;
return p0 == "System.Int32" && p1 == "System.Exception"; else
}
static bool isV2(MethodDefinition method) {
if (method.Parameters.Count < 2)
return false;
var p0 = method.Parameters[0].ParameterType.FullName;
var p1 = method.Parameters[1].ParameterType.FullName;
return p0 == "System.Exception" && p1 == "System.Int32";
}
bool isAutomatedErrorReportingMethodHelper(MethodDefinition method) {
if (!method.HasBody || !method.IsStatic || method.Name == ".ctor")
return false;
if (DotNetUtils.hasReturnValue(method) && method.MethodReturnType.ReturnType.FullName != "System.Exception")
return false;
if (method.Parameters.Count == 0)
return false;
if (!isV1(method) && !isV2(method) && method.Parameters[0].ParameterType.FullName != "System.Exception")
return false;
for (int i = getConstantArgs(method); i < method.Parameters.Count; i++) {
if (method.Parameters[i].ParameterType.FullName != "System.Object")
return false; return false;
} }
return true; else
}
bool isAutomatedErrorReportingMethod(MethodDefinition method) {
if (!method.HasBody || !method.IsStatic || method.Name == ".ctor")
return false; return false;
return
// 5.x-6.x
DotNetUtils.isMethod(method, "System.Void", "(System.Exception,System.Object[])") ||
// 5.x-6.x
DotNetUtils.isMethod(method, "System.Void", "(System.Exception,System.Int32,System.Object[])") ||
// 3.x-4.x
DotNetUtils.isMethod(method, "System.Exception", "(System.Exception,System.Object[])") ||
// 2.x-4.x
DotNetUtils.isMethod(method, "System.Exception", "(System.Exception,System.Int32,System.Object[])") ||
// 1.x
DotNetUtils.isMethod(method, "System.Exception", "(System.Int32,System.Exception,System.Object[])");
}
void initUnhandledExceptionFilterMethods() { if (index + 1 == parameters.Count && parameters[index].ParameterType.FullName == "System.Object[]")
var main = module.EntryPoint; return true;
if (main == null || !main.HasBody)
return;
if (!main.Body.HasExceptionHandlers)
return;
MethodDefinition mainExceptionHandlerMethod = null; for (int i = index; i < parameters.Count; i++) {
var instructions = main.Body.Instructions; if (parameters[i].ParameterType.FullName != "System.Object")
for (int i = 0; i < instructions.Count; i++) { return false;
var call = instructions[i];
if (call.OpCode != OpCodes.Call)
continue;
var method = getMainExceptionHandlerMethod(call.Operand as MethodReference);
if (method == null)
continue;
mainExceptionHandlerMethod = method; // Use the last one we find
} }
if (mainExceptionHandlerMethod != null) return true;
exceptionLoggerRemover.add(mainExceptionHandlerMethod);
}
MethodDefinition getMainExceptionHandlerMethod(MethodReference methodReference) {
var type = DotNetUtils.getType(module, methodReference.DeclaringType);
var method = DotNetUtils.getMethod(type, methodReference);
if (method == null || !method.IsStatic)
return null;
if (DotNetUtils.hasReturnValue(method))
return null;
switch (aerVersion) {
case AerVersion.V0:
case AerVersion.V1:
if (!DotNetUtils.isMethod(method, "System.Void", "(System.Int32,System.Object[])"))
return null;
break;
case AerVersion.V2:
if (method.Parameters.Count < 2)
return null;
if (method.Parameters[0].ParameterType.ToString() != "System.Exception")
return null;
if (method.Parameters[1].ParameterType.ToString() != "System.Int32")
return null;
if (method.Parameters[method.Parameters.Count - 1].ParameterType.ToString() != "System.Object[]")
return null;
break;
case AerVersion.V3:
if (method.Parameters.Count < 1)
return null;
if (method.Parameters[0].ParameterType.ToString() != "System.Exception")
return null;
if (method.Parameters[method.Parameters.Count - 1].ParameterType.ToString() != "System.Object[]")
return null;
break;
default:
throw new ApplicationException("Invalid AER version");
}
return method;
} }
} }
} }

View File

@ -72,6 +72,8 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
class Deobfuscator : DeobfuscatorBase { class Deobfuscator : DeobfuscatorBase {
Options options; Options options;
bool foundVersion = false; bool foundVersion = false;
Version approxVersion = new Version(0, 0, 0, 0);
bool canRemoveTypes;
string poweredByAttributeString = null; string poweredByAttributeString = null;
string obfuscatorName = DeobfuscatorInfo.THE_NAME; string obfuscatorName = DeobfuscatorInfo.THE_NAME;
bool foundSmartAssemblyAttribute = false; bool foundSmartAssemblyAttribute = false;
@ -123,8 +125,6 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
public override void init(ModuleDefinition module) { public override void init(ModuleDefinition module) {
base.init(module); base.init(module);
automatedErrorReportingFinder = new AutomatedErrorReportingFinder(module);
tamperProtectionRemover = new TamperProtectionRemover(module);
} }
protected override int detectInternal() { protected override int detectInternal() {
@ -133,12 +133,6 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
if (foundSmartAssemblyAttribute) if (foundSmartAssemblyAttribute)
val += 100; val += 100;
// Since we don't remove this type, we will detect it even when we've deobfuscated
// an assembly. Don't use this code for now. When the type is removed, this code
// should be re-enabled.
// if (automatedErrorReportingFinder.Detected)
// val += 10;
if (memoryManagerInfo.Detected) if (memoryManagerInfo.Detected)
val += 10; val += 10;
@ -146,10 +140,10 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
} }
protected override void scanForObfuscator() { protected override void scanForObfuscator() {
proxyDelegateFinder = new ProxyDelegateFinder(module, DeobfuscatedFile);
findSmartAssemblyAttributes(); findSmartAssemblyAttributes();
findAutomatedErrorReportingType();
memoryManagerInfo = new MemoryManagerInfo(module); memoryManagerInfo = new MemoryManagerInfo(module);
memoryManagerInfo.find();
proxyDelegateFinder = new ProxyDelegateFinder(module, DeobfuscatedFile);
proxyDelegateFinder.findDelegateCreator(module); proxyDelegateFinder.findDelegateCreator(module);
if (!foundVersion) if (!foundVersion)
@ -173,43 +167,53 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
poweredByAttributeString = s; poweredByAttributeString = s;
var val = System.Text.RegularExpressions.Regex.Match(s, @"^Powered by (SmartAssembly \d+\.\d+\.\d+\.\d+)$"); var val = System.Text.RegularExpressions.Regex.Match(s, @"^Powered by (SmartAssembly (\d+)\.(\d+)\.(\d+)\.(\d+))$");
if (val.Groups.Count < 2) if (val.Groups.Count < 6)
return; return;
ObfuscatorName = val.Groups[1].ToString(); ObfuscatorName = val.Groups[1].ToString();
approxVersion = new Version(int.Parse(val.Groups[2].ToString()),
int.Parse(val.Groups[3].ToString()),
int.Parse(val.Groups[4].ToString()),
int.Parse(val.Groups[5].ToString()));
return; return;
} }
void guessVersion() { void guessVersion() {
if (poweredByAttributeString == "Powered by SmartAssembly") { if (poweredByAttributeString == "Powered by SmartAssembly") {
ObfuscatorName = "SmartAssembly 5.0/5.1"; ObfuscatorName = "SmartAssembly 5.0/5.1";
approxVersion = new Version(5, 0, 0, 0);
return; return;
} }
if (poweredByAttributeString == "Powered by {smartassembly}") { if (poweredByAttributeString == "Powered by {smartassembly}") {
// It's SA 1.x - 4.x // It's SA 1.x - 4.x
if (hasEmptyClassesInEveryNamespace() || proxyDelegateFinder.Detected) { if (proxyDelegateFinder.Detected || hasEmptyClassesInEveryNamespace()) {
ObfuscatorName = "SmartAssembly 4.x"; ObfuscatorName = "SmartAssembly 4.x";
approxVersion = new Version(4, 0, 0, 0);
return; return;
} }
int ver = checkTypeIdAttribute(); int ver = checkTypeIdAttribute();
if (ver == 2) { if (ver == 2) {
ObfuscatorName = "SmartAssembly 2.x"; ObfuscatorName = "SmartAssembly 2.x";
approxVersion = new Version(2, 0, 0, 0);
return; return;
} }
if (ver == 1) { if (ver == 1) {
ObfuscatorName = "SmartAssembly 1.x-2.x"; ObfuscatorName = "SmartAssembly 1.x-2.x";
approxVersion = new Version(1, 0, 0, 0);
return; return;
} }
if (hasModuleCctor()) { if (hasModuleCctor()) {
ObfuscatorName = "SmartAssembly 3.x"; ObfuscatorName = "SmartAssembly 3.x";
approxVersion = new Version(3, 0, 0, 0);
return; return;
} }
ObfuscatorName = "SmartAssembly 1.x-4.x"; ObfuscatorName = "SmartAssembly 1.x-4.x";
approxVersion = new Version(1, 0, 0, 0);
return; return;
} }
} }
@ -290,16 +294,18 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
return true; return true;
} }
void findAutomatedErrorReportingType() {
automatedErrorReportingFinder.find();
}
public override void deobfuscateBegin() { public override void deobfuscateBegin() {
base.deobfuscateBegin(); base.deobfuscateBegin();
tamperProtectionRemover = new TamperProtectionRemover(module);
automatedErrorReportingFinder = new AutomatedErrorReportingFinder(module);
automatedErrorReportingFinder.find();
if (options.RemoveMemoryManager) { if (options.RemoveMemoryManager) {
addModuleCctorInitCallToBeRemoved(memoryManagerInfo.CctorInitMethod); addModuleCctorInitCallToBeRemoved(memoryManagerInfo.CctorInitMethod);
addCallToBeRemoved(module.EntryPoint, memoryManagerInfo.CctorInitMethod); addCallToBeRemoved(module.EntryPoint, memoryManagerInfo.CctorInitMethod);
} }
initDecrypters(); initDecrypters();
proxyDelegateFinder.find(); proxyDelegateFinder.find();
} }
@ -307,7 +313,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
void initDecrypters() { void initDecrypters() {
assemblyResolverInfo = new AssemblyResolverInfo(module, DeobfuscatedFile, this); assemblyResolverInfo = new AssemblyResolverInfo(module, DeobfuscatedFile, this);
assemblyResolverInfo.findTypes(); assemblyResolverInfo.findTypes();
resourceDecrypterInfo = new ResourceDecrypterInfo(module, assemblyResolverInfo.SimpleZipType, DeobfuscatedFile); resourceDecrypterInfo = new ResourceDecrypterInfo(module, assemblyResolverInfo.SimpleZipTypeMethod, DeobfuscatedFile);
resourceResolverInfo = new ResourceResolverInfo(module, DeobfuscatedFile, this, assemblyResolverInfo); resourceResolverInfo = new ResourceResolverInfo(module, DeobfuscatedFile, this, assemblyResolverInfo);
resourceResolverInfo.findTypes(); resourceResolverInfo.findTypes();
resourceDecrypter = new ResourceDecrypter(resourceDecrypterInfo); resourceDecrypter = new ResourceDecrypter(resourceDecrypterInfo);
@ -323,7 +329,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
addModuleCctorInitCallToBeRemoved(resourceResolverInfo.CallResolverMethod); addModuleCctorInitCallToBeRemoved(resourceResolverInfo.CallResolverMethod);
addCallToBeRemoved(module.EntryPoint, resourceResolverInfo.CallResolverMethod); addCallToBeRemoved(module.EntryPoint, resourceResolverInfo.CallResolverMethod);
resourceDecrypterInfo.setSimpleZipType(getGlobalSimpleZipType(), DeobfuscatedFile); resourceDecrypterInfo.setSimpleZipType(getGlobalSimpleZipTypeMethod(), DeobfuscatedFile);
if (!decryptResources()) if (!decryptResources())
throw new ApplicationException("Could not decrypt resources"); throw new ApplicationException("Could not decrypt resources");
@ -350,12 +356,12 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
return true; return true;
} }
TypeDefinition getGlobalSimpleZipType() { MethodDefinition getGlobalSimpleZipTypeMethod() {
if (assemblyResolverInfo.SimpleZipType != null) if (assemblyResolverInfo.SimpleZipTypeMethod != null)
return assemblyResolverInfo.SimpleZipType; return assemblyResolverInfo.SimpleZipTypeMethod;
foreach (var info in stringDecrypterInfos) { foreach (var info in stringDecrypterInfos) {
if (info.SimpleZipType != null) if (info.SimpleZipTypeMethod != null)
return info.SimpleZipType; return info.SimpleZipTypeMethod;
} }
return null; return null;
} }
@ -383,7 +389,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
if (initd.ContainsKey(info)) if (initd.ContainsKey(info))
continue; continue;
if (info.init(this, DeobfuscatedFile)) { if (info.init(this, DeobfuscatedFile)) {
resourceDecrypterInfo.setSimpleZipType(info.SimpleZipType, DeobfuscatedFile); resourceDecrypterInfo.setSimpleZipType(info.SimpleZipTypeMethod, DeobfuscatedFile);
initdInfo = info; initdInfo = info;
break; break;
} }
@ -436,7 +442,8 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
} }
public override void deobfuscateEnd() { public override void deobfuscateEnd() {
removeProxyDelegates(proxyDelegateFinder); canRemoveTypes = findBigType() == null;
removeProxyDelegates(proxyDelegateFinder, canRemoveTypes);
removeMemoryManagerStuff(); removeMemoryManagerStuff();
removeTamperProtectionStuff(); removeTamperProtectionStuff();
removeStringDecryptionStuff(); removeStringDecryptionStuff();
@ -445,7 +452,37 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
base.deobfuscateEnd(); base.deobfuscateEnd();
} }
TypeDefinition findBigType() {
if (approxVersion <= new Version(6, 5, 3, 53))
return null;
TypeDefinition bigType = null;
foreach (var type in module.Types) {
if (isBigType(type)) {
if (bigType == null || type.Methods.Count > bigType.Methods.Count)
bigType = type;
}
}
return bigType;
}
bool isBigType(TypeDefinition type) {
if (type.Methods.Count < 50)
return false;
if (type.HasProperties || type.HasEvents)
return false;
if (type.Fields.Count > 3)
return false;
foreach (var method in type.Methods) {
if (!method.IsStatic)
return false;
}
return true;
}
void removeResolverInfoTypes(ResolverInfoBase info, string typeName) { void removeResolverInfoTypes(ResolverInfoBase info, string typeName) {
if (!canRemoveTypes)
return;
addTypeToBeRemoved(info.CallResolverType, string.Format("{0} resolver type #1", typeName)); addTypeToBeRemoved(info.CallResolverType, string.Format("{0} resolver type #1", typeName));
addTypeToBeRemoved(info.Type, string.Format("{0} resolver type #2", typeName)); addTypeToBeRemoved(info.Type, string.Format("{0} resolver type #2", typeName));
} }
@ -453,7 +490,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
void removeAutomatedErrorReportingCode(Blocks blocks) { void removeAutomatedErrorReportingCode(Blocks blocks) {
if (!options.RemoveAutomatedErrorReporting) if (!options.RemoveAutomatedErrorReporting)
return; return;
if (automatedErrorReportingFinder.ExceptionLoggerRemover.remove(blocks)) if (automatedErrorReportingFinder.remove(blocks))
Log.v("Removed Automated Error Reporting code"); Log.v("Removed Automated Error Reporting code");
} }
@ -465,7 +502,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
} }
void removeMemoryManagerStuff() { void removeMemoryManagerStuff() {
if (!options.RemoveMemoryManager) if (!canRemoveTypes || !options.RemoveMemoryManager)
return; return;
addTypeToBeRemoved(memoryManagerInfo.Type, "Memory manager type"); addTypeToBeRemoved(memoryManagerInfo.Type, "Memory manager type");
} }
@ -489,9 +526,11 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
addResourceToBeRemoved(info.StringsResource, "Encrypted strings"); addResourceToBeRemoved(info.StringsResource, "Encrypted strings");
addFieldsToBeRemoved(info.getAllStringDelegateFields(), "String decrypter delegate field"); addFieldsToBeRemoved(info.getAllStringDelegateFields(), "String decrypter delegate field");
addTypeToBeRemoved(info.StringsEncodingClass, "String decrypter type"); if (canRemoveTypes) {
addTypeToBeRemoved(info.StringsType, "Creates the string decrypter delegates"); addTypeToBeRemoved(info.StringsEncodingClass, "String decrypter type");
addTypeToBeRemoved(info.GetStringDelegate, "String decrypter delegate type"); addTypeToBeRemoved(info.StringsType, "Creates the string decrypter delegates");
addTypeToBeRemoved(info.GetStringDelegate, "String decrypter delegate type");
}
} }
} }

View File

@ -40,10 +40,9 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
public MemoryManagerInfo(ModuleDefinition module) { public MemoryManagerInfo(ModuleDefinition module) {
this.module = module; this.module = module;
find();
} }
bool find() { public bool find() {
if (checkCalledMethods(DotNetUtils.getMethod(DotNetUtils.getModuleType(module), ".cctor"))) if (checkCalledMethods(DotNetUtils.getMethod(DotNetUtils.getModuleType(module), ".cctor")))
return true; return true;
if (checkCalledMethods(module.EntryPoint)) if (checkCalledMethods(module.EntryPoint))

View File

@ -112,7 +112,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
if (mostCalls == null) if (mostCalls == null)
return; return;
setDelegateCreatorMethod(DotNetUtils.getMethod(DotNetUtils.getType(module, mostCalls.DeclaringType), mostCalls)); setDelegateCreatorMethod(DotNetUtils.getMethod(module, mostCalls));
} }
} }
} }

View File

@ -28,7 +28,6 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
ISimpleDeobfuscator simpleDeobfuscator; ISimpleDeobfuscator simpleDeobfuscator;
IDeobfuscator deob; IDeobfuscator deob;
TypeDefinition resolverType; TypeDefinition resolverType;
TypeDefinition callResolverType;
MethodDefinition callResolverMethod; MethodDefinition callResolverMethod;
public TypeDefinition Type { public TypeDefinition Type {
@ -36,7 +35,13 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
} }
public TypeDefinition CallResolverType { public TypeDefinition CallResolverType {
get { return callResolverType; } get {
if (callResolverMethod == null)
return null;
if (!hasOnlyThisMethod(callResolverMethod.DeclaringType, callResolverMethod))
return null;
return callResolverMethod.DeclaringType;
}
} }
public MethodDefinition CallResolverMethod { public MethodDefinition CallResolverMethod {
@ -70,26 +75,17 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
continue; continue;
if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()")) if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()"))
continue; continue;
if (checkAttachAppType(tuple.Item1, method)) if (checkAttachAppMethod(method))
return true; return true;
} }
return false; return false;
} }
bool checkAttachAppType(TypeDefinition type, MethodDefinition attachAppMethod) { bool checkAttachAppMethod(MethodDefinition attachAppMethod) {
callResolverType = null; callResolverMethod = null;
if (!attachAppMethod.HasBody) if (!attachAppMethod.HasBody)
return false; return false;
if (type.Fields.Count > 0 || type.Properties.Count > 0 || type.Events.Count > 0)
return false;
foreach (var m in type.Methods) {
if (m.Name == ".cctor" || m.Name == ".ctor")
continue;
if (m == attachAppMethod)
continue;
return false;
}
foreach (var tuple in DotNetUtils.getCalledMethods(module, attachAppMethod)) { foreach (var tuple in DotNetUtils.getCalledMethods(module, attachAppMethod)) {
var method = tuple.Item2; var method = tuple.Item2;
@ -97,26 +93,25 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
continue; continue;
if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()")) if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()"))
continue; continue;
if (!checkResolverType(tuple.Item1, method)) if (!checkResolverInitMethod(method))
continue; continue;
callResolverMethod = attachAppMethod; callResolverMethod = attachAppMethod;
callResolverType = type;
return true; return true;
} }
if (hasLdftn(attachAppMethod)) { if (hasLdftn(attachAppMethod)) {
simpleDeobfuscator.deobfuscate(attachAppMethod); simpleDeobfuscator.deobfuscate(attachAppMethod);
foreach (var resolverHandler in getResolverHandlers(type, attachAppMethod)) { foreach (var resolverHandler in getResolverHandlers(attachAppMethod)) {
if (!resolverHandler.HasBody) if (!resolverHandler.HasBody)
continue; continue;
if (!checkResolverType2(resolverHandler.DeclaringType)) var resolverTypeTmp = getResolverType(resolverHandler);
if (resolverTypeTmp == null)
continue; continue;
deobfuscate(resolverHandler); deobfuscate(resolverHandler);
if (checkHandlerMethod(resolverHandler)) { if (checkHandlerMethod(resolverHandler)) {
callResolverMethod = attachAppMethod; callResolverMethod = attachAppMethod;
callResolverType = type; resolverType = resolverTypeTmp;
resolverType = resolverHandler.DeclaringType;
return true; return true;
} }
} }
@ -135,27 +130,21 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
return false; return false;
} }
bool checkResolverType2(TypeDefinition type) { bool checkResolverInitMethod(MethodDefinition initMethod) {
if (type.Properties.Count > 1 || type.Events.Count > 0)
return false;
if (!checkResolverType(type))
return false;
return true;
}
bool checkResolverType(TypeDefinition type, MethodDefinition initMethod) {
resolverType = null; resolverType = null;
if (!initMethod.HasBody) if (!initMethod.HasBody)
return false; return false;
if (!checkResolverType2(type))
return false;
deobfuscate(initMethod); deobfuscate(initMethod);
foreach (var handlerDef in getResolverHandlers(type, initMethod)) { foreach (var handlerDef in getResolverHandlers(initMethod)) {
deobfuscate(handlerDef); deobfuscate(handlerDef);
var resolverTypeTmp = getResolverType(handlerDef);
if (resolverTypeTmp == null)
continue;
if (checkHandlerMethod(handlerDef)) { if (checkHandlerMethod(handlerDef)) {
resolverType = type; resolverType = resolverTypeTmp;
return true; return true;
} }
} }
@ -168,10 +157,31 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
simpleDeobfuscator.decryptStrings(method, deob); simpleDeobfuscator.decryptStrings(method, deob);
} }
TypeDefinition getResolverType(MethodDefinition resolveHandler) {
if (resolveHandler.Body == null)
return null;
foreach (var instr in resolveHandler.Body.Instructions) {
if (instr.OpCode.Code != Code.Ldsfld && instr.OpCode.Code != Code.Stsfld)
continue;
var field = DotNetUtils.getField(module, instr.Operand as FieldReference);
if (field == null)
continue;
if (!checkResolverType(field.DeclaringType))
continue;
return field.DeclaringType;
}
if (checkResolverType(resolveHandler.DeclaringType))
return resolveHandler.DeclaringType;
return null;
}
protected abstract bool checkResolverType(TypeDefinition type); protected abstract bool checkResolverType(TypeDefinition type);
protected abstract bool checkHandlerMethod(MethodDefinition handler); protected abstract bool checkHandlerMethod(MethodDefinition handler);
static IEnumerable<MethodDefinition> getResolverHandlers(TypeDefinition type, MethodDefinition method) { IEnumerable<MethodDefinition> getResolverHandlers(MethodDefinition method) {
int numHandlers = 0; int numHandlers = 0;
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++) {
@ -184,7 +194,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
continue; continue;
var ldftn = instrs[2]; var ldftn = instrs[2];
var handlerDef = DotNetUtils.getMethod(type, ldftn.Operand as MethodReference); var handlerDef = DotNetUtils.getMethod(module, ldftn.Operand as MethodReference);
if (handlerDef == null) if (handlerDef == null)
continue; continue;
@ -204,5 +214,18 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
if (numHandlers == 0) if (numHandlers == 0)
yield return method; yield return method;
} }
static bool hasOnlyThisMethod(TypeDefinition type, MethodDefinition method) {
if (type == null || method == null)
return false;
foreach (var m in type.Methods) {
if (m.Name == ".cctor" || m.Name == ".ctor")
continue;
if (m == method)
continue;
return false;
}
return true;
}
} }
} }

View File

@ -25,7 +25,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.SmartAssembly { namespace de4dot.code.deobfuscators.SmartAssembly {
class ResourceDecrypterInfo { class ResourceDecrypterInfo {
ModuleDefinition module; ModuleDefinition module;
TypeDefinition simpleZipType; MethodDefinition simpleZipTypeDecryptMethod;
public byte[] DES_Key { get; private set; } public byte[] DES_Key { get; private set; }
public byte[] DES_IV { get; private set; } public byte[] DES_IV { get; private set; }
@ -33,56 +33,52 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
public byte[] AES_IV { get; private set; } public byte[] AES_IV { get; private set; }
public bool CanDecrypt { public bool CanDecrypt {
get { return simpleZipType != null; } get { return simpleZipTypeDecryptMethod != null; }
} }
public ResourceDecrypterInfo(ModuleDefinition module) { public ResourceDecrypterInfo(ModuleDefinition module) {
this.module = module; this.module = module;
} }
public ResourceDecrypterInfo(ModuleDefinition module, TypeDefinition simpleZipType, ISimpleDeobfuscator simpleDeobfuscator) public ResourceDecrypterInfo(ModuleDefinition module, MethodDefinition simpleZipTypeDecryptMethod, ISimpleDeobfuscator simpleDeobfuscator)
: this(module) { : this(module) {
setSimpleZipType(simpleZipType, simpleDeobfuscator); setSimpleZipType(simpleZipTypeDecryptMethod, simpleDeobfuscator);
} }
public void setSimpleZipType(TypeDefinition type, ISimpleDeobfuscator simpleDeobfuscator) { public void setSimpleZipType(MethodDefinition method, ISimpleDeobfuscator simpleDeobfuscator) {
if (simpleZipType != null || type == null) if (simpleZipTypeDecryptMethod != null || method == null)
return; return;
simpleZipType = type; simpleZipTypeDecryptMethod = method;
init(simpleDeobfuscator); init(simpleDeobfuscator, method);
} }
void init(ISimpleDeobfuscator simpleDeobfuscator) { void init(ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition method) {
var desList = new List<byte[]>(2); var desList = new List<byte[]>(2);
var aesList = new List<byte[]>(2); var aesList = new List<byte[]>(2);
if (simpleZipType != null) { var instructions = method.Body.Instructions;
foreach (var method in DotNetUtils.findMethods(simpleZipType.Methods, "System.Byte[]", new string[] { "System.Byte[]" }, true)) { simpleDeobfuscator.deobfuscate(method);
var instructions = method.Body.Instructions; for (int i = 0; i <= instructions.Count - 2; i++) {
simpleDeobfuscator.deobfuscate(method); var ldtoken = instructions[i];
for (int i = 0; i <= instructions.Count - 2; i++) { if (ldtoken.OpCode.Code != Code.Ldtoken)
var ldtoken = instructions[i]; continue;
if (ldtoken.OpCode.Code != Code.Ldtoken) var field = DotNetUtils.getField(module, ldtoken.Operand as FieldReference);
continue; if (field == null)
var field = DotNetUtils.getField(module, ldtoken.Operand as FieldReference); continue;
if (field == null) if (field.InitialValue == null)
continue; continue;
if (field.InitialValue == null)
continue;
var call = instructions[i + 1]; var call = instructions[i + 1];
if (call.OpCode.Code != Code.Call) if (call.OpCode.Code != Code.Call)
continue; continue;
var calledMethod = call.Operand as MethodReference; var calledMethod = call.Operand as MethodReference;
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "(System.Array,System.RuntimeFieldHandle)")) if (!DotNetUtils.isMethod(calledMethod, "System.Void", "(System.Array,System.RuntimeFieldHandle)"))
continue; continue;
if (field.InitialValue.Length == 8) if (field.InitialValue.Length == 8)
desList.Add(field.InitialValue); desList.Add(field.InitialValue);
else if (field.InitialValue.Length == 16) else if (field.InitialValue.Length == 16)
aesList.Add(field.InitialValue); aesList.Add(field.InitialValue);
}
}
} }
if (desList.Count >= 2) { if (desList.Count >= 2) {

View File

@ -23,18 +23,17 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.SmartAssembly { namespace de4dot.code.deobfuscators.SmartAssembly {
class SimpleZipInfo { class SimpleZipInfo {
public static bool isSimpleZipDecryptMethod_QuickCheck(ModuleDefinition module, MethodReference method, out TypeDefinition simpleZipType) { public static bool isSimpleZipDecryptMethod_QuickCheck(ModuleDefinition module, MethodReference method, out MethodDefinition simpleZipTypeMethod) {
simpleZipType = null; simpleZipTypeMethod = null;
if (!DotNetUtils.isMethod(method, "System.Byte[]", "(System.Byte[])")) if (!DotNetUtils.isMethod(method, "System.Byte[]", "(System.Byte[])"))
return false; return false;
var type = DotNetUtils.getType(module, method.DeclaringType); var methodDef = DotNetUtils.getMethod(DotNetUtils.getType(module, method.DeclaringType), method);
var methodDef = DotNetUtils.getMethod(type, method);
if (methodDef == null) if (methodDef == null)
return false; return false;
simpleZipType = type; simpleZipTypeMethod = methodDef;
return true; return true;
} }
} }

View File

@ -38,7 +38,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
TypeDefinition stringsEncodingClass; TypeDefinition stringsEncodingClass;
EmbeddedResource stringsResource; EmbeddedResource stringsResource;
int stringOffset; int stringOffset;
TypeDefinition simpleZipType; MethodDefinition simpleZipTypeMethod;
MethodDefinition stringDecrypterMethod; MethodDefinition stringDecrypterMethod;
StringDecrypterVersion decrypterVersion; StringDecrypterVersion decrypterVersion;
@ -58,8 +58,8 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
get { return resourceDecrypter == null || resourceDecrypter.CanDecrypt; } get { return resourceDecrypter == null || resourceDecrypter.CanDecrypt; }
} }
public TypeDefinition SimpleZipType { public MethodDefinition SimpleZipTypeMethod {
get { return simpleZipType; } get { return simpleZipTypeMethod; }
} }
public EmbeddedResource StringsResource { public EmbeddedResource StringsResource {
@ -71,7 +71,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
} }
public bool StringsEncrypted { public bool StringsEncrypted {
get { return simpleZipType != null; } get { return simpleZipTypeMethod != null; }
} }
public MethodDefinition StringDecrypterMethod { public MethodDefinition StringDecrypterMethod {
@ -148,9 +148,9 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
decrypterVersion = StringDecrypterVersion.V4; decrypterVersion = StringDecrypterVersion.V4;
} }
simpleZipType = findSimpleZipType(cctor) ?? findSimpleZipType(stringDecrypterMethod); simpleZipTypeMethod = findSimpleZipTypeMethod(cctor) ?? findSimpleZipTypeMethod(stringDecrypterMethod);
if (simpleZipType != null) if (simpleZipTypeMethod != null)
resourceDecrypter = new ResourceDecrypter(new ResourceDecrypterInfo(module, simpleZipType, simpleDeobfuscator)); resourceDecrypter = new ResourceDecrypter(new ResourceDecrypterInfo(module, simpleZipTypeMethod, simpleDeobfuscator));
return true; return true;
} }
@ -292,9 +292,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
return true; return true;
} }
// Find SmartAssembly.Zip.SimpleZip, which is the class that decrypts and inflates MethodDefinition findSimpleZipTypeMethod(MethodDefinition method) {
// data in the resources.
TypeDefinition findSimpleZipType(MethodDefinition method) {
if (method == null || method.Body == null) if (method == null || method.Body == null)
return null; return null;
var instructions = method.Body.Instructions; var instructions = method.Body.Instructions;
@ -302,7 +300,9 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
var call = instructions[i]; var call = instructions[i];
if (call.OpCode.Code != Code.Call) if (call.OpCode.Code != Code.Call)
continue; continue;
var calledMethod = call.Operand as MethodReference; var calledMethod = call.Operand as MethodDefinition;
if (calledMethod == null)
continue;
if (!DotNetUtils.isMethod(calledMethod, "System.Byte[]", "(System.Byte[])")) if (!DotNetUtils.isMethod(calledMethod, "System.Byte[]", "(System.Byte[])"))
continue; continue;
@ -315,11 +315,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
if (!MemberReferenceHelper.compareTypes(stringsEncodingClass, field.DeclaringType)) if (!MemberReferenceHelper.compareTypes(stringsEncodingClass, field.DeclaringType))
continue; continue;
var type = DotNetUtils.getType(module, calledMethod.DeclaringType); return calledMethod;
if (type == null)
continue;
return type;
} }
return null; return null;

View File

@ -607,18 +607,16 @@ namespace de4dot.code.renamer.asmmodules {
continue; continue;
if (!resolvedAllInterfaces() || !resolvedBaseClasses()) if (!resolvedAllInterfaces() || !resolvedBaseClasses())
continue; continue;
string errMsg = string.Format(
"Could not find interface method {0} ({1:X8}). Type: {2} ({3:X8})",
Utils.removeNewlines(pair.Key.MethodDefinition),
pair.Key.MethodDefinition.MetadataToken.ToInt32(),
Utils.removeNewlines(TypeDefinition),
TypeDefinition.MetadataToken.ToInt32());
// Ignore if COM class // Ignore if COM class
if (!TypeDefinition.IsImport && if (!TypeDefinition.IsImport &&
!hasAttribute("System.Runtime.InteropServices.ComImportAttribute") && !hasAttribute("System.Runtime.InteropServices.ComImportAttribute") &&
!hasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute")) !hasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute")) {
throw new ApplicationException(errMsg); Log.w("Could not find interface method {0} ({1:X8}). Type: {2} ({3:X8})",
Log.w("{0}", errMsg); Utils.removeNewlines(pair.Key.MethodDefinition),
pair.Key.MethodDefinition.MetadataToken.ToInt32(),
Utils.removeNewlines(TypeDefinition),
TypeDefinition.MetadataToken.ToInt32());
}
} }
} }

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]

View File

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.4.2.3405")] [assembly: AssemblyVersion("1.4.4.3405")]
[assembly: AssemblyFileVersion("1.4.2.3405")] [assembly: AssemblyFileVersion("1.4.4.3405")]