/// <inheritdoc/> protected override void WriteSingleItem( TinyBinaryWriter writer, MethodDefinition item) { WriteStringReference(writer, item.Name); writer.WriteUInt16(_context.ByteCodeTable.GetMethodRva(item)); writer.WriteUInt32(GetFlags(item)); var parametersCount = (Byte)item.Parameters.Count; if (!item.IsStatic) { ++parametersCount; // add implicit 'this' pointer into non-static methods } _context.SignaturesTable.WriteDataType(item.ReturnType, writer, false, false); if (item.ReturnType is TypeSpecification) { _context.TypeSpecificationsTable .GetOrCreateTypeSpecificationId(item.ReturnType); } writer.WriteByte(parametersCount); writer.WriteByte((Byte)(item.HasBody ? item.Body.Variables.Count : 0)); writer.WriteByte(CodeWriter.CalculateStackSize(item.Body)); var methodSignature = _context.SignaturesTable.GetOrCreateSignatureId(item); writer.WriteUInt16(item.HasBody ? _context.SignaturesTable.GetOrCreateSignatureId(item.Body.Variables) : (item.IsAbstract || item.IsRuntime ? (UInt16)0x0000 : (UInt16)0xFFFF)); writer.WriteUInt16(methodSignature); }
/// <summary> /// Writes header information into output stream (w/o CRC and table offsets/paddings). /// </summary> /// <param name="writer">Binary writer with correct endianness.</param> /// <param name="isPreAllocationCall">If true no assembly name will be written.</param> public void Write( TinyBinaryWriter writer, Boolean isPreAllocationCall) { writer.WriteString("MSSpot1"); writer.WriteUInt32(0); // header CRC writer.WriteUInt32(0); // assembly CRC writer.WriteUInt32(writer.IsBigEndian ? FLAGS_BIG_ENDIAN : FLAGS_LITTLE_ENDIAN); // This CRC calculated only for BE assemblies!!! writer.WriteUInt32(writer.IsBigEndian ? _context.NativeMethodsCrc.Current : 0x00); writer.WriteUInt32(0xFFFFFFFF); // Native methods offset writer.WriteVersion(_context.AssemblyDefinition.Name.Version); writer.WriteUInt16(isPreAllocationCall ? (UInt16)0x0000 : _context.StringTable.GetOrCreateStringId(_context.AssemblyDefinition.Name.Name)); writer.WriteUInt16(1); // String table version if (isPreAllocationCall) { _tablesOffset = writer.BaseStream.Position; for (var i = 0; i < 16; ++i) { writer.WriteUInt32(0); } writer.WriteUInt32(0); // Number of patched methods _paddingsOffset = writer.BaseStream.Position; for (var i = 0; i < 16; ++i) { writer.WriteByte(0); } } else { writer.BaseStream.Seek(12, SeekOrigin.Begin); var assemblyCrc32 = ComputeCrc32(writer.BaseStream, _paddingsOffset, writer.BaseStream.Length - _paddingsOffset); writer.WriteUInt32(assemblyCrc32); writer.BaseStream.Seek(8, SeekOrigin.Begin); var headerCrc32 = ComputeCrc32(writer.BaseStream, 0, _paddingsOffset); writer.WriteUInt32(headerCrc32); } }
/// <inheritdoc/> public void Write( TinyBinaryWriter writer) { var offset = 0U; foreach (var item in _resouces) { writer.WriteUInt32(0x02); // Version writer.WriteUInt32(0x04); // Size of header writer.WriteUInt32(0x08); // Size of resouce header writer.WriteUInt32(item.Item2); writer.WriteUInt16(item.Item1); writer.WriteUInt16(0x0); // paddding writer.WriteUInt32(offset); offset += 8; // Size of resource table record } }
public void Process( TinyBinaryWriter writer) { writer.WriteUInt32((UInt32)_bitmap.Width); writer.WriteUInt32((UInt32)_bitmap.Height); writer.WriteUInt16(0x00); // flags var tinyImageFormat = GetTinytImageFormat(_bitmap.RawFormat); if (tinyImageFormat != 0) { writer.WriteByte(0x01); // bpp writer.WriteByte(tinyImageFormat); _bitmap.Save(writer.BaseStream, _bitmap.RawFormat); } else { writer.WriteByte(0x10); // bpp writer.WriteByte(tinyImageFormat); var rect = new Rectangle(Point.Empty, _bitmap.Size); using (var convertedBitmap = _bitmap.Clone(new Rectangle(Point.Empty, _bitmap.Size), PixelFormat.Format16bppRgb565)) { var bitmapData = convertedBitmap.LockBits( rect, ImageLockMode.ReadOnly, convertedBitmap.PixelFormat); var buffer = new Int16[bitmapData.Stride * convertedBitmap.Height / sizeof(Int16)]; System.Runtime.InteropServices.Marshal.Copy( bitmapData.Scan0, buffer, 0, buffer.Length); convertedBitmap.UnlockBits(bitmapData); foreach (var item in buffer) { writer.WriteInt16(item); } } } }
/// <summary> /// Writes header information into output stream (w/o CRC and table offsets/paddings). /// </summary> /// <param name="writer">Binary writer with correct endianness.</param> /// <param name="isPreAllocationCall">If true no assembly name will be written.</param> public void Write( TinyBinaryWriter writer, Boolean isPreAllocationCall) { writer.WriteString("MSSpot1"); writer.WriteUInt32(0); // header CRC writer.WriteUInt32(0); // assembly CRC writer.WriteUInt32(writer.IsBigEndian ? FLAGS_BIG_ENDIAN : FLAGS_LITTLE_ENDIAN); // This CRC calculated only for BE assemblies!!! writer.WriteUInt32(writer.IsBigEndian ? _context.NativeMethodsCrc.Current : 0x00); writer.WriteUInt32(0xFFFFFFFF); // Native methods offset writer.WriteVersion(_context.AssemblyDefinition.Name.Version); writer.WriteUInt16(isPreAllocationCall ? (UInt16) 0x0000 : _context.StringTable.GetOrCreateStringId(_context.AssemblyDefinition.Name.Name)); writer.WriteUInt16(1); // String table version if (isPreAllocationCall) { _tablesOffset = writer.BaseStream.Position; for (var i = 0; i < 16; ++i) { writer.WriteUInt32(0); } writer.WriteUInt32(0); // Number of patched methods _paddingsOffset = writer.BaseStream.Position; for (var i = 0; i < 16; ++i) { writer.WriteByte(0); } } else { writer.BaseStream.Seek(12, SeekOrigin.Begin); var assemblyCrc32 = ComputeCrc32(writer.BaseStream, _paddingsOffset, writer.BaseStream.Length - _paddingsOffset); writer.WriteUInt32(assemblyCrc32); writer.BaseStream.Seek(8, SeekOrigin.Begin); var headerCrc32 = ComputeCrc32(writer.BaseStream, 0, _paddingsOffset); writer.WriteUInt32(headerCrc32); } }
/// <summary> /// Updates tables offest value and padding value for current table and /// advance writing position for next method call (filling tables info). /// </summary> /// <param name="writer">Binary writer with correct endianness.</param> /// <param name="tableBegin">Table beginning address (offset).</param> /// <param name="padding">Table padding value.</param> public void UpdateTableOffset( TinyBinaryWriter writer, Int64 tableBegin, Int64 padding) { writer.BaseStream.Seek(_tablesOffset, SeekOrigin.Begin); writer.WriteUInt32((UInt32)tableBegin); _tablesOffset += sizeof(Int32); writer.BaseStream.Seek(_paddingsOffset, SeekOrigin.Begin); writer.WriteByte((Byte)padding); _paddingsOffset += sizeof(Byte); writer.BaseStream.Seek(0, SeekOrigin.End); }
/// <summary> /// Processes original data and writes processed data into output writer. /// </summary> /// <param name="writer">Endianness-aware binary writer.</param> public void Process( TinyBinaryWriter writer) { using (var stream = new MemoryStream(_fontResouce, false)) using (var reader = new BinaryReader(stream)) { // CLR_GFX_FontDescription { // CLR_GFX_FontMetrics writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_FontMetrics.m_height writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_offset writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_ascent writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_descent writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_internalLeading writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_externalLeading writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_aveCharWidth writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_aveCharWidth } var rangesCount = reader.ReadInt16(); writer.WriteInt16(rangesCount); // CLR_GFX_FontDescription.m_ranges var charactersCount = reader.ReadInt16(); writer.WriteInt16(charactersCount); // CLR_GFX_FontDescription.m_characters var flags = reader.ReadInt16(); writer.WriteInt16(flags); // CLR_GFX_FontDescription.m_flags writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontDescription.m_pad // CLR_GFX_BitmapDescription var width = reader.ReadUInt32(); writer.WriteUInt32(width); // CLR_GFX_BitmapDescription.m_width var height = reader.ReadUInt32(); writer.WriteUInt32(height); // CLR_GFX_BitmapDescription.m_height writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_BitmapDescription.m_flags var bitsPerPixel = reader.ReadByte(); writer.WriteByte(bitsPerPixel); // CLR_GFX_BitmapDescription.m_bitsPerPixel writer.WriteByte(reader.ReadByte()); // CLR_GFX_BitmapDescription.m_type for (var i = 0; i <= rangesCount; ++i) // Including sentinel range { // CLR_GFX_FontCharacterRange writer.WriteUInt32(reader.ReadUInt32()); // CLR_GFX_FontCharacterRange.m_indexOfFirstFontCharacter writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_FontCharacterRange.m_firstChar writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_FontCharacterRange.m_lastChar writer.WriteUInt32(reader.ReadUInt32()); // CLR_GFX_FontCharacterRange.m_rangeOffset } for (var i = 0; i <= charactersCount; ++i) // Including sentinel character { // CLR_GFX_FontCharacter writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_FontCharacter.m_offset writer.WriteByte(reader.ReadByte()); // CLR_GFX_FontCharacter.m_marginLeft writer.WriteByte(reader.ReadByte()); // CLR_GFX_FontCharacter.m_marginRight } if (bitsPerPixel == 0) { bitsPerPixel = 16; // Native value, rest calculations are same } var totalSizeInWords = ((width * bitsPerPixel + 31) / 32) * height; for (var i = 0; i < totalSizeInWords; ++i) { writer.WriteUInt32(reader.ReadUInt32()); } if ((flags & FLAG_FONT_EX) == FLAG_FONT_EX) { // TODO: implement it according original idea if needed } while (stream.Position < stream.Length) { writer.WriteByte(reader.ReadByte()); } } }
private void WriteOperand( Instruction instruction) { var opcode = instruction.OpCode; var operandType = opcode.OperandType; if (operandType == OperandType.InlineNone) { return; } var operand = instruction.Operand; if (operand == null) { throw new ArgumentException(); } switch (operandType) { case OperandType.InlineSwitch: { var targets = (Instruction[])operand; _writer.WriteByte((Byte)targets.Length); var diff = instruction.Offset + opcode.Size + 2 * targets.Length + 1; foreach (var item in targets) { _writer.WriteInt16((Int16)(GetTargetOffset(item) - diff)); } break; } case OperandType.ShortInlineBrTarget: { var target = (Instruction)operand; _writer.WriteSByte((SByte) (GetTargetOffset(target) - (instruction.Offset + opcode.Size + 1))); break; } case OperandType.InlineBrTarget: { var target = (Instruction)operand; _writer.WriteInt16((Int16) (GetTargetOffset(target) - (instruction.Offset + opcode.Size + 2))); break; } case OperandType.ShortInlineVar: _writer.WriteByte((byte)GetVariableIndex((VariableDefinition)operand)); break; case OperandType.ShortInlineArg: _writer.WriteByte((byte)GetParameterIndex((ParameterDefinition)operand)); break; case OperandType.InlineVar: _writer.WriteInt16((short)GetVariableIndex((VariableDefinition)operand)); break; case OperandType.InlineArg: _writer.WriteInt16((short)GetParameterIndex((ParameterDefinition)operand)); break; case OperandType.InlineSig: // TODO: implement this properly after finding when such code is generated //WriteMetadataToken (GetStandAloneSignature ((CallSite) operand)); break; case OperandType.ShortInlineI: if (opcode == OpCodes.Ldc_I4_S) { _writer.WriteSByte((SByte)operand); } else { _writer.WriteByte((Byte)operand); } break; case OperandType.InlineI: _writer.WriteInt32((Int32)operand); break; case OperandType.InlineI8: _writer.WriteInt64((Int64)operand); break; case OperandType.ShortInlineR: _writer.WriteSingle((Single)operand); break; case OperandType.InlineR: _writer.WriteDouble((Double)operand); break; case OperandType.InlineString: var stringReferenceId = _stringTable.GetOrCreateStringId((String)operand, false); _writer.WriteUInt16(stringReferenceId); break; case OperandType.InlineMethod: _writer.WriteUInt16(_context.GetMethodReferenceId((MethodReference)operand)); break; case OperandType.InlineType: _writer.WriteUInt16(GetTypeReferenceId((TypeReference)operand)); break; case OperandType.InlineField: _writer.WriteUInt16(GetFieldReferenceId((FieldReference)operand)); break; case OperandType.InlineTok: _writer.WriteUInt32(GetMetadataToken((IMetadataTokenProvider)operand)); break; default: throw new ArgumentException(); } }