public void InitializeView()
        {
            if (!NativeFile.Exists(this.Filename))
            {
                MessageBox.Show(
                    String.Format("{0:s} is not present on the disk", this.Filename),
                    "Invalid PE",
                    MessageBoxButton.OK
                    );

                return;
            }

            this.Pe = (Application.Current as App).LoadBinary(this.Filename);
            if (this.Pe == null || !this.Pe.LoadSuccessful)
            {
                MessageBox.Show(
                    String.Format("{0:s} is not a valid PE-COFF file", this.Filename),
                    "Invalid PE",
                    MessageBoxButton.OK
                    );

                return;
            }

            this.SymPrv                = new PhSymbolProvider();
            this.RootFolder            = Path.GetDirectoryName(this.Filename);
            this.SxsEntriesCache       = SxsManifest.GetSxsEntries(this.Pe);
            this.ProcessedModulesCache = new ModulesCache();
            this.ApiSetmapCache        = Phlib.GetApiSetSchema();
            this._SelectedModule       = null;
            this._DisplayWarning       = false;

            // TODO : Find a way to properly bind commands instead of using this hack
            this.ModulesList.Items.Clear();
            this.ModulesList.DoFindModuleInTreeCommand   = DoFindModuleInTree;
            this.ModulesList.ConfigureSearchOrderCommand = ConfigureSearchOrderCommand;

            var RootFilename = Path.GetFileName(this.Filename);
            var RootModule   = new DisplayModuleInfo(RootFilename, this.Pe, ModuleSearchStrategy.ROOT);

            this.ProcessedModulesCache.Add(new ModuleCacheKey(RootFilename, this.Filename), RootModule);

            ModuleTreeViewItem    treeNode             = new ModuleTreeViewItem();
            DependencyNodeContext childTreeInfoContext = new DependencyNodeContext()
            {
                ModuleInfo = new WeakReference(RootModule),
                IsDummy    = false
            };

            treeNode.DataContext = childTreeInfoContext;
            treeNode.Header      = treeNode.GetTreeNodeHeaderName(Dependencies.Properties.Settings.Default.FullPath);
            treeNode.IsExpanded  = true;

            this.DllTreeView.Items.Clear();
            this.DllTreeView.Items.Add(treeNode);

            // Recursively construct tree of dll imports
            ConstructDependencyTree(treeNode, this.Pe);
        }
        private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            DependencyNodeContext childTreeContext = ((DependencyNodeContext)(this.DllTreeView.SelectedItem as ModuleTreeViewItem).DataContext);
            DisplayModuleInfo     SelectedModule   = childTreeContext.ModuleInfo.Target as DisplayModuleInfo;

            // Selected Pe has not been found on disk
            if (SelectedModule == null)
            {
                return;
            }

            UpdateImportExportLists(SelectedModule);
        }
        private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            if (this.DllTreeView.SelectedItem == null)
            {
                UpdateImportExportLists(null, null);
                return;
            }

            DependencyNodeContext childTreeContext = ((DependencyNodeContext)(this.DllTreeView.SelectedItem as ModuleTreeViewItem).DataContext);
            DisplayModuleInfo     SelectedModule   = childTreeContext.ModuleInfo.Target as DisplayModuleInfo;

            if (SelectedModule == null)
            {
                return;
            }

            // Selected Pe has not been found on disk : unvalidate current module
            SelectedModule.HasErrors = !NativeFile.Exists(SelectedModule.Filepath);
            if (SelectedModule.HasErrors)
            {
                // TODO : do a proper refresh instead of asking the user to do it
                System.Windows.MessageBox.Show(String.Format("We could not find {0:s} file on the disk anymore, please fix this problem and refresh the window via F5", SelectedModule.Filepath));
            }

            // Root Item : no parent
            ModuleTreeViewItem TreeRootItem = this.DllTreeView.Items[0] as ModuleTreeViewItem;
            ModuleTreeViewItem SelectedItem = this.DllTreeView.SelectedItem as ModuleTreeViewItem;

            if (SelectedItem == TreeRootItem)
            {
                // Selected Pe has not been found on disk : unvalidate current module
                if (SelectedModule.HasErrors)
                {
                    UpdateImportExportLists(null, null);
                }
                else
                {
                    SelectedModule.HasErrors = false;
                    UpdateImportExportLists(SelectedModule, null);
                }

                return;
            }

            // Tree Item
            DisplayModuleInfo parentModule = SelectedItem.ParentModule.ModuleInfo;

            UpdateImportExportLists(SelectedModule, parentModule);
        }
