Exemplo n.º 1
0
        uint WriteUTF8(string s)
        {
            if (s is null)
            {
                helper.Error("String is null");
                s = string.Empty;
            }
            var bytes = Encoding.UTF8.GetBytes(s);

            return(blobHeap.Add(bytes));
        }
Exemplo n.º 2
0
		public static int WriteCompressedInt32(this BinaryWriter writer, IWriterError helper, int value) {
			if (value < -0x10000000) {
				helper.Error("Int32 value is too small and can't be compressed.");
				value = -0x10000000;
			}
			else if (value > 0x0FFFFFFF) {
				helper.Error("Int32 value is too big and can't be compressed.");
				value = 0x0FFFFFFF;
			}
			writer.WriteCompressedInt32(value);
			return value;
		}
Exemplo n.º 3
0
        byte[] WriteFormat2(IList <SecurityAttribute> secAttrs)
        {
            var stream = new MemoryStream();
            var writer = new DataWriter(stream);

            writer.WriteByte((byte)'.');
            WriteCompressedUInt32(writer, (uint)secAttrs.Count);

            int count = secAttrs.Count;

            for (int i = 0; i < count; i++)
            {
                var sa = secAttrs[i];
                if (sa is null)
                {
                    helper.Error("SecurityAttribute is null");
                    Write(writer, UTF8String.Empty);
                    WriteCompressedUInt32(writer, 1);
                    WriteCompressedUInt32(writer, 0);
                    continue;
                }
                var    attrType = sa.AttributeType;
                string fqn;
                if (attrType is null)
                {
                    helper.Error("SecurityAttribute attribute type is null");
                    fqn = string.Empty;
                }
                else
                {
                    fqn = attrType.AssemblyQualifiedName;
                }
                Write(writer, fqn);

                var namedArgsBlob = context is null?
                                    CustomAttributeWriter.Write(this, sa.NamedArguments) :
                                        CustomAttributeWriter.Write(this, sa.NamedArguments, context);

                if (namedArgsBlob.Length > 0x1FFFFFFF)
                {
                    helper.Error("Named arguments blob size doesn't fit in 29 bits");
                    namedArgsBlob = Array2.Empty <byte>();
                }
                WriteCompressedUInt32(writer, (uint)namedArgsBlob.Length);
                writer.WriteBytes(namedArgsBlob);
            }

            return(stream.ToArray());
        }
Exemplo n.º 4
0
 public static int WriteCompressedInt32(this DataWriter writer, IWriterError helper, int value)
 {
     if (value < -0x10000000)
     {
         helper.Error("Int32 value is too small and can't be compressed.");
         value = -0x10000000;
     }
     else if (value > 0x0FFFFFFF)
     {
         helper.Error("Int32 value is too big and can't be compressed.");
         value = 0x0FFFFFFF;
     }
     writer.WriteCompressedInt32(value);
     return(value);
 }
Exemplo n.º 5
0
        byte[] WriteFormat2(IList <SecurityAttribute> secAttrs)
        {
            using (var stream = new MemoryStream())
                using (var writer = new BinaryWriter(stream)) {
                    writer.Write((byte)'.');
                    WriteCompressedUInt32(writer, (uint)secAttrs.Count);

                    foreach (var sa in secAttrs)
                    {
                        if (sa == null)
                        {
                            helper.Error("SecurityAttribute is null");
                            Write(writer, UTF8String.Empty);
                            WriteCompressedUInt32(writer, 1);
                            WriteCompressedUInt32(writer, 0);
                            continue;
                        }
                        var    attrType = sa.AttributeType;
                        string fqn;
                        if (attrType == null)
                        {
                            helper.Error("SecurityAttribute attribute type is null");
                            fqn = string.Empty;
                        }
                        else
                        {
                            fqn = attrType.AssemblyQualifiedName;
                        }
                        Write(writer, fqn);

                        var namedArgsBlob = context == null?
                                            CustomAttributeWriter.Write(this, sa.NamedArguments) :
                                                CustomAttributeWriter.Write(this, sa.NamedArguments, context);

                        if (namedArgsBlob.Length > 0x1FFFFFFF)
                        {
                            helper.Error("Named arguments blob size doesn't fit in 29 bits");
                            namedArgsBlob = new byte[0];
                        }
                        WriteCompressedUInt32(writer, (uint)namedArgsBlob.Length);
                        writer.Write(namedArgsBlob);
                    }

                    return(stream.ToArray());
                }
        }
