// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; using dnlib.IO; namespace dnlib.DotNet { /// /// Reads DeclSecurity blobs /// public struct DeclSecurityReader { DataReader reader; readonly ModuleDef module; readonly GenericParamContext gpContext; /// /// Reads a DeclSecurity blob /// /// Module that will own the returned list /// #Blob offset of DeclSecurity signature /// A list of s public static IList Read(ModuleDefMD module, uint sig) => Read(module, module.BlobStream.CreateReader(sig), new GenericParamContext()); /// /// Reads a DeclSecurity blob /// /// Module that will own the returned list /// #Blob offset of DeclSecurity signature /// Generic parameter context /// A list of s public static IList Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) => Read(module, module.BlobStream.CreateReader(sig), gpContext); /// /// Reads a DeclSecurity blob /// /// Module that will own the returned list /// DeclSecurity blob /// A list of s public static IList Read(ModuleDef module, byte[] blob) => Read(module, ByteArrayDataReaderFactory.CreateReader(blob), new GenericParamContext()); /// /// Reads a DeclSecurity blob /// /// Module that will own the returned list /// DeclSecurity blob /// Generic parameter context/// /// A list of s public static IList Read(ModuleDef module, byte[] blob, GenericParamContext gpContext) => Read(module, ByteArrayDataReaderFactory.CreateReader(blob), gpContext); /// /// Reads a DeclSecurity blob /// /// Module that will own the returned list /// DeclSecurity stream that will be owned by us /// A list of s public static IList Read(ModuleDef module, DataReader signature) => Read(module, signature, new GenericParamContext()); /// /// Reads a DeclSecurity blob /// /// Module that will own the returned list /// DeclSecurity stream that will be owned by us /// Generic parameter context /// A list of s public static IList Read(ModuleDef module, DataReader signature, GenericParamContext gpContext) { var reader = new DeclSecurityReader(module, signature, gpContext); return reader.Read(); } DeclSecurityReader(ModuleDef module, DataReader reader, GenericParamContext gpContext) { this.reader = reader; this.module = module; this.gpContext = gpContext; } IList Read() { try { if (reader.Position >= reader.Length) return new List(); if (reader.ReadByte() == '.') return ReadBinaryFormat(); reader.Position--; return ReadXmlFormat(); } catch { return new List(); } } /// /// Reads the new (.NET Framework 2.0+) DeclSecurity blob format /// /// IList ReadBinaryFormat() { int numAttrs = (int)reader.ReadCompressedUInt32(); var list = new List(numAttrs); for (int i = 0; i < numAttrs; i++) { var name = ReadUTF8String(); // Use CA search rules. Some tools don't write the fully qualified name. var attrRef = TypeNameParser.ParseReflection(module, UTF8String.ToSystemStringOrEmpty(name), new CAAssemblyRefFinder(module), gpContext); /*int blobLength = (int)*/reader.ReadCompressedUInt32(); int numNamedArgs = (int)reader.ReadCompressedUInt32(); var namedArgs = CustomAttributeReader.ReadNamedArguments(module, ref reader, numNamedArgs, gpContext); if (namedArgs is null) throw new ApplicationException("Could not read named arguments"); list.Add(new SecurityAttribute(attrRef, namedArgs)); } return list; } /// /// Reads the old (.NET Framework 1.x) DeclSecurity blob format /// /// IList ReadXmlFormat() { var xml = reader.ReadUtf16String((int)reader.Length / 2); var sa = SecurityAttribute.CreateFromXml(module, xml); return new List { sa }; } UTF8String ReadUTF8String() { uint len = reader.ReadCompressedUInt32(); return len == 0 ? UTF8String.Empty : new UTF8String(reader.ReadBytes((int)len)); } } }