2011-09-22 10:55:30 +08:00
|
|
|
|
/*
|
|
|
|
|
Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
2011-11-05 16:35:36 +08:00
|
|
|
|
using System.Text.RegularExpressions;
|
2011-09-22 10:55:30 +08:00
|
|
|
|
using Mono.Cecil;
|
|
|
|
|
|
|
|
|
|
namespace de4dot {
|
|
|
|
|
class AssemblyResolver : DefaultAssemblyResolver {
|
|
|
|
|
public static readonly AssemblyResolver Instance = new AssemblyResolver();
|
|
|
|
|
Dictionary<string, bool> addedAssemblies = new Dictionary<string, bool>(StringComparer.Ordinal);
|
|
|
|
|
Dictionary<string, bool> addedDirectories = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
|
|
static AssemblyResolver() {
|
|
|
|
|
// Make sure there's only ONE assembly resolver
|
|
|
|
|
GlobalAssemblyResolver.Instance = Instance;
|
2011-11-05 16:45:34 +08:00
|
|
|
|
addOtherAssemblySearchPaths();
|
2011-11-05 16:35:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2011-11-05 16:45:34 +08:00
|
|
|
|
static void addOtherAssemblySearchPaths() {
|
|
|
|
|
addOtherAssemblySearchPaths(Environment.GetEnvironmentVariable("ProgramFiles"));
|
|
|
|
|
addOtherAssemblySearchPaths(Environment.GetEnvironmentVariable("ProgramFiles(x86)"));
|
2011-11-05 16:35:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2011-11-05 16:45:34 +08:00
|
|
|
|
static void addOtherAssemblySearchPaths(string path) {
|
2011-11-05 16:35:36 +08:00
|
|
|
|
if (string.IsNullOrEmpty(path))
|
|
|
|
|
return;
|
|
|
|
|
addSilverlightDirs(Path.Combine(path, @"Microsoft Silverlight"));
|
|
|
|
|
addIfExists(path, @"Microsoft SDKs\Silverlight\v3.0\Libraries\Client");
|
|
|
|
|
addIfExists(path, @"Microsoft SDKs\Silverlight\v3.0\Libraries\Server");
|
|
|
|
|
addIfExists(path, @"Microsoft SDKs\Silverlight\v4.0\Libraries\Client");
|
|
|
|
|
addIfExists(path, @"Microsoft SDKs\Silverlight\v4.0\Libraries\Server");
|
|
|
|
|
addIfExists(path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v3.0");
|
|
|
|
|
addIfExists(path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v4.0");
|
2011-11-05 16:45:34 +08:00
|
|
|
|
addIfExists(path, @"Microsoft Visual Studio .NET\Common7\IDE\PublicAssemblies");
|
|
|
|
|
addIfExists(path, @"Microsoft Visual Studio 8.0\Common7\IDE\PublicAssemblies");
|
|
|
|
|
addIfExists(path, @"Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies");
|
|
|
|
|
addIfExists(path, @"Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies");
|
2011-11-05 16:35:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// basePath is eg. "C:\Program Files (x86)\Microsoft Silverlight"
|
|
|
|
|
static void addSilverlightDirs(string basePath) {
|
|
|
|
|
try {
|
|
|
|
|
var di = new DirectoryInfo(basePath);
|
|
|
|
|
foreach (var dir in di.GetDirectories()) {
|
|
|
|
|
if (Regex.IsMatch(dir.Name, @"^\d+(?:\.\d+){3}$"))
|
|
|
|
|
addIfExists(basePath, dir.Name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void addIfExists(string basePath, string extraPath) {
|
|
|
|
|
try {
|
|
|
|
|
var path = Path.Combine(basePath, extraPath);
|
2011-11-05 16:56:51 +08:00
|
|
|
|
if (Utils.pathExists(path))
|
2011-11-05 16:35:36 +08:00
|
|
|
|
Instance.addSearchDirectory(path);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception) {
|
|
|
|
|
}
|
2011-09-22 10:55:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void addSearchDirectory(string dir) {
|
|
|
|
|
if (!addedDirectories.ContainsKey(dir)) {
|
|
|
|
|
addedDirectories[dir] = true;
|
|
|
|
|
AddSearchDirectory(dir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void addModule(ModuleDefinition module) {
|
2011-10-26 20:32:10 +08:00
|
|
|
|
if (module.FullyQualifiedName != "")
|
|
|
|
|
addSearchDirectory(Path.GetDirectoryName(module.FullyQualifiedName));
|
2011-10-05 14:20:32 +08:00
|
|
|
|
|
|
|
|
|
var assembly = module.Assembly;
|
|
|
|
|
if (assembly != null) {
|
|
|
|
|
var name = assembly.Name.FullName;
|
|
|
|
|
if (!addedAssemblies.ContainsKey(name) && cache.ContainsKey(name))
|
|
|
|
|
throw new ApplicationException(string.Format("Assembly {0} was loaded by other code.", name));
|
|
|
|
|
addedAssemblies[name] = true;
|
|
|
|
|
RegisterAssembly(assembly);
|
|
|
|
|
}
|
2011-09-22 10:55:30 +08:00
|
|
|
|
}
|
2011-10-08 19:28:39 +08:00
|
|
|
|
|
|
|
|
|
public void removeModule(ModuleDefinition module) {
|
|
|
|
|
var assembly = module.Assembly;
|
|
|
|
|
if (assembly == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var name = assembly.Name.FullName;
|
|
|
|
|
addedAssemblies.Remove(name);
|
|
|
|
|
cache.Remove(name);
|
|
|
|
|
}
|
2011-09-22 10:55:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|