diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs index ccdff446..11ca8c53 100644 --- a/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs @@ -155,6 +155,12 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { stringMethod = method; realMethod = GetRealDecrypterMethod(method); isV50OrLater = true; + foreach (var inst in stringMethod.Body.Instructions) { + if (inst.OpCode.Code == Code.Cgt_Un) { + isV51OrLater = true; + break; + } + } } else stringMethod = method; @@ -422,7 +428,36 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { return -1; } - static Local GetFlagsLocal(MethodDef method, int index) { + Local GetFlagsLocal(MethodDef method, int index) { + if (isV51OrLater) + return GetFlagsLocalNew(method, index); + return GetFlagsLocalOld(method, index); + } + + // <= 5.0 + static Local GetFlagsLocalOld(MethodDef method, int index) { + var instrs = method.Body.Instructions; + if (index + 5 >= instrs.Count) + return null; + if (instrs[index++].OpCode.Code != Code.And) + return null; + if (instrs[index++].OpCode.Code != Code.Ldc_I4_0) + return null; + if (instrs[index++].OpCode.Code != Code.Ceq) + return null; + if (instrs[index++].OpCode.Code != Code.Ldc_I4_0) + return null; + if (instrs[index++].OpCode.Code != Code.Ceq) + return null; + var stloc = instrs[index++]; + if (!stloc.IsStloc()) + return null; + return stloc.GetLocal(method.Body.Variables); + } + + // 5.1+ + // Uses different OpCodes + static Local GetFlagsLocalNew(MethodDef method, int index) { var instrs = method.Body.Instructions; if (index + 5 >= instrs.Count) return null; @@ -695,7 +730,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { break; } } -done: ; +done: foreach (var val in fields.Values) { if (val == null) @@ -708,6 +743,75 @@ done: ; } bool EmulateDynocode(InstructionEmulator emu, ref int index) { + if (isV51OrLater) + return EmulateDynocodeNew(emu, ref index); + return EmulateDynocodeOld(emu, ref index); + } + + // <= 5.0 + bool EmulateDynocodeOld(InstructionEmulator emu, ref int index) { + var instrs = stringMethod.Body.Instructions; + var instr = instrs[index]; + + var ctor = instr.Operand as MethodDef; + if (ctor == null || ctor.MethodSig.GetParamCount() != 1 || ctor.MethodSig.Params[0].ElementType != ElementType.I4) + return false; + + if (index + 4 >= instrs.Count) + return false; + var ldloc = instrs[index + 3]; + var stfld = instrs[index + 4]; + if (!ldloc.IsLdloc() || stfld.OpCode.Code != Code.Stfld) + return false; + var enumerableField = stfld.Operand as FieldDef; + if (enumerableField == null) + return false; + + var initValue = emu.GetLocal(ldloc.GetLocal(stringMethod.Body.Variables)) as Int32Value; + if (initValue == null || !initValue.AllBitsValid()) + return false; + + int leaveIndex = FindLeave(instrs, index); + if (leaveIndex < 0) + return false; + var afterLoop = instrs[leaveIndex].Operand as Instruction; + if (afterLoop == null) + return false; + int newIndex = instrs.IndexOf(afterLoop); + var loopLocal = GetDCLoopLocal(index, newIndex); + if (loopLocal == null) + return false; + var initValue2 = emu.GetLocal(loopLocal) as Int32Value; + if (initValue2 == null || !initValue2.AllBitsValid()) + return false; + + int loopStart = GetIndexOfCall(instrs, index, leaveIndex, "System.Int32", "()"); + int loopEnd = GetIndexOfCall(instrs, loopStart, leaveIndex, "System.Boolean", "()"); + if (loopStart < 0 || loopEnd < 0) + return false; + loopStart++; + loopEnd--; + + dynocode.Initialize(module); + var ctorArg = emu.Pop() as Int32Value; + if (ctorArg == null || !ctorArg.AllBitsValid()) + return false; + dynocode.CreateEnumerable(ctor, new object[] { ctorArg.Value }); + dynocode.WriteEnumerableField(enumerableField.MDToken.ToUInt32(), initValue.Value); + dynocode.CreateEnumerator(); + foreach (var val in dynocode) { + emu.Push(new Int32Value(val)); + for (int i = loopStart; i < loopEnd; i++) + emu.Emulate(instrs[i]); + } + + index = newIndex - 1; + return true; + } + + // 5.1+ + // the only changes are the indexes of ldloc and stfld + bool EmulateDynocodeNew(InstructionEmulator emu, ref int index) { var instrs = stringMethod.Body.Instructions; var instr = instrs[index]; diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/VersionDetector.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/VersionDetector.cs index 8623122e..eb7eb34c 100644 --- a/de4dot.code/deobfuscators/Eazfuscator_NET/VersionDetector.cs +++ b/de4dot.code/deobfuscators/Eazfuscator_NET/VersionDetector.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; +using dnlib.DotNet.Emit; using dnlib.DotNet; using de4dot.blocks; @@ -818,7 +819,11 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { decryptStringMethod.Body.ExceptionHandlers.Count == 1 && new LocalTypes(decryptStringMethod).All(locals50) && CheckTypeFields2(fields50)) { - return "5.0"; + foreach (var inst in stringDecrypter.Method.Body.Instructions) { + if (inst.OpCode.Code == Code.Cgt_Un) + return "5.1"; + } + return "5.0"; } }