Beispiel #4
0
        public DependencyWindow(String FileName)
        {
            InitializeComponent();

            this.Filename = FileName;
            this.Pe       = new PE(FileName);

            if (!this.Pe.LoadSuccessful)
            {
                MessageBox.Show(
                    String.Format("{0:s} is not a valid PE-COFF file", this.Filename),
                    "Invalid PE",
                    MessageBoxButton.OK
                    );
                return;
            }

            this.SymPrv                = new PhSymbolProvider();
            this.RootFolder            = Path.GetDirectoryName(FileName);
            this.SxsEntriesCache       = SxsManifest.GetSxsEntries(this.Pe);
            this.ProcessedModulesCache = new ModulesCache();
            this.ApiSetmapCache        = Phlib.GetApiSetSchema();

            // TODO : Find a way to properly bind commands instead of using this hack
            this.ModulesList.DoFindModuleInTreeCommand = DoFindModuleInTree;

            var RootFilename = Path.GetFileName(FileName);
            var RootModule   = new DisplayModuleInfo(RootFilename, this.Pe);

            this.ProcessedModulesCache.Add(new ModuleCacheKey(RootFilename, FileName), RootModule);

            ModuleTreeViewItem    treeNode             = new ModuleTreeViewItem();
            DependencyNodeContext childTreeInfoContext = new DependencyNodeContext()
            {
                ModuleInfo = new WeakReference(RootModule),
                IsDummy    = false
            };

            treeNode.DataContext = childTreeInfoContext;
            treeNode.Header      = treeNode.GetTreeNodeHeaderName(Dependencies.Properties.Settings.Default.FullPath);
            treeNode.IsExpanded  = true;

            this.DllTreeView.Items.Add(treeNode);

            // Recursively construct tree of dll imports
            ConstructDependencyTree(treeNode, this.Pe);
        }
        private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            if (this.DllTreeView.SelectedItem == null)
            {
                UpdateImportExportLists(null, null);
                return;
            }

            DependencyNodeContext childTreeContext = ((DependencyNodeContext)(this.DllTreeView.SelectedItem as ModuleTreeViewItem).DataContext);
            DisplayModuleInfo     SelectedModule   = childTreeContext.ModuleInfo.Target as DisplayModuleInfo;

            // Selected Pe has not been found on disk
            if (SelectedModule == null)
            {
                return;
            }

            // Root Item : no parent
            ModuleTreeViewItem TreeRootItem = this.DllTreeView.Items[0] as ModuleTreeViewItem;
            ModuleTreeViewItem SelectedItem = this.DllTreeView.SelectedItem as ModuleTreeViewItem;

            if (SelectedItem == TreeRootItem)
            {
                UpdateImportExportLists(SelectedModule, null);
                return;
            }

            // find parent. TODO : add parent ref to treeview context
            var parent = VisualTreeHelper.GetParent(SelectedItem as DependencyObject);

            while ((parent as TreeViewItem) == null)
            {
                parent = VisualTreeHelper.GetParent(parent);
            }

            DependencyNodeContext parentTreeContext = ((DependencyNodeContext)(parent as ModuleTreeViewItem).DataContext);
            DisplayModuleInfo     parentModule      = parentTreeContext.ModuleInfo.Target as DisplayModuleInfo;

            UpdateImportExportLists(SelectedModule, parentModule);
        }
Beispiel #6
0
        /// <summary>
        /// Resolve imports when the user expand the node.
        /// </summary>
        private void ResolveDummyEntries(object sender, RoutedEventArgs e)
        {
            ModuleTreeViewItem NeedDummyPeNode = e.OriginalSource as ModuleTreeViewItem;

            if (NeedDummyPeNode.Items.Count == 0)
            {
                return;
            }
            ModuleTreeViewItem    MaybeDummyNode = (ModuleTreeViewItem)NeedDummyPeNode.Items[0];
            DependencyNodeContext Context        = (DependencyNodeContext)MaybeDummyNode.DataContext;

            //TODO: Improve resolution predicate
            if (!Context.IsDummy)
            {
                return;
            }

            NeedDummyPeNode.Items.Clear();
            string Filepath = NeedDummyPeNode.ModuleFilePath;

            ConstructDependencyTree(NeedDummyPeNode, Filepath);
        }
