Exemplo n.º 1
0
 void printOption(Option option)
 {
     string defaultAndDesc;
     if (option.NeedArgument && option.Default != null)
         defaultAndDesc = string.Format("{0} ({1})", option.Description, option.Default);
     else
         defaultAndDesc = option.Description;
     printOptionAndExplanation(getOptionAndArgName(option, option.ShortName ?? option.LongName), defaultAndDesc);
     if (option.ShortName != null && option.LongName != null)
         printOptionAndExplanation(option.LongName, string.Format("Same as {0}", option.ShortName));
 }
Exemplo n.º 2
0
 string getOptionAndArgName(Option option, string optionName)
 {
     if (option.NeedArgument)
         return optionName + " " + option.ArgumentValueName.ToUpperInvariant();
     else
         return optionName;
 }
Exemplo n.º 3
0
        void addAllOptions()
        {
            miscOptions.Add(new OneArgOption("r", null, "Scan for .NET files in all subdirs", "dir", (val) => {
                addSearchDir();
                searchDir = new FilesDeobfuscator.SearchDir();
                if (!Utils.pathExists(val))
                    exitError(string.Format("Directory {0} does not exist", val));
                searchDir.InputDirectory = val;
            }));
            miscOptions.Add(new OneArgOption("ro", null, "Output base dir for recursively found files", "dir", (val) => {
                if (searchDir == null)
                    exitError("Missing -r option");
                searchDir.OutputDirectory = val;
            }));
            miscOptions.Add(new NoArgOption("ru", null, "Skip recursively found files with unsupported obfuscator", () => {
                if (searchDir == null)
                    exitError("Missing -r option");
                searchDir.SkipUnknownObfuscators = true;
            }));
            miscOptions.Add(new NoArgOption("d", null, "Detect obfuscators and exit", () => {
                filesOptions.DetectObfuscators = true;
            }));
            miscOptions.Add(new OneArgOption(null, "asm-path", "Add an assembly search path", "path", (val) => {
                AssemblyResolver.Instance.addSearchDirectory(val);
            }));
            miscOptions.Add(new NoArgOption(null, "dont-rename", "Don't rename classes, methods, etc.", () => {
                filesOptions.RenameSymbols = false;
            }));
            miscOptions.Add(new NoArgOption(null, "dont-restore-props", "Don't restore properties/events", () => {
                filesOptions.RestorePropsEvents = false;
            }));
            miscOptions.Add(new OneArgOption(null, "default-strtyp", "Default string decrypter type", "type", (val) => {
                object decrypterType;
                if (!stringDecrypterTypes.getValue(val, out decrypterType))
                    exitError(string.Format("Invalid string decrypter type '{0}'", val));
                defaultStringDecrypterType = (DecrypterType)decrypterType;
            }));
            miscOptions.Add(new OneArgOption(null, "default-strtok", "Default string decrypter method token or [type::][name][(args,...)]", "method", (val) => {
                defaultStringDecrypterMethods.Add(val);
            }));
            miscOptions.Add(new NoArgOption(null, "no-cflow-deob", "No control flow deobfuscation (NOT recommended)", () => {
                filesOptions.ControlFlowDeobfuscation = false;
            }));
            miscOptions.Add(new NoArgOption(null, "load-new-process", "Load executed assemblies into a new process", () => {
                filesOptions.AssemblyClientFactory = new NewProcessAssemblyClientFactory();
            }));
            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;
            }));
            miscOptions.Add(new NoArgOption("vv", null, "Very verbose", () => {
                Log.logLevel = Log.LogLevel.veryverbose;
            }));
            miscOptions.Add(new NoArgOption("h", "help", "Show this help message", () => {
                usage();
                exit(0);
            }));

            defaultOption = new OneArgOption("f", null, "Name of .NET file", "file", (val) => {
                addFile();
                if (!Utils.fileExists(val))
                    exitError(string.Format("File \"{0}\" does not exist.", val));
                newFileOptions = new ObfuscatedFile.Options {
                    Filename = val,
                    ControlFlowDeobfuscation = filesOptions.ControlFlowDeobfuscation,
                    KeepObfuscatorTypes = filesOptions.KeepObfuscatorTypes,
                };
                if (defaultStringDecrypterType != null)
                    newFileOptions.StringDecrypterType = defaultStringDecrypterType.Value;
                newFileOptions.StringDecrypterMethods.AddRange(defaultStringDecrypterMethods);
            });
            fileOptions.Add(defaultOption);
            fileOptions.Add(new OneArgOption("o", null, "Name of output file", "file", (val) => {
                if (newFileOptions == null)
                    exitError("Missing input file");
                if (string.Equals(Utils.getFullPath(newFileOptions.Filename), Utils.getFullPath(val), StringComparison.OrdinalIgnoreCase))
                    exitError(string.Format("Output file can't be same as input file ({0})", val));
                newFileOptions.NewFilename = val;
            }));
            fileOptions.Add(new OneArgOption("p", null, "Obfuscator type (see below)", "type", (val) => {
                if (newFileOptions == null)
                    exitError("Missing input file");
                if (!isValidObfuscatorType(val))
                    exitError(string.Format("Invalid obfuscator type '{0}'", val));
                newFileOptions.ForcedObfuscatorType = val;
            }));
            fileOptions.Add(new OneArgOption(null, "strtyp", "String decrypter type", "type", (val) => {
                if (newFileOptions == null)
                    exitError("Missing input file");
                object decrypterType;
                if (!stringDecrypterTypes.getValue(val, out decrypterType))
                    exitError(string.Format("Invalid string decrypter type '{0}'", val));
                newFileOptions.StringDecrypterType = (DecrypterType)decrypterType;
            }));
            fileOptions.Add(new OneArgOption(null, "strtok", "String decrypter method token or [type::][name][(args,...)]", "method", (val) => {
                if (newFileOptions == null)
                    exitError("Missing input file");
                newFileOptions.StringDecrypterMethods.Add(val);
            }));

            addOptions(miscOptions);
            addOptions(fileOptions);
            foreach (var info in deobfuscatorInfos)
                addOptions(info.getOptions());
        }
