X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fldr%2Floader.c;h=960db413a2358547593c7b21eb9291b3f0d472e6;hp=ff215f9b038dd28fc62b240f0f909516220f0c67;hb=03af8776dc14167b078911b0c7c5327d1bcdd128;hpb=f4077c1bf64ef89d74a8d4822d2d7aada3ba9927 diff --git a/ntoskrnl/ldr/loader.c b/ntoskrnl/ldr/loader.c index ff215f9..960db41 100644 --- a/ntoskrnl/ldr/loader.c +++ b/ntoskrnl/ldr/loader.c @@ -828,6 +828,40 @@ LdrGetModuleObject(PUNICODE_STRING ModuleName) /* ---------------------------------------------- PE Module support */ +static BOOL +PageNeedsWriteAccess(PVOID PageStart, + PVOID DriverBase, + PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders) +{ + BOOL NeedsWriteAccess; + unsigned Idx; + ULONG Characteristics; + ULONG Length; + PVOID BaseAddress; + + NeedsWriteAccess = FALSE; + /* Set the protections for the various parts of the driver */ + for (Idx = 0; Idx < PEFileHeader->NumberOfSections && ! NeedsWriteAccess; Idx++) + { + Characteristics = PESectionHeaders[Idx].Characteristics; + if (!(Characteristics & IMAGE_SECTION_CHAR_CODE) || + (Characteristics & IMAGE_SECTION_CHAR_WRITABLE || + Characteristics & IMAGE_SECTION_CHAR_DATA || + Characteristics & IMAGE_SECTION_CHAR_BSS)) + { + Length = + max(PESectionHeaders[Idx].Misc.VirtualSize, + PESectionHeaders[Idx].SizeOfRawData); + BaseAddress = PESectionHeaders[Idx].VirtualAddress + DriverBase; + NeedsWriteAccess = BaseAddress < PageStart + PAGE_SIZE && + PageStart < (PVOID)((PCHAR) BaseAddress + Length); + } + } + + return(NeedsWriteAccess); +} + static NTSTATUS LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING FileName, @@ -1122,20 +1156,32 @@ LdrPEProcessModule(PVOID ModuleLoadBase, ULONG Characteristics = PESectionHeaders[Idx].Characteristics; ULONG Length; PVOID BaseAddress; - ULONG i; - Length = - max(PESectionHeaders[Idx].Misc.VirtualSize, - PESectionHeaders[Idx].SizeOfRawData); - BaseAddress = PESectionHeaders[Idx].VirtualAddress + DriverBase; + PVOID PageAddress; if (Characteristics & IMAGE_SECTION_CHAR_CODE && !(Characteristics & IMAGE_SECTION_CHAR_WRITABLE || Characteristics & IMAGE_SECTION_CHAR_DATA || Characteristics & IMAGE_SECTION_CHAR_BSS)) { - for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++) + Length = + max(PESectionHeaders[Idx].Misc.VirtualSize, + PESectionHeaders[Idx].SizeOfRawData); + BaseAddress = PESectionHeaders[Idx].VirtualAddress + DriverBase; + PageAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress); + if (! PageNeedsWriteAccess(PageAddress, DriverBase, PEFileHeader, PESectionHeaders)) + { + MmSetPageProtect(NULL, PageAddress, PAGE_READONLY); + } + PageAddress = (PVOID)((PCHAR) PageAddress + PAGE_SIZE); + while ((PVOID)((PCHAR) PageAddress + PAGE_SIZE) < + (PVOID)((PCHAR) BaseAddress + Length)) + { + MmSetPageProtect(NULL, PageAddress, PAGE_READONLY); + PageAddress = (PVOID)((PCHAR) PageAddress + PAGE_SIZE); + } + if (PageAddress < (PVOID)((PCHAR) BaseAddress + Length) && + ! PageNeedsWriteAccess(PageAddress, DriverBase, PEFileHeader, PESectionHeaders)) { - MmSetPageProtect(NULL, BaseAddress + (i * PAGE_SIZE), - PAGE_READONLY); + MmSetPageProtect(NULL, PageAddress, PAGE_READONLY); } } }