ReactOS 0.4.15-dev-5893-g1bb4167
peloader.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for peloader.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (PELOADER)
 
static BOOLEAN PeLdrpCompareDllName (IN PCH DllName, IN PUNICODE_STRING UnicodeName)
 
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)
 
static BOOLEAN PeLdrpBindImportName (IN OUT PLIST_ENTRY ModuleListHead, IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA ThunkData, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN ProcessForwards, IN PCSTR DirectoryPath, IN PLIST_ENTRY Parent)
 
static BOOLEAN PeLdrpScanImportAddressTable (IN OUT PLIST_ENTRY ModuleListHead, IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA ThunkData, IN PCSTR DirectoryPath, IN PLIST_ENTRY Parent)
 
BOOLEAN PeLdrCheckForLoadedDll (IN OUT PLIST_ENTRY ModuleListHead, IN PCH DllName, OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
 
BOOLEAN PeLdrScanImportDescriptorTable (IN OUT PLIST_ENTRY ModuleListHead, IN PCCH DirectoryPath, IN PLDR_DATA_TABLE_ENTRY ScanDTE)
 
BOOLEAN PeLdrAllocateDataTableEntry (IN OUT PLIST_ENTRY ModuleListHead, IN PCCH BaseDllName, IN PCCH FullDllName, IN PVOID BasePA, OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
 
VOID PeLdrFreeDataTableEntry (_In_ PLDR_DATA_TABLE_ENTRY Entry)
 
BOOLEAN PeLdrLoadImage (IN PCHAR FileName, IN TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA)
 

Variables

PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL
 

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( PELOADER  )

◆ PeLdrAllocateDataTableEntry()

BOOLEAN PeLdrAllocateDataTableEntry ( IN OUT PLIST_ENTRY  ModuleListHead,
IN PCCH  BaseDllName,
IN PCCH  FullDllName,
IN PVOID  BasePA,
OUT PLDR_DATA_TABLE_ENTRY NewEntry 
)

Definition at line 598 of file peloader.c.

604{
605 PVOID BaseVA = PaToVa(BasePA);
606 PWSTR BaseDllNameBuffer, Buffer;
607 PLDR_DATA_TABLE_ENTRY DataTableEntry;
608 PIMAGE_NT_HEADERS NtHeaders;
610
611 TRACE("PeLdrAllocateDataTableEntry('%s', '%s', %p)\n",
612 BaseDllName, FullDllName, BasePA);
613
614 /* Allocate memory for a data table entry, zero-initialize it */
617 if (DataTableEntry == NULL)
618 return FALSE;
619
620 /* Get NT headers from the image */
621 NtHeaders = RtlImageNtHeader(BasePA);
622
623 /* Initialize corresponding fields of DTE based on NT headers value */
624 RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
625 DataTableEntry->DllBase = BaseVA;
626 DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
627 DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
628 DataTableEntry->SectionPointer = 0;
629 DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
630
631 /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
632 by simple conversion - copying each character */
633 Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
635 if (Buffer == NULL)
636 {
637 FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
638 return FALSE;
639 }
640
641 /* Save Buffer, in case of later failure */
642 BaseDllNameBuffer = Buffer;
643
644 DataTableEntry->BaseDllName.Length = Length;
645 DataTableEntry->BaseDllName.MaximumLength = Length;
646 DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
647
649 Length /= sizeof(WCHAR);
650 while (Length--)
651 {
652 *Buffer++ = *BaseDllName++;
653 }
654
655 /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
656 using the same method */
657 Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
659 if (Buffer == NULL)
660 {
661 FrLdrHeapFree(BaseDllNameBuffer, TAG_WLDR_NAME);
662 FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
663 return FALSE;
664 }
665
666 DataTableEntry->FullDllName.Length = Length;
667 DataTableEntry->FullDllName.MaximumLength = Length;
668 DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
669
671 Length /= sizeof(WCHAR);
672 while (Length--)
673 {
674 *Buffer++ = *FullDllName++;
675 }
676
677 /* Initialize what's left - LoadCount which is 1, and set Flags so that
678 we know this entry is processed */
679 DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
680 DataTableEntry->LoadCount = 1;
681
682 /* Honour the FORCE_INTEGRITY flag */
684 {
685 /*
686 * On Vista and above, the LDRP_IMAGE_INTEGRITY_FORCED flag must be set
687 * if IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY is set in the image header.
688 * This is done after the image has been loaded and the digital signature
689 * check has passed successfully. (We do not do it yet!)
690 *
691 * Several OS functionality depend on the presence of this flag.
692 * For example, when using Object-Manager callbacks the latter will call
693 * MmVerifyCallbackFunction() to verify whether the flag is present.
694 * If not callbacks will not work.
695 * (See Windows Internals Part 1, 6th edition, p. 176.)
696 */
697 DataTableEntry->Flags |= LDRP_IMAGE_INTEGRITY_FORCED;
698 }
699
700 /* Insert this DTE to a list in the LPB */
702 TRACE("Inserting DTE %p, name='%.*S' DllBase=%p\n", DataTableEntry,
703 DataTableEntry->BaseDllName.Length / sizeof(WCHAR),
704 VaToPa(DataTableEntry->BaseDllName.Buffer),
705 DataTableEntry->DllBase);
706
707 /* Save pointer to a newly allocated and initialized entry */
708 *NewEntry = DataTableEntry;
709
710 /* Return success */
711 return TRUE;
712}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
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 NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RtlImageNtHeader
Definition: compat.h:806
#define InsertTailList(ListHead, Entry)
#define RVA(m, b)
Definition: freeldr.h:24
#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_ENTRY_PROCESSED
Definition: ldrtypes.h:44
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:247
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
Definition: ntimage.h:456
unsigned short USHORT
Definition: pedump.c:61
#define TRACE(s)
Definition: solgame.cpp:4
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
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
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by LoadBootDeviceDriver(), LoadModule(), PeLdrpLoadAndScanReferencedDll(), and WinLdrLoadDeviceDriver().

◆ PeLdrCheckForLoadedDll()

BOOLEAN PeLdrCheckForLoadedDll ( IN OUT PLIST_ENTRY  ModuleListHead,
IN PCH  DllName,
OUT PLDR_DATA_TABLE_ENTRY LoadedEntry 
)

Definition at line 478 of file peloader.c.

482{
483 PLDR_DATA_TABLE_ENTRY DataTableEntry;
484 LIST_ENTRY *ModuleEntry;
485
486 TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName);
487
488 /* Just go through each entry in the LoadOrderList and compare loaded module's
489 name with a given name */
490 ModuleEntry = ModuleListHead->Flink;
491 while (ModuleEntry != ModuleListHead)
492 {
493 /* Get pointer to the current DTE */
494 DataTableEntry = CONTAINING_RECORD(ModuleEntry,
496 InLoadOrderLinks);
497
498 TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, base %p name '%.*ws'\n",
499 DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
500 DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer));
501
502 /* Compare names */
503 if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
504 {
505 /* Yes, found it, report pointer to the loaded module's DTE
506 to the caller and increase load count for it */
507 *LoadedEntry = DataTableEntry;
508 DataTableEntry->LoadCount++;
509 TRACE("PeLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry);
510 return TRUE;
511 }
512
513 /* Go to the next entry */
514 ModuleEntry = ModuleEntry->Flink;
515 }
516
517 /* Nothing found */
518 return FALSE;
519}
static BOOLEAN PeLdrpCompareDllName(IN PCH DllName, IN PUNICODE_STRING UnicodeName)
Definition: peloader.c:35
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by PeLdrpBindImportName(), PeLdrScanImportDescriptorTable(), and WinLdrLoadDeviceDriver().

