mirror of
https://github.com/reactos/reactos.git
synced 2024-07-07 05:05:09 +00:00
Implement and use LdrProcessRelocationBlock().
svn path=/trunk/; revision=9905
This commit is contained in:
parent
3bd4ef3363
commit
fbe9f7f64f
|
@ -126,6 +126,12 @@ LdrLoadDll(IN PWSTR SearchPath OPTIONAL,
|
||||||
IN PUNICODE_STRING Name,
|
IN PUNICODE_STRING Name,
|
||||||
OUT PVOID *BaseAddress OPTIONAL);
|
OUT PVOID *BaseAddress OPTIONAL);
|
||||||
|
|
||||||
|
PIMAGE_BASE_RELOCATION STDCALL
|
||||||
|
LdrProcessRelocationBlock(IN PVOID Address,
|
||||||
|
IN USHORT Count,
|
||||||
|
IN PUSHORT TypeOffset,
|
||||||
|
IN ULONG_PTR Delta);
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
|
LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
|
||||||
IN PCWSTR ValueName,
|
IN PCWSTR ValueName,
|
||||||
|
|
|
@ -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
|
; ReactOS Operating System
|
||||||
;
|
;
|
||||||
|
@ -51,7 +51,7 @@ LdrGetDllHandle@16
|
||||||
LdrGetProcedureAddress@16
|
LdrGetProcedureAddress@16
|
||||||
LdrInitializeThunk@16
|
LdrInitializeThunk@16
|
||||||
LdrLoadDll@16
|
LdrLoadDll@16
|
||||||
;LdrProcessRelocationBlock@16
|
LdrProcessRelocationBlock@16
|
||||||
LdrQueryImageFileExecutionOptions@24
|
LdrQueryImageFileExecutionOptions@24
|
||||||
LdrQueryProcessModuleInformation@12
|
LdrQueryProcessModuleInformation@12
|
||||||
LdrShutdownProcess@0
|
LdrShutdownProcess@0
|
||||||
|
|
|
@ -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
|
; ReactOS Operating System
|
||||||
;
|
;
|
||||||
|
@ -51,7 +51,7 @@ LdrGetDllHandle=LdrGetDllHandle@16
|
||||||
LdrGetProcedureAddress=LdrGetProcedureAddress@16
|
LdrGetProcedureAddress=LdrGetProcedureAddress@16
|
||||||
LdrInitializeThunk=LdrInitializeThunk@16
|
LdrInitializeThunk=LdrInitializeThunk@16
|
||||||
LdrLoadDll=LdrLoadDll@16
|
LdrLoadDll=LdrLoadDll@16
|
||||||
;LdrProcessRelocationBlock
|
LdrProcessRelocationBlock=LdrProcessRelocationBlock@16
|
||||||
LdrQueryImageFileExecutionOptions=LdrQueryImageFileExecutionOptions@24
|
LdrQueryImageFileExecutionOptions=LdrQueryImageFileExecutionOptions@24
|
||||||
LdrQueryProcessModuleInformation=LdrQueryProcessModuleInformation@12
|
LdrQueryProcessModuleInformation=LdrQueryProcessModuleInformation@12
|
||||||
LdrShutdownProcess=LdrShutdownProcess@0
|
LdrShutdownProcess=LdrShutdownProcess@0
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -1226,10 +1226,10 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
{
|
{
|
||||||
PIMAGE_DATA_DIRECTORY RelocationDDir;
|
PIMAGE_DATA_DIRECTORY RelocationDDir;
|
||||||
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
||||||
ULONG Count, ProtectSize, OldProtect, OldProtect2, i;
|
ULONG Count, ProtectSize, OldProtect, OldProtect2;
|
||||||
PVOID Page, ProtectPage, ProtectPage2;
|
PVOID Page, ProtectPage, ProtectPage2;
|
||||||
PWORD TypeOffset;
|
PUSHORT TypeOffset;
|
||||||
ULONG Delta = (ULONG_PTR)ImageBase - NTHeaders->OptionalHeader.ImageBase;
|
ULONG_PTR Delta;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
|
if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
|
||||||
|
@ -1244,19 +1244,21 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtectSize = PAGE_SIZE;
|
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);
|
RelocationDDir->VirtualAddress);
|
||||||
RelocationEnd = (IMAGE_BASE_RELOCATION*)((ULONG_PTR)ImageBase +
|
RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)ImageBase +
|
||||||
RelocationDDir->VirtualAddress + RelocationDDir->Size);
|
RelocationDDir->VirtualAddress + RelocationDDir->Size);
|
||||||
|
|
||||||
while (RelocationDir < RelocationEnd &&
|
while (RelocationDir < RelocationEnd &&
|
||||||
RelocationDir->SizeOfBlock > 0)
|
RelocationDir->SizeOfBlock > 0)
|
||||||
{
|
{
|
||||||
Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
|
Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
|
||||||
sizeof(WORD);
|
sizeof(USHORT);
|
||||||
Page = ImageBase + RelocationDir->VirtualAddress;
|
Page = ImageBase + RelocationDir->VirtualAddress;
|
||||||
TypeOffset = (PWORD)(RelocationDir + 1);
|
TypeOffset = (PUSHORT)(RelocationDir + 1);
|
||||||
|
|
||||||
/* Unprotect the page(s) we're about to relocate. */
|
/* Unprotect the page(s) we're about to relocate. */
|
||||||
ProtectPage = Page;
|
ProtectPage = Page;
|
||||||
|
@ -1268,7 +1270,7 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to unprotect relocation target.\n");
|
DPRINT1("Failed to unprotect relocation target.\n");
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RelocationDir->VirtualAddress + PAGE_SIZE <
|
if (RelocationDir->VirtualAddress + PAGE_SIZE <
|
||||||
|
@ -1288,36 +1290,21 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
&ProtectSize,
|
&ProtectSize,
|
||||||
OldProtect,
|
OldProtect,
|
||||||
&OldProtect);
|
&OldProtect);
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Patch the page. */
|
|
||||||
for (i = 0; i < Count; i++)
|
|
||||||
{
|
{
|
||||||
SHORT Offset = TypeOffset[i] & 0xFFF;
|
ProtectPage2 = NULL;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RelocationDir = LdrProcessRelocationBlock(Page,
|
||||||
|
Count,
|
||||||
|
TypeOffset,
|
||||||
|
Delta);
|
||||||
|
if (RelocationDir == NULL)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
/* Restore old page protection. */
|
/* Restore old page protection. */
|
||||||
NtProtectVirtualMemory(NtCurrentProcess(),
|
NtProtectVirtualMemory(NtCurrentProcess(),
|
||||||
&ProtectPage,
|
&ProtectPage,
|
||||||
|
@ -1325,8 +1312,7 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
OldProtect,
|
OldProtect,
|
||||||
&OldProtect);
|
&OldProtect);
|
||||||
|
|
||||||
if (RelocationDir->VirtualAddress + PAGE_SIZE <
|
if (ProtectPage2 != NULL)
|
||||||
NTHeaders->OptionalHeader.SizeOfImage)
|
|
||||||
{
|
{
|
||||||
NtProtectVirtualMemory(NtCurrentProcess(),
|
NtProtectVirtualMemory(NtCurrentProcess(),
|
||||||
&ProtectPage2,
|
&ProtectPage2,
|
||||||
|
@ -1334,9 +1320,6 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
OldProtect2,
|
OldProtect2,
|
||||||
&OldProtect2);
|
&OldProtect2);
|
||||||
}
|
}
|
||||||
|
|
||||||
RelocationDir = (IMAGE_BASE_RELOCATION*)((ULONG_PTR)RelocationDir +
|
|
||||||
RelocationDir->SizeOfBlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -3030,4 +3013,55 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
|
||||||
return Status;
|
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 */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue