Support Eazfuscator.NET 4.2 - 4.3
This commit is contained in:
parent
a9359729e9
commit
1cdac23681
|
@ -31,8 +31,10 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
public const int MSG_CALL_MOVE_NEXT = 4;
|
public const int MSG_CALL_MOVE_NEXT = 4;
|
||||||
|
|
||||||
Module reflObfModule;
|
Module reflObfModule;
|
||||||
IEnumerable<int> ienumerable = null;
|
object ienumerable = null;
|
||||||
IEnumerator<int> ienumerator = null;
|
object ienumerator = null;
|
||||||
|
MethodInfo mi_get_Current;
|
||||||
|
MethodInfo mi_MoveNext;
|
||||||
|
|
||||||
[CreateUserGenericService]
|
[CreateUserGenericService]
|
||||||
public static IUserGenericService Create() {
|
public static IUserGenericService Create() {
|
||||||
|
@ -72,7 +74,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
var ctor = reflObfModule.ResolveMethod((int)ctorToken) as ConstructorInfo;
|
var ctor = reflObfModule.ResolveMethod((int)ctorToken) as ConstructorInfo;
|
||||||
if (ctor == null)
|
if (ctor == null)
|
||||||
throw new ApplicationException(string.Format("Invalid ctor with token: {0:X8}", ctorToken));
|
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) {
|
void WriteEnumerableField(uint fieldToken, object value) {
|
||||||
|
@ -83,15 +85,74 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateEnumerator() {
|
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() {
|
int CallGetCurrent() {
|
||||||
return ienumerator.Current;
|
return (int)mi_get_Current.Invoke(ienumerator, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CallMoveNext() {
|
bool CallMoveNext() {
|
||||||
return ienumerator.MoveNext();
|
return (bool)mi_MoveNext.Invoke(ienumerator, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
|
|
|
@ -696,8 +696,8 @@ done: ;
|
||||||
if (initValue2 == null || !initValue2.AllBitsValid())
|
if (initValue2 == null || !initValue2.AllBitsValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int loopStart = GetIndexOfCall(instrs, index, leaveIndex, "System.Int32 System.Collections.Generic.IEnumerator`1<System.Int32>::get_Current()");
|
int loopStart = GetIndexOfCall(instrs, index, leaveIndex, "System.Int32", "()");
|
||||||
int loopEnd = GetIndexOfCall(instrs, loopStart, leaveIndex, "System.Boolean System.Collections.IEnumerator::MoveNext()");
|
int loopEnd = GetIndexOfCall(instrs, loopStart, leaveIndex, "System.Boolean", "()");
|
||||||
if (loopStart < 0 || loopEnd < 0)
|
if (loopStart < 0 || loopEnd < 0)
|
||||||
return false;
|
return false;
|
||||||
loopStart++;
|
loopStart++;
|
||||||
|
@ -720,7 +720,7 @@ done: ;
|
||||||
return true;
|
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)
|
if (startIndex < 0 || endIndex < 0)
|
||||||
return -1;
|
return -1;
|
||||||
for (int i = startIndex; i < endIndex; i++) {
|
for (int i = startIndex; i < endIndex; i++) {
|
||||||
|
@ -728,7 +728,7 @@ done: ;
|
||||||
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
||||||
continue;
|
continue;
|
||||||
var method = instr.Operand as IMethod;
|
var method = instr.Operand as IMethod;
|
||||||
if (method == null || method.FullName != fullMethodName)
|
if (!DotNetUtils.IsMethod(method, returnType, parameters))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
|
@ -722,13 +722,85 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
decryptStringMethod.Body.ExceptionHandlers.Count >= 2 &&
|
decryptStringMethod.Body.ExceptionHandlers.Count >= 2 &&
|
||||||
new LocalTypes(decryptStringMethod).All(locals35) &&
|
new LocalTypes(decryptStringMethod).All(locals35) &&
|
||||||
CheckTypeFields2(fields35)) {
|
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;
|
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) {
|
TypeDef GetNestedType(int n) {
|
||||||
var type = stringDecrypter.Type;
|
var type = stringDecrypter.Type;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user