◆ PeLdrFreeDataTableEntry()

VOID PeLdrFreeDataTableEntry ( _In_ PLDR_DATA_TABLE_ENTRY  Entry)

Definition at line 715 of file peloader.c.

718{
719 // ASSERT(ModuleListHead);
720 ASSERT(Entry);
721
722 RemoveEntryList(&Entry->InLoadOrderLinks);
723 FrLdrHeapFree(VaToPa(Entry->FullDllName.Buffer), TAG_WLDR_NAME);
724 FrLdrHeapFree(VaToPa(Entry->BaseDllName.Buffer), TAG_WLDR_NAME);
726}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ASSERT(a)
Definition: mode.c:44
base of all file and directory entries
Definition: entries.h:83

Referenced by LoadBootDeviceDriver(), LoadWindowsCore(), PeLdrpLoadAndScanReferencedDll(), and WinLdrLoadDeviceDriver().

◆ PeLdrLoadImage()

BOOLEAN PeLdrLoadImage ( IN PCHAR  FileName,
IN TYPE_OF_MEMORY  MemoryType,
OUT PVOID ImageBasePA 
)

Definition at line 736 of file peloader.c.

740{
741 ULONG FileId;
742 PVOID PhysicalBase;
743 PVOID VirtualBase = NULL;
744 UCHAR HeadersBuffer[SECTOR_SIZE * 2];
745 PIMAGE_NT_HEADERS NtHeaders;
746 PIMAGE_SECTION_HEADER SectionHeader;
747 ULONG VirtualSize, SizeOfRawData, NumberOfSections;
751
752 TRACE("PeLdrLoadImage('%s', %ld)\n", FileName, MemoryType);
753
754 /* Open the image file */
756 if (Status != ESUCCESS)
757 {
758 WARN("ArcOpen('%s') failed. Status: %u\n", FileName, Status);
759 return FALSE;
760 }
761
762 /* Load the first 2 sectors of the image so we can read the PE header */
763 Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
764 if (Status != ESUCCESS)
765 {
766 ERR("ArcRead('%s') failed. Status: %u\n", FileName, Status);
767 ArcClose(FileId);
768 return FALSE;
769 }
770
771 /* Now read the MZ header to get the offset to the PE Header */
772 NtHeaders = RtlImageNtHeader(HeadersBuffer);
773 if (!NtHeaders)
774 {
775 ERR("No NT header found in \"%s\"\n", FileName);
776 ArcClose(FileId);
777 return FALSE;
778 }
779
780 /* Ensure this is executable image */
782 {
783 ERR("Not an executable image \"%s\"\n", FileName);
784 ArcClose(FileId);
785 return FALSE;
786 }
787
788 /* Store number of sections to read and a pointer to the first section */
789 NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
790 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
791
792 /* Try to allocate this memory; if it fails, allocate somewhere else */
793 PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
794 (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
795 MemoryType);
796
797 if (PhysicalBase == NULL)
798 {
799 /* Don't fail, allocate again at any other "low" place */
800 PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
801
802 if (PhysicalBase == NULL)
803 {
804 ERR("Failed to alloc %lu bytes for image %s\n", NtHeaders->OptionalHeader.SizeOfImage, FileName);
805 ArcClose(FileId);
806 return FALSE;
807 }
808 }
809
810 /* This is the real image base, in form of a virtual address */
811 VirtualBase = PaToVa(PhysicalBase);
812
813 TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
814
815 /* Copy headers from already read data */
816 RtlCopyMemory(PhysicalBase, HeadersBuffer, min(NtHeaders->OptionalHeader.SizeOfHeaders, sizeof(HeadersBuffer)));
817 /* If headers are quite big, request next bytes from file */
818 if (NtHeaders->OptionalHeader.SizeOfHeaders > sizeof(HeadersBuffer))
819 {
820 Status = ArcRead(FileId, (PUCHAR)PhysicalBase + sizeof(HeadersBuffer), NtHeaders->OptionalHeader.SizeOfHeaders - sizeof(HeadersBuffer), &BytesRead);
821 if (Status != ESUCCESS)
822 {
823 ERR("ArcRead('%s') failed. Status: %u\n", FileName, Status);
824 // UiMessageBox("Error reading headers.");
825 ArcClose(FileId);
826 goto Failure;
827 }
828 }
829
830 /*
831 * On Vista and above, a digital signature check is performed when the image
832 * has the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag set in its header.
833 * (We of course do not perform this check yet!)
834 */
835
836 /* Reload the NT Header */
837 NtHeaders = RtlImageNtHeader(PhysicalBase);
838
839 /* Load the first section */
840 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
841
842 /* Walk through each section and read it (check/fix any possible
843 bad situations, if they arise) */
844 for (i = 0; i < NumberOfSections; i++)
845 {
846 VirtualSize = SectionHeader->Misc.VirtualSize;
847 SizeOfRawData = SectionHeader->SizeOfRawData;
848
849 /* Handle a case when VirtualSize equals 0 */
850 if (VirtualSize == 0)
851 VirtualSize = SizeOfRawData;
852
853 /* If PointerToRawData is 0, then force its size to be also 0 */
854 if (SectionHeader->PointerToRawData == 0)
855 {
856 SizeOfRawData = 0;
857 }
858 else
859 {
860 /* Cut the loaded size to the VirtualSize extents */
861 if (SizeOfRawData > VirtualSize)
862 SizeOfRawData = VirtualSize;
863 }
864
865 /* Actually read the section (if its size is not 0) */
866 if (SizeOfRawData != 0)
867 {
868 /* Seek to the correct position */
869 Position.QuadPart = SectionHeader->PointerToRawData;
870 Status = ArcSeek(FileId, &Position, SeekAbsolute);
871
872 TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
873
874 /* Read this section from the file, size = SizeOfRawData */
875 Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
876 if (Status != ESUCCESS)
877 {
878 ERR("PeLdrLoadImage(): Error reading section from file!\n");
879 break;
880 }
881 }
882
883 /* Size of data is less than the virtual size: fill up the remainder with zeroes */
884 if (SizeOfRawData < VirtualSize)
885 {
886 TRACE("PeLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
887 RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
888 }
889
890 SectionHeader++;
891 }
892
893 /* We are done with the file, close it */
894 ArcClose(FileId);
895
896 /* If loading failed, return right now */
897 if (Status != ESUCCESS)
898 goto Failure;
899
900 /* Relocate the image, if it needs it */
901 if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
902 {
903 WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase);
904 Status = LdrRelocateImageWithBias(PhysicalBase,
905 (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
906 "FreeLdr",
907 ESUCCESS,
908 ESUCCESS, /* In case of conflict still return success */
909 ENOEXEC);
910 if (Status != ESUCCESS)
911 goto Failure;
912 }
913
914 /* Fill output parameters */
915 *ImageBasePA = PhysicalBase;
916
917 TRACE("PeLdrLoadImage() done, PA = %p\n", *ImageBasePA);
918 return TRUE;
919
920Failure:
921 /* Cleanup and bail out */
922 MmFreeMemory(PhysicalBase);
923 return FALSE;
924}
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:220
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:245
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:56
#define SECTOR_SIZE
Definition: fs.h:22
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:238
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
#define ENOEXEC
Definition: errno.h:14
Status
Definition: gdiplustypes.h:25
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 min(a, b)
Definition: monoChain.cc:55
#define KSEG0_BASE
Definition: ketypes.h:278
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
#define IMAGE_FILE_EXECUTABLE_IMAGE
Definition: pedump.c:160
@ ESUCCESS
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
@ SeekAbsolute
Definition: arc.h:59
@ OpenReadOnly
Definition: arc.h:65
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
union _IMAGE_SECTION_HEADER::@1538 Misc
DWORD PointerToRawData
Definition: pedump.c:290
static COORD Position
Definition: mouse.c:34
char * PSTR
Definition: typedefs.h:51
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_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
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by LoadBootDeviceDriver(), LoadModule(), PeLdrpLoadAndScanReferencedDll(), and WinLdrLoadDeviceDriver().

◆ PeLdrpBindImportName()

static BOOLEAN PeLdrpBindImportName ( IN OUT PLIST_ENTRY  ModuleListHead,
IN PVOID  DllBase,
IN PVOID  ImageBase,
IN PIMAGE_THUNK_DATA  ThunkData,
IN PIMAGE_EXPORT_DIRECTORY  ExportDirectory,
IN ULONG  ExportSize,
IN BOOLEAN  ProcessForwards,
IN PCSTR  DirectoryPath,
IN PLIST_ENTRY  Parent 
)
static

Definition at line 94 of file peloader.c.

104{
105 ULONG Ordinal;
106 PULONG NameTable, FunctionTable;
107 PUSHORT OrdinalTable;
108 LONG High, Low, Middle, Result;
109 ULONG Hint;
110 PIMAGE_IMPORT_BY_NAME ImportData;
111 PCHAR ExportName, ForwarderName;
113
114 //TRACE("PeLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
115 // DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards);
116
117 /* Check passed DllBase param */
118 if (DllBase == NULL)
119 {
120 WARN("DllBase == NULL!\n");
121 return FALSE;
122 }
123
124 /* Convert all non-critical pointers to PA from VA */
125 ThunkData = VaToPa(ThunkData);
126
127 /* Is the reference by ordinal? */
128 if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
129 {
130 /* Yes, calculate the ordinal */
131 Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base);
132 //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
133 }
134 else
135 {
136 /* It's reference by name, we have to look it up in the export directory */
137 if (!ProcessForwards)
138 {
139 /* AddressOfData in thunk entry will become a virtual address (from relative) */
140 //TRACE("PeLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData);
141 ThunkData->u1.AddressOfData =
142 (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData);
143 //TRACE("PeLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData);
144 }
145
146 /* Get the import name */
147 ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData);
148
149 /* Get pointers to Name and Ordinal tables (RVA -> VA) */
150 NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
151 OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
152
153 //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
154 // NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals);
155
156 /* Get the hint, convert it to a physical pointer */
157 Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
158 //TRACE("HintIndex %d\n", Hint);
159
160 /* Get the export name from the hint */
161 ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));
162
163 /* If Hint is less than total number of entries in the export directory,
164 and import name == export name, then we can just get it from the OrdinalTable */
165 if ((Hint < ExportDirectory->NumberOfNames) &&
166 (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
167 {
168 Ordinal = OrdinalTable[Hint];
169 //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
170 }
171 else
172 {
173 /* It's not the easy way, we have to lookup import name in the name table.
174 Let's use a binary search for this task. */
175
176 //TRACE("PeLdrpBindImportName() looking up the import name using binary search...\n");
177
178 /* Low boundary is set to 0, and high boundary to the maximum index */
179 Low = 0;
180 High = ExportDirectory->NumberOfNames - 1;
181
182 /* Perform a binary-search loop */
183 while (High >= Low)
184 {
185 /* Divide by 2 by shifting to the right once */
186 Middle = (Low + High) / 2;
187
188 /* Get the name from the name table */
189 ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));
190
191 /* Compare the names */
192 Result = strcmp(ExportName, (PCHAR)ImportData->Name);
193
194 // TRACE("Binary search: comparing Import '__', Export '%s'\n",
195 // VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),
196 // (PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));
197
198 // TRACE("TE->u1.AOD %p, fulladdr %p\n",
199 // ThunkData->u1.AddressOfData,
200 // ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );
201
202 /* Depending on result of strcmp, perform different actions */
203 if (Result > 0)
204 {
205 /* Adjust top boundary */
206 High = Middle - 1;
207 }
208 else if (Result < 0)
209 {
210 /* Adjust bottom boundary */
211 Low = Middle + 1;
212 }
213 else
214 {
215 /* Yay, found it! */
216 break;
217 }
218 }
219
220 /* If high boundary is less than low boundary, then no result found */
221 if (High < Low)
222 {
223 ERR("Did not find export '%s'!\n", (PCHAR)ImportData->Name);
224 return FALSE;
225 }
226
227 /* Everything alright, get the ordinal */
228 Ordinal = OrdinalTable[Middle];
229
230 //TRACE("PeLdrpBindImportName() found Ordinal %d\n", Ordinal);
231 }
232 }
233
234 /* Check ordinal number for validity! */
235 if (Ordinal >= ExportDirectory->NumberOfFunctions)
236 {
237 ERR("Ordinal number is invalid!\n");
238 return FALSE;
239 }
240
241 /* Get a pointer to the function table */
242 FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));
243
244 /* Save a pointer to the function */
245 ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);
246
247 /* Is it a forwarder? (function pointer is within the export directory) */
248 ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
249 if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
250 ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
251 {
252 PLDR_DATA_TABLE_ENTRY DataTableEntry;
253 PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
254 ULONG RefExportSize;
255 CHAR ForwardDllName[256];
256
257 TRACE("PeLdrpBindImportName(): ForwarderName %s\n", ForwarderName);
258
259 /* Save the name of the forward dll */
260 RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));
261
262 /* Strip out the symbol name */
263 *strrchr(ForwardDllName, '.') = ANSI_NULL;
264
265 /* Check if the target image is already loaded */
266 if (!PeLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry))
267 {
268 /* Check if the forward dll name has an extension */
269 if (strchr(ForwardDllName, '.') == NULL)
270 {
271 /* Name does not have an extension, append '.dll' */
272 RtlStringCbCatA(ForwardDllName, sizeof(ForwardDllName), ".dll");
273 }
274
275 /* Now let's try to load it! */
277 DirectoryPath,
278 ForwardDllName,
279 Parent,
280 &DataTableEntry);
281 if (!Success)
282 {
283 ERR("PeLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n");
284 return Success;
285 }
286 }
287
288 /* Get pointer to the export directory of loaded DLL */
289 RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
291 TRUE,
293 &RefExportSize);
294
295 /* Fail if it's NULL */
296 if (RefExportDirectory)
297 {
298 UCHAR Buffer[128];
299 IMAGE_THUNK_DATA RefThunkData;
300 PIMAGE_IMPORT_BY_NAME ImportByName;
301 PCHAR ImportName;
302
303 /* Get pointer to the import name */
304 ImportName = strrchr(ForwarderName, '.') + 1;
305
306 /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
307 ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
308
309 /* Fill the name with the import name */
310 RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
311
312 /* Set Hint to 0 */
313 ImportByName->Hint = 0;
314
315 /* And finally point ThunkData's AddressOfData to that structure */
316 RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;
317
318 /* And recursively call ourselves */
320 DataTableEntry->DllBase,
321 ImageBase,
322 &RefThunkData,
323 RefExportDirectory,
324 RefExportSize,
325 TRUE,
326 DirectoryPath,
327 Parent);
328
329 /* Fill out the ThunkData with data from RefThunkData */
330 ThunkData->u1 = RefThunkData.u1;
331
332 /* Return what we got from the recursive call */
333 return Success;
334 }
335 else
336 {
337 /* Fail if ExportDirectory is NULL */
338 return FALSE;
339 }
340 }
341
342 /* Success! */
343 return TRUE;
344}
unsigned char BOOLEAN
unsigned int UINT32
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
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
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
struct _IMAGE_EXPORT_DIRECTORY * PIMAGE_EXPORT_DIRECTORY
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define ULONG_PTR
Definition: config.h:101
@ Success
Definition: eventcreate.c:712
#define PCHAR
Definition: match.c:90
#define ANSI_NULL
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625
long LONG
Definition: pedump.c:60
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
BOOLEAN PeLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead, IN PCH DllName, OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
Definition: peloader.c:478
static BOOLEAN PeLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead, IN PVOID DllBase, IN PVOID ImageBase, IN 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:94
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:347
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
union _IMAGE_THUNK_DATA32::@2111 u1
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
char * PCHAR
Definition: typedefs.h:51
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:426
char CHAR
Definition: xmlstorage.h:175

