130 lines
5.2 KiB
C#
130 lines
5.2 KiB
C#
|
// dnlib: See LICENSE.txt for more info
|
||
|
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using dnlib.IO;
|
||
|
|
||
|
namespace dnlib.DotNet {
|
||
|
/// <summary>
|
||
|
/// Reads <c>DeclSecurity</c> blobs
|
||
|
/// </summary>
|
||
|
public struct DeclSecurityReader {
|
||
|
DataReader reader;
|
||
|
readonly ModuleDef module;
|
||
|
readonly GenericParamContext gpContext;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reads a <c>DeclSecurity</c> blob
|
||
|
/// </summary>
|
||
|
/// <param name="module">Module that will own the returned list</param>
|
||
|
/// <param name="sig"><c>#Blob</c> offset of <c>DeclSecurity</c> signature</param>
|
||
|
/// <returns>A list of <see cref="SecurityAttribute"/>s</returns>
|
||
|
public static IList<SecurityAttribute> Read(ModuleDefMD module, uint sig) => Read(module, module.BlobStream.CreateReader(sig), new GenericParamContext());
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reads a <c>DeclSecurity</c> blob
|
||
|
/// </summary>
|
||
|
/// <param name="module">Module that will own the returned list</param>
|
||
|
/// <param name="sig"><c>#Blob</c> offset of <c>DeclSecurity</c> signature</param>
|
||
|
/// <param name="gpContext">Generic parameter context</param>
|
||
|
/// <returns>A list of <see cref="SecurityAttribute"/>s</returns>
|
||
|
public static IList<SecurityAttribute> Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) => Read(module, module.BlobStream.CreateReader(sig), gpContext);
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reads a <c>DeclSecurity</c> blob
|
||
|
/// </summary>
|
||
|
/// <param name="module">Module that will own the returned list</param>
|
||
|
/// <param name="blob"><c>DeclSecurity</c> blob</param>
|
||
|
/// <returns>A list of <see cref="SecurityAttribute"/>s</returns>
|
||
|
public static IList<SecurityAttribute> Read(ModuleDef module, byte[] blob) => Read(module, ByteArrayDataReaderFactory.CreateReader(blob), new GenericParamContext());
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reads a <c>DeclSecurity</c> blob
|
||
|
/// </summary>
|
||
|
/// <param name="module">Module that will own the returned list</param>
|
||
|
/// <param name="blob"><c>DeclSecurity</c> blob</param>
|
||
|
/// <param name="gpContext">Generic parameter context</param>///
|
||
|
/// <returns>A list of <see cref="SecurityAttribute"/>s</returns>
|
||
|
public static IList<SecurityAttribute> Read(ModuleDef module, byte[] blob, GenericParamContext gpContext) => Read(module, ByteArrayDataReaderFactory.CreateReader(blob), gpContext);
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reads a <c>DeclSecurity</c> blob
|
||
|
/// </summary>
|
||
|
/// <param name="module">Module that will own the returned list</param>
|
||
|
/// <param name="signature"><c>DeclSecurity</c> stream that will be owned by us</param>
|
||
|
/// <returns>A list of <see cref="SecurityAttribute"/>s</returns>
|
||
|
public static IList<SecurityAttribute> Read(ModuleDef module, DataReader signature) => Read(module, signature, new GenericParamContext());
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reads a <c>DeclSecurity</c> blob
|
||
|
/// </summary>
|
||
|
/// <param name="module">Module that will own the returned list</param>
|
||
|
/// <param name="signature"><c>DeclSecurity</c> stream that will be owned by us</param>
|
||
|
/// <param name="gpContext">Generic parameter context</param>
|
||
|
/// <returns>A list of <see cref="SecurityAttribute"/>s</returns>
|
||
|
public static IList<SecurityAttribute> 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<SecurityAttribute> Read() {
|
||
|
try {
|
||
|
if (reader.Position >= reader.Length)
|
||
|
return new List<SecurityAttribute>();
|
||
|
|
||
|
if (reader.ReadByte() == '.')
|
||
|
return ReadBinaryFormat();
|
||
|
reader.Position--;
|
||
|
return ReadXmlFormat();
|
||
|
}
|
||
|
catch {
|
||
|
return new List<SecurityAttribute>();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reads the new (.NET Framework 2.0+) DeclSecurity blob format
|
||
|
/// </summary>
|
||
|
/// <returns></returns>
|
||
|
IList<SecurityAttribute> ReadBinaryFormat() {
|
||
|
int numAttrs = (int)reader.ReadCompressedUInt32();
|
||
|
var list = new List<SecurityAttribute>(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;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Reads the old (.NET Framework 1.x) DeclSecurity blob format
|
||
|
/// </summary>
|
||
|
/// <returns></returns>
|
||
|
IList<SecurityAttribute> ReadXmlFormat() {
|
||
|
var xml = reader.ReadUtf16String((int)reader.Length / 2);
|
||
|
var sa = SecurityAttribute.CreateFromXml(module, xml);
|
||
|
return new List<SecurityAttribute> { sa };
|
||
|
}
|
||
|
|
||
|
UTF8String ReadUTF8String() {
|
||
|
uint len = reader.ReadCompressedUInt32();
|
||
|
return len == 0 ? UTF8String.Empty : new UTF8String(reader.ReadBytes((int)len));
|
||
|
}
|
||
|
}
|
||
|
}
|