mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 06:22:58 +00:00
- Implemented fast loading of bounded images.
- Implemented handling of tls sections. - Fixed referencing of loaded dlls. svn path=/trunk/; revision=7498
This commit is contained in:
parent
d3fbd8e582
commit
446ec6d27b
4 changed files with 1533 additions and 743 deletions
|
@ -13,6 +13,15 @@ typedef BOOL STDCALL_FUNC
|
||||||
ULONG ul_reason_for_call,
|
ULONG ul_reason_for_call,
|
||||||
LPVOID lpReserved);
|
LPVOID lpReserved);
|
||||||
|
|
||||||
|
/* Module flags */
|
||||||
|
#define IMAGE_DLL 0x00000004
|
||||||
|
#define LOAD_IN_PROGRESS 0x00001000
|
||||||
|
#define UNLOAD_IN_PROGRESS 0x00002000
|
||||||
|
#define ENTRY_PROCESSED 0x00004000
|
||||||
|
#define DONT_CALL_FOR_THREAD 0x00040000
|
||||||
|
#define PROCESS_ATTACH_CALLED 0x00080000
|
||||||
|
#define IMAGE_NOT_AT_BASE 0x00200000
|
||||||
|
|
||||||
typedef struct _LDR_MODULE
|
typedef struct _LDR_MODULE
|
||||||
{
|
{
|
||||||
LIST_ENTRY InLoadOrderModuleList;
|
LIST_ENTRY InLoadOrderModuleList;
|
||||||
|
@ -67,7 +76,7 @@ typedef struct _MODULE_INFORMATION
|
||||||
MODULE_ENTRY ModuleEntry[1];
|
MODULE_ENTRY ModuleEntry[1];
|
||||||
} MODULE_INFORMATION, *PMODULE_INFORMATION;
|
} MODULE_INFORMATION, *PMODULE_INFORMATION;
|
||||||
|
|
||||||
#if defined(KDBG) || defined(DBG)
|
#ifdef KDBG
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule);
|
LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule);
|
||||||
|
@ -90,7 +99,7 @@ NTSTATUS STDCALL
|
||||||
LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress);
|
LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress);
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
LdrGetDllHandle(IN ULONG Unknown1,
|
LdrGetDllHandle(IN PWCHAR Path OPTIONAL,
|
||||||
IN ULONG Unknown2,
|
IN ULONG Unknown2,
|
||||||
IN PUNICODE_STRING DllName,
|
IN PUNICODE_STRING DllName,
|
||||||
OUT PVOID *BaseAddress);
|
OUT PVOID *BaseAddress);
|
||||||
|
|
|
@ -15,12 +15,14 @@
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
#define TRACE_LDR(args...) if (NtGlobalFlag & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); }
|
||||||
#define DPRINT(args...)
|
#define DPRINT(args...)
|
||||||
#else
|
#else
|
||||||
#define DPRINT
|
#define DPRINT
|
||||||
#endif /* __GNUC__ */
|
#endif /* __GNUC__ */
|
||||||
#define CHECKPOINT
|
#define CHECKPOINT
|
||||||
#else
|
#else
|
||||||
|
#define TRACE_LDR(args...) do { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0)
|
||||||
#define DPRINT(args...) do { DbgPrint("(NTDLL:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0)
|
#define DPRINT(args...) do { DbgPrint("(NTDLL:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0)
|
||||||
#define CHECKPOINT do { DbgPrint("(NTDLL:%s:%d) Checkpoint\n",__FILE__,__LINE__); } while(0)
|
#define CHECKPOINT do { DbgPrint("(NTDLL:%s:%d) Checkpoint\n",__FILE__,__LINE__); } while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: startup.c,v 1.56 2003/11/17 02:32:45 hyperion Exp $
|
/* $Id: startup.c,v 1.57 2004/01/07 10:09:03 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
VOID RtlInitializeHeapManager (VOID);
|
VOID RtlInitializeHeapManager (VOID);
|
||||||
VOID LdrpInitLoader(VOID);
|
VOID LdrpInitLoader(VOID);
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,9 +35,13 @@ extern unsigned int _image_base__;
|
||||||
static CRITICAL_SECTION PebLock;
|
static CRITICAL_SECTION PebLock;
|
||||||
static CRITICAL_SECTION LoaderLock;
|
static CRITICAL_SECTION LoaderLock;
|
||||||
static RTL_BITMAP TlsBitMap;
|
static RTL_BITMAP TlsBitMap;
|
||||||
|
PLDR_MODULE ExeModule;
|
||||||
|
|
||||||
ULONG NtGlobalFlag = 0;
|
ULONG NtGlobalFlag = 0;
|
||||||
|
|
||||||
|
NTSTATUS LdrpAttachThread (VOID);
|
||||||
|
|
||||||
|
|
||||||
#define VALUE_BUFFER_SIZE 256
|
#define VALUE_BUFFER_SIZE 256
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
|
@ -66,6 +69,45 @@ ReadCompatibilitySetting(HANDLE Key, LPWSTR Value, PKEY_VALUE_PARTIAL_INFORMATIO
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
LoadImageFileExecutionOptions(PPEB Peb)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
ULONG Value = 0;
|
||||||
|
UNICODE_STRING ValueString;
|
||||||
|
WCHAR ValueBuffer[64];
|
||||||
|
ULONG ValueSize;
|
||||||
|
|
||||||
|
if (Peb->ProcessParameters &&
|
||||||
|
Peb->ProcessParameters->ImagePathName.Length > 0)
|
||||||
|
{
|
||||||
|
/* global flag */
|
||||||
|
Status = LdrQueryImageFileExecutionOptions (&Peb->ProcessParameters->ImagePathName,
|
||||||
|
L"GlobalFlag",
|
||||||
|
REG_SZ,
|
||||||
|
(PVOID)ValueBuffer,
|
||||||
|
sizeof(ValueBuffer),
|
||||||
|
&ValueSize);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ValueString.Buffer = ValueBuffer + 1;
|
||||||
|
ValueString.Length = ValueSize - 2 * sizeof(WCHAR);
|
||||||
|
ValueString.MaximumLength = sizeof(ValueBuffer);
|
||||||
|
RtlUnicodeStringToInteger(&ValueString, 16, &Value);
|
||||||
|
Peb->NtGlobalFlag |= Value;
|
||||||
|
DPRINT("GlobalFlag: Key='%S', Value=%08x\n", ValueBuffer, Value);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* FIXME:
|
||||||
|
* read more options
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
NtGlobalFlag = Peb->NtGlobalFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
LoadCompatibilitySettings(PPEB Peb)
|
LoadCompatibilitySettings(PPEB Peb)
|
||||||
{
|
{
|
||||||
|
@ -198,230 +240,212 @@ __true_LdrInitializeThunk (ULONG Unknown1,
|
||||||
PVOID ImageBase;
|
PVOID ImageBase;
|
||||||
PPEB Peb;
|
PPEB Peb;
|
||||||
PLDR_MODULE NtModule; // ntdll
|
PLDR_MODULE NtModule; // ntdll
|
||||||
PLDR_MODULE ExeModule; // executable
|
|
||||||
NLSTABLEINFO NlsTable;
|
NLSTABLEINFO NlsTable;
|
||||||
WCHAR FullNtDllPath[MAX_PATH];
|
WCHAR FullNtDllPath[MAX_PATH];
|
||||||
|
|
||||||
DPRINT("LdrInitializeThunk()\n");
|
DPRINT("LdrInitializeThunk()\n");
|
||||||
if (NtCurrentPeb()->Ldr != NULL && NtCurrentPeb()->Ldr->Initialized == TRUE)
|
if (NtCurrentPeb()->Ldr == NULL || NtCurrentPeb()->Ldr->Initialized == FALSE)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
Peb = (PPEB)(PEB_BASE);
|
||||||
PDLLMAIN_FUNC Entrypoint;
|
DPRINT("Peb %x\n", Peb);
|
||||||
PLDR_MODULE current;
|
ImageBase = Peb->ImageBaseAddress;
|
||||||
|
DPRINT("ImageBase %x\n", ImageBase);
|
||||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
if (ImageBase <= (PVOID)0x1000)
|
||||||
current_entry =
|
|
||||||
NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Flink;
|
|
||||||
while (current_entry !=
|
|
||||||
&NtCurrentPeb()->Ldr->InInitializationOrderModuleList)
|
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, LDR_MODULE,
|
DPRINT("ImageBase is null\n");
|
||||||
InInitializationOrderModuleList);
|
ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
|
||||||
Entrypoint = (PDLLMAIN_FUNC)current->EntryPoint;
|
|
||||||
if (Entrypoint != NULL &&
|
|
||||||
current->BaseAddress != NtCurrentPeb()->ImageBaseAddress)
|
|
||||||
{
|
|
||||||
(VOID)Entrypoint(current->BaseAddress, DLL_THREAD_ATTACH, NULL);
|
|
||||||
}
|
|
||||||
current_entry = current_entry->Flink;
|
|
||||||
}
|
}
|
||||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Peb = (PPEB)(PEB_BASE);
|
/* If MZ header exists */
|
||||||
DPRINT("Peb %x\n", Peb);
|
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
|
||||||
ImageBase = Peb->ImageBaseAddress;
|
DPRINT("PEDosHeader %x\n", PEDosHeader);
|
||||||
DPRINT("ImageBase %x\n", ImageBase);
|
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
|
||||||
if (ImageBase <= (PVOID)0x1000)
|
PEDosHeader->e_lfanew == 0L ||
|
||||||
{
|
*(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_PE_MAGIC)
|
||||||
DPRINT("ImageBase is null\n");
|
{
|
||||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
|
DbgPrint("Image has bad header\n");
|
||||||
}
|
ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
NtGlobalFlag = Peb->NtGlobalFlag;
|
/* normalize process parameters */
|
||||||
|
RtlNormalizeProcessParams (Peb->ProcessParameters);
|
||||||
|
|
||||||
/* If MZ header exists */
|
/* Initialize NLS data */
|
||||||
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
|
RtlInitNlsTables (Peb->AnsiCodePageData,
|
||||||
DPRINT("PEDosHeader %x\n", PEDosHeader);
|
Peb->OemCodePageData,
|
||||||
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
|
Peb->UnicodeCaseTableData,
|
||||||
PEDosHeader->e_lfanew == 0L ||
|
&NlsTable);
|
||||||
*(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_PE_MAGIC)
|
RtlResetRtlTranslations (&NlsTable);
|
||||||
{
|
|
||||||
DbgPrint("Image has bad header\n");
|
|
||||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* normalize process parameters */
|
NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
|
||||||
RtlNormalizeProcessParams (Peb->ProcessParameters);
|
|
||||||
|
|
||||||
/* Initialize NLS data */
|
/* create process heap */
|
||||||
RtlInitNlsTables (Peb->AnsiCodePageData,
|
RtlInitializeHeapManager();
|
||||||
Peb->OemCodePageData,
|
Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
|
||||||
Peb->UnicodeCaseTableData,
|
(PVOID)HEAP_BASE,
|
||||||
&NlsTable);
|
NTHeaders->OptionalHeader.SizeOfHeapReserve,
|
||||||
RtlResetRtlTranslations (&NlsTable);
|
NTHeaders->OptionalHeader.SizeOfHeapCommit,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (Peb->ProcessHeap == 0)
|
||||||
|
{
|
||||||
|
DbgPrint("Failed to create process heap\n");
|
||||||
|
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
|
/* initalize peb lock support */
|
||||||
|
RtlInitializeCriticalSection (&PebLock);
|
||||||
|
Peb->FastPebLock = &PebLock;
|
||||||
|
Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
|
||||||
|
Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
|
||||||
|
|
||||||
/* create process heap */
|
/* initialize tls bitmap */
|
||||||
RtlInitializeHeapManager();
|
RtlInitializeBitMap (&TlsBitMap,
|
||||||
Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
|
Peb->TlsBitmapBits,
|
||||||
(PVOID)HEAP_BASE,
|
TLS_MINIMUM_AVAILABLE);
|
||||||
NTHeaders->OptionalHeader.SizeOfHeapReserve,
|
Peb->TlsBitmap = &TlsBitMap;
|
||||||
NTHeaders->OptionalHeader.SizeOfHeapCommit,
|
Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE;
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
if (Peb->ProcessHeap == 0)
|
|
||||||
{
|
|
||||||
DbgPrint("Failed to create process heap\n");
|
|
||||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initalize peb lock support */
|
/* Initialize table of callbacks for the kernel. */
|
||||||
RtlInitializeCriticalSection (&PebLock);
|
Peb->KernelCallbackTable =
|
||||||
Peb->FastPebLock = &PebLock;
|
RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
|
0,
|
||||||
Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
|
sizeof(PVOID) * (USER32_CALLBACK_MAXIMUM + 1));
|
||||||
|
|
||||||
/* initialize tls bitmap */
|
/* initalize loader lock */
|
||||||
RtlInitializeBitMap (&TlsBitMap,
|
RtlInitializeCriticalSection (&LoaderLock);
|
||||||
Peb->TlsBitmapBits,
|
Peb->LoaderLock = &LoaderLock;
|
||||||
TLS_MINIMUM_AVAILABLE);
|
|
||||||
Peb->TlsBitmap = &TlsBitMap;
|
|
||||||
Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE;
|
|
||||||
|
|
||||||
/* Initialize table of callbacks for the kernel. */
|
/* create loader information */
|
||||||
Peb->KernelCallbackTable =
|
Peb->Ldr = (PPEB_LDR_DATA)RtlAllocateHeap (Peb->ProcessHeap,
|
||||||
RtlAllocateHeap(RtlGetProcessHeap(),
|
0,
|
||||||
0,
|
sizeof(PEB_LDR_DATA));
|
||||||
sizeof(PVOID) * (USER32_CALLBACK_MAXIMUM + 1));
|
if (Peb->Ldr == NULL)
|
||||||
|
{
|
||||||
|
DbgPrint("Failed to create loader data\n");
|
||||||
|
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
|
||||||
|
Peb->Ldr->Initialized = FALSE;
|
||||||
|
Peb->Ldr->SsHandle = NULL;
|
||||||
|
InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
|
||||||
|
InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
|
||||||
|
InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
|
||||||
|
|
||||||
/* initalize loader lock */
|
/* Load compatibility settings */
|
||||||
RtlInitializeCriticalSection (&LoaderLock);
|
LoadCompatibilitySettings(Peb);
|
||||||
Peb->LoaderLock = &LoaderLock;
|
|
||||||
|
|
||||||
/* create loader information */
|
/* Load execution options */
|
||||||
Peb->Ldr = (PPEB_LDR_DATA)RtlAllocateHeap (Peb->ProcessHeap,
|
LoadImageFileExecutionOptions(Peb);
|
||||||
0,
|
|
||||||
sizeof(PEB_LDR_DATA));
|
|
||||||
if (Peb->Ldr == NULL)
|
|
||||||
{
|
|
||||||
DbgPrint("Failed to create loader data\n");
|
|
||||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
|
|
||||||
Peb->Ldr->Initialized = FALSE;
|
|
||||||
Peb->Ldr->SsHandle = NULL;
|
|
||||||
InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
|
|
||||||
InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
|
|
||||||
InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
|
|
||||||
|
|
||||||
/* Load compatibility settings */
|
/* build full ntdll path */
|
||||||
LoadCompatibilitySettings(Peb);
|
wcscpy (FullNtDllPath, SharedUserData->NtSystemRoot);
|
||||||
|
wcscat (FullNtDllPath, L"\\system32\\ntdll.dll");
|
||||||
|
|
||||||
/* build full ntdll path */
|
/* add entry for ntdll */
|
||||||
wcscpy (FullNtDllPath, SharedUserData->NtSystemRoot);
|
NtModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap,
|
||||||
wcscat (FullNtDllPath, L"\\system32\\ntdll.dll");
|
0,
|
||||||
|
sizeof(LDR_MODULE));
|
||||||
|
if (NtModule == NULL)
|
||||||
|
{
|
||||||
|
DbgPrint("Failed to create loader module entry (NTDLL)\n");
|
||||||
|
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
memset(NtModule, 0, sizeof(LDR_MODULE));
|
||||||
|
|
||||||
/* add entry for ntdll */
|
NtModule->BaseAddress = (PVOID)&_image_base__;
|
||||||
NtModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap,
|
NtModule->EntryPoint = 0; /* no entry point */
|
||||||
0,
|
RtlCreateUnicodeString (&NtModule->FullDllName,
|
||||||
sizeof(LDR_MODULE));
|
FullNtDllPath);
|
||||||
if (NtModule == NULL)
|
RtlCreateUnicodeString (&NtModule->BaseDllName,
|
||||||
{
|
L"ntdll.dll");
|
||||||
DbgPrint("Failed to create loader module entry (NTDLL)\n");
|
NtModule->Flags = IMAGE_DLL|ENTRY_PROCESSED;
|
||||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
memset(NtModule, 0, sizeof(LDR_MODULE));
|
|
||||||
|
|
||||||
NtModule->BaseAddress = (PVOID)&_image_base__;
|
NtModule->LoadCount = -1; /* don't unload */
|
||||||
NtModule->EntryPoint = 0; /* no entry point */
|
NtModule->TlsIndex = -1;
|
||||||
RtlCreateUnicodeString (&NtModule->FullDllName,
|
NtModule->SectionHandle = NULL;
|
||||||
FullNtDllPath);
|
NtModule->CheckSum = 0;
|
||||||
RtlCreateUnicodeString (&NtModule->BaseDllName,
|
|
||||||
L"ntdll.dll");
|
|
||||||
NtModule->Flags = 0;
|
|
||||||
NtModule->LoadCount = -1; /* don't unload */
|
|
||||||
NtModule->TlsIndex = 0;
|
|
||||||
NtModule->SectionHandle = NULL;
|
|
||||||
NtModule->CheckSum = 0;
|
|
||||||
|
|
||||||
NTHeaders = RtlImageNtHeader (NtModule->BaseAddress);
|
NTHeaders = RtlImageNtHeader (NtModule->BaseAddress);
|
||||||
NtModule->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
|
NtModule->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
|
||||||
NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||||
|
|
||||||
InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
|
InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
|
||||||
&NtModule->InLoadOrderModuleList);
|
&NtModule->InLoadOrderModuleList);
|
||||||
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
|
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
|
||||||
&NtModule->InInitializationOrderModuleList);
|
&NtModule->InInitializationOrderModuleList);
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef KDBG
|
||||||
|
|
||||||
LdrpLoadUserModuleSymbols(NtModule);
|
LdrpLoadUserModuleSymbols(NtModule);
|
||||||
|
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
|
|
||||||
/* add entry for executable (becomes first list entry) */
|
/* add entry for executable (becomes first list entry) */
|
||||||
ExeModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap,
|
ExeModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap,
|
||||||
0,
|
0,
|
||||||
sizeof(LDR_MODULE));
|
sizeof(LDR_MODULE));
|
||||||
if (ExeModule == NULL)
|
if (ExeModule == NULL)
|
||||||
{
|
{
|
||||||
DbgPrint("Failed to create loader module infomation\n");
|
DbgPrint("Failed to create loader module infomation\n");
|
||||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
ExeModule->BaseAddress = Peb->ImageBaseAddress;
|
ExeModule->BaseAddress = Peb->ImageBaseAddress;
|
||||||
|
|
||||||
if ((Peb->ProcessParameters == NULL) ||
|
if ((Peb->ProcessParameters == NULL) ||
|
||||||
(Peb->ProcessParameters->ImagePathName.Length == 0))
|
(Peb->ProcessParameters->ImagePathName.Length == 0))
|
||||||
{
|
{
|
||||||
DbgPrint("Failed to access the process parameter block\n");
|
DbgPrint("Failed to access the process parameter block\n");
|
||||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlCreateUnicodeString(&ExeModule->FullDllName,
|
RtlCreateUnicodeString(&ExeModule->FullDllName,
|
||||||
Peb->ProcessParameters->ImagePathName.Buffer);
|
Peb->ProcessParameters->ImagePathName.Buffer);
|
||||||
RtlCreateUnicodeString(&ExeModule->BaseDllName,
|
RtlCreateUnicodeString(&ExeModule->BaseDllName,
|
||||||
wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1);
|
wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1);
|
||||||
|
|
||||||
DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n",
|
DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n",
|
||||||
&ExeModule->BaseDllName,
|
&ExeModule->BaseDllName,
|
||||||
&ExeModule->FullDllName);
|
&ExeModule->FullDllName);
|
||||||
|
|
||||||
ExeModule->Flags = 0;
|
ExeModule->Flags = ENTRY_PROCESSED;
|
||||||
ExeModule->LoadCount = -1; /* don't unload */
|
ExeModule->LoadCount = -1; /* don't unload */
|
||||||
ExeModule->TlsIndex = 0;
|
ExeModule->TlsIndex = -1;
|
||||||
ExeModule->SectionHandle = NULL;
|
ExeModule->SectionHandle = NULL;
|
||||||
ExeModule->CheckSum = 0;
|
ExeModule->CheckSum = 0;
|
||||||
|
|
||||||
NTHeaders = RtlImageNtHeader (ExeModule->BaseAddress);
|
NTHeaders = RtlImageNtHeader (ExeModule->BaseAddress);
|
||||||
ExeModule->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
|
ExeModule->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
|
||||||
ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||||
|
|
||||||
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
|
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
|
||||||
&ExeModule->InLoadOrderModuleList);
|
&ExeModule->InLoadOrderModuleList);
|
||||||
|
|
||||||
LdrpInitLoader();
|
LdrpInitLoader();
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef KDBG
|
||||||
|
|
||||||
LdrpLoadUserModuleSymbols(ExeModule);
|
LdrpLoadUserModuleSymbols(ExeModule);
|
||||||
|
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
|
|
||||||
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
|
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
|
||||||
ExeModule->EntryPoint = (ULONG)EntryPoint;
|
ExeModule->EntryPoint = (ULONG)EntryPoint;
|
||||||
|
|
||||||
/* all required dlls are loaded now */
|
/* all required dlls are loaded now */
|
||||||
Peb->Ldr->Initialized = TRUE;
|
Peb->Ldr->Initialized = TRUE;
|
||||||
|
|
||||||
/* Check before returning that we can run the image safely. */
|
/* Check before returning that we can run the image safely. */
|
||||||
if (EntryPoint == NULL)
|
if (EntryPoint == NULL)
|
||||||
{
|
{
|
||||||
DbgPrint("Failed to initialize image\n");
|
DbgPrint("Failed to initialize image\n");
|
||||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/* attach the thread */
|
||||||
|
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||||
|
LdrpAttachThread();
|
||||||
|
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue