Fix crash in loader relocation code.

svn path=/trunk/; revision=9872
This commit is contained in:
Eric Kohl 2004-06-25 18:50:48 +00:00
parent 2dea234132
commit acf32a2988

View file

@ -1,4 +1,4 @@
/* $Id: utils.c,v 1.90 2004/06/20 10:36:17 gvg Exp $ /* $Id: utils.c,v 1.91 2004/06/25 18:50:48 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -717,7 +717,10 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
NTSTATUS Status; NTSTATUS Status;
PLDR_MODULE Module; PLDR_MODULE Module;
TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n", Name, SearchPath ? " from " : "", SearchPath ? SearchPath : L""); TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n",
Name,
SearchPath ? " from " : "",
SearchPath ? SearchPath : L"");
if (Name == NULL) if (Name == NULL)
{ {
@ -1217,18 +1220,19 @@ LdrGetExportByName(PVOID BaseAddress,
* NOTE * NOTE
* *
*/ */
static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, static NTSTATUS
PVOID ImageBase) LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
PVOID ImageBase)
{ {
USHORT NumberOfEntries; USHORT NumberOfEntries;
PUSHORT pValue16; PUSHORT pValue16;
ULONG RelocationRVA; ULONG RelocationRVA;
ULONG Delta32; LONG Delta32;
ULONG Offset; ULONG Offset;
PULONG pValue32; PULONG pValue32;
PRELOCATION_DIRECTORY RelocationDir; PRELOCATION_DIRECTORY RelocationDir;
PRELOCATION_ENTRY RelocationBlock; PRELOCATION_ENTRY RelocationBlock;
int i; int i;
PIMAGE_DATA_DIRECTORY RelocationDDir; PIMAGE_DATA_DIRECTORY RelocationDDir;
ULONG OldProtect; ULONG OldProtect;
PVOID ProtectBase; PVOID ProtectBase;
@ -1239,6 +1243,8 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
NTSTATUS Status; NTSTATUS Status;
PIMAGE_SECTION_HEADER Sections; PIMAGE_SECTION_HEADER Sections;
ULONG MaxExtend; ULONG MaxExtend;
ULONG RelocationBlockOffset;
ULONG RelocationSectionSize;
if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
{ {
@ -1248,6 +1254,7 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
Sections = Sections =
(PIMAGE_SECTION_HEADER)((PVOID)NTHeaders + sizeof(IMAGE_NT_HEADERS)); (PIMAGE_SECTION_HEADER)((PVOID)NTHeaders + sizeof(IMAGE_NT_HEADERS));
MaxExtend = 0; MaxExtend = 0;
RelocationSectionSize = 0;
for (i = 0; i < NTHeaders->FileHeader.NumberOfSections; i++) for (i = 0; i < NTHeaders->FileHeader.NumberOfSections; i++)
{ {
if (!(Sections[i].Characteristics & IMAGE_SECTION_NOLOAD)) if (!(Sections[i].Characteristics & IMAGE_SECTION_NOLOAD))
@ -1257,6 +1264,12 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
(ULONG)(Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize); (ULONG)(Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize);
MaxExtend = max(MaxExtend, Extend); MaxExtend = max(MaxExtend, Extend);
} }
if (!memcmp(Sections[i].Name,".reloc", 6))
{
RelocationSectionSize = Sections[i].Misc.VirtualSize;
DPRINT("Relocation section size: %lx\n", RelocationSectionSize);
}
} }
RelocationDDir = RelocationDDir =
@ -1268,7 +1281,8 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
RelocationDir = RelocationDir =
(PRELOCATION_DIRECTORY)((PCHAR)ImageBase + RelocationRVA); (PRELOCATION_DIRECTORY)((PCHAR)ImageBase + RelocationRVA);
while (RelocationDir->SizeOfBlock) RelocationBlockOffset = 0;
while (RelocationBlockOffset < RelocationSectionSize)
{ {
if (RelocationDir->VirtualAddress > MaxExtend) if (RelocationDir->VirtualAddress > MaxExtend)
{ {
@ -1319,7 +1333,6 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
return(Status); return(Status);
} }
} }
for (i = 0; i < NumberOfEntries; i++) for (i = 0; i < NumberOfEntries; i++)
{ {
Offset = (RelocationBlock[i].TypeOffset & 0xfff); Offset = (RelocationBlock[i].TypeOffset & 0xfff);
@ -1352,7 +1365,7 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
case TYPE_RELOC_HIGHADJ: case TYPE_RELOC_HIGHADJ:
/* FIXME: do the highadjust fixup */ /* FIXME: do the highadjust fixup */
DPRINT("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n"); DPRINT("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n");
return(STATUS_UNSUCCESSFUL); return STATUS_UNSUCCESSFUL;
default: default:
DPRINT("unexpected fixup type\n"); DPRINT("unexpected fixup type\n");
@ -1388,8 +1401,10 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
RelocationRVA += RelocationDir->SizeOfBlock; RelocationRVA += RelocationDir->SizeOfBlock;
RelocationDir = RelocationDir =
(PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA); (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
RelocationBlockOffset += RelocationDir->SizeOfBlock;
} }
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1427,10 +1442,9 @@ LdrpGetOrLoadModule(PWCHAR SerachPath,
} }
static NTSTATUS static NTSTATUS
LdrpProcessImportDirectoryEntry( LdrpProcessImportDirectoryEntry(PLDR_MODULE Module,
PLDR_MODULE Module, PLDR_MODULE ImportedModule,
PLDR_MODULE ImportedModule, PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory)
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory)
{ {
NTSTATUS Status; NTSTATUS Status;
PVOID* ImportAddressList; PVOID* ImportAddressList;
@ -2571,8 +2585,8 @@ LdrpAttachProcess(VOID)
NTSTATUS STDCALL NTSTATUS STDCALL
LdrShutdownProcess (VOID) LdrShutdownProcess (VOID)
{ {
LdrpDetachProcess(TRUE); LdrpDetachProcess(TRUE);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* /*
@ -2582,48 +2596,47 @@ LdrShutdownProcess (VOID)
NTSTATUS NTSTATUS
LdrpAttachThread (VOID) LdrpAttachThread (VOID)
{ {
PLIST_ENTRY ModuleListHead; PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
PLDR_MODULE Module; PLDR_MODULE Module;
NTSTATUS Status; NTSTATUS Status;
DPRINT("LdrpAttachThread() called for %wZ\n", DPRINT("LdrpAttachThread() called for %wZ\n",
&ExeModule->BaseDllName); &ExeModule->BaseDllName);
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
Status = LdrpInitializeTlsForThread(); Status = LdrpInitializeTlsForThread();
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
Entry = ModuleListHead->Flink;
ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList; while (Entry != ModuleListHead)
Entry = ModuleListHead->Flink; {
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList);
if (Module->Flags & PROCESS_ATTACH_CALLED &&
!(Module->Flags & DONT_CALL_FOR_THREAD) &&
!(Module->Flags & UNLOAD_IN_PROGRESS))
{
TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n",
&Module->BaseDllName, Module->EntryPoint);
LdrpCallDllEntry(Module, DLL_THREAD_ATTACH, NULL);
}
Entry = Entry->Flink;
}
while (Entry != ModuleListHead) Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
{ Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList); LdrpTlsCallback(Module, DLL_THREAD_ATTACH);
if (Module->Flags & PROCESS_ATTACH_CALLED && }
!(Module->Flags & DONT_CALL_FOR_THREAD) &&
!(Module->Flags & UNLOAD_IN_PROGRESS))
{
TRACE_LDR("%wZ - Calling entry point at %x for thread attaching\n",
&Module->BaseDllName, Module->EntryPoint);
LdrpCallDllEntry(Module, DLL_THREAD_ATTACH, NULL);
}
Entry = Entry->Flink;
}
Entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink; RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
LdrpTlsCallback(Module, DLL_THREAD_ATTACH);
}
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); DPRINT("LdrpAttachThread() done\n");
DPRINT("LdrpAttachThread() done\n"); return Status;
return Status;
} }