Ejemplo n.º 1
0
        /// <summary>
        /// Recupera os redirecionamentos das versões.
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static Dictionary <string, List <Redirection> > GetVersionRedirections(string fileName)
        {
            var ret    = new Dictionary <string, List <Redirection> >();
            var config = new System.Xml.XmlDocument();

            config.Load(fileName);
            foreach (System.Xml.XmlNode dependentAssemblyTag in config.GetElementsByTagName("dependentAssembly"))
            {
                if (((dependentAssemblyTag.ParentNode.Name == "assemblyBinding") && (dependentAssemblyTag.ParentNode.ParentNode != null)) && (dependentAssemblyTag.ParentNode.ParentNode.Name == "runtime"))
                {
                    Redirection red = new Redirection();
                    foreach (System.Xml.XmlNode node in dependentAssemblyTag.ChildNodes)
                    {
                        if (node.Name == "assemblyIdentity")
                        {
                            var name = new System.Reflection.AssemblyName(node.Attributes["name"].Value);
                            if (node.Attributes["processorArchitecture"] != null)
                            {
                                name.ProcessorArchitecture = (System.Reflection.ProcessorArchitecture)Enum.Parse(typeof(System.Reflection.ProcessorArchitecture), node.Attributes["processorArchitecture"].Value, true);
                            }
                            red.AssemblyIdentity = name;
                            continue;
                        }
                        if (node.Name == "bindingRedirect")
                        {
                            BindingRedirect redirect = new BindingRedirect();
                            if (node.Attributes["oldVersion"] != null)
                            {
                                System.Xml.XmlAttribute attr = node.Attributes["oldVersion"];
                                if (attr.Value.Contains("-"))
                                {
                                    string[] versions = attr.Value.Split(new char[] {
                                        '-'
                                    });
                                    redirect.OldVersionMin = new Version(versions[0]);
                                    redirect.OldVersionMax = new Version(versions[1]);
                                }
                                else
                                {
                                    redirect.OldVersionMax = new Version(attr.Value);
                                    redirect.OldVersionMin = new Version(attr.Value);
                                }
                            }
                            if (node.Attributes["newVersion"] != null)
                            {
                                redirect.NewVersion = new Version(node.Attributes["newVersion"].Value);
                            }
                            red.BindingRedirection = redirect;
                        }
                    }
                    if (ret.ContainsKey(red.AssemblyIdentity.Name))
                    {
                        ret[red.AssemblyIdentity.Name].Add(red);
                    }
                    else
                    {
                        var aux = new List <Redirection>();
                        aux.Add(red);
                        ret.Add(red.AssemblyIdentity.Name, aux);
                    }
                }
            }
            if (ret.Count > 0)
            {
                return(ret);
            }
            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Analiza o assembly informado.
        /// </summary>
        /// <param name="asmName"></param>
        /// <param name="parent"></param>
        /// <param name="domain"></param>
        /// <param name="throwWhenMissing"></param>
        private void AnalyzeAssembly(System.Reflection.AssemblyName asmName, AsmData parent, AppDomain domain, bool throwWhenMissing)
        {
            bool   redirectionApplied = false;
            string additionalInfo     = string.Empty;

            System.Reflection.AssemblyName           analyzedAssembly = asmName;
            Dictionary <string, List <Redirection> > asmRedirections  = this.GetRedirections(asmName);

            if (asmRedirections != null)
            {
                analyzedAssembly   = Redirection.GetCorrectAssemblyName(asmName, asmRedirections);
                redirectionApplied = analyzedAssembly.Version != asmName.Version;
            }
            bool    invalid         = false;
            bool    isInGac         = false;
            AsmData gacAssemblyData = null;

            System.Reflection.Assembly asm = null;
            string file = analyzedAssembly.FullName;

            try
            {
                if (_gac != null)
                {
                    foreach (AsmData item in _gac)
                    {
                        if (item.AssemblyFullName.Contains(analyzedAssembly.FullName))
                        {
                            isInGac         = true;
                            gacAssemblyData = item;
                            break;
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
            if (_cache.ContainsKey(analyzedAssembly.FullName) && !_parentsStack.Contains(analyzedAssembly.FullName))
            {
                AsmData cachedItem = _cache[analyzedAssembly.FullName];
                parent.References.Add(cachedItem);
                return;
            }
            string  asmLocation    = null;
            AsmData currentAsmData = null;
            bool    gacAssemblySet = false;

            if (!isInGac)
            {
                string extAdd = "";
                if (file.LastIndexOf(", Version=") != -1)
                {
                    file = file.Substring(0, file.LastIndexOf(", Version="));
                }
                if ((System.IO.Path.GetExtension(file) != ".exe") && (System.IO.Path.GetExtension(file) != ".dll"))
                {
                    extAdd = ".dll";
                }
                string tmpPath = this.FindPath(parent, file, extAdd, analyzedAssembly.FullName);
                if (System.IO.File.Exists(tmpPath))
                {
                    TryLoad(domain, ref additionalInfo, ref invalid, ref asm, tmpPath);
                }
                asmLocation = tmpPath;
            }
            else
            {
                try
                {
                    using (var stream = System.IO.File.OpenRead(gacAssemblyData.Path))
                    {
                        var raw = new byte[stream.Length];
                        stream.Read(raw, 0, raw.Length);
                        asm = domain.Load(raw);
                    }
                    asmLocation = gacAssemblyData.Path;
                    if (!gacAssemblyData.AssemblyFullName.Contains(asm.FullName) && !asm.FullName.Contains(gacAssemblyData.AssemblyFullName))
                    {
                        currentAsmData = gacAssemblyData;
                        gacAssemblySet = true;
                        asm            = null;
                    }
                }
                catch (System.IO.FileNotFoundException ex)
                {
                    additionalInfo = "File " + ex.FileName + " could not be found.";
                }
                catch (System.IO.FileLoadException ex)
                {
                    additionalInfo = "File " + ex.FileName + " could not be loaded. " + ex.FusionLog;
                }
                catch (BadImageFormatException ex)
                {
                    additionalInfo = "Bad image format. " + ex.ToString() + "\r\n" + ex.FusionLog;
                }
            }
            if (currentAsmData == null)
            {
                currentAsmData = new AsmData(analyzedAssembly.Name, (asm == null) ? "" : System.IO.Path.GetFullPath(asmLocation));
                currentAsmData.AssemblyFullName       = analyzedAssembly.FullName;
                currentAsmData.Validity               = AsmData.AsmValidity.Invalid;
                currentAsmData.InvalidAssemblyDetails = additionalInfo;
                currentAsmData.Architecture           = this.GetArchitecture(currentAsmData.Path);
            }
            if ((!gacAssemblySet && (asm != null)) && (analyzedAssembly.Version != asm.GetName().Version))
            {
                string message = string.Concat(new object[] {
                    "Assembly was found with version ",
                    asm.GetName().Version,
                    " but parent references ",
                    analyzedAssembly.Version
                });
                currentAsmData.AdditionalInfo = message;
                asm = null;
            }
            if ((!gacAssemblySet && (asm != null)) && !invalid)
            {
                try
                {
                    object[] attributes = asm.GetCustomAttributes(typeof(System.Reflection.AssemblyProductAttribute), false);
                    if (attributes.Length > 0)
                    {
                        currentAsmData.AssemblyProductName = ((System.Reflection.AssemblyProductAttribute)attributes[0]).Product;
                    }
                }
                catch (InvalidOperationException)
                {
                    currentAsmData.AssemblyProductName = "Product name could not be read.";
                }
                catch (System.IO.FileNotFoundException)
                {
                    currentAsmData.AssemblyProductName = "Product name could not be read. Assembly was loaded but later could not be found.";
                }
                catch (Exception ex)
                {
                    currentAsmData.AssemblyProductName = "Product name could not be read. Error: " + ex.Message;
                }
            }
            parent.References.Add(currentAsmData);
            if (invalid)
            {
                currentAsmData.Validity = AsmData.AsmValidity.ReferencesOnly;
            }
            if (_parentsStack.Contains(analyzedAssembly.FullName))
            {
                string circ = this.GetParentsString();
                currentAsmData.Validity = AsmData.AsmValidity.CircularDependency;
                if (!_circularDependencyWarningShown)
                {
                    _circularDependencyWarningShown = true;
                }
                return;
            }
            if (asm != null)
            {
                currentAsmData.Path             = asmLocation;
                currentAsmData.AssemblyFullName = asm.FullName;
                if (!invalid)
                {
                    currentAsmData.Validity        = redirectionApplied ? AsmData.AsmValidity.Redirected : AsmData.AsmValidity.Valid;
                    currentAsmData.OriginalVersion = redirectionApplied ? asmName.Version.ToString() : string.Empty;
                }
                if (((asm.CodeBase != null) && System.Runtime.InteropServices.RuntimeEnvironment.FromGlobalAccessCache(asm)) && (currentAsmData.AssemblyProductName == "Microsoft\x00ae .NET Framework"))
                {
                    return;
                }
                if ((currentAsmData.Validity != AsmData.AsmValidity.Invalid) && !this.ApplyArchitecture(currentAsmData.Architecture))
                {
                    currentAsmData.Validity       = AsmData.AsmValidity.ReferencesOnly;
                    currentAsmData.AdditionalInfo = currentAsmData.AdditionalInfo + "\r\nProcessorArchitecture mismatch";
                }
                _parentsStack.Push(currentAsmData.AssemblyFullName);
                _cache.Add(analyzedAssembly.FullName, currentAsmData);
                foreach (System.Reflection.AssemblyName n in asm.GetReferencedAssemblies())
                {
                    this.AnalyzeAssembly(n, currentAsmData, domain, throwWhenMissing);
                }
                _parentsStack.Pop();
                if (!System.IO.File.Exists(currentAsmData.Path))
                {
                    return;
                }
            }
            if (throwWhenMissing && !gacAssemblySet)
            {
                throw new Exception("returning from analysis");
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Analiza o assembly informado.
        /// </summary>
        /// <param name="assemblyName"></param>
        /// <param name="throwWhenMissing"></param>
        /// <returns></returns>
        public AsmData AnalyzeRootAssembly(string assemblyName, bool throwWhenMissing)
        {
            _cache = new Dictionary <string, AsmData>();
            _circularDependencyWarningShown = false;
            _parentsStack = new Stack <string>();
            _workingDir   = Environment.CurrentDirectory;
            string  fullPath = System.IO.Path.GetFullPath(assemblyName);
            AsmData ret      = new AsmData(assemblyName, fullPath);
            var     domain   = AppDomain.CurrentDomain;

            try
            {
                if (!System.IO.File.Exists(assemblyName))
                {
                    ret.Path             = "";
                    ret.Validity         = AsmData.AsmValidity.Invalid;
                    ret.AssemblyFullName = "";
                    return(ret);
                }
                System.Reflection.Assembly asm = null;
                try
                {
                    using (var stream = System.IO.File.OpenRead(fullPath))
                    {
                        var raw = new byte[stream.Length];
                        stream.Read(raw, 0, raw.Length);
                        try
                        {
                            asm          = domain.Load(raw);
                            ret.Validity = AsmData.AsmValidity.Valid;
                        }
                        catch (Exception)
                        {
                            asm          = System.Reflection.Assembly.ReflectionOnlyLoad(raw);
                            ret.Validity = AsmData.AsmValidity.ReferencesOnly;
                        }
                    }
                }
                catch (Exception)
                {
                    asm          = null;
                    ret.Validity = AsmData.AsmValidity.Invalid;
                }
                if (asm != null)
                {
                    ret.AssemblyFullName       = asm.FullName;
                    ret.Path                   = fullPath;
                    ret.Architecture           = asm.GetName().ProcessorArchitecture;
                    _currentLoadedArchitecture = ret.Architecture;
                    string tempName = asm.GetName().Name;
                    if (!this.assemblyNameToPathMap.ContainsKey(tempName))
                    {
                        this.assemblyNameToPathMap.Add(tempName, asm.Location);
                    }
                    string cfgFilePath = Redirection.FindConfigFile(ret.Path);
                    if (!string.IsNullOrEmpty(cfgFilePath) && !_allVersionRedirections.ContainsKey(fullPath))
                    {
                        var             versionRedirections = Redirection.GetVersionRedirections(cfgFilePath);
                        PathRedirection pathRedirections    = Redirection.GetPathRedirections(ret.AssemblyFullName, cfgFilePath);
                        _allVersionRedirections.Add(fullPath, versionRedirections);
                        _probingPaths.Add(ret.AssemblyFullName, pathRedirections);
                    }
                    var references = asm.GetReferencedAssemblies().ToList();
                    var fileName   = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(fullPath), string.Format("{0}.XmlSerializers{1}", System.IO.Path.GetFileNameWithoutExtension(fullPath), System.IO.Path.GetExtension(fullPath)));
                    if (System.IO.File.Exists(fileName))
                    {
                        references.Add(System.Reflection.AssemblyName.GetAssemblyName(fileName));
                    }
                    _totalReferencedAssemblies = references.Count;
                    _parentsStack.Push(ret.AssemblyFullName);
                    foreach (System.Reflection.AssemblyName asmName in references)
                    {
                        this.AnalyzeAssembly(asmName, ret, domain, throwWhenMissing);
                        _assembliesFinished++;
                        if (_bgWorker != null)
                        {
                            _bgWorker.ReportProgress((100 * _assembliesFinished) / _totalReferencedAssemblies);
                        }
                    }
                    _parentsStack.Pop();
                }
            }
            finally
            {
            }
            return(ret);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Recupera os redirecionamentos do Framework.
        /// </summary>
        /// <param name="assembliesInGac"></param>
        /// <param name="progressDialog"></param>
        /// <returns></returns>
        public Dictionary <string, List <Redirection> > GetFrameworkRedirections(List <AsmData> assembliesInGac, IAssemblyAnalyzerObserver progressDialog)
        {
            Dictionary <string, List <Redirection> > redirections = new Dictionary <string, List <Redirection> >();

            try
            {
                progressDialog.ReportProgress(0, "Checking .NET Framework libraries...".GetFormatter());
                int assembliesCount = 0;
                var upgrades        = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework\Policy\Upgrades");
                if (upgrades == null)
                {
                    return(redirections);
                }
                var bindingRedirects = new List <BindingRedirect>();
                foreach (string targetVersion in upgrades.GetValueNames())
                {
                    string          sourceVersion = upgrades.GetValue(targetVersion) as string;
                    BindingRedirect redirect      = new BindingRedirect();
                    redirect.NewVersion = new Version(targetVersion);
                    if (sourceVersion.Contains("-"))
                    {
                        string[] versions = sourceVersion.Split(new char[] {
                            '-'
                        });
                        redirect.OldVersionMin = new Version(versions[0]);
                        redirect.OldVersionMax = new Version(versions[1]);
                    }
                    else
                    {
                        redirect.OldVersionMax = new Version(sourceVersion);
                        redirect.OldVersionMin = new Version(sourceVersion);
                    }
                    bindingRedirects.Add(redirect);
                }
                upgrades.Close();
                foreach (AsmData assemblyDescription in assembliesInGac)
                {
                    System.Reflection.Assembly asm = null;
                    try
                    {
                        asm = System.Reflection.Assembly.Load(assemblyDescription.Name);
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                    var assemblyName = asm.GetName(false);
                    if (!redirections.ContainsKey(assemblyName.Name))
                    {
                        object[] attributes = null;
                        try
                        {
                            attributes = asm.GetCustomAttributes(typeof(System.Reflection.AssemblyProductAttribute), false);
                        }
                        catch (Exception)
                        {
                        }
                        if ((attributes != null) && (attributes.Length > 0))
                        {
                            var productAttribute = attributes[0] as System.Reflection.AssemblyProductAttribute;
                            if ((productAttribute != null) && (productAttribute.Product == "Microsoft\x00ae .NET Framework"))
                            {
                                foreach (BindingRedirect bindingRedirect in bindingRedirects)
                                {
                                    Redirection redirection = new Redirection();
                                    redirection.AssemblyIdentity   = assemblyName;
                                    redirection.BindingRedirection = bindingRedirect;
                                    if (assemblyName.Version <= redirection.BindingRedirection.NewVersion)
                                    {
                                        redirection.BindingRedirection.NewVersion = assemblyName.Version;
                                    }
                                    if (redirections.ContainsKey(redirection.AssemblyIdentity.Name))
                                    {
                                        redirections[redirection.AssemblyIdentity.Name].Add(redirection);
                                    }
                                    else
                                    {
                                        var aux = new List <Redirection>();
                                        aux.Add(redirection);
                                        redirections.Add(redirection.AssemblyIdentity.Name, aux);
                                    }
                                }
                            }
                        }
                        assembliesCount++;
                        progressDialog.ReportProgress((int)((100.0 * assembliesCount) / ((double)assembliesInGac.Count)), "Checking .NET Framework libraries...".GetFormatter());
                        if (progressDialog.CancellationPending)
                        {
                            redirections.Clear();
                            return(redirections);
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
            return(redirections);
        }