1 /* $Id: loader.c,v 1.97 2002/02/09 19:20:44 chorns Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ldr/loader.c
6 * PURPOSE: Loaders for PE executables
7 * PROGRAMMERS: Jean Michault
8 * Rex Jolliff (rex@lvcablemodem.com)
9 * Jason Filby (jasonfilby@yahoo.com)
10 * Casper S. Hornstrup (chorns@users.sourceforge.net)
13 * RJJ 10/12/98 Completed image loader function and added hooks for MZ/PE
14 * RJJ 10/12/98 Built driver loader function and added hooks for PE/COFF
15 * RJJ 10/12/98 Rolled in David's code to load COFF drivers
16 * JM 14/12/98 Built initial PE user module loader
17 * RJJ 06/03/99 Moved user PE loader into NTDLL
18 * JF 26/01/2000 Recoded some parts to retrieve export details correctly
19 * DW 27/06/2000 Removed redundant header files
20 * CSH 11/04/2001 Added automatic loading of module symbols if they exist
24 /* INCLUDES *****************************************************************/
27 #include <ddk/ntddk.h>
29 #include <internal/module.h>
30 #include <internal/ntoskrnl.h>
31 #include <internal/kd.h>
32 #include <internal/io.h>
33 #include <internal/mm.h>
34 #include <internal/ob.h>
35 #include <internal/ps.h>
36 #include <internal/ldr.h>
37 #include <internal/pool.h>
40 #include <internal/ntosdbg.h>
46 #include <internal/debug.h>
48 /* MACROS ********************************************************************/
50 #define KERNEL_MODULE_NAME L"ntoskrnl.exe"
51 #define HAL_MODULE_NAME L"hal.dll"
52 #define MODULE_ROOT_NAME L"\\Modules\\"
53 #define FILESYSTEM_ROOT_NAME L"\\FileSystem\\"
55 /* GLOBALS *******************************************************************/
57 LIST_ENTRY ModuleListHead
;
58 POBJECT_TYPE EXPORTED IoDriverObjectType
= NULL
;
59 LIST_ENTRY ModuleTextListHead
;
60 STATIC MODULE_TEXT_SECTION NtoskrnlTextSection
;
61 STATIC MODULE_TEXT_SECTION LdrHalTextSection
;
64 #define TAG_DRIVER_MEM TAG('D', 'R', 'V', 'M')
65 #define TAG_SYM_BUF TAG('S', 'Y', 'M', 'B')
67 /* FORWARD DECLARATIONS ******************************************************/
69 PMODULE_OBJECT
LdrLoadModule(PUNICODE_STRING Filename
);
70 NTSTATUS
LdrProcessModule(PVOID ModuleLoadBase
,
71 PUNICODE_STRING ModuleName
,
72 PMODULE_OBJECT
*ModuleObject
);
73 PVOID
LdrGetExportAddress(PMODULE_OBJECT ModuleObject
, char *Name
, unsigned short Hint
);
74 static PMODULE_OBJECT
LdrOpenModule(PUNICODE_STRING Filename
);
75 static NTSTATUS STDCALL
76 LdrCreateModule(PVOID ObjectBody
,
79 POBJECT_ATTRIBUTES ObjectAttributes
);
80 static VOID
LdrpBuildModuleBaseName(PUNICODE_STRING BaseName
,
81 PUNICODE_STRING FullName
);
83 /* PE Driver load support */
84 static NTSTATUS
LdrPEProcessModule(PVOID ModuleLoadBase
,
85 PUNICODE_STRING FileName
,
86 PMODULE_OBJECT
*ModuleObject
);
87 static PVOID
LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject
,
90 static PMODULE_OBJECT
LdrPEGetModuleObject(PUNICODE_STRING ModuleName
);
91 static PVOID
LdrPEFixupForward(PCHAR ForwardName
);
94 LdrSafePEGetExportAddress(
95 PVOID ImportModuleBase
,
100 /* FUNCTIONS *****************************************************************/
103 LdrInitDebug(PLOADER_MODULE Module
, PWCH Name
)
105 PLIST_ENTRY current_entry
;
106 MODULE_TEXT_SECTION
* current
;
108 current_entry
= ModuleTextListHead
.Flink
;
109 while (current_entry
!= &ModuleTextListHead
)
112 CONTAINING_RECORD(current_entry
, MODULE_TEXT_SECTION
, ListEntry
);
113 if (wcscmp(current
->Name
, Name
) == 0)
117 current_entry
= current_entry
->Flink
;
120 if (current_entry
== &ModuleTextListHead
)
125 current
->SymbolsBase
= (PVOID
)Module
->ModStart
;
126 current
->SymbolsLength
= Module
->ModEnd
- Module
->ModStart
;
132 PIMAGE_DOS_HEADER DosHeader
;
133 PIMAGE_FILE_HEADER FileHeader
;
134 PIMAGE_OPTIONAL_HEADER OptionalHeader
;
135 PIMAGE_SECTION_HEADER SectionList
;
137 InitializeListHead(&ModuleTextListHead
);
139 /* Setup ntoskrnl.exe text section */
140 DosHeader
= (PIMAGE_DOS_HEADER
) KERNEL_BASE
;
142 (PIMAGE_FILE_HEADER
) ((DWORD
)KERNEL_BASE
+
143 DosHeader
->e_lfanew
+ sizeof(ULONG
));
144 OptionalHeader
= (PIMAGE_OPTIONAL_HEADER
)
145 ((DWORD
)FileHeader
+ sizeof(IMAGE_FILE_HEADER
));
146 SectionList
= (PIMAGE_SECTION_HEADER
)
147 ((DWORD
)OptionalHeader
+ sizeof(IMAGE_OPTIONAL_HEADER
));
148 NtoskrnlTextSection
.Base
= KERNEL_BASE
;
149 NtoskrnlTextSection
.Length
= SectionList
[0].Misc
.VirtualSize
+
150 SectionList
[0].VirtualAddress
;
151 NtoskrnlTextSection
.Name
= KERNEL_MODULE_NAME
;
152 NtoskrnlTextSection
.SymbolsBase
= NULL
;
153 NtoskrnlTextSection
.SymbolsLength
= 0;
154 InsertTailList(&ModuleTextListHead
, &NtoskrnlTextSection
.ListEntry
);
156 /* Setup hal.dll text section */
157 DosHeader
= (PIMAGE_DOS_HEADER
)LdrHalBase
;
159 (PIMAGE_FILE_HEADER
) ((DWORD
)LdrHalBase
+
160 DosHeader
->e_lfanew
+ sizeof(ULONG
));
161 OptionalHeader
= (PIMAGE_OPTIONAL_HEADER
)
162 ((DWORD
)FileHeader
+ sizeof(IMAGE_FILE_HEADER
));
163 SectionList
= (PIMAGE_SECTION_HEADER
)
164 ((DWORD
)OptionalHeader
+ sizeof(IMAGE_OPTIONAL_HEADER
));
165 LdrHalTextSection
.Base
= LdrHalBase
;
166 LdrHalTextSection
.Length
= SectionList
[0].Misc
.VirtualSize
+
167 SectionList
[0].VirtualAddress
;
168 LdrHalTextSection
.Name
= HAL_MODULE_NAME
;
169 LdrHalTextSection
.SymbolsBase
= NULL
;
170 LdrHalTextSection
.SymbolsLength
= 0;
171 InsertTailList(&ModuleTextListHead
, &LdrHalTextSection
.ListEntry
);
174 VOID
LdrInitModuleManagement(VOID
)
176 HANDLE DirHandle
, ModuleHandle
;
178 WCHAR NameBuffer
[60];
179 UNICODE_STRING ModuleName
;
180 OBJECT_ATTRIBUTES ObjectAttributes
;
181 PIMAGE_DOS_HEADER DosHeader
;
182 PMODULE_OBJECT ModuleObject
;
184 /* Register the process object type */
185 IoDriverObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
186 IoDriverObjectType
->Tag
= TAG('D', 'R', 'V', 'T');
187 IoDriverObjectType
->TotalObjects
= 0;
188 IoDriverObjectType
->TotalHandles
= 0;
189 IoDriverObjectType
->MaxObjects
= ULONG_MAX
;
190 IoDriverObjectType
->MaxHandles
= ULONG_MAX
;
191 IoDriverObjectType
->PagedPoolCharge
= 0;
192 IoDriverObjectType
->NonpagedPoolCharge
= sizeof(MODULE
);
193 IoDriverObjectType
->Dump
= NULL
;
194 IoDriverObjectType
->Open
= NULL
;
195 IoDriverObjectType
->Close
= NULL
;
196 IoDriverObjectType
->Delete
= NULL
;
197 IoDriverObjectType
->Parse
= NULL
;
198 IoDriverObjectType
->Security
= NULL
;
199 IoDriverObjectType
->QueryName
= NULL
;
200 IoDriverObjectType
->OkayToClose
= NULL
;
201 IoDriverObjectType
->Create
= LdrCreateModule
;
202 IoDriverObjectType
->DuplicationNotify
= NULL
;
203 RtlInitUnicodeString(&IoDriverObjectType
->TypeName
, L
"Driver");
205 /* Create Modules object directory */
206 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
207 *(wcsrchr(NameBuffer
, L
'\\')) = 0;
208 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
209 InitializeObjectAttributes(&ObjectAttributes
,
214 DPRINT("Create dir: %wZ\n", &ModuleName
);
215 Status
= NtCreateDirectoryObject(&DirHandle
, 0, &ObjectAttributes
);
216 assert(NT_SUCCESS(Status
));
218 /* Create FileSystem object directory */
219 wcscpy(NameBuffer
, FILESYSTEM_ROOT_NAME
);
220 *(wcsrchr(NameBuffer
, L
'\\')) = 0;
221 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
222 InitializeObjectAttributes(&ObjectAttributes
,
227 DPRINT("Create dir: %wZ\n", &ModuleName
);
228 Status
= NtCreateDirectoryObject(&DirHandle
, 0, &ObjectAttributes
);
229 assert(NT_SUCCESS(Status
));
231 /* Add module entry for NTOSKRNL */
232 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
233 wcscat(NameBuffer
, KERNEL_MODULE_NAME
);
234 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
235 DPRINT("Kernel's Module name is: %wZ\n", &ModuleName
);
237 /* Initialize ObjectAttributes for ModuleObject */
238 InitializeObjectAttributes(&ObjectAttributes
,
244 /* Create module object */
246 Status
= ObCreateObject(&ModuleHandle
,
247 STANDARD_RIGHTS_REQUIRED
,
250 (PVOID
*)&ModuleObject
);
251 assert(NT_SUCCESS(Status
));
253 InitializeListHead(&ModuleListHead
);
255 /* Initialize ModuleObject data */
256 ModuleObject
->Base
= (PVOID
) KERNEL_BASE
;
257 ModuleObject
->Flags
= MODULE_FLAG_PE
;
258 InsertTailList(&ModuleListHead
,
259 &ModuleObject
->ListEntry
);
260 RtlCreateUnicodeString(&ModuleObject
->FullName
,
262 LdrpBuildModuleBaseName(&ModuleObject
->BaseName
,
263 &ModuleObject
->FullName
);
265 DosHeader
= (PIMAGE_DOS_HEADER
) KERNEL_BASE
;
266 ModuleObject
->Image
.PE
.FileHeader
=
267 (PIMAGE_FILE_HEADER
) ((DWORD
) ModuleObject
->Base
+
268 DosHeader
->e_lfanew
+ sizeof(ULONG
));
269 ModuleObject
->Image
.PE
.OptionalHeader
= (PIMAGE_OPTIONAL_HEADER
)
270 ((DWORD
)ModuleObject
->Image
.PE
.FileHeader
+ sizeof(IMAGE_FILE_HEADER
));
271 ModuleObject
->Image
.PE
.SectionList
= (PIMAGE_SECTION_HEADER
)
272 ((DWORD
)ModuleObject
->Image
.PE
.OptionalHeader
+ sizeof(IMAGE_OPTIONAL_HEADER
));
273 ModuleObject
->EntryPoint
= (PVOID
) ((DWORD
) ModuleObject
->Base
+
274 ModuleObject
->Image
.PE
.OptionalHeader
->AddressOfEntryPoint
);
275 DPRINT("ModuleObject:%08x entrypoint at %x\n", ModuleObject
, ModuleObject
->EntryPoint
);
276 ModuleObject
->Length
= ModuleObject
->Image
.PE
.OptionalHeader
->SizeOfImage
;
277 ModuleObject
->TextSection
= &NtoskrnlTextSection
;
279 /* Add module entry for HAL */
280 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
281 wcscat(NameBuffer
, HAL_MODULE_NAME
);
282 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
283 DPRINT("HAL's Module name is: %wZ\n", &ModuleName
);
285 /* Initialize ObjectAttributes for ModuleObject */
286 InitializeObjectAttributes(&ObjectAttributes
,
292 /* Create module object */
294 Status
= ObCreateObject(&ModuleHandle
,
295 STANDARD_RIGHTS_REQUIRED
,
298 (PVOID
*)&ModuleObject
);
299 assert(NT_SUCCESS(Status
));
301 /* Initialize ModuleObject data */
302 ModuleObject
->Base
= (PVOID
) LdrHalBase
;
303 ModuleObject
->Flags
= MODULE_FLAG_PE
;
304 InsertTailList(&ModuleListHead
,
305 &ModuleObject
->ListEntry
);
306 RtlCreateUnicodeString(&ModuleObject
->FullName
,
308 LdrpBuildModuleBaseName(&ModuleObject
->BaseName
,
309 &ModuleObject
->FullName
);
311 DosHeader
= (PIMAGE_DOS_HEADER
) LdrHalBase
;
312 ModuleObject
->Image
.PE
.FileHeader
=
313 (PIMAGE_FILE_HEADER
) ((DWORD
) ModuleObject
->Base
+
314 DosHeader
->e_lfanew
+ sizeof(ULONG
));
315 ModuleObject
->Image
.PE
.OptionalHeader
= (PIMAGE_OPTIONAL_HEADER
)
316 ((DWORD
)ModuleObject
->Image
.PE
.FileHeader
+ sizeof(IMAGE_FILE_HEADER
));
317 ModuleObject
->Image
.PE
.SectionList
= (PIMAGE_SECTION_HEADER
)
318 ((DWORD
)ModuleObject
->Image
.PE
.OptionalHeader
+ sizeof(IMAGE_OPTIONAL_HEADER
));
319 ModuleObject
->EntryPoint
= (PVOID
) ((DWORD
) ModuleObject
->Base
+
320 ModuleObject
->Image
.PE
.OptionalHeader
->AddressOfEntryPoint
);
321 DPRINT("ModuleObject:%08x entrypoint at %x\n", ModuleObject
, ModuleObject
->EntryPoint
);
322 ModuleObject
->Length
= ModuleObject
->Image
.PE
.OptionalHeader
->SizeOfImage
;
323 ModuleObject
->TextSection
= &LdrHalTextSection
;
328 LdrpOpenModuleDirectory(PHANDLE Handle
)
330 OBJECT_ATTRIBUTES ObjectAttributes
;
331 UNICODE_STRING ModuleDirectory
;
333 RtlInitUnicodeString (&ModuleDirectory
, MODULE_ROOT_NAME
);
334 InitializeObjectAttributes(&ObjectAttributes
,
336 OBJ_CASE_INSENSITIVE
,
340 return NtOpenDirectoryObject(Handle
, GENERIC_ALL
, &ObjectAttributes
);
345 * load the auto config drivers.
347 static VOID
LdrLoadAutoConfigDriver (LPWSTR RelativeDriverName
)
349 WCHAR TmpFileName
[MAX_PATH
];
350 UNICODE_STRING DriverName
;
351 PDEVICE_NODE DeviceNode
;
354 CPRINT("Loading %S\n",RelativeDriverName
);
356 wcscpy(TmpFileName
, L
"\\SystemRoot\\system32\\drivers\\");
357 wcscat(TmpFileName
, RelativeDriverName
);
358 RtlInitUnicodeString (&DriverName
, TmpFileName
);
360 /* Use IopRootDeviceNode for now */
361 Status
= IopCreateDeviceNode(IopRootDeviceNode
, NULL
, &DeviceNode
);
362 if (!NT_SUCCESS(Status
))
367 Status
= LdrLoadDriver(&DriverName
, DeviceNode
, FALSE
);
368 if (!NT_SUCCESS(Status
))
370 IopFreeDeviceNode(DeviceNode
);
371 DPRINT1("Driver load failed, status (%x)\n", Status
);
377 BOOLEAN
LdrpReadLine(PCHAR Line
,
392 while ((*Size
> 0) && (Count
< LineSize
) && ((ch
= *Block
) != (CHAR
)13))
408 if ((*Size
> 0) && (*Block
== (CHAR
)10))
419 ULONG
HexL(PCHAR Buffer
)
428 while ((j
> 0) && ((ch
= Buffer
[i
]) != ' '))
431 if ((ch
>= '0') && (ch
<= '9'))
432 Value
|= ((ch
- '0') << j
);
433 if ((ch
>= 'A') && (ch
<= 'F'))
434 Value
|= ((10 + (ch
- 'A')) << j
);
436 if ((ch
>= 'a') && (ch
<= 'f'))
437 Value
|= ((10 + (ch
- 'a')) << j
);
443 PSYMBOL
LdrpParseLine(PCHAR Line
,
445 PBOOLEAN TextBaseValid
,
448 Line format: [ADDRESS] <TYPE> <NAME>
451 A = Image information
452 t = Symbol in text segment
453 T = Symbol in text segment
454 d = Symbol in data segment
455 D = Symbol in data segment
456 b = Symbol in BSS segment
457 B = Symbol in BSS segment
458 ? = Unknown segment or symbol in unknown segment
461 ANSI_STRING AnsiString
;
468 if ((Line
[0] == (CHAR
)0) || (Line
[0] == ' '))
471 Address
= HexL(Line
);
473 Line
= strchr(Line
, ' ');
480 Line
= strchr(Line
, ' ');
485 Str
= strchr(Line
, ' ');
487 strcpy((char*)&Buffer
, Line
);
489 strncpy((char*)&Buffer
, Line
, Str
- Line
);
491 if ((Type
== 'A') && (strcmp((char*)&Buffer
, "__section_alignment__")) == 0)
493 *Alignment
= Address
;
497 /* We only want symbols in the .text segment */
498 if ((Type
!= 't') && (Type
!= 'T'))
501 /* Discard other symbols we can't use */
502 if ((Buffer
[0] != '_') || ((Buffer
[0] == '_') && (Buffer
[1] == '_')))
505 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
511 Symbol
->RelativeAddress
= Address
;
513 RtlInitAnsiString(&AnsiString
, (PCSZ
)&Buffer
);
514 RtlAnsiStringToUnicodeString(&Symbol
->Name
, &AnsiString
, TRUE
);
516 if (!(*TextBaseValid
))
518 *TextBase
= Address
- *Alignment
;
519 *TextBaseValid
= TRUE
;
525 VOID
LdrpLoadModuleSymbolsFromBuffer(
526 PMODULE_OBJECT ModuleObject
,
530 Symbols must be sorted by address, e.g.
531 "nm --numeric-sort module.sys > module.sym"
534 PSYMBOL Symbol
, CurrentSymbol
= NULL
;
535 BOOLEAN TextBaseValid
;
542 assert(ModuleObject
);
544 if (ModuleObject
->TextSection
== NULL
)
546 ModuleObject
->TextSection
= &NtoskrnlTextSection
;
549 if (ModuleObject
->TextSection
->Symbols
.SymbolCount
> 0)
551 CPRINT("Symbols are already loaded for %wZ\n", &ModuleObject
->BaseName
);
555 ModuleObject
->TextSection
->Symbols
.SymbolCount
= 0;
556 ModuleObject
->TextSection
->Symbols
.Symbols
= NULL
;
557 TextBaseValid
= FALSE
;
559 while (LdrpReadLine((PCHAR
)&Line
, 256, &Buffer
, &Length
))
561 Symbol
= LdrpParseLine((PCHAR
)&Line
, &Tmp
, &Valid
, &Alignment
);
563 if ((Valid
) && (!TextBaseValid
))
566 TextBaseValid
= TRUE
;
571 Symbol
->RelativeAddress
-= TextBase
;
573 if (ModuleObject
->TextSection
->Symbols
.Symbols
== NULL
)
574 ModuleObject
->TextSection
->Symbols
.Symbols
= Symbol
;
576 CurrentSymbol
->Next
= Symbol
;
578 CurrentSymbol
= Symbol
;
580 ModuleObject
->TextSection
->Symbols
.SymbolCount
++;
585 VOID
LdrpLoadUserModuleSymbolsFromBuffer(
586 PLDR_MODULE ModuleObject
,
590 Symbols must be sorted by address, e.g.
591 "nm --numeric-sort module.dll > module.sym"
594 PSYMBOL Symbol
, CurrentSymbol
= NULL
;
595 BOOLEAN TextBaseValid
;
602 if (ModuleObject
->Symbols
.SymbolCount
> 0)
604 DPRINT("Symbols are already loaded for %wZ\n", &ModuleObject
->BaseDllName
);
608 ModuleObject
->Symbols
.SymbolCount
= 0;
609 ModuleObject
->Symbols
.Symbols
= NULL
;
610 TextBaseValid
= FALSE
;
612 while (LdrpReadLine((PCHAR
)&Line
, 256, &Buffer
, &Length
))
614 Symbol
= LdrpParseLine((PCHAR
)&Line
, &Tmp
, &Valid
, &Alignment
);
616 if ((Valid
) && (!TextBaseValid
))
619 TextBaseValid
= TRUE
;
624 Symbol
->RelativeAddress
-= TextBase
;
626 if (ModuleObject
->Symbols
.Symbols
== NULL
)
627 ModuleObject
->Symbols
.Symbols
= Symbol
;
629 CurrentSymbol
->Next
= Symbol
;
631 CurrentSymbol
= Symbol
;
633 ModuleObject
->Symbols
.SymbolCount
++;
639 LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject
)
641 FILE_STANDARD_INFORMATION FileStdInfo
;
642 OBJECT_ATTRIBUTES ObjectAttributes
;
643 WCHAR TmpFileName
[MAX_PATH
];
644 UNICODE_STRING Filename
;
650 IO_STATUS_BLOCK IoStatusBlock
;
652 ModuleObject
->TextSection
->Symbols
.SymbolCount
= 0;
653 ModuleObject
->TextSection
->Symbols
.Symbols
= NULL
;
655 /* Get the path to the symbol store */
656 wcscpy(TmpFileName
, L
"\\SystemRoot\\symbols\\");
658 /* Get the symbol filename from the module name */
659 Start
= wcsrchr(ModuleObject
->BaseName
.Buffer
, L
'\\');
661 Start
= ModuleObject
->BaseName
.Buffer
;
665 Ext
= wcsrchr(ModuleObject
->BaseName
.Buffer
, L
'.');
667 Length
= Ext
- Start
;
669 Length
= wcslen(Start
);
671 wcsncat(TmpFileName
, Start
, Length
);
672 wcscat(TmpFileName
, L
".sym");
673 RtlInitUnicodeString(&Filename
, TmpFileName
);
676 InitializeObjectAttributes(&ObjectAttributes
,
682 Status
= ZwOpenFile(&FileHandle
,
688 if (!NT_SUCCESS(Status
))
690 DPRINT("Could not open symbol file: %wZ\n", &Filename
);
694 CPRINT("Loading symbols from %wZ...\n", &Filename
);
696 /* Get the size of the file */
697 Status
= ZwQueryInformationFile(FileHandle
,
701 FileStandardInformation
);
702 if (!NT_SUCCESS(Status
))
704 DPRINT("Could not get file size\n");
708 /* Allocate nonpageable memory for symbol file */
709 FileBuffer
= ExAllocatePool(NonPagedPool
,
710 FileStdInfo
.EndOfFile
.u
.LowPart
);
712 if (FileBuffer
== NULL
)
714 DPRINT("Could not allocate memory for symbol file\n");
718 /* Load file into memory chunk */
719 Status
= ZwReadFile(FileHandle
,
723 FileStdInfo
.EndOfFile
.u
.LowPart
,
725 if (!NT_SUCCESS(Status
))
727 DPRINT("Could not read symbol file into memory\n");
728 ExFreePool(FileBuffer
);
734 LdrpLoadModuleSymbolsFromBuffer(ModuleObject
,
736 FileStdInfo
.EndOfFile
.u
.LowPart
);
738 ExFreePool(FileBuffer
);
741 VOID
LdrLoadUserModuleSymbols(PLDR_MODULE ModuleObject
)
743 FILE_STANDARD_INFORMATION FileStdInfo
;
744 OBJECT_ATTRIBUTES ObjectAttributes
;
745 WCHAR TmpFileName
[MAX_PATH
];
746 UNICODE_STRING Filename
;
752 IO_STATUS_BLOCK IoStatusBlock
;
754 ModuleObject
->Symbols
.SymbolCount
= 0;
755 ModuleObject
->Symbols
.Symbols
= NULL
;
757 /* Get the path to the symbol store */
758 wcscpy(TmpFileName
, L
"\\SystemRoot\\symbols\\");
760 /* Get the symbol filename from the module name */
761 Start
= wcsrchr(ModuleObject
->BaseDllName
.Buffer
, L
'\\');
763 Start
= ModuleObject
->BaseDllName
.Buffer
;
767 Ext
= wcsrchr(ModuleObject
->BaseDllName
.Buffer
, L
'.');
769 Length
= Ext
- Start
;
771 Length
= wcslen(Start
);
773 wcsncat(TmpFileName
, Start
, Length
);
774 wcscat(TmpFileName
, L
".sym");
775 RtlInitUnicodeString(&Filename
, TmpFileName
);
778 InitializeObjectAttributes(&ObjectAttributes
,
784 Status
= ZwOpenFile(&FileHandle
,
790 if (!NT_SUCCESS(Status
))
792 DPRINT("Could not open symbol file: %wZ\n", &Filename
);
796 CPRINT("Loading symbols from %wZ...\n", &Filename
);
798 /* Get the size of the file */
799 Status
= ZwQueryInformationFile(FileHandle
,
803 FileStandardInformation
);
804 if (!NT_SUCCESS(Status
))
806 DPRINT("Could not get file size\n");
810 /* Allocate nonpageable memory for symbol file */
811 FileBuffer
= ExAllocatePool(NonPagedPool
,
812 FileStdInfo
.EndOfFile
.u
.LowPart
);
814 if (FileBuffer
== NULL
)
816 DPRINT("Could not allocate memory for symbol file\n");
820 /* Load file into memory chunk */
821 Status
= ZwReadFile(FileHandle
,
825 FileStdInfo
.EndOfFile
.u
.LowPart
,
827 if (!NT_SUCCESS(Status
))
829 DPRINT("Could not read symbol file into memory\n");
830 ExFreePool(FileBuffer
);
836 LdrpLoadUserModuleSymbolsFromBuffer(ModuleObject
,
838 FileStdInfo
.EndOfFile
.u
.LowPart
);
840 ExFreePool(FileBuffer
);
846 NTSTATUS
LdrFindModuleObject(
847 PUNICODE_STRING ModuleName
,
848 PMODULE_OBJECT
*ModuleObject
)
851 WCHAR NameBuffer
[MAX_PATH
];
853 OBJECT_ATTRIBUTES ObjectAttributes
;
854 UNICODE_STRING RemainingPath
;
856 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
857 wcscat(NameBuffer
, ModuleName
->Buffer
);
858 RtlInitUnicodeString(&Name
, NameBuffer
);
860 InitializeObjectAttributes(&ObjectAttributes
,
865 Status
= ObFindObject(&ObjectAttributes
,
866 (PVOID
*)ModuleObject
,
869 if (!NT_SUCCESS(Status
))
874 if ((RemainingPath
.Buffer
!= NULL
) || (*ModuleObject
== NULL
))
876 RtlFreeUnicodeString(&RemainingPath
);
877 return STATUS_UNSUCCESSFUL
;
880 return STATUS_SUCCESS
;
883 VOID
LdrLoadAutoConfigDrivers (VOID
)
889 UNICODE_STRING ModuleName
;
890 PMODULE_OBJECT ModuleObject
;
892 /* Load symbols for ntoskrnl.exe and hal.dll because \SystemRoot
893 is created after their module entries */
895 RtlInitUnicodeString(&ModuleName
, KERNEL_MODULE_NAME
);
896 Status
= LdrFindModuleObject(&ModuleName
, &ModuleObject
);
897 if (NT_SUCCESS(Status
))
899 LdrpLoadModuleSymbols(ModuleObject
);
902 RtlInitUnicodeString(&ModuleName
, HAL_MODULE_NAME
);
903 Status
= LdrFindModuleObject(&ModuleName
, &ModuleObject
);
904 if (NT_SUCCESS(Status
))
906 LdrpLoadModuleSymbols(ModuleObject
);
914 //LdrLoadAutoConfigDriver( L"pci.sys" );
919 LdrLoadAutoConfigDriver( L
"keyboard.sys" );
921 if (KdDebugType
== PiceDebug
)
924 * Private ICE debugger
926 LdrLoadAutoConfigDriver( L
"pice.sys" );
932 LdrLoadAutoConfigDriver( L
"blue.sys" );
937 LdrLoadAutoConfigDriver(L
"vidport.sys");
942 LdrLoadAutoConfigDriver(L
"vgamp.sys");
945 * Minix filesystem driver
947 LdrLoadAutoConfigDriver(L
"minixfs.sys");
950 * Mailslot filesystem driver
952 LdrLoadAutoConfigDriver(L
"msfs.sys");
955 * Named pipe filesystem driver
957 LdrLoadAutoConfigDriver(L
"npfs.sys");
962 // LdrLoadAutoConfigDriver(L"l8042prt.sys");
963 LdrLoadAutoConfigDriver(L
"psaux.sys");
964 LdrLoadAutoConfigDriver(L
"mouclass.sys");
973 LdrLoadAutoConfigDriver(L
"ndis.sys");
976 * Novell Eagle 2000 driver
978 //LdrLoadAutoConfigDriver(L"ne2000.sys");
981 * TCP/IP protocol driver
983 LdrLoadAutoConfigDriver(L
"tcpip.sys");
988 //LdrLoadAutoConfigDriver(L"tditest.sys");
991 * Ancillary Function Driver
993 LdrLoadAutoConfigDriver(L
"afd.sys");
998 static NTSTATUS STDCALL
999 LdrCreateModule(PVOID ObjectBody
,
1001 PWSTR RemainingPath
,
1002 POBJECT_ATTRIBUTES ObjectAttributes
)
1004 DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n",
1008 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+ 1, '\\') != NULL
)
1010 return STATUS_UNSUCCESSFUL
;
1012 if (Parent
!= NULL
&& RemainingPath
!= NULL
)
1014 ObAddEntryDirectory(Parent
, ObjectBody
, RemainingPath
+ 1);
1017 return STATUS_SUCCESS
;
1021 * FUNCTION: Loads a kernel driver
1023 * FileName = Driver to load
1027 NTSTATUS
LdrLoadDriver(PUNICODE_STRING Filename
,
1028 PDEVICE_NODE DeviceNode
,
1029 BOOLEAN BootDriversOnly
)
1031 PMODULE_OBJECT ModuleObject
;
1032 WCHAR Buffer
[MAX_PATH
];
1038 ModuleObject
= LdrLoadModule(Filename
);
1041 return STATUS_UNSUCCESSFUL
;
1044 /* Set a service name for the device node */
1046 /* Get the service name from the module name */
1047 Start
= wcsrchr(ModuleObject
->BaseName
.Buffer
, L
'\\');
1049 Start
= ModuleObject
->BaseName
.Buffer
;
1053 Ext
= wcsrchr(ModuleObject
->BaseName
.Buffer
, L
'.');
1055 Length
= Ext
- Start
;
1057 Length
= wcslen(Start
);
1059 wcsncpy(Buffer
, Start
, Length
);
1060 RtlInitUnicodeString(&DeviceNode
->ServiceName
, Buffer
);
1063 Status
= IopInitializeDriver(ModuleObject
->EntryPoint
, DeviceNode
);
1064 if (!NT_SUCCESS(Status
))
1066 ObDereferenceObject(ModuleObject
);
1072 NTSTATUS
LdrLoadGdiDriver (PUNICODE_STRING DriverName
,
1073 PVOID
*ImageAddress
,
1074 PVOID
*SectionPointer
,
1076 PVOID
*ExportSectionPointer
)
1078 PMODULE_OBJECT ModuleObject
;
1080 ModuleObject
= LdrLoadModule(DriverName
);
1081 if (ModuleObject
== 0)
1083 return STATUS_UNSUCCESSFUL
;
1087 *ImageAddress
= ModuleObject
->Base
;
1089 // if (SectionPointer)
1090 // *SectionPointer = ModuleObject->
1093 *EntryPoint
= ModuleObject
->EntryPoint
;
1095 // if (ExportSectionPointer)
1096 // *ExportSectionPointer = ModuleObject->
1098 return STATUS_SUCCESS
;
1103 LdrLoadModule(PUNICODE_STRING Filename
)
1105 PVOID ModuleLoadBase
;
1108 OBJECT_ATTRIBUTES ObjectAttributes
;
1109 PMODULE_OBJECT ModuleObject
;
1110 FILE_STANDARD_INFORMATION FileStdInfo
;
1111 IO_STATUS_BLOCK IoStatusBlock
;
1113 /* Check for module already loaded */
1114 if ((ModuleObject
= LdrOpenModule(Filename
)) != NULL
)
1116 return ModuleObject
;
1119 DPRINT("Loading Module %wZ...\n", Filename
);
1121 /* Open the Module */
1122 InitializeObjectAttributes(&ObjectAttributes
,
1128 Status
= NtOpenFile(&FileHandle
,
1135 if (!NT_SUCCESS(Status
))
1137 CPRINT("Could not open module file: %wZ\n", Filename
);
1142 /* Get the size of the file */
1143 Status
= NtQueryInformationFile(FileHandle
,
1146 sizeof(FileStdInfo
),
1147 FileStandardInformation
);
1148 if (!NT_SUCCESS(Status
))
1150 CPRINT("Could not get file size\n");
1155 /* Allocate nonpageable memory for driver */
1156 ModuleLoadBase
= ExAllocatePoolWithTag(NonPagedPool
,
1157 FileStdInfo
.EndOfFile
.u
.LowPart
,
1160 if (ModuleLoadBase
== NULL
)
1162 CPRINT("Could not allocate memory for module");
1167 /* Load driver into memory chunk */
1168 Status
= NtReadFile(FileHandle
,
1172 FileStdInfo
.EndOfFile
.u
.LowPart
,
1174 if (!NT_SUCCESS(Status
))
1176 CPRINT("Could not read module file into memory");
1177 ExFreePool(ModuleLoadBase
);
1182 NtClose(FileHandle
);
1184 Status
= LdrProcessModule(ModuleLoadBase
,
1187 if (!NT_SUCCESS(Status
))
1189 CPRINT("Could not process module");
1190 ExFreePool(ModuleLoadBase
);
1195 ExFreePool(ModuleLoadBase
);
1199 /* Load symbols for module if available */
1200 LdrpLoadModuleSymbols(ModuleObject
);
1204 return ModuleObject
;
1208 LdrProcessDriver(PVOID ModuleLoadBase
, PCHAR FileName
, ULONG ModuleLength
)
1210 PMODULE_OBJECT ModuleObject
;
1211 UNICODE_STRING ModuleName
;
1212 PDEVICE_NODE DeviceNode
;
1217 CHAR TmpBaseName
[MAX_PATH
];
1218 CHAR TmpFileName
[MAX_PATH
];
1219 ANSI_STRING AnsiString
;
1223 /* Split the filename into base name and extension */
1224 Ext
= strrchr(FileName
, '.');
1226 Length
= Ext
- FileName
;
1228 Length
= strlen(FileName
);
1230 if ((Ext
!= NULL
) && (strcmp(Ext
, ".sym") == 0))
1232 DPRINT("Module %s is a symbol file\n", FileName
);
1234 strncpy(TmpBaseName
, FileName
, Length
);
1235 TmpBaseName
[Length
] = '\0';
1237 DPRINT("base: %s (Length %d)\n", TmpBaseName
, Length
);
1239 strcpy(TmpFileName
, TmpBaseName
);
1240 strcat(TmpFileName
, ".sys");
1241 RtlInitAnsiString(&AnsiString
, TmpFileName
);
1243 DPRINT("dasdsad: %s\n", TmpFileName
);
1245 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
1246 Status
= LdrFindModuleObject(&ModuleName
, &ModuleObject
);
1247 RtlFreeUnicodeString(&ModuleName
);
1248 if (!NT_SUCCESS(Status
))
1250 strcpy(TmpFileName
, TmpBaseName
);
1251 strcat(TmpFileName
, ".exe");
1252 RtlInitAnsiString(&AnsiString
, TmpFileName
);
1253 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
1254 Status
= LdrFindModuleObject(&ModuleName
, &ModuleObject
);
1255 RtlFreeUnicodeString(&ModuleName
);
1257 if (NT_SUCCESS(Status
))
1259 LdrpLoadModuleSymbolsFromBuffer(
1264 return(STATUS_SUCCESS
);
1268 DPRINT("Module %s is executable\n", FileName
);
1272 /* Use IopRootDeviceNode for now */
1273 Status
= IopCreateDeviceNode(IopRootDeviceNode
, NULL
, &DeviceNode
);
1274 if (!NT_SUCCESS(Status
))
1276 CPRINT("Driver load failed, status (%x)\n", Status
);
1280 RtlCreateUnicodeStringFromAsciiz(&ModuleName
,
1282 Status
= LdrProcessModule(ModuleLoadBase
,
1285 RtlFreeUnicodeString(&ModuleName
);
1286 if (ModuleObject
== NULL
)
1288 IopFreeDeviceNode(DeviceNode
);
1289 CPRINT("Driver load failed, status (%x)\n", Status
);
1290 return(STATUS_UNSUCCESSFUL
);
1293 Status
= IopInitializeDriver(ModuleObject
->EntryPoint
, DeviceNode
);
1294 if (!NT_SUCCESS(Status
))
1296 IopFreeDeviceNode(DeviceNode
);
1297 CPRINT("Driver load failed, status (%x)\n", Status
);
1304 LdrProcessModule(PVOID ModuleLoadBase
,
1305 PUNICODE_STRING ModuleName
,
1306 PMODULE_OBJECT
*ModuleObject
)
1308 PIMAGE_DOS_HEADER PEDosHeader
;
1310 /* If MZ header exists */
1311 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
1312 if (PEDosHeader
->e_magic
== IMAGE_DOS_MAGIC
&& PEDosHeader
->e_lfanew
!= 0L)
1314 return LdrPEProcessModule(ModuleLoadBase
,
1319 CPRINT("Module wasn't PE\n");
1320 return STATUS_UNSUCCESSFUL
;
1323 static PMODULE_OBJECT
1324 LdrOpenModule(PUNICODE_STRING Filename
)
1327 WCHAR NameBuffer
[60];
1328 UNICODE_STRING ModuleName
;
1329 OBJECT_ATTRIBUTES ObjectAttributes
;
1330 PMODULE_OBJECT ModuleObject
;
1331 UNICODE_STRING RemainingPath
;
1333 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
1334 if (wcsrchr(Filename
->Buffer
, '\\') != 0)
1336 wcscat(NameBuffer
, wcsrchr(Filename
->Buffer
, '\\') + 1);
1340 wcscat(NameBuffer
, Filename
->Buffer
);
1342 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
1343 InitializeObjectAttributes(&ObjectAttributes
,
1345 OBJ_CASE_INSENSITIVE
,
1349 Status
= ObFindObject(&ObjectAttributes
,
1350 (PVOID
*) &ModuleObject
,
1354 if (NT_SUCCESS(Status
) && (RemainingPath
.Buffer
== NULL
|| *(RemainingPath
.Buffer
) == 0))
1356 DPRINT("Module %wZ at %p\n", Filename
, ModuleObject
);
1357 RtlFreeUnicodeString (&RemainingPath
);
1359 return ModuleObject
;
1362 RtlFreeUnicodeString (&RemainingPath
);
1368 LdrGetExportAddress(PMODULE_OBJECT ModuleObject
,
1370 unsigned short Hint
)
1372 if (ModuleObject
->Flags
& MODULE_FLAG_PE
)
1374 return LdrPEGetExportAddress(ModuleObject
, Name
, Hint
);
1383 LdrpQueryModuleInformation(PVOID Buffer
,
1387 PLIST_ENTRY current_entry
;
1388 PMODULE_OBJECT current
;
1389 ULONG ModuleCount
= 0;
1390 PSYSTEM_MODULE_INFORMATION Smi
;
1391 ANSI_STRING AnsiName
;
1394 // KeAcquireSpinLock(&ModuleListLock,&oldlvl);
1396 /* calculate required size */
1397 current_entry
= ModuleListHead
.Flink
;
1398 while (current_entry
!= (&ModuleListHead
))
1401 current_entry
= current_entry
->Flink
;
1404 *ReqSize
= sizeof(SYSTEM_MODULE_INFORMATION
)+
1405 (ModuleCount
- 1) * sizeof(SYSTEM_MODULE_ENTRY
);
1407 if (Size
< *ReqSize
)
1409 // KeReleaseSpinLock(&ModuleListLock,oldlvl);
1410 return STATUS_INFO_LENGTH_MISMATCH
;
1413 /* fill the buffer */
1414 memset(Buffer
, '=', Size
);
1416 Smi
= (PSYSTEM_MODULE_INFORMATION
)Buffer
;
1417 Smi
->Count
= ModuleCount
;
1420 current_entry
= ModuleListHead
.Flink
;
1421 while (current_entry
!= (&ModuleListHead
))
1423 current
= CONTAINING_RECORD(current_entry
,MODULE_OBJECT
,ListEntry
);
1425 Smi
->Module
[ModuleCount
].Unknown2
= 0; /* Always 0 */
1426 Smi
->Module
[ModuleCount
].BaseAddress
= current
->Base
;
1427 Smi
->Module
[ModuleCount
].Size
= current
->Length
;
1428 Smi
->Module
[ModuleCount
].Flags
= 0; /* Flags ??? (GN) */
1429 Smi
->Module
[ModuleCount
].EntryIndex
= ModuleCount
;
1431 AnsiName
.Length
= 0;
1432 AnsiName
.MaximumLength
= 256;
1433 AnsiName
.Buffer
= Smi
->Module
[ModuleCount
].Name
;
1434 RtlUnicodeStringToAnsiString(&AnsiName
,
1438 p
= strrchr (AnsiName
.Buffer
, '\\');
1441 Smi
->Module
[ModuleCount
].PathLength
= 0;
1442 Smi
->Module
[ModuleCount
].NameLength
= strlen(AnsiName
.Buffer
);
1447 Smi
->Module
[ModuleCount
].PathLength
= p
- AnsiName
.Buffer
;
1448 Smi
->Module
[ModuleCount
].NameLength
= strlen(p
);
1452 current_entry
= current_entry
->Flink
;
1455 // KeReleaseSpinLock(&ModuleListLock,oldlvl);
1457 return STATUS_SUCCESS
;
1462 LdrpBuildModuleBaseName(PUNICODE_STRING BaseName
,
1463 PUNICODE_STRING FullName
)
1465 UNICODE_STRING Name
;
1469 DPRINT("LdrpBuildModuleBaseName()\n");
1470 DPRINT("FullName %wZ\n", FullName
);
1472 p
= wcsrchr(FullName
->Buffer
, '\\');
1475 p
= FullName
->Buffer
;
1482 DPRINT("p %S\n", p
);
1484 RtlCreateUnicodeString(&Name
, p
);
1492 DPRINT("p %S\n", p
);
1494 RtlCreateUnicodeString(BaseName
, p
);
1495 RtlFreeUnicodeString(&Name
);
1499 /* ---------------------------------------------- PE Module support */
1502 LdrPEProcessModule(PVOID ModuleLoadBase
,
1503 PUNICODE_STRING FileName
,
1504 PMODULE_OBJECT
*ModuleObject
)
1506 unsigned int DriverSize
, Idx
, Idx2
;
1507 ULONG RelocDelta
, NumRelocs
;
1508 DWORD CurrentSize
, TotalRelocs
;
1511 PIMAGE_DOS_HEADER PEDosHeader
;
1512 PIMAGE_FILE_HEADER PEFileHeader
;
1513 PIMAGE_OPTIONAL_HEADER PEOptionalHeader
;
1514 PIMAGE_SECTION_HEADER PESectionHeaders
;
1515 PRELOCATION_DIRECTORY RelocDir
;
1516 PRELOCATION_ENTRY RelocEntry
;
1517 PMODULE_OBJECT LibraryModuleObject
;
1518 HANDLE ModuleHandle
;
1519 PMODULE_OBJECT CreatedModuleObject
;
1520 PVOID
*ImportAddressList
;
1521 PULONG FunctionNameList
;
1524 OBJECT_ATTRIBUTES ObjectAttributes
;
1525 UNICODE_STRING ModuleName
;
1526 WCHAR NameBuffer
[60];
1527 MODULE_TEXT_SECTION
* ModuleTextSection
;
1530 DPRINT("Processing PE Module at module base:%08lx\n", ModuleLoadBase
);
1532 /* Get header pointers */
1533 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
1534 PEMagic
= (PULONG
) ((unsigned int) ModuleLoadBase
+
1535 PEDosHeader
->e_lfanew
);
1536 PEFileHeader
= (PIMAGE_FILE_HEADER
) ((unsigned int) ModuleLoadBase
+
1537 PEDosHeader
->e_lfanew
+ sizeof(ULONG
));
1538 PEOptionalHeader
= (PIMAGE_OPTIONAL_HEADER
) ((unsigned int) ModuleLoadBase
+
1539 PEDosHeader
->e_lfanew
+ sizeof(ULONG
) + sizeof(IMAGE_FILE_HEADER
));
1540 PESectionHeaders
= (PIMAGE_SECTION_HEADER
) ((unsigned int) ModuleLoadBase
+
1541 PEDosHeader
->e_lfanew
+ sizeof(ULONG
) + sizeof(IMAGE_FILE_HEADER
) +
1542 sizeof(IMAGE_OPTIONAL_HEADER
));
1545 /* Check file magic numbers */
1546 if (PEDosHeader
->e_magic
!= IMAGE_DOS_MAGIC
)
1548 CPRINT("Incorrect MZ magic: %04x\n", PEDosHeader
->e_magic
);
1549 return STATUS_UNSUCCESSFUL
;
1551 if (PEDosHeader
->e_lfanew
== 0)
1553 CPRINT("Invalid lfanew offset: %08x\n", PEDosHeader
->e_lfanew
);
1554 return STATUS_UNSUCCESSFUL
;
1556 if (*PEMagic
!= IMAGE_PE_MAGIC
)
1558 CPRINT("Incorrect PE magic: %08x\n", *PEMagic
);
1559 return STATUS_UNSUCCESSFUL
;
1561 if (PEFileHeader
->Machine
!= IMAGE_FILE_MACHINE_I386
)
1563 CPRINT("Incorrect Architechture: %04x\n", PEFileHeader
->Machine
);
1564 return STATUS_UNSUCCESSFUL
;
1568 /* FIXME: if image is fixed-address load, then fail */
1570 /* FIXME: check/verify OS version number */
1572 DPRINT("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
1573 PEOptionalHeader
->Magic
,
1574 PEOptionalHeader
->MajorLinkerVersion
,
1575 PEOptionalHeader
->MinorLinkerVersion
);
1576 DPRINT("Entry Point:%08lx\n", PEOptionalHeader
->AddressOfEntryPoint
);
1579 /* Determine the size of the module */
1580 DriverSize
= PEOptionalHeader
->SizeOfImage
;
1581 DPRINT("DriverSize %x\n",DriverSize
);
1583 /* Allocate a virtual section for the module */
1584 DriverBase
= MmAllocateSection(DriverSize
);
1585 if (DriverBase
== 0)
1587 CPRINT("Failed to allocate a virtual section for driver\n");
1588 return STATUS_UNSUCCESSFUL
;
1590 CPRINT("DriverBase: %x\n", DriverBase
);
1592 /* Copy headers over */
1593 memcpy(DriverBase
, ModuleLoadBase
, PEOptionalHeader
->SizeOfHeaders
);
1595 /* Copy image sections into virtual section */
1596 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
1598 // Copy current section into current offset of virtual section
1599 if (PESectionHeaders
[Idx
].Characteristics
&
1600 (IMAGE_SECTION_CHAR_CODE
| IMAGE_SECTION_CHAR_DATA
))
1602 DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
1603 PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
);
1604 memcpy(PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
,
1605 (PVOID
)(ModuleLoadBase
+ PESectionHeaders
[Idx
].PointerToRawData
),
1606 PESectionHeaders
[Idx
].Misc
.VirtualSize
> PESectionHeaders
[Idx
].SizeOfRawData
? PESectionHeaders
[Idx
].SizeOfRawData
: PESectionHeaders
[Idx
].Misc
.VirtualSize
);
1610 DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
1611 PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
);
1612 memset(PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
,
1613 '\0', PESectionHeaders
[Idx
].Misc
.VirtualSize
);
1616 CurrentSize
+= ROUND_UP(PESectionHeaders
[Idx
].Misc
.VirtualSize
,
1617 PEOptionalHeader
->SectionAlignment
);
1620 // CurrentBase = (PVOID)((DWORD)CurrentBase +
1621 // ROUND_UP(PESectionHeaders[Idx].SizeOfRawData.Misc.VirtualSize,
1622 // PEOptionalHeader->SectionAlignment));
1625 /* Perform relocation fixups */
1626 RelocDelta
= (DWORD
) DriverBase
- PEOptionalHeader
->ImageBase
;
1627 RelocDir
= (PRELOCATION_DIRECTORY
)(PEOptionalHeader
->DataDirectory
[
1628 IMAGE_DIRECTORY_ENTRY_BASERELOC
].VirtualAddress
);
1629 DPRINT("DrvrBase:%08lx ImgBase:%08lx RelocDelta:%08lx\n",
1631 PEOptionalHeader
->ImageBase
,
1633 DPRINT("RelocDir %x\n",RelocDir
);
1635 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
1637 if (PESectionHeaders
[Idx
].VirtualAddress
== (DWORD
)RelocDir
)
1639 DPRINT("Name %.8s PESectionHeader[Idx].PointerToRawData %x\n",
1640 PESectionHeaders
[Idx
].Name
,
1641 PESectionHeaders
[Idx
].PointerToRawData
);
1642 RelocDir
= PESectionHeaders
[Idx
].PointerToRawData
+
1644 CurrentSize
= PESectionHeaders
[Idx
].Misc
.VirtualSize
;
1649 RelocDir
= RelocDir
+ (ULONG
)DriverBase
;
1650 CurrentSize
= PEOptionalHeader
->DataDirectory
1651 [IMAGE_DIRECTORY_ENTRY_BASERELOC
].Size
;
1653 DPRINT("RelocDir %08lx CurrentSize %08lx\n", RelocDir
, CurrentSize
);
1655 while (TotalRelocs
< CurrentSize
&& RelocDir
->SizeOfBlock
!= 0)
1657 NumRelocs
= (RelocDir
->SizeOfBlock
- sizeof(RELOCATION_DIRECTORY
)) /
1659 /* DPRINT("RelocDir at %08lx for VA %08lx with %08lx relocs\n",
1661 RelocDir->VirtualAddress,
1663 RelocEntry
= (PRELOCATION_ENTRY
) ((DWORD
)RelocDir
+
1664 sizeof(RELOCATION_DIRECTORY
));
1665 for (Idx
= 0; Idx
< NumRelocs
; Idx
++)
1671 Offset
= RelocEntry
[Idx
].TypeOffset
& 0xfff;
1672 Type
= (RelocEntry
[Idx
].TypeOffset
>> 12) & 0xf;
1673 RelocItem
= (PDWORD
)(DriverBase
+ RelocDir
->VirtualAddress
+
1675 /* DPRINT(" reloc at %08lx %x %s old:%08lx new:%08lx\n",
1678 Type ? "HIGHLOW" : "ABS",
1680 (*RelocItem) + RelocDelta); */
1683 (*RelocItem
) += RelocDelta
;
1687 CPRINT("Unknown relocation type %x at %x\n",Type
, &Type
);
1688 return STATUS_UNSUCCESSFUL
;
1691 TotalRelocs
+= RelocDir
->SizeOfBlock
;
1692 RelocDir
= (PRELOCATION_DIRECTORY
)((DWORD
)RelocDir
+
1693 RelocDir
->SizeOfBlock
);
1694 // DPRINT("TotalRelocs: %08lx CurrentSize: %08lx\n", TotalRelocs, CurrentSize);
1697 DPRINT("PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] %x\n",
1698 PEOptionalHeader
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
]
1700 /* Perform import fixups */
1701 if (PEOptionalHeader
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress
)
1703 PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory
;
1705 /* Process each import module */
1706 ImportModuleDirectory
= (PIMAGE_IMPORT_MODULE_DIRECTORY
)
1707 ((DWORD
)DriverBase
+ PEOptionalHeader
->
1708 DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress
);
1709 DPRINT("Processeing import directory at %p\n", ImportModuleDirectory
);
1710 while (ImportModuleDirectory
->dwRVAModuleName
)
1712 /* Check to make sure that import lib is kernel */
1713 pName
= (PCHAR
) DriverBase
+
1714 ImportModuleDirectory
->dwRVAModuleName
;
1715 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
1717 for (Idx
= 0; NameBuffer
[Idx
] != 0; Idx
++);
1718 for (Idx2
= 0; pName
[Idx2
] != '\0'; Idx2
++)
1720 NameBuffer
[Idx
+ Idx2
] = (WCHAR
) pName
[Idx2
];
1722 NameBuffer
[Idx
+ Idx2
] = 0;
1724 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
1725 DPRINT("Import module: %wZ\n", &ModuleName
);
1727 LibraryModuleObject
= LdrLoadModule(&ModuleName
);
1728 if (LibraryModuleObject
== 0)
1730 CPRINT("Unknown import module: %wZ\n", &ModuleName
);
1732 /* Get the import address list */
1733 ImportAddressList
= (PVOID
*) ((DWORD
)DriverBase
+
1734 ImportModuleDirectory
->dwRVAFunctionAddressList
);
1736 /* Get the list of functions to import */
1737 if (ImportModuleDirectory
->dwRVAFunctionNameList
!= 0)
1739 FunctionNameList
= (PULONG
) ((DWORD
)DriverBase
+
1740 ImportModuleDirectory
->dwRVAFunctionNameList
);
1744 FunctionNameList
= (PULONG
) ((DWORD
)DriverBase
+
1745 ImportModuleDirectory
->dwRVAFunctionAddressList
);
1747 /* Walk through function list and fixup addresses */
1748 while (*FunctionNameList
!= 0L)
1750 if ((*FunctionNameList
) & 0x80000000) // hint
1755 Hint
= (*FunctionNameList
) & 0xffff;
1759 pName
= (PCHAR
)((DWORD
)DriverBase
+
1760 *FunctionNameList
+ 2);
1761 Hint
= *(PWORD
)((DWORD
)DriverBase
+ *FunctionNameList
);
1763 DPRINT(" Hint:%04x Name:%s\n", Hint
, pName
);
1765 /* Fixup the current import symbol */
1766 if (LibraryModuleObject
!= NULL
)
1768 *ImportAddressList
= LdrGetExportAddress(LibraryModuleObject
,
1774 CPRINT("Unresolved kernel symbol: %s\n", pName
);
1775 return STATUS_UNSUCCESSFUL
;
1777 ImportAddressList
++;
1780 ImportModuleDirectory
++;
1784 /* Create ModuleName string */
1785 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
1786 if (wcsrchr(FileName
->Buffer
, '\\') != 0)
1788 wcscat(NameBuffer
, wcsrchr(FileName
->Buffer
, '\\') + 1);
1792 wcscat(NameBuffer
, FileName
->Buffer
);
1794 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
1795 CPRINT("Module name is: %wZ\n", &ModuleName
);
1797 /* Initialize ObjectAttributes for ModuleObject */
1798 InitializeObjectAttributes(&ObjectAttributes
,
1804 /* Create module object */
1806 Status
= ObCreateObject(&ModuleHandle
,
1807 STANDARD_RIGHTS_REQUIRED
,
1810 (PVOID
*)&CreatedModuleObject
);
1811 if (!NT_SUCCESS(Status
))
1816 /* Initialize ModuleObject data */
1817 CreatedModuleObject
->Base
= DriverBase
;
1818 CreatedModuleObject
->Flags
= MODULE_FLAG_PE
;
1819 InsertTailList(&ModuleListHead
,
1820 &CreatedModuleObject
->ListEntry
);
1821 RtlCreateUnicodeString(&CreatedModuleObject
->FullName
,
1823 LdrpBuildModuleBaseName(&CreatedModuleObject
->BaseName
,
1824 &CreatedModuleObject
->FullName
);
1826 CreatedModuleObject
->EntryPoint
= (PVOID
) ((DWORD
)DriverBase
+
1827 PEOptionalHeader
->AddressOfEntryPoint
);
1828 CreatedModuleObject
->Length
= DriverSize
;
1829 DPRINT("EntryPoint at %x\n", CreatedModuleObject
->EntryPoint
);
1831 CreatedModuleObject
->Image
.PE
.FileHeader
=
1832 (PIMAGE_FILE_HEADER
) ((unsigned int) DriverBase
+ PEDosHeader
->e_lfanew
+ sizeof(ULONG
));
1834 DPRINT("FileHeader at %x\n", CreatedModuleObject
->Image
.PE
.FileHeader
);
1835 CreatedModuleObject
->Image
.PE
.OptionalHeader
=
1836 (PIMAGE_OPTIONAL_HEADER
) ((unsigned int) DriverBase
+ PEDosHeader
->e_lfanew
+ sizeof(ULONG
) +
1837 sizeof(IMAGE_FILE_HEADER
));
1838 DPRINT("OptionalHeader at %x\n", CreatedModuleObject
->Image
.PE
.OptionalHeader
);
1839 CreatedModuleObject
->Image
.PE
.SectionList
=
1840 (PIMAGE_SECTION_HEADER
) ((unsigned int) DriverBase
+ PEDosHeader
->e_lfanew
+ sizeof(ULONG
) +
1841 sizeof(IMAGE_FILE_HEADER
) + sizeof(IMAGE_OPTIONAL_HEADER
));
1842 DPRINT("SectionList at %x\n", CreatedModuleObject
->Image
.PE
.SectionList
);
1844 ModuleTextSection
= ExAllocatePool(NonPagedPool
,
1845 sizeof(MODULE_TEXT_SECTION
));
1846 ModuleTextSection
->Base
= (ULONG
)DriverBase
;
1847 ModuleTextSection
->Length
= DriverSize
;
1848 ModuleTextSection
->SymbolsBase
= NULL
;
1849 ModuleTextSection
->SymbolsLength
= 0;
1850 ModuleTextSection
->Name
=
1851 ExAllocatePool(NonPagedPool
,
1852 (wcslen(NameBuffer
) + 1) * sizeof(WCHAR
));
1853 wcscpy(ModuleTextSection
->Name
, NameBuffer
);
1854 InsertTailList(&ModuleTextListHead
, &ModuleTextSection
->ListEntry
);
1856 CreatedModuleObject
->TextSection
= ModuleTextSection
;
1858 *ModuleObject
= CreatedModuleObject
;
1860 return STATUS_SUCCESS
;
1863 PVOID
LdrSafePEProcessModule(
1864 PVOID ModuleLoadBase
,
1866 PVOID ImportModuleBase
,
1869 unsigned int Idx
, Idx2
;
1870 ULONG RelocDelta
, NumRelocs
;
1871 DWORD CurrentSize
, TotalRelocs
;
1873 PIMAGE_DOS_HEADER PEDosHeader
;
1874 PIMAGE_FILE_HEADER PEFileHeader
;
1875 PIMAGE_OPTIONAL_HEADER PEOptionalHeader
;
1876 PIMAGE_SECTION_HEADER PESectionHeaders
;
1877 PRELOCATION_DIRECTORY RelocDir
;
1878 PRELOCATION_ENTRY RelocEntry
;
1879 PVOID
*ImportAddressList
;
1880 PULONG FunctionNameList
;
1883 UNICODE_STRING ModuleName
;
1884 WCHAR NameBuffer
[60];
1886 ps("Processing PE Module at module base:%08lx\n", ModuleLoadBase
);
1888 /* Get header pointers */
1889 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
1890 PEMagic
= (PULONG
) ((unsigned int) ModuleLoadBase
+
1891 PEDosHeader
->e_lfanew
);
1892 PEFileHeader
= (PIMAGE_FILE_HEADER
) ((unsigned int) ModuleLoadBase
+
1893 PEDosHeader
->e_lfanew
+ sizeof(ULONG
));
1894 PEOptionalHeader
= (PIMAGE_OPTIONAL_HEADER
) ((unsigned int) ModuleLoadBase
+
1895 PEDosHeader
->e_lfanew
+ sizeof(ULONG
) + sizeof(IMAGE_FILE_HEADER
));
1896 PESectionHeaders
= (PIMAGE_SECTION_HEADER
) ((unsigned int) ModuleLoadBase
+
1897 PEDosHeader
->e_lfanew
+ sizeof(ULONG
) + sizeof(IMAGE_FILE_HEADER
) +
1898 sizeof(IMAGE_OPTIONAL_HEADER
));
1901 /* Check file magic numbers */
1902 if (PEDosHeader
->e_magic
!= IMAGE_DOS_MAGIC
)
1906 if (PEDosHeader
->e_lfanew
== 0)
1910 if (*PEMagic
!= IMAGE_PE_MAGIC
)
1914 if (PEFileHeader
->Machine
!= IMAGE_FILE_MACHINE_I386
)
1919 ps("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
1920 PEOptionalHeader
->Magic
,
1921 PEOptionalHeader
->MajorLinkerVersion
,
1922 PEOptionalHeader
->MinorLinkerVersion
);
1923 ps("Entry Point:%08lx\n", PEOptionalHeader
->AddressOfEntryPoint
);
1925 /* Determine the size of the module */
1926 *DriverSize
= PEOptionalHeader
->SizeOfImage
;
1927 ps("DriverSize %x\n",*DriverSize
);
1929 /* Copy headers over */
1930 if (DriverBase
!= ModuleLoadBase
)
1932 memcpy(DriverBase
, ModuleLoadBase
, PEOptionalHeader
->SizeOfHeaders
);
1935 ps("Hdr: 0x%X\n", (ULONG
)PEOptionalHeader
);
1936 ps("Hdr->SizeOfHeaders: 0x%X\n", (ULONG
)PEOptionalHeader
->SizeOfHeaders
);
1937 ps("FileHdr->NumberOfSections: 0x%X\n", (ULONG
)PEFileHeader
->NumberOfSections
);
1939 /* Ntoskrnl.exe need no relocation fixups since it is linked to run at the same
1940 address as it is mapped */
1941 if (DriverBase
!= ModuleLoadBase
)
1945 /* Copy image sections into virtual section */
1946 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
1948 // Copy current section into current offset of virtual section
1949 if (PESectionHeaders
[Idx
].Characteristics
&
1950 (IMAGE_SECTION_CHAR_CODE
| IMAGE_SECTION_CHAR_DATA
))
1952 //ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n",
1953 //PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].VirtualAddress + DriverBase);
1954 memcpy(PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
,
1955 (PVOID
)(ModuleLoadBase
+ PESectionHeaders
[Idx
].PointerToRawData
),
1956 PESectionHeaders
[Idx
].Misc
.VirtualSize
> PESectionHeaders
[Idx
].SizeOfRawData
?
1957 PESectionHeaders
[Idx
].SizeOfRawData
: PESectionHeaders
[Idx
].Misc
.VirtualSize
);
1961 ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n",
1962 PESectionHeaders
[Idx
].VirtualAddress
, PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
);
1963 memset(PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
,
1964 '\0', PESectionHeaders
[Idx
].Misc
.VirtualSize
);
1967 CurrentSize
+= ROUND_UP(PESectionHeaders
[Idx
].Misc
.VirtualSize
,
1968 PEOptionalHeader
->SectionAlignment
);
1971 /* Perform relocation fixups */
1972 RelocDelta
= (DWORD
) DriverBase
- PEOptionalHeader
->ImageBase
;
1973 RelocDir
= (PRELOCATION_DIRECTORY
)(PEOptionalHeader
->DataDirectory
[
1974 IMAGE_DIRECTORY_ENTRY_BASERELOC
].VirtualAddress
);
1975 ps("DrvrBase:%08lx ImgBase:%08lx RelocDelta:%08lx\n",
1977 PEOptionalHeader
->ImageBase
,
1979 ps("RelocDir %x\n",RelocDir
);
1981 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
1983 if (PESectionHeaders
[Idx
].VirtualAddress
== (DWORD
)RelocDir
)
1985 DPRINT("Name %.8s PESectionHeader[Idx].PointerToRawData %x\n",
1986 PESectionHeaders
[Idx
].Name
,
1987 PESectionHeaders
[Idx
].PointerToRawData
);
1988 RelocDir
= PESectionHeaders
[Idx
].PointerToRawData
+ ModuleLoadBase
;
1989 CurrentSize
= PESectionHeaders
[Idx
].Misc
.VirtualSize
;
1994 ps("RelocDir %08lx CurrentSize %08lx\n", RelocDir
, CurrentSize
);
1997 while (TotalRelocs
< CurrentSize
&& RelocDir
->SizeOfBlock
!= 0)
1999 NumRelocs
= (RelocDir
->SizeOfBlock
- sizeof(RELOCATION_DIRECTORY
)) /
2001 RelocEntry
= (PRELOCATION_ENTRY
) ((DWORD
)RelocDir
+
2002 sizeof(RELOCATION_DIRECTORY
));
2003 for (Idx
= 0; Idx
< NumRelocs
; Idx
++)
2009 Offset
= RelocEntry
[Idx
].TypeOffset
& 0xfff;
2010 Type
= (RelocEntry
[Idx
].TypeOffset
>> 12) & 0xf;
2011 RelocItem
= (PDWORD
)(DriverBase
+ RelocDir
->VirtualAddress
+
2015 (*RelocItem
) += RelocDelta
;
2019 CPRINT("Unknown relocation type %x at %x\n",Type
, &Type
);
2023 TotalRelocs
+= RelocDir
->SizeOfBlock
;
2024 RelocDir
= (PRELOCATION_DIRECTORY
)((DWORD
)RelocDir
+
2025 RelocDir
->SizeOfBlock
);
2028 ps("PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] %x\n",
2029 PEOptionalHeader
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
]
2033 /* Perform import fixups */
2034 if (PEOptionalHeader
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress
)
2036 PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory
;
2038 /* Process each import module */
2039 ImportModuleDirectory
= (PIMAGE_IMPORT_MODULE_DIRECTORY
)
2040 ((DWORD
)DriverBase
+ PEOptionalHeader
->
2041 DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress
);
2043 ps("Processeing import directory at %p\n", ImportModuleDirectory
);
2046 /* Check to make sure that import lib is kernel */
2047 pName
= (PCHAR
) DriverBase
+
2048 ImportModuleDirectory
->dwRVAModuleName
;
2049 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
2050 for (Idx
= 0; NameBuffer
[Idx
] != 0; Idx
++);
2051 for (Idx2
= 0; pName
[Idx2
] != '\0'; Idx2
++)
2053 NameBuffer
[Idx
+ Idx2
] = (WCHAR
) pName
[Idx2
];
2055 NameBuffer
[Idx
+ Idx2
] = 0;
2056 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
2059 ps("Import module: %wZ\n", &ModuleName
);
2061 /* Get the import address list */
2062 ImportAddressList
= (PVOID
*) ((DWORD
)DriverBase
+
2063 ImportModuleDirectory
->dwRVAFunctionAddressList
);
2065 ps(" ImportModuleDirectory->dwRVAFunctionAddressList: 0x%X\n",
2066 ImportModuleDirectory
->dwRVAFunctionAddressList
);
2067 ps(" ImportAddressList: 0x%X\n", ImportAddressList
);
2069 /* Get the list of functions to import */
2070 if (ImportModuleDirectory
->dwRVAFunctionNameList
!= 0)
2073 ps("Using function name list.\n");
2075 FunctionNameList
= (PULONG
) ((DWORD
)DriverBase
+
2076 ImportModuleDirectory
->dwRVAFunctionNameList
);
2081 ps("Using function address list.\n");
2083 FunctionNameList
= (PULONG
) ((DWORD
)DriverBase
+
2084 ImportModuleDirectory
->dwRVAFunctionAddressList
);
2087 /* Walk through function list and fixup addresses */
2088 while (*FunctionNameList
!= 0L)
2090 if ((*FunctionNameList
) & 0x80000000) // hint
2094 Hint
= (*FunctionNameList
) & 0xffff;
2098 pName
= (PCHAR
)((DWORD
)DriverBase
+
2099 *FunctionNameList
+ 2);
2100 Hint
= *(PWORD
)((DWORD
)DriverBase
+ *FunctionNameList
);
2102 //ps(" Hint:%04x Name:%s(0x%X)(%x)\n", Hint, pName, pName, ImportAddressList);
2104 *ImportAddressList
= LdrSafePEGetExportAddress(
2109 ImportAddressList
++;
2112 ImportModuleDirectory
++;
2116 ps("Finished importing.\n");
2122 LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject
,
2124 unsigned short Hint
)
2127 PVOID ExportAddress
;
2129 PDWORD FunctionList
, NameList
;
2130 PIMAGE_EXPORT_DIRECTORY ExportDir
;
2131 ULONG ExportDirSize
;
2133 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)
2134 RtlImageDirectoryEntryToData(ModuleObject
->Base
,
2136 IMAGE_DIRECTORY_ENTRY_EXPORT
,
2138 DPRINT("ExportDir %p ExportDirSize %lx\n", ExportDir
, ExportDirSize
);
2139 if (ExportDir
== NULL
)
2144 FunctionList
= (PDWORD
)((DWORD
)ExportDir
->AddressOfFunctions
+ ModuleObject
->Base
);
2145 NameList
= (PDWORD
)((DWORD
)ExportDir
->AddressOfNames
+ ModuleObject
->Base
);
2146 OrdinalList
= (PWORD
)((DWORD
)ExportDir
->AddressOfNameOrdinals
+ ModuleObject
->Base
);
2152 for (Idx
= 0; Idx
< ExportDir
->NumberOfNames
; Idx
++)
2155 DPRINT(" Name:%s NameList[%d]:%s\n",
2158 (DWORD
) ModuleObject
->Base
+ NameList
[Idx
]);
2161 if (!strcmp(Name
, (PCHAR
) ((DWORD
)ModuleObject
->Base
+ NameList
[Idx
])))
2163 ExportAddress
= (PVOID
) ((DWORD
)ModuleObject
->Base
+
2164 FunctionList
[OrdinalList
[Idx
]]);
2165 if (((ULONG
)ExportAddress
>= (ULONG
)ExportDir
) &&
2166 ((ULONG
)ExportAddress
< (ULONG
)ExportDir
+ ExportDirSize
))
2168 DPRINT("Forward: %s\n", (PCHAR
)ExportAddress
);
2169 ExportAddress
= LdrPEFixupForward((PCHAR
)ExportAddress
);
2170 DPRINT("ExportAddress: %p\n", ExportAddress
);
2179 ExportAddress
= (PVOID
) ((DWORD
)ModuleObject
->Base
+
2180 FunctionList
[Hint
- ExportDir
->Base
]);
2183 if (ExportAddress
== 0)
2185 CPRINT("Export not found for %d:%s\n",
2187 Name
!= NULL
? Name
: "(Ordinal)");
2191 return ExportAddress
;
2195 LdrSafePEGetExportAddress(
2196 PVOID ImportModuleBase
,
2198 unsigned short Hint
)
2201 PVOID ExportAddress
;
2203 PDWORD FunctionList
, NameList
;
2204 PIMAGE_EXPORT_DIRECTORY ExportDir
;
2205 ULONG ExportDirSize
;
2207 static BOOLEAN EP
= FALSE
;
2209 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)
2210 RtlImageDirectoryEntryToData(ImportModuleBase
,
2212 IMAGE_DIRECTORY_ENTRY_EXPORT
,
2217 ps("ExportDir %x\n", ExportDir
);
2220 FunctionList
= (PDWORD
)((DWORD
)ExportDir
->AddressOfFunctions
+ ImportModuleBase
);
2221 NameList
= (PDWORD
)((DWORD
)ExportDir
->AddressOfNames
+ ImportModuleBase
);
2222 OrdinalList
= (PWORD
)((DWORD
)ExportDir
->AddressOfNameOrdinals
+ ImportModuleBase
);
2228 for (Idx
= 0; Idx
< ExportDir
->NumberOfNames
; Idx
++)
2230 if (!strcmp(Name
, (PCHAR
) ((DWORD
)ImportModuleBase
+ NameList
[Idx
])))
2232 ExportAddress
= (PVOID
) ((DWORD
)ImportModuleBase
+
2233 FunctionList
[OrdinalList
[Idx
]]);
2240 ExportAddress
= (PVOID
) ((DWORD
)ImportModuleBase
+
2241 FunctionList
[Hint
- ExportDir
->Base
]);
2244 if (ExportAddress
== 0)
2246 ps("Export not found for %d:%s\n",
2248 Name
!= NULL
? Name
: "(Ordinal)");
2251 return ExportAddress
;
2255 static PMODULE_OBJECT
2256 LdrPEGetModuleObject(PUNICODE_STRING ModuleName
)
2259 PMODULE_OBJECT Module
;
2261 DPRINT("LdrPEGetModuleObject (ModuleName %wZ)\n",
2264 Entry
= ModuleListHead
.Flink
;
2266 while (Entry
!= &ModuleListHead
)
2268 Module
= CONTAINING_RECORD(Entry
, MODULE_OBJECT
, ListEntry
);
2270 DPRINT("Comparing %wZ and %wZ\n",
2274 if (!RtlCompareUnicodeString(&Module
->BaseName
, ModuleName
, TRUE
))
2276 DPRINT("Module %x\n", Module
);
2280 Entry
= Entry
->Flink
;
2283 CPRINT("LdrPEGetModuleObject: Failed to find dll %wZ\n", ModuleName
);
2290 LdrPEFixupForward(PCHAR ForwardName
)
2292 CHAR NameBuffer
[128];
2293 UNICODE_STRING ModuleName
;
2295 PMODULE_OBJECT ModuleObject
;
2297 DPRINT("LdrPEFixupForward (%s)\n", ForwardName
);
2299 strcpy(NameBuffer
, ForwardName
);
2300 p
= strchr(NameBuffer
, '.');
2308 DPRINT("Driver: %s Function: %s\n", NameBuffer
, p
+1);
2310 RtlCreateUnicodeStringFromAsciiz(&ModuleName
,
2312 ModuleObject
= LdrPEGetModuleObject(&ModuleName
);
2313 RtlFreeUnicodeString(&ModuleName
);
2315 DPRINT("ModuleObject: %p\n", ModuleObject
);
2317 if (ModuleObject
== NULL
)
2319 CPRINT("LdrPEFixupForward: failed to find module %s\n", NameBuffer
);
2323 return LdrPEGetExportAddress(ModuleObject
, p
+1, 0);