/// <summary>
 /// Constructor
 /// </summary>
 /// <param name="reader">PE file reader pointing to the start of this section</param>
 /// <param name="totalSize">Total size of this optional header (from the file header)</param>
 /// <param name="verify">Verify section</param>
 /// <exception cref="BadImageFormatException">Thrown if verification fails</exception>
 public ImageOptionalHeader64(IImageStream reader, uint totalSize, bool verify)
 {
     if (totalSize < 0x70)
     {
         throw new BadImageFormatException("Invalid optional header size");
     }
     if (verify && reader.Position + totalSize > reader.Length)
     {
         throw new BadImageFormatException("Invalid optional header size");
     }
     SetStartOffset(reader);
     this.magic = reader.ReadUInt16();
     this.majorLinkerVersion      = reader.ReadByte();
     this.minorLinkerVersion      = reader.ReadByte();
     this.sizeOfCode              = reader.ReadUInt32();
     this.sizeOfInitializedData   = reader.ReadUInt32();
     this.sizeOfUninitializedData = reader.ReadUInt32();
     this.addressOfEntryPoint     = (RVA)reader.ReadUInt32();
     this.baseOfCode              = (RVA)reader.ReadUInt32();
     this.imageBase                   = reader.ReadUInt64();
     this.sectionAlignment            = reader.ReadUInt32();
     this.fileAlignment               = reader.ReadUInt32();
     this.majorOperatingSystemVersion = reader.ReadUInt16();
     this.minorOperatingSystemVersion = reader.ReadUInt16();
     this.majorImageVersion           = reader.ReadUInt16();
     this.minorImageVersion           = reader.ReadUInt16();
     this.majorSubsystemVersion       = reader.ReadUInt16();
     this.minorSubsystemVersion       = reader.ReadUInt16();
     this.win32VersionValue           = reader.ReadUInt32();
     this.sizeOfImage                 = reader.ReadUInt32();
     this.sizeOfHeaders               = reader.ReadUInt32();
     this.checkSum            = reader.ReadUInt32();
     this.subsystem           = (Subsystem)reader.ReadUInt16();
     this.dllCharacteristics  = (DllCharacteristics)reader.ReadUInt16();
     this.sizeOfStackReserve  = reader.ReadUInt64();
     this.sizeOfStackCommit   = reader.ReadUInt64();
     this.sizeOfHeapReserve   = reader.ReadUInt64();
     this.sizeOfHeapCommit    = reader.ReadUInt64();
     this.loaderFlags         = reader.ReadUInt32();
     this.numberOfRvaAndSizes = reader.ReadUInt32();
     for (int i = 0; i < dataDirectories.Length; i++)
     {
         uint len = (uint)(reader.Position - startOffset);
         if (len + 8 <= totalSize)
         {
             dataDirectories[i] = new ImageDataDirectory(reader, verify);
         }
         else
         {
             dataDirectories[i] = new ImageDataDirectory();
         }
     }
     reader.Position = (long)startOffset + totalSize;
     SetEndoffset(reader);
 }
Esempio n. 2
0
 ulong ReadPtr(long pos)
 {
     reader.Position = pos;
     return(is32bit ? reader.ReadUInt32() : reader.ReadUInt64());
 }
