public static string GetSystemPath(PE RootPe) { if (RootPe.IsArm32Dll()) { return(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysArm32")); } else if (RootPe.IsWow64Dll()) { return(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86)); } return(Environment.GetFolderPath(Environment.SpecialFolder.System)); }
// default search order : // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx // // if (SafeDllSearchMode) { // -1. Sxs manifests // 0. KnownDlls list // 1. Loaded PE folder // 2. C:\Windows\(System32 | SysWow64 ) // 3. 16-bit system directory <-- ignored // 4. C:\Windows // 5. %pwd% // 6. AppDatas // } public static Tuple <ModuleSearchStrategy, string> FindPeFromDefault(PE RootPe, string ModuleName, SxsEntries SxsCache, List <string> CustomSearchFolders, string WorkingDirectory) { bool Wow64Dll = RootPe.IsWow64Dll(); string ProcessorArch = RootPe.GetProcessor(); string RootPeFolder = Path.GetDirectoryName(RootPe.Filepath); string FoundPePath = null; Environment.SpecialFolder WindowsSystemFolder = (Wow64Dll) ? Environment.SpecialFolder.SystemX86 : Environment.SpecialFolder.System; String WindowsSystemFolderPath = (RootPe.IsArm32Dll()) ? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysArm32") : Environment.GetFolderPath(WindowsSystemFolder); // -1. Look in Sxs manifest (copious reversing needed) // TODO : find dll search order if (SxsCache.Count != 0) { SxsEntry Entry = SxsCache.Find(SxsItem => string.Equals(SxsItem.Name, ModuleName, StringComparison.OrdinalIgnoreCase) ); if (Entry != null) { return(new Tuple <ModuleSearchStrategy, string>(ModuleSearchStrategy.SxS, Entry.Path)); } } // 0. Look in well-known dlls list // HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs // https://blogs.msdn.microsoft.com/larryosterman/2004/07/19/what-are-known-dlls-anyway/ String KnownDll = Phlib.GetKnownDlls(Wow64Dll).Find(x => string.Equals(x, ModuleName, StringComparison.OrdinalIgnoreCase)); if (KnownDll != null) { return(new Tuple <ModuleSearchStrategy, string>( ModuleSearchStrategy.WellKnownDlls, Path.Combine(WindowsSystemFolderPath, KnownDll) )); } // 1. Look in application folder FoundPePath = FindPeFromPath(ModuleName, new List <string>(new string[] { RootPeFolder }), ProcessorArch); if (FoundPePath != null) { return(new Tuple <ModuleSearchStrategy, string>( ModuleSearchStrategy.ApplicationDirectory, FoundPePath )); } // {2-3-4}. Look in system folders List <String> SystemFolders = new List <string>(new string[] { WindowsSystemFolderPath, Environment.GetFolderPath(Environment.SpecialFolder.Windows) } ); FoundPePath = FindPeFromPath(ModuleName, SystemFolders, ProcessorArch); if (FoundPePath != null) { return(new Tuple <ModuleSearchStrategy, string>( ModuleSearchStrategy.WindowsFolder, FoundPePath )); } // 5. Look in current directory // Ignored for the time being since we can't know from // where the exe is run // TODO : Add a user supplied path emulating %cwd% FoundPePath = FindPeFromPath(ModuleName, new List <string>(new string[] { WorkingDirectory }), ProcessorArch); if (FoundPePath != null) { return(new Tuple <ModuleSearchStrategy, string>( ModuleSearchStrategy.WorkingDirectory, FoundPePath )); } // 6. Look in local app data (check for python for exemple) // 7. Find in PATH string PATH = Environment.GetEnvironmentVariable("PATH"); List <String> PATHFolders = new List <string>(PATH.Split(';')); // Filter out empty paths, since it resolve to the current working directory // fix https://github.com/lucasg/Dependencies/issues/51 PATHFolders = PATHFolders.Where(path => path.Length != 0).ToList(); FoundPePath = FindPeFromPath(ModuleName, PATHFolders, ProcessorArch); if (FoundPePath != null) { return(new Tuple <ModuleSearchStrategy, string>( ModuleSearchStrategy.Environment, FoundPePath )); } // 8. Check if it's an absolute import if (ModuleName != "" && (Path.GetFullPath(ModuleName) == ModuleName) && File.Exists(ModuleName)) { return(new Tuple <ModuleSearchStrategy, string>( ModuleSearchStrategy.Fullpath, ModuleName )); } // 0xff. Allow the user to supply custom search folders, to take into account // specific cases. FoundPePath = FindPeFromPath(ModuleName, CustomSearchFolders, ProcessorArch); if (FoundPePath != null) { return(new Tuple <ModuleSearchStrategy, string>( ModuleSearchStrategy.UserDefined, FoundPePath )); } return(new Tuple <ModuleSearchStrategy, string>( ModuleSearchStrategy.NOT_FOUND, null )); }