Referenced by PeLdrpBindImportName(), and PeLdrpScanImportAddressTable().

◆ PeLdrpCompareDllName()

static BOOLEAN PeLdrpCompareDllName ( IN PCH  DllName,
IN PUNICODE_STRING  UnicodeName 
)
static

Definition at line 35 of file peloader.c.

38{
41
42 /* First obvious check: for length of two names */
43 Length = strlen(DllName);
44
45#if DBG
46 {
47 UNICODE_STRING UnicodeNamePA;
48 UnicodeNamePA.Length = UnicodeName->Length;
49 UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
50 UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
51 TRACE("PeLdrpCompareDllName: %s and %wZ, Length = %d "
52 "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length);
53 }
54#endif
55
56 if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
57 return FALSE;
58
59 /* Store pointer to unicode string's buffer */
60 Buffer = VaToPa(UnicodeName->Buffer);
61
62 /* Loop character by character */
63 for (i = 0; i < Length; i++)
64 {
65 /* Compare two characters, uppercasing them */
66 if (toupper(*DllName) != toupper((CHAR)*Buffer))
67 return FALSE;
68
69 /* Move to the next character */
70 DllName++;
71 Buffer++;
72 }
73
74 /* Check, if strings either fully match, or match till the "." (w/o extension) */
75 if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
76 {
77 /* Yes they do */
78 return TRUE;
79 }
80
81 /* Strings don't match, return FALSE */
82 return FALSE;
83}
int toupper(int c)
Definition: utclib.c:881
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1305
#define L(x)
Definition: ntvdm.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by PeLdrCheckForLoadedDll(), and PeLdrScanImportDescriptorTable().

◆ PeLdrpLoadAndScanReferencedDll()

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 
)
static