Esempio n. 3
0
        object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgType)
        {
            if (!recursionCounter.Increment())
            {
                throw new CABlobParserException("Too much recursion");
            }

            object result;

            switch (etype)
            {
            case SerializationType.Boolean:
                realArgType = module.CorLibTypes.Boolean;
                result      = reader.ReadByte() != 0;
                break;

            case SerializationType.Char:
                realArgType = module.CorLibTypes.Char;
                result      = (char)reader.ReadUInt16();
                break;

            case SerializationType.I1:
                realArgType = module.CorLibTypes.SByte;
                result      = reader.ReadSByte();
                break;

            case SerializationType.U1:
                realArgType = module.CorLibTypes.Byte;
                result      = reader.ReadByte();
                break;

            case SerializationType.I2:
                realArgType = module.CorLibTypes.Int16;
                result      = reader.ReadInt16();
                break;

            case SerializationType.U2:
                realArgType = module.CorLibTypes.UInt16;
                result      = reader.ReadUInt16();
                break;

            case SerializationType.I4:
                realArgType = module.CorLibTypes.Int32;
                result      = reader.ReadInt32();
                break;

            case SerializationType.U4:
                realArgType = module.CorLibTypes.UInt32;
                result      = reader.ReadUInt32();
                break;

            case SerializationType.I8:
                realArgType = module.CorLibTypes.Int64;
                result      = reader.ReadInt64();
                break;

            case SerializationType.U8:
                realArgType = module.CorLibTypes.UInt64;
                result      = reader.ReadUInt64();
                break;

            case SerializationType.R4:
                realArgType = module.CorLibTypes.Single;
                result      = reader.ReadSingle();
                break;

            case SerializationType.R8:
                realArgType = module.CorLibTypes.Double;
                result      = reader.ReadDouble();
                break;

            case SerializationType.String:
                realArgType = module.CorLibTypes.String;
                result      = ReadUTF8String();
                break;

            // It's ET.ValueType if it's eg. a ctor enum arg type
            case (SerializationType)ElementType.ValueType:
                if (argType == null)
                {
                    throw new CABlobParserException("Invalid element type");
                }
                realArgType = argType;
                result      = ReadEnumValue(GetEnumUnderlyingType(argType));
                break;

            // It's ET.Object if it's a ctor object arg type
            case (SerializationType)ElementType.Object:
            case SerializationType.TaggedObject:
                realArgType = ReadFieldOrPropType();
                var arraySig = realArgType as SZArraySig;
                if (arraySig != null)
                {
                    result = ReadArrayArgument(arraySig);
                }
                else
                {
                    TypeSig tmpType;
                    result = ReadValue((SerializationType)realArgType.ElementType, realArgType, out tmpType);
                }
                break;

            // It's ET.Class if it's eg. a ctor System.Type arg type
            case (SerializationType)ElementType.Class:
                var tdr = argType as TypeDefOrRefSig;
                if (tdr != null && tdr.DefinitionAssembly.IsCorLib() && tdr.Namespace == "System")
                {
                    if (tdr.TypeName == "Type")
                    {
                        result = ReadValue(SerializationType.Type, tdr, out realArgType);
                        break;
                    }
                    if (tdr.TypeName == "String")
                    {
                        result = ReadValue(SerializationType.String, tdr, out realArgType);
                        break;
                    }
                    if (tdr.TypeName == "Object")
                    {
                        result = ReadValue(SerializationType.TaggedObject, tdr, out realArgType);
                        break;
                    }
                }

                // Assume it's an enum that couldn't be resolved
                realArgType = argType;
                return(ReadEnumValue(null));

            case SerializationType.Type:
                realArgType = argType;
                result      = ReadType();
                break;

            case SerializationType.Enum:
                realArgType = ReadType();
                result      = ReadEnumValue(GetEnumUnderlyingType(realArgType));
                break;

            default:
                throw new CABlobParserException("Invalid element type");
            }

            recursionCounter.Decrement();
            return(result);
        }
