Less memory are used when loading files one at a time
This commit is contained in:
parent
3719e9a375
commit
ae9f59c918
|
@ -63,17 +63,21 @@ namespace de4dot {
|
||||||
|
|
||||||
public void doIt() {
|
public void doIt() {
|
||||||
if (options.DetectObfuscators)
|
if (options.DetectObfuscators)
|
||||||
loadAllFiles();
|
detectObfuscators();
|
||||||
else if (options.OneFileAtATime)
|
else if (options.OneFileAtATime)
|
||||||
deobfuscateOneAtATime();
|
deobfuscateOneAtATime();
|
||||||
else
|
else
|
||||||
deobfuscateAll();
|
deobfuscateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void deobfuscateOneAtATime() {
|
void detectObfuscators() {
|
||||||
loadAllFiles();
|
foreach (var file in loadAllFiles()) {
|
||||||
|
AssemblyResolver.Instance.removeModule(file.ModuleDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var file in options.Files) {
|
void deobfuscateOneAtATime() {
|
||||||
|
foreach (var file in loadAllFiles()) {
|
||||||
try {
|
try {
|
||||||
file.deobfuscateBegin();
|
file.deobfuscateBegin();
|
||||||
file.deobfuscate();
|
file.deobfuscate();
|
||||||
|
@ -95,13 +99,13 @@ namespace de4dot {
|
||||||
}
|
}
|
||||||
|
|
||||||
void deobfuscateAll() {
|
void deobfuscateAll() {
|
||||||
loadAllFiles();
|
var allFiles = new List<IObfuscatedFile>(loadAllFiles());
|
||||||
deobfuscateAllFiles();
|
deobfuscateAllFiles(allFiles);
|
||||||
renameAllFiles();
|
renameAllFiles(allFiles);
|
||||||
saveAllFiles();
|
saveAllFiles(allFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadAllFiles() {
|
IEnumerable<IObfuscatedFile> loadAllFiles() {
|
||||||
var loader = new DotNetFileLoader(new DotNetFileLoader.Options {
|
var loader = new DotNetFileLoader(new DotNetFileLoader.Options {
|
||||||
PossibleFiles = options.Files,
|
PossibleFiles = options.Files,
|
||||||
SearchDirs = options.SearchDirs,
|
SearchDirs = options.SearchDirs,
|
||||||
|
@ -113,14 +117,13 @@ namespace de4dot {
|
||||||
ControlFlowDeobfuscation = options.ControlFlowDeobfuscation,
|
ControlFlowDeobfuscation = options.ControlFlowDeobfuscation,
|
||||||
KeepObfuscatorTypes = options.KeepObfuscatorTypes,
|
KeepObfuscatorTypes = options.KeepObfuscatorTypes,
|
||||||
});
|
});
|
||||||
options.Files = loader.load();
|
return loader.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
class DotNetFileLoader {
|
class DotNetFileLoader {
|
||||||
Options options;
|
Options options;
|
||||||
Dictionary<string, bool> allFiles = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
Dictionary<string, bool> allFiles = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||||
Dictionary<string, bool> visitedDirectory = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
Dictionary<string, bool> visitedDirectory = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
||||||
IList<IObfuscatedFile> files;
|
|
||||||
|
|
||||||
public class Options {
|
public class Options {
|
||||||
public IEnumerable<IObfuscatedFile> PossibleFiles { get; set; }
|
public IEnumerable<IObfuscatedFile> PossibleFiles { get; set; }
|
||||||
|
@ -138,23 +141,23 @@ namespace de4dot {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<IObfuscatedFile> load() {
|
public IEnumerable<IObfuscatedFile> load() {
|
||||||
files = new List<IObfuscatedFile>();
|
foreach (var file in options.PossibleFiles) {
|
||||||
|
if (add(file))
|
||||||
|
yield return file;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var file in options.PossibleFiles)
|
foreach (var searchDir in options.SearchDirs) {
|
||||||
add(file);
|
foreach (var file in loadFiles(searchDir))
|
||||||
|
yield return file;
|
||||||
foreach (var searchDir in options.SearchDirs)
|
}
|
||||||
recursiveAdd(searchDir);
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(IObfuscatedFile file, bool skipUnknownObfuscator = false) {
|
bool add(IObfuscatedFile file, bool skipUnknownObfuscator = false) {
|
||||||
var key = Utils.getFullPath(file.Filename);
|
var key = Utils.getFullPath(file.Filename);
|
||||||
if (allFiles.ContainsKey(key)) {
|
if (allFiles.ContainsKey(key)) {
|
||||||
Log.w("Ingoring duplicate file: {0}", file.Filename);
|
Log.w("Ingoring duplicate file: {0}", file.Filename);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
allFiles[key] = true;
|
allFiles[key] = true;
|
||||||
|
|
||||||
|
@ -162,62 +165,77 @@ namespace de4dot {
|
||||||
file.load(options.CreateDeobfuscators());
|
file.load(options.CreateDeobfuscators());
|
||||||
}
|
}
|
||||||
catch (NotSupportedException) {
|
catch (NotSupportedException) {
|
||||||
return; // Eg. unsupported architecture
|
return false; // Eg. unsupported architecture
|
||||||
}
|
}
|
||||||
catch (BadImageFormatException) {
|
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) {
|
catch (NullReferenceException) {
|
||||||
Log.w("Could not load file (null ref): {0}", file.Filename);
|
Log.w("Could not load file (null ref): {0}", file.Filename);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
catch (IOException) {
|
catch (IOException) {
|
||||||
Log.w("Could not load file (io exception): {0}", file.Filename);
|
Log.w("Could not load file (io exception): {0}", file.Filename);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var deob = file.Deobfuscator;
|
var deob = file.Deobfuscator;
|
||||||
if (skipUnknownObfuscator && deob is deobfuscators.Unknown.Deobfuscator) {
|
if (skipUnknownObfuscator && deob is deobfuscators.Unknown.Deobfuscator) {
|
||||||
Log.v("Skipping unknown obfuscator: {0}", file.Filename);
|
Log.v("Skipping unknown obfuscator: {0}", file.Filename);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.n("Detected {0} ({1})", deob.Name, file.Filename);
|
Log.n("Detected {0} ({1})", deob.Name, file.Filename);
|
||||||
files.Add(file);
|
|
||||||
createDirectories(Path.GetDirectoryName(file.NewFilename));
|
createDirectories(Path.GetDirectoryName(file.NewFilename));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void recursiveAdd(SearchDir searchDir) {
|
IEnumerable<IObfuscatedFile> loadFiles(SearchDir searchDir) {
|
||||||
DirectoryInfo di;
|
DirectoryInfo di = null;
|
||||||
|
bool ok = false;
|
||||||
try {
|
try {
|
||||||
di = new DirectoryInfo(searchDir.InputDirectory);
|
di = new DirectoryInfo(searchDir.InputDirectory);
|
||||||
if (!di.Exists)
|
if (di.Exists)
|
||||||
return;
|
ok = true;
|
||||||
}
|
}
|
||||||
catch (System.Security.SecurityException) {
|
catch (System.Security.SecurityException) {
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
catch (ArgumentException) {
|
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<FileSystemInfo> fileSystemInfos) {
|
IEnumerable<string> recursiveAdd(SearchDir searchDir, IEnumerable<FileSystemInfo> fileSystemInfos) {
|
||||||
foreach (var fsi in fileSystemInfos) {
|
foreach (var fsi in fileSystemInfos) {
|
||||||
if ((int)(fsi.Attributes & FileAttributes.Directory) != 0)
|
if ((int)(fsi.Attributes & FileAttributes.Directory) != 0) {
|
||||||
doDirectoryInfo(searchDir, (DirectoryInfo)fsi);
|
foreach (var filename in doDirectoryInfo(searchDir, (DirectoryInfo)fsi))
|
||||||
else
|
yield return filename;
|
||||||
doFileInfo(searchDir, (FileInfo)fsi);
|
}
|
||||||
|
else {
|
||||||
|
var fi = (FileInfo)fsi;
|
||||||
|
if (fi.Exists)
|
||||||
|
yield return fi.FullName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void doDirectoryInfo(SearchDir searchDir, DirectoryInfo di) {
|
IEnumerable<string> doDirectoryInfo(SearchDir searchDir, DirectoryInfo di) {
|
||||||
if (!di.Exists)
|
if (!di.Exists)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
if (visitedDirectory.ContainsKey(di.FullName))
|
if (visitedDirectory.ContainsKey(di.FullName))
|
||||||
return;
|
return null;
|
||||||
visitedDirectory[di.FullName] = true;
|
visitedDirectory[di.FullName] = true;
|
||||||
|
|
||||||
FileSystemInfo[] fsinfos;
|
FileSystemInfo[] fsinfos;
|
||||||
|
@ -225,20 +243,17 @@ namespace de4dot {
|
||||||
fsinfos = di.GetFileSystemInfos();
|
fsinfos = di.GetFileSystemInfos();
|
||||||
}
|
}
|
||||||
catch (UnauthorizedAccessException) {
|
catch (UnauthorizedAccessException) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
catch (IOException) {
|
catch (IOException) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
recursiveAdd(searchDir, fsinfos);
|
return recursiveAdd(searchDir, fsinfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void doFileInfo(SearchDir searchDir, FileInfo fi) {
|
IObfuscatedFile createObfuscatedFile(SearchDir searchDir, string filename) {
|
||||||
if (!fi.Exists)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var fileOptions = new ObfuscatedFile.Options {
|
var fileOptions = new ObfuscatedFile.Options {
|
||||||
Filename = Utils.getFullPath(fi.FullName),
|
Filename = Utils.getFullPath(filename),
|
||||||
RenameSymbols = options.RenameSymbols,
|
RenameSymbols = options.RenameSymbols,
|
||||||
ControlFlowDeobfuscation = options.ControlFlowDeobfuscation,
|
ControlFlowDeobfuscation = options.ControlFlowDeobfuscation,
|
||||||
KeepObfuscatorTypes = options.KeepObfuscatorTypes,
|
KeepObfuscatorTypes = options.KeepObfuscatorTypes,
|
||||||
|
@ -263,7 +278,10 @@ namespace de4dot {
|
||||||
throw new UserException(string.Format("Input and output filename is the same: {0}", fileOptions.Filename));
|
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) {
|
void createDirectories(string path) {
|
||||||
|
@ -275,29 +293,29 @@ namespace de4dot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deobfuscateAllFiles() {
|
void deobfuscateAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
||||||
try {
|
try {
|
||||||
foreach (var file in options.Files)
|
foreach (var file in allFiles)
|
||||||
file.deobfuscateBegin();
|
file.deobfuscateBegin();
|
||||||
foreach (var file in options.Files) {
|
foreach (var file in allFiles) {
|
||||||
file.deobfuscate();
|
file.deobfuscate();
|
||||||
file.deobfuscateEnd();
|
file.deobfuscateEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
foreach (var file in options.Files)
|
foreach (var file in allFiles)
|
||||||
file.deobfuscateCleanUp();
|
file.deobfuscateCleanUp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renameAllFiles() {
|
void renameAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
||||||
if (!options.RenameSymbols)
|
if (!options.RenameSymbols)
|
||||||
return;
|
return;
|
||||||
new DefinitionsRenamer(options.Files).renameAll();
|
new DefinitionsRenamer(allFiles).renameAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveAllFiles() {
|
void saveAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
||||||
foreach (var file in options.Files)
|
foreach (var file in allFiles)
|
||||||
file.save();
|
file.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user