mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:03:00 +00:00
Fix crash in loader relocation code.
svn path=/trunk/; revision=9872
This commit is contained in:
parent
2dea234132
commit
acf32a2988
1 changed files with 67 additions and 54 deletions
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue