diff --git a/de4dot.code/CommandLineParser.cs b/de4dot.code/CommandLineParser.cs index bb7b4ec1..f9e88238 100644 --- a/de4dot.code/CommandLineParser.cs +++ b/de4dot.code/CommandLineParser.cs @@ -135,6 +135,9 @@ namespace de4dot { miscOptions.Add(new NoArgOption(null, "keep-types", "Keep obfuscator types, fields, methods", () => { filesOptions.KeepObfuscatorTypes = true; })); + miscOptions.Add(new NoArgOption(null, "one-file", "Deobfuscate one file at a time", () => { + filesOptions.OneFileAtATime = true; + })); miscOptions.Add(new NoArgOption("v", null, "Verbose", () => { Log.logLevel = Log.LogLevel.verbose; })); diff --git a/de4dot.code/FilesDeobfuscator.cs b/de4dot.code/FilesDeobfuscator.cs index 41caec61..4a0e56c7 100644 --- a/de4dot.code/FilesDeobfuscator.cs +++ b/de4dot.code/FilesDeobfuscator.cs @@ -36,6 +36,7 @@ namespace de4dot { public bool RenameSymbols { get; set; } public bool ControlFlowDeobfuscation { get; set; } public bool KeepObfuscatorTypes { get; set; } + public bool OneFileAtATime { get; set; } public DecrypterType? DefaultStringDecrypterType { get; set; } public List DefaultStringDecrypterMethods { get; private set; } public IAssemblyClientFactory AssemblyClientFactory { get; set; } @@ -63,10 +64,36 @@ namespace de4dot { public void doIt() { if (options.DetectObfuscators) loadAllFiles(); + else if (options.OneFileAtATime) + deobfuscateOneAtATime(); else deobfuscateAll(); } + void deobfuscateOneAtATime() { + loadAllFiles(); + + foreach (var file in options.Files) { + try { + file.deobfuscateBegin(); + file.deobfuscate(); + file.deobfuscateEnd(); + + if (options.RenameSymbols) + new DefinitionsRenamer(new List { file }).renameAll(); + + file.save(); + } + catch (Exception ex) { + Log.w("Could not deobfuscate {0}. Use -v to see stack trace", file.Filename); + Utils.printStackTrace(ex, Log.LogLevel.verbose); + } + finally { + file.deobfuscateCleanUp(); + } + } + } + void deobfuscateAll() { loadAllFiles(); deobfuscateAllFiles(); diff --git a/de4dot.code/Log.cs b/de4dot.code/Log.cs index 017c896c..db0bb1d9 100644 --- a/de4dot.code/Log.cs +++ b/de4dot.code/Log.cs @@ -44,7 +44,7 @@ namespace de4dot { indentLevel--; } - static void log(LogLevel l, string format, params object[] args) { + public static void log(LogLevel l, string format, params object[] args) { if (l > logLevel) return; string indent = new string(' ', indentLevel * indentSize); diff --git a/de4dot.code/Program.cs b/de4dot.code/Program.cs index 08809851..bdc237ef 100644 --- a/de4dot.code/Program.cs +++ b/de4dot.code/Program.cs @@ -55,13 +55,7 @@ namespace de4dot { Log.e("ERROR: {0}", ex.Message); } catch (Exception ex) { - var line = new string('-', 78); - Log.e("\n\nERROR: Caught an exception:\n\n"); - Log.e(line); - Log.e("Message: {0}", ex.Message); - Log.e("Type: {0}", ex.GetType()); - Log.e(line); - Log.e("\n\nStack trace:\n{0}", ex.StackTrace); + Utils.printStackTrace(ex); return 1; } diff --git a/de4dot.code/Utils.cs b/de4dot.code/Utils.cs index 74c338b1..dff2d724 100644 --- a/de4dot.code/Utils.cs +++ b/de4dot.code/Utils.cs @@ -173,5 +173,15 @@ namespace de4dot { public static string getPathOfOurFile(string filename) { return Path.Combine(getOurBaseDir(), filename); } + + public static void printStackTrace(Exception ex, Log.LogLevel logLevel = Log.LogLevel.error) { + var line = new string('-', 78); + Log.log(logLevel, "\n\nERROR: Caught an exception:\n\n"); + Log.log(logLevel, line); + Log.log(logLevel, "Message: {0}", ex.Message); + Log.log(logLevel, "Type: {0}", ex.GetType()); + Log.log(logLevel, line); + Log.log(logLevel, "\n\nStack trace:\n{0}", ex.StackTrace); + } } }