static void FinalizeSections(PMEMORYMODULE module) { int i; PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); #ifdef _WIN64 POINTER_TYPE imageOffset = (module->headers->OptionalHeader.ImageBase & 0xffffffff00000000); #else #define imageOffset 0 #endif // loop through all sections and change access flags for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) { DWORD protect, oldProtect, size; int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0; int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0; if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) { // section is not needed any more and can safely be freed VirtualFree((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), section->SizeOfRawData, MEM_DECOMMIT); continue; } // force it rwx readable=executable=writeable=1; // determine protection flags based on characteristics protect = ProtectionFlags[executable][readable][writeable]; if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) { protect |= PAGE_NOCACHE; } // determine size of region size = section->SizeOfRawData; if (size == 0) { if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) { size = module->headers->OptionalHeader.SizeOfInitializedData; } else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) { size = module->headers->OptionalHeader.SizeOfUninitializedData; } } if (size > 0) { // change memory access flags if (VirtualProtect((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), size, protect, &oldProtect) == 0) #ifdef DEBUG_OUTPUT OutputLastError("Error protecting memory page") #endif ; } } #ifndef _WIN64 #undef imageOffset #endif }
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 VirtualFree(sectionData->address, sectionData->size, MEM_DECOMMIT); } 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) { #ifdef DEBUG_OUTPUT OutputLastError("Error protecting memory page") #endif ; return FALSE; } return TRUE; }
static void FinalizeSectionsEx( HANDLE hProcess, PMEMORYMODULE module ) { WORD sizeOfOptionalHeader, numberOfSections; // IMAGE_FIRST_SECTION work-around for remote process ReadProcessMemory( hProcess, (LPCVOID)((LONG)(module->headers) + FIELD_OFFSET(IMAGE_NT_HEADERS, FileHeader.SizeOfOptionalHeader)), &sizeOfOptionalHeader, sizeof(sizeOfOptionalHeader), NULL ); // number of sections work-around for remote process ReadProcessMemory( hProcess, (LPCVOID)((LONG)(module->headers) + FIELD_OFFSET(IMAGE_NT_HEADERS, FileHeader.NumberOfSections)), &numberOfSections, sizeof(numberOfSections), NULL ); PIMAGE_SECTION_HEADER section = (PIMAGE_SECTION_HEADER)((ULONG_PTR)(module->headers) + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader ) + (ULONG_PTR)sizeOfOptionalHeader); #ifdef _WIN64 POINTER_TYPE imageOffset = (module->headers->OptionalHeader.ImageBase & 0xffffffff00000000); #else #define imageOffset 0 #endif // loop through all sections and change access flags for (int i=0; i < numberOfSections; ++i, ++section) { DWORD protect, oldProtect, size, sectionCharacteristics, sectionMiscPhysicalAddress, sectionSizeOfRawData; ReadProcessMemory( hProcess, (LPVOID)((LONG)section + FIELD_OFFSET(IMAGE_SECTION_HEADER, Characteristics)), §ionCharacteristics, sizeof(sectionCharacteristics), NULL ); ReadProcessMemory( hProcess, (LPVOID)((LONG)section + FIELD_OFFSET(IMAGE_SECTION_HEADER, Misc.PhysicalAddress)), §ionMiscPhysicalAddress, sizeof(sectionMiscPhysicalAddress), NULL ); ReadProcessMemory( hProcess, (LPVOID)((LONG)section + FIELD_OFFSET(IMAGE_SECTION_HEADER, SizeOfRawData)), §ionSizeOfRawData, sizeof(sectionSizeOfRawData), NULL ); int executable = (sectionCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0; int readable = (sectionCharacteristics & IMAGE_SCN_MEM_READ) != 0; int writeable = (sectionCharacteristics & IMAGE_SCN_MEM_WRITE) != 0; if (sectionCharacteristics & IMAGE_SCN_MEM_DISCARDABLE) { // section is not needed any more and can safely be freed VirtualFreeEx( hProcess, (LPVOID)((POINTER_TYPE)sectionMiscPhysicalAddress | imageOffset), sectionSizeOfRawData, MEM_DECOMMIT); continue; } // determine protection flags based on characteristics protect = ProtectionFlags[executable][readable][writeable]; if (sectionCharacteristics & IMAGE_SCN_MEM_NOT_CACHED) { protect |= PAGE_NOCACHE; } // determine size of region size = sectionSizeOfRawData; if (size == 0) { if (sectionCharacteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) { //size = module->headers->OptionalHeader.SizeOfInitializedData; ReadProcessMemory( hProcess, (LPVOID)((LONG)(module->headers) + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader.SizeOfInitializedData)), &size, sizeof(size), NULL ); } else if (sectionCharacteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) { //size = module->headers->OptionalHeader.SizeOfUninitializedData; ReadProcessMemory( hProcess, (LPVOID)((LONG)(module->headers) + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader.SizeOfUninitializedData)), &size, sizeof(size), NULL ); } } if (size > 0) { // change memory access flags if (VirtualProtectEx( hProcess, (LPVOID)((POINTER_TYPE)sectionMiscPhysicalAddress | imageOffset), size, protect, &oldProtect) == 0) { #ifdef DEBUG_OUTPUT OutputLastError("Error protecting memory page"); #endif } } } #ifndef _WIN64 #undef imageOffset #endif }