Exemplo n.º 6
0
		public static uint WriteCompressedUInt32(this BinaryWriter writer, IWriterError helper, uint value) {
			if (value > 0x1FFFFFFF) {
				helper.Error("UInt32 value is too big and can't be compressed");
				value = 0x1FFFFFFF;
			}
			writer.WriteCompressedUInt32(value);
			return value;
		}
Exemplo n.º 7
0
		public static void Write(this BinaryWriter writer, IWriterError helper, UTF8String s) {
			if (UTF8String.IsNull(s)) {
				helper.Error("UTF8String is null");
				s = UTF8String.Empty;
			}

			writer.WriteCompressedUInt32(helper, (uint)s.DataLength);
			writer.Write(s.Data);
		}
Exemplo n.º 8
0
 public static uint WriteCompressedUInt32(this DataWriter writer, IWriterError helper, uint value)
 {
     if (value > 0x1FFFFFFF)
     {
         helper.Error("UInt32 value is too big and can't be compressed");
         value = 0x1FFFFFFF;
     }
     writer.WriteCompressedUInt32(value);
     return(value);
 }
Exemplo n.º 9
0
        public static void Write(this DataWriter writer, IWriterError helper, UTF8String s)
        {
            if (UTF8String.IsNull(s))
            {
                helper.Error("UTF8String is null");
                s = UTF8String.Empty;
            }

            writer.WriteCompressedUInt32(helper, (uint)s.DataLength);
            writer.WriteBytes(s.Data);
        }
Exemplo n.º 10
0
 /// <summary>
 /// Called when an error is detected (eg. a null pointer or other invalid value). The error
 /// can be ignored but the written data won't be valid.
 /// </summary>
 /// <param name="helper">The instance of <see cref="IWriterError"/></param>
 /// <param name="message">Error message</param>
 /// <param name="args">Optional message arguments</param>
 internal static void Error2(this IWriterError helper, string message, params object[] args)
 {
     if (helper is IWriterError2 helper2)
     {
         helper2.Error(message, args);
     }
     else
     {
         helper.Error(string.Format(message, args));
     }
 }
Exemplo n.º 11
0
 public uint GetOffset(Instruction instr)
 {
     if (!dictInitd)
     {
         Debug.Assert(body is not null);
         if (body is null)
         {
             return(0);
         }
         InitializeDict();
     }
     if (instr is null)
     {
         return(bodySize);
     }
     if (toOffset.TryGetValue(instr, out uint offset))
     {
         return(offset);
     }
     helper.Error("Couldn't find an instruction, maybe it was removed. It's still being referenced by some code or by the PDB");
     return(bodySize);
 }
Exemplo n.º 12
0
        byte[] Write(MarshalType marshalType)
        {
            if (marshalType is null)
            {
                return(null);
            }

            var type = marshalType.NativeType;

            if (type != NativeType.RawBlob)
            {
                if ((uint)type > byte.MaxValue)
                {
                    helper.Error("Invalid MarshalType.NativeType");
                }
                writer.WriteByte((byte)type);
            }
            bool canWrite = true;

            switch (type)
            {
            case NativeType.FixedSysString:
                var fixedSysString = (FixedSysStringMarshalType)marshalType;
                if (fixedSysString.IsSizeValid)
                {
                    WriteCompressedUInt32((uint)fixedSysString.Size);
                }
                break;

            case NativeType.SafeArray:
                var safeArray = (SafeArrayMarshalType)marshalType;
                if (UpdateCanWrite(safeArray.IsVariantTypeValid, "VariantType", ref canWrite))
                {
                    WriteCompressedUInt32((uint)safeArray.VariantType);
                }
                if (UpdateCanWrite(safeArray.IsUserDefinedSubTypeValid, "UserDefinedSubType", ref canWrite))
                {
                    Write(safeArray.UserDefinedSubType.AssemblyQualifiedName);
                }
                break;

            case NativeType.FixedArray:
                var fixedArray = (FixedArrayMarshalType)marshalType;
                if (UpdateCanWrite(fixedArray.IsSizeValid, "Size", ref canWrite))
                {
                    WriteCompressedUInt32((uint)fixedArray.Size);
                }
                if (UpdateCanWrite(fixedArray.IsElementTypeValid, "ElementType", ref canWrite))
                {
                    WriteCompressedUInt32((uint)fixedArray.ElementType);
                }
                break;

            case NativeType.Array:
                var array = (ArrayMarshalType)marshalType;
                if (UpdateCanWrite(array.IsElementTypeValid, "ElementType", ref canWrite))
                {
                    WriteCompressedUInt32((uint)array.ElementType);
                }
                if (UpdateCanWrite(array.IsParamNumberValid, "ParamNumber", ref canWrite))
                {
                    WriteCompressedUInt32((uint)array.ParamNumber);
                }
                if (UpdateCanWrite(array.IsSizeValid, "Size", ref canWrite))
                {
                    WriteCompressedUInt32((uint)array.Size);
                }
                if (UpdateCanWrite(array.IsFlagsValid, "Flags", ref canWrite))
                {
                    WriteCompressedUInt32((uint)array.Flags);
                }
                break;

            case NativeType.CustomMarshaler:
                var custMarshaler = (CustomMarshalType)marshalType;
                Write(custMarshaler.Guid);
                Write(custMarshaler.NativeTypeName);
                var cm     = custMarshaler.CustomMarshaler;
                var cmName = cm is null ? string.Empty : FullNameFactory.AssemblyQualifiedName(cm, this);
                Write(cmName);
                Write(custMarshaler.Cookie);
                break;

            case NativeType.IUnknown:
            case NativeType.IDispatch:
            case NativeType.IntF:
                var iface = (InterfaceMarshalType)marshalType;
                if (iface.IsIidParamIndexValid)
                {
                    WriteCompressedUInt32((uint)iface.IidParamIndex);
                }
                break;

            case NativeType.RawBlob:
                var data = ((RawMarshalType)marshalType).Data;
                if (data is not null)
                {
                    writer.WriteBytes(data);
                }
                break;

            default:
                break;
            }

            return(outStream.ToArray());
        }
