1 /* $Id: loader.c,v 1.95 2002/01/23 23:39:25 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/io.h>
32 #include <internal/mm.h>
33 #include <internal/ob.h>
34 #include <internal/ps.h>
35 #include <internal/ldr.h>
36 #include <internal/pool.h>
39 #include <internal/ntosdbg.h>
45 #include <internal/debug.h>
47 /* MACROS ********************************************************************/
49 #define KERNEL_MODULE_NAME L"ntoskrnl.exe"
50 #define HAL_MODULE_NAME L"hal.dll"
51 #define MODULE_ROOT_NAME L"\\Modules\\"
52 #define FILESYSTEM_ROOT_NAME L"\\FileSystem\\"
54 /* GLOBALS *******************************************************************/
56 LIST_ENTRY ModuleListHead
;
57 POBJECT_TYPE EXPORTED IoDriverObjectType
= NULL
;
58 LIST_ENTRY ModuleTextListHead
;
59 STATIC MODULE_TEXT_SECTION NtoskrnlTextSection
;
60 STATIC MODULE_TEXT_SECTION LdrHalTextSection
;
63 #define TAG_DRIVER_MEM TAG('D', 'R', 'V', 'M')
64 #define TAG_SYM_BUF TAG('S', 'Y', 'M', 'B')
66 /* FORWARD DECLARATIONS ******************************************************/
68 PMODULE_OBJECT
LdrLoadModule(PUNICODE_STRING Filename
);
69 NTSTATUS
LdrProcessModule(PVOID ModuleLoadBase
,
70 PUNICODE_STRING ModuleName
,
71 PMODULE_OBJECT
*ModuleObject
);
72 PVOID
LdrGetExportAddress(PMODULE_OBJECT ModuleObject
, char *Name
, unsigned short Hint
);
73 static PMODULE_OBJECT
LdrOpenModule(PUNICODE_STRING Filename
);
74 static NTSTATUS STDCALL
75 LdrCreateModule(PVOID ObjectBody
,
78 POBJECT_ATTRIBUTES ObjectAttributes
);
79 static VOID
LdrpBuildModuleBaseName(PUNICODE_STRING BaseName
,
80 PUNICODE_STRING FullName
);
82 /* PE Driver load support */
83 static NTSTATUS
LdrPEProcessModule(PVOID ModuleLoadBase
,
84 PUNICODE_STRING FileName
,
85 PMODULE_OBJECT
*ModuleObject
);
86 static PVOID
LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject
,
89 static PMODULE_OBJECT
LdrPEGetModuleObject(PUNICODE_STRING ModuleName
);
90 static PVOID
LdrPEFixupForward(PCHAR ForwardName
);
93 LdrSafePEGetExportAddress(
94 PVOID ImportModuleBase
,
99 /* FUNCTIONS *****************************************************************/
102 LdrInitDebug(PLOADER_MODULE Module
, PWCH Name
)
104 PLIST_ENTRY current_entry
;
105 MODULE_TEXT_SECTION
* current
;
107 current_entry
= ModuleTextListHead
.Flink
;
108 while (current_entry
!= &ModuleTextListHead
)
111 CONTAINING_RECORD(current_entry
, MODULE_TEXT_SECTION
, ListEntry
);
112 if (wcscmp(current
->Name
, Name
) == 0)
116 current_entry
= current_entry
->Flink
;
119 if (current_entry
== &ModuleTextListHead
)
124 current
->SymbolsBase
= (PVOID
)Module
->ModStart
;
125 current
->SymbolsLength
= Module
->ModEnd
- Module
->ModStart
;
131 PIMAGE_DOS_HEADER DosHeader
;
132 PIMAGE_FILE_HEADER FileHeader
;
133 PIMAGE_OPTIONAL_HEADER OptionalHeader
;
134 PIMAGE_SECTION_HEADER SectionList
;
136 InitializeListHead(&ModuleTextListHead
);
138 /* Setup ntoskrnl.exe text section */
139 DosHeader
= (PIMAGE_DOS_HEADER
) KERNEL_BASE
;
141 (PIMAGE_FILE_HEADER
) ((DWORD
)KERNEL_BASE
+
142 DosHeader
->e_lfanew
+ sizeof(ULONG
));
143 OptionalHeader
= (PIMAGE_OPTIONAL_HEADER
)
144 ((DWORD
)FileHeader
+ sizeof(IMAGE_FILE_HEADER
));
145 SectionList
= (PIMAGE_SECTION_HEADER
)
146 ((DWORD
)OptionalHeader
+ sizeof(IMAGE_OPTIONAL_HEADER
));
147 NtoskrnlTextSection
.Base
= KERNEL_BASE
;
148 NtoskrnlTextSection
.Length
= SectionList
[0].Misc
.VirtualSize
+
149 SectionList
[0].VirtualAddress
;
150 NtoskrnlTextSection
.Name
= KERNEL_MODULE_NAME
;
151 NtoskrnlTextSection
.SymbolsBase
= NULL
;
152 NtoskrnlTextSection
.SymbolsLength
= 0;
153 InsertTailList(&ModuleTextListHead
, &NtoskrnlTextSection
.ListEntry
);
155 /* Setup hal.dll text section */
156 DosHeader
= (PIMAGE_DOS_HEADER
)LdrHalBase
;
158 (PIMAGE_FILE_HEADER
) ((DWORD
)LdrHalBase
+
159 DosHeader
->e_lfanew
+ sizeof(ULONG
));
160 OptionalHeader
= (PIMAGE_OPTIONAL_HEADER
)
161 ((DWORD
)FileHeader
+ sizeof(IMAGE_FILE_HEADER
));
162 SectionList
= (PIMAGE_SECTION_HEADER
)
163 ((DWORD
)OptionalHeader
+ sizeof(IMAGE_OPTIONAL_HEADER
));
164 LdrHalTextSection
.Base
= LdrHalBase
;
165 LdrHalTextSection
.Length
= SectionList
[0].Misc
.VirtualSize
+
166 SectionList
[0].VirtualAddress
;
167 LdrHalTextSection
.Name
= HAL_MODULE_NAME
;
168 LdrHalTextSection
.SymbolsBase
= NULL
;
169 LdrHalTextSection
.SymbolsLength
= 0;
170 InsertTailList(&ModuleTextListHead
, &LdrHalTextSection
.ListEntry
);
173 VOID
LdrInitModuleManagement(VOID
)
175 HANDLE DirHandle
, ModuleHandle
;
177 WCHAR NameBuffer
[60];
178 UNICODE_STRING ModuleName
;
179 OBJECT_ATTRIBUTES ObjectAttributes
;
180 PIMAGE_DOS_HEADER DosHeader
;
181 PMODULE_OBJECT ModuleObject
;
183 /* Register the process object type */
184 IoDriverObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
185 IoDriverObjectType
->Tag
= TAG('D', 'R', 'V', 'T');
186 IoDriverObjectType
->TotalObjects
= 0;
187 IoDriverObjectType
->TotalHandles
= 0;
188 IoDriverObjectType
->MaxObjects
= ULONG_MAX
;
189 IoDriverObjectType
->MaxHandles
= ULONG_MAX
;
190 IoDriverObjectType
->PagedPoolCharge
= 0;
191 IoDriverObjectType
->NonpagedPoolCharge
= sizeof(MODULE
);
192 IoDriverObjectType
->Dump
= NULL
;
193 IoDriverObjectType
->Open
= NULL
;
194 IoDriverObjectType
->Close
= NULL
;
195 IoDriverObjectType
->Delete
= NULL
;
196 IoDriverObjectType
->Parse
= NULL
;
197 IoDriverObjectType
->Security
= NULL
;
198 IoDriverObjectType
->QueryName
= NULL
;
199 IoDriverObjectType
->OkayToClose
= NULL
;
200 IoDriverObjectType
->Create
= LdrCreateModule
;
201 IoDriverObjectType
->DuplicationNotify
= NULL
;
202 RtlInitUnicodeString(&IoDriverObjectType
->TypeName
, L
"Driver");
204 /* Create Modules object directory */
205 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
206 *(wcsrchr(NameBuffer
, L
'\\')) = 0;
207 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
208 InitializeObjectAttributes(&ObjectAttributes
,
213 DPRINT("Create dir: %wZ\n", &ModuleName
);
214 Status
= NtCreateDirectoryObject(&DirHandle
, 0, &ObjectAttributes
);
215 assert(NT_SUCCESS(Status
));
217 /* Create FileSystem object directory */
218 wcscpy(NameBuffer
, FILESYSTEM_ROOT_NAME
);
219 *(wcsrchr(NameBuffer
, L
'\\')) = 0;
220 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
221 InitializeObjectAttributes(&ObjectAttributes
,
226 DPRINT("Create dir: %wZ\n", &ModuleName
);
227 Status
= NtCreateDirectoryObject(&DirHandle
, 0, &ObjectAttributes
);
228 assert(NT_SUCCESS(Status
));
230 /* Add module entry for NTOSKRNL */
231 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
232 wcscat(NameBuffer
, KERNEL_MODULE_NAME
);
233 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
234 DPRINT("Kernel's Module name is: %wZ\n", &ModuleName
);
236 /* Initialize ObjectAttributes for ModuleObject */
237 InitializeObjectAttributes(&ObjectAttributes
,
243 /* Create module object */
245 Status
= ObCreateObject(&ModuleHandle
,
246 STANDARD_RIGHTS_REQUIRED
,
249 (PVOID
*)&ModuleObject
);
250 assert(NT_SUCCESS(Status
));
252 InitializeListHead(&ModuleListHead
);
254 /* Initialize ModuleObject data */
255 ModuleObject
->Base
= (PVOID
) KERNEL_BASE
;
256 ModuleObject
->Flags
= MODULE_FLAG_PE
;
257 InsertTailList(&ModuleListHead
,
258 &ModuleObject
->ListEntry
);
259 RtlCreateUnicodeString(&ModuleObject
->FullName
,
261 LdrpBuildModuleBaseName(&ModuleObject
->BaseName
,
262 &ModuleObject
->FullName
);
264 DosHeader
= (PIMAGE_DOS_HEADER
) KERNEL_BASE
;
265 ModuleObject
->Image
.PE
.FileHeader
=
266 (PIMAGE_FILE_HEADER
) ((DWORD
) ModuleObject
->Base
+
267 DosHeader
->e_lfanew
+ sizeof(ULONG
));
268 ModuleObject
->Image
.PE
.OptionalHeader
= (PIMAGE_OPTIONAL_HEADER
)
269 ((DWORD
)ModuleObject
->Image
.PE
.FileHeader
+ sizeof(IMAGE_FILE_HEADER
));
270 ModuleObject
->Image
.PE
.SectionList
= (PIMAGE_SECTION_HEADER
)
271 ((DWORD
)ModuleObject
->Image
.PE
.OptionalHeader
+ sizeof(IMAGE_OPTIONAL_HEADER
));
272 ModuleObject
->EntryPoint
= (PVOID
) ((DWORD
) ModuleObject
->Base
+
273 ModuleObject
->Image
.PE
.OptionalHeader
->AddressOfEntryPoint
);
274 DPRINT("ModuleObject:%08x entrypoint at %x\n", ModuleObject
, ModuleObject
->EntryPoint
);
275 ModuleObject
->Length
= ModuleObject
->Image
.PE
.OptionalHeader
->SizeOfImage
;
276 ModuleObject
->TextSection
= &NtoskrnlTextSection
;
278 /* Add module entry for HAL */
279 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
280 wcscat(NameBuffer
, HAL_MODULE_NAME
);
281 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
282 DPRINT("HAL's Module name is: %wZ\n", &ModuleName
);
284 /* Initialize ObjectAttributes for ModuleObject */
285 InitializeObjectAttributes(&ObjectAttributes
,
291 /* Create module object */
293 Status
= ObCreateObject(&ModuleHandle
,
294 STANDARD_RIGHTS_REQUIRED
,
297 (PVOID
*)&ModuleObject
);
298 assert(NT_SUCCESS(Status
));
300 /* Initialize ModuleObject data */
301 ModuleObject
->Base
= (PVOID
) LdrHalBase
;
302 ModuleObject
->Flags
= MODULE_FLAG_PE
;
303 InsertTailList(&ModuleListHead
,
304 &ModuleObject
->ListEntry
);
305 RtlCreateUnicodeString(&ModuleObject
->FullName
,
307 LdrpBuildModuleBaseName(&ModuleObject
->BaseName
,
308 &ModuleObject
->FullName
);
310 DosHeader
= (PIMAGE_DOS_HEADER
) LdrHalBase
;
311 ModuleObject
->Image
.PE
.FileHeader
=
312 (PIMAGE_FILE_HEADER
) ((DWORD
) ModuleObject
->Base
+
313 DosHeader
->e_lfanew
+ sizeof(ULONG
));
314 ModuleObject
->Image
.PE
.OptionalHeader
= (PIMAGE_OPTIONAL_HEADER
)
315 ((DWORD
)ModuleObject
->Image
.PE
.FileHeader
+ sizeof(IMAGE_FILE_HEADER
));
316 ModuleObject
->Image
.PE
.SectionList
= (PIMAGE_SECTION_HEADER
)
317 ((DWORD
)ModuleObject
->Image
.PE
.OptionalHeader
+ sizeof(IMAGE_OPTIONAL_HEADER
));
318 ModuleObject
->EntryPoint
= (PVOID
) ((DWORD
) ModuleObject
->Base
+
319 ModuleObject
->Image
.PE
.OptionalHeader
->AddressOfEntryPoint
);
320 DPRINT("ModuleObject:%08x entrypoint at %x\n", ModuleObject
, ModuleObject
->EntryPoint
);
321 ModuleObject
->Length
= ModuleObject
->Image
.PE
.OptionalHeader
->SizeOfImage
;
322 ModuleObject
->TextSection
= &LdrHalTextSection
;
327 LdrpOpenModuleDirectory(PHANDLE Handle
)
329 OBJECT_ATTRIBUTES ObjectAttributes
;
330 UNICODE_STRING ModuleDirectory
;
332 RtlInitUnicodeString (&ModuleDirectory
, MODULE_ROOT_NAME
);
333 InitializeObjectAttributes(&ObjectAttributes
,
335 OBJ_CASE_INSENSITIVE
,
339 return NtOpenDirectoryObject(Handle
, GENERIC_ALL
, &ObjectAttributes
);
344 * load the auto config drivers.
346 static VOID
LdrLoadAutoConfigDriver (LPWSTR RelativeDriverName
)
348 WCHAR TmpFileName
[MAX_PATH
];
349 UNICODE_STRING DriverName
;
350 PDEVICE_NODE DeviceNode
;
353 CPRINT("Loading %S\n",RelativeDriverName
);
355 wcscpy(TmpFileName
, L
"\\SystemRoot\\system32\\drivers\\");
356 wcscat(TmpFileName
, RelativeDriverName
);
357 RtlInitUnicodeString (&DriverName
, TmpFileName
);
359 /* Use IopRootDeviceNode for now */
360 Status
= IopCreateDeviceNode(IopRootDeviceNode
, NULL
, &DeviceNode
);
361 if (!NT_SUCCESS(Status
))
366 Status
= LdrLoadDriver(&DriverName
, DeviceNode
, FALSE
);
367 if (!NT_SUCCESS(Status
))
369 IopFreeDeviceNode(DeviceNode
);
370 DPRINT1("Driver load failed, status (%x)\n", Status
);
376 BOOLEAN
LdrpReadLine(PCHAR Line
,
391 while ((*Size
> 0) && (Count
< LineSize
) && ((ch
= *Block
) != (CHAR
)13))
407 if ((*Size
> 0) && (*Block
== (CHAR
)10))
418 ULONG
HexL(PCHAR Buffer
)
427 while ((j
> 0) && ((ch
= Buffer
[i
]) != ' '))
430 if ((ch
>= '0') && (ch
<= '9'))
431 Value
|= ((ch
- '0') << j
);
432 if ((ch
>= 'A') && (ch
<= 'F'))
433 Value
|= ((10 + (ch
- 'A')) << j
);
435 if ((ch
>= 'a') && (ch
<= 'f'))
436 Value
|= ((10 + (ch
- 'a')) << j
);
442 PSYMBOL
LdrpParseLine(PCHAR Line
,
444 PBOOLEAN TextBaseValid
,
447 Line format: [ADDRESS] <TYPE> <NAME>
450 A = Image information
451 t = Symbol in text segment
452 T = Symbol in text segment
453 d = Symbol in data segment
454 D = Symbol in data segment
455 b = Symbol in BSS segment
456 B = Symbol in BSS segment
457 ? = Unknown segment or symbol in unknown segment
460 ANSI_STRING AnsiString
;
467 if ((Line
[0] == (CHAR
)0) || (Line
[0] == ' '))
470 Address
= HexL(Line
);
472 Line
= strchr(Line
, ' ');
479 Line
= strchr(Line
, ' ');
484 Str
= strchr(Line
, ' ');
486 strcpy((char*)&Buffer
, Line
);
488 strncpy((char*)&Buffer
, Line
, Str
- Line
);
490 if ((Type
== 'A') && (strcmp((char*)&Buffer
, "__section_alignment__")) == 0)
492 *Alignment
= Address
;
496 /* We only want symbols in the .text segment */
497 if ((Type
!= 't') && (Type
!= 'T'))
500 /* Discard other symbols we can't use */
501 if ((Buffer
[0] != '_') || ((Buffer
[0] == '_') && (Buffer
[1] == '_')))
504 Symbol
= ExAllocatePool(NonPagedPool
, sizeof(SYMBOL
));
510 Symbol
->RelativeAddress
= Address
;
512 RtlInitAnsiString(&AnsiString
, (PCSZ
)&Buffer
);
513 RtlAnsiStringToUnicodeString(&Symbol
->Name
, &AnsiString
, TRUE
);
515 if (!(*TextBaseValid
))
517 *TextBase
= Address
- *Alignment
;
518 *TextBaseValid
= TRUE
;
524 VOID
LdrpLoadModuleSymbolsFromBuffer(
525 PMODULE_OBJECT ModuleObject
,
529 Symbols must be sorted by address, e.g.
530 "nm --numeric-sort module.sys > module.sym"
533 PSYMBOL Symbol
, CurrentSymbol
= NULL
;
534 BOOLEAN TextBaseValid
;
541 assert(ModuleObject
);
543 if (ModuleObject
->TextSection
== NULL
)
545 ModuleObject
->TextSection
= &NtoskrnlTextSection
;
548 if (ModuleObject
->TextSection
->Symbols
.SymbolCount
> 0)
550 CPRINT("Symbols are already loaded for %wZ\n", &ModuleObject
->BaseName
);
554 ModuleObject
->TextSection
->Symbols
.SymbolCount
= 0;
555 ModuleObject
->TextSection
->Symbols
.Symbols
= NULL
;
556 TextBaseValid
= FALSE
;
558 while (LdrpReadLine((PCHAR
)&Line
, 256, &Buffer
, &Length
))
560 Symbol
= LdrpParseLine((PCHAR
)&Line
, &Tmp
, &Valid
, &Alignment
);
562 if ((Valid
) && (!TextBaseValid
))
565 TextBaseValid
= TRUE
;
570 Symbol
->RelativeAddress
-= TextBase
;
572 if (ModuleObject
->TextSection
->Symbols
.Symbols
== NULL
)
573 ModuleObject
->TextSection
->Symbols
.Symbols
= Symbol
;
575 CurrentSymbol
->Next
= Symbol
;
577 CurrentSymbol
= Symbol
;
579 ModuleObject
->TextSection
->Symbols
.SymbolCount
++;
584 VOID
LdrpLoadUserModuleSymbolsFromBuffer(
585 PLDR_MODULE ModuleObject
,
589 Symbols must be sorted by address, e.g.
590 "nm --numeric-sort module.dll > module.sym"
593 PSYMBOL Symbol
, CurrentSymbol
= NULL
;
594 BOOLEAN TextBaseValid
;
601 if (ModuleObject
->Symbols
.SymbolCount
> 0)
603 DPRINT("Symbols are already loaded for %wZ\n", &ModuleObject
->BaseDllName
);
607 ModuleObject
->Symbols
.SymbolCount
= 0;
608 ModuleObject
->Symbols
.Symbols
= NULL
;
609 TextBaseValid
= FALSE
;
611 while (LdrpReadLine((PCHAR
)&Line
, 256, &Buffer
, &Length
))
613 Symbol
= LdrpParseLine((PCHAR
)&Line
, &Tmp
, &Valid
, &Alignment
);
615 if ((Valid
) && (!TextBaseValid
))
618 TextBaseValid
= TRUE
;
623 Symbol
->RelativeAddress
-= TextBase
;
625 if (ModuleObject
->Symbols
.Symbols
== NULL
)
626 ModuleObject
->Symbols
.Symbols
= Symbol
;
628 CurrentSymbol
->Next
= Symbol
;
630 CurrentSymbol
= Symbol
;
632 ModuleObject
->Symbols
.SymbolCount
++;
638 LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject
)
640 FILE_STANDARD_INFORMATION FileStdInfo
;
641 OBJECT_ATTRIBUTES ObjectAttributes
;
642 WCHAR TmpFileName
[MAX_PATH
];
643 UNICODE_STRING Filename
;
649 IO_STATUS_BLOCK IoStatusBlock
;
651 ModuleObject
->TextSection
->Symbols
.SymbolCount
= 0;
652 ModuleObject
->TextSection
->Symbols
.Symbols
= NULL
;
654 /* Get the path to the symbol store */
655 wcscpy(TmpFileName
, L
"\\SystemRoot\\symbols\\");
657 /* Get the symbol filename from the module name */
658 Start
= wcsrchr(ModuleObject
->BaseName
.Buffer
, L
'\\');
660 Start
= ModuleObject
->BaseName
.Buffer
;
664 Ext
= wcsrchr(ModuleObject
->BaseName
.Buffer
, L
'.');
666 Length
= Ext
- Start
;
668 Length
= wcslen(Start
);
670 wcsncat(TmpFileName
, Start
, Length
);
671 wcscat(TmpFileName
, L
".sym");
672 RtlInitUnicodeString(&Filename
, TmpFileName
);
675 InitializeObjectAttributes(&ObjectAttributes
,
681 Status
= ZwOpenFile(&FileHandle
,
687 if (!NT_SUCCESS(Status
))
689 DPRINT("Could not open symbol file: %wZ\n", &Filename
);
693 CPRINT("Loading symbols from %wZ...\n", &Filename
);
695 /* Get the size of the file */
696 Status
= ZwQueryInformationFile(FileHandle
,
700 FileStandardInformation
);
701 if (!NT_SUCCESS(Status
))
703 DPRINT("Could not get file size\n");
707 /* Allocate nonpageable memory for symbol file */
708 FileBuffer
= ExAllocatePool(NonPagedPool
,
709 FileStdInfo
.EndOfFile
.u
.LowPart
);
711 if (FileBuffer
== NULL
)
713 DPRINT("Could not allocate memory for symbol file\n");
717 /* Load file into memory chunk */
718 Status
= ZwReadFile(FileHandle
,
722 FileStdInfo
.EndOfFile
.u
.LowPart
,
724 if (!NT_SUCCESS(Status
))
726 DPRINT("Could not read symbol file into memory\n");
727 ExFreePool(FileBuffer
);
733 LdrpLoadModuleSymbolsFromBuffer(ModuleObject
,
735 FileStdInfo
.EndOfFile
.u
.LowPart
);
737 ExFreePool(FileBuffer
);
740 VOID
LdrLoadUserModuleSymbols(PLDR_MODULE ModuleObject
)
742 FILE_STANDARD_INFORMATION FileStdInfo
;
743 OBJECT_ATTRIBUTES ObjectAttributes
;
744 WCHAR TmpFileName
[MAX_PATH
];
745 UNICODE_STRING Filename
;
751 IO_STATUS_BLOCK IoStatusBlock
;
753 ModuleObject
->Symbols
.SymbolCount
= 0;
754 ModuleObject
->Symbols
.Symbols
= NULL
;
756 /* Get the path to the symbol store */
757 wcscpy(TmpFileName
, L
"\\SystemRoot\\symbols\\");
759 /* Get the symbol filename from the module name */
760 Start
= wcsrchr(ModuleObject
->BaseDllName
.Buffer
, L
'\\');
762 Start
= ModuleObject
->BaseDllName
.Buffer
;
766 Ext
= wcsrchr(ModuleObject
->BaseDllName
.Buffer
, L
'.');
768 Length
= Ext
- Start
;
770 Length
= wcslen(Start
);
772 wcsncat(TmpFileName
, Start
, Length
);
773 wcscat(TmpFileName
, L
".sym");
774 RtlInitUnicodeString(&Filename
, TmpFileName
);
777 InitializeObjectAttributes(&ObjectAttributes
,
783 Status
= ZwOpenFile(&FileHandle
,
789 if (!NT_SUCCESS(Status
))
791 DPRINT("Could not open symbol file: %wZ\n", &Filename
);
795 DbgPrint("Loading symbols from %wZ...\n", &Filename
);
797 /* Get the size of the file */
798 Status
= ZwQueryInformationFile(FileHandle
,
802 FileStandardInformation
);
803 if (!NT_SUCCESS(Status
))
805 DPRINT("Could not get file size\n");
809 /* Allocate nonpageable memory for symbol file */
810 FileBuffer
= ExAllocatePool(NonPagedPool
,
811 FileStdInfo
.EndOfFile
.u
.LowPart
);
813 if (FileBuffer
== NULL
)
815 DPRINT("Could not allocate memory for symbol file\n");
819 /* Load file into memory chunk */
820 Status
= ZwReadFile(FileHandle
,
824 FileStdInfo
.EndOfFile
.u
.LowPart
,
826 if (!NT_SUCCESS(Status
))
828 DPRINT("Could not read symbol file into memory\n");
829 ExFreePool(FileBuffer
);
835 LdrpLoadUserModuleSymbolsFromBuffer(ModuleObject
,
837 FileStdInfo
.EndOfFile
.u
.LowPart
);
839 ExFreePool(FileBuffer
);
845 NTSTATUS
LdrFindModuleObject(
846 PUNICODE_STRING ModuleName
,
847 PMODULE_OBJECT
*ModuleObject
)
850 WCHAR NameBuffer
[MAX_PATH
];
852 OBJECT_ATTRIBUTES ObjectAttributes
;
853 UNICODE_STRING RemainingPath
;
855 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
856 wcscat(NameBuffer
, ModuleName
->Buffer
);
857 RtlInitUnicodeString(&Name
, NameBuffer
);
859 InitializeObjectAttributes(&ObjectAttributes
,
864 Status
= ObFindObject(&ObjectAttributes
,
865 (PVOID
*)ModuleObject
,
868 if (!NT_SUCCESS(Status
))
873 if ((RemainingPath
.Buffer
!= NULL
) || (*ModuleObject
== NULL
))
875 RtlFreeUnicodeString(&RemainingPath
);
876 return STATUS_UNSUCCESSFUL
;
879 return STATUS_SUCCESS
;
882 VOID
LdrLoadAutoConfigDrivers (VOID
)
888 UNICODE_STRING ModuleName
;
889 PMODULE_OBJECT ModuleObject
;
891 /* Load symbols for ntoskrnl.exe and hal.dll because \SystemRoot
892 is created after their module entries */
894 RtlInitUnicodeString(&ModuleName
, KERNEL_MODULE_NAME
);
895 Status
= LdrFindModuleObject(&ModuleName
, &ModuleObject
);
896 if (NT_SUCCESS(Status
))
898 LdrpLoadModuleSymbols(ModuleObject
);
901 RtlInitUnicodeString(&ModuleName
, HAL_MODULE_NAME
);
902 Status
= LdrFindModuleObject(&ModuleName
, &ModuleObject
);
903 if (NT_SUCCESS(Status
))
905 LdrpLoadModuleSymbols(ModuleObject
);
913 //LdrLoadAutoConfigDriver( L"pci.sys" );
918 LdrLoadAutoConfigDriver( L
"keyboard.sys" );
923 LdrLoadAutoConfigDriver( L
"blue.sys" );
928 LdrLoadAutoConfigDriver(L
"vidport.sys");
933 LdrLoadAutoConfigDriver(L
"vgamp.sys");
936 * Minix filesystem driver
938 LdrLoadAutoConfigDriver(L
"minixfs.sys");
941 * Mailslot filesystem driver
943 LdrLoadAutoConfigDriver(L
"msfs.sys");
946 * Named pipe filesystem driver
948 LdrLoadAutoConfigDriver(L
"npfs.sys");
953 // LdrLoadAutoConfigDriver(L"l8042prt.sys");
954 LdrLoadAutoConfigDriver(L
"psaux.sys");
955 LdrLoadAutoConfigDriver(L
"mouclass.sys");
964 LdrLoadAutoConfigDriver(L
"ndis.sys");
967 * Novell Eagle 2000 driver
969 //LdrLoadAutoConfigDriver(L"ne2000.sys");
972 * TCP/IP protocol driver
974 LdrLoadAutoConfigDriver(L
"tcpip.sys");
979 //LdrLoadAutoConfigDriver(L"tditest.sys");
982 * Ancillary Function Driver
984 LdrLoadAutoConfigDriver(L
"afd.sys");
989 static NTSTATUS STDCALL
990 LdrCreateModule(PVOID ObjectBody
,
993 POBJECT_ATTRIBUTES ObjectAttributes
)
995 DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n",
999 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+ 1, '\\') != NULL
)
1001 return STATUS_UNSUCCESSFUL
;
1003 if (Parent
!= NULL
&& RemainingPath
!= NULL
)
1005 ObAddEntryDirectory(Parent
, ObjectBody
, RemainingPath
+ 1);
1008 return STATUS_SUCCESS
;
1012 * FUNCTION: Loads a kernel driver
1014 * FileName = Driver to load
1018 NTSTATUS
LdrLoadDriver(PUNICODE_STRING Filename
,
1019 PDEVICE_NODE DeviceNode
,
1020 BOOLEAN BootDriversOnly
)
1022 PMODULE_OBJECT ModuleObject
;
1023 WCHAR Buffer
[MAX_PATH
];
1029 ModuleObject
= LdrLoadModule(Filename
);
1032 return STATUS_UNSUCCESSFUL
;
1035 /* Set a service name for the device node */
1037 /* Get the service name from the module name */
1038 Start
= wcsrchr(ModuleObject
->BaseName
.Buffer
, L
'\\');
1040 Start
= ModuleObject
->BaseName
.Buffer
;
1044 Ext
= wcsrchr(ModuleObject
->BaseName
.Buffer
, L
'.');
1046 Length
= Ext
- Start
;
1048 Length
= wcslen(Start
);
1050 wcsncpy(Buffer
, Start
, Length
);
1051 RtlInitUnicodeString(&DeviceNode
->ServiceName
, Buffer
);
1054 Status
= IopInitializeDriver(ModuleObject
->EntryPoint
, DeviceNode
);
1055 if (!NT_SUCCESS(Status
))
1057 ObDereferenceObject(ModuleObject
);
1063 NTSTATUS
LdrLoadGdiDriver (PUNICODE_STRING DriverName
,
1064 PVOID
*ImageAddress
,
1065 PVOID
*SectionPointer
,
1067 PVOID
*ExportSectionPointer
)
1069 PMODULE_OBJECT ModuleObject
;
1071 ModuleObject
= LdrLoadModule(DriverName
);
1072 if (ModuleObject
== 0)
1074 return STATUS_UNSUCCESSFUL
;
1078 *ImageAddress
= ModuleObject
->Base
;
1080 // if (SectionPointer)
1081 // *SectionPointer = ModuleObject->
1084 *EntryPoint
= ModuleObject
->EntryPoint
;
1086 // if (ExportSectionPointer)
1087 // *ExportSectionPointer = ModuleObject->
1089 return STATUS_SUCCESS
;
1094 LdrLoadModule(PUNICODE_STRING Filename
)
1096 PVOID ModuleLoadBase
;
1099 OBJECT_ATTRIBUTES ObjectAttributes
;
1100 PMODULE_OBJECT ModuleObject
;
1101 FILE_STANDARD_INFORMATION FileStdInfo
;
1102 IO_STATUS_BLOCK IoStatusBlock
;
1104 /* Check for module already loaded */
1105 if ((ModuleObject
= LdrOpenModule(Filename
)) != NULL
)
1107 return ModuleObject
;
1110 DPRINT("Loading Module %wZ...\n", Filename
);
1112 /* Open the Module */
1113 InitializeObjectAttributes(&ObjectAttributes
,
1119 Status
= NtOpenFile(&FileHandle
,
1126 if (!NT_SUCCESS(Status
))
1128 CPRINT("Could not open module file: %wZ\n", Filename
);
1133 /* Get the size of the file */
1134 Status
= NtQueryInformationFile(FileHandle
,
1137 sizeof(FileStdInfo
),
1138 FileStandardInformation
);
1139 if (!NT_SUCCESS(Status
))
1141 CPRINT("Could not get file size\n");
1146 /* Allocate nonpageable memory for driver */
1147 ModuleLoadBase
= ExAllocatePoolWithTag(NonPagedPool
,
1148 FileStdInfo
.EndOfFile
.u
.LowPart
,
1151 if (ModuleLoadBase
== NULL
)
1153 CPRINT("Could not allocate memory for module");
1158 /* Load driver into memory chunk */
1159 Status
= NtReadFile(FileHandle
,
1163 FileStdInfo
.EndOfFile
.u
.LowPart
,
1165 if (!NT_SUCCESS(Status
))
1167 CPRINT("Could not read module file into memory");
1168 ExFreePool(ModuleLoadBase
);
1173 NtClose(FileHandle
);
1175 Status
= LdrProcessModule(ModuleLoadBase
,
1178 if (!NT_SUCCESS(Status
))
1180 CPRINT("Could not process module");
1181 ExFreePool(ModuleLoadBase
);
1186 ExFreePool(ModuleLoadBase
);
1190 /* Load symbols for module if available */
1191 LdrpLoadModuleSymbols(ModuleObject
);
1195 return ModuleObject
;
1199 LdrProcessDriver(PVOID ModuleLoadBase
, PCHAR FileName
, ULONG ModuleLength
)
1201 PMODULE_OBJECT ModuleObject
;
1202 UNICODE_STRING ModuleName
;
1203 PDEVICE_NODE DeviceNode
;
1208 CHAR TmpBaseName
[MAX_PATH
];
1209 CHAR TmpFileName
[MAX_PATH
];
1210 ANSI_STRING AnsiString
;
1214 /* Split the filename into base name and extension */
1215 Ext
= strrchr(FileName
, '.');
1217 Length
= Ext
- FileName
;
1219 Length
= strlen(FileName
);
1221 if ((Ext
!= NULL
) && (strcmp(Ext
, ".sym") == 0))
1223 DPRINT("Module %s is a symbol file\n", FileName
);
1225 strncpy(TmpBaseName
, FileName
, Length
);
1226 TmpBaseName
[Length
] = '\0';
1228 DPRINT("base: %s (Length %d)\n", TmpBaseName
, Length
);
1230 strcpy(TmpFileName
, TmpBaseName
);
1231 strcat(TmpFileName
, ".sys");
1232 RtlInitAnsiString(&AnsiString
, TmpFileName
);
1234 DPRINT("dasdsad: %s\n", TmpFileName
);
1236 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
1237 Status
= LdrFindModuleObject(&ModuleName
, &ModuleObject
);
1238 RtlFreeUnicodeString(&ModuleName
);
1239 if (!NT_SUCCESS(Status
))
1241 strcpy(TmpFileName
, TmpBaseName
);
1242 strcat(TmpFileName
, ".exe");
1243 RtlInitAnsiString(&AnsiString
, TmpFileName
);
1244 RtlAnsiStringToUnicodeString(&ModuleName
, &AnsiString
, TRUE
);
1245 Status
= LdrFindModuleObject(&ModuleName
, &ModuleObject
);
1246 RtlFreeUnicodeString(&ModuleName
);
1248 if (NT_SUCCESS(Status
))
1250 LdrpLoadModuleSymbolsFromBuffer(
1255 return(STATUS_SUCCESS
);
1259 DPRINT("Module %s is executable\n", FileName
);
1263 /* Use IopRootDeviceNode for now */
1264 Status
= IopCreateDeviceNode(IopRootDeviceNode
, NULL
, &DeviceNode
);
1265 if (!NT_SUCCESS(Status
))
1267 CPRINT("Driver load failed, status (%x)\n", Status
);
1271 RtlCreateUnicodeStringFromAsciiz(&ModuleName
,
1273 Status
= LdrProcessModule(ModuleLoadBase
,
1276 RtlFreeUnicodeString(&ModuleName
);
1277 if (ModuleObject
== NULL
)
1279 IopFreeDeviceNode(DeviceNode
);
1280 CPRINT("Driver load failed, status (%x)\n", Status
);
1281 return(STATUS_UNSUCCESSFUL
);
1284 Status
= IopInitializeDriver(ModuleObject
->EntryPoint
, DeviceNode
);
1285 if (!NT_SUCCESS(Status
))
1287 IopFreeDeviceNode(DeviceNode
);
1288 CPRINT("Driver load failed, status (%x)\n", Status
);
1295 LdrProcessModule(PVOID ModuleLoadBase
,
1296 PUNICODE_STRING ModuleName
,
1297 PMODULE_OBJECT
*ModuleObject
)
1299 PIMAGE_DOS_HEADER PEDosHeader
;
1301 /* If MZ header exists */
1302 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
1303 if (PEDosHeader
->e_magic
== IMAGE_DOS_MAGIC
&& PEDosHeader
->e_lfanew
!= 0L)
1305 return LdrPEProcessModule(ModuleLoadBase
,
1310 CPRINT("Module wasn't PE\n");
1311 return STATUS_UNSUCCESSFUL
;
1314 static PMODULE_OBJECT
1315 LdrOpenModule(PUNICODE_STRING Filename
)
1318 WCHAR NameBuffer
[60];
1319 UNICODE_STRING ModuleName
;
1320 OBJECT_ATTRIBUTES ObjectAttributes
;
1321 PMODULE_OBJECT ModuleObject
;
1322 UNICODE_STRING RemainingPath
;
1324 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
1325 if (wcsrchr(Filename
->Buffer
, '\\') != 0)
1327 wcscat(NameBuffer
, wcsrchr(Filename
->Buffer
, '\\') + 1);
1331 wcscat(NameBuffer
, Filename
->Buffer
);
1333 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
1334 InitializeObjectAttributes(&ObjectAttributes
,
1336 OBJ_CASE_INSENSITIVE
,
1340 Status
= ObFindObject(&ObjectAttributes
,
1341 (PVOID
*) &ModuleObject
,
1345 if (NT_SUCCESS(Status
) && (RemainingPath
.Buffer
== NULL
|| *(RemainingPath
.Buffer
) == 0))
1347 DPRINT("Module %wZ at %p\n", Filename
, ModuleObject
);
1348 RtlFreeUnicodeString (&RemainingPath
);
1350 return ModuleObject
;
1353 RtlFreeUnicodeString (&RemainingPath
);
1359 LdrGetExportAddress(PMODULE_OBJECT ModuleObject
,
1361 unsigned short Hint
)
1363 if (ModuleObject
->Flags
& MODULE_FLAG_PE
)
1365 return LdrPEGetExportAddress(ModuleObject
, Name
, Hint
);
1374 LdrpQueryModuleInformation(PVOID Buffer
,
1378 PLIST_ENTRY current_entry
;
1379 PMODULE_OBJECT current
;
1380 ULONG ModuleCount
= 0;
1381 PSYSTEM_MODULE_INFORMATION Smi
;
1382 ANSI_STRING AnsiName
;
1385 // KeAcquireSpinLock(&ModuleListLock,&oldlvl);
1387 /* calculate required size */
1388 current_entry
= ModuleListHead
.Flink
;
1389 while (current_entry
!= (&ModuleListHead
))
1392 current_entry
= current_entry
->Flink
;
1395 *ReqSize
= sizeof(SYSTEM_MODULE_INFORMATION
)+
1396 (ModuleCount
- 1) * sizeof(SYSTEM_MODULE_ENTRY
);
1398 if (Size
< *ReqSize
)
1400 // KeReleaseSpinLock(&ModuleListLock,oldlvl);
1401 return STATUS_INFO_LENGTH_MISMATCH
;
1404 /* fill the buffer */
1405 memset(Buffer
, '=', Size
);
1407 Smi
= (PSYSTEM_MODULE_INFORMATION
)Buffer
;
1408 Smi
->Count
= ModuleCount
;
1411 current_entry
= ModuleListHead
.Flink
;
1412 while (current_entry
!= (&ModuleListHead
))
1414 current
= CONTAINING_RECORD(current_entry
,MODULE_OBJECT
,ListEntry
);
1416 Smi
->Module
[ModuleCount
].Unknown2
= 0; /* Always 0 */
1417 Smi
->Module
[ModuleCount
].BaseAddress
= current
->Base
;
1418 Smi
->Module
[ModuleCount
].Size
= current
->Length
;
1419 Smi
->Module
[ModuleCount
].Flags
= 0; /* Flags ??? (GN) */
1420 Smi
->Module
[ModuleCount
].EntryIndex
= ModuleCount
;
1422 AnsiName
.Length
= 0;
1423 AnsiName
.MaximumLength
= 256;
1424 AnsiName
.Buffer
= Smi
->Module
[ModuleCount
].Name
;
1425 RtlUnicodeStringToAnsiString(&AnsiName
,
1429 p
= strrchr (AnsiName
.Buffer
, '\\');
1432 Smi
->Module
[ModuleCount
].PathLength
= 0;
1433 Smi
->Module
[ModuleCount
].NameLength
= strlen(AnsiName
.Buffer
);
1438 Smi
->Module
[ModuleCount
].PathLength
= p
- AnsiName
.Buffer
;
1439 Smi
->Module
[ModuleCount
].NameLength
= strlen(p
);
1443 current_entry
= current_entry
->Flink
;
1446 // KeReleaseSpinLock(&ModuleListLock,oldlvl);
1448 return STATUS_SUCCESS
;
1453 LdrpBuildModuleBaseName(PUNICODE_STRING BaseName
,
1454 PUNICODE_STRING FullName
)
1456 UNICODE_STRING Name
;
1460 DPRINT("LdrpBuildModuleBaseName()\n");
1461 DPRINT("FullName %wZ\n", FullName
);
1463 p
= wcsrchr(FullName
->Buffer
, '\\');
1466 p
= FullName
->Buffer
;
1473 DPRINT("p %S\n", p
);
1475 RtlCreateUnicodeString(&Name
, p
);
1483 DPRINT("p %S\n", p
);
1485 RtlCreateUnicodeString(BaseName
, p
);
1486 RtlFreeUnicodeString(&Name
);
1490 /* ---------------------------------------------- PE Module support */
1493 LdrPEProcessModule(PVOID ModuleLoadBase
,
1494 PUNICODE_STRING FileName
,
1495 PMODULE_OBJECT
*ModuleObject
)
1497 unsigned int DriverSize
, Idx
, Idx2
;
1498 ULONG RelocDelta
, NumRelocs
;
1499 DWORD CurrentSize
, TotalRelocs
;
1502 PIMAGE_DOS_HEADER PEDosHeader
;
1503 PIMAGE_FILE_HEADER PEFileHeader
;
1504 PIMAGE_OPTIONAL_HEADER PEOptionalHeader
;
1505 PIMAGE_SECTION_HEADER PESectionHeaders
;
1506 PRELOCATION_DIRECTORY RelocDir
;
1507 PRELOCATION_ENTRY RelocEntry
;
1508 PMODULE_OBJECT LibraryModuleObject
;
1509 HANDLE ModuleHandle
;
1510 PMODULE_OBJECT CreatedModuleObject
;
1511 PVOID
*ImportAddressList
;
1512 PULONG FunctionNameList
;
1515 OBJECT_ATTRIBUTES ObjectAttributes
;
1516 UNICODE_STRING ModuleName
;
1517 WCHAR NameBuffer
[60];
1518 MODULE_TEXT_SECTION
* ModuleTextSection
;
1521 DPRINT("Processing PE Module at module base:%08lx\n", ModuleLoadBase
);
1523 /* Get header pointers */
1524 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
1525 PEMagic
= (PULONG
) ((unsigned int) ModuleLoadBase
+
1526 PEDosHeader
->e_lfanew
);
1527 PEFileHeader
= (PIMAGE_FILE_HEADER
) ((unsigned int) ModuleLoadBase
+
1528 PEDosHeader
->e_lfanew
+ sizeof(ULONG
));
1529 PEOptionalHeader
= (PIMAGE_OPTIONAL_HEADER
) ((unsigned int) ModuleLoadBase
+
1530 PEDosHeader
->e_lfanew
+ sizeof(ULONG
) + sizeof(IMAGE_FILE_HEADER
));
1531 PESectionHeaders
= (PIMAGE_SECTION_HEADER
) ((unsigned int) ModuleLoadBase
+
1532 PEDosHeader
->e_lfanew
+ sizeof(ULONG
) + sizeof(IMAGE_FILE_HEADER
) +
1533 sizeof(IMAGE_OPTIONAL_HEADER
));
1536 /* Check file magic numbers */
1537 if (PEDosHeader
->e_magic
!= IMAGE_DOS_MAGIC
)
1539 CPRINT("Incorrect MZ magic: %04x\n", PEDosHeader
->e_magic
);
1540 return STATUS_UNSUCCESSFUL
;
1542 if (PEDosHeader
->e_lfanew
== 0)
1544 CPRINT("Invalid lfanew offset: %08x\n", PEDosHeader
->e_lfanew
);
1545 return STATUS_UNSUCCESSFUL
;
1547 if (*PEMagic
!= IMAGE_PE_MAGIC
)
1549 CPRINT("Incorrect PE magic: %08x\n", *PEMagic
);
1550 return STATUS_UNSUCCESSFUL
;
1552 if (PEFileHeader
->Machine
!= IMAGE_FILE_MACHINE_I386
)
1554 CPRINT("Incorrect Architechture: %04x\n", PEFileHeader
->Machine
);
1555 return STATUS_UNSUCCESSFUL
;
1559 /* FIXME: if image is fixed-address load, then fail */
1561 /* FIXME: check/verify OS version number */
1563 DPRINT("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
1564 PEOptionalHeader
->Magic
,
1565 PEOptionalHeader
->MajorLinkerVersion
,
1566 PEOptionalHeader
->MinorLinkerVersion
);
1567 DPRINT("Entry Point:%08lx\n", PEOptionalHeader
->AddressOfEntryPoint
);
1570 /* Determine the size of the module */
1571 DriverSize
= PEOptionalHeader
->SizeOfImage
;
1572 DPRINT("DriverSize %x\n",DriverSize
);
1574 /* Allocate a virtual section for the module */
1575 DriverBase
= MmAllocateSection(DriverSize
);
1576 if (DriverBase
== 0)
1578 CPRINT("Failed to allocate a virtual section for driver\n");
1579 return STATUS_UNSUCCESSFUL
;
1581 CPRINT("DriverBase: %x\n", DriverBase
);
1583 /* Copy headers over */
1584 memcpy(DriverBase
, ModuleLoadBase
, PEOptionalHeader
->SizeOfHeaders
);
1586 /* Copy image sections into virtual section */
1587 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
1589 // Copy current section into current offset of virtual section
1590 if (PESectionHeaders
[Idx
].Characteristics
&
1591 (IMAGE_SECTION_CHAR_CODE
| IMAGE_SECTION_CHAR_DATA
))
1593 DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
1594 PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
);
1595 memcpy(PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
,
1596 (PVOID
)(ModuleLoadBase
+ PESectionHeaders
[Idx
].PointerToRawData
),
1597 PESectionHeaders
[Idx
].Misc
.VirtualSize
> PESectionHeaders
[Idx
].SizeOfRawData
? PESectionHeaders
[Idx
].SizeOfRawData
: PESectionHeaders
[Idx
].Misc
.VirtualSize
);
1601 DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
1602 PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
);
1603 memset(PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
,
1604 '\0', PESectionHeaders
[Idx
].Misc
.VirtualSize
);
1607 CurrentSize
+= ROUND_UP(PESectionHeaders
[Idx
].Misc
.VirtualSize
,
1608 PEOptionalHeader
->SectionAlignment
);
1611 // CurrentBase = (PVOID)((DWORD)CurrentBase +
1612 // ROUND_UP(PESectionHeaders[Idx].SizeOfRawData.Misc.VirtualSize,
1613 // PEOptionalHeader->SectionAlignment));
1616 /* Perform relocation fixups */
1617 RelocDelta
= (DWORD
) DriverBase
- PEOptionalHeader
->ImageBase
;
1618 RelocDir
= (PRELOCATION_DIRECTORY
)(PEOptionalHeader
->DataDirectory
[
1619 IMAGE_DIRECTORY_ENTRY_BASERELOC
].VirtualAddress
);
1620 DPRINT("DrvrBase:%08lx ImgBase:%08lx RelocDelta:%08lx\n",
1622 PEOptionalHeader
->ImageBase
,
1624 DPRINT("RelocDir %x\n",RelocDir
);
1626 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
1628 if (PESectionHeaders
[Idx
].VirtualAddress
== (DWORD
)RelocDir
)
1630 DPRINT("Name %.8s PESectionHeader[Idx].PointerToRawData %x\n",
1631 PESectionHeaders
[Idx
].Name
,
1632 PESectionHeaders
[Idx
].PointerToRawData
);
1633 RelocDir
= PESectionHeaders
[Idx
].PointerToRawData
+
1635 CurrentSize
= PESectionHeaders
[Idx
].Misc
.VirtualSize
;
1640 RelocDir
= RelocDir
+ (ULONG
)DriverBase
;
1641 CurrentSize
= PEOptionalHeader
->DataDirectory
1642 [IMAGE_DIRECTORY_ENTRY_BASERELOC
].Size
;
1644 DPRINT("RelocDir %08lx CurrentSize %08lx\n", RelocDir
, CurrentSize
);
1646 while (TotalRelocs
< CurrentSize
&& RelocDir
->SizeOfBlock
!= 0)
1648 NumRelocs
= (RelocDir
->SizeOfBlock
- sizeof(RELOCATION_DIRECTORY
)) /
1650 /* DPRINT("RelocDir at %08lx for VA %08lx with %08lx relocs\n",
1652 RelocDir->VirtualAddress,
1654 RelocEntry
= (PRELOCATION_ENTRY
) ((DWORD
)RelocDir
+
1655 sizeof(RELOCATION_DIRECTORY
));
1656 for (Idx
= 0; Idx
< NumRelocs
; Idx
++)
1662 Offset
= RelocEntry
[Idx
].TypeOffset
& 0xfff;
1663 Type
= (RelocEntry
[Idx
].TypeOffset
>> 12) & 0xf;
1664 RelocItem
= (PDWORD
)(DriverBase
+ RelocDir
->VirtualAddress
+
1666 /* DPRINT(" reloc at %08lx %x %s old:%08lx new:%08lx\n",
1669 Type ? "HIGHLOW" : "ABS",
1671 (*RelocItem) + RelocDelta); */
1674 (*RelocItem
) += RelocDelta
;
1678 CPRINT("Unknown relocation type %x at %x\n",Type
, &Type
);
1679 return STATUS_UNSUCCESSFUL
;
1682 TotalRelocs
+= RelocDir
->SizeOfBlock
;
1683 RelocDir
= (PRELOCATION_DIRECTORY
)((DWORD
)RelocDir
+
1684 RelocDir
->SizeOfBlock
);
1685 // DPRINT("TotalRelocs: %08lx CurrentSize: %08lx\n", TotalRelocs, CurrentSize);
1688 DPRINT("PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] %x\n",
1689 PEOptionalHeader
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
]
1691 /* Perform import fixups */
1692 if (PEOptionalHeader
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress
)
1694 PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory
;
1696 /* Process each import module */
1697 ImportModuleDirectory
= (PIMAGE_IMPORT_MODULE_DIRECTORY
)
1698 ((DWORD
)DriverBase
+ PEOptionalHeader
->
1699 DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress
);
1700 DPRINT("Processeing import directory at %p\n", ImportModuleDirectory
);
1701 while (ImportModuleDirectory
->dwRVAModuleName
)
1703 /* Check to make sure that import lib is kernel */
1704 pName
= (PCHAR
) DriverBase
+
1705 ImportModuleDirectory
->dwRVAModuleName
;
1706 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
1708 for (Idx
= 0; NameBuffer
[Idx
] != 0; Idx
++);
1709 for (Idx2
= 0; pName
[Idx2
] != '\0'; Idx2
++)
1711 NameBuffer
[Idx
+ Idx2
] = (WCHAR
) pName
[Idx2
];
1713 NameBuffer
[Idx
+ Idx2
] = 0;
1715 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
1716 DPRINT("Import module: %wZ\n", &ModuleName
);
1718 LibraryModuleObject
= LdrLoadModule(&ModuleName
);
1719 if (LibraryModuleObject
== 0)
1721 CPRINT("Unknown import module: %wZ\n", &ModuleName
);
1723 /* Get the import address list */
1724 ImportAddressList
= (PVOID
*) ((DWORD
)DriverBase
+
1725 ImportModuleDirectory
->dwRVAFunctionAddressList
);
1727 /* Get the list of functions to import */
1728 if (ImportModuleDirectory
->dwRVAFunctionNameList
!= 0)
1730 FunctionNameList
= (PULONG
) ((DWORD
)DriverBase
+
1731 ImportModuleDirectory
->dwRVAFunctionNameList
);
1735 FunctionNameList
= (PULONG
) ((DWORD
)DriverBase
+
1736 ImportModuleDirectory
->dwRVAFunctionAddressList
);
1738 /* Walk through function list and fixup addresses */
1739 while (*FunctionNameList
!= 0L)
1741 if ((*FunctionNameList
) & 0x80000000) // hint
1746 Hint
= (*FunctionNameList
) & 0xffff;
1750 pName
= (PCHAR
)((DWORD
)DriverBase
+
1751 *FunctionNameList
+ 2);
1752 Hint
= *(PWORD
)((DWORD
)DriverBase
+ *FunctionNameList
);
1754 DPRINT(" Hint:%04x Name:%s\n", Hint
, pName
);
1756 /* Fixup the current import symbol */
1757 if (LibraryModuleObject
!= NULL
)
1759 *ImportAddressList
= LdrGetExportAddress(LibraryModuleObject
,
1765 CPRINT("Unresolved kernel symbol: %s\n", pName
);
1766 return STATUS_UNSUCCESSFUL
;
1768 ImportAddressList
++;
1771 ImportModuleDirectory
++;
1775 /* Create ModuleName string */
1776 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
1777 if (wcsrchr(FileName
->Buffer
, '\\') != 0)
1779 wcscat(NameBuffer
, wcsrchr(FileName
->Buffer
, '\\') + 1);
1783 wcscat(NameBuffer
, FileName
->Buffer
);
1785 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
1786 CPRINT("Module name is: %wZ\n", &ModuleName
);
1788 /* Initialize ObjectAttributes for ModuleObject */
1789 InitializeObjectAttributes(&ObjectAttributes
,
1795 /* Create module object */
1797 Status
= ObCreateObject(&ModuleHandle
,
1798 STANDARD_RIGHTS_REQUIRED
,
1801 (PVOID
*)&CreatedModuleObject
);
1802 if (!NT_SUCCESS(Status
))
1807 /* Initialize ModuleObject data */
1808 CreatedModuleObject
->Base
= DriverBase
;
1809 CreatedModuleObject
->Flags
= MODULE_FLAG_PE
;
1810 InsertTailList(&ModuleListHead
,
1811 &CreatedModuleObject
->ListEntry
);
1812 RtlCreateUnicodeString(&CreatedModuleObject
->FullName
,
1814 LdrpBuildModuleBaseName(&CreatedModuleObject
->BaseName
,
1815 &CreatedModuleObject
->FullName
);
1817 CreatedModuleObject
->EntryPoint
= (PVOID
) ((DWORD
)DriverBase
+
1818 PEOptionalHeader
->AddressOfEntryPoint
);
1819 CreatedModuleObject
->Length
= DriverSize
;
1820 DPRINT("EntryPoint at %x\n", CreatedModuleObject
->EntryPoint
);
1822 CreatedModuleObject
->Image
.PE
.FileHeader
=
1823 (PIMAGE_FILE_HEADER
) ((unsigned int) DriverBase
+ PEDosHeader
->e_lfanew
+ sizeof(ULONG
));
1825 DPRINT("FileHeader at %x\n", CreatedModuleObject
->Image
.PE
.FileHeader
);
1826 CreatedModuleObject
->Image
.PE
.OptionalHeader
=
1827 (PIMAGE_OPTIONAL_HEADER
) ((unsigned int) DriverBase
+ PEDosHeader
->e_lfanew
+ sizeof(ULONG
) +
1828 sizeof(IMAGE_FILE_HEADER
));
1829 DPRINT("OptionalHeader at %x\n", CreatedModuleObject
->Image
.PE
.OptionalHeader
);
1830 CreatedModuleObject
->Image
.PE
.SectionList
=
1831 (PIMAGE_SECTION_HEADER
) ((unsigned int) DriverBase
+ PEDosHeader
->e_lfanew
+ sizeof(ULONG
) +
1832 sizeof(IMAGE_FILE_HEADER
) + sizeof(IMAGE_OPTIONAL_HEADER
));
1833 DPRINT("SectionList at %x\n", CreatedModuleObject
->Image
.PE
.SectionList
);
1835 ModuleTextSection
= ExAllocatePool(NonPagedPool
,
1836 sizeof(MODULE_TEXT_SECTION
));
1837 ModuleTextSection
->Base
= (ULONG
)DriverBase
;
1838 ModuleTextSection
->Length
= DriverSize
;
1839 ModuleTextSection
->SymbolsBase
= NULL
;
1840 ModuleTextSection
->SymbolsLength
= 0;
1841 ModuleTextSection
->Name
=
1842 ExAllocatePool(NonPagedPool
,
1843 (wcslen(NameBuffer
) + 1) * sizeof(WCHAR
));
1844 wcscpy(ModuleTextSection
->Name
, NameBuffer
);
1845 InsertTailList(&ModuleTextListHead
, &ModuleTextSection
->ListEntry
);
1847 CreatedModuleObject
->TextSection
= ModuleTextSection
;
1849 *ModuleObject
= CreatedModuleObject
;
1851 return STATUS_SUCCESS
;
1854 PVOID
LdrSafePEProcessModule(
1855 PVOID ModuleLoadBase
,
1857 PVOID ImportModuleBase
,
1860 unsigned int Idx
, Idx2
;
1861 ULONG RelocDelta
, NumRelocs
;
1862 DWORD CurrentSize
, TotalRelocs
;
1864 PIMAGE_DOS_HEADER PEDosHeader
;
1865 PIMAGE_FILE_HEADER PEFileHeader
;
1866 PIMAGE_OPTIONAL_HEADER PEOptionalHeader
;
1867 PIMAGE_SECTION_HEADER PESectionHeaders
;
1868 PRELOCATION_DIRECTORY RelocDir
;
1869 PRELOCATION_ENTRY RelocEntry
;
1870 PVOID
*ImportAddressList
;
1871 PULONG FunctionNameList
;
1874 UNICODE_STRING ModuleName
;
1875 WCHAR NameBuffer
[60];
1877 ps("Processing PE Module at module base:%08lx\n", ModuleLoadBase
);
1879 /* Get header pointers */
1880 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
1881 PEMagic
= (PULONG
) ((unsigned int) ModuleLoadBase
+
1882 PEDosHeader
->e_lfanew
);
1883 PEFileHeader
= (PIMAGE_FILE_HEADER
) ((unsigned int) ModuleLoadBase
+
1884 PEDosHeader
->e_lfanew
+ sizeof(ULONG
));
1885 PEOptionalHeader
= (PIMAGE_OPTIONAL_HEADER
) ((unsigned int) ModuleLoadBase
+
1886 PEDosHeader
->e_lfanew
+ sizeof(ULONG
) + sizeof(IMAGE_FILE_HEADER
));
1887 PESectionHeaders
= (PIMAGE_SECTION_HEADER
) ((unsigned int) ModuleLoadBase
+
1888 PEDosHeader
->e_lfanew
+ sizeof(ULONG
) + sizeof(IMAGE_FILE_HEADER
) +
1889 sizeof(IMAGE_OPTIONAL_HEADER
));
1892 /* Check file magic numbers */
1893 if (PEDosHeader
->e_magic
!= IMAGE_DOS_MAGIC
)
1897 if (PEDosHeader
->e_lfanew
== 0)
1901 if (*PEMagic
!= IMAGE_PE_MAGIC
)
1905 if (PEFileHeader
->Machine
!= IMAGE_FILE_MACHINE_I386
)
1910 ps("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
1911 PEOptionalHeader
->Magic
,
1912 PEOptionalHeader
->MajorLinkerVersion
,
1913 PEOptionalHeader
->MinorLinkerVersion
);
1914 ps("Entry Point:%08lx\n", PEOptionalHeader
->AddressOfEntryPoint
);
1916 /* Determine the size of the module */
1917 *DriverSize
= PEOptionalHeader
->SizeOfImage
;
1918 ps("DriverSize %x\n",*DriverSize
);
1920 /* Copy headers over */
1921 if (DriverBase
!= ModuleLoadBase
)
1923 memcpy(DriverBase
, ModuleLoadBase
, PEOptionalHeader
->SizeOfHeaders
);
1926 ps("Hdr: 0x%X\n", (ULONG
)PEOptionalHeader
);
1927 ps("Hdr->SizeOfHeaders: 0x%X\n", (ULONG
)PEOptionalHeader
->SizeOfHeaders
);
1928 ps("FileHdr->NumberOfSections: 0x%X\n", (ULONG
)PEFileHeader
->NumberOfSections
);
1930 /* Ntoskrnl.exe need no relocation fixups since it is linked to run at the same
1931 address as it is mapped */
1932 if (DriverBase
!= ModuleLoadBase
)
1936 /* Copy image sections into virtual section */
1937 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
1939 // Copy current section into current offset of virtual section
1940 if (PESectionHeaders
[Idx
].Characteristics
&
1941 (IMAGE_SECTION_CHAR_CODE
| IMAGE_SECTION_CHAR_DATA
))
1943 //ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n",
1944 //PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].VirtualAddress + DriverBase);
1945 memcpy(PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
,
1946 (PVOID
)(ModuleLoadBase
+ PESectionHeaders
[Idx
].PointerToRawData
),
1947 PESectionHeaders
[Idx
].Misc
.VirtualSize
> PESectionHeaders
[Idx
].SizeOfRawData
?
1948 PESectionHeaders
[Idx
].SizeOfRawData
: PESectionHeaders
[Idx
].Misc
.VirtualSize
);
1952 ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n",
1953 PESectionHeaders
[Idx
].VirtualAddress
, PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
);
1954 memset(PESectionHeaders
[Idx
].VirtualAddress
+ DriverBase
,
1955 '\0', PESectionHeaders
[Idx
].Misc
.VirtualSize
);
1958 CurrentSize
+= ROUND_UP(PESectionHeaders
[Idx
].Misc
.VirtualSize
,
1959 PEOptionalHeader
->SectionAlignment
);
1962 /* Perform relocation fixups */
1963 RelocDelta
= (DWORD
) DriverBase
- PEOptionalHeader
->ImageBase
;
1964 RelocDir
= (PRELOCATION_DIRECTORY
)(PEOptionalHeader
->DataDirectory
[
1965 IMAGE_DIRECTORY_ENTRY_BASERELOC
].VirtualAddress
);
1966 ps("DrvrBase:%08lx ImgBase:%08lx RelocDelta:%08lx\n",
1968 PEOptionalHeader
->ImageBase
,
1970 ps("RelocDir %x\n",RelocDir
);
1972 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
1974 if (PESectionHeaders
[Idx
].VirtualAddress
== (DWORD
)RelocDir
)
1976 DPRINT("Name %.8s PESectionHeader[Idx].PointerToRawData %x\n",
1977 PESectionHeaders
[Idx
].Name
,
1978 PESectionHeaders
[Idx
].PointerToRawData
);
1979 RelocDir
= PESectionHeaders
[Idx
].PointerToRawData
+ ModuleLoadBase
;
1980 CurrentSize
= PESectionHeaders
[Idx
].Misc
.VirtualSize
;
1985 ps("RelocDir %08lx CurrentSize %08lx\n", RelocDir
, CurrentSize
);
1988 while (TotalRelocs
< CurrentSize
&& RelocDir
->SizeOfBlock
!= 0)
1990 NumRelocs
= (RelocDir
->SizeOfBlock
- sizeof(RELOCATION_DIRECTORY
)) /
1992 RelocEntry
= (PRELOCATION_ENTRY
) ((DWORD
)RelocDir
+
1993 sizeof(RELOCATION_DIRECTORY
));
1994 for (Idx
= 0; Idx
< NumRelocs
; Idx
++)
2000 Offset
= RelocEntry
[Idx
].TypeOffset
& 0xfff;
2001 Type
= (RelocEntry
[Idx
].TypeOffset
>> 12) & 0xf;
2002 RelocItem
= (PDWORD
)(DriverBase
+ RelocDir
->VirtualAddress
+
2006 (*RelocItem
) += RelocDelta
;
2010 DbgPrint("Unknown relocation type %x at %x\n",Type
, &Type
);
2014 TotalRelocs
+= RelocDir
->SizeOfBlock
;
2015 RelocDir
= (PRELOCATION_DIRECTORY
)((DWORD
)RelocDir
+
2016 RelocDir
->SizeOfBlock
);
2019 ps("PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] %x\n",
2020 PEOptionalHeader
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
]
2024 /* Perform import fixups */
2025 if (PEOptionalHeader
->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress
)
2027 PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory
;
2029 /* Process each import module */
2030 ImportModuleDirectory
= (PIMAGE_IMPORT_MODULE_DIRECTORY
)
2031 ((DWORD
)DriverBase
+ PEOptionalHeader
->
2032 DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress
);
2034 ps("Processeing import directory at %p\n", ImportModuleDirectory
);
2037 /* Check to make sure that import lib is kernel */
2038 pName
= (PCHAR
) DriverBase
+
2039 ImportModuleDirectory
->dwRVAModuleName
;
2040 wcscpy(NameBuffer
, MODULE_ROOT_NAME
);
2041 for (Idx
= 0; NameBuffer
[Idx
] != 0; Idx
++);
2042 for (Idx2
= 0; pName
[Idx2
] != '\0'; Idx2
++)
2044 NameBuffer
[Idx
+ Idx2
] = (WCHAR
) pName
[Idx2
];
2046 NameBuffer
[Idx
+ Idx2
] = 0;
2047 RtlInitUnicodeString (&ModuleName
, NameBuffer
);
2050 ps("Import module: %wZ\n", &ModuleName
);
2052 /* Get the import address list */
2053 ImportAddressList
= (PVOID
*) ((DWORD
)DriverBase
+
2054 ImportModuleDirectory
->dwRVAFunctionAddressList
);
2056 ps(" ImportModuleDirectory->dwRVAFunctionAddressList: 0x%X\n",
2057 ImportModuleDirectory
->dwRVAFunctionAddressList
);
2058 ps(" ImportAddressList: 0x%X\n", ImportAddressList
);
2060 /* Get the list of functions to import */
2061 if (ImportModuleDirectory
->dwRVAFunctionNameList
!= 0)
2064 ps("Using function name list.\n");
2066 FunctionNameList
= (PULONG
) ((DWORD
)DriverBase
+
2067 ImportModuleDirectory
->dwRVAFunctionNameList
);
2072 ps("Using function address list.\n");
2074 FunctionNameList
= (PULONG
) ((DWORD
)DriverBase
+
2075 ImportModuleDirectory
->dwRVAFunctionAddressList
);
2078 /* Walk through function list and fixup addresses */
2079 while (*FunctionNameList
!= 0L)
2081 if ((*FunctionNameList
) & 0x80000000) // hint
2085 Hint
= (*FunctionNameList
) & 0xffff;
2089 pName
= (PCHAR
)((DWORD
)DriverBase
+
2090 *FunctionNameList
+ 2);
2091 Hint
= *(PWORD
)((DWORD
)DriverBase
+ *FunctionNameList
);
2093 //ps(" Hint:%04x Name:%s(0x%X)(%x)\n", Hint, pName, pName, ImportAddressList);
2095 *ImportAddressList
= LdrSafePEGetExportAddress(
2100 ImportAddressList
++;
2103 ImportModuleDirectory
++;
2107 ps("Finished importing.\n");
2113 LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject
,
2115 unsigned short Hint
)
2118 PVOID ExportAddress
;
2120 PDWORD FunctionList
, NameList
;
2121 PIMAGE_EXPORT_DIRECTORY ExportDir
;
2122 ULONG ExportDirSize
;
2124 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)
2125 RtlImageDirectoryEntryToData(ModuleObject
->Base
,
2127 IMAGE_DIRECTORY_ENTRY_EXPORT
,
2129 DPRINT("ExportDir %p ExportDirSize %lx\n", ExportDir
, ExportDirSize
);
2130 if (ExportDir
== NULL
)
2135 FunctionList
= (PDWORD
)((DWORD
)ExportDir
->AddressOfFunctions
+ ModuleObject
->Base
);
2136 NameList
= (PDWORD
)((DWORD
)ExportDir
->AddressOfNames
+ ModuleObject
->Base
);
2137 OrdinalList
= (PWORD
)((DWORD
)ExportDir
->AddressOfNameOrdinals
+ ModuleObject
->Base
);
2143 for (Idx
= 0; Idx
< ExportDir
->NumberOfNames
; Idx
++)
2146 DPRINT(" Name:%s NameList[%d]:%s\n",
2149 (DWORD
) ModuleObject
->Base
+ NameList
[Idx
]);
2152 if (!strcmp(Name
, (PCHAR
) ((DWORD
)ModuleObject
->Base
+ NameList
[Idx
])))
2154 ExportAddress
= (PVOID
) ((DWORD
)ModuleObject
->Base
+
2155 FunctionList
[OrdinalList
[Idx
]]);
2156 if (((ULONG
)ExportAddress
>= (ULONG
)ExportDir
) &&
2157 ((ULONG
)ExportAddress
< (ULONG
)ExportDir
+ ExportDirSize
))
2159 DPRINT("Forward: %s\n", (PCHAR
)ExportAddress
);
2160 ExportAddress
= LdrPEFixupForward((PCHAR
)ExportAddress
);
2161 DPRINT("ExportAddress: %p\n", ExportAddress
);
2170 ExportAddress
= (PVOID
) ((DWORD
)ModuleObject
->Base
+
2171 FunctionList
[Hint
- ExportDir
->Base
]);
2174 if (ExportAddress
== 0)
2176 CPRINT("Export not found for %d:%s\n",
2178 Name
!= NULL
? Name
: "(Ordinal)");
2182 return ExportAddress
;
2186 LdrSafePEGetExportAddress(
2187 PVOID ImportModuleBase
,
2189 unsigned short Hint
)
2192 PVOID ExportAddress
;
2194 PDWORD FunctionList
, NameList
;
2195 PIMAGE_EXPORT_DIRECTORY ExportDir
;
2196 ULONG ExportDirSize
;
2198 static BOOLEAN EP
= FALSE
;
2200 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)
2201 RtlImageDirectoryEntryToData(ImportModuleBase
,
2203 IMAGE_DIRECTORY_ENTRY_EXPORT
,
2208 ps("ExportDir %x\n", ExportDir
);
2211 FunctionList
= (PDWORD
)((DWORD
)ExportDir
->AddressOfFunctions
+ ImportModuleBase
);
2212 NameList
= (PDWORD
)((DWORD
)ExportDir
->AddressOfNames
+ ImportModuleBase
);
2213 OrdinalList
= (PWORD
)((DWORD
)ExportDir
->AddressOfNameOrdinals
+ ImportModuleBase
);
2219 for (Idx
= 0; Idx
< ExportDir
->NumberOfNames
; Idx
++)
2221 if (!strcmp(Name
, (PCHAR
) ((DWORD
)ImportModuleBase
+ NameList
[Idx
])))
2223 ExportAddress
= (PVOID
) ((DWORD
)ImportModuleBase
+
2224 FunctionList
[OrdinalList
[Idx
]]);
2231 ExportAddress
= (PVOID
) ((DWORD
)ImportModuleBase
+
2232 FunctionList
[Hint
- ExportDir
->Base
]);
2235 if (ExportAddress
== 0)
2237 ps("Export not found for %d:%s\n",
2239 Name
!= NULL
? Name
: "(Ordinal)");
2242 return ExportAddress
;
2246 static PMODULE_OBJECT
2247 LdrPEGetModuleObject(PUNICODE_STRING ModuleName
)
2250 PMODULE_OBJECT Module
;
2252 DPRINT("LdrPEGetModuleObject (ModuleName %wZ)\n",
2255 Entry
= ModuleListHead
.Flink
;
2257 while (Entry
!= &ModuleListHead
)
2259 Module
= CONTAINING_RECORD(Entry
, MODULE_OBJECT
, ListEntry
);
2261 DPRINT("Comparing %wZ and %wZ\n",
2265 if (!RtlCompareUnicodeString(&Module
->BaseName
, ModuleName
, TRUE
))
2267 DPRINT("Module %x\n", Module
);
2271 Entry
= Entry
->Flink
;
2274 CPRINT("LdrPEGetModuleObject: Failed to find dll %wZ\n", ModuleName
);
2281 LdrPEFixupForward(PCHAR ForwardName
)
2283 CHAR NameBuffer
[128];
2284 UNICODE_STRING ModuleName
;
2286 PMODULE_OBJECT ModuleObject
;
2288 DPRINT("LdrPEFixupForward (%s)\n", ForwardName
);
2290 strcpy(NameBuffer
, ForwardName
);
2291 p
= strchr(NameBuffer
, '.');
2299 DPRINT("Driver: %s Function: %s\n", NameBuffer
, p
+1);
2301 RtlCreateUnicodeStringFromAsciiz(&ModuleName
,
2303 ModuleObject
= LdrPEGetModuleObject(&ModuleName
);
2304 RtlFreeUnicodeString(&ModuleName
);
2306 DPRINT("ModuleObject: %p\n", ModuleObject
);
2308 if (ModuleObject
== NULL
)
2310 CPRINT("LdrPEFixupForward: failed to find module %s\n", NameBuffer
);
2314 return LdrPEGetExportAddress(ModuleObject
, p
+1, 0);