obfuz/Plugins/dnlib/DotNet/DeclSecurityReader.cs

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));
}
}
}