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
}
Example #2
0
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)),
            &sectionCharacteristics,
            sizeof(sectionCharacteristics),
            NULL );
        ReadProcessMemory( hProcess,
            (LPVOID)((LONG)section + FIELD_OFFSET(IMAGE_SECTION_HEADER, Misc.PhysicalAddress)),
            &sectionMiscPhysicalAddress,
            sizeof(sectionMiscPhysicalAddress),
            NULL );
        ReadProcessMemory( hProcess,
            (LPVOID)((LONG)section + FIELD_OFFSET(IMAGE_SECTION_HEADER, SizeOfRawData)),
            &sectionSizeOfRawData,
            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
}