Exemplo n.º 13
0
        void Write(DataWriter writer, TypeSig type, object value)
        {
            for (; ; type = type.Next)
            {
                if (type is null)
                {
                    return;
                }

                var et = type.ElementType;
                switch (et)
                {
                case ElementType.Boolean:
                case ElementType.Char:
                case ElementType.I1:
                case ElementType.U1:
                case ElementType.I2:
                case ElementType.U2:
                case ElementType.I4:
                case ElementType.U4:
                case ElementType.I8:
                case ElementType.U8:
                    writer.WriteByte((byte)et);
                    WritePrimitiveValue(writer, et, value);
                    return;

                case ElementType.R4:
                    writer.WriteByte((byte)et);
                    if (value is float f)
                    {
                        writer.WriteSingle(f);
                    }
                    else
                    {
                        helper.Error("Expected a Single constant");
                        writer.WriteSingle(0);
                    }
                    return;

                case ElementType.R8:
                    writer.WriteByte((byte)et);
                    if (value is double d)
                    {
                        writer.WriteDouble(d);
                    }
                    else
                    {
                        helper.Error("Expected a Double constant");
                        writer.WriteDouble(0);
                    }
                    return;

                case ElementType.String:
                    writer.WriteByte((byte)et);
                    if (value is null)
                    {
                        writer.WriteByte(0xFF);
                    }
                    else if (value is string s)
                    {
                        writer.WriteBytes(Encoding.Unicode.GetBytes(s));
                    }
                    else
                    {
                        helper.Error("Expected a String constant");
                    }
                    return;

                case ElementType.Ptr:
                case ElementType.ByRef:
                    writer.WriteByte((byte)et);
                    WriteTypeDefOrRef(writer, new TypeSpecUser(type));
                    return;

                case ElementType.Object:
                    writer.WriteByte((byte)et);
                    return;

                case ElementType.ValueType:
                    writer.WriteByte((byte)et);
                    var tdr = ((ValueTypeSig)type).TypeDefOrRef;
                    var td  = tdr.ResolveTypeDef();
                    if (td is null)
                    {
                        helper.Error($"Couldn't resolve type 0x{tdr?.MDToken.Raw ?? 0:X8}");
                    }
                    else if (td.IsEnum)
                    {
                        var underlyingType = td.GetEnumUnderlyingType().RemovePinnedAndModifiers();
                        switch (underlyingType.GetElementType())
                        {
                        case ElementType.Boolean:
                        case ElementType.Char:
                        case ElementType.I1:
                        case ElementType.U1:
                        case ElementType.I2:
                        case ElementType.U2:
                        case ElementType.I4:
                        case ElementType.U4:
                        case ElementType.I8:
                        case ElementType.U8:
                            writer.Position--;
                            writer.WriteByte((byte)underlyingType.GetElementType());
                            WritePrimitiveValue(writer, underlyingType.GetElementType(), value);
                            WriteTypeDefOrRef(writer, tdr);
                            return;

                        default:
                            helper.Error("Invalid enum underlying type");
                            return;
                        }
                    }
                    else
                    {
                        WriteTypeDefOrRef(writer, tdr);
                        bool valueWritten = false;
                        if (GetName(tdr, out var ns, out var name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib())
                        {
                            if (name == stringDecimal)
                            {
                                if (value is decimal dec)
                                {
                                    var bits = decimal.GetBits(dec);
                                    writer.WriteByte((byte)((((uint)bits[3] >> 31) << 7) | (((uint)bits[3] >> 16) & 0x7F)));
                                    writer.WriteInt32(bits[0]);
                                    writer.WriteInt32(bits[1]);
                                    writer.WriteInt32(bits[2]);
                                }
                                else
                                {
                                    helper.Error("Expected a Decimal constant");
                                    writer.WriteBytes(new byte[13]);
                                }
                                valueWritten = true;
                            }
                            else if (name == stringDateTime)
                            {
                                if (value is DateTime time)
                                {
                                    writer.WriteInt64(time.Ticks);
                                }
                                else
                                {
                                    helper.Error("Expected a DateTime constant");
                                    writer.WriteInt64(0);
                                }
                                valueWritten = true;
                            }
                        }
                        if (!valueWritten)
                        {
                            if (value is byte[] b)
                            {
                                writer.WriteBytes(b);
                            }
                            else if (value is not null)
                            {
                                helper.Error("Unsupported constant: " + value.GetType().FullName);
                                return;
                            }
                        }
                    }
                    return;

                case ElementType.Class:
                    var cTdr = ((ClassSig)type).TypeDefOrRef;
                    if (value is byte[] bytes)
                    {
                        writer.WriteByte((byte)et);
                        writer.WriteBytes(bytes);
                    }
                    else if (value is not null)
                    {
                        writer.WriteByte((byte)ElementType.ValueType);
                        WriteTypeDefOrRef(writer, cTdr);
                        bool valueWritten = false;
                        if (GetName(cTdr, out var ns, out var name) && ns == stringSystem && cTdr.DefinitionAssembly.IsCorLib())
                        {
                            if (name == stringDecimal)
                            {
                                if (value is decimal dec)
                                {
                                    var bits = decimal.GetBits(dec);
                                    writer.WriteByte((byte)((((uint)bits[3] >> 31) << 7) | (((uint)bits[3] >> 16) & 0x7F)));
                                    writer.WriteInt32(bits[0]);
                                    writer.WriteInt32(bits[1]);
                                    writer.WriteInt32(bits[2]);
                                }
                                else
                                {
                                    helper.Error("Expected a Decimal constant");
                                    writer.WriteBytes(new byte[13]);
                                }
                                valueWritten = true;
                            }
                            else if (name == stringDateTime)
                            {
                                if (value is DateTime time)
                                {
                                    writer.WriteInt64(time.Ticks);
                                }
                                else
                                {
                                    helper.Error("Expected a DateTime constant");
                                    writer.WriteInt64(0);
                                }
                                valueWritten = true;
                            }
                        }
                        if (!valueWritten)
                        {
                            if (value is byte[] b)
                            {
                                writer.WriteBytes(b);
                            }
                            else if (value is not null)
                            {
                                helper.Error("Unsupported constant: " + value.GetType().FullName);
                                return;
                            }
                        }
                    }
                    return;

                case ElementType.CModReqd:
                case ElementType.CModOpt:
                    writer.WriteByte((byte)et);
                    WriteTypeDefOrRef(writer, ((ModifierSig)type).Modifier);
                    break;

                case ElementType.Var:
                case ElementType.Array:
                case ElementType.GenericInst:
                case ElementType.TypedByRef:
                case ElementType.I:
                case ElementType.U:
                case ElementType.FnPtr:
                case ElementType.SZArray:
                case ElementType.MVar:
                    writer.WriteByte((byte)et);
                    WriteTypeDefOrRef(writer, new TypeSpecUser(type));
                    return;

                case ElementType.End:
                case ElementType.Void:
                case ElementType.ValueArray:
                case ElementType.R:
                case ElementType.Internal:
                case ElementType.Module:
                case ElementType.Sentinel:
                case ElementType.Pinned:
                default:
                    helper.Error("Unsupported element type in LocalConstant sig blob: " + et.ToString());
                    return;
                }
            }
        }