コード例 #1
0
        /// <summary>
        /// Deattach from the process and do a cleanup.
        /// </summary>
        /// <param name="hModule">Pointer to a memory module.</param>
        private void MemoryFreeLibrary(IntPtr hModule)
        {
            if (hModule == IntPtr.Zero)
            {
                return;
            }

            MEMORY_MODULE *memory_module = (MEMORY_MODULE *)hModule;

            if (memory_module != null)
            {
                if (memory_module->initialized != 0)
                {
                    this.CallDllEntryPoint(memory_module, WinNT.DLL_PROCESS_DETACH);
                }

                if (memory_module->modules != null)
                {
                    // free previously opened libraries
                    for (int index = 0; index < memory_module->numModules; index++)
                    {
                        if (memory_module->modules[index] != IntPtr.Zero)
                        {
                            WinBase.FreeLibrary(memory_module->modules[index]);
                        }
                    }

                    Marshal.FreeHGlobal((IntPtr)memory_module->modules);
                }

                if ((IntPtr)memory_module->codeBase != IntPtr.Zero)
                {
                    // release memory of library
                    WinBase.VirtualFree((IntPtr)memory_module->codeBase, 0, WinNT.MEM_RELEASE);
                }

                Marshal.FreeHGlobal((IntPtr)memory_module);
            }
        }
コード例 #2
0
        /// <summary>
        /// Marks memory pages depending on section headers and release sections that are marked as "discardable".
        /// </summary>
        /// <param name="memory_module">Pointer to a memory module.</param>
        private void FinalizeSections(MEMORY_MODULE *memory_module)
        {
            WinNT.IMAGE_SECTION_HEADER *section = WinNT.IMAGE_FIRST_SECTION(memory_module->headers);;

            ushort number_of_sections;
            uint   size_of_initialized_data;
            uint   size_of_uninitialized_data;

            long image_offset = 0;

            if (Environment.Is64BitProcess)
            {
                WinNT.IMAGE_NT_HEADERS64 *headers = (WinNT.IMAGE_NT_HEADERS64 *)memory_module->headers;
                number_of_sections         = headers->FileHeader.NumberOfSections;
                size_of_initialized_data   = headers->OptionalHeader.SizeOfInitializedData;
                size_of_uninitialized_data = headers->OptionalHeader.SizeOfUninitializedData;

                image_offset = (long)((ulong)headers->OptionalHeader.ImageBase & 0xffffffff00000000);
            }
            else
            {
                WinNT.IMAGE_NT_HEADERS32 *headers = (WinNT.IMAGE_NT_HEADERS32 *)memory_module->headers;
                number_of_sections         = headers->FileHeader.NumberOfSections;
                size_of_initialized_data   = headers->OptionalHeader.SizeOfInitializedData;
                size_of_uninitialized_data = headers->OptionalHeader.SizeOfUninitializedData;
            }

            for (int i = 0; i < number_of_sections; i++, section++)
            {
                uint protect, oldProtect, rawDataSize;
                uint executable = Convert.ToUInt32((section->Characteristics & WinNT.IMAGE_SCN_MEM_EXECUTE) != 0);
                uint readable   = Convert.ToUInt32((section->Characteristics & WinNT.IMAGE_SCN_MEM_READ) != 0);
                uint writeable  = Convert.ToUInt32((section->Characteristics & WinNT.IMAGE_SCN_MEM_WRITE) != 0);

                if ((section->Characteristics & WinNT.IMAGE_SCN_MEM_DISCARDABLE) != 0)
                {
                    // section is not needed any more and can safely be freed
                    WinBase.VirtualFree((IntPtr)(void *)((long)section->PhysicalAddress | (long)image_offset), section->SizeOfRawData, WinNT.MEM_DECOMMIT);
                    continue;
                }

                protect = _protectionFlags[executable, readable, writeable];

                if ((section->Characteristics & WinNT.IMAGE_SCN_MEM_NOT_CACHED) != 0)
                {
                    protect |= WinNT.PAGE_NOCACHE;
                }

                // determine size of region
                rawDataSize = section->SizeOfRawData;

                if (rawDataSize == 0)
                {
                    if ((section->Characteristics & WinNT.IMAGE_SCN_CNT_INITIALIZED_DATA) != 0)
                    {
                        rawDataSize = size_of_initialized_data;
                    }

                    else if ((section->Characteristics & WinNT.IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
                    {
                        rawDataSize = size_of_uninitialized_data;
                    }
                }

                if (rawDataSize > 0)
                {
                    // change memory access flags
                    WinBase.VirtualProtect((IntPtr)(void *)((long)section->PhysicalAddress | (long)image_offset), rawDataSize, protect, &oldProtect);
                }
            }
        }