Definition at line 347 of file peloader.c.

353{
354 CHAR FullDllName[256];
356 PVOID BasePA = NULL;
357
358 /* Prepare the full path to the file to be loaded */
359 RtlStringCbCopyA(FullDllName, sizeof(FullDllName), DirectoryPath);
360 RtlStringCbCatA(FullDllName, sizeof(FullDllName), ImportName);
361
362 TRACE("Loading referenced DLL: %s\n", FullDllName);
363
366
367 /* Load the image */
369 if (!Success)
370 {
371 ERR("PeLdrLoadImage('%s') failed\n", FullDllName);
372 return Success;
373 }
374
375 /* Allocate DTE for newly loaded DLL */
377 ImportName,
379 BasePA,
380 DataTableEntry);
381 if (!Success)
382 {
383 /* Cleanup and bail out */
384 ERR("PeLdrAllocateDataTableEntry('%s') failed\n", FullDllName);
385 MmFreeMemory(BasePA);
386 return Success;
387 }
388
389 (*DataTableEntry)->Flags |= LDRP_DRIVER_DEPENDENT_DLL;
390
391 /* Scan its dependencies too */
392 TRACE("PeLdrScanImportDescriptorTable() calling ourselves for %S\n",
393 VaToPa((*DataTableEntry)->BaseDllName.Buffer));
394 Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
395 if (!Success)
396 {
397 /* Cleanup and bail out */
398 ERR("PeLdrScanImportDescriptorTable() failed\n");
399 PeLdrFreeDataTableEntry(*DataTableEntry);
400 MmFreeMemory(BasePA);
401 return Success;
402 }
403
404 return TRUE;
405}
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
BOOLEAN PeLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH DirectoryPath, IN PLDR_DATA_TABLE_ENTRY ScanDTE)
Definition: peloader.c:522
VOID PeLdrFreeDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY Entry)
Definition: peloader.c:715
PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback
Definition: peloader.c:28
BOOLEAN PeLdrLoadImage(IN PCHAR FileName, IN TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA)
Definition: peloader.c:736
BOOLEAN PeLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH BaseDllName, IN PCCH FullDllName, IN PVOID BasePA, OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
Definition: peloader.c:598
@ LoaderBootDriver
Definition: arc.h:138

