Beispiel #1
0
 public void Read(ReaderContext ctxt, BlobReader reader, bool isFat, Func<OpCode, Row, object> resolveRow)
 {
     if (isFat)
     {
         Flags = (CorILExceptionClause)reader.ReadUInt32();
         TryOffset = (int)reader.ReadUInt32();
         TryLength = (int)reader.ReadUInt32();
         HandlerOffset = (int)reader.ReadUInt32();
         HandlerLength = (int)reader.ReadUInt32();
     }
     else
     {
         Flags = (CorILExceptionClause)reader.ReadUInt16();
         TryOffset = (int)reader.ReadUInt16();
         TryLength = (int)reader.ReadByte();
         HandlerOffset = (int)reader.ReadUInt16();
         HandlerLength = (int)reader.ReadByte();
     }
     var rowRef = default(TokenRef);
     rowRef.Read(ctxt, reader);
     rowRef.ResolveIndexes(ctxt);
     Class = rowRef.Value == null ? null : resolveRow(OpCode.Ldobj, rowRef.Value);
     if (Flags == CorILExceptionClause.Filter)
         FilterOffset = (int)reader.ReadUInt32();
 }
Beispiel #2
0
        public void Read(ReaderContext ctxt, BlobReader reader, bool isFat, Func <OpCode, Row, object> resolveRow)
        {
            if (isFat)
            {
                Flags         = (CorILExceptionClause)reader.ReadUInt32();
                TryOffset     = (int)reader.ReadUInt32();
                TryLength     = (int)reader.ReadUInt32();
                HandlerOffset = (int)reader.ReadUInt32();
                HandlerLength = (int)reader.ReadUInt32();
            }
            else
            {
                Flags         = (CorILExceptionClause)reader.ReadUInt16();
                TryOffset     = (int)reader.ReadUInt16();
                TryLength     = (int)reader.ReadByte();
                HandlerOffset = (int)reader.ReadUInt16();
                HandlerLength = (int)reader.ReadByte();
            }
            var rowRef = default(TokenRef);

            rowRef.Read(ctxt, reader);
            rowRef.ResolveIndexes(ctxt);
            Class = rowRef.Value == null ? null : resolveRow(OpCode.Ldobj, rowRef.Value);
            if (Flags == CorILExceptionClause.Filter)
            {
                FilterOffset = (int)reader.ReadUInt32();
            }
        }
Beispiel #3
0
        private bool ReadMethodDataSection(ReaderContext ctxt, BlobReader reader, Func <OpCode, Row, object> resolveRow)
        {
            reader.Align(4);
            var flags = (CorILMethodSect)reader.ReadByte();

            if ((flags & CorILMethodSect.EHTable) == 0)
            {
                throw new PEException("unrecognised method data section");
            }

            var isFat = (flags & CorILMethodSect.FatFormat) != 0;
            var count = default(uint);

            if (isFat)
            {
                var size = reader.ReadUInt24();
                if (size < 4 || (size - 4) % 24 != 0)
                {
                    throw new InvalidOperationException("invalid method data section");
                }
                count = (size - 4) / 24;
            }
            else
            {
                var size = (uint)reader.ReadByte();
                // NOTE: Looks live VB emits size without including the 4 byte header...
                if (size < 4 || (size - 4) % 12 != 0)
                {
                    throw new InvalidOperationException("invalid method data section");
                }
                var padding = reader.ReadUInt16();
                if (padding != 0)
                {
                    throw new PEException("unexpected data");
                }
                count = (size - 4) / 12;
            }

            for (var i = 0; i < count; i++)
            {
                var c = new ExceptionHandlingClause();
                c.Read(ctxt, reader, isFat, resolveRow);
                ExceptionHandlingClauses.Add(c);
            }

            return((flags & CorILMethodSect.MoreSects) != 0);
        }
Beispiel #4
0
 public void Read(ReaderContext ctxt, BlobReader reader)
 {
     var word = reader.ReadUInt16();
     Type = (ImageRelocation)(word >> 12);
     Offset = (ushort)(word & 0xFFF);
 }
Beispiel #5
0
 public void Read(ReaderContext ctxt, BlobReader reader)
 {
     var actualHint = reader.ReadUInt16();
     if (actualHint != hint)
         throw new PEException("invalid HintNameTable.Hint");
     Name = reader.ReadAsciiZeroTerminatedString(1);
     if (!Name.Equals(ExeHintName, StringComparison.Ordinal) &&
         !Name.Equals(DllHintName, StringComparison.Ordinal))
         throw new PEException("invalid HintNameTable.Name");
 }
