Print deobfuscated method if -vv

This commit is contained in:
de4dot 2011-10-12 19:47:51 +02:00
parent 38b08dddfd
commit 9ed55629e6
3 changed files with 165 additions and 5 deletions

2
cecil

@ -1 +1 @@
Subproject commit 6771f0f303228463c924de0634a8dbd5fa59bd47
Subproject commit 56c51312b7efb755194a76612bf0c41c517f0360

View File

@ -33,23 +33,32 @@ namespace de4dot {
veryverbose,
}
public static LogLevel logLevel = LogLevel.normal;
public static string indentString = "";
public static bool isAtLeast(LogLevel ll) {
return logLevel >= ll;
}
static void initIndentString() {
indentString = new string(' ', indentLevel * indentSize);
}
public static void indent() {
indentLevel++;
initIndentString();
}
public static void deIndent() {
if (indentLevel <= 0)
throw new ApplicationException("Can't de-indent!");
indentLevel--;
initIndentString();
}
public static void log(LogLevel l, string format, params object[] args) {
if (l > logLevel)
if (!isAtLeast(l))
return;
string indent = new string(' ', indentLevel * indentSize);
if (l <= LogLevel.warning)
indent = "";
var indent = l <= LogLevel.warning ? "" : indentString;
Console.WriteLine(indent + format, args);
}

View File

@ -21,6 +21,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using Mono.Cecil;
using Mono.Cecil.Cil;
using de4dot.deobfuscators;
@ -439,6 +440,7 @@ namespace de4dot {
deob.DeobfuscatedFile = null;
Log.v("Deobfuscating methods");
var methodPrinter = new MethodPrinter();
foreach (var method in allMethods) {
Log.v("Deobfuscating {0} ({1:X8})", method, method.MetadataToken.ToUInt32());
Log.indent();
@ -461,6 +463,14 @@ namespace de4dot {
IList<ExceptionHandler> allExceptionHandlers;
blocks.getCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
const Log.LogLevel dumpLogLevel = Log.LogLevel.veryverbose;
if (Log.isAtLeast(dumpLogLevel)) {
Log.log(dumpLogLevel, "Deobfuscated code:");
Log.indent();
methodPrinter.print(dumpLogLevel, allInstructions, allExceptionHandlers);
Log.deIndent();
}
}
removeNoInliningAttribute(method);
@ -469,6 +479,147 @@ namespace de4dot {
}
}
class MethodPrinter {
Log.LogLevel logLevel;
IList<Instruction> allInstructions;
IList<ExceptionHandler> allExceptionHandlers;
Dictionary<Instruction, bool> targets = new Dictionary<Instruction, bool>();
class ExInfo {
public List<ExceptionHandler> tryStarts = new List<ExceptionHandler>();
public List<ExceptionHandler> tryEnds = new List<ExceptionHandler>();
public List<ExceptionHandler> filterStarts = new List<ExceptionHandler>();
public List<ExceptionHandler> handlerStarts = new List<ExceptionHandler>();
public List<ExceptionHandler> handlerEnds = new List<ExceptionHandler>();
}
Dictionary<Instruction, ExInfo> exInfos = new Dictionary<Instruction, ExInfo>();
ExInfo lastExInfo;
public void print(Log.LogLevel logLevel, IList<Instruction> allInstructions, IList<ExceptionHandler> allExceptionHandlers) {
try {
this.logLevel = logLevel;
this.allInstructions = allInstructions;
this.allExceptionHandlers = allExceptionHandlers;
lastExInfo = new ExInfo();
print();
}
finally {
this.allInstructions = null;
this.allExceptionHandlers = null;
targets.Clear();
exInfos.Clear();
lastExInfo = null;
}
}
void initTargets() {
foreach (var instr in allInstructions) {
switch (instr.OpCode.OperandType) {
case OperandType.ShortInlineBrTarget:
case OperandType.InlineBrTarget:
var targetInstr = instr.Operand as Instruction;
if (targetInstr != null)
targets[targetInstr] = true;
break;
case OperandType.InlineSwitch:
foreach (var targetInstr2 in (Instruction[])instr.Operand) {
if (targetInstr2 != null)
targets[targetInstr2] = true;
}
break;
}
}
}
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) {
ExInfo exInfo;
if (exInfos.TryGetValue(instr, out exInfo))
printExInfo(exInfo);
if (targets.ContainsKey(instr)) {
Log.deIndent();
Log.log(logLevel, "{0}:", instr.GetLabelString());
Log.indent();
}
var instrString = instr.GetOpCodeString();
var operandString = instr.GetOperandString();
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, operandString, memberReference.MetadataToken.ToUInt32());
else
Log.log(logLevel, "{0,-9} {1}", instrString, operandString);
}
printExInfo(lastExInfo);
Log.deIndent();
}
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}", getOffset(ex.TryStart), getOffset(ex.TryEnd)));
if (ex.FilterStart != null)
sb.Append(string.Format(", FILTER: {0}", getOffset(ex.FilterStart)));
if (ex.HandlerStart != null)
sb.Append(string.Format(", HANDLER: {0}-{1}", getOffset(ex.HandlerStart), getOffset(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 getOffset(Instruction instr) {
if (instr == null)
return "END";
return string.Format("{0:X4}", instr.Offset);
}
}
bool hasNonEmptyBody(MethodDefinition method) {
return method.HasBody && method.Body.Instructions.Count > 0;
}