Referenced by PeLdrpBindImportName(), and PeLdrScanImportDescriptorTable().

◆ PeLdrpScanImportAddressTable()

static BOOLEAN PeLdrpScanImportAddressTable ( IN OUT PLIST_ENTRY  ModuleListHead,
IN PVOID  DllBase,
IN PVOID  ImageBase,
IN PIMAGE_THUNK_DATA  ThunkData,
IN PCSTR  DirectoryPath,
IN PLIST_ENTRY  Parent 
)
static

Definition at line 408 of file peloader.c.

415{
416 PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
418 ULONG ExportSize;
419
420 TRACE("PeLdrpScanImportAddressTable(): DllBase 0x%X, "
421 "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
422
423 /* Obtain the export table from the DLL's base */
424 if (DllBase == NULL)
425 {
426 ERR("Error, DllBase == NULL!\n");
427 return FALSE;
428 }
429 else
430 {
431 ExportDirectory =
433 TRUE,
435 &ExportSize);
436 }
437
438 TRACE("PeLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory);
439
440 /* If pointer to Export Directory is */
441 if (ExportDirectory == NULL)
442 {
443 ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
444 return FALSE;
445 }
446
447 /* Go through each entry in the thunk table and bind it */
448 while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
449 {
450 /* Bind it */
452 DllBase,
453 ImageBase,
454 ThunkData,
455 ExportDirectory,
456 ExportSize,
457 FALSE,
458 DirectoryPath,
459 Parent);
460
461 /* Move to the next entry */
462 ThunkData++;
463
464 /* Return error if binding was unsuccessful */
465 if (!Success)
466 return Success;
467 }
468
469 /* Return success */
470 return TRUE;
471}
GLdouble u1
Definition: glext.h:8308

