/// <summary>
        /// Create a Optional header from file
        /// </summary>
        /// <param name="reader">the reader</param>
        /// <param name="peHeader">the previous PE header</param>
        public OptionalHeader(Reader reader, PE_Header peHeader)
        {
            ///
            /// init header
            ///

            this.reader = reader;

            this.entries = new List <Entry>();

            this.peHeader = peHeader;

            this.is32Bit = this.peHeader.Architecture.value == Machines.INTEL386;

            headerBaseAddress = this.peHeader.headerBaseAddress + this.peHeader.export().Count - HeaderSymbols.PE_HEADER.Length;

            setupStruct();

            ///
            /// init values
            ///

            foreach (var item in entries)
            {
                item.readValue(this.reader);
            }

            // now the header is dynamic (is32bit)

            int sizeTmp = headerBaseAddress;

            entries.ForEach(e => sizeTmp += ((int)e.getEntrySize()) / 8);

            this.endOfHeader = sizeTmp;
        }
        /// <summary>
        /// Create a Optional header from memory
        /// </summary>
        /// <param name="peHeader">the previous PE header</param>
        public OptionalHeader(PE_Header peHeader)
        {
            ///
            /// init header
            ///

            this.entries = new List <Entry>();

            this.peHeader = peHeader;

            // TODO : improve 32 bit detection
            this.is32Bit = this.peHeader.Architecture.value == Machines.INTEL386;

            headerBaseAddress = this.peHeader.headerBaseAddress + this.peHeader.export().Count - HeaderSymbols.PE_HEADER.Length;

            setupStruct();

            ///
            /// init values
            ///

            // 32 bit by default
            this.Magic.setValue(MagicNumber.PE32);

            // linker indicate info about compiler
            // so I just fill random value
            this.MajorLinkerVersion.setValue(1);
            this.MinorLinkerVersion.setValue(0);

            // will be set by the user depending of its actions
            this.SizeOfCode.setValue(0);
            this.SizeOfInitializedData.setValue(0);
            this.SizeOfUninitializedData.setValue(0);
            this.AddressOfEntryPoint.setValue(0);
            this.BaseOfCode.setValue(0);

            // BaseOfData is not in x64
            if (this.is32Bit)
            {
                this.BaseOfData.setValue(0);
            }

            // default image base
            this.ImageBase.setValue(0x00010000);

            // will be set by the user depending of its actions
            this.SectionAlignment.setValue(0);
            this.FileAlignment.setValue(0);

            // default versions (discontinue)
            this.MajorOSVersion.setValue(4);
            this.MinorOSVersion.setValue(0);
            this.MajorImageVersion.setValue(0);
            this.MinorImageVersion.setValue(0);
            this.MajorSubsystemVersion.setValue(6);
            this.MinorSubsystemVersion.setValue(0);
            this.Win32VersionValue.setValue(0);

            // will be set by the user depending of its actions
            this.SizeOfImage.setValue(0);

            // will be written after
            this.SizeOfHeaders.setValue(0);

            // useless unless you create a driver
            this.Checksum.setValue(0);

            // default windows app
            this.peSubSystem.setValue(SubSystem.WINDOWS_GUI);

            // default (ASLR + DEP + TERMINAL_SERVER_AWARE)
            int characteristics = (int)DllCharacteristics.DYNAMIC_BASE + (int)DllCharacteristics.NX_COMPAT
                                  + (int)DllCharacteristics.TERMINAL_SERVER_AWARE;

            this.DLLCharacteristics.setValue(characteristics);

            // defaults
            this.SizeOfStackReserve.setValue(0x100000);
            this.SizeOfStackCommit.setValue(0x1000);
            this.SizeOfHeapReserve.setValue(0x100000);
            this.SizeOfHeapCommit.setValue(0x1000);

            // "Reserved, must be zero", probably driver stuff
            this.LoaderFlags.setValue(0);

            // in general its always 16 but, the user can decide
            this.NumberOfRvaAndSizes.setValue(16);

            // now the header is dynamic (is32bit)
            int sizeTmp = headerBaseAddress;

            entries.ForEach(e => sizeTmp += ((int)e.getEntrySize()) / 8);

            this.endOfHeader = sizeTmp;
        }