Пример #1
0
        /// <summary>
        /// Reentrant version of Collapse/Expand Node
        /// </summary>
        /// <param name="Item"></param>
        /// <param name="ExpandNode"></param>
        private ModuleTreeViewItem FindModuleInTree(ModuleTreeViewItem Item, DisplayModuleInfo Module, bool Highlight = false)
        {
            if (Item.GetTreeNodeHeaderName(Dependencies.Properties.Settings.Default.FullPath) == Module.ModuleName)
            {
                if (Highlight)
                {
                    ExpandAllParentNode(Item.Parent as ModuleTreeViewItem);
                    Item.IsSelected = true;
                    Item.BringIntoView();
                    Item.Focus();
                }

                return(Item);
            }

            // BFS style search -> return the first matching node with the lowest "depth"
            foreach (ModuleTreeViewItem ChildItem in Item.Items)
            {
                if (ChildItem.GetTreeNodeHeaderName(Dependencies.Properties.Settings.Default.FullPath) == Module.ModuleName)
                {
                    if (Highlight)
                    {
                        ExpandAllParentNode(Item);
                        ChildItem.IsSelected = true;
                        ChildItem.BringIntoView();
                        ChildItem.Focus();
                    }

                    return(Item);
                }
            }

            foreach (ModuleTreeViewItem ChildItem in Item.Items)
            {
                ModuleTreeViewItem matchingItem = FindModuleInTree(ChildItem, Module, Highlight);

                // early exit as soon as we find a matching node
                if (matchingItem != null)
                {
                    return(matchingItem);
                }
            }

            return(null);
        }
Пример #2
0
        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));

                UpdateImportExportLists(null, null);
                return;
            }

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

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

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

            UpdateImportExportLists(SelectedModule, parentModule);
        }
Пример #3
0
        private void VerifyModuleImports()
        {
            // no parent : it's probably the root item
            ModuleTreeViewItem ParentModule = this.ParentModule;

            if (ParentModule == null)
            {
                ModuleInfo.HasErrors = false;
                return;
            }


            foreach (PeImportDll DllImport in ParentModule.ModuleInfo.Imports)
            {
                if (DllImport.Name != ModuleInfo._Name)
                {
                    continue;
                }



                List <Tuple <PeImport, bool> > resolvedImports = BinaryCache.LookupImports(DllImport, ModuleInfo.Filepath);
                if (resolvedImports.Count == 0)
                {
                    ModuleInfo.HasErrors = true;
                    return;
                }

                foreach (var Import in resolvedImports)
                {
                    if (!Import.Item2)
                    {
                        ModuleInfo.HasErrors = true;
                        return;
                    }
                }
            }

            ModuleInfo.HasErrors = false;
        }
        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);
        }
Пример #5
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);
        }
Пример #6
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();
        }
Пример #7
0
        public ModuleTreeViewItem(ModuleTreeViewItem Other)
        {
            Dependencies.Properties.Settings.Default.PropertyChanged += this.ModuleTreeViewItem_PropertyChanged;

            this.DataContext = new DependencyNodeContext((DependencyNodeContext)Other.DataContext);
        }
Пример #8
0
 public ModuleTreeViewItem(ModuleTreeViewItem Parent)
 {
     _importsVerified = false;
     _Parent          = Parent;
     Dependencies.Properties.Settings.Default.PropertyChanged += this.ModuleTreeViewItem_PropertyChanged;
 }
 private void ConstructDependencyTree(ModuleTreeViewItem RootNode, string FilePath, int RecursionLevel = 0)
 {
     ConstructDependencyTree(RootNode, BinaryCache.LoadPe(FilePath), RecursionLevel);
 }
Пример #10
0
 private void ConstructDependencyTree(ModuleTreeViewItem RootNode, string FilePath, int RecursionLevel = 0)
 {
     ConstructDependencyTree(RootNode, new PE(FilePath), RecursionLevel);
 }