Esempio n. 4
0
        public static bool TryReadNumeric(IImageStream stream, long end, out object value)
        {
            value = null;
            if (stream.Position + 2 > end)
            {
                return(false);
            }
            var numLeaf = (NumericLeaf)stream.ReadUInt16();

            if (numLeaf < NumericLeaf.LF_NUMERIC)
            {
                value = (short)numLeaf;
                return(true);
            }

            switch (numLeaf)
            {
            case NumericLeaf.LF_CHAR:
                if (stream.Position > end)
                {
                    return(false);
                }
                value = stream.ReadSByte();
                return(true);

            case NumericLeaf.LF_SHORT:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                value = stream.ReadInt16();
                return(true);

            case NumericLeaf.LF_USHORT:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt16();
                return(true);

            case NumericLeaf.LF_LONG:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadInt32();
                return(true);

            case NumericLeaf.LF_ULONG:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt32();
                return(true);

            case NumericLeaf.LF_REAL32:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadSingle();
                return(true);

            case NumericLeaf.LF_REAL64:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadDouble();
                return(true);

            case NumericLeaf.LF_QUADWORD:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadInt64();
                return(true);

            case NumericLeaf.LF_UQUADWORD:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt64();
                return(true);

            case NumericLeaf.LF_VARSTRING:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                int varStrLen = stream.ReadUInt16();
                if (stream.Position + varStrLen > end)
                {
                    return(false);
                }
                value = Encoding.UTF8.GetString(stream.ReadBytes(varStrLen));
                return(true);

            case NumericLeaf.LF_VARIANT:
                if (stream.Position + 0x10 > end)
                {
                    return(false);
                }
                int  v0    = stream.ReadInt32();
                int  v1    = stream.ReadInt32();
                int  v2    = stream.ReadInt32();
                int  v3    = stream.ReadInt32();
                byte scale = (byte)(v0 >> 16);
                if (scale <= 28)
                {
                    value = new decimal(v2, v3, v1, v0 < 0, scale);
                }
                else
                {
                    value = null;
                }
                return(true);

            default:
                return(false);
            }
        }
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="reader">PE file reader pointing to the start of this section</param>
		/// <param name="totalSize">Total size of this optional header (from the file header)</param>
		/// <param name="verify">Verify section</param>
		/// <exception cref="BadImageFormatException">Thrown if verification fails</exception>
		public ImageOptionalHeader64(IImageStream reader, uint totalSize, bool verify) {
			if (totalSize < 0x70)
				throw new BadImageFormatException("Invalid optional header size");
			if (verify && reader.Position + totalSize > reader.Length)
				throw new BadImageFormatException("Invalid optional header size");
			SetStartOffset(reader);
			this.magic = reader.ReadUInt16();
			this.majorLinkerVersion = reader.ReadByte();
			this.minorLinkerVersion = reader.ReadByte();
			this.sizeOfCode = reader.ReadUInt32();
			this.sizeOfInitializedData = reader.ReadUInt32();
			this.sizeOfUninitializedData = reader.ReadUInt32();
			this.addressOfEntryPoint = (RVA)reader.ReadUInt32();
			this.baseOfCode = (RVA)reader.ReadUInt32();
			this.imageBase = reader.ReadUInt64();
			this.sectionAlignment = reader.ReadUInt32();
			this.fileAlignment = reader.ReadUInt32();
			this.majorOperatingSystemVersion = reader.ReadUInt16();
			this.minorOperatingSystemVersion = reader.ReadUInt16();
			this.majorImageVersion = reader.ReadUInt16();
			this.minorImageVersion = reader.ReadUInt16();
			this.majorSubsystemVersion = reader.ReadUInt16();
			this.minorSubsystemVersion = reader.ReadUInt16();
			this.win32VersionValue = reader.ReadUInt32();
			this.sizeOfImage = reader.ReadUInt32();
			this.sizeOfHeaders = reader.ReadUInt32();
			this.checkSum = reader.ReadUInt32();
			this.subsystem = (Subsystem)reader.ReadUInt16();
			this.dllCharacteristics = (DllCharacteristics)reader.ReadUInt16();
			this.sizeOfStackReserve = reader.ReadUInt64();
			this.sizeOfStackCommit = reader.ReadUInt64();
			this.sizeOfHeapReserve = reader.ReadUInt64();
			this.sizeOfHeapCommit = reader.ReadUInt64();
			this.loaderFlags = reader.ReadUInt32();
			this.numberOfRvaAndSizes = reader.ReadUInt32();
			for (int i = 0; i < dataDirectories.Length; i++) {
				uint len = (uint)(reader.Position - startOffset);
				if (len + 8 <= totalSize)
					dataDirectories[i] = new ImageDataDirectory(reader, verify);
				else
					dataDirectories[i] = new ImageDataDirectory();
			}
			reader.Position = (long)startOffset + totalSize;
			SetEndoffset(reader);
		}
