static bool TryApplyFrameworkRedirect(IAssembly assembly, Dictionary <string, FrameworkRedirectInfo> frmRedir, out IAssembly redirectedAssembly) { redirectedAssembly = null; if (!Utils.LocaleEquals(assembly.Culture, "")) { return(false); } if (!frmRedir.TryGetValue(assembly.Name, out var redirect)) { return(false); } if (PublicKeyBase.TokenCompareTo(assembly.PublicKeyOrToken, redirect.publicKeyToken) != 0) { return(false); } if (Utils.CompareTo(assembly.Version, redirect.redirectVersion) == 0) { redirectedAssembly = assembly; } else { redirectedAssembly = new AssemblyNameInfo(assembly); redirectedAssembly.Version = redirect.redirectVersion; } return(true); }
/// <summary> /// Redirects a .NET framework assembly from an older version to the correct version /// loaded at runtime. /// </summary> /// <param name="assembly">Current assembly reference that might get updated</param> /// <param name="sourceModule">Module using the assembly reference</param> public static void ApplyFrameworkRedirect(ref IAssembly assembly, ModuleDef sourceModule) { if (sourceModule == null) { return; } if (!Utils.LocaleEquals(assembly.Culture, "")) { return; } if (!sourceModule.IsClr20 && !sourceModule.IsClr40) { return; } FrameworkRedirectInfo redirect; if (!(sourceModule.IsClr20 ? frmRedir2 : frmRedir4).TryGetValue(assembly.Name, out redirect)) { return; } if (PublicKeyBase.TokenCompareTo(assembly.PublicKeyOrToken, redirect.publicKeyToken) != 0) { return; } if (Utils.CompareTo(assembly.Version, redirect.redirectVersion) == 0) { return; } assembly = new AssemblyNameInfo(assembly); assembly.Version = redirect.redirectVersion; }
static void ApplyFrameworkRedirect(ref IAssembly assembly, Dictionary <string, FrameworkRedirectInfo> frmRedir) { if (!Utils.LocaleEquals(assembly.Culture, "")) { return; } if (!frmRedir.TryGetValue(assembly.Name, out var redirect)) { return; } if (PublicKeyBase.TokenCompareTo(assembly.PublicKeyOrToken, redirect.publicKeyToken) != 0) { return; } if (Utils.CompareTo(assembly.Version, redirect.redirectVersion) == 0) { return; } assembly = new AssemblyNameInfo(assembly); assembly.Version = redirect.redirectVersion; }
/// <summary> /// Figures out which of two assembly names is closer to another assembly name /// </summary> /// <param name="requested">Requested assembly name</param> /// <param name="a">First</param> /// <param name="b">Second</param> /// <returns>-1 if both are equally close, 0 if a is closest, 1 if b is closest</returns> public int CompareClosest(AssemblyNameInfo requested, AssemblyNameInfo a, AssemblyNameInfo b) { if (a == b) { return(0); } if (a == null) { return(1); } if (b == null) { return(0); } // Compare the most important parts first: // 1. Assembly simple name // 2. Public key token // 3. Version // 4. Locale if (CompareName) { // If the name only matches one of a or b, return that one. bool na = UTF8String.CaseInsensitiveEquals(requested.Name, a.Name); bool nb = UTF8String.CaseInsensitiveEquals(requested.Name, b.Name); if (na && !nb) { return(0); } if (!na && nb) { return(1); } if (!na && !nb) { return(-1); } } if (ComparePublicKeyToken) { bool pa, pb; if (PublicKeyBase.IsNullOrEmpty2(requested.PublicKeyOrToken)) { // If one of them has a pkt but the other one hasn't, return the one with // no pkt. pa = PublicKeyBase.IsNullOrEmpty2(a.PublicKeyOrToken); pb = PublicKeyBase.IsNullOrEmpty2(b.PublicKeyOrToken); } else { // If one of them has the correct pkt, but the other one has an incorrect // pkt, return the one with the correct pkt. pa = PublicKeyBase.TokenEquals(requested.PublicKeyOrToken, a.PublicKeyOrToken); pb = PublicKeyBase.TokenEquals(requested.PublicKeyOrToken, b.PublicKeyOrToken); } if (pa && !pb) { return(0); } if (!pa && pb) { return(1); } } if (CompareVersion && !Utils.Equals(a.Version, b.Version)) { var rv = Utils.CreateVersionWithNoUndefinedValues(requested.Version); if (rv == new Version(0, 0, 0, 0)) { rv = new Version(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); } int va = Utils.CompareTo(a.Version, rv); int vb = Utils.CompareTo(b.Version, rv); if (va == 0) { return(0); // vb != 0 so return 0 } if (vb == 0) { return(1); // va != 0 so return 1 } if (va > 0 && vb < 0) { return(0); } if (va < 0 && vb > 0) { return(1); } // Now either both a and b's version > req version or both are < req version if (va > 0) { // a.Version and b.Version > req.Version. Pick the one that is closest. return(Utils.CompareTo(a.Version, b.Version) < 0 ? 0 : 1); } else { // a.Version and b.Version < req.Version. Pick the one that is closest. return(Utils.CompareTo(a.Version, b.Version) > 0 ? 0 : 1); } } if (CompareLocale) { bool la = Utils.LocaleEquals(requested.Locale, a.Locale); bool lb = Utils.LocaleEquals(requested.Locale, b.Locale); if (la && !lb) { return(0); } if (!la && lb) { return(1); } } return(-1); }
/// <summary> /// Figures out which of two assembly names is closer to another assembly name /// </summary> /// <param name="requested">Requested assembly name</param> /// <param name="a">First</param> /// <param name="b">Second</param> /// <returns> /// -1 if both are equally close, 0 if <paramref name="a" /> is closest, 1 if /// <paramref name="b" /> is closest /// </returns> public int CompareClosest(IAssembly requested, IAssembly a, IAssembly b) { if (a == b) { return(0); } if (a == null) { return(!CompareName ? 1 : UTF8String.CaseInsensitiveEquals(requested.Name, b.Name) ? 1 : 0); } if (b == null) { return(!CompareName ? 0 : UTF8String.CaseInsensitiveEquals(requested.Name, a.Name) ? 0 : 1); } // Compare the most important parts first: // 1. Assembly simple name // 2. Public key token // 3. Version // 4. Locale // 5. Content type if (CompareName) { // If the name only matches one of a or b, return that one. var na = UTF8String.CaseInsensitiveEquals(requested.Name, a.Name); var nb = UTF8String.CaseInsensitiveEquals(requested.Name, b.Name); if (na && !nb) { return(0); } if (!na && nb) { return(1); } if (!na && !nb) { return(-1); } } if (ComparePublicKeyToken) { bool pa, pb; if (PublicKeyBase.IsNullOrEmpty2(requested.PublicKeyOrToken)) { // If one of them has a pkt but the other one hasn't, return the one with // no pkt. pa = PublicKeyBase.IsNullOrEmpty2(a.PublicKeyOrToken); pb = PublicKeyBase.IsNullOrEmpty2(b.PublicKeyOrToken); } else { // If one of them has the correct pkt, but the other one has an incorrect // pkt, return the one with the correct pkt. pa = PublicKeyBase.TokenEquals(requested.PublicKeyOrToken, a.PublicKeyOrToken); pb = PublicKeyBase.TokenEquals(requested.PublicKeyOrToken, b.PublicKeyOrToken); } if (pa && !pb) { return(0); } if (!pa && pb) { return(1); } } if (CompareVersion && !Utils.Equals(a.Version, b.Version)) { var rv = Utils.CreateVersionWithNoUndefinedValues(requested.Version); if (rv == new Version(0, 0, 0, 0)) { rv = new Version(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); } var va = Utils.CompareTo(a.Version, rv); var vb = Utils.CompareTo(b.Version, rv); if (va == 0) { return(0); // vb != 0 so return 0 } if (vb == 0) { return(1); // va != 0 so return 1 } if (va > 0 && vb < 0) { return(0); } if (va < 0 && vb > 0) { return(1); } // Now either both a and b's version > req version or both are < req version if (va > 0) { return(Utils.CompareTo(a.Version, b.Version) < 0 ? 0 : 1); } return(Utils.CompareTo(a.Version, b.Version) > 0 ? 0 : 1); } if (CompareCulture) { var la = Utils.LocaleEquals(requested.Culture, a.Culture); var lb = Utils.LocaleEquals(requested.Culture, b.Culture); if (la && !lb) { return(0); } if (!la && lb) { return(1); } } if (CompareContentType) { var ca = requested.ContentType == a.ContentType; var cb = requested.ContentType == b.ContentType; if (ca && !cb) { return(0); } if (!ca && cb) { return(1); } } return(-1); }