/* 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; using System.Collections.Generic; using System.Text; using dot10.DotNet; using de4dot.code; using de4dot.code.deobfuscators; namespace de4dot.cui { class ExitException : Exception { public readonly int code; public ExitException(int code) { this.code = code; } } class Program { static IList deobfuscatorInfos = createDeobfuscatorInfos(); static IList createDeobfuscatorInfos() { return new List { new de4dot.code.deobfuscators.Unknown.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Agile_NET.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Babel_NET.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CryptoObfuscator.DeobfuscatorInfo(), new de4dot.code.deobfuscators.DeepSea.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Dotfuscator.DeobfuscatorInfo(), new de4dot.code.deobfuscators.dotNET_Reactor.v3.DeobfuscatorInfo(), new de4dot.code.deobfuscators.dotNET_Reactor.v4.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Eazfuscator_NET.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Goliath_NET.DeobfuscatorInfo(), #if PORT new de4dot.code.deobfuscators.ILProtector.DeobfuscatorInfo(), new de4dot.code.deobfuscators.MaxtoCode.DeobfuscatorInfo(), #endif new de4dot.code.deobfuscators.MPRESS.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Rummage.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Skater_NET.DeobfuscatorInfo(), #if PORT new de4dot.code.deobfuscators.SmartAssembly.DeobfuscatorInfo(), #endif new de4dot.code.deobfuscators.Spices_Net.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Xenocode.DeobfuscatorInfo(), }; } public static int main(string[] args) { int exitCode = 0; const string showAllMessagesEnvName = "SHOWALLMESSAGES"; try { if (Console.OutputEncoding.IsSingleByte) Console.OutputEncoding = new UTF8Encoding(false); Logger.Instance.CanIgnoreMessages = !hasEnv(showAllMessagesEnvName); Logger.n(""); Logger.n("de4dot v{0} Copyright (C) 2011-2012 de4dot@gmail.com", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); Logger.n("Latest version and source code: https://github.com/0xd4d/de4dot"); Logger.n(""); var options = new FilesDeobfuscator.Options(); parseCommandLine(args, options); new FilesDeobfuscator(options).doIt(); } catch (ExitException ex) { exitCode = ex.code; } catch (UserException ex) { Logger.Instance.Log(false, null, LoggerEvent.Error, "ERROR: {0}", ex.Message); exitCode = 1; } catch (Exception ex) { if (printFullStackTrace()) { printStackTrace(ex); Logger.Instance.Log(false, null, LoggerEvent.Error, "\nTry the latest version before reporting this problem!"); Logger.Instance.Log(false, null, LoggerEvent.Error, "Send bug reports to de4dot@gmail.com or go to https://github.com/0xd4d/de4dot/issues"); } else { Logger.Instance.Log(false, null, LoggerEvent.Error, "\n\n"); Logger.Instance.Log(false, null, LoggerEvent.Error, "Hmmmm... something didn't work. Try the latest version."); Logger.Instance.Log(false, null, LoggerEvent.Error, " EX: {0} : message: {1}", ex.GetType(), ex.Message); Logger.Instance.Log(false, null, LoggerEvent.Error, "If it's a supported obfuscator, it could be a bug or a new obfuscator version."); Logger.Instance.Log(false, null, LoggerEvent.Error, "If it's an unsupported obfuscator, make sure the methods are decrypted!"); Logger.Instance.Log(false, null, LoggerEvent.Error, "Send bug reports to de4dot@gmail.com or go to https://github.com/0xd4d/de4dot/issues"); } exitCode = 1; } if (Logger.Instance.NumIgnoredMessages > 0) { Logger.n("Ignored {0} warnings/errors", Logger.Instance.NumIgnoredMessages); Logger.n("Use -v/-vv option or set environment variable {0}=1 to see all messages", showAllMessagesEnvName); } if (isN00bUser()) { Console.Error.WriteLine("\n\nPress any key to exit...\n"); try { Console.ReadKey(true); } catch (InvalidOperationException) { } } return exitCode; } static bool printFullStackTrace() { if (!Logger.Instance.IgnoresEvent(LoggerEvent.Verbose)) return true; if (hasEnv("STACKTRACE")) return true; return false; } static bool hasEnv(string name) { foreach (var tmp in Environment.GetEnvironmentVariables().Keys) { var env = tmp as string; if (env == null) continue; if (string.Equals(env, name, StringComparison.OrdinalIgnoreCase)) return true; } return false; } static bool isN00bUser() { if (hasEnv("VisualStudioDir")) return false; return hasEnv("windir") && !hasEnv("PROMPT"); } public static void printStackTrace(Exception ex) { printStackTrace(ex, LoggerEvent.Error); } public static void printStackTrace(Exception ex, LoggerEvent loggerEvent) { var line = new string('-', 78); Logger.Instance.Log(false, null, loggerEvent, "\n\n"); Logger.Instance.Log(false, null, loggerEvent, line); Logger.Instance.Log(false, null, loggerEvent, "Stack trace:\n{0}", ex.StackTrace); Logger.Instance.Log(false, null, loggerEvent, "\n\nERROR: Caught an exception:\n"); Logger.Instance.Log(false, null, loggerEvent, line); Logger.Instance.Log(false, null, loggerEvent, "Message:"); Logger.Instance.Log(false, null, loggerEvent, " {0}", ex.Message); Logger.Instance.Log(false, null, loggerEvent, "Type:"); Logger.Instance.Log(false, null, loggerEvent, " {0}", ex.GetType()); Logger.Instance.Log(false, null, loggerEvent, line); } static void parseCommandLine(string[] args, FilesDeobfuscator.Options options) { new CommandLineParser(deobfuscatorInfos, options).parse(args); Logger.vv("Args:"); Logger.Instance.indent(); foreach (var arg in args) Logger.vv("{0}", Utils.toCsharpString(arg)); Logger.Instance.deIndent(); } } }