/// <summary> /// Creates a new tables stream based on a segment in a file. /// </summary> /// <param name="name">The name of the stream.</param> /// <param name="contents">The raw contents of the stream.</param> /// <param name="referenceResolver">The instance that resolves references to other segments in the file to segments.</param> public SerializedTableStream(string name, IReadableSegment contents, ISegmentReferenceResolver referenceResolver) { Name = name ?? throw new ArgumentNullException(nameof(name)); _contents = contents ?? throw new ArgumentNullException(nameof(contents)); _referenceResolver = referenceResolver ?? throw new ArgumentNullException(nameof(referenceResolver)); var reader = contents.CreateReader(); Reserved = reader.ReadUInt32(); MajorVersion = reader.ReadByte(); MinorVersion = reader.ReadByte(); Flags = (TablesStreamFlags)reader.ReadByte(); Log2LargestRid = reader.ReadByte(); _validMask = reader.ReadUInt64(); _sortedMask = reader.ReadUInt64(); _rowCounts = ReadRowCounts(reader); if (HasExtraData) { ExtraData = reader.ReadUInt32(); } _headerSize = (uint)(reader.Offset - reader.StartOffset); _indexSizes = InitializeIndexSizes(); }
/// <summary> /// Creates a new fat method body. /// </summary> /// <param name="attributes">The attributes associated to the method body.</param> /// <param name="maxStack">The maximum amount of values that can be pushed onto the stack.</param> /// <param name="localVarSigToken">The metadata token that defines the local variables for the method body.</param> /// <param name="code">The raw code of the method.</param> public CilRawFatMethodBody(CilMethodBodyAttributes attributes, ushort maxStack, MetadataToken localVarSigToken, IReadableSegment code) { Attributes = attributes; MaxStack = maxStack; LocalVarSigToken = localVarSigToken; Code = code ?? throw new ArgumentNullException(nameof(code)); }
/// <summary> /// Creates a new instance of the <see cref="SerializedDotNetResourcesDirectory"/> using an input stream as /// raw contents of the directory. /// </summary> /// <param name="reader">The input stream.</param> public SerializedDotNetResourcesDirectory(IBinaryStreamReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } _contents = DataSegment.FromReader(reader); }
public KoiStream(string name, IReadableSegment contents, ILogger logger) : base(name, contents) { var reader = contents.CreateReader(); logger.Debug(Tag, "Reading koi stream header..."); uint magic = reader.ReadUInt32(); if (magic != Signature) { logger.Warning(Tag, $"Koi stream data does not start with a valid signature (Expected 0x{Signature:X4} but read 0x{magic:X4})."); } uint mdCount = reader.ReadUInt32(); uint strCount = reader.ReadUInt32(); uint expCount = reader.ReadUInt32(); logger.Debug(Tag, $"Reading {mdCount} references..."); for (int i = 0; i < mdCount; i++) { uint id = Utils.ReadCompressedUInt(ref reader); uint token = Utils.FromCodedToken(Utils.ReadCompressedUInt(ref reader)); References.Add(id, new MetadataToken(token)); } logger.Debug(Tag, $"Reading {strCount} strings..."); for (int i = 0; i < strCount; i++) { uint id = Utils.ReadCompressedUInt(ref reader); int length = (int)Utils.ReadCompressedUInt(ref reader); byte[] buffer = new byte[length * 2]; reader.ReadBytes(buffer, 0, buffer.Length); Strings.Add(id, Encoding.Unicode.GetString(buffer)); } logger.Debug(Tag, $"Reading {expCount} exports..."); for (int i = 0; i < expCount; i++) { uint id = Utils.ReadCompressedUInt(ref reader); var exportInfo = VMExportInfo.FromReader(ref reader); // Exports in KoiVM either point to entrypoints of virtualised methods, or just act as a descriptor // for methods that are intra linked through instructions like ldftn. if (exportInfo.IsSignatureOnly) { logger.Debug(Tag, $"Export {id} maps to a method signature of an intra-linked method."); } else { logger.Debug(Tag, $"Export {id} maps to function_{exportInfo.EntrypointAddress:X4}."); } Exports.Add(id, exportInfo); } }
/// <summary> /// Creates a new user-strings stream based on a segment in a file. /// </summary> /// <param name="name">The name of the stream.</param> /// <param name="contents">The raw contents of the stream.</param> public SerializedUserStringsStream(string name, IReadableSegment contents) : base(name) { _contents = contents ?? throw new ArgumentNullException(nameof(contents)); }
/// <summary> /// Creates a new instance of the <see cref="SerializedDotNetResourcesDirectory"/> using a readable data segment /// as raw contents of the directory. /// </summary> /// <param name="contents">The input stream.</param> public SerializedDotNetResourcesDirectory(IReadableSegment contents) { _contents = contents ?? throw new ArgumentNullException(nameof(contents)); }
/// <summary> /// Reads the segment and puts the data in a byte array. /// </summary> /// <param name="segment">The segment to read.</param> /// <returns>The byte array that was read.</returns> public static byte[] ToArray(this IReadableSegment segment) { return(segment.CreateReader().ReadToEnd()); }
/// <summary> /// Creates a new binary reader that reads the raw contents of the segment. /// </summary> /// <returns>The created binary reader.</returns> /// <param name="segment">The segment to read from.</param> /// <param name="fileOffset">The starting file offset of the reader.</param> public static BinaryStreamReader CreateReader(this IReadableSegment segment, ulong fileOffset) { return(segment.CreateReader(fileOffset, (uint)(segment.GetPhysicalSize() - (fileOffset - segment.Offset)))); }
/// <summary> /// Creates a new binary reader that reads the raw contents of the segment. /// </summary> /// <param name="segment">The segment to read from.</param> /// <returns>The created binary reader.</returns> public static BinaryStreamReader CreateReader(this IReadableSegment segment) { return(segment.CreateReader(segment.Offset, segment.GetPhysicalSize())); }