Beispiel #6
0
        public void Read(ReaderContext ctxt, BlobReader reader)
        {
            var name = reader.ReadAsciiZeroPaddedString(8);
            if (string.IsNullOrEmpty(name))
                throw new PEException("invalid SectionHeader.Name");
            if (name.Equals(".text", StringComparison.Ordinal))
                Section = Section.Text;
            else if (name.Equals(".rsrc", StringComparison.Ordinal))
                Section = Section.Rsrc;
            else if (name.Equals(".reloc", StringComparison.Ordinal))
                Section = Section.Reloc;
            else
                throw new PEException("invalid SectionHeader.Name");

            VirtualSize = reader.ReadUInt32();
            VirtualAddress = reader.ReadUInt32();
            SizeOfRawData = reader.ReadUInt32();
            // NOTE: Virtual size may be less than raw data size
            if (VirtualSize > SizeOfRawData)
                // Need to support readers with implicit zero padding at end
                throw new NotImplementedException();
            PointerToRawData.Read(reader);
            PointerToRelocations = reader.ReadUInt32();
            var actualPointerToLinenumbers = reader.ReadUInt32();
            if (actualPointerToLinenumbers != pointerToLinenumbers)
                throw new PEException("invalid SectionHeader.PointerToLinenumbers");
            NumberOfRelocations = reader.ReadUInt16();
            var actualNumberOfLinenumbers = reader.ReadUInt16();
            if (actualNumberOfLinenumbers != numberOfLinenumbers)
                throw new PEException("invalid SectionHeader.NumberOfLinenumbers");
            Characteristics = (ImageSectionCharacteristics)reader.ReadUInt32();

            if (ctxt.Tracer != null)
            {
                ctxt.Tracer.AppendLine("SectionHeader {");
                ctxt.Tracer.Indent();
                ctxt.Tracer.AppendLine(String.Format("Name: {0}", Section.ToString()));
                ctxt.Tracer.AppendLine(String.Format("VirtualSize: {0:x8}", VirtualSize));
                ctxt.Tracer.AppendLine(String.Format("VirtualAddress: {0:x8}", VirtualAddress));
                ctxt.Tracer.AppendLine(String.Format("SizeOfRawData: {0:x8}", SizeOfRawData));
                PointerToRawData.Append(ctxt, "PointerToRawData");
                ctxt.Tracer.Outdent();
                ctxt.Tracer.AppendLine("}");
            }
        }