Referenced by PeLdrScanImportDescriptorTable().

◆ PeLdrScanImportDescriptorTable()

BOOLEAN PeLdrScanImportDescriptorTable ( IN OUT PLIST_ENTRY  ModuleListHead,
IN PCCH  DirectoryPath,
IN PLDR_DATA_TABLE_ENTRY  ScanDTE 
)

Definition at line 522 of file peloader.c.

526{
527 PLDR_DATA_TABLE_ENTRY DataTableEntry;
528 PIMAGE_IMPORT_DESCRIPTOR ImportTable;
529 ULONG ImportTableSize;
530 PCH ImportName;
532
533 /* Get a pointer to the import table of this image */
534 ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
535 TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
536
537#if DBG
538 {
539 UNICODE_STRING BaseName;
540 BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
541 BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
542 BaseName.Length = ScanDTE->BaseDllName.Length;
543 TRACE("PeLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
544 &BaseName, ImportTable);
545 }
546#endif
547
548 /* If image doesn't have any import directory - just return success */
549 if (ImportTable == NULL)
550 return TRUE;
551
552 /* Loop through all entries */
553 for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
554 {
555 /* Get pointer to the name */
556 ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
557 TRACE("PeLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);
558
559 /* In case we get a reference to ourselves - just skip it */
560 if (PeLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
561 continue;
562
563 /* Load the DLL if it is not already loaded */
564 if (!PeLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
565 {
567 DirectoryPath,
568 ImportName,
569 &ScanDTE->InLoadOrderLinks,
570 &DataTableEntry);
571 if (!Success)
572 {
573 ERR("PeLdrpLoadAndScanReferencedDll() failed\n");
574 return Success;
575 }
576 }
577
578 /* Scan its import address table */
580 DataTableEntry->DllBase,
581 ScanDTE->DllBase,
582 (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
583 DirectoryPath,
584 &ScanDTE->InLoadOrderLinks);
585
586 if (!Success)
587 {
588 ERR("PeLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
589 ImportName, DirectoryPath);
590 return Success;
591 }
592 }
593
594 return TRUE;
595}
DWORD RVA
Definition: compat.h:1262
CHAR * PCH
Definition: ntbasedef.h:391
struct _IMAGE_IMPORT_DESCRIPTOR * PIMAGE_IMPORT_DESCRIPTOR
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
static BOOLEAN PeLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead, IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA ThunkData, IN PCSTR DirectoryPath, IN PLIST_ENTRY Parent)
Definition: peloader.c:408

Referenced by LoadBootDeviceDriver(), LoadWindowsCore(), PeLdrpLoadAndScanReferencedDll(), and WinLdrLoadDeviceDriver().

Variable Documentation

◆ PeLdrImportDllLoadCallback

PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL

Definition at line 28 of file peloader.c.

Referenced by LoadAndBootWindowsCommon(), and PeLdrpLoadAndScanReferencedDll().