コード例 #1
0
        private static bool FinalizeSection(MEMORYMODULE module, SECTIONFINALIZEDATA sectionData)
        {
            uint protect, oldProtect;
            bool executable;
            bool readable;
            bool writeable;

            if (sectionData.size == null)
                return true;

            if ((sectionData.characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)
            {
                // section is not needed any more and can safely be freed
                if (sectionData.address == sectionData.alignedAddress && (sectionData.last || (WIN64 ? ((IMAGE_NT_HEADERS64*)module.headers)->OptionalHeader.SectionAlignment : ((IMAGE_NT_HEADERS32*)module.headers)->OptionalHeader.SectionAlignment) == module.pageSize || ((ulong)sectionData.size % module.pageSize) == 0))
                    // Only allowed to decommit whole pages
                    module.free(sectionData.address, sectionData.size, MEM_DECOMMIT, module.userdata);
                return true;
            }

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

            // change memory access flags
            if (!VirtualProtect(sectionData.address, sectionData.size, protect, &oldProtect))
                return false;

            return true;
        }
コード例 #2
0
ファイル: MemoryModuleC.cs プロジェクト: wwh1004/MemoryModule
        private static bool FinalizeSections(MEMORYMODULE module)
        {
            int   i;
            void *imageOffset;
            IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(module.headers);

            // "PhysicalAddress" might have been truncated to 32bit above, expand to
            // 64bits again.
            imageOffset = WIN64 ? (void *)(((IMAGE_NT_HEADERS64 *)module.headers)->OptionalHeader.ImageBase & 0xffffffff00000000) : null;
            SECTIONFINALIZEDATA sectionData = new SECTIONFINALIZEDATA {
                address         = (void *)(section->PhysicalAddress | (ulong)imageOffset),
                size            = GetRealSectionSize(module, section),
                characteristics = section->Characteristics,
                last            = false
            };

            sectionData.alignedAddress = AlignAddressDown(sectionData.address, (void *)module.pageSize);
            section++;

            // loop through all sections and change access flags
            for (i = 1; i < (WIN64 ? ((IMAGE_NT_HEADERS64 *)module.headers)->FileHeader.NumberOfSections : ((IMAGE_NT_HEADERS32 *)module.headers)->FileHeader.NumberOfSections); i++, section++)
            {
                void *sectionAddress = (void *)(section->PhysicalAddress | (ulong)imageOffset);
                void *alignedAddress = AlignAddressDown(sectionAddress, (void *)module.pageSize);
                void *sectionSize    = GetRealSectionSize(module, 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 || (ulong)sectionData.address + (ulong)sectionData.size > (ulong)alignedAddress)
                {
                    // Section shares page with previous
                    if ((section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0 || (sectionData.characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0)
                    {
                        sectionData.characteristics = (sectionData.characteristics | section->Characteristics) & ~IMAGE_SCN_MEM_DISCARDABLE;
                    }
                    else
                    {
                        sectionData.characteristics |= section->Characteristics;
                    }
                    sectionData.size = (void *)((ulong)sectionAddress + (ulong)sectionSize - (ulong)sectionData.address);
                    continue;
                }

                if (!FinalizeSection(module, sectionData))
                {
                    return(false);
                }
                sectionData.address         = sectionAddress;
                sectionData.alignedAddress  = alignedAddress;
                sectionData.size            = sectionSize;
                sectionData.characteristics = section->Characteristics;
            }
            sectionData.last = true;
            if (!FinalizeSection(module, sectionData))
            {
                return(false);
            }
            return(true);
        }