Support Eazfuscator.NET 4.2 - 4.3

This commit is contained in:
de4dot 2014-03-23 07:39:55 +01:00
parent a9359729e9
commit 1cdac23681
3 changed files with 144 additions and 11 deletions

View File

@ -31,8 +31,10 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
public const int MSG_CALL_MOVE_NEXT = 4;
Module reflObfModule;
IEnumerable<int> ienumerable = null;
IEnumerator<int> ienumerator = null;
object ienumerable = null;
object ienumerator = null;
MethodInfo mi_get_Current;
MethodInfo mi_MoveNext;
[CreateUserGenericService]
public static IUserGenericService Create() {
@ -72,7 +74,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
var ctor = reflObfModule.ResolveMethod((int)ctorToken) as ConstructorInfo;
if (ctor == null)
throw new ApplicationException(string.Format("Invalid ctor with token: {0:X8}", ctorToken));
ienumerable = (IEnumerable<int>)ctor.Invoke(args);
ienumerable = ctor.Invoke(args);
}
void WriteEnumerableField(uint fieldToken, object value) {
@ -83,15 +85,74 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
}
void CreateEnumerator() {
ienumerator = ienumerable.GetEnumerator();
foreach (var method in ienumerable.GetType().GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
if (method.GetParameters().Length != 0)
continue;
var retType = method.ReturnType;
if (!retType.IsGenericType)
continue;
var genArgs = retType.GetGenericArguments();
if (genArgs.Length != 1)
continue;
if (genArgs[0] != typeof(int))
continue;
if (!FindEnumeratorMethods(retType))
continue;
ienumerator = method.Invoke(ienumerable, null);
return;
}
throw new ApplicationException("No GetEnumerator() method found");
}
bool FindEnumeratorMethods(Type type) {
mi_get_Current = null;
mi_MoveNext = null;
foreach (var method in ienumerable.GetType().GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
if (Is_get_Current(method)) {
if (mi_get_Current != null)
return false;
mi_get_Current = method;
continue;
}
if (Is_MoveNext(method)) {
if (mi_MoveNext != null)
return false;
mi_MoveNext = method;
continue;
}
}
return mi_get_Current != null && mi_MoveNext != null;
}
static bool Is_get_Current(MethodInfo method) {
if (method.GetParameters().Length != 0)
return false;
if (method.ReturnType != typeof(int))
return false;
return true;
}
static bool Is_MoveNext(MethodInfo method) {
if (method.GetParameters().Length != 0)
return false;
if (method.ReturnType != typeof(bool))
return false;
return true;
}
int CallGetCurrent() {
return ienumerator.Current;
return (int)mi_get_Current.Invoke(ienumerator, null);
}
bool CallMoveNext() {
return ienumerator.MoveNext();
return (bool)mi_MoveNext.Invoke(ienumerator, null);
}
public void Dispose() {

View File

@ -696,8 +696,8 @@ done: ;
if (initValue2 == null || !initValue2.AllBitsValid())
return false;
int loopStart = GetIndexOfCall(instrs, index, leaveIndex, "System.Int32 System.Collections.Generic.IEnumerator`1<System.Int32>::get_Current()");
int loopEnd = GetIndexOfCall(instrs, loopStart, leaveIndex, "System.Boolean System.Collections.IEnumerator::MoveNext()");
int loopStart = GetIndexOfCall(instrs, index, leaveIndex, "System.Int32", "()");
int loopEnd = GetIndexOfCall(instrs, loopStart, leaveIndex, "System.Boolean", "()");
if (loopStart < 0 || loopEnd < 0)
return false;
loopStart++;
@ -720,7 +720,7 @@ done: ;
return true;
}
static int GetIndexOfCall(IList<Instruction> instrs, int startIndex, int endIndex, string fullMethodName) {
static int GetIndexOfCall(IList<Instruction> instrs, int startIndex, int endIndex, string returnType, string parameters) {
if (startIndex < 0 || endIndex < 0)
return -1;
for (int i = startIndex; i < endIndex; i++) {
@ -728,7 +728,7 @@ done: ;
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
continue;
var method = instr.Operand as IMethod;
if (method == null || method.FullName != fullMethodName)
if (!DotNetUtils.IsMethod(method, returnType, parameters))
continue;
return i;

View File

@ -722,13 +722,85 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
decryptStringMethod.Body.ExceptionHandlers.Count >= 2 &&
new LocalTypes(decryptStringMethod).All(locals35) &&
CheckTypeFields2(fields35)) {
return "3.5 - 4.1";
return "3.5 - 4.2";
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
var fields43 = new string[] {
GetNestedTypeName(0),
GetNestedTypeName(1),
"System.Byte[]",
"System.Int16",
"System.Int32",
"System.Byte[]",
"System.Int32",
"System.Int32",
GetNestedTypeName(2),
};
var locals43 = CreateLocalsArray(
"System.Boolean",
"System.Byte",
"System.Byte[]",
"System.Char[]",
FindEnumeratorName(decryptStringMethod),
GetNestedTypeName(0),
"System.Diagnostics.StackFrame",
"System.Diagnostics.StackTrace",
"System.Int16",
"System.Int32",
"System.Int64",
"System.IO.Stream",
"System.Reflection.Assembly",
"System.Reflection.AssemblyName",
"System.Reflection.MethodBase",
"System.String",
"System.Text.StringBuilder",
"System.Type"
);
var olocals43 = CreateLocalsArray(
"System.Int32"
);
if (otherMethods.Count == 1 &&
decryptStringType.NestedTypes.Count == 3 &&
DotNetUtils.IsMethod(otherMethods[0], "System.Void", "(System.Byte[],System.Int32,System.Byte[])") &&
otherMethods[0].IsPrivate &&
otherMethods[0].IsStatic &&
new LocalTypes(otherMethods[0]).Exactly(olocals43) &&
decryptStringMethod.IsNoInlining &&
decryptStringMethod.IsAssembly &&
!decryptStringMethod.IsSynchronized &&
decryptStringMethod.Body.MaxStack >= 1 &&
decryptStringMethod.Body.MaxStack <= 8 &&
decryptStringMethod.Body.ExceptionHandlers.Count >= 2 &&
new LocalTypes(decryptStringMethod).All(locals43) &&
CheckTypeFields2(fields43)) {
return "4.3";
}
}
return null;
}
static string FindEnumeratorName(MethodDef method) {
foreach (var local in method.Body.Variables) {
var gis = local.Type as GenericInstSig;
if (gis == null)
continue;
if (gis.FullName == "System.Collections.Generic.IEnumerator`1<System.Int32>")
continue;
if (gis.GenericArguments.Count != 1)
continue;
if (gis.GenericArguments[0].GetFullName() != "System.Int32")
continue;
return gis.FullName;
}
return null;
}
TypeDef GetNestedType(int n) {
var type = stringDecrypter.Type;