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)
10 * Skywing 09/11/2003 Added support for KiRaiseUserExceptionDispatcher
13 /* INCLUDES *****************************************************************/
15 #include <ddk/ntddk.h>
16 #include <internal/module.h>
17 #include <internal/ntoskrnl.h>
18 #include <internal/ob.h>
19 #include <internal/ps.h>
20 #include <internal/ldr.h>
23 #include <internal/debug.h>
25 /* GLOBALS *******************************************************************/
27 static PVOID SystemDllEntryPoint = NULL;
28 static PVOID SystemDllApcDispatcher = NULL;
29 static PVOID SystemDllCallbackDispatcher = NULL;
30 static PVOID SystemDllExceptionDispatcher = NULL;
31 static PVOID SystemDllRaiseExceptionDispatcher = NULL;
33 /* FUNCTIONS *****************************************************************/
35 PVOID LdrpGetSystemDllExceptionDispatcher(VOID)
37 return(SystemDllExceptionDispatcher);
40 PVOID LdrpGetSystemDllCallbackDispatcher(VOID)
42 return(SystemDllCallbackDispatcher);
45 PVOID LdrpGetSystemDllEntryPoint(VOID)
47 return(SystemDllEntryPoint);
50 PVOID LdrpGetSystemDllApcDispatcher(VOID)
52 return(SystemDllApcDispatcher);
55 PVOID LdrpGetSystemDllRaiseExceptionDispatcher(VOID)
57 return(SystemDllRaiseExceptionDispatcher);
60 NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle,
61 PVOID* LdrStartupAddr)
63 * FUNCTION: LdrpMapSystemDll maps the system dll into the specified process
64 * address space and returns its startup address.
67 * Points to the process to map the system dll into
70 * Receives the startup address of the system dll on function
76 CHAR BlockBuffer [1024];
80 OBJECT_ATTRIBUTES FileObjectAttributes;
82 HANDLE NTDllSectionHandle;
83 UNICODE_STRING DllPathname = UNICODE_STRING_INITIALIZER(L"\\SystemRoot\\system32\\ntdll.dll");
84 PIMAGE_DOS_HEADER DosHeader;
85 PIMAGE_NT_HEADERS NTHeaders;
87 ANSI_STRING ProcedureName;
92 * Locate and open NTDLL to determine ImageBase
95 InitializeObjectAttributes(&FileObjectAttributes,
100 DPRINT("Opening NTDLL\n");
101 Status = ZwOpenFile(&FileHandle,
103 &FileObjectAttributes,
106 FILE_SYNCHRONOUS_IO_NONALERT);
107 if (!NT_SUCCESS(Status))
109 DbgPrint("NTDLL open failed (Status %x)\n", Status);
112 Status = ZwReadFile(FileHandle,
121 if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer))
123 DbgPrint("NTDLL header read failed (Status %x)\n", Status);
129 * FIXME: this will fail if the NT headers are
130 * more than 1024 bytes from start.
132 DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
133 NTHeaders = (PIMAGE_NT_HEADERS) (BlockBuffer + DosHeader->e_lfanew);
134 if ((DosHeader->e_magic != IMAGE_DOS_MAGIC)
135 || (DosHeader->e_lfanew == 0L)
136 || (*(PULONG) NTHeaders != IMAGE_PE_MAGIC))
138 DbgPrint("NTDLL format invalid\n");
140 return(STATUS_UNSUCCESSFUL);
142 ImageBase = NTHeaders->OptionalHeader.ImageBase;
143 ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
146 * Create a section for NTDLL
148 DPRINT("Creating section\n");
149 Status = ZwCreateSection(&NTDllSectionHandle,
154 SEC_IMAGE | SEC_COMMIT,
156 if (!NT_SUCCESS(Status))
158 DbgPrint("NTDLL create section failed (Status %x)\n", Status);
165 * Map the NTDLL into the process
169 Status = ZwMapViewOfSection(NTDllSectionHandle,
179 if (!NT_SUCCESS(Status))
181 DbgPrint("NTDLL map view of secion failed (Status %x)", Status);
182 ZwClose(NTDllSectionHandle);
186 DPRINT("Referencing process\n");
187 Status = ObReferenceObjectByHandle(ProcessHandle,
193 if (!NT_SUCCESS(Status))
195 DbgPrint("ObReferenceObjectByProcess() failed (Status %x)\n", Status);
199 DPRINT("Attaching to Process\n");
200 KeAttachProcess(Process);
203 * retrieve ntdll's startup address
205 if (SystemDllEntryPoint == NULL)
207 RtlInitAnsiString (&ProcedureName,
208 "LdrInitializeThunk");
209 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
212 &SystemDllEntryPoint);
213 if (!NT_SUCCESS(Status))
215 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
217 ObDereferenceObject(Process);
218 ZwClose(NTDllSectionHandle);
221 *LdrStartupAddr = SystemDllEntryPoint;
225 * Retrieve the offset of the APC dispatcher from NTDLL
227 if (SystemDllApcDispatcher == NULL)
229 RtlInitAnsiString (&ProcedureName,
230 "KiUserApcDispatcher");
231 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
234 &SystemDllApcDispatcher);
235 if (!NT_SUCCESS(Status))
237 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
239 ObDereferenceObject(Process);
240 ZwClose(NTDllSectionHandle);
246 * Retrieve the offset of the exception dispatcher from NTDLL
248 if (SystemDllExceptionDispatcher == NULL)
250 RtlInitAnsiString (&ProcedureName,
251 "KiUserExceptionDispatcher");
252 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
255 &SystemDllExceptionDispatcher);
256 if (!NT_SUCCESS(Status))
258 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
260 ObDereferenceObject(Process);
261 ZwClose(NTDllSectionHandle);
267 * Retrieve the offset of the callback dispatcher from NTDLL
269 if (SystemDllCallbackDispatcher == NULL)
271 RtlInitAnsiString (&ProcedureName,
272 "KiUserCallbackDispatcher");
273 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
276 &SystemDllCallbackDispatcher);
277 if (!NT_SUCCESS(Status))
279 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
281 ObDereferenceObject(Process);
282 ZwClose(NTDllSectionHandle);
288 * Retrieve the offset of the raise exception dispatcher from NTDLL
290 if (SystemDllRaiseExceptionDispatcher == NULL)
292 RtlInitAnsiString (&ProcedureName,
293 "KiRaiseUserExceptionDispatcher");
294 Status = LdrGetProcedureAddress ((PVOID)ImageBase,
297 &SystemDllRaiseExceptionDispatcher);
298 if (!NT_SUCCESS(Status))
300 DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
302 ObDereferenceObject(Process);
303 ZwClose(NTDllSectionHandle);
309 ObDereferenceObject(Process);
311 ZwClose(NTDllSectionHandle);
313 return(STATUS_SUCCESS);