From 33e2177059acd92eacd7b0e7ffab64bb9f7f8913 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 6 Apr 2012 16:08:35 +0200 Subject: [PATCH] Restore constrained. prefix --- .../CliSecure/vm/CsvmToCilMethodConverter.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/de4dot.code/deobfuscators/CliSecure/vm/CsvmToCilMethodConverter.cs b/de4dot.code/deobfuscators/CliSecure/vm/CsvmToCilMethodConverter.cs index 21184851..265d3739 100644 --- a/de4dot.code/deobfuscators/CliSecure/vm/CsvmToCilMethodConverter.cs +++ b/de4dot.code/deobfuscators/CliSecure/vm/CsvmToCilMethodConverter.cs @@ -51,6 +51,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm { if (operandRestorer.restore(cilMethod)) Log.w("Failed to restore one or more instruction operands in CSVM method {0:X8}", cilMethod.MetadataToken.ToInt32()); + restoreConstrainedPrefix(cilMethod); } void fixLocals(IList instrs, IList locals) { @@ -405,5 +406,40 @@ namespace de4dot.code.deobfuscators.CliSecure.vm { throw new ApplicationException(string.Format("Could not find member ref: {0:X8}", token)); return memberRef; } + + static void restoreConstrainedPrefix(MethodDefinition method) { + if (method == null || method.Body == null) + return; + + var instrs = method.Body.Instructions; + for (int i = 0; i < instrs.Count; i++) { + var instr = instrs[i]; + if (instr.OpCode.Code != Code.Callvirt) + continue; + + var calledMethod = instr.Operand as MethodReference; + if (calledMethod == null || !calledMethod.HasThis) + continue; + var thisType = MethodStack.getLoadedType(method, instrs, i, calledMethod.Parameters.Count) as ByReferenceType; + if (thisType == null) + continue; + if (hasPrefix(instrs, i, Code.Constrained)) + continue; + instrs.Insert(i, Instruction.Create(OpCodes.Constrained, thisType.ElementType)); + i++; + } + } + + static bool hasPrefix(IList instrs, int index, Code prefix) { + index--; + for (; index >= 0; index--) { + var instr = instrs[index]; + if (instr.OpCode.OpCodeType != OpCodeType.Prefix) + break; + if (instr.OpCode.Code == prefix) + return true; + } + return false; + } } }