Ejemplo n.º 1
0
 void AddSearchDir()
 {
     if (searchDir == null)
     {
         return;
     }
     filesOptions.SearchDirs.Add(searchDir);
     searchDir = null;
 }
Ejemplo n.º 2
0
 void addSearchDir()
 {
     if (searchDir == null)
         return;
     filesOptions.SearchDirs.Add(searchDir);
     searchDir = null;
 }
Ejemplo 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());
        }
Ejemplo n.º 4
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());
		}
Ejemplo 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($"Directory {val} does not exist");
                }
                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($"Unrecognized --keep-names char: '{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) => {
                if (!stringDecrypterTypes.GetValue(val, out object decrypterType))
                {
                    ExitError($"Invalid string decrypter type '{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, "only-cflow-deob", "Only control flow deobfuscation", () => {
                filesOptions.ControlFlowDeobfuscation = true;
                // --strtyp none
                defaultStringDecrypterType = DecrypterType.None;
                // --keep-types
                filesOptions.KeepObfuscatorTypes = true;
                // --preserve-tokens
                filesOptions.MetadataFlags |= MetadataFlags.PreserveRids |
                                              MetadataFlags.PreserveUSOffsets |
                                              MetadataFlags.PreserveBlobOffsets |
                                              MetadataFlags.PreserveExtraSignatureData;
                // --dont-rename
                filesOptions.RenameSymbols = false;
                filesOptions.RenamerFlags  = 0;
            }));
            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", () => {
                newFileOptions.KeepObfuscatorTypes = true;
            }));
            miscOptions.Add(new NoArgOption(null, "preserve-tokens", "Preserve important tokens, #US, #Blob, extra sig data", () => {
                newFileOptions.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($"Invalid --preserve-table option: {s}");
                    }
                    if (clear)
                    {
                        filesOptions.MetadataFlags &= ~flag;
                    }
                    else
                    {
                        filesOptions.MetadataFlags |= flag;
                    }
                }
            }));
            miscOptions.Add(new NoArgOption(null, "preserve-all", "Preserve all tokens", () => {
                newFileOptions.MetadataFlags |= MetadataFlags.PreserveAll;
            }));
            miscOptions.Add(new NoArgOption(null, "preserve-strings", "Preserve #Strings heap offsets", () => {
                newFileOptions.MetadataFlags |= MetadataFlags.PreserveStringsOffsets;
            }));
            miscOptions.Add(new NoArgOption(null, "preserve-us", "Preserve #US heap offsets", () => {
                newFileOptions.MetadataFlags |= MetadataFlags.PreserveUSOffsets;
            }));
            miscOptions.Add(new NoArgOption(null, "preserve-blob", "Preserve #Blob heap offsets", () => {
                newFileOptions.MetadataFlags |= MetadataFlags.PreserveBlobOffsets;
            }));
            miscOptions.Add(new NoArgOption(null, "preserve-sig-data", "Preserve extra data at the end of signatures", () => {
                newFileOptions.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($"File \"{val}\" does not exist.");
                }
                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($"Output file can't be same as input file ({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($"Invalid obfuscator type '{val}'");
                }
                newFileOptions.ForcedObfuscatorType = val;
            }));
            fileOptions.Add(new OneArgOption(null, "strtyp", "String decrypter type", "type", (val) => {
                if (newFileOptions == null)
                {
                    ExitError("Missing input file");
                }
                if (!stringDecrypterTypes.GetValue(val, out object decrypterType))
                {
                    ExitError($"Invalid string decrypter type '{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());
            }
        }
Ejemplo n.º 6
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());
            }
        }