Beispiel #7
0
        private void ConstructDependencyTree(ModuleTreeViewItem RootNode, PE CurrentPE, int RecursionLevel = 0)
        {
            // "Closured" variables (it 's a scope hack really).
            Dictionary <string, ImportContext> NewTreeContexts = new Dictionary <string, ImportContext>();

            BackgroundWorker bw = new BackgroundWorker();

            bw.WorkerReportsProgress = true; // useless here for now


            bw.DoWork += (sender, e) => {
                ProcessPe(NewTreeContexts, CurrentPE);
            };


            bw.RunWorkerCompleted += (sender, e) =>
            {
                TreeBuildingBehaviour.DependencyTreeBehaviour SettingTreeBehaviour = Dependencies.TreeBuildingBehaviour.GetGlobalBehaviour();
                List <ModuleTreeViewItem> PeWithDummyEntries  = new List <ModuleTreeViewItem>();
                List <BacklogImport>      PEProcessingBacklog = new List <BacklogImport>();

                // Important !
                //
                // This handler is executed in the STA (Single Thread Application)
                // which is authorized to manipulate UI elements. The BackgroundWorker is not.
                //

                foreach (ImportContext NewTreeContext in NewTreeContexts.Values)
                {
                    ModuleTreeViewItem    childTreeNode        = new ModuleTreeViewItem();
                    DependencyNodeContext childTreeNodeContext = new DependencyNodeContext();
                    childTreeNodeContext.IsDummy = false;

                    string         ModuleName     = NewTreeContext.ModuleName;
                    string         ModuleFilePath = NewTreeContext.PeFilePath;
                    ModuleCacheKey ModuleKey      = new ModuleCacheKey(ModuleName, ModuleFilePath);

                    // Newly seen modules
                    if (!this.ProcessedModulesCache.ContainsKey(ModuleKey))
                    {
                        // Missing module "found"
                        if ((NewTreeContext.PeFilePath == null) || !NativeFile.Exists(NewTreeContext.PeFilePath))
                        {
                            this.ProcessedModulesCache[ModuleKey] = new NotFoundModuleInfo(ModuleName);
                        }
                        else
                        {
                            if (NewTreeContext.IsApiSet)
                            {
                                var ApiSetContractModule = new DisplayModuleInfo(NewTreeContext.ApiSetModuleName, NewTreeContext.PeProperties, NewTreeContext.ModuleLocation, NewTreeContext.Flags);
                                var NewModule            = new ApiSetModuleInfo(NewTreeContext.ModuleName, ref ApiSetContractModule);

                                this.ProcessedModulesCache[ModuleKey] = NewModule;

                                if (SettingTreeBehaviour == TreeBuildingBehaviour.DependencyTreeBehaviour.Recursive)
                                {
                                    PEProcessingBacklog.Add(new BacklogImport(childTreeNode, ApiSetContractModule.ModuleName));
                                }
                            }
                            else
                            {
                                var NewModule = new DisplayModuleInfo(NewTreeContext.ModuleName, NewTreeContext.PeProperties, NewTreeContext.ModuleLocation, NewTreeContext.Flags);
                                this.ProcessedModulesCache[ModuleKey] = NewModule;

                                switch (SettingTreeBehaviour)
                                {
                                case TreeBuildingBehaviour.DependencyTreeBehaviour.RecursiveOnlyOnDirectImports:
                                    if ((NewTreeContext.Flags & ModuleFlag.DelayLoad) == 0)
                                    {
                                        PEProcessingBacklog.Add(new BacklogImport(childTreeNode, NewModule.ModuleName));
                                    }
                                    break;

                                case TreeBuildingBehaviour.DependencyTreeBehaviour.Recursive:
                                    PEProcessingBacklog.Add(new BacklogImport(childTreeNode, NewModule.ModuleName));
                                    break;
                                }
                            }
                        }

                        // add it to the module list
                        this.ModulesList.AddModule(this.ProcessedModulesCache[ModuleKey]);
                    }

                    // Since we uniquely process PE, for thoses who have already been "seen",
                    // we set a dummy entry in order to set the "[+]" icon next to the node.
                    // The dll dependencies are actually resolved on user double-click action
                    // We can't do the resolution in the same time as the tree construction since
                    // it's asynchronous (we would have to wait for all the background to finish and
                    // use another Async worker to resolve).

                    if ((NewTreeContext.PeProperties != null) && (NewTreeContext.PeProperties.GetImports().Count > 0))
                    {
                        ModuleTreeViewItem    DummyEntry   = new ModuleTreeViewItem();
                        DependencyNodeContext DummyContext = new DependencyNodeContext()
                        {
                            ModuleInfo = new WeakReference(new NotFoundModuleInfo("Dummy")),
                            IsDummy    = true
                        };

                        DummyEntry.DataContext = DummyContext;
                        DummyEntry.Header      = "@Dummy : if you see this header, it's a bug.";
                        DummyEntry.IsExpanded  = false;

                        childTreeNode.Items.Add(DummyEntry);
                        childTreeNode.Expanded += ResolveDummyEntries;
                    }

                    // Add to tree view
                    childTreeNodeContext.ModuleInfo = new WeakReference(this.ProcessedModulesCache[ModuleKey]);
                    childTreeNode.DataContext       = childTreeNodeContext;
                    childTreeNode.Header            = childTreeNode.GetTreeNodeHeaderName(Dependencies.Properties.Settings.Default.FullPath);
                    RootNode.Items.Add(childTreeNode);
                }


                // Process next batch of dll imports
                if (SettingTreeBehaviour != TreeBuildingBehaviour.DependencyTreeBehaviour.ChildOnly)
                {
                    foreach (var ImportNode in PEProcessingBacklog)
                    {
                        ConstructDependencyTree(ImportNode.Item1, ImportNode.Item2, RecursionLevel + 1); // warning : recursive call
                    }
                }
            };

            bw.RunWorkerAsync();
        }
Beispiel #8
0
 public DependencyNodeContext(DependencyNodeContext other)
 {
     ModuleInfo = other.ModuleInfo;
     IsDummy    = other.IsDummy;
 }