Esempio n. 6
0
        bool ReadCore(out TypeSig type, out object value)
        {
            if (!recursionCounter.Increment())
            {
                type  = null;
                value = null;
                return(false);
            }

            bool          res;
            ITypeDefOrRef tdr;
            UTF8String    ns, name;
            var           et = (ElementType)reader.ReadByte();

            switch (et)
            {
            case ElementType.Boolean:
                type  = module.CorLibTypes.Boolean;
                value = reader.ReadBoolean();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.Char:
                type  = module.CorLibTypes.Char;
                value = (char)reader.ReadUInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I1:
                type  = module.CorLibTypes.SByte;
                value = reader.ReadSByte();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U1:
                type  = module.CorLibTypes.Byte;
                value = reader.ReadByte();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I2:
                type  = module.CorLibTypes.Int16;
                value = reader.ReadInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U2:
                type  = module.CorLibTypes.UInt16;
                value = reader.ReadUInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I4:
                type  = module.CorLibTypes.Int32;
                value = reader.ReadInt32();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U4:
                type  = module.CorLibTypes.UInt32;
                value = reader.ReadUInt32();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I8:
                type  = module.CorLibTypes.Int64;
                value = reader.ReadInt64();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U8:
                type  = module.CorLibTypes.UInt64;
                value = reader.ReadUInt64();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.R4:
                type  = module.CorLibTypes.Single;
                value = reader.ReadSingle();
                res   = true;
                break;

            case ElementType.R8:
                type  = module.CorLibTypes.Double;
                value = reader.ReadDouble();
                res   = true;
                break;

            case ElementType.String:
                type  = module.CorLibTypes.String;
                value = ReadString();
                res   = true;
                break;

            case ElementType.Ptr:
                res = Read(out type, out value);
                if (res)
                {
                    type = new PtrSig(type);
                }
                break;

            case ElementType.ByRef:
                res = Read(out type, out value);
                if (res)
                {
                    type = new ByRefSig(type);
                }
                break;

            case ElementType.Object:
                type  = module.CorLibTypes.Object;
                value = null;
                res   = true;
                break;

            case ElementType.ValueType:
                tdr   = ReadTypeDefOrRef();
                type  = tdr.ToTypeSig();
                value = null;
                if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib())
                {
                    if (name == stringDecimal)
                    {
                        if (reader.Length - reader.Position != 13)
                        {
                            goto default;
                        }
                        try {
                            byte b = reader.ReadByte();
                            value = new Decimal(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), (b & 0x80) != 0, (byte)(b & 0x7F));
                        }
                        catch {
                            goto default;
                        }
                    }
                    else if (name == stringDateTime)
                    {
                        if (reader.Length - reader.Position != 8)
                        {
                            goto default;
                        }
                        try {
                            value = new DateTime(reader.ReadInt64());
                        }
                        catch {
                            goto default;
                        }
                    }
                }
                if (value == null && reader.Position != reader.Length)
                {
                    value = reader.ReadRemainingBytes();
                }
                res = true;
                break;

            case ElementType.Class:
                type  = new ClassSig(ReadTypeDefOrRef());
                value = reader.Position == reader.Length ? null : reader.ReadRemainingBytes();
                res   = true;
                break;

            case ElementType.CModReqd:
                tdr = ReadTypeDefOrRef();
                res = Read(out type, out value);
                if (res)
                {
                    type = new CModReqdSig(tdr, type);
                }
                break;

            case ElementType.CModOpt:
                tdr = ReadTypeDefOrRef();
                res = Read(out type, out value);
                if (res)
                {
                    type = new CModOptSig(tdr, type);
                }
                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:
            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:
                Debug.Fail("Unsupported element type in LocalConstant sig blob: " + et.ToString());
                res   = false;
                type  = null;
                value = null;
                break;
            }

            recursionCounter.Decrement();
            return(res);
        }