Beispiel #7
0
        public void Read(ReaderContext ctxt, BlobReader reader)
        {
            ImageBase = reader.ReadUInt32();
            var actualSectionAlignment = reader.ReadUInt32();
            if (actualSectionAlignment != sectionAlignment)
                throw new PEException("invalid PEHeaderNTSpecificFields.SectionAlignment");
            FileAlignment = reader.ReadUInt32();
            if (FileAlignment != fileAlignment1 && FileAlignment != fileAlignment2)
                throw new PEException("invalid PEHeaderNTSpecificFields.FileAlignment");
            var actualOSMajor = reader.ReadUInt16();
            if (actualOSMajor != osMajor)
                throw new PEException("invalid PEHeaderNTSpecificFields.OSMajor");
            var actualOSMinor = reader.ReadUInt16();
            if (actualOSMinor != osMinor)
                throw new PEException("invalid PEHeaderNTSpecificFields.OSMinor");
            var actualUserMajor = reader.ReadUInt16();
            if (actualUserMajor != userMajor)
                throw new PEException("invalid PEHeaderNTSpecificFields.UserMajor");
            var actualUserMinor = reader.ReadUInt16();
            if (actualUserMinor != userMinor)
                throw new PEException("invalid PEHeaderNTSpecificFields.UserMinor");
            var actualSubSysMajor = reader.ReadUInt16();
            if (actualSubSysMajor != subSysMajor)
                throw new PEException("invalid PEHeaderNTSpecificFields.SubSysMajor");
            var actualSubSysMinor = reader.ReadUInt16();
            if (actualSubSysMinor != subSysMinor)
                throw new PEException("invalid PEHeaderNTSpecificFields.SubSysMinor");
            var actualReserved = reader.ReadUInt32();
            if (actualReserved != reserved)
                throw new PEException("invalid PEHeaderNTSpecificFields.Reserved");
            ImageSize = reader.ReadUInt32();
            if (ImageSize % sectionAlignment != 0)
                throw new PEException("invalid PEHeaderNTSpecificFields.ImageSize");
            HeaderSize = reader.ReadUInt32();
            if (HeaderSize % FileAlignment != 0)
                throw new PEException("invalid PEHeaderNTSpecificFields.HeaderSize");
            FileChecksum = reader.ReadUInt32();
            SubSystem = (SubSystem)reader.ReadUInt16();
            if (SubSystem != SubSystem.WINDOWS_CUI && SubSystem != SubSystem.WINDOWS_GUI)
                throw new PEException("invalid PEHeaderNTSpecificFields.SubSystem");
            DllFlags = reader.ReadUInt16();
            var actualStackReserveSize = reader.ReadUInt32();
            if (actualStackReserveSize != stackReserveSize)
                throw new PEException("invalid PEHeaderNTSpecificFields.StackReserveSize");
            StackCommitSize = reader.ReadUInt32();
            HeapReserveSize = reader.ReadUInt32();
            HeapCommitSize = reader.ReadUInt32();
            var actualLoaderFlags = reader.ReadUInt32();
            if (actualLoaderFlags != loaderFlags)
                throw new PEException("invalid PEHeaderNTSpecificFields.LoaderFlags");
            var actualNumberOfDataDirectories = reader.ReadUInt32();
            if (actualNumberOfDataDirectories != numberOfDataDirectories)
                throw new PEException("invalid PEHeaderNTSpecificFields.NumberOfDataDirectories");

            if (ctxt.Tracer != null)
            {
                ctxt.Tracer.AppendLine(String.Format("PEHeaderNTSpecificFields.ImageBase: {0:x8}", ImageBase));
                ctxt.Tracer.AppendLine(String.Format("PEHeaderNTSpecificFields.ImageSize: {0:x8}", ImageSize));
                ctxt.Tracer.AppendLine(String.Format("PEHeaderNTSpecificFields.HeaderSize: {0:x8}", HeaderSize));
                ctxt.Tracer.AppendLine(String.Format("PEHeaderNTSpecificFields.FileChecksum: {0:x8}", FileChecksum));
            }
        }
Beispiel #8
0
        public RVA BaseOfData; // == start of .reloc or .rsrc section, whichever is lower

        public void Read(ReaderContext ctxt, BlobReader reader)
        {
            var actualMagic = reader.ReadUInt16();
            if (actualMagic != magic)
                throw new PEException("invalid PEHeaderStandardFields.Magic");
            LMajor = reader.ReadByte();
            if (LMajor < lMajorLow || LMajor > lMajorHigh)
                throw new PEException("invalid PEHeaderStandardFields.LMajor");
            var actualLMinor = reader.ReadByte();
            if (actualLMinor != lMinor)
                throw new PEException("invalid PEHeaderStandardFields.LMinor");
            CodeSize = reader.ReadUInt32();
            InitializedDataSize = reader.ReadUInt32();
            var actualUninitializedDataSize = reader.ReadUInt32();
            if (actualUninitializedDataSize != uninitializedDataSize)
                throw new PEException("invalid PEHeaderStandardFields.UninitializedDataSize");
            EntryPoint.Read(reader);
            BaseOfCode.Read(reader);
            BaseOfData.Read(reader);

            if (ctxt.Tracer != null)
            {
                ctxt.Tracer.AppendLine(String.Format("PEHeaderStandardFields.CodeSize: {0:x8}", CodeSize));
                ctxt.Tracer.AppendLine
                    (String.Format("PEHeaderStandardFields.InitializedDataSize: {0:x8}", InitializedDataSize));
            }
        }
