From ae9f59c91896428aaa93f1ed834b8789fceed32a Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 8 Oct 2011 13:33:48 +0200 Subject: [PATCH] Less memory are used when loading files one at a time --- de4dot.code/FilesDeobfuscator.cs | 136 +++++++++++++++++-------------- 1 file changed, 77 insertions(+), 59 deletions(-) diff --git a/de4dot.code/FilesDeobfuscator.cs b/de4dot.code/FilesDeobfuscator.cs index acea5362..f05ac97c 100644 --- a/de4dot.code/FilesDeobfuscator.cs +++ b/de4dot.code/FilesDeobfuscator.cs @@ -63,17 +63,21 @@ namespace de4dot { public void doIt() { if (options.DetectObfuscators) - loadAllFiles(); + detectObfuscators(); else if (options.OneFileAtATime) deobfuscateOneAtATime(); else deobfuscateAll(); } - void deobfuscateOneAtATime() { - loadAllFiles(); + void detectObfuscators() { + foreach (var file in loadAllFiles()) { + AssemblyResolver.Instance.removeModule(file.ModuleDefinition); + } + } - foreach (var file in options.Files) { + void deobfuscateOneAtATime() { + foreach (var file in loadAllFiles()) { try { file.deobfuscateBegin(); file.deobfuscate(); @@ -95,13 +99,13 @@ namespace de4dot { } void deobfuscateAll() { - loadAllFiles(); - deobfuscateAllFiles(); - renameAllFiles(); - saveAllFiles(); + var allFiles = new List(loadAllFiles()); + deobfuscateAllFiles(allFiles); + renameAllFiles(allFiles); + saveAllFiles(allFiles); } - void loadAllFiles() { + IEnumerable loadAllFiles() { var loader = new DotNetFileLoader(new DotNetFileLoader.Options { PossibleFiles = options.Files, SearchDirs = options.SearchDirs, @@ -113,14 +117,13 @@ namespace de4dot { ControlFlowDeobfuscation = options.ControlFlowDeobfuscation, KeepObfuscatorTypes = options.KeepObfuscatorTypes, }); - options.Files = loader.load(); + return loader.load(); } class DotNetFileLoader { Options options; Dictionary allFiles = new Dictionary(StringComparer.OrdinalIgnoreCase); Dictionary visitedDirectory = new Dictionary(StringComparer.OrdinalIgnoreCase); - IList files; public class Options { public IEnumerable PossibleFiles { get; set; } @@ -138,23 +141,23 @@ namespace de4dot { this.options = options; } - public IList load() { - files = new List(); + public IEnumerable load() { + foreach (var file in options.PossibleFiles) { + if (add(file)) + yield return file; + } - foreach (var file in options.PossibleFiles) - add(file); - - foreach (var searchDir in options.SearchDirs) - recursiveAdd(searchDir); - - return files; + foreach (var searchDir in options.SearchDirs) { + foreach (var file in loadFiles(searchDir)) + yield return file; + } } - void add(IObfuscatedFile file, bool skipUnknownObfuscator = false) { + bool add(IObfuscatedFile file, bool skipUnknownObfuscator = false) { var key = Utils.getFullPath(file.Filename); if (allFiles.ContainsKey(key)) { Log.w("Ingoring duplicate file: {0}", file.Filename); - return; + return false; } allFiles[key] = true; @@ -162,62 +165,77 @@ namespace de4dot { file.load(options.CreateDeobfuscators()); } catch (NotSupportedException) { - return; // Eg. unsupported architecture + return false; // Eg. unsupported architecture } catch (BadImageFormatException) { - return; // Not a .NET file + return false; // Not a .NET file + } + catch (UnauthorizedAccessException) { + Log.w("Could not load file (not authorized): {0}", file.Filename); + return false; } catch (NullReferenceException) { Log.w("Could not load file (null ref): {0}", file.Filename); - return; + return false; } catch (IOException) { Log.w("Could not load file (io exception): {0}", file.Filename); - return; + return false; } var deob = file.Deobfuscator; if (skipUnknownObfuscator && deob is deobfuscators.Unknown.Deobfuscator) { Log.v("Skipping unknown obfuscator: {0}", file.Filename); + return false; } else { Log.n("Detected {0} ({1})", deob.Name, file.Filename); - files.Add(file); createDirectories(Path.GetDirectoryName(file.NewFilename)); + return true; } } - void recursiveAdd(SearchDir searchDir) { - DirectoryInfo di; + IEnumerable loadFiles(SearchDir searchDir) { + DirectoryInfo di = null; + bool ok = false; try { di = new DirectoryInfo(searchDir.InputDirectory); - if (!di.Exists) - return; + if (di.Exists) + ok = true; } catch (System.Security.SecurityException) { - return; } catch (ArgumentException) { - return; } - doDirectoryInfo(searchDir, di); + if (ok) { + foreach (var filename in doDirectoryInfo(searchDir, di)) { + var obfuscatedFile = createObfuscatedFile(searchDir, filename); + if (obfuscatedFile != null) + yield return obfuscatedFile; + } + } } - void recursiveAdd(SearchDir searchDir, IEnumerable fileSystemInfos) { + IEnumerable recursiveAdd(SearchDir searchDir, IEnumerable fileSystemInfos) { foreach (var fsi in fileSystemInfos) { - if ((int)(fsi.Attributes & FileAttributes.Directory) != 0) - doDirectoryInfo(searchDir, (DirectoryInfo)fsi); - else - doFileInfo(searchDir, (FileInfo)fsi); + if ((int)(fsi.Attributes & FileAttributes.Directory) != 0) { + foreach (var filename in doDirectoryInfo(searchDir, (DirectoryInfo)fsi)) + yield return filename; + } + else { + var fi = (FileInfo)fsi; + if (fi.Exists) + yield return fi.FullName; + } } } - void doDirectoryInfo(SearchDir searchDir, DirectoryInfo di) { + IEnumerable doDirectoryInfo(SearchDir searchDir, DirectoryInfo di) { if (!di.Exists) - return; + return null; if (visitedDirectory.ContainsKey(di.FullName)) - return; + return null; visitedDirectory[di.FullName] = true; FileSystemInfo[] fsinfos; @@ -225,20 +243,17 @@ namespace de4dot { fsinfos = di.GetFileSystemInfos(); } catch (UnauthorizedAccessException) { - return; + return null; } catch (IOException) { - return; + return null; } - recursiveAdd(searchDir, fsinfos); + return recursiveAdd(searchDir, fsinfos); } - void doFileInfo(SearchDir searchDir, FileInfo fi) { - if (!fi.Exists) - return; - + IObfuscatedFile createObfuscatedFile(SearchDir searchDir, string filename) { var fileOptions = new ObfuscatedFile.Options { - Filename = Utils.getFullPath(fi.FullName), + Filename = Utils.getFullPath(filename), RenameSymbols = options.RenameSymbols, ControlFlowDeobfuscation = options.ControlFlowDeobfuscation, KeepObfuscatorTypes = options.KeepObfuscatorTypes, @@ -263,7 +278,10 @@ namespace de4dot { throw new UserException(string.Format("Input and output filename is the same: {0}", fileOptions.Filename)); } - add(new ObfuscatedFile(fileOptions, options.AssemblyClientFactory), searchDir.SkipUnknownObfuscators); + var obfuscatedFile = new ObfuscatedFile(fileOptions, options.AssemblyClientFactory); + if (add(obfuscatedFile, searchDir.SkipUnknownObfuscators)) + return obfuscatedFile; + return null; } void createDirectories(string path) { @@ -275,29 +293,29 @@ namespace de4dot { } } - void deobfuscateAllFiles() { + void deobfuscateAllFiles(IEnumerable allFiles) { try { - foreach (var file in options.Files) + foreach (var file in allFiles) file.deobfuscateBegin(); - foreach (var file in options.Files) { + foreach (var file in allFiles) { file.deobfuscate(); file.deobfuscateEnd(); } } finally { - foreach (var file in options.Files) + foreach (var file in allFiles) file.deobfuscateCleanUp(); } } - void renameAllFiles() { + void renameAllFiles(IEnumerable allFiles) { if (!options.RenameSymbols) return; - new DefinitionsRenamer(options.Files).renameAll(); + new DefinitionsRenamer(allFiles).renameAll(); } - void saveAllFiles() { - foreach (var file in options.Files) + void saveAllFiles(IEnumerable allFiles) { + foreach (var file in allFiles) file.save(); }