Print deobfuscated method if -vv
This commit is contained in:
parent
38b08dddfd
commit
9ed55629e6
2
cecil
2
cecil
|
@ -1 +1 @@
|
||||||
Subproject commit 6771f0f303228463c924de0634a8dbd5fa59bd47
|
Subproject commit 56c51312b7efb755194a76612bf0c41c517f0360
|
|
@ -33,23 +33,32 @@ namespace de4dot {
|
||||||
veryverbose,
|
veryverbose,
|
||||||
}
|
}
|
||||||
public static LogLevel logLevel = LogLevel.normal;
|
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() {
|
public static void indent() {
|
||||||
indentLevel++;
|
indentLevel++;
|
||||||
|
initIndentString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deIndent() {
|
public static void deIndent() {
|
||||||
if (indentLevel <= 0)
|
if (indentLevel <= 0)
|
||||||
throw new ApplicationException("Can't de-indent!");
|
throw new ApplicationException("Can't de-indent!");
|
||||||
indentLevel--;
|
indentLevel--;
|
||||||
|
initIndentString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void log(LogLevel l, string format, params object[] args) {
|
public static void log(LogLevel l, string format, params object[] args) {
|
||||||
if (l > logLevel)
|
if (!isAtLeast(l))
|
||||||
return;
|
return;
|
||||||
string indent = new string(' ', indentLevel * indentSize);
|
var indent = l <= LogLevel.warning ? "" : indentString;
|
||||||
if (l <= LogLevel.warning)
|
|
||||||
indent = "";
|
|
||||||
Console.WriteLine(indent + format, args);
|
Console.WriteLine(indent + format, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using Mono.Cecil.Cil;
|
using Mono.Cecil.Cil;
|
||||||
using de4dot.deobfuscators;
|
using de4dot.deobfuscators;
|
||||||
|
@ -439,6 +440,7 @@ namespace de4dot {
|
||||||
deob.DeobfuscatedFile = null;
|
deob.DeobfuscatedFile = null;
|
||||||
|
|
||||||
Log.v("Deobfuscating methods");
|
Log.v("Deobfuscating methods");
|
||||||
|
var methodPrinter = new MethodPrinter();
|
||||||
foreach (var method in allMethods) {
|
foreach (var method in allMethods) {
|
||||||
Log.v("Deobfuscating {0} ({1:X8})", method, method.MetadataToken.ToUInt32());
|
Log.v("Deobfuscating {0} ({1:X8})", method, method.MetadataToken.ToUInt32());
|
||||||
Log.indent();
|
Log.indent();
|
||||||
|
@ -461,6 +463,14 @@ namespace de4dot {
|
||||||
IList<ExceptionHandler> allExceptionHandlers;
|
IList<ExceptionHandler> allExceptionHandlers;
|
||||||
blocks.getCode(out allInstructions, out allExceptionHandlers);
|
blocks.getCode(out allInstructions, out allExceptionHandlers);
|
||||||
DotNetUtils.restoreBody(method, allInstructions, 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);
|
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) {
|
bool hasNonEmptyBody(MethodDefinition method) {
|
||||||
return method.HasBody && method.Body.Instructions.Count > 0;
|
return method.HasBody && method.Body.Instructions.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user