Beispiel #9
0
        public void Read(ReaderContext ctxt, BlobReader reader)
        {
            if (reader.RemainingBytes < Size)
                throw new PEException("missing PEFileHeader");

            var actualPrefix = reader.ReadUInt32();
            if (actualPrefix != prefix)
                throw new PEException("invalid PEFileHeader.Prefix");
            var actualMachine = reader.ReadUInt16();
            if (actualMachine != machine)
                throw new PEException("invalid PEFileHeader.Machine");
            var actualNumberOfSections = reader.ReadUInt16();
            if (actualNumberOfSections != NumberOfSections)
                throw new PEException("invalid PEFileHeader.NumberOfSections");
            var seconds = reader.ReadUInt32();
            DateTimeStamp = nineteenSeventy.AddSeconds((double)seconds);
            var actualPointerToSymbolTable = reader.ReadUInt32();
            if (actualPointerToSymbolTable != pointerToSymbolTable)
                throw new PEException("invalid PEFileHeader.PointerToSymbolTable");
            var actualNumberOfSymbols = reader.ReadUInt32();
            if (actualNumberOfSymbols != numberOfSymbols)
                throw new PEException("invalid PEFileHeader.NumberOfSymbols");
            var actualOptionalHeaderSize = reader.ReadUInt16();
            if (actualOptionalHeaderSize != PEOptionalHeader.Size)
                throw new PEException("invalid PEFileHeader.OptionalHeaderSize");
            Flags = (ImageFileFlags)reader.ReadUInt16();
            var check = Flags & ~ImageFileFlags.DLL;
            if ((check & setFlags) != setFlags)
                throw new PEException("invalid PEFileHeader.Flags");
            if ((check & clearFlags) != 0)
                throw new PEException("invalid PEFileHeader.Flags");
        }
Beispiel #10
0
 public void Read(IImSeq<CustomAttributePropertyType> fixedArgTypes, BlobReader reader, Func<string, CustomAttributePropertyType> resolveType)
 {
     var fieldArgs = default(Map<string, CustomAttributeProperty>);
     var propertyArgs = default(Map<string, CustomAttributeProperty>);
     if (reader.AtEndOfBlob)
     {
         if (fixedArgTypes.Count > 0)
             throw new PEException("expected fixed arguments in custom attribute");
         FixedArgs = Constants.EmptyCustomAttributeProperties;
         FieldArgs = Constants.EmptyNamedCustomAttributueProperties;
         PropertyArgs = Constants.EmptyNamedCustomAttributueProperties;
     }
     else
     {
         if (reader.ReadUInt16() != prolog)
             throw new PEException("invalid custom attribute");
         if (fixedArgTypes.Count > 0)
         {
             var fixedArgs = new Seq<CustomAttributeProperty>(fixedArgTypes.Count);
             for (var i = 0; i < fixedArgTypes.Count; i++)
             {
                 var type = fixedArgTypes[i];
                 fixedArgs.Add
                     (new CustomAttributeProperty { Type = type, Value = type.ReadValue(reader, resolveType) });
             }
             FixedArgs = fixedArgs;
         }
         else
             FixedArgs = Constants.EmptyCustomAttributeProperties;
         var numNamed = reader.ReadUInt16();
         for (var i = 0; i < numNamed; i++)
         {
             var tag = (TypeSigTag)reader.ReadByte();
             var type = CustomAttributePropertyType.Read(reader, resolveType);
             var nm = reader.ReadUTF8SizedString();
             var prop = new CustomAttributeProperty { Type = type, Value = type.ReadValue(reader, resolveType) };
             if (tag == TypeSigTag.CUSTOM_ATTRIBUTE_FIELD)
             {
                 if (fieldArgs == null)
                     fieldArgs = new Map<string, CustomAttributeProperty>();
                 if (fieldArgs.ContainsKey(nm))
                     throw new PEException("duplicate named field in custom attribute");
                 fieldArgs.Add(nm, prop);
             }
             else if (tag == TypeSigTag.CUSTOM_ATTRIBUTE_PROPERTY)
             {
                 if (propertyArgs == null)
                     propertyArgs = new Map<string, CustomAttributeProperty>();
                 if (propertyArgs.ContainsKey(nm))
                     throw new PEException("duplicate named property in custom attribute");
                 propertyArgs.Add(nm, prop);
             }
             else
                 throw new PEException("invalid custom attribute");
         }
         FieldArgs = fieldArgs ?? Constants.EmptyNamedCustomAttributueProperties;
         PropertyArgs = propertyArgs ?? Constants.EmptyNamedCustomAttributueProperties;
     }
 }
