void MemoryFreeLibrary(HMEMORYMODULE mod) { PMEMORYMODULE module = (PMEMORYMODULE)mod; if (module == NULL) { return; } if (module->initialized) { // notify library about detaching from process DllEntryProc DllEntry = (DllEntryProc)(LPVOID)(module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint); (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0); } if (module->modules != NULL) { // free previously opened libraries int i; for (i=0; i<module->numModules; i++) { if (module->modules[i] != NULL) { module->freeLibrary(module->modules[i], module->userdata); } } free(module->modules); } if (module->codeBase != NULL) { // release memory of library module->free(module->codeBase, 0, MEM_RELEASE, module->userdata); } HeapFree(GetProcessHeap(), 0, module); }
static BOOL FinalizeSection(PMEMORYMODULE module, PSECTIONFINALIZEDATA sectionData) { DWORD protect, oldProtect; BOOL executable; BOOL readable; BOOL writeable; if (sectionData->size == 0) { return TRUE; } if (sectionData->characteristics & IMAGE_SCN_MEM_DISCARDABLE) { // section is not needed any more and can safely be freed if (sectionData->address == sectionData->alignedAddress && (sectionData->last || module->headers->OptionalHeader.SectionAlignment == module->pageSize || (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][readable][writeable]; if (sectionData->characteristics & IMAGE_SCN_MEM_NOT_CACHED) { protect |= PAGE_NOCACHE; } // change memory access flags if (VirtualProtect(sectionData->address, sectionData->size, protect, &oldProtect) == 0) { OutputLastError("Error protecting memory page"); return FALSE; } return TRUE; }