Пример #1
0
        private void FinalizeSections()
        {
            IMAGE_SECTION_HEADER *section = Win.IMAGE_FIRST_SECTION(_headers);

#if WIN64
            UIntPtrT imageOffset = ((UIntPtrT)_headers->OptionalHeader.ImageBase & 0xffffffff00000000);
#elif WIN32
            UIntPtrT imageOffset = 0;
#endif


            SectionFinalizeData sectionData = new SectionFinalizeData();
            sectionData.Address         = (void *)(section->PhysicalAddress | imageOffset);
            sectionData.AlignedAddress  = AlignAddressDown(sectionData.Address, _pageSize);
            sectionData.Size            = GetRealSectionSize(section);
            sectionData.Characteristics = section->Characteristics;
            sectionData.Last            = false;
            section++;

            // loop through all sections and change access flags
            for (int i = 1; i < _headers->FileHeader.NumberOfSections; i++, section++)
            {
                void *sectionAddress = (void *)(section->PhysicalAddress | imageOffset);
                void *alignedAddress = AlignAddressDown(sectionAddress, _pageSize);
                SizeT sectionSize    = GetRealSectionSize(section);
                // Combine access flags of all sections that share a page
                // TODO(fancycode): We currently share flags of a trailing large section
                //   with the page of a first small section. This should be optimized.
                if (sectionData.AlignedAddress == alignedAddress || (UIntPtrT)sectionData.Address + sectionData.Size > (UIntPtrT)alignedAddress)
                {
                    // Section shares page with previous
                    if ((section->Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0 || (sectionData.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0)
                    {
                        sectionData.Characteristics = (sectionData.Characteristics | section->Characteristics) & ~Win.IMAGE_SCN_MEM_DISCARDABLE;
                    }
                    else
                    {
                        sectionData.Characteristics |= section->Characteristics;
                    }
                    sectionData.Size = (((UIntPtrT)sectionAddress) + (sectionSize)) - (UIntPtrT)sectionData.Address;
                    continue;
                }

                FinalizeSection(sectionData);

                sectionData.Address         = sectionAddress;
                sectionData.AlignedAddress  = alignedAddress;
                sectionData.Size            = sectionSize;
                sectionData.Characteristics = section->Characteristics;
            }
            sectionData.Last = true;
            FinalizeSection(sectionData);
        }
Пример #2
0
    static void FinalizeSections(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders, uint PageSize)
    {
        UIntPtr imageOffset              = (Is64BitProcess ? (UIntPtr)(unchecked ((ulong)pCode.ToInt64()) & 0xffffffff00000000) : UIntPtr.Zero);
        IntPtr  pSection                 = Win.IMAGE_FIRST_SECTION(pNTHeaders, OrgNTHeaders.FileHeader.SizeOfOptionalHeader);
        IMAGE_SECTION_HEADER Section     = PtrRead <IMAGE_SECTION_HEADER>(pSection);
        SectionFinalizeData  sectionData = new SectionFinalizeData();

        sectionData.Address         = PtrBitOr(PtrAdd((IntPtr)0, Section.PhysicalAddress), imageOffset);
        sectionData.AlignedAddress  = PtrAlignDown(sectionData.Address, (UIntPtr)PageSize);
        sectionData.Size            = GetRealSectionSize(ref Section, ref OrgNTHeaders);
        sectionData.Characteristics = Section.Characteristics;
        sectionData.Last            = false;
        pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER);

        // loop through all sections and change access flags
        for (int i = 1; i < OrgNTHeaders.FileHeader.NumberOfSections; i++, pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER))
        {
            Section = PtrRead <IMAGE_SECTION_HEADER>(pSection);
            IntPtr sectionAddress = PtrBitOr(PtrAdd((IntPtr)0, Section.PhysicalAddress), imageOffset);
            IntPtr alignedAddress = PtrAlignDown(sectionAddress, (UIntPtr)PageSize);
            IntPtr sectionSize    = GetRealSectionSize(ref Section, ref OrgNTHeaders);

            // Combine access flags of all sections that share a page
            // TODO(fancycode): We currently share flags of a trailing large section with the page of a first small section. This should be optimized.
            IntPtr a = PtrAdd(sectionData.Address, sectionData.Size);
            ulong  b = unchecked ((ulong)a.ToInt64()), c = unchecked ((ulong)alignedAddress);

            if (sectionData.AlignedAddress == alignedAddress || unchecked ((ulong)PtrAdd(sectionData.Address, sectionData.Size).ToInt64()) > unchecked ((ulong)alignedAddress))
            {
                // Section shares page with previous
                if ((Section.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0 || (sectionData.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0)
                {
                    sectionData.Characteristics = (sectionData.Characteristics | Section.Characteristics) & ~Win.IMAGE_SCN_MEM_DISCARDABLE;
                }
                else
                {
                    sectionData.Characteristics |= Section.Characteristics;
                }
                sectionData.Size = PtrSub(PtrAdd(sectionAddress, sectionSize), sectionData.Address);
                continue;
            }

            FinalizeSection(sectionData, PageSize, OrgNTHeaders.OptionalHeader.SectionAlignment);

            sectionData.Address         = sectionAddress;
            sectionData.AlignedAddress  = alignedAddress;
            sectionData.Size            = sectionSize;
            sectionData.Characteristics = Section.Characteristics;
        }
        sectionData.Last = true;
        FinalizeSection(sectionData, PageSize, OrgNTHeaders.OptionalHeader.SectionAlignment);
    }
Пример #3
0
        private void FinalizeSection(SectionFinalizeData sectionData)
        {
            uint protect, oldProtect;
            int  executable;
            int  readable;
            int  writeable;

            if (sectionData.Size == 0)
            {
                return;
            }

            if ((sectionData.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) > 0)
            {
                // section is not needed any more and can safely be freed
                if (sectionData.Address == sectionData.AlignedAddress &&
                    (sectionData.Last ||
                     _headers->OptionalHeader.SectionAlignment == _pageSize ||
                     (sectionData.Size % _pageSize) == 0)
                    )
                {
                    // Only allowed to decommit whole pages
                    Win.VirtualFree(sectionData.Address, sectionData.Size, AllocationType.DECOMMIT);
                }
                return;
            }

            // determine protection flags based on characteristics
            executable = (sectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_EXECUTE) != 0 ? 1 : 0;
            readable   = (sectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_READ) != 0 ? 1 : 0;
            writeable  = (sectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_WRITE) != 0 ? 1 : 0;
            protect    = (uint)ProtectionFlags[executable, readable, writeable];
            if ((sectionData.Characteristics & Win.IMAGE_SCN_MEM_NOT_CACHED) > 0)
            {
                protect |= Win.PAGE_NOCACHE;
            }

            // change memory access flags
            if (!Win.VirtualProtect(sectionData.Address, sectionData.Size, protect, out oldProtect))
            {
                throw new NativeDllLoadException("Error protecting memory page");
            }
        }
Пример #4
0
    static void FinalizeSection(SectionFinalizeData SectionData, uint PageSize, uint SectionAlignment)
    {
        if (SectionData.Size == IntPtr.Zero)
        {
            return;
        }

        if ((SectionData.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) > 0)
        {
            // section is not needed any more and can safely be freed
            if (SectionData.Address == SectionData.AlignedAddress &&
                (SectionData.Last ||
                 SectionAlignment == PageSize ||
                 (unchecked ((ulong)SectionData.Size.ToInt64()) % PageSize) == 0)
                )
            {
                // Only allowed to decommit whole pages
                Win.VirtualFree(SectionData.Address, SectionData.Size, AllocationType.DECOMMIT);
            }
            return;
        }

        // determine protection flags based on characteristics
        int  readable   = (SectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_READ) != 0 ? 1 : 0;
        int  writeable  = (SectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_WRITE) != 0 ? 1 : 0;
        int  executable = (SectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_EXECUTE) != 0 ? 1 : 0;
        uint protect    = (uint)ProtectionFlags[executable, readable, writeable];

        if ((SectionData.Characteristics & Win.IMAGE_SCN_MEM_NOT_CACHED) > 0)
        {
            protect |= Win.PAGE_NOCACHE;
        }

        // change memory access flags
        uint oldProtect;

        if (!Win.VirtualProtect(SectionData.Address, SectionData.Size, protect, out oldProtect))
        {
            throw new DllException("Error protecting memory page");
        }
    }