ReactOS 0.4.16-dev-336-gb667d82
peloader.c
Go to the documentation of this file.
1/*
2 * PROJECT: FreeLoader
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Provides routines for loading PE files.
5 * (Deprecated remark) To be merged with arch/i386/loader.c in future.
6 *
7 * COPYRIGHT: Copyright 1998-2003 Brian Palmer <brianp@sginet.com>
8 * Copyright 2006-2019 Aleksey Bragin <aleksey@reactos.org>
9 *
10 * NOTES: The source code in this file is based on the work of respective
11 * authors of PE loading code in ReactOS and Brian Palmer and
12 * Alex Ionescu's arch/i386/loader.c, and my research project
13 * (creating a native EFI loader for Windows).
14 *
15 * This article was very handy during development:
16 * http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/
17 */
18
19/* INCLUDES ******************************************************************/
20
21#include <freeldr.h>
22
23#include <debug.h>
25
26/* GLOBALS *******************************************************************/
27
29
31
32#ifdef _WIN64
33#define COOKIE_MAX 0x0000FFFFFFFFFFFFll
34#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
35#else
36#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
37#endif
38
39
40/* PRIVATE FUNCTIONS *********************************************************/
41
42static PVOID
44{
46 ULONG DirSize;
48
49 /* Get the pointer to the config directory */
51 TRUE,
53 &DirSize);
54
55 /* Check for sanity */
56 if (!ConfigDir ||
58 {
59 /* Invalid directory*/
60 return NULL;
61 }
62
63 /* Now get the cookie */
65
66 /* Check this cookie */
67 if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
68 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage - sizeof(*Cookie))
69 {
70 Cookie = NULL;
71 }
72
73 /* Return validated security cookie */
74 return Cookie;
75}
76
77/* DllName - physical, UnicodeString->Buffer - virtual */
78static BOOLEAN
80 IN PCH DllName,
82{
85
86 /* First obvious check: for length of two names */
87 Length = strlen(DllName);
88
89#if DBG
90 {
91 UNICODE_STRING UnicodeNamePA;
92 UnicodeNamePA.Length = UnicodeName->Length;
93 UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
94 UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
95 TRACE("PeLdrpCompareDllName: %s and %wZ, Length = %d "
96 "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length);
97 }
98#endif
99
100 if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
101 return FALSE;
102
103 /* Store pointer to unicode string's buffer */
104 Buffer = VaToPa(UnicodeName->Buffer);
105
106 /* Loop character by character */
107 for (i = 0; i < Length; i++)
108 {
109 /* Compare two characters, uppercasing them */
110 if (toupper(*DllName) != toupper((CHAR)*Buffer))
111 return FALSE;
112
113 /* Move to the next character */
114 DllName++;
115 Buffer++;
116 }
117
118 /* Check, if strings either fully match, or match till the "." (w/o extension) */
119 if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
120 {
121 /* Yes they do */
122 return TRUE;
123 }
124
125 /* Strings don't match, return FALSE */
126 return FALSE;
127}
128
129static BOOLEAN
132 IN PCCH DirectoryPath,
133 IN PCH ImportName,
135 OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry);
136
137static BOOLEAN
140 _In_ PVOID DllBase,
141 _In_ PVOID ImageBase,
142 _In_ PIMAGE_THUNK_DATA ThunkName,
143 _Inout_ PIMAGE_THUNK_DATA ThunkData,
144 _In_ PIMAGE_EXPORT_DIRECTORY ExportDirectory,
145 _In_ ULONG ExportSize,
146 _In_ BOOLEAN ProcessForwards,
147 _In_ PCSTR DirectoryPath,
149{
150 ULONG Ordinal;
151 PULONG NameTable, FunctionTable;
152 PUSHORT OrdinalTable;
153 LONG High, Low, Middle, Result;
154 ULONG Hint;
155 PIMAGE_IMPORT_BY_NAME ImportData;
156 PCHAR ExportName, ForwarderName;
158
159 //TRACE("PeLdrpBindImportName(): "
160 // "DllBase 0x%p, ImageBase 0x%p, ThunkName 0x%p, ThunkData 0x%p, ExportDirectory 0x%p, ExportSize %d, ProcessForwards 0x%X\n",
161 // DllBase, ImageBase, ThunkName, ThunkData, ExportDirectory, ExportSize, ProcessForwards);
162
163 /* Check passed DllBase */
164 if (!DllBase)
165 {
166 WARN("DllBase == NULL\n");
167 return FALSE;
168 }
169
170 /* Convert all non-critical pointers to PA from VA */
171 ThunkName = VaToPa(ThunkName);
172 ThunkData = VaToPa(ThunkData);
173
174 /* Is the reference by ordinal? */
175 if (IMAGE_SNAP_BY_ORDINAL(ThunkName->u1.Ordinal) && !ProcessForwards)
176 {
177 /* Yes, calculate the ordinal */
178 Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkName->u1.Ordinal) - (UINT32)ExportDirectory->Base);
179 //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
180 }
181 else
182 {
183 /* It's reference by name, we have to look it up in the export directory */
184 if (!ProcessForwards)
185 {
186 /* AddressOfData in thunk entry will become a virtual address (from relative) */
187 //TRACE("PeLdrpBindImportName(): ThunkName->u1.AOD was %p\n", ThunkName->u1.AddressOfData);
188 ThunkName->u1.AddressOfData =
189 (ULONG_PTR)RVA(ImageBase, ThunkName->u1.AddressOfData);
190 //TRACE("PeLdrpBindImportName(): ThunkName->u1.AOD became %p\n", ThunkName->u1.AddressOfData);
191 }
192
193 /* Get the import name, convert it to a physical pointer */
194 ImportData = VaToPa((PVOID)ThunkName->u1.AddressOfData);
195
196 /* Get pointers to Name and Ordinal tables (RVA -> VA) */
197 NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
198 OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
199
200 //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
201 // NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals);
202
203 /* Get the hint */
204 Hint = ImportData->Hint;
205 //TRACE("HintIndex %d\n", Hint);
206
207 /* Get the export name from the hint */
208 ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));
209
210 /* If Hint is less than total number of entries in the export directory,
211 and import name == export name, then we can just get it from the OrdinalTable */
212 if ((Hint < ExportDirectory->NumberOfNames) &&
213 (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
214 {
215 Ordinal = OrdinalTable[Hint];
216 //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
217 }
218 else
219 {
220 /* It's not the easy way, we have to lookup import name in the name table.
221 Let's use a binary search for this task. */
222
223 //TRACE("PeLdrpBindImportName() looking up the import name using binary search...\n");
224
225 /* Low boundary is set to 0, and high boundary to the maximum index */
226 Low = 0;
227 High = ExportDirectory->NumberOfNames - 1;
228
229 /* Perform a binary-search loop */
230 while (High >= Low)
231 {
232 /* Divide by 2 by shifting to the right once */
233 Middle = (Low + High) / 2;
234
235 /* Get the name from the name table */
236 ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));
237
238 /* Compare the names */
239 Result = strcmp(ExportName, (PCHAR)ImportData->Name);
240
241 // TRACE("Binary search: comparing Import '%s', Export '%s'\n",
242 // (PCHAR)ImportData->Name, ExportName);
243
244 /* Depending on result of strcmp, perform different actions */
245 if (Result > 0)
246 {
247 /* Adjust top boundary */
248 High = Middle - 1;
249 }
250 else if (Result < 0)
251 {
252 /* Adjust bottom boundary */
253 Low = Middle + 1;
254 }
255 else
256 {
257 /* Yay, found it! */
258 break;
259 }
260 }
261
262 /* If high boundary is less than low boundary, then no result found */
263 if (High < Low)
264 {
265 ERR("Did not find export '%s'!\n", (PCHAR)ImportData->Name);
266 return FALSE;
267 }
268
269 /* Everything alright, get the ordinal */
270 Ordinal = OrdinalTable[Middle];
271 //TRACE("PeLdrpBindImportName() found Ordinal %d\n", Ordinal);
272 }
273 }
274
275 /* Check ordinal number for validity! */
276 if (Ordinal >= ExportDirectory->NumberOfFunctions)
277 {
278 ERR("Ordinal number is invalid!\n");
279 return FALSE;
280 }
281
282 /* Get a pointer to the function table */
283 FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));
284
285 /* Save a pointer to the function */
286 ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);
287
288 /* Is it a forwarder? (function pointer is within the export directory) */
289 ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
290 if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
291 ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
292 {
293 PLDR_DATA_TABLE_ENTRY DataTableEntry;
294 PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
295 ULONG RefExportSize;
296 CHAR ForwardDllName[256];
297
298 TRACE("PeLdrpBindImportName(): ForwarderName %s\n", ForwarderName);
299
300 /* Save the name of the forward dll */
301 RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));
302
303 /* Strip out the symbol name */
304 *strrchr(ForwardDllName, '.') = ANSI_NULL;
305
306 /* Check if the target image is already loaded */
307 if (!PeLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry))
308 {
309 /* Check if the forward dll name has an extension */
310 if (strchr(ForwardDllName, '.') == NULL)
311 {
312 /* Name does not have an extension, append '.dll' */
313 RtlStringCbCatA(ForwardDllName, sizeof(ForwardDllName), ".dll");
314 }
315
316 /* Now let's try to load it! */
318 DirectoryPath,
319 ForwardDllName,
320 Parent,
321 &DataTableEntry);
322 if (!Success)
323 {
324 ERR("PeLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n");
325 return Success;
326 }
327 }
328
329 /* Get pointer to the export directory of loaded DLL */
330 RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
332 TRUE,
334 &RefExportSize);
335
336 /* Fail if it's NULL */
337 if (RefExportDirectory)
338 {
339 UCHAR Buffer[128];
340 IMAGE_THUNK_DATA RefThunkData;
341 PIMAGE_IMPORT_BY_NAME ImportByName;
342 PCHAR ImportName;
343
344 /* Get pointer to the import name */
345 ImportName = strrchr(ForwarderName, '.') + 1;
346
347 /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
348 ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
349
350 /* Fill the name with the import name */
351 RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
352
353 /* Set Hint to 0 */
354 ImportByName->Hint = 0;
355
356 /* And finally point ThunkData's AddressOfData to that structure */
357 RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;
358
359 /* And recursively call ourselves */
361 DataTableEntry->DllBase,
362 ImageBase,
363 &RefThunkData,
364 &RefThunkData,
365 RefExportDirectory,
366 RefExportSize,
367 TRUE,
368 DirectoryPath,
369 Parent);
370
371 /* Fill out the ThunkData with data from RefThunkData */
372 ThunkData->u1 = RefThunkData.u1;
373
374 /* Return what we got from the recursive call */
375 return Success;
376 }
377 else
378 {
379 /* Fail if ExportDirectory is NULL */
380 return FALSE;
381 }
382 }
383
384 /* Success! */
385 return TRUE;
386}
387
388static BOOLEAN
391 IN PCCH DirectoryPath,
392 IN PCH ImportName,
394 OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
395{
396 CHAR FullDllName[256];
398 PVOID BasePA = NULL;
399
400 /* Prepare the full path to the file to be loaded */
401 RtlStringCbCopyA(FullDllName, sizeof(FullDllName), DirectoryPath);
402 RtlStringCbCatA(FullDllName, sizeof(FullDllName), ImportName);
403
404 TRACE("Loading referenced DLL: %s\n", FullDllName);
405
408
409 /* Load the image */
411 if (!Success)
412 {
413 ERR("PeLdrLoadImage('%s') failed\n", FullDllName);
414 return Success;
415 }
416
417 /* Allocate DTE for newly loaded DLL */
419 ImportName,
421 PaToVa(BasePA),
422 DataTableEntry);
423 if (!Success)
424 {
425 /* Cleanup and bail out */
426 ERR("PeLdrAllocateDataTableEntry('%s') failed\n", FullDllName);
427 MmFreeMemory(BasePA);
428 return Success;
429 }
430
431 /* Init security cookie */
432 PeLdrInitSecurityCookie(*DataTableEntry);
433
434 (*DataTableEntry)->Flags |= LDRP_DRIVER_DEPENDENT_DLL;
435
436 /* Scan its dependencies too */
437 TRACE("PeLdrScanImportDescriptorTable() calling ourselves for '%.*S'\n",
438 (*DataTableEntry)->BaseDllName.Length / sizeof(WCHAR),
439 VaToPa((*DataTableEntry)->BaseDllName.Buffer));
440 Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
441 if (!Success)
442 {
443 /* Cleanup and bail out */
444 ERR("PeLdrScanImportDescriptorTable() failed\n");
445 PeLdrFreeDataTableEntry(*DataTableEntry);
446 MmFreeMemory(BasePA);
447 return Success;
448 }
449
450 return TRUE;
451}
452
453static BOOLEAN
456 _In_ PVOID DllBase,
457 _In_ PVOID ImageBase,
458 _In_ PIMAGE_THUNK_DATA ThunkName,
459 _Inout_ PIMAGE_THUNK_DATA ThunkData,
460 _In_ PCSTR DirectoryPath,
462{
463 PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
465 ULONG ExportSize;
466
467 TRACE("PeLdrpScanImportAddressTable(): "
468 "DllBase 0x%p, ImageBase 0x%p, ThunkName 0x%p, ThunkData 0x%p\n",
469 DllBase, ImageBase, ThunkName, ThunkData);
470
471 /* Obtain the export table from the DLL's base */
472 if (!DllBase)
473 {
474 ERR("DllBase == NULL\n");
475 return FALSE;
476 }
477 else
478 {
479 ExportDirectory =
481 TRUE,
483 &ExportSize);
484 }
485 TRACE("PeLdrpScanImportAddressTable(): ExportDirectory 0x%p\n", ExportDirectory);
486
487 /* Fail if no export directory */
488 if (!ExportDirectory)
489 {
490 ERR("No ExportDir, DllBase = %p (%p)\n", DllBase, VaToPa(DllBase));
491 return FALSE;
492 }
493
494 /* Go through each thunk in the table and bind it */
495 while (((PIMAGE_THUNK_DATA)VaToPa(ThunkName))->u1.AddressOfData != 0)
496 {
497 /* Bind it */
499 DllBase,
500 ImageBase,
501 ThunkName,
502 ThunkData,
503 ExportDirectory,
504 ExportSize,
505 FALSE,
506 DirectoryPath,
507 Parent);
508 /* Fail if binding was unsuccessful */
509 if (!Success)
510 return Success;
511
512 /* Move to the next thunk */
513 ThunkName++;
514 ThunkData++;
515 }
516
517 /* Return success */
518 return TRUE;
519}
520
521
522/* FUNCTIONS *****************************************************************/
523
526{
527 PLDR_DATA_TABLE_ENTRY FreeldrDTE;
528
530
531 /* Allocate a data table entry for freeldr.sys.
532 The base name is scsiport.sys for imports from ntbootdd.sys */
534 "scsiport.sys",
535 "freeldr.sys",
537 &FreeldrDTE))
538 {
539 /* Cleanup and bail out */
540 ERR("Failed to allocate DTE for freeldr\n");
541 return FALSE;
542 }
543
544 return TRUE;
545}
546
547PVOID
549{
551 ULONG_PTR NewCookie;
552
553 /* Fetch address of the cookie */
555
556 if (!Cookie)
557 return NULL;
558
559 /* Check if it's a default one */
561 (*Cookie == 0))
562 {
563 /* Generate new cookie using cookie address and time as seed */
565#ifdef _WIN64
566 /* Some images expect first 16 bits to be kept clean (like in default cookie) */
567 if (NewCookie > COOKIE_MAX)
568 {
569 NewCookie >>= 16;
570 }
571#endif
572 /* If the result is 0 or the same as we got, just add one to the default value */
573 if ((NewCookie == 0) || (NewCookie == *Cookie))
574 {
575 NewCookie = DEFAULT_SECURITY_COOKIE + 1;
576 }
577
578 /* Set the new cookie value */
579 *Cookie = NewCookie;
580 }
581
582 return Cookie;
583}
584
585/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
589 IN PCH DllName,
590 OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
591{
592 PLDR_DATA_TABLE_ENTRY DataTableEntry;
593 LIST_ENTRY *ModuleEntry;
594
595 TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName);
596
597 /* Just go through each entry in the LoadOrderList and compare loaded module's
598 name with a given name */
599 ModuleEntry = ModuleListHead->Flink;
600 while (ModuleEntry != ModuleListHead)
601 {
602 /* Get pointer to the current DTE */
603 DataTableEntry = CONTAINING_RECORD(ModuleEntry,
605 InLoadOrderLinks);
606
607 TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, Base %p, Name '%.*S'\n",
608 DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
609 DataTableEntry->BaseDllName.Length / sizeof(WCHAR),
610 VaToPa(DataTableEntry->BaseDllName.Buffer));
611
612 /* Compare names */
613 if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
614 {
615 /* Yes, found it, report pointer to the loaded module's DTE
616 to the caller and increase load count for it */
617 *LoadedEntry = DataTableEntry;
618 DataTableEntry->LoadCount++;
619 TRACE("PeLdrCheckForLoadedDll: LoadedEntry 0x%p\n", DataTableEntry);
620 return TRUE;
621 }
622
623 /* Go to the next entry */
624 ModuleEntry = ModuleEntry->Flink;
625 }
626
627 /* Nothing found */
628 return FALSE;
629}
630
634 IN PCCH DirectoryPath,
636{
637 PLDR_DATA_TABLE_ENTRY DataTableEntry;
638 PIMAGE_IMPORT_DESCRIPTOR ImportTable;
639 ULONG ImportTableSize;
640 PCH ImportName;
642
643 /* Get a pointer to the import table of this image */
644 ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
645 TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
646
647#if DBG
648 {
649 UNICODE_STRING BaseName;
650 BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
651 BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
652 BaseName.Length = ScanDTE->BaseDllName.Length;
653 TRACE("PeLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%p\n",
654 &BaseName, ImportTable);
655 }
656#endif
657
658 /* If the image doesn't have any import directory, just return success */
659 if (!ImportTable)
660 return TRUE;
661
662 /* Loop through all the entries */
663 for (;(ImportTable->Name != 0) && (ImportTable->OriginalFirstThunk != 0);ImportTable++)
664 {
665 PIMAGE_THUNK_DATA ThunkName = RVA(ScanDTE->DllBase, ImportTable->OriginalFirstThunk);
666 PIMAGE_THUNK_DATA ThunkData = RVA(ScanDTE->DllBase, ImportTable->FirstThunk);
667
668 /* Get pointer to the name */
669 ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
670 TRACE("PeLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);
671
672 /* In case we get a reference to ourselves - just skip it */
673 if (PeLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
674 continue;
675
676 /* Load the DLL if it is not already loaded */
677 if (!PeLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
678 {
680 DirectoryPath,
681 ImportName,
682 &ScanDTE->InLoadOrderLinks,
683 &DataTableEntry);
684 if (!Success)
685 {
686 ERR("PeLdrpLoadAndScanReferencedDll() failed\n");
687 return Success;
688 }
689 }
690
691 /* Scan its import address table */
693 DataTableEntry->DllBase,
694 ScanDTE->DllBase,
695 ThunkName,
696 ThunkData,
697 DirectoryPath,
698 &ScanDTE->InLoadOrderLinks);
699
700 if (!Success)
701 {
702 ERR("PeLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
703 ImportName, DirectoryPath);
704 return Success;
705 }
706 }
707
708 return TRUE;
709}
710
714 IN PCCH BaseDllName,
716 IN PVOID BaseVA,
717 OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
718{
719 PVOID BasePA = VaToPa(BaseVA);
720 PWSTR BaseDllNameBuffer, Buffer;
721 PLDR_DATA_TABLE_ENTRY DataTableEntry;
722 PIMAGE_NT_HEADERS NtHeaders;
724
725 TRACE("PeLdrAllocateDataTableEntry('%s', '%s', %p)\n",
726 BaseDllName, FullDllName, BasePA);
727
728 /* Allocate memory for a data table entry, zero-initialize it */
731 if (DataTableEntry == NULL)
732 return FALSE;
733
734 /* Get NT headers from the image */
735 NtHeaders = RtlImageNtHeader(BasePA);
736
737 /* Initialize corresponding fields of DTE based on NT headers value */
738 RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
739 DataTableEntry->DllBase = BaseVA;
740 DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
741 DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
742 DataTableEntry->SectionPointer = 0;
743 DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
744
745 /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
746 by simple conversion - copying each character */
747 Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
749 if (Buffer == NULL)
750 {
751 FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
752 return FALSE;
753 }
754
755 /* Save Buffer, in case of later failure */
756 BaseDllNameBuffer = Buffer;
757
758 DataTableEntry->BaseDllName.Length = Length;
759 DataTableEntry->BaseDllName.MaximumLength = Length;
760 DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
761
763 Length /= sizeof(WCHAR);
764 while (Length--)
765 {
766 *Buffer++ = *BaseDllName++;
767 }
768
769 /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
770 using the same method */
771 Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
773 if (Buffer == NULL)
774 {
775 FrLdrHeapFree(BaseDllNameBuffer, TAG_WLDR_NAME);
776 FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
777 return FALSE;
778 }
779
780 DataTableEntry->FullDllName.Length = Length;
781 DataTableEntry->FullDllName.MaximumLength = Length;
782 DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
783
785 Length /= sizeof(WCHAR);
786 while (Length--)
787 {
788 *Buffer++ = *FullDllName++;
789 }
790
791 /* Initialize what's left - LoadCount which is 1, and set Flags so that
792 we know this entry is processed */
793 DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
794 DataTableEntry->LoadCount = 1;
795
796 /* Honour the FORCE_INTEGRITY flag */
798 {
799 /*
800 * On Vista and above, the LDRP_IMAGE_INTEGRITY_FORCED flag must be set
801 * if IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY is set in the image header.
802 * This is done after the image has been loaded and the digital signature
803 * check has passed successfully. (We do not do it yet!)
804 *
805 * Several OS functionality depend on the presence of this flag.
806 * For example, when using Object-Manager callbacks the latter will call
807 * MmVerifyCallbackFunction() to verify whether the flag is present.
808 * If not callbacks will not work.
809 * (See Windows Internals Part 1, 6th edition, p. 176.)
810 */
811 DataTableEntry->Flags |= LDRP_IMAGE_INTEGRITY_FORCED;
812 }
813
814 /* Insert this DTE to a list in the LPB */
816 TRACE("Inserting DTE %p, name='%.*S' DllBase=%p\n", DataTableEntry,
817 DataTableEntry->BaseDllName.Length / sizeof(WCHAR),
818 VaToPa(DataTableEntry->BaseDllName.Buffer),
819 DataTableEntry->DllBase);
820
821 /* Save pointer to a newly allocated and initialized entry */
822 *NewEntry = DataTableEntry;
823
824 /* Return success */
825 return TRUE;
826}
827
828VOID
830 // _In_ PLIST_ENTRY ModuleListHead,
832{
833 // ASSERT(ModuleListHead);
834 ASSERT(Entry);
835
836 RemoveEntryList(&Entry->InLoadOrderLinks);
837 FrLdrHeapFree(VaToPa(Entry->FullDllName.Buffer), TAG_WLDR_NAME);
838 FrLdrHeapFree(VaToPa(Entry->BaseDllName.Buffer), TAG_WLDR_NAME);
840}
841
856 _In_ TYPE_OF_MEMORY MemoryType,
857 _Out_ PVOID* ImageBasePA,
858 _In_ BOOLEAN KernelMapping)
859{
860 ULONG FileId;
861 PVOID PhysicalBase;
862 PVOID VirtualBase = NULL;
863 UCHAR HeadersBuffer[SECTOR_SIZE * 2];
864 PIMAGE_NT_HEADERS NtHeaders;
865 PIMAGE_SECTION_HEADER SectionHeader;
866 ULONG VirtualSize, SizeOfRawData, NumberOfSections;
870
871 TRACE("PeLdrLoadImage('%s', %ld)\n", FilePath, MemoryType);
872
873 /* Open the image file */
875 if (Status != ESUCCESS)
876 {
877 WARN("ArcOpen('%s') failed. Status: %u\n", FilePath, Status);
878 return FALSE;
879 }
880
881 /* Load the first 2 sectors of the image so we can read the PE header */
882 Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
883 if (Status != ESUCCESS)
884 {
885 ERR("ArcRead('%s') failed. Status: %u\n", FilePath, Status);
886 ArcClose(FileId);
887 return FALSE;
888 }
889
890 /* Now read the MZ header to get the offset to the PE Header */
891 NtHeaders = RtlImageNtHeader(HeadersBuffer);
892 if (!NtHeaders)
893 {
894 ERR("No NT header found in \"%s\"\n", FilePath);
895 ArcClose(FileId);
896 return FALSE;
897 }
898
899 /* Ensure this is executable image */
901 {
902 ERR("Not an executable image \"%s\"\n", FilePath);
903 ArcClose(FileId);
904 return FALSE;
905 }
906
907 /* Store number of sections to read and a pointer to the first section */
908 NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
909 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
910
911 /* Try to allocate this memory; if it fails, allocate somewhere else */
912 PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
913 (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
914 MemoryType);
915
916 if (PhysicalBase == NULL)
917 {
918 /* Don't fail, allocate again at any other "low" place */
919 PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
920
921 if (PhysicalBase == NULL)
922 {
923 ERR("Failed to alloc %lu bytes for image %s\n", NtHeaders->OptionalHeader.SizeOfImage, FilePath);
924 ArcClose(FileId);
925 return FALSE;
926 }
927 }
928
929 /* This is the real image base, in form of a virtual address */
930 VirtualBase = KernelMapping ? PaToVa(PhysicalBase) : PhysicalBase;
931
932 TRACE("Base PA: 0x%p, VA: 0x%p\n", PhysicalBase, VirtualBase);
933
934 /* Copy headers from already read data */
935 RtlCopyMemory(PhysicalBase, HeadersBuffer, min(NtHeaders->OptionalHeader.SizeOfHeaders, sizeof(HeadersBuffer)));
936 /* If headers are quite big, request next bytes from file */
937 if (NtHeaders->OptionalHeader.SizeOfHeaders > sizeof(HeadersBuffer))
938 {
939 Status = ArcRead(FileId, (PUCHAR)PhysicalBase + sizeof(HeadersBuffer), NtHeaders->OptionalHeader.SizeOfHeaders - sizeof(HeadersBuffer), &BytesRead);
940 if (Status != ESUCCESS)
941 {
942 ERR("ArcRead('%s') failed. Status: %u\n", FilePath, Status);
943 // UiMessageBox("Error reading headers.");
944 ArcClose(FileId);
945 goto Failure;
946 }
947 }
948
949 /*
950 * On Vista and above, a digital signature check is performed when the image
951 * has the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag set in its header.
952 * (We of course do not perform this check yet!)
953 */
954
955 /* Reload the NT Header */
956 NtHeaders = RtlImageNtHeader(PhysicalBase);
957
958 /* Load the first section */
959 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
960
961 /* Walk through each section and read it (check/fix any possible
962 bad situations, if they arise) */
963 for (i = 0; i < NumberOfSections; i++)
964 {
965 VirtualSize = SectionHeader->Misc.VirtualSize;
966 SizeOfRawData = SectionHeader->SizeOfRawData;
967
968 /* Handle a case when VirtualSize equals 0 */
969 if (VirtualSize == 0)
970 VirtualSize = SizeOfRawData;
971
972 /* If PointerToRawData is 0, then force its size to be also 0 */
973 if (SectionHeader->PointerToRawData == 0)
974 {
975 SizeOfRawData = 0;
976 }
977 else
978 {
979 /* Cut the loaded size to the VirtualSize extents */
980 if (SizeOfRawData > VirtualSize)
981 SizeOfRawData = VirtualSize;
982 }
983
984 /* Actually read the section (if its size is not 0) */
985 if (SizeOfRawData != 0)
986 {
987 /* Seek to the correct position */
988 Position.QuadPart = SectionHeader->PointerToRawData;
989 Status = ArcSeek(FileId, &Position, SeekAbsolute);
990
991 TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
992
993 /* Read this section from the file, size = SizeOfRawData */
994 Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
995 if (Status != ESUCCESS)
996 {
997 ERR("PeLdrLoadImage(): Error reading section from file!\n");
998 break;
999 }
1000 }
1001
1002 /* Size of data is less than the virtual size: fill up the remainder with zeroes */
1003 if (SizeOfRawData < VirtualSize)
1004 {
1005 TRACE("PeLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
1006 RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
1007 }
1008
1009 SectionHeader++;
1010 }
1011
1012 /* We are done with the file, close it */
1013 ArcClose(FileId);
1014
1015 /* If loading failed, return right now */
1016 if (Status != ESUCCESS)
1017 goto Failure;
1018
1019 /* Relocate the image, if it needs it */
1020 if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
1021 {
1022 WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase);
1023 Status = LdrRelocateImageWithBias(PhysicalBase,
1024 (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
1025 "FreeLdr",
1026 ESUCCESS,
1027 ESUCCESS, /* In case of conflict still return success */
1028 ENOEXEC);
1029 if (Status != ESUCCESS)
1030 goto Failure;
1031 }
1032
1033 /* Fill output parameters */
1034 *ImageBasePA = PhysicalBase;
1035
1036 TRACE("PeLdrLoadImage() done, PA = %p\n", *ImageBasePA);
1037 return TRUE;
1038
1039Failure:
1040 /* Cleanup and bail out */
1041 MmFreeMemory(PhysicalBase);
1042 return FALSE;
1043}
1044
1045BOOLEAN
1048 _In_ TYPE_OF_MEMORY MemoryType,
1049 _Out_ PVOID* ImageBasePA)
1050{
1051 return PeLdrLoadImageEx(FilePath, MemoryType, ImageBasePA, TRUE);
1052}
1053
1054BOOLEAN
1057 _In_ PCSTR BaseDllName,
1058 _Out_ PVOID* ImageBase,
1059 _Out_ PLDR_DATA_TABLE_ENTRY* DataTableEntry)
1060{
1062
1063 /* Load the image as a bootloader image */
1066 ImageBase,
1067 FALSE);
1068 if (!Success)
1069 {
1070 WARN("Failed to load boot image '%s'\n", FilePath);
1071 return FALSE;
1072 }
1073
1074 /* Allocate a DTE */
1076 BaseDllName,
1077 FilePath,
1078 *ImageBase,
1079 DataTableEntry);
1080 if (!Success)
1081 {
1082 /* Cleanup and bail out */
1083 ERR("Failed to allocate DTE for '%s'\n", FilePath);
1084 MmFreeMemory(*ImageBase);
1085 return FALSE;
1086 }
1087
1088 /* Resolve imports */
1090 if (!Success)
1091 {
1092 /* Cleanup and bail out */
1093 ERR("Failed to resolve imports for '%s'\n", FilePath);
1094 PeLdrFreeDataTableEntry(*DataTableEntry);
1095 MmFreeMemory(*ImageBase);
1096 return FALSE;
1097 }
1098
1099 return TRUE;
1100}
PCWSTR FilePath
unsigned char BOOLEAN
unsigned int UINT32
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int toupper(int c)
Definition: utclib.c:881
char * strchr(const char *String, int ch)
Definition: utclib.c:501
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
ULONG ArcGetRelativeTime(VOID)
Definition: arcemul.c:33
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:455
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:219
ARC_STATUS ArcClose(_In_ ULONG FileId)
Definition: fs.c:409
#define SECTOR_SIZE
Definition: fs.h:22
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:448
PVOID MmAllocateMemoryAtAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:85
VOID MmFreeMemory(PVOID MemoryPointer)
Definition: mm.c:215
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
FORCEINLINE VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: mm.h:181
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: mm.h:174
struct _LDR_DATA_TABLE_ENTRY * PLDR_DATA_TABLE_ENTRY
Definition: bufpool.h:45
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
#define __ImageBase
Definition: crt_handler.c:22
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
struct _IMAGE_EXPORT_DIRECTORY * PIMAGE_EXPORT_DIRECTORY
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
#define RtlImageNtHeader
Definition: compat.h:806
#define ENOEXEC
Definition: errno.h:14
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ Success
Definition: eventcreate.c:712
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1306
#define RVA(m, b)
Definition: freeldr.h:28
Status
Definition: gdiplustypes.h:25
GLdouble u1
Definition: glext.h:8308
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TAG_WLDR_DTE
Definition: winldr.h:13
#define TAG_WLDR_NAME
Definition: winldr.h:15
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23
#define LDRP_IMAGE_INTEGRITY_FORCED
Definition: ldrtypes.h:41
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:247
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define min(a, b)
Definition: monoChain.cc:55
#define KSEG0_BASE
Definition: ketypes.h:343
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID BaseAddress, _In_ LONGLONG AdditionalBias, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
Definition: image.c:474
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
CHAR * PCH
Definition: ntbasedef.h:399
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:680
#define ANSI_NULL
CONST CHAR * PCCH
Definition: ntbasedef.h:400
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
struct _IMAGE_IMPORT_DESCRIPTOR * PIMAGE_IMPORT_DESCRIPTOR
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
Definition: ntimage.h:456
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
#define L(x)
Definition: ntvdm.h:50
#define IMAGE_FILE_EXECUTABLE_IMAGE
Definition: pedump.c:160
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
long LONG
Definition: pedump.c:60
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
unsigned short USHORT
Definition: pedump.c:61
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
BOOLEAN PeLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH DirectoryPath, IN PLDR_DATA_TABLE_ENTRY ScanDTE)
Definition: peloader.c:632
static BOOLEAN PeLdrpBindImportName(_Inout_ PLIST_ENTRY ModuleListHead, _In_ PVOID DllBase, _In_ PVOID ImageBase, _In_ PIMAGE_THUNK_DATA ThunkName, _Inout_ PIMAGE_THUNK_DATA ThunkData, _In_ PIMAGE_EXPORT_DIRECTORY ExportDirectory, _In_ ULONG ExportSize, _In_ BOOLEAN ProcessForwards, _In_ PCSTR DirectoryPath, _In_ PLIST_ENTRY Parent)
Definition: peloader.c:138
VOID PeLdrFreeDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY Entry)
Definition: peloader.c:829
BOOLEAN PeLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead, IN PCH DllName, OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
Definition: peloader.c:587
PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback
Definition: peloader.c:30
BOOLEAN PeLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH BaseDllName, IN PCCH FullDllName, IN PVOID BaseVA, OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
Definition: peloader.c:712
#define DEFAULT_SECURITY_COOKIE
Definition: peloader.c:36
static BOOLEAN PeLdrpLoadAndScanReferencedDll(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH DirectoryPath, IN PCH ImportName, IN PLIST_ENTRY Parent OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: peloader.c:389
static BOOLEAN PeLdrpCompareDllName(IN PCH DllName, IN PUNICODE_STRING UnicodeName)
Definition: peloader.c:79
static PVOID PeLdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: peloader.c:43
BOOLEAN PeLdrLoadBootImage(_In_ PCSTR FilePath, _In_ PCSTR BaseDllName, _Out_ PVOID *ImageBase, _Out_ PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: peloader.c:1055
BOOLEAN PeLdrInitializeModuleList(VOID)
Definition: peloader.c:525
BOOLEAN PeLdrLoadImageEx(_In_ PCSTR FilePath, _In_ TYPE_OF_MEMORY MemoryType, _Out_ PVOID *ImageBasePA, _In_ BOOLEAN KernelMapping)
Loads the specified image from the file.
Definition: peloader.c:854
PVOID PeLdrInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: peloader.c:548
BOOLEAN PeLdrLoadImage(_In_ PCSTR FilePath, _In_ TYPE_OF_MEMORY MemoryType, _Out_ PVOID *ImageBasePA)
Definition: peloader.c:1046
static BOOLEAN PeLdrpScanImportAddressTable(_Inout_ PLIST_ENTRY ModuleListHead, _In_ PVOID DllBase, _In_ PVOID ImageBase, _In_ PIMAGE_THUNK_DATA ThunkName, _Inout_ PIMAGE_THUNK_DATA ThunkData, _In_ PCSTR DirectoryPath, _In_ PLIST_ENTRY Parent)
Definition: peloader.c:454
LIST_ENTRY FrLdrModuleList
Definition: peloader.c:28
VOID(NTAPI * PELDR_IMPORTDLL_LOAD_CALLBACK)(_In_ PCSTR FileName)
Definition: peloader.h:24
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
@ ESUCCESS
Definition: arc.h:32
@ LoaderBootDriver
Definition: arc.h:185
@ LoaderLoadedProgram
Definition: arc.h:178
ULONG ARC_STATUS
Definition: arc.h:4
@ SeekAbsolute
Definition: arc.h:59
@ OpenReadOnly
Definition: arc.h:65
enum _TYPE_OF_MEMORY TYPE_OF_MEMORY
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
base of all file and directory entries
Definition: entries.h:83
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
DWORD PointerToRawData
Definition: pedump.c:290
union _IMAGE_SECTION_HEADER::@1573 Misc
union _IMAGE_THUNK_DATA32::@2143 u1
Definition: btrfs_drv.h:1876
USHORT LoadCount
Definition: ntddk_ex.h:208
PVOID EntryPoint
Definition: ntddk_ex.h:203
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
ULONG SizeOfImage
Definition: ldrtypes.h:143
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG Flags
Definition: ntddk_ex.h:207
PVOID SectionPointer
Definition: ntddk_ex.h:213
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
ULONG CheckSum
Definition: btrfs_drv.h:1886
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
static COORD Position
Definition: mouse.c:34
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t * PULONG
Definition: typedefs.h:59
char * PSTR
Definition: typedefs.h:51
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PUSHORT
Definition: typedefs.h:56
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
static WLX_DISPATCH_VERSION_1_4 FunctionTable
Definition: wlx.c:722
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175