Exemplo n.º 4
0
 void addOption(Option option, string name)
 {
     if (name == null)
         return;
     if (optionsDict.ContainsKey(name))
         throw new ApplicationException(string.Format("Option {0} is present twice!", name));
     optionsDict[name] = option;
 }
Exemplo n.º 5
0
		void AddAllOptions() {
			miscOptions.Add(new OneArgOption("r", null, "Scan for .NET files in all subdirs", "dir", (val) => {
				AddSearchDir();
				searchDir = new FilesDeobfuscator.SearchDir();
				if (!Utils.PathExists(val))
					ExitError(string.Format("Directory {0} does not exist", val));
				searchDir.InputDirectory = val;
			}));
			miscOptions.Add(new OneArgOption("ro", null, "Output base dir for recursively found files", "dir", (val) => {
				if (searchDir == null)
					ExitError("Missing -r option");
				searchDir.OutputDirectory = val;
			}));
			miscOptions.Add(new NoArgOption("ru", null, "Skip recursively found files with unsupported obfuscator", () => {
				if (searchDir == null)
					ExitError("Missing -r option");
				searchDir.SkipUnknownObfuscators = true;
			}));
			miscOptions.Add(new NoArgOption("d", null, "Detect obfuscators and exit", () => {
				filesOptions.DetectObfuscators = true;
			}));
			miscOptions.Add(new OneArgOption(null, "asm-path", "Add an assembly search path", "path", (val) => {
				TheAssemblyResolver.Instance.AddSearchDirectory(val);
			}));
			miscOptions.Add(new NoArgOption(null, "dont-rename", "Don't rename classes, methods, etc.", () => {
				filesOptions.RenameSymbols = false;
				filesOptions.RenamerFlags = 0;
			}));
			miscOptions.Add(new OneArgOption(null, "keep-names", "Don't rename n(amespaces), t(ypes), p(rops), e(vents), f(ields), m(ethods), a(rgs), g(enericparams), d(elegate fields). Can be combined, eg. efm", "flags", (val) => {
				foreach (var c in val) {
					switch (c) {
					case 'n': filesOptions.RenamerFlags &= ~RenamerFlags.RenameNamespaces; break;
					case 't': filesOptions.RenamerFlags &= ~RenamerFlags.RenameTypes; break;
					case 'p': filesOptions.RenamerFlags &= ~RenamerFlags.RenameProperties; break;
					case 'e': filesOptions.RenamerFlags &= ~RenamerFlags.RenameEvents; break;
					case 'f': filesOptions.RenamerFlags &= ~RenamerFlags.RenameFields; break;
					case 'm': filesOptions.RenamerFlags &= ~RenamerFlags.RenameMethods; break;
					case 'a': filesOptions.RenamerFlags &= ~RenamerFlags.RenameMethodArgs; break;
					case 'g': filesOptions.RenamerFlags &= ~RenamerFlags.RenameGenericParams; break;
					case 'd': filesOptions.RenamerFlags |= RenamerFlags.DontRenameDelegateFields; break;
					default: throw new UserException(string.Format("Unrecognized --keep-names char: '{0}'", c));
					}
				}
			}));
			miscOptions.Add(new NoArgOption(null, "dont-create-params", "Don't create method params when renaming", () => {
				filesOptions.RenamerFlags |= RenamerFlags.DontCreateNewParamDefs;
			}));
			miscOptions.Add(new NoArgOption(null, "dont-restore-props", "Don't restore properties/events", () => {
				filesOptions.RenamerFlags &= ~(RenamerFlags.RestorePropertiesFromNames | RenamerFlags.RestoreEventsFromNames);
			}));
			miscOptions.Add(new OneArgOption(null, "default-strtyp", "Default string decrypter type", "type", (val) => {
				object decrypterType;
				if (!stringDecrypterTypes.GetValue(val, out decrypterType))
					ExitError(string.Format("Invalid string decrypter type '{0}'", val));
				defaultStringDecrypterType = (DecrypterType)decrypterType;
			}));
			miscOptions.Add(new OneArgOption(null, "default-strtok", "Default string decrypter method token or [type::][name][(args,...)]", "method", (val) => {
				defaultStringDecrypterMethods.Add(val);
			}));
			miscOptions.Add(new NoArgOption(null, "no-cflow-deob", "No control flow deobfuscation (NOT recommended)", () => {
				filesOptions.ControlFlowDeobfuscation = false;
			}));
			miscOptions.Add(new NoArgOption(null, "load-new-process", "Load executed assemblies into a new process", () => {
				filesOptions.AssemblyClientFactory = new NewProcessAssemblyClientFactory();
			}));
			miscOptions.Add(new NoArgOption(null, "keep-types", "Keep obfuscator types, fields, methods", () => {
				filesOptions.KeepObfuscatorTypes = true;
			}));
			miscOptions.Add(new NoArgOption(null, "preserve-tokens", "Preserve important tokens, #US, #Blob, extra sig data", () => {
				filesOptions.MetaDataFlags |= MetaDataFlags.PreserveRids |
						MetaDataFlags.PreserveUSOffsets |
						MetaDataFlags.PreserveBlobOffsets |
						MetaDataFlags.PreserveExtraSignatureData;
			}));
			miscOptions.Add(new OneArgOption(null, "preserve-table", "Preserve rids in table: tr (TypeRef), td (TypeDef), fd (Field), md (Method), pd (Param), mr (MemberRef), s (StandAloneSig), ed (Event), pr (Property), ts (TypeSpec), ms (MethodSpec), all (all previous tables). Use - to disable (eg. all,-pd). Can be combined: ed,fd,md", "flags", (val) => {
				foreach (var t in val.Split(',')) {
					var s = t.Trim();
					if (s.Length == 0)
						continue;
					bool clear = s[0] == '-';
					if (clear)
						s = s.Substring(1);
					MetaDataFlags flag;
					switch (s.Trim()) {
					case "": flag = 0; break;
					case "all": flag = MetaDataFlags.PreserveRids; break;
					case "tr": flag = MetaDataFlags.PreserveTypeRefRids; break;
					case "td": flag = MetaDataFlags.PreserveTypeDefRids; break;
					case "fd": flag = MetaDataFlags.PreserveFieldRids; break;
					case "md": flag = MetaDataFlags.PreserveMethodRids; break;
					case "pd": flag = MetaDataFlags.PreserveParamRids; break;
					case "mr": flag = MetaDataFlags.PreserveMemberRefRids; break;
					case "s": flag = MetaDataFlags.PreserveStandAloneSigRids; break;
					case "ed": flag = MetaDataFlags.PreserveEventRids; break;
					case "pr": flag = MetaDataFlags.PreservePropertyRids; break;
					case "ts": flag = MetaDataFlags.PreserveTypeSpecRids; break;
					case "ms": flag = MetaDataFlags.PreserveMethodSpecRids; break;
					default: throw new UserException(string.Format("Invalid --preserve-table option: {0}", s));
					}
					if (clear)
						filesOptions.MetaDataFlags &= ~flag;
					else
						filesOptions.MetaDataFlags |= flag;
				}
			}));
			miscOptions.Add(new NoArgOption(null, "preserve-strings", "Preserve #Strings heap offsets", () => {
				filesOptions.MetaDataFlags |= MetaDataFlags.PreserveStringsOffsets;
			}));
			miscOptions.Add(new NoArgOption(null, "preserve-us", "Preserve #US heap offsets", () => {
				filesOptions.MetaDataFlags |= MetaDataFlags.PreserveUSOffsets;
			}));
			miscOptions.Add(new NoArgOption(null, "preserve-blob", "Preserve #Blob heap offsets", () => {
				filesOptions.MetaDataFlags |= MetaDataFlags.PreserveBlobOffsets;
			}));
			miscOptions.Add(new NoArgOption(null, "preserve-sig-data", "Preserve extra data at the end of signatures", () => {
				filesOptions.MetaDataFlags |= MetaDataFlags.PreserveExtraSignatureData;
			}));
			miscOptions.Add(new NoArgOption(null, "one-file", "Deobfuscate one file at a time", () => {
				filesOptions.OneFileAtATime = true;
			}));
			miscOptions.Add(new NoArgOption("v", null, "Verbose", () => {
				Logger.Instance.MaxLoggerEvent = LoggerEvent.Verbose;
				Logger.Instance.CanIgnoreMessages = false;
			}));
			miscOptions.Add(new NoArgOption("vv", null, "Very verbose", () => {
				Logger.Instance.MaxLoggerEvent = LoggerEvent.VeryVerbose;
				Logger.Instance.CanIgnoreMessages = false;
			}));
			miscOptions.Add(new NoArgOption("h", "help", "Show this help message", () => {
				Usage();
				Exit(0);
			}));

			defaultOption = new OneArgOption("f", null, "Name of .NET file", "file", (val) => {
				AddFile();
				if (!Utils.FileExists(val))
					ExitError(string.Format("File \"{0}\" does not exist.", val));
				newFileOptions = new ObfuscatedFile.Options {
					Filename = val,
					ControlFlowDeobfuscation = filesOptions.ControlFlowDeobfuscation,
					KeepObfuscatorTypes = filesOptions.KeepObfuscatorTypes,
					MetaDataFlags = filesOptions.MetaDataFlags,
					RenamerFlags = filesOptions.RenamerFlags,
				};
				if (defaultStringDecrypterType != null)
					newFileOptions.StringDecrypterType = defaultStringDecrypterType.Value;
				newFileOptions.StringDecrypterMethods.AddRange(defaultStringDecrypterMethods);
			});
			fileOptions.Add(defaultOption);
			fileOptions.Add(new OneArgOption("o", null, "Name of output file", "file", (val) => {
				if (newFileOptions == null)
					ExitError("Missing input file");
				var newFilename = Utils.GetFullPath(val);
				if (string.Equals(Utils.GetFullPath(newFileOptions.Filename), newFilename, StringComparison.OrdinalIgnoreCase))
					ExitError(string.Format("Output file can't be same as input file ({0})", newFilename));
				newFileOptions.NewFilename = newFilename;
			}));
			fileOptions.Add(new OneArgOption("p", null, "Obfuscator type (see below)", "type", (val) => {
				if (newFileOptions == null)
					ExitError("Missing input file");
				if (!IsValidObfuscatorType(val))
					ExitError(string.Format("Invalid obfuscator type '{0}'", val));
				newFileOptions.ForcedObfuscatorType = val;
			}));
			fileOptions.Add(new OneArgOption(null, "strtyp", "String decrypter type", "type", (val) => {
				if (newFileOptions == null)
					ExitError("Missing input file");
				object decrypterType;
				if (!stringDecrypterTypes.GetValue(val, out decrypterType))
					ExitError(string.Format("Invalid string decrypter type '{0}'", val));
				newFileOptions.StringDecrypterType = (DecrypterType)decrypterType;
			}));
			fileOptions.Add(new OneArgOption(null, "strtok", "String decrypter method token or [type::][name][(args,...)]", "method", (val) => {
				if (newFileOptions == null)
					ExitError("Missing input file");
				newFileOptions.StringDecrypterMethods.Add(val);
			}));

			AddOptions(miscOptions);
			AddOptions(fileOptions);
			foreach (var info in deobfuscatorInfos)
				AddOptions(info.GetOptions());
		}