Beispiel #11
0
        private bool ReadMethodDataSection(ReaderContext ctxt, BlobReader reader, Func<OpCode, Row, object> resolveRow)
        {
            reader.Align(4);
            var flags = (CorILMethodSect)reader.ReadByte();
            if ((flags & CorILMethodSect.EHTable) == 0)
                throw new PEException("unrecognised method data section");

            var isFat = (flags & CorILMethodSect.FatFormat) != 0;
            var count = default(uint);
            if (isFat)
            {
                var size = reader.ReadUInt24();
                if (size < 4 || (size - 4) % 24 != 0)
                    throw new InvalidOperationException("invalid method data section");
                count = (size - 4) / 24;
            }
            else
            {
                var size = (uint)reader.ReadByte();
                // NOTE: Looks live VB emits size without including the 4 byte header...
                if (size < 4 || (size - 4) % 12 != 0)
                    throw new InvalidOperationException("invalid method data section");
                var padding = reader.ReadUInt16();
                if (padding != 0)
                    throw new PEException("unexpected data");
                count = (size - 4) / 12;
            }

            for (var i = 0; i < count; i++)
            {
                var c = new ExceptionHandlingClause();
                c.Read(ctxt, reader, isFat, resolveRow);
                ExceptionHandlingClauses.Add(c);
            }

            return (flags & CorILMethodSect.MoreSects) != 0;
        }
Beispiel #12
0
        public void Read(ReaderContext ctxt, BlobReader reader, Func<OpCode, Row, object> resolveRow)
        {
            ExceptionHandlingClauses = new Seq<ExceptionHandlingClause>();

            var firstByte = reader.ReadByte();
            var formatKind = (CorILMethod)(firstByte & 0x3);
            var bodySize = default(uint);
            var more = default(bool);
            switch (formatKind)
            {
            case CorILMethod.TinyFormat:
                {
                    MaxStack = 8;
                    bodySize = (uint)(firstByte >> 2);
                    break;
                }
            case CorILMethod.FatFormat:
                {
                    var secondByte = reader.ReadByte();
                    var flags = (CorILMethod)(((ushort)(secondByte & 0x7) << 8) | (ushort)firstByte);
                    IsInitLocals = (flags & CorILMethod.InitLocals) != 0;
                    var headerSize = (secondByte >> 4) & 0x7;
                    if (headerSize != 3)
                        throw new PEException("unexpected method body header size");
                    MaxStack = (int)reader.ReadUInt16();
                    bodySize = reader.ReadUInt32();
                    LocalVarRef.Read(ctxt, reader);
                    LocalVarRef.ResolveIndexes(ctxt);
                    more = (flags & CorILMethod.MoreSects) != 0;
                    break;
                }
            default:
                throw new InvalidOperationException("invalid method body format");
            }

            if (bodySize > 0)
            {
                var beginOffset = reader.Offset;
                var endOffset = reader.Offset + bodySize;
                var n = 0;
                while (reader.Offset < endOffset)
                {
                    n++;
                    Instruction.Skip(reader);
                }
                reader.Offset = beginOffset;
                Instructions = new Instruction[n];
                for (var i = 0; i < n; i++)
                    Instructions[i].Read(ctxt, reader, beginOffset, resolveRow);
            }

            while (more)
                more = ReadMethodDataSection(ctxt, reader, resolveRow);
        }
Beispiel #13
0
        public void Read(ReaderContext ctxt, BlobReader reader, Func <OpCode, Row, object> resolveRow)
        {
            ExceptionHandlingClauses = new Seq <ExceptionHandlingClause>();

            var firstByte  = reader.ReadByte();
            var formatKind = (CorILMethod)(firstByte & 0x3);
            var bodySize   = default(uint);
            var more       = default(bool);

            switch (formatKind)
            {
            case CorILMethod.TinyFormat:
            {
                MaxStack = 8;
                bodySize = (uint)(firstByte >> 2);
                break;
            }

            case CorILMethod.FatFormat:
            {
                var secondByte = reader.ReadByte();
                var flags      = (CorILMethod)(((ushort)(secondByte & 0x7) << 8) | (ushort)firstByte);
                IsInitLocals = (flags & CorILMethod.InitLocals) != 0;
                var headerSize = (secondByte >> 4) & 0x7;
                if (headerSize != 3)
                {
                    throw new PEException("unexpected method body header size");
                }
                MaxStack = (int)reader.ReadUInt16();
                bodySize = reader.ReadUInt32();
                LocalVarRef.Read(ctxt, reader);
                LocalVarRef.ResolveIndexes(ctxt);
                more = (flags & CorILMethod.MoreSects) != 0;
                break;
            }

            default:
                throw new InvalidOperationException("invalid method body format");
            }

            if (bodySize > 0)
            {
                var beginOffset = reader.Offset;
                var endOffset   = reader.Offset + bodySize;
                var n           = 0;
                while (reader.Offset < endOffset)
                {
                    n++;
                    Instruction.Skip(reader);
                }
                reader.Offset = beginOffset;
                Instructions  = new Instruction[n];
                for (var i = 0; i < n; i++)
                {
                    Instructions[i].Read(ctxt, reader, beginOffset, resolveRow);
                }
            }

            while (more)
            {
                more = ReadMethodDataSection(ctxt, reader, resolveRow);
            }
        }
