/// <summary> /// Constructor /// </summary> /// <param name="name">Simple name</param> /// <param name="version">Version</param> /// <param name="publicKey">Public key or public key token</param> /// <param name="locale">Locale</param> /// <exception cref="ArgumentNullException">If any of the args is invalid</exception> public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey, UTF8String locale) { if ((object)name == null) throw new ArgumentNullException("name"); if (version == null) throw new ArgumentNullException("version"); if ((object)locale == null) throw new ArgumentNullException("locale"); this.name = name; this.version = version; this.publicKeyOrToken = publicKey; this.locale = locale; this.flags = publicKey is PublicKey ? AssemblyAttributes.PublicKey : AssemblyAttributes.None; }
/// <summary> /// Constructor /// </summary> /// <param name="assembly">Assembly</param> public AssemblyRefUser(IAssembly assembly) { if (assembly == null) throw new ArgumentNullException("asmName"); this.version = assembly.Version ?? new Version(0, 0, 0, 0); this.publicKeyOrToken = assembly.PublicKeyOrToken; this.name = UTF8String.IsNullOrEmpty(assembly.Name) ? UTF8String.Empty : assembly.Name; this.locale = assembly.Culture; this.flags = publicKeyOrToken is PublicKey ? AssemblyAttributes.PublicKey : AssemblyAttributes.None; }
/// <summary> /// Checks whether a public key or token is null or empty /// </summary> /// <param name="a">Public key or token instance</param> public static bool IsNullOrEmpty2(PublicKeyBase a) { return a == null || a.data == null || a.data.Length == 0; }
/// <summary> /// Constructor /// </summary> /// <param name="name">Simple name</param> /// <param name="version">Version</param> /// <param name="publicKey">Public key or public key token</param> /// <exception cref="ArgumentNullException">If any of the args is invalid</exception> public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey) : this(name, version, publicKey, UTF8String.Empty) { }
/// <summary> /// Gets the public key token hash code /// </summary> /// <param name="a">Public key or token</param> /// <returns>The hash code</returns> public static int GetHashCodeToken(PublicKeyBase a) { return GetHashCode(ToPublicKeyToken(a)); }
public bool TryGetSimilarValue(ITypeDefOrRef type, out T value) { List <ITypeDefOrRef> list; if (!refs.TryGetValue(type, out list)) { value = default(T); return(false); } // Find a type whose version is >= type's version and closest to it. ITypeDefOrRef foundType = null; var typeAsmName = type.DefinitionAssembly; IAssembly foundAsmName = null; foreach (var otherRef in list) { if (!dict.TryGetValue(otherRef, out value)) { continue; } if (typeAsmName == null) { foundType = otherRef; break; } var otherAsmName = otherRef.DefinitionAssembly; if (otherAsmName == null) { continue; } // Check pkt or we could return a type in eg. a SL assembly when it's not a SL app. if (!PublicKeyBase.TokenEquals(typeAsmName.PublicKeyOrToken, otherAsmName.PublicKeyOrToken)) { continue; } if (typeAsmName.Version > otherAsmName.Version) { continue; // old version } if (foundType == null) { foundAsmName = otherAsmName; foundType = otherRef; continue; } if (foundAsmName.Version <= otherAsmName.Version) { continue; } foundAsmName = otherAsmName; foundType = otherRef; } if (foundType != null) { value = dict[foundType]; return(true); } value = default(T); return(false); }
/// <summary> /// Constructor /// </summary> /// <param name="module">The module</param> /// <param name="listener">Module writer listener</param> protected ModuleWriterOptionsBase(ModuleDef module, IModuleWriterListener listener) { Listener = listener; ShareMethodBodies = true; MetaDataOptions.MetaDataHeaderOptions.VersionString = module.RuntimeVersion; ModuleKind = module.Kind; PEHeadersOptions.Machine = module.Machine; PEHeadersOptions.Characteristics = module.Characteristics; PEHeadersOptions.DllCharacteristics = module.DllCharacteristics; if (module.Kind == ModuleKind.Windows) { PEHeadersOptions.Subsystem = Subsystem.WindowsGui; } else { PEHeadersOptions.Subsystem = Subsystem.WindowsCui; } PEHeadersOptions.NumberOfRvaAndSizes = 0x10; Cor20HeaderOptions.Flags = module.Cor20HeaderFlags; if (module.Assembly != null && !PublicKeyBase.IsNullOrEmpty2(module.Assembly.PublicKey)) { Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; } if (module.Cor20HeaderRuntimeVersion != null) { Cor20HeaderOptions.MajorRuntimeVersion = (ushort)(module.Cor20HeaderRuntimeVersion.Value >> 16); Cor20HeaderOptions.MinorRuntimeVersion = (ushort)module.Cor20HeaderRuntimeVersion.Value; } else if (module.IsClr1x) { Cor20HeaderOptions.MajorRuntimeVersion = 2; Cor20HeaderOptions.MinorRuntimeVersion = 0; } else { Cor20HeaderOptions.MajorRuntimeVersion = 2; Cor20HeaderOptions.MinorRuntimeVersion = 5; } if (module.TablesHeaderVersion != null) { MetaDataOptions.TablesHeapOptions.MajorVersion = (byte)(module.TablesHeaderVersion.Value >> 8); MetaDataOptions.TablesHeapOptions.MinorVersion = (byte)module.TablesHeaderVersion.Value; } else if (module.IsClr1x) { // Generics aren't supported MetaDataOptions.TablesHeapOptions.MajorVersion = 1; MetaDataOptions.TablesHeapOptions.MinorVersion = 0; } else { // Generics are supported MetaDataOptions.TablesHeapOptions.MajorVersion = 2; MetaDataOptions.TablesHeapOptions.MinorVersion = 0; } // Some tools crash if #GUID is missing so always create it by default MetaDataOptions.Flags |= MetaDataFlags.AlwaysCreateGuidHeap; var modDefMD = module as ModuleDefMD; if (modDefMD != null) { var ntHeaders = modDefMD.MetaData.PEImage.ImageNTHeaders; PEHeadersOptions.TimeDateStamp = ntHeaders.FileHeader.TimeDateStamp; PEHeadersOptions.MajorLinkerVersion = ntHeaders.OptionalHeader.MajorLinkerVersion; PEHeadersOptions.MinorLinkerVersion = ntHeaders.OptionalHeader.MinorLinkerVersion; PEHeadersOptions.ImageBase = ntHeaders.OptionalHeader.ImageBase; AddCheckSum = ntHeaders.OptionalHeader.CheckSum != 0; } if (Is64Bit) { PEHeadersOptions.Characteristics &= ~Characteristics._32BitMachine; PEHeadersOptions.Characteristics |= Characteristics.LargeAddressAware; } else { PEHeadersOptions.Characteristics |= Characteristics._32BitMachine; } }
/// <summary> /// Compares two <see cref="PublicKeyBase"/>s as <see cref="PublicKeyToken"/>s /// </summary> /// <param name="a">First</param> /// <param name="b">Second</param> /// <returns>< 0 if a < b, 0 if a == b, > 0 if a > b</returns> public static int TokenCompareTo(PublicKeyBase a, PublicKeyBase b) { if (a == b) return 0; return TokenCompareTo(ToPublicKeyToken(a), ToPublicKeyToken(b)); }
public AssemblyRefInfo(AssemblyRef asmRef) { this.AssemblyRef = asmRef; this.OrigName = asmRef.Name; this.OrigPublicKeyOrToken = asmRef.PublicKeyOrToken; }
static IEnumerable <GacFileInfo> GetAssemblies(GacDirInfo gacInfo) { foreach (var subDir in gacInfo.SubDirs) { var baseDir = Path.Combine(gacInfo.Path, subDir); foreach (var dir in GetDirectories(baseDir)) { foreach (var dir2 in GetDirectories(dir)) { Version version; string culture; PublicKeyToken pkt; if (gacInfo.Version == 2) { var m = gac2Regex.Match(Path.GetFileName(dir2)); if (!m.Success || m.Groups.Count != 4) { continue; } if (!Version.TryParse(m.Groups[1].Value, out version)) { continue; } culture = m.Groups[2].Value; pkt = new PublicKeyToken(m.Groups[3].Value); if (PublicKeyBase.IsNullOrEmpty2(pkt)) { continue; } } else if (gacInfo.Version == 4) { var m = gac4Regex.Match(Path.GetFileName(dir2)); if (!m.Success || m.Groups.Count != 4) { continue; } if (!Version.TryParse(m.Groups[1].Value, out version)) { continue; } culture = m.Groups[2].Value; pkt = new PublicKeyToken(m.Groups[3].Value); if (PublicKeyBase.IsNullOrEmpty2(pkt)) { continue; } } else { throw new InvalidOperationException(); } var asmName = Path.GetFileName(dir); var file = Path.Combine(dir2, asmName) + ".dll"; if (!File.Exists(file)) { file = Path.Combine(dir2, asmName) + ".exe"; if (!File.Exists(file)) { continue; } } var asmInfo = new AssemblyNameInfo { Name = asmName, Version = version, Culture = culture, PublicKeyOrToken = pkt, }; yield return(new GacFileInfo(asmInfo, file)); } } } }
protected override void Write(ITextOutput output, Language language) { if (!assembly.IsLoaded) { output.Write(UIUtils.CleanUpName(assembly.ShortName), TextTokenType.Assembly); } else if (assembly.ModuleDefinition == null) { var pe = assembly.PEImage; if (pe != null) { bool isExe = (pe.ImageNTHeaders.FileHeader.Characteristics & Characteristics.Dll) == 0; output.Write(UIUtils.CleanUpName(assembly.ShortName), isExe ? TextTokenType.AssemblyExe : TextTokenType.Assembly); } else { output.Write(UIUtils.CleanUpName(assembly.ShortName), TextTokenType.Text); } } else if (Parent is AssemblyTreeNode || assembly.AssemblyDefinition == null) { output.Write(UIUtils.CleanUpName(assembly.ModuleDefinition.Name), TextTokenType.Module); } else { var asm = assembly.AssemblyDefinition; bool isExe = (assembly.ModuleDefinition.Characteristics & Characteristics.Dll) == 0; output.Write(asm.Name, isExe ? TextTokenType.AssemblyExe : TextTokenType.Assembly); bool showAsmVer = DisplaySettingsPanel.CurrentDisplaySettings.ShowAssemblyVersion; bool showPublicKeyToken = DisplaySettingsPanel.CurrentDisplaySettings.ShowAssemblyPublicKeyToken && !PublicKeyBase.IsNullOrEmpty2(asm.PublicKeyToken); if (showAsmVer || showPublicKeyToken) { output.WriteSpace(); output.Write('(', TextTokenType.Operator); bool needComma = false; if (showAsmVer) { if (needComma) { output.Write(',', TextTokenType.Operator); output.WriteSpace(); } needComma = true; output.Write(asm.Version.Major.ToString(), TextTokenType.Number); output.Write('.', TextTokenType.Operator); output.Write(asm.Version.Minor.ToString(), TextTokenType.Number); output.Write('.', TextTokenType.Operator); output.Write(asm.Version.Build.ToString(), TextTokenType.Number); output.Write('.', TextTokenType.Operator); output.Write(asm.Version.Revision.ToString(), TextTokenType.Number); } if (showPublicKeyToken) { if (needComma) { output.Write(',', TextTokenType.Operator); output.WriteSpace(); } needComma = true; var pkt = asm.PublicKeyToken; if (PublicKeyBase.IsNullOrEmpty2(pkt)) { output.Write("null", TextTokenType.Keyword); } else { output.Write(pkt.ToString(), TextTokenType.Number); } } output.Write(')', TextTokenType.Operator); } } }
static void Write(ITextOutput output, IAssembly asm) { var asmDef = asm as AssemblyDef; bool isExe = asmDef != null && asmDef.ManifestModule != null && (asmDef.ManifestModule.Characteristics & dnlib.PE.Characteristics.Dll) == 0; output.Write(asm.Name, isExe ? TextTokenType.AssemblyExe : TextTokenType.Assembly); output.Write(',', TextTokenType.Operator); output.WriteSpace(); output.Write("Version", TextTokenType.InstanceProperty); output.Write('=', TextTokenType.Operator); output.Write(asm.Version.Major.ToString(), TextTokenType.Number); output.Write('.', TextTokenType.Operator); output.Write(asm.Version.Minor.ToString(), TextTokenType.Number); output.Write('.', TextTokenType.Operator); output.Write(asm.Version.Build.ToString(), TextTokenType.Number); output.Write('.', TextTokenType.Operator); output.Write(asm.Version.Revision.ToString(), TextTokenType.Number); output.Write(',', TextTokenType.Operator); output.WriteSpace(); output.Write("Culture", TextTokenType.InstanceProperty); output.Write('=', TextTokenType.Operator); output.Write(UTF8String.IsNullOrEmpty(asm.Culture) ? "neutral" : asm.Culture.String, TextTokenType.EnumField); output.Write(',', TextTokenType.Operator); output.WriteSpace(); var publicKey = PublicKeyBase.ToPublicKeyToken(asm.PublicKeyOrToken); output.Write(publicKey == null || publicKey is PublicKeyToken ? "PublicKeyToken" : "PublicKey", TextTokenType.InstanceProperty); output.Write('=', TextTokenType.Operator); if (PublicKeyBase.IsNullOrEmpty2(publicKey)) { output.Write("null", TextTokenType.Keyword); } else { output.Write(publicKey.ToString(), TextTokenType.Number); } if ((asm.Attributes & AssemblyAttributes.Retargetable) != 0) { output.Write(',', TextTokenType.Operator); output.WriteSpace(); output.Write("Retargetable", TextTokenType.InstanceProperty); output.Write('=', TextTokenType.Operator); output.Write("Yes", TextTokenType.EnumField); } if ((asm.Attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime) { output.Write(',', TextTokenType.Operator); output.WriteSpace(); output.Write("ContentType", TextTokenType.InstanceProperty); output.Write('=', TextTokenType.Operator); output.Write("WindowsRuntime", TextTokenType.EnumField); } }
void OnWriterEvent(object sender, ModuleWriterListenerEventArgs e) { var writer = (ModuleWriterBase)sender; if (e.WriterEvent == ModuleWriterEvent.MDBeginAddResources) { ctx.Context.CheckCancellation(); ctx.Context.Logger.Debug("Encrypting resources..."); bool hasPacker = ctx.Context.Packer != null; List <EmbeddedResource> resources = ctx.Module.Resources.OfType <EmbeddedResource>().ToList(); if (!hasPacker) { ctx.Module.Resources.RemoveWhere(res => res is EmbeddedResource); } // move resources string asmName = ctx.Name.RandomName(RenameMode.Letters); PublicKey pubKey = null; if (writer.TheOptions.StrongNameKey != null) { pubKey = PublicKeyBase.CreatePublicKey(writer.TheOptions.StrongNameKey.PublicKey); } var assembly = new AssemblyDefUser(asmName, new Version(0, 0), pubKey); assembly.Modules.Add(new ModuleDefUser(asmName + ".dll")); ModuleDef module = assembly.ManifestModule; assembly.ManifestModule.Kind = ModuleKind.Dll; var asmRef = new AssemblyRefUser(module.Assembly); if (!hasPacker) { foreach (EmbeddedResource res in resources) { res.Attributes = ManifestResourceAttributes.Public; module.Resources.Add(res); ctx.Module.Resources.Add(new AssemblyLinkedResource(res.Name, asmRef, res.Attributes)); } } byte[] moduleBuff; using (var ms = new MemoryStream()) { module.Write(ms, new ModuleWriterOptions { StrongNameKey = writer.TheOptions.StrongNameKey }); moduleBuff = ms.ToArray(); } // compress moduleBuff = ctx.Context.Registry.GetService <ICompressionService>().Compress( moduleBuff, progress => ctx.Context.Logger.Progress((int)(progress * 10000), 10000)); ctx.Context.Logger.EndProgress(); ctx.Context.CheckCancellation(); uint compressedLen = (uint)(moduleBuff.Length + 3) / 4; compressedLen = (compressedLen + 0xfu) & ~0xfu; var compressedBuff = new uint[compressedLen]; Buffer.BlockCopy(moduleBuff, 0, compressedBuff, 0, moduleBuff.Length); Debug.Assert(compressedLen % 0x10 == 0); // encrypt uint keySeed = ctx.Random.NextUInt32() | 0x10; var key = new uint[0x10]; uint state = keySeed; for (int i = 0; i < 0x10; i++) { state ^= state >> 13; state ^= state << 25; state ^= state >> 27; key[i] = state; } var encryptedBuffer = new byte[compressedBuff.Length * 4]; int buffIndex = 0; while (buffIndex < compressedBuff.Length) { uint[] enc = ctx.ModeHandler.Encrypt(compressedBuff, buffIndex, key); for (int j = 0; j < 0x10; j++) { key[j] ^= compressedBuff[buffIndex + j]; } Buffer.BlockCopy(enc, 0, encryptedBuffer, buffIndex * 4, 0x40); buffIndex += 0x10; } Debug.Assert(buffIndex == compressedBuff.Length); var size = (uint)encryptedBuffer.Length; TablesHeap tblHeap = writer.MetaData.TablesHeap; tblHeap.ClassLayoutTable[writer.MetaData.GetClassLayoutRid(ctx.DataType)].ClassSize = size; tblHeap.FieldTable[writer.MetaData.GetRid(ctx.DataField)].Flags |= (ushort)FieldAttributes.HasFieldRVA; encryptedResource = writer.Constants.Add(new ByteArrayChunk(encryptedBuffer), 8); // inject key values MutationHelper.InjectKeys(ctx.InitMethod, new[] { 0, 1 }, new[] { (int)(size / 4), (int)(keySeed) }); } else if (e.WriterEvent == ModuleWriterEvent.EndCalculateRvasAndFileOffsets) { TablesHeap tblHeap = writer.MetaData.TablesHeap; tblHeap.FieldRVATable[writer.MetaData.GetFieldRVARid(ctx.DataField)].RVA = (uint)encryptedResource.RVA; } }
/// <summary> /// Checks whether a public key or token is null or empty /// </summary> /// <param name="a">Public key or token instance</param> public static bool IsNullOrEmpty2(PublicKeyBase a) { return a == null || a.IsNullOrEmpty; }
/// <summary> /// Checks whether two public key tokens are equal /// </summary> /// <param name="a">First</param> /// <param name="b">Second</param> /// <returns><c>true</c> if same, <c>false</c> otherwise</returns> public static bool TokenEquals(PublicKeyBase a, PublicKeyBase b) { return(TokenCompareTo(a, b) == 0); }
/// <summary> /// Returns a <see cref="PublicKeyToken"/> /// </summary> /// <param name="pkb">A <see cref="PublicKey"/> or a <see cref="PublicKeyToken"/> instance</param> public static PublicKeyToken ToPublicKeyToken(PublicKeyBase pkb) { var pkt = pkb as PublicKeyToken; if (pkt != null) return pkt; var pk = pkb as PublicKey; if (pk != null) return pk.Token; return null; }
/// <summary> /// Gets the public key token hash code /// </summary> /// <param name="a">Public key or token</param> /// <returns>The hash code</returns> public static int GetHashCodeToken(PublicKeyBase a) { return(GetHashCode(ToPublicKeyToken(a))); }
/// <summary> /// Checks whether two public key tokens are equal /// </summary> /// <param name="a">First</param> /// <param name="b">Second</param> /// <returns><c>true</c> if same, <c>false</c> otherwise</returns> public static bool TokenEquals(PublicKeyBase a, PublicKeyBase b) { return TokenCompareTo(a, b) == 0; }
/// <summary> /// Checks whether a public key or token is null or empty /// </summary> /// <param name="a">Public key or token instance</param> public static bool IsNullOrEmpty2(PublicKeyBase a) { return(a == null || a.IsNullOrEmpty); }
/// <summary> /// Gets the raw public key / public key token byte array /// </summary> /// <param name="pkb">The instance or <c>null</c></param> /// <returns>Raw public key / public key token data or <c>null</c></returns> public static byte[] GetRawData(PublicKeyBase pkb) { if (pkb == null) return null; return pkb.Data; }
public AssemblyRefInfo(AssemblyRef asmRef) { AssemblyRef = asmRef; OrigName = asmRef.Name; OrigPublicKeyOrToken = asmRef.PublicKeyOrToken; }