2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ldr/sysdll.c
5 * PURPOSE: Loaders for PE executables
6 * PROGRAMMERS: Jean Michault
7 * Rex Jolliff (rex@lvcablemodem.com)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/module.h>
16 #include <internal/ntoskrnl.h>
17 #include <internal/ob.h>
18 #include <internal/ps.h>
19 #include <internal/ldr.h>
22 #include <internal/debug.h>
24 /* GLOBALS *******************************************************************/
26 static PVOID SystemDllEntryPoint = NULL;
27 static PVOID SystemDllApcDispatcher = NULL;
28 static PVOID SystemDllCallbackDispatcher = NULL;
29 static PVOID SystemDllExceptionDispatcher = NULL;
31 /* FUNCTIONS *****************************************************************/
33 PVOID LdrpGetSystemDllExceptionDispatcher(VOID)
35 return(SystemDllExceptionDispatcher);
38 PVOID LdrpGetSystemDllCallbackDispatcher(VOID)
40 return(SystemDllCallbackDispatcher);
43 PVOID LdrpGetSystemDllEntryPoint(VOID)
45 return(SystemDllEntryPoint);
48 PVOID LdrpGetSystemDllApcDispatcher(VOID)
50 return(SystemDllApcDispatcher);
53 NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle,
54 PVOID* LdrStartupAddr)
56 * FUNCTION: LdrpMapSystemDll maps the system dll into the specified process
57 * address space and returns its startup address.
60 * Points to the process to map the system dll into
63 * Receives the startup address of the system dll on function
69 CHAR BlockBuffer [1024];
73 OBJECT_ATTRIBUTES FileObjectAttributes;
75 HANDLE NTDllSectionHandle;
76 UNICODE_STRING DllPathname = UNICODE_STRING_INITIALIZER(L"\\SystemRoot\\system32\\ntdll.dll");
77 PIMAGE_DOS_HEADER DosHeader;
78 PIMAGE_NT_HEADERS NTHeaders;
80 ANSI_STRING ProcedureName;
85 * Locate and open NTDLL to determine ImageBase
88 InitializeObjectAttributes(&FileObjectAttributes,
93 DPRINT("Opening NTDLL\n");
94 Status = ZwOpenFile(&FileHandle,
96 &FileObjectAttributes,
99 FILE_SYNCHRONOUS_IO_NONALERT);
100 if (!NT_SUCCESS(Status))
102 DbgPrint("NTDLL open failed (Status %x)\n", Status);
105 Status = ZwReadFile(FileHandle,
114 if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer))
116 DbgPrint("NTDLL header read failed (Status %x)\n", Status);
122 * FIXME: this will fail if the NT headers are
123 * more than 1024 bytes from start.
125 DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
126 NTHeaders = (PIMAGE_NT_HEADERS) (BlockBuffer + DosHeader->e_lfanew);
127 if ((DosHeader->e_magic != IMAGE_DOS_MAGIC)
128 || (DosHeader->e_lfanew == 0L)
129 || (*(PULONG) NTHeaders != IMAGE_PE_MAGIC))
131 DbgPrint("NTDLL format invalid\n");
133 return(STATUS_UNSUCCESSFUL);
135 ImageBase = NTHeaders->OptionalHeader.ImageBase;
136 ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
139 * Create a section for NTDLL
141 DPRINT("Creating section\n");
142 Status = ZwCreateSection(&NTDllSectionHandle,
147 SEC_IMAGE | SEC_COMMIT,
149 if (!NT_SUCCESS(Status))
151 DbgPrint("NTDLL create section failed (Status %x)\n", Status);
158 * Map the NTDLL into the process
162 Status = ZwMapViewOfSection(NTDllSectionHandle,
172 if (!NT_SUCCESS(Status))
174 DbgPrint("NTDLL map view of secion failed (Status %x)", Status);
175 ZwClose(NTDllSectionHandle);
179 DPRINT("Referencing process\n");
180 Status = ObReferenceObjectByHandle(ProcessHandle,
186 if (!NT_SUCCESS(Status))
188 DbgPrint("ObReferenceObjectByProcess() failed (Status %x)\n", Status);
192 DPRINT("Attaching to Process\n");
193 KeAttachProcess(Process);
196 * retrieve ntdll's startup address
198 if (SystemDllEntryPoint == NULL)
200 RtlInitAnsiString (&ProcedureName,
201 "LdrInitializeThunk");
202 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
205 &SystemDllEntryPoint);
206 if (!NT_SUCCESS(Status))
208 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
210 ObDereferenceObject(Process);
211 ZwClose(NTDllSectionHandle);
214 *LdrStartupAddr = SystemDllEntryPoint;
218 * Retrieve the offset of the APC dispatcher from NTDLL
220 if (SystemDllApcDispatcher == NULL)
222 RtlInitAnsiString (&ProcedureName,
223 "KiUserApcDispatcher");
224 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
227 &SystemDllApcDispatcher);
228 if (!NT_SUCCESS(Status))
230 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
232 ObDereferenceObject(Process);
233 ZwClose(NTDllSectionHandle);
239 * Retrieve the offset of the exception dispatcher from NTDLL
241 if (SystemDllExceptionDispatcher == NULL)
243 RtlInitAnsiString (&ProcedureName,
244 "KiUserExceptionDispatcher");
245 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
248 &SystemDllExceptionDispatcher);
249 if (!NT_SUCCESS(Status))
251 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
253 ObDereferenceObject(Process);
254 ZwClose(NTDllSectionHandle);
260 * Retrieve the offset of the callback dispatcher from NTDLL
262 if (SystemDllCallbackDispatcher == NULL)
264 RtlInitAnsiString (&ProcedureName,
265 "KiUserCallbackDispatcher");
266 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
269 &SystemDllCallbackDispatcher);
270 if (!NT_SUCCESS(Status))
272 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
274 ObDereferenceObject(Process);
275 ZwClose(NTDllSectionHandle);
281 ObDereferenceObject(Process);
283 ZwClose(NTDllSectionHandle);
285 return(STATUS_SUCCESS);