Beispiel #14
0
 public void Read(ReaderContext ctxt, BlobReader reader)
 {
     var actualCb = reader.ReadUInt32();
     if (actualCb != cb)
         throw new PEException("invalid CLIHeader.ActualCb");
     MajorRuntimeVersion = reader.ReadUInt16();
     MinorRuntimeVersion = reader.ReadUInt16();
     MetaData.Read(reader);
     Flags = (RuntimeFlags)reader.ReadUInt32();
     EntryPointToken = reader.ReadUInt32();
     Resources.Read(reader);
     StrongNameSignature.Read(reader);
     var actualCodeManagerTable = reader.ReadUInt64();
     if (actualCodeManagerTable != codeManagerTable)
         throw new PEException("invalid CLIHeader.CodeManagerTable");
     VtableFixups.Read(reader);
     var actualExportAddressTableJumps = reader.ReadUInt64();
     if (actualExportAddressTableJumps != exportAddressTableJumps)
         throw new PEException("invalid CLIHeader.ExportAddressTableJumps");
     var actualManagedNativeHeader = reader.ReadUInt64();
     if (actualManagedNativeHeader != managedNativeHeader)
         throw new PEException("invalid CLIHeader.ManagedNativeHeader");
 }
Beispiel #15
0
 public void Read(ReaderContext ctxt, BlobReader reader)
 {
     var actualSignature = reader.ReadUInt32();
     if (actualSignature != signature)
         throw new PEException("invalid MetadataHeader.Signature");
     MajorVersion = reader.ReadUInt16();
     MinorVersion = reader.ReadUInt16();
     var actualReserved = reader.ReadUInt32();
     if (actualReserved != reserved)
         throw new PEException("invalid MetadataHeader.Reserved");
     Version = reader.ReadUTF8SizedZeroPaddedString(4);
     var actualFlags = reader.ReadUInt16();
     if (actualFlags != flags)
         throw new PEException("invalid MetadataHeader.Flags");
     var numStreams = reader.ReadUInt16();
     StreamHeaders = new StreamHeader[numStreams];
     for (var i = 0; i < numStreams; i++)
         StreamHeaders[i].Read(ctxt, reader);
 }
Beispiel #16
0
 public void Read(ReaderContext ctxt, BlobReader reader)
 {
     VirtualAddress = reader.ReadUInt32();
     Size = reader.ReadUInt16();
     Type = (CorVtable)reader.ReadUInt16();
 }
Beispiel #17
0
 public override object ReadValue(BlobReader reader, Func<string, CustomAttributePropertyType> resolveType)
 {
     switch (Type)
     {
     case PrimitiveType.Boolean:
         return reader.ReadByte() == 0 ? false : true;
     case PrimitiveType.Char:
         return (char)reader.ReadUInt16();
     case PrimitiveType.Int8:
         return reader.ReadSByte();
     case PrimitiveType.Int16:
         return reader.ReadInt16();
     case PrimitiveType.Int32:
         return reader.ReadInt32();
     case PrimitiveType.Int64:
         return reader.ReadInt64();
     case PrimitiveType.UInt8:
         return reader.ReadByte();
     case PrimitiveType.UInt16:
         return reader.ReadUInt16();
     case PrimitiveType.UInt32:
         return reader.ReadUInt32();
     case PrimitiveType.UInt64:
         return reader.ReadUInt64();
     case PrimitiveType.IntNative:
     case PrimitiveType.UIntNative:
         throw new PEException("cannot read native integers");
     case PrimitiveType.Single:
         return reader.ReadSingle();
     case PrimitiveType.Double:
         return reader.ReadDouble();
     case PrimitiveType.String:
         return reader.ReadUTF8SizedString();
     case PrimitiveType.Type:
         return new TypeCustomAttributePropertyValue { Name = reader.ReadUTF8SizedString() };
     case PrimitiveType.Object:
     case PrimitiveType.TypedRef:
     case PrimitiveType.Void:
         throw new PEException("invalid type tag in custom attribute");
     default:
         throw new ArgumentOutOfRangeException();
     }
 }