/// <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);
 }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
 /// <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));
 }
Beispiel #7
0
 /// <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());
 }
Beispiel #8
0
 /// <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))));
 }
Beispiel #9
0
 /// <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()));
 }