Example #1
0
        static string FindPeFromPath(string ModuleName, List <string> CandidateFolders, string ProcessorArch)
        {
            string PeFilePath = null;

            // Filter out "problematic" search paths before it triggers an exception from Path.Combine
            // see https://github.com/lucasg/Dependencies/issues/49
            var CuratedCandidateFolders = CandidateFolders.Where(
                path => !IsFilepathInvalid(path)
                );


            foreach (String CandidatePath in CuratedCandidateFolders)
            {
                PeFilePath = Path.Combine(CandidatePath, ModuleName);
                PE TestPe = BinaryCache.LoadPe(PeFilePath);

                if (TestPe != null && TestPe.LoadSuccessful)
                {
                    Debug.WriteLine("Attempt to load {0:s} {1:s} {2:s}", PeFilePath, TestPe.GetProcessor(), ProcessorArch);
                    if (TestPe.GetProcessor() == ProcessorArch)
                    {
                        return(PeFilePath);
                    }
                }
            }

            return(null);
        }
Example #2
0
        public static SxsEntries GetSxsEntries(PE Pe)
        {
            SxsEntries Entries = new SxsEntries();

            string RootPeFolder   = Path.GetDirectoryName(Pe.Filepath);
            string RootPeFilename = Path.GetFileName(Pe.Filepath);

            // Look for overriding manifest file (named "{$name}.manifest)
            string OverridingManifest = String.Format("{0:s}.manifest", Pe.Filepath);

            if (File.Exists(OverridingManifest))
            {
                return(ExtractDependenciesFromSxsManifestFile(
                           OverridingManifest,
                           RootPeFolder,
                           RootPeFilename,
                           Pe.GetProcessor()
                           ));
            }

            // Retrieve embedded manifest
            string PeManifest = Pe.GetManifest();

            if (PeManifest.Length == 0)
            {
                return(Entries);
            }


            byte[]           RawManifest    = System.Text.Encoding.UTF8.GetBytes(PeManifest);
            System.IO.Stream ManifestStream = new System.IO.MemoryStream(RawManifest);

            Entries = ExtractDependenciesFromSxsManifest(
                ManifestStream,
                RootPeFolder,
                RootPeFilename,
                Pe.GetProcessor()
                );
            return(Entries);
        }
Example #3
0
        // 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
                       ));
        }