From fbe9f7f64f32fb2735db9019ae3e58081d21b1ac Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 27 Jun 2004 12:21:14 +0000 Subject: [PATCH] Implement and use LdrProcessRelocationBlock(). svn path=/trunk/; revision=9905 --- reactos/include/ntdll/ldr.h | 6 ++ reactos/lib/ntdll/def/ntdll.def | 4 +- reactos/lib/ntdll/def/ntdll.edf | 4 +- reactos/lib/ntdll/ldr/utils.c | 114 +++++++++++++++++++++----------- 4 files changed, 84 insertions(+), 44 deletions(-) diff --git a/reactos/include/ntdll/ldr.h b/reactos/include/ntdll/ldr.h index 8075d53b200..e4a05e109f7 100644 --- a/reactos/include/ntdll/ldr.h +++ b/reactos/include/ntdll/ldr.h @@ -126,6 +126,12 @@ LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PUNICODE_STRING Name, OUT PVOID *BaseAddress OPTIONAL); +PIMAGE_BASE_RELOCATION STDCALL +LdrProcessRelocationBlock(IN PVOID Address, + IN USHORT Count, + IN PUSHORT TypeOffset, + IN ULONG_PTR Delta); + NTSTATUS STDCALL LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey, IN PCWSTR ValueName, diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index 7f6b2e06a7c..376a3486cdc 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.121 2004/06/13 10:35:52 navaraf Exp $ +; $Id: ntdll.def,v 1.122 2004/06/27 12:21:14 ekohl Exp $ ; ; ReactOS Operating System ; @@ -51,7 +51,7 @@ LdrGetDllHandle@16 LdrGetProcedureAddress@16 LdrInitializeThunk@16 LdrLoadDll@16 -;LdrProcessRelocationBlock@16 +LdrProcessRelocationBlock@16 LdrQueryImageFileExecutionOptions@24 LdrQueryProcessModuleInformation@12 LdrShutdownProcess@0 diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index d7c771d57b1..c21b6a89cf4 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.111 2004/06/13 10:35:52 navaraf Exp $ +; $Id: ntdll.edf,v 1.112 2004/06/27 12:21:14 ekohl Exp $ ; ; ReactOS Operating System ; @@ -51,7 +51,7 @@ LdrGetDllHandle=LdrGetDllHandle@16 LdrGetProcedureAddress=LdrGetProcedureAddress@16 LdrInitializeThunk=LdrInitializeThunk@16 LdrLoadDll=LdrLoadDll@16 -;LdrProcessRelocationBlock +LdrProcessRelocationBlock=LdrProcessRelocationBlock@16 LdrQueryImageFileExecutionOptions=LdrQueryImageFileExecutionOptions@24 LdrQueryProcessModuleInformation=LdrQueryProcessModuleInformation@12 LdrShutdownProcess=LdrShutdownProcess@0 diff --git a/reactos/lib/ntdll/ldr/utils.c b/reactos/lib/ntdll/ldr/utils.c index e68ef93bcaa..54fe950a1df 100644 --- a/reactos/lib/ntdll/ldr/utils.c +++ b/reactos/lib/ntdll/ldr/utils.c @@ -1,4 +1,4 @@ -/* $Id: utils.c,v 1.95 2004/06/26 15:11:14 navaraf Exp $ +/* $Id: utils.c,v 1.96 2004/06/27 12:20:33 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1226,10 +1226,10 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, { PIMAGE_DATA_DIRECTORY RelocationDDir; PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; - ULONG Count, ProtectSize, OldProtect, OldProtect2, i; + ULONG Count, ProtectSize, OldProtect, OldProtect2; PVOID Page, ProtectPage, ProtectPage2; - PWORD TypeOffset; - ULONG Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase; + PUSHORT TypeOffset; + ULONG_PTR Delta; NTSTATUS Status; if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) @@ -1244,19 +1244,21 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, { return STATUS_SUCCESS; } - + ProtectSize = PAGE_SIZE; - RelocationDir = (IMAGE_BASE_RELOCATION*)((ULONG_PTR)ImageBase + + Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase; + RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase + RelocationDDir->VirtualAddress); - RelocationEnd = (IMAGE_BASE_RELOCATION*)((ULONG_PTR)ImageBase + + RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase + RelocationDDir->VirtualAddress + RelocationDDir->Size); + while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) { Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / - sizeof(WORD); + sizeof(USHORT); Page = ImageBase + RelocationDir->VirtualAddress; - TypeOffset = (PWORD)(RelocationDir + 1); + TypeOffset = (PUSHORT)(RelocationDir + 1); /* Unprotect the page(s) we're about to relocate. */ ProtectPage = Page; @@ -1268,7 +1270,7 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to unprotect relocation target.\n"); - return(Status); + return Status; } if (RelocationDir->VirtualAddress + PAGE_SIZE < @@ -1288,36 +1290,21 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, &ProtectSize, OldProtect, &OldProtect); - return(Status); + return Status; } } - - /* Patch the page. */ - for (i = 0; i < Count; i++) + else { - SHORT Offset = TypeOffset[i] & 0xFFF; - USHORT Type = TypeOffset[i] >> 12; - - switch (Type) - { - case IMAGE_REL_BASED_ABSOLUTE: - break; - case IMAGE_REL_BASED_HIGH: - *(PUSHORT)(Page + Offset) += HIWORD(Delta); - break; - case IMAGE_REL_BASED_LOW: - *(PUSHORT)(Page + Offset) += LOWORD(Delta); - break; - case IMAGE_REL_BASED_HIGHLOW: - *(PULONG)(Page + Offset) += Delta; - break; - case IMAGE_REL_BASED_HIGHADJ: - default: - DPRINT("Unknown/unsupported fixup type %d.\n", type); - return STATUS_UNSUCCESSFUL; - } + ProtectPage2 = NULL; } + RelocationDir = LdrProcessRelocationBlock(Page, + Count, + TypeOffset, + Delta); + if (RelocationDir == NULL) + return STATUS_UNSUCCESSFUL; + /* Restore old page protection. */ NtProtectVirtualMemory(NtCurrentProcess(), &ProtectPage, @@ -1325,8 +1312,7 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, OldProtect, &OldProtect); - if (RelocationDir->VirtualAddress + PAGE_SIZE < - NTHeaders->OptionalHeader.SizeOfImage) + if (ProtectPage2 != NULL) { NtProtectVirtualMemory(NtCurrentProcess(), &ProtectPage2, @@ -1334,9 +1320,6 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, OldProtect2, &OldProtect2); } - - RelocationDir = (IMAGE_BASE_RELOCATION*)((ULONG_PTR)RelocationDir + - RelocationDir->SizeOfBlock); } return STATUS_SUCCESS; @@ -3030,4 +3013,55 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey, return Status; } + +PIMAGE_BASE_RELOCATION STDCALL +LdrProcessRelocationBlock(IN PVOID Address, + IN USHORT Count, + IN PUSHORT TypeOffset, + IN ULONG_PTR Delta) +{ + SHORT Offset; + USHORT Type; + USHORT i; + PUSHORT ShortPtr; + PULONG LongPtr; + + for (i = 0; i < Count; i++) + { + Offset = *TypeOffset & 0xFFF; + Type = *TypeOffset >> 12; + + switch (Type) + { + case IMAGE_REL_BASED_ABSOLUTE: + break; + + case IMAGE_REL_BASED_HIGH: + ShortPtr = (PUSHORT)(Address + Offset); + *ShortPtr += HIWORD(Delta); + break; + + case IMAGE_REL_BASED_LOW: + ShortPtr = (PUSHORT)(Address + Offset); + *ShortPtr += LOWORD(Delta); + break; + + case IMAGE_REL_BASED_HIGHLOW: + LongPtr = (PULONG)(Address + Offset); + *LongPtr += Delta; + break; + + case IMAGE_REL_BASED_HIGHADJ: + case IMAGE_REL_BASED_MIPS_JMPADDR: + default: + DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); + return NULL; + } + + TypeOffset++; + } + + return (PIMAGE_BASE_RELOCATION)TypeOffset; +} + /* EOF */