internal static void MemoryFreeLibrary(MEMORYMODULE mod) { MEMORYMODULE module = mod; if (module == null) return; if (module.initialized) { // notify library about detaching from process DllEntryProc DllEntry = (DllEntryProc)Marshal.GetDelegateForFunctionPointer((IntPtr)(module.codeBase + (WIN64 ? ((IMAGE_NT_HEADERS64*)module.headers)->OptionalHeader.AddressOfEntryPoint : ((IMAGE_NT_HEADERS32*)module.headers)->OptionalHeader.AddressOfEntryPoint)), typeof(DllEntryProc)); DllEntry(module.codeBase, DLL_PROCESS_DETACH, null); } if (module.modules != null) { // free previously opened libraries int i; for (i = 0; i < module.numModules; i++) if ((void*)((IntPtr*)module.modules)[i] != null) module.freeLibrary((void*)((IntPtr*)module.modules)[i], module.userdata); free(module.modules); } if (module.codeBase != null) { // release memory of library module.free(module.codeBase, null, MEM_RELEASE, module.userdata); } if (WIN64) FreePointerList(module.blockedMemory, module.free, module.userdata); }
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; }