Merge branch 'master' into newcode
This commit is contained in:
commit
ed31063b1b
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
|
@ -441,6 +441,8 @@ namespace de4dot.blocks {
|
|||
}
|
||||
|
||||
public static FieldDefinition getField(ModuleDefinition module, FieldReference field) {
|
||||
if (field == null)
|
||||
return null;
|
||||
if (field is FieldDefinition)
|
||||
return (FieldDefinition)field;
|
||||
return getField(getType(module, field.DeclaringType), field);
|
||||
|
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
2
cecil
2
cecil
|
@ -1 +1 @@
|
|||
Subproject commit 188d7947ad6c9a260099f7b58e2595a13e9a5f07
|
||||
Subproject commit 2bc3f2014c697f697e8bb09e5ca004e5e252fe06
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
|
@ -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) {
|
||||
Log.v("Not removing proxy delegates and creator type since errors were detected.");
|
||||
return;
|
||||
}
|
||||
addTypesToBeRemoved(proxyDelegateFinder.DelegateTypes, "Proxy delegate type");
|
||||
if (proxyDelegateFinder.RemovedDelegateCreatorCalls > 0)
|
||||
if (removeCreators && proxyDelegateFinder.RemovedDelegateCreatorCalls > 0)
|
||||
addTypesToBeRemoved(proxyDelegateFinder.DelegateCreatorTypes, "Proxy delegate creator type");
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace de4dot.code.deobfuscators {
|
|||
continue;
|
||||
var catchBlock = tryBlock.TryHandlerBlocks[0];
|
||||
if (catchBlock.HandlerType != ExceptionHandlerType.Catch ||
|
||||
!MemberReferenceHelper.verifyType(catchBlock.CatchType, "mscorlib", "System.Exception")) {
|
||||
catchBlock.CatchType.FullName != "System.Exception") {
|
||||
continue;
|
||||
}
|
||||
if (catchBlock.BaseBlocks.Count != 1)
|
||||
|
@ -77,7 +77,7 @@ namespace de4dot.code.deobfuscators {
|
|||
var calledMethod = callInstr.Operand as MethodReference;
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
if (!exceptionLoggerMethods.ContainsKey(calledMethod))
|
||||
if (!isExceptionLogger(calledMethod))
|
||||
continue;
|
||||
|
||||
return true;
|
||||
|
@ -86,8 +86,16 @@ namespace de4dot.code.deobfuscators {
|
|||
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) {
|
||||
if (exceptionLoggerMethods.Count == 0)
|
||||
if (!HasExceptionLoggers)
|
||||
return false;
|
||||
|
||||
TryBlock tryBlock;
|
||||
|
|
|
@ -71,11 +71,11 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
}
|
||||
|
||||
class AssemblyResolverInfo : ResolverInfoBase {
|
||||
TypeDefinition simpleZipType;
|
||||
MethodDefinition simpleZipTypeMethod;
|
||||
List<EmbeddedAssemblyInfo> embeddedAssemblyInfos = new List<EmbeddedAssemblyInfo>();
|
||||
|
||||
public TypeDefinition SimpleZipType {
|
||||
get { return simpleZipType; }
|
||||
public MethodDefinition SimpleZipTypeMethod {
|
||||
get { return simpleZipTypeMethod; }
|
||||
}
|
||||
|
||||
public IList<EmbeddedAssemblyInfo> EmbeddedAssemblyInfos {
|
||||
|
@ -163,7 +163,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
var calledMethod = call.Operand as MethodReference;
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
if (!SimpleZipInfo.isSimpleZipDecryptMethod_QuickCheck(module, calledMethod, out simpleZipType))
|
||||
if (!SimpleZipInfo.isSimpleZipDecryptMethod_QuickCheck(module, calledMethod, out simpleZipTypeMethod))
|
||||
continue;
|
||||
|
||||
return;
|
||||
|
|
|
@ -24,267 +24,127 @@ using Mono.Cecil.Cil;
|
|||
using de4dot.blocks;
|
||||
|
||||
namespace de4dot.code.deobfuscators.SmartAssembly {
|
||||
class AutomatedErrorReportingFinder {
|
||||
class AutomatedErrorReportingFinder : ExceptionLoggerRemover {
|
||||
ModuleDefinition module;
|
||||
ExceptionLoggerRemover exceptionLoggerRemover = new ExceptionLoggerRemover();
|
||||
TypeDefinition automatedErrorReportingType;
|
||||
int constantArgs;
|
||||
AerVersion aerVersion;
|
||||
bool enabled;
|
||||
|
||||
enum AerVersion {
|
||||
V0,
|
||||
V1,
|
||||
V2,
|
||||
V3,
|
||||
}
|
||||
|
||||
public ExceptionLoggerRemover ExceptionLoggerRemover {
|
||||
get { return exceptionLoggerRemover; }
|
||||
}
|
||||
|
||||
public TypeDefinition Type {
|
||||
get { return automatedErrorReportingType; }
|
||||
}
|
||||
|
||||
public bool Detected {
|
||||
get { return automatedErrorReportingType != null; }
|
||||
protected override bool HasExceptionLoggers {
|
||||
get { return enabled; }
|
||||
}
|
||||
|
||||
public AutomatedErrorReportingFinder(ModuleDefinition module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
protected override bool isExceptionLogger(MethodReference method) {
|
||||
return isExceptionLoggerMethod(method);
|
||||
}
|
||||
|
||||
public void find() {
|
||||
foreach (var type in module.Types) {
|
||||
if (detectAutomatedErrorReportingType(type))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
var entryPoint = module.EntryPoint;
|
||||
if (entryPoint == null)
|
||||
enabled = true;
|
||||
else {
|
||||
if (methods.Count < MIN_HELPER_METHODS)
|
||||
return false;
|
||||
|
||||
if (isV1(mainMethod))
|
||||
aerVersion = AerVersion.V1;
|
||||
else if (isV2(mainMethod))
|
||||
aerVersion = AerVersion.V2;
|
||||
else
|
||||
aerVersion = AerVersion.V3;
|
||||
|
||||
methods.Sort((a, b) => Utils.compareInt32(a.Parameters.Count, b.Parameters.Count));
|
||||
for (int i = 0; i < methods.Count; i++) {
|
||||
var method = methods[i];
|
||||
if (method.Parameters.Count != i + constantArgs)
|
||||
return false;
|
||||
var methodCalls = DotNetUtils.getMethodCallCounts(method);
|
||||
if (methodCalls.count(mainMethod.FullName) != 1)
|
||||
return false;
|
||||
MethodDefinition exceptionMethod;
|
||||
enabled = checkMethod(entryPoint, out exceptionMethod);
|
||||
}
|
||||
}
|
||||
|
||||
exceptionLoggerRemover.add(mainMethod);
|
||||
foreach (var method in methods)
|
||||
exceptionLoggerRemover.add(method);
|
||||
automatedErrorReportingType = type;
|
||||
bool checkMethod(MethodDefinition method, out MethodDefinition exceptionMethod) {
|
||||
exceptionMethod = null;
|
||||
|
||||
if (aerVersion == AerVersion.V1) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (DotNetUtils.isMethod(method, "System.Exception", "(System.Int32,System.Object[])"))
|
||||
exceptionLoggerRemover.add(method);
|
||||
}
|
||||
var body = method.Body;
|
||||
if (body == null)
|
||||
return false;
|
||||
var instrs = body.Instructions;
|
||||
if (instrs.Count < 1)
|
||||
return false;
|
||||
if (body.ExceptionHandlers.Count == 0)
|
||||
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);
|
||||
}
|
||||
|
||||
initUnhandledExceptionFilterMethods();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void initializeConstantArgs(MethodDefinition method) {
|
||||
if (constantArgs > 0)
|
||||
return;
|
||||
constantArgs = getConstantArgs(method);
|
||||
}
|
||||
|
||||
static int getConstantArgs(MethodDefinition method) {
|
||||
if (method.Parameters.Count >= 2) {
|
||||
if (isV1(method) || isV2(method))
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static string[] v0Fields = new string[] {
|
||||
"System.Int32",
|
||||
"System.Object[]",
|
||||
};
|
||||
static bool isV0(TypeDefinition type) {
|
||||
if (!new FieldTypes(type).exactly(v0Fields))
|
||||
return false;
|
||||
if (type.Methods.Count != 3)
|
||||
return false;
|
||||
if (type.HasEvents || type.HasProperties)
|
||||
return false;
|
||||
MethodDefinition ctor = null, meth1 = null, meth2 = null;
|
||||
foreach (var method in type.Methods) {
|
||||
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
|
||||
return false;
|
||||
}
|
||||
|
||||
return ctor != null && meth1 != null && meth2 != null;
|
||||
}
|
||||
|
||||
static bool isV1(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.Int32" && p1 == "System.Exception";
|
||||
}
|
||||
|
||||
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 true;
|
||||
}
|
||||
|
||||
bool isAutomatedErrorReportingMethod(MethodDefinition method) {
|
||||
if (!method.HasBody || !method.IsStatic || method.Name == ".ctor")
|
||||
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() {
|
||||
var main = module.EntryPoint;
|
||||
if (main == null || !main.HasBody)
|
||||
return;
|
||||
if (!main.Body.HasExceptionHandlers)
|
||||
return;
|
||||
|
||||
MethodDefinition mainExceptionHandlerMethod = null;
|
||||
var instructions = main.Body.Instructions;
|
||||
for (int i = 0; i < instructions.Count; i++) {
|
||||
var call = instructions[i];
|
||||
if (call.OpCode != OpCodes.Call)
|
||||
continue;
|
||||
var method = getMainExceptionHandlerMethod(call.Operand as MethodReference);
|
||||
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)
|
||||
continue;
|
||||
|
||||
mainExceptionHandlerMethod = method; // Use the last one we find
|
||||
return null;
|
||||
calledMethod = method;
|
||||
}
|
||||
}
|
||||
|
||||
if (mainExceptionHandlerMethod != null)
|
||||
exceptionLoggerRemover.add(mainExceptionHandlerMethod);
|
||||
return calledMethod;
|
||||
}
|
||||
|
||||
MethodDefinition getMainExceptionHandlerMethod(MethodReference methodReference) {
|
||||
var type = DotNetUtils.getType(module, methodReference.DeclaringType);
|
||||
var method = DotNetUtils.getMethod(type, methodReference);
|
||||
if (method == null || !method.IsStatic)
|
||||
return null;
|
||||
static bool isExceptionLoggerMethod(MethodReference method) {
|
||||
if (method.Name == ".ctor" || method.Name == ".cctor")
|
||||
return false;
|
||||
|
||||
if (DotNetUtils.hasReturnValue(method))
|
||||
return null;
|
||||
var parameters = method.Parameters;
|
||||
if (parameters.Count < 1)
|
||||
return false;
|
||||
|
||||
switch (aerVersion) {
|
||||
case AerVersion.V0:
|
||||
case AerVersion.V1:
|
||||
if (!DotNetUtils.isMethod(method, "System.Void", "(System.Int32,System.Object[])"))
|
||||
return null;
|
||||
break;
|
||||
var rtype = method.MethodReturnType.ReturnType.FullName;
|
||||
var type0 = parameters[0].ParameterType.FullName;
|
||||
var type1 = parameters.Count < 2 ? "" : parameters[1].ParameterType.FullName;
|
||||
int index;
|
||||
if (rtype == "System.Void") {
|
||||
if (type0 == "System.Exception" && type1 == "System.Int32")
|
||||
index = 2;
|
||||
else if (type0 == "System.Object[]" && type1 == "System.Exception")
|
||||
return true;
|
||||
else if (parameters.Count == 2 && type0 == "System.Int32" && type1 == "System.Object[]")
|
||||
return true;
|
||||
else if (type0 == "System.Exception")
|
||||
index = 1;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (rtype == "System.Exception") {
|
||||
if (type0 == "System.Exception" && type1 == "System.Int32")
|
||||
index = 2;
|
||||
else if (type0 == "System.Int32" && type1 == "System.Exception")
|
||||
index = 2;
|
||||
else if (parameters.Count == 2 && type0 == "System.Int32" && type1 == "System.Object[]")
|
||||
return true;
|
||||
else if (type0 == "System.Exception")
|
||||
index = 1;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
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;
|
||||
if (index + 1 == parameters.Count && parameters[index].ParameterType.FullName == "System.Object[]")
|
||||
return true;
|
||||
|
||||
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");
|
||||
for (int i = index; i < parameters.Count; i++) {
|
||||
if (parameters[i].ParameterType.FullName != "System.Object")
|
||||
return false;
|
||||
}
|
||||
|
||||
return method;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
class Deobfuscator : DeobfuscatorBase {
|
||||
Options options;
|
||||
bool foundVersion = false;
|
||||
Version approxVersion = new Version(0, 0, 0, 0);
|
||||
bool canRemoveTypes;
|
||||
string poweredByAttributeString = null;
|
||||
string obfuscatorName = DeobfuscatorInfo.THE_NAME;
|
||||
bool foundSmartAssemblyAttribute = false;
|
||||
|
@ -123,8 +125,6 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
|
||||
public override void init(ModuleDefinition module) {
|
||||
base.init(module);
|
||||
automatedErrorReportingFinder = new AutomatedErrorReportingFinder(module);
|
||||
tamperProtectionRemover = new TamperProtectionRemover(module);
|
||||
}
|
||||
|
||||
protected override int detectInternal() {
|
||||
|
@ -133,12 +133,6 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
if (foundSmartAssemblyAttribute)
|
||||
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)
|
||||
val += 10;
|
||||
|
||||
|
@ -146,10 +140,10 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
}
|
||||
|
||||
protected override void scanForObfuscator() {
|
||||
proxyDelegateFinder = new ProxyDelegateFinder(module, DeobfuscatedFile);
|
||||
findSmartAssemblyAttributes();
|
||||
findAutomatedErrorReportingType();
|
||||
memoryManagerInfo = new MemoryManagerInfo(module);
|
||||
memoryManagerInfo.find();
|
||||
proxyDelegateFinder = new ProxyDelegateFinder(module, DeobfuscatedFile);
|
||||
proxyDelegateFinder.findDelegateCreator(module);
|
||||
|
||||
if (!foundVersion)
|
||||
|
@ -173,43 +167,53 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
|
||||
poweredByAttributeString = s;
|
||||
|
||||
var val = System.Text.RegularExpressions.Regex.Match(s, @"^Powered by (SmartAssembly \d+\.\d+\.\d+\.\d+)$");
|
||||
if (val.Groups.Count < 2)
|
||||
var val = System.Text.RegularExpressions.Regex.Match(s, @"^Powered by (SmartAssembly (\d+)\.(\d+)\.(\d+)\.(\d+))$");
|
||||
if (val.Groups.Count < 6)
|
||||
return;
|
||||
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;
|
||||
}
|
||||
|
||||
void guessVersion() {
|
||||
if (poweredByAttributeString == "Powered by SmartAssembly") {
|
||||
ObfuscatorName = "SmartAssembly 5.0/5.1";
|
||||
approxVersion = new Version(5, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (poweredByAttributeString == "Powered by {smartassembly}") {
|
||||
// It's SA 1.x - 4.x
|
||||
|
||||
if (hasEmptyClassesInEveryNamespace() || proxyDelegateFinder.Detected) {
|
||||
if (proxyDelegateFinder.Detected || hasEmptyClassesInEveryNamespace()) {
|
||||
ObfuscatorName = "SmartAssembly 4.x";
|
||||
approxVersion = new Version(4, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
int ver = checkTypeIdAttribute();
|
||||
if (ver == 2) {
|
||||
ObfuscatorName = "SmartAssembly 2.x";
|
||||
approxVersion = new Version(2, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
if (ver == 1) {
|
||||
ObfuscatorName = "SmartAssembly 1.x-2.x";
|
||||
approxVersion = new Version(1, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasModuleCctor()) {
|
||||
ObfuscatorName = "SmartAssembly 3.x";
|
||||
approxVersion = new Version(3, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ObfuscatorName = "SmartAssembly 1.x-4.x";
|
||||
approxVersion = new Version(1, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -290,16 +294,18 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
return true;
|
||||
}
|
||||
|
||||
void findAutomatedErrorReportingType() {
|
||||
automatedErrorReportingFinder.find();
|
||||
}
|
||||
|
||||
public override void deobfuscateBegin() {
|
||||
base.deobfuscateBegin();
|
||||
|
||||
tamperProtectionRemover = new TamperProtectionRemover(module);
|
||||
automatedErrorReportingFinder = new AutomatedErrorReportingFinder(module);
|
||||
automatedErrorReportingFinder.find();
|
||||
|
||||
if (options.RemoveMemoryManager) {
|
||||
addModuleCctorInitCallToBeRemoved(memoryManagerInfo.CctorInitMethod);
|
||||
addCallToBeRemoved(module.EntryPoint, memoryManagerInfo.CctorInitMethod);
|
||||
}
|
||||
|
||||
initDecrypters();
|
||||
proxyDelegateFinder.find();
|
||||
}
|
||||
|
@ -307,7 +313,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
void initDecrypters() {
|
||||
assemblyResolverInfo = new AssemblyResolverInfo(module, DeobfuscatedFile, this);
|
||||
assemblyResolverInfo.findTypes();
|
||||
resourceDecrypterInfo = new ResourceDecrypterInfo(module, assemblyResolverInfo.SimpleZipType, DeobfuscatedFile);
|
||||
resourceDecrypterInfo = new ResourceDecrypterInfo(module, assemblyResolverInfo.SimpleZipTypeMethod, DeobfuscatedFile);
|
||||
resourceResolverInfo = new ResourceResolverInfo(module, DeobfuscatedFile, this, assemblyResolverInfo);
|
||||
resourceResolverInfo.findTypes();
|
||||
resourceDecrypter = new ResourceDecrypter(resourceDecrypterInfo);
|
||||
|
@ -323,7 +329,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
addModuleCctorInitCallToBeRemoved(resourceResolverInfo.CallResolverMethod);
|
||||
addCallToBeRemoved(module.EntryPoint, resourceResolverInfo.CallResolverMethod);
|
||||
|
||||
resourceDecrypterInfo.setSimpleZipType(getGlobalSimpleZipType(), DeobfuscatedFile);
|
||||
resourceDecrypterInfo.setSimpleZipType(getGlobalSimpleZipTypeMethod(), DeobfuscatedFile);
|
||||
|
||||
if (!decryptResources())
|
||||
throw new ApplicationException("Could not decrypt resources");
|
||||
|
@ -350,12 +356,12 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
return true;
|
||||
}
|
||||
|
||||
TypeDefinition getGlobalSimpleZipType() {
|
||||
if (assemblyResolverInfo.SimpleZipType != null)
|
||||
return assemblyResolverInfo.SimpleZipType;
|
||||
MethodDefinition getGlobalSimpleZipTypeMethod() {
|
||||
if (assemblyResolverInfo.SimpleZipTypeMethod != null)
|
||||
return assemblyResolverInfo.SimpleZipTypeMethod;
|
||||
foreach (var info in stringDecrypterInfos) {
|
||||
if (info.SimpleZipType != null)
|
||||
return info.SimpleZipType;
|
||||
if (info.SimpleZipTypeMethod != null)
|
||||
return info.SimpleZipTypeMethod;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -383,7 +389,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
if (initd.ContainsKey(info))
|
||||
continue;
|
||||
if (info.init(this, DeobfuscatedFile)) {
|
||||
resourceDecrypterInfo.setSimpleZipType(info.SimpleZipType, DeobfuscatedFile);
|
||||
resourceDecrypterInfo.setSimpleZipType(info.SimpleZipTypeMethod, DeobfuscatedFile);
|
||||
initdInfo = info;
|
||||
break;
|
||||
}
|
||||
|
@ -436,7 +442,8 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
}
|
||||
|
||||
public override void deobfuscateEnd() {
|
||||
removeProxyDelegates(proxyDelegateFinder);
|
||||
canRemoveTypes = findBigType() == null;
|
||||
removeProxyDelegates(proxyDelegateFinder, canRemoveTypes);
|
||||
removeMemoryManagerStuff();
|
||||
removeTamperProtectionStuff();
|
||||
removeStringDecryptionStuff();
|
||||
|
@ -445,7 +452,37 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
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) {
|
||||
if (!canRemoveTypes)
|
||||
return;
|
||||
addTypeToBeRemoved(info.CallResolverType, string.Format("{0} resolver type #1", typeName));
|
||||
addTypeToBeRemoved(info.Type, string.Format("{0} resolver type #2", typeName));
|
||||
}
|
||||
|
@ -453,7 +490,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
void removeAutomatedErrorReportingCode(Blocks blocks) {
|
||||
if (!options.RemoveAutomatedErrorReporting)
|
||||
return;
|
||||
if (automatedErrorReportingFinder.ExceptionLoggerRemover.remove(blocks))
|
||||
if (automatedErrorReportingFinder.remove(blocks))
|
||||
Log.v("Removed Automated Error Reporting code");
|
||||
}
|
||||
|
||||
|
@ -465,7 +502,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
}
|
||||
|
||||
void removeMemoryManagerStuff() {
|
||||
if (!options.RemoveMemoryManager)
|
||||
if (!canRemoveTypes || !options.RemoveMemoryManager)
|
||||
return;
|
||||
addTypeToBeRemoved(memoryManagerInfo.Type, "Memory manager type");
|
||||
}
|
||||
|
@ -489,11 +526,13 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
addResourceToBeRemoved(info.StringsResource, "Encrypted strings");
|
||||
addFieldsToBeRemoved(info.getAllStringDelegateFields(), "String decrypter delegate field");
|
||||
|
||||
if (canRemoveTypes) {
|
||||
addTypeToBeRemoved(info.StringsEncodingClass, "String decrypter type");
|
||||
addTypeToBeRemoved(info.StringsType, "Creates the string decrypter delegates");
|
||||
addTypeToBeRemoved(info.GetStringDelegate, "String decrypter delegate type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeStringsInitCode(Blocks blocks) {
|
||||
if (!canRemoveStringDecrypterStuff())
|
||||
|
|
|
@ -40,10 +40,9 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
|
||||
public MemoryManagerInfo(ModuleDefinition module) {
|
||||
this.module = module;
|
||||
find();
|
||||
}
|
||||
|
||||
bool find() {
|
||||
public bool find() {
|
||||
if (checkCalledMethods(DotNetUtils.getMethod(DotNetUtils.getModuleType(module), ".cctor")))
|
||||
return true;
|
||||
if (checkCalledMethods(module.EntryPoint))
|
||||
|
|
|
@ -112,7 +112,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
if (mostCalls == null)
|
||||
return;
|
||||
|
||||
setDelegateCreatorMethod(DotNetUtils.getMethod(DotNetUtils.getType(module, mostCalls.DeclaringType), mostCalls));
|
||||
setDelegateCreatorMethod(DotNetUtils.getMethod(module, mostCalls));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
ISimpleDeobfuscator simpleDeobfuscator;
|
||||
IDeobfuscator deob;
|
||||
TypeDefinition resolverType;
|
||||
TypeDefinition callResolverType;
|
||||
MethodDefinition callResolverMethod;
|
||||
|
||||
public TypeDefinition Type {
|
||||
|
@ -36,7 +35,13 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
@ -70,26 +75,17 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
continue;
|
||||
if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()"))
|
||||
continue;
|
||||
if (checkAttachAppType(tuple.Item1, method))
|
||||
if (checkAttachAppMethod(method))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool checkAttachAppType(TypeDefinition type, MethodDefinition attachAppMethod) {
|
||||
callResolverType = null;
|
||||
bool checkAttachAppMethod(MethodDefinition attachAppMethod) {
|
||||
callResolverMethod = null;
|
||||
if (!attachAppMethod.HasBody)
|
||||
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)) {
|
||||
var method = tuple.Item2;
|
||||
|
@ -97,26 +93,25 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
continue;
|
||||
if (!method.IsStatic || !DotNetUtils.isMethod(method, "System.Void", "()"))
|
||||
continue;
|
||||
if (!checkResolverType(tuple.Item1, method))
|
||||
if (!checkResolverInitMethod(method))
|
||||
continue;
|
||||
|
||||
callResolverMethod = attachAppMethod;
|
||||
callResolverType = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hasLdftn(attachAppMethod)) {
|
||||
simpleDeobfuscator.deobfuscate(attachAppMethod);
|
||||
foreach (var resolverHandler in getResolverHandlers(type, attachAppMethod)) {
|
||||
foreach (var resolverHandler in getResolverHandlers(attachAppMethod)) {
|
||||
if (!resolverHandler.HasBody)
|
||||
continue;
|
||||
if (!checkResolverType2(resolverHandler.DeclaringType))
|
||||
var resolverTypeTmp = getResolverType(resolverHandler);
|
||||
if (resolverTypeTmp == null)
|
||||
continue;
|
||||
deobfuscate(resolverHandler);
|
||||
if (checkHandlerMethod(resolverHandler)) {
|
||||
callResolverMethod = attachAppMethod;
|
||||
callResolverType = type;
|
||||
resolverType = resolverHandler.DeclaringType;
|
||||
resolverType = resolverTypeTmp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -135,27 +130,21 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool checkResolverType2(TypeDefinition type) {
|
||||
if (type.Properties.Count > 1 || type.Events.Count > 0)
|
||||
return false;
|
||||
if (!checkResolverType(type))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkResolverType(TypeDefinition type, MethodDefinition initMethod) {
|
||||
bool checkResolverInitMethod(MethodDefinition initMethod) {
|
||||
resolverType = null;
|
||||
if (!initMethod.HasBody)
|
||||
return false;
|
||||
if (!checkResolverType2(type))
|
||||
return false;
|
||||
|
||||
deobfuscate(initMethod);
|
||||
foreach (var handlerDef in getResolverHandlers(type, initMethod)) {
|
||||
foreach (var handlerDef in getResolverHandlers(initMethod)) {
|
||||
deobfuscate(handlerDef);
|
||||
|
||||
var resolverTypeTmp = getResolverType(handlerDef);
|
||||
if (resolverTypeTmp == null)
|
||||
continue;
|
||||
|
||||
if (checkHandlerMethod(handlerDef)) {
|
||||
resolverType = type;
|
||||
resolverType = resolverTypeTmp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -168,10 +157,31 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
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 checkHandlerMethod(MethodDefinition handler);
|
||||
|
||||
static IEnumerable<MethodDefinition> getResolverHandlers(TypeDefinition type, MethodDefinition method) {
|
||||
IEnumerable<MethodDefinition> getResolverHandlers(MethodDefinition method) {
|
||||
int numHandlers = 0;
|
||||
var instructions = method.Body.Instructions;
|
||||
for (int i = 0; i < instructions.Count; i++) {
|
||||
|
@ -184,7 +194,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
continue;
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
@ -204,5 +214,18 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
if (numHandlers == 0)
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ using de4dot.blocks;
|
|||
namespace de4dot.code.deobfuscators.SmartAssembly {
|
||||
class ResourceDecrypterInfo {
|
||||
ModuleDefinition module;
|
||||
TypeDefinition simpleZipType;
|
||||
MethodDefinition simpleZipTypeDecryptMethod;
|
||||
|
||||
public byte[] DES_Key { get; private set; }
|
||||
public byte[] DES_IV { get; private set; }
|
||||
|
@ -33,31 +33,29 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
public byte[] AES_IV { get; private set; }
|
||||
|
||||
public bool CanDecrypt {
|
||||
get { return simpleZipType != null; }
|
||||
get { return simpleZipTypeDecryptMethod != null; }
|
||||
}
|
||||
|
||||
public ResourceDecrypterInfo(ModuleDefinition module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public ResourceDecrypterInfo(ModuleDefinition module, TypeDefinition simpleZipType, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
public ResourceDecrypterInfo(ModuleDefinition module, MethodDefinition simpleZipTypeDecryptMethod, ISimpleDeobfuscator simpleDeobfuscator)
|
||||
: this(module) {
|
||||
setSimpleZipType(simpleZipType, simpleDeobfuscator);
|
||||
setSimpleZipType(simpleZipTypeDecryptMethod, simpleDeobfuscator);
|
||||
}
|
||||
|
||||
public void setSimpleZipType(TypeDefinition type, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
if (simpleZipType != null || type == null)
|
||||
public void setSimpleZipType(MethodDefinition method, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
if (simpleZipTypeDecryptMethod != null || method == null)
|
||||
return;
|
||||
simpleZipType = type;
|
||||
init(simpleDeobfuscator);
|
||||
simpleZipTypeDecryptMethod = method;
|
||||
init(simpleDeobfuscator, method);
|
||||
}
|
||||
|
||||
void init(ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
void init(ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition method) {
|
||||
var desList = new List<byte[]>(2);
|
||||
var aesList = new List<byte[]>(2);
|
||||
|
||||
if (simpleZipType != null) {
|
||||
foreach (var method in DotNetUtils.findMethods(simpleZipType.Methods, "System.Byte[]", new string[] { "System.Byte[]" }, true)) {
|
||||
var instructions = method.Body.Instructions;
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
for (int i = 0; i <= instructions.Count - 2; i++) {
|
||||
|
@ -82,8 +80,6 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
else if (field.InitialValue.Length == 16)
|
||||
aesList.Add(field.InitialValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (desList.Count >= 2) {
|
||||
DES_Key = desList[desList.Count - 2];
|
||||
|
|
|
@ -23,18 +23,17 @@ using de4dot.blocks;
|
|||
namespace de4dot.code.deobfuscators.SmartAssembly {
|
||||
class SimpleZipInfo {
|
||||
|
||||
public static bool isSimpleZipDecryptMethod_QuickCheck(ModuleDefinition module, MethodReference method, out TypeDefinition simpleZipType) {
|
||||
simpleZipType = null;
|
||||
public static bool isSimpleZipDecryptMethod_QuickCheck(ModuleDefinition module, MethodReference method, out MethodDefinition simpleZipTypeMethod) {
|
||||
simpleZipTypeMethod = null;
|
||||
|
||||
if (!DotNetUtils.isMethod(method, "System.Byte[]", "(System.Byte[])"))
|
||||
return false;
|
||||
|
||||
var type = DotNetUtils.getType(module, method.DeclaringType);
|
||||
var methodDef = DotNetUtils.getMethod(type, method);
|
||||
var methodDef = DotNetUtils.getMethod(DotNetUtils.getType(module, method.DeclaringType), method);
|
||||
if (methodDef == null)
|
||||
return false;
|
||||
|
||||
simpleZipType = type;
|
||||
simpleZipTypeMethod = methodDef;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
TypeDefinition stringsEncodingClass;
|
||||
EmbeddedResource stringsResource;
|
||||
int stringOffset;
|
||||
TypeDefinition simpleZipType;
|
||||
MethodDefinition simpleZipTypeMethod;
|
||||
MethodDefinition stringDecrypterMethod;
|
||||
StringDecrypterVersion decrypterVersion;
|
||||
|
||||
|
@ -58,8 +58,8 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
get { return resourceDecrypter == null || resourceDecrypter.CanDecrypt; }
|
||||
}
|
||||
|
||||
public TypeDefinition SimpleZipType {
|
||||
get { return simpleZipType; }
|
||||
public MethodDefinition SimpleZipTypeMethod {
|
||||
get { return simpleZipTypeMethod; }
|
||||
}
|
||||
|
||||
public EmbeddedResource StringsResource {
|
||||
|
@ -71,7 +71,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
}
|
||||
|
||||
public bool StringsEncrypted {
|
||||
get { return simpleZipType != null; }
|
||||
get { return simpleZipTypeMethod != null; }
|
||||
}
|
||||
|
||||
public MethodDefinition StringDecrypterMethod {
|
||||
|
@ -148,9 +148,9 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
decrypterVersion = StringDecrypterVersion.V4;
|
||||
}
|
||||
|
||||
simpleZipType = findSimpleZipType(cctor) ?? findSimpleZipType(stringDecrypterMethod);
|
||||
if (simpleZipType != null)
|
||||
resourceDecrypter = new ResourceDecrypter(new ResourceDecrypterInfo(module, simpleZipType, simpleDeobfuscator));
|
||||
simpleZipTypeMethod = findSimpleZipTypeMethod(cctor) ?? findSimpleZipTypeMethod(stringDecrypterMethod);
|
||||
if (simpleZipTypeMethod != null)
|
||||
resourceDecrypter = new ResourceDecrypter(new ResourceDecrypterInfo(module, simpleZipTypeMethod, simpleDeobfuscator));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -292,9 +292,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Find SmartAssembly.Zip.SimpleZip, which is the class that decrypts and inflates
|
||||
// data in the resources.
|
||||
TypeDefinition findSimpleZipType(MethodDefinition method) {
|
||||
MethodDefinition findSimpleZipTypeMethod(MethodDefinition method) {
|
||||
if (method == null || method.Body == null)
|
||||
return null;
|
||||
var instructions = method.Body.Instructions;
|
||||
|
@ -302,7 +300,9 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
var call = instructions[i];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
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[])"))
|
||||
continue;
|
||||
|
||||
|
@ -315,11 +315,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
if (!MemberReferenceHelper.compareTypes(stringsEncodingClass, field.DeclaringType))
|
||||
continue;
|
||||
|
||||
var type = DotNetUtils.getType(module, calledMethod.DeclaringType);
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
return type;
|
||||
return calledMethod;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -607,18 +607,16 @@ namespace de4dot.code.renamer.asmmodules {
|
|||
continue;
|
||||
if (!resolvedAllInterfaces() || !resolvedBaseClasses())
|
||||
continue;
|
||||
string errMsg = string.Format(
|
||||
"Could not find interface method {0} ({1:X8}). Type: {2} ({3:X8})",
|
||||
// Ignore if COM class
|
||||
if (!TypeDefinition.IsImport &&
|
||||
!hasAttribute("System.Runtime.InteropServices.ComImportAttribute") &&
|
||||
!hasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute")) {
|
||||
Log.w("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
|
||||
if (!TypeDefinition.IsImport &&
|
||||
!hasAttribute("System.Runtime.InteropServices.ComImportAttribute") &&
|
||||
!hasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute"))
|
||||
throw new ApplicationException(errMsg);
|
||||
Log.w("{0}", errMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
|
@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.2.3405")]
|
||||
[assembly: AssemblyVersion("1.4.4.3405")]
|
||||
[assembly: AssemblyFileVersion("1.4.4.3405")]
|
||||
|
|
Loading…
Reference in New Issue
Block a user