diff --git a/de4dot.code/MethodPrinter.cs b/de4dot.code/MethodPrinter.cs
new file mode 100644
index 00000000..d6ed2881
--- /dev/null
+++ b/de4dot.code/MethodPrinter.cs
@@ -0,0 +1,209 @@
+/*
+ Copyright (C) 2011-2012 de4dot@gmail.com
+
+ This file is part of de4dot.
+
+ de4dot is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ de4dot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with de4dot. If not, see .
+*/
+
+using System.Collections.Generic;
+using System.Text;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using de4dot.blocks;
+
+namespace de4dot.code {
+ class MethodPrinter {
+ Log.LogLevel logLevel;
+ IList allInstructions;
+ IList allExceptionHandlers;
+ Dictionary targets = new Dictionary();
+ Dictionary labels = new Dictionary();
+
+ class ExInfo {
+ public List tryStarts = new List();
+ public List tryEnds = new List();
+ public List filterStarts = new List();
+ public List handlerStarts = new List();
+ public List handlerEnds = new List();
+ }
+ Dictionary exInfos = new Dictionary();
+ ExInfo lastExInfo;
+
+ public void print(Log.LogLevel logLevel, IList allInstructions, IList allExceptionHandlers) {
+ try {
+ this.logLevel = logLevel;
+ this.allInstructions = allInstructions;
+ this.allExceptionHandlers = allExceptionHandlers;
+ lastExInfo = new ExInfo();
+ print();
+ }
+ finally {
+ this.allInstructions = null;
+ this.allExceptionHandlers = null;
+ targets.Clear();
+ labels.Clear();
+ exInfos.Clear();
+ lastExInfo = null;
+ }
+ }
+
+ void initTargets() {
+ foreach (var instr in allInstructions) {
+ switch (instr.OpCode.OperandType) {
+ case OperandType.ShortInlineBrTarget:
+ case OperandType.InlineBrTarget:
+ setTarget(instr.Operand as Instruction);
+ break;
+
+ case OperandType.InlineSwitch:
+ foreach (var targetInstr in (Instruction[])instr.Operand)
+ setTarget(targetInstr);
+ break;
+ }
+ }
+
+ foreach (var ex in allExceptionHandlers) {
+ setTarget(ex.TryStart);
+ setTarget(ex.TryEnd);
+ setTarget(ex.FilterStart);
+ setTarget(ex.HandlerStart);
+ setTarget(ex.HandlerEnd);
+ }
+
+ var sortedTargets = new List(targets.Keys);
+ sortedTargets.Sort((a, b) => Utils.compareInt32(a.Offset, b.Offset));
+ for (int i = 0; i < sortedTargets.Count; i++)
+ labels[sortedTargets[i]] = string.Format("label_{0}", i);
+ }
+
+ void setTarget(Instruction instr) {
+ if (instr != null)
+ targets[instr] = true;
+ }
+
+ void initExHandlers() {
+ foreach (var ex in allExceptionHandlers) {
+ if (ex.TryStart != null) {
+ getExInfo(ex.TryStart).tryStarts.Add(ex);
+ getExInfo(ex.TryEnd).tryEnds.Add(ex);
+ }
+ if (ex.FilterStart != null)
+ getExInfo(ex.FilterStart).filterStarts.Add(ex);
+ if (ex.HandlerStart != null) {
+ getExInfo(ex.HandlerStart).handlerStarts.Add(ex);
+ getExInfo(ex.HandlerEnd).handlerEnds.Add(ex);
+ }
+ }
+ }
+
+ ExInfo getExInfo(Instruction instruction) {
+ if (instruction == null)
+ return lastExInfo;
+ ExInfo exInfo;
+ if (!exInfos.TryGetValue(instruction, out exInfo))
+ exInfos[instruction] = exInfo = new ExInfo();
+ return exInfo;
+ }
+
+ void print() {
+ initTargets();
+ initExHandlers();
+
+ Log.indent();
+ foreach (var instr in allInstructions) {
+ if (targets.ContainsKey(instr)) {
+ Log.deIndent();
+ Log.log(logLevel, "{0}:", getLabel(instr));
+ Log.indent();
+ }
+ ExInfo exInfo;
+ if (exInfos.TryGetValue(instr, out exInfo))
+ printExInfo(exInfo);
+ var instrString = instr.GetOpCodeString();
+ var operandString = getOperandString(instr);
+ var memberReference = instr.Operand as MemberReference;
+ if (operandString == "")
+ Log.log(logLevel, "{0}", instrString);
+ else if (memberReference != null)
+ Log.log(logLevel, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberReference.MetadataToken.ToUInt32());
+ else
+ Log.log(logLevel, "{0,-9} {1}", instrString, Utils.removeNewlines(operandString));
+ }
+ printExInfo(lastExInfo);
+ Log.deIndent();
+ }
+
+ string getOperandString(Instruction instr) {
+ if (instr.Operand is Instruction)
+ return getLabel((Instruction)instr.Operand);
+ else if (instr.Operand is Instruction[]) {
+ var sb = new StringBuilder();
+ var targets = (Instruction[])instr.Operand;
+ for (int i = 0; i < targets.Length; i++) {
+ if (i > 0)
+ sb.Append(',');
+ sb.Append(getLabel(targets[i]));
+ }
+ return sb.ToString();
+ }
+ else if (instr.Operand is string)
+ return Utils.toCsharpString((string)instr.Operand);
+ else if (instr.Operand is ParameterDefinition) {
+ var arg = (ParameterDefinition)instr.Operand;
+ var s = instr.GetOperandString();
+ if (s != "")
+ return s;
+ return string.Format("", DotNetUtils.getArgIndex(arg));
+ }
+ else
+ return instr.GetOperandString();
+ }
+
+ void printExInfo(ExInfo exInfo) {
+ Log.deIndent();
+ foreach (var ex in exInfo.tryStarts)
+ Log.log(logLevel, "// try start: {0}", getExceptionString(ex));
+ foreach (var ex in exInfo.tryEnds)
+ Log.log(logLevel, "// try end: {0}", getExceptionString(ex));
+ foreach (var ex in exInfo.filterStarts)
+ Log.log(logLevel, "// filter start: {0}", getExceptionString(ex));
+ foreach (var ex in exInfo.handlerStarts)
+ Log.log(logLevel, "// handler start: {0}", getExceptionString(ex));
+ foreach (var ex in exInfo.handlerEnds)
+ Log.log(logLevel, "// handler end: {0}", getExceptionString(ex));
+ Log.indent();
+ }
+
+ string getExceptionString(ExceptionHandler ex) {
+ var sb = new StringBuilder();
+ if (ex.TryStart != null)
+ sb.Append(string.Format("TRY: {0}-{1}", getLabel(ex.TryStart), getLabel(ex.TryEnd)));
+ if (ex.FilterStart != null)
+ sb.Append(string.Format(", FILTER: {0}", getLabel(ex.FilterStart)));
+ if (ex.HandlerStart != null)
+ sb.Append(string.Format(", HANDLER: {0}-{1}", getLabel(ex.HandlerStart), getLabel(ex.HandlerEnd)));
+ sb.Append(string.Format(", TYPE: {0}", ex.HandlerType));
+ if (ex.CatchType != null)
+ sb.Append(string.Format(", CATCH: {0}", ex.CatchType));
+ return sb.ToString();
+ }
+
+ string getLabel(Instruction instr) {
+ if (instr == null)
+ return "";
+ return labels[instr];
+ }
+ }
+}
diff --git a/de4dot.code/ObfuscatedFile.cs b/de4dot.code/ObfuscatedFile.cs
index 1323f9fa..c74e8b9c 100644
--- a/de4dot.code/ObfuscatedFile.cs
+++ b/de4dot.code/ObfuscatedFile.cs
@@ -607,197 +607,11 @@ namespace de4dot.code {
if (Log.isAtLeast(dumpLogLevel)) {
Log.log(dumpLogLevel, "Deobfuscated code:");
Log.indent();
- methodPrinter.print(dumpLogLevel, method, allInstructions, allExceptionHandlers);
+ methodPrinter.print(dumpLogLevel, allInstructions, allExceptionHandlers);
Log.deIndent();
}
}
- class MethodPrinter {
- Log.LogLevel logLevel;
- MethodReference method;
- IList allInstructions;
- IList allExceptionHandlers;
- Dictionary targets = new Dictionary();
- Dictionary labels = new Dictionary();
-
- class ExInfo {
- public List tryStarts = new List();
- public List tryEnds = new List();
- public List filterStarts = new List();
- public List handlerStarts = new List();
- public List handlerEnds = new List();
- }
- Dictionary exInfos = new Dictionary();
- ExInfo lastExInfo;
-
- public void print(Log.LogLevel logLevel, MethodReference method, IList allInstructions, IList allExceptionHandlers) {
- try {
- this.logLevel = logLevel;
- this.method = method;
- this.allInstructions = allInstructions;
- this.allExceptionHandlers = allExceptionHandlers;
- lastExInfo = new ExInfo();
- print();
- }
- finally {
- this.method = null;
- this.allInstructions = null;
- this.allExceptionHandlers = null;
- targets.Clear();
- labels.Clear();
- exInfos.Clear();
- lastExInfo = null;
- }
- }
-
- void initTargets() {
- foreach (var instr in allInstructions) {
- switch (instr.OpCode.OperandType) {
- case OperandType.ShortInlineBrTarget:
- case OperandType.InlineBrTarget:
- setTarget(instr.Operand as Instruction);
- break;
-
- case OperandType.InlineSwitch:
- foreach (var targetInstr in (Instruction[])instr.Operand)
- setTarget(targetInstr);
- break;
- }
- }
-
- foreach (var ex in allExceptionHandlers) {
- setTarget(ex.TryStart);
- setTarget(ex.TryEnd);
- setTarget(ex.FilterStart);
- setTarget(ex.HandlerStart);
- setTarget(ex.HandlerEnd);
- }
-
- var sortedTargets = new List(targets.Keys);
- sortedTargets.Sort((a, b) => Utils.compareInt32(a.Offset, b.Offset));
- for (int i = 0; i < sortedTargets.Count; i++)
- labels[sortedTargets[i]] = string.Format("label_{0}", i);
- }
-
- void setTarget(Instruction instr) {
- if (instr != null)
- targets[instr] = true;
- }
-
- void initExHandlers() {
- foreach (var ex in allExceptionHandlers) {
- if (ex.TryStart != null) {
- getExInfo(ex.TryStart).tryStarts.Add(ex);
- getExInfo(ex.TryEnd).tryEnds.Add(ex);
- }
- if (ex.FilterStart != null)
- getExInfo(ex.FilterStart).filterStarts.Add(ex);
- if (ex.HandlerStart != null) {
- getExInfo(ex.HandlerStart).handlerStarts.Add(ex);
- getExInfo(ex.HandlerEnd).handlerEnds.Add(ex);
- }
- }
- }
-
- ExInfo getExInfo(Instruction instruction) {
- if (instruction == null)
- return lastExInfo;
- ExInfo exInfo;
- if (!exInfos.TryGetValue(instruction, out exInfo))
- exInfos[instruction] = exInfo = new ExInfo();
- return exInfo;
- }
-
- void print() {
- initTargets();
- initExHandlers();
-
- Log.indent();
- foreach (var instr in allInstructions) {
- if (targets.ContainsKey(instr)) {
- Log.deIndent();
- Log.log(logLevel, "{0}:", getLabel(instr));
- Log.indent();
- }
- ExInfo exInfo;
- if (exInfos.TryGetValue(instr, out exInfo))
- printExInfo(exInfo);
- var instrString = instr.GetOpCodeString();
- var operandString = getOperandString(instr);
- var memberReference = instr.Operand as MemberReference;
- if (operandString == "")
- Log.log(logLevel, "{0}", instrString);
- else if (memberReference != null)
- Log.log(logLevel, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberReference.MetadataToken.ToUInt32());
- else
- Log.log(logLevel, "{0,-9} {1}", instrString, Utils.removeNewlines(operandString));
- }
- printExInfo(lastExInfo);
- Log.deIndent();
- }
-
- string getOperandString(Instruction instr) {
- if (instr.Operand is Instruction)
- return getLabel((Instruction)instr.Operand);
- else if (instr.Operand is Instruction[]) {
- var sb = new StringBuilder();
- var targets = (Instruction[])instr.Operand;
- for (int i = 0; i < targets.Length; i++) {
- if (i > 0)
- sb.Append(',');
- sb.Append(getLabel(targets[i]));
- }
- return sb.ToString();
- }
- else if (instr.Operand is string)
- return Utils.toCsharpString((string)instr.Operand);
- else if (instr.Operand is ParameterDefinition) {
- var arg = (ParameterDefinition)instr.Operand;
- var s = instr.GetOperandString();
- if (s != "")
- return s;
- return string.Format("", DotNetUtils.getArgIndex(arg));
- }
- else
- return instr.GetOperandString();
- }
-
- void printExInfo(ExInfo exInfo) {
- Log.deIndent();
- foreach (var ex in exInfo.tryStarts)
- Log.log(logLevel, "// try start: {0}", getExceptionString(ex));
- foreach (var ex in exInfo.tryEnds)
- Log.log(logLevel, "// try end: {0}", getExceptionString(ex));
- foreach (var ex in exInfo.filterStarts)
- Log.log(logLevel, "// filter start: {0}", getExceptionString(ex));
- foreach (var ex in exInfo.handlerStarts)
- Log.log(logLevel, "// handler start: {0}", getExceptionString(ex));
- foreach (var ex in exInfo.handlerEnds)
- Log.log(logLevel, "// handler end: {0}", getExceptionString(ex));
- Log.indent();
- }
-
- string getExceptionString(ExceptionHandler ex) {
- var sb = new StringBuilder();
- if (ex.TryStart != null)
- sb.Append(string.Format("TRY: {0}-{1}", getLabel(ex.TryStart), getLabel(ex.TryEnd)));
- if (ex.FilterStart != null)
- sb.Append(string.Format(", FILTER: {0}", getLabel(ex.FilterStart)));
- if (ex.HandlerStart != null)
- sb.Append(string.Format(", HANDLER: {0}-{1}", getLabel(ex.HandlerStart), getLabel(ex.HandlerEnd)));
- sb.Append(string.Format(", TYPE: {0}", ex.HandlerType));
- if (ex.CatchType != null)
- sb.Append(string.Format(", CATCH: {0}", ex.CatchType));
- return sb.ToString();
- }
-
- string getLabel(Instruction instr) {
- if (instr == null)
- return "";
- return labels[instr];
- }
- }
-
bool hasNonEmptyBody(MethodDefinition method) {
return method.HasBody && method.Body.Instructions.Count > 0;
}
diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj
index db4a0fb2..3c210e11 100644
--- a/de4dot.code/de4dot.code.csproj
+++ b/de4dot.code/de4dot.code.csproj
@@ -220,6 +220,7 @@
+