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

Go to the source code of this file.

Macros

#define DEFAULT_SECURITY_COOKIE   0xBB40E64E
 

Functions

 DBG_DEFAULT_CHANNEL (PELOADER)
 
static PVOID PeLdrpFetchAddressOfSecurityCookie (PVOID BaseAddress, ULONG SizeOfImage)
 
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)
 
PVOID PeLdrInitSecurityCookie (PLDR_DATA_TABLE_ENTRY LdrEntry)
 
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_ PCSTR FilePath, _In_ TYPE_OF_MEMORY MemoryType, _Out_ PVOID *ImageBasePA)
 Loads the specified image from the file.
 

Variables

PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL
 

Macro Definition Documentation

◆ DEFAULT_SECURITY_COOKIE

#define DEFAULT_SECURITY_COOKIE   0xBB40E64E

Definition at line 34 of file peloader.c.

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 681 of file peloader.c.

687{
688 PVOID BaseVA = PaToVa(BasePA);
689 PWSTR BaseDllNameBuffer, Buffer;
690 PLDR_DATA_TABLE_ENTRY DataTableEntry;
691 PIMAGE_NT_HEADERS NtHeaders;
693
694 TRACE("PeLdrAllocateDataTableEntry('%s', '%s', %p)\n",
695 BaseDllName, FullDllName, BasePA);
696
697 /* Allocate memory for a data table entry, zero-initialize it */
700 if (DataTableEntry == NULL)
701 return FALSE;
702
703 /* Get NT headers from the image */
704 NtHeaders = RtlImageNtHeader(BasePA);
705
706 /* Initialize corresponding fields of DTE based on NT headers value */
707 RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
708 DataTableEntry->DllBase = BaseVA;
709 DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
710 DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
711 DataTableEntry->SectionPointer = 0;
712 DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
713
714 /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
715 by simple conversion - copying each character */
716 Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
718 if (Buffer == NULL)
719 {
720 FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
721 return FALSE;
722 }
723
724 /* Save Buffer, in case of later failure */
725 BaseDllNameBuffer = Buffer;
726
727 DataTableEntry->BaseDllName.Length = Length;
728 DataTableEntry->BaseDllName.MaximumLength = Length;
729 DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
730
732 Length /= sizeof(WCHAR);
733 while (Length--)
734 {
735 *Buffer++ = *BaseDllName++;
736 }
737
738 /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
739 using the same method */
740 Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
742 if (Buffer == NULL)
743 {
744 FrLdrHeapFree(BaseDllNameBuffer, TAG_WLDR_NAME);
745 FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
746 return FALSE;
747 }
748
749 DataTableEntry->FullDllName.Length = Length;
750 DataTableEntry->FullDllName.MaximumLength = Length;
751 DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
752
754 Length /= sizeof(WCHAR);
755 while (Length--)
756 {
757 *Buffer++ = *FullDllName++;
758 }
759
760 /* Initialize what's left - LoadCount which is 1, and set Flags so that
761 we know this entry is processed */
762 DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
763 DataTableEntry->LoadCount = 1;
764
765 /* Honour the FORCE_INTEGRITY flag */
767 {
768 /*
769 * On Vista and above, the LDRP_IMAGE_INTEGRITY_FORCED flag must be set
770 * if IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY is set in the image header.
771 * This is done after the image has been loaded and the digital signature
772 * check has passed successfully. (We do not do it yet!)
773 *
774 * Several OS functionality depend on the presence of this flag.
775 * For example, when using Object-Manager callbacks the latter will call
776 * MmVerifyCallbackFunction() to verify whether the flag is present.
777 * If not callbacks will not work.
778 * (See Windows Internals Part 1, 6th edition, p. 176.)
779 */
780 DataTableEntry->Flags |= LDRP_IMAGE_INTEGRITY_FORCED;
781 }
782
783 /* Insert this DTE to a list in the LPB */
785 TRACE("Inserting DTE %p, name='%.*S' DllBase=%p\n", DataTableEntry,
786 DataTableEntry->BaseDllName.Length / sizeof(WCHAR),
787 VaToPa(DataTableEntry->BaseDllName.Buffer),
788 DataTableEntry->DllBase);
789
790 /* Save pointer to a newly allocated and initialized entry */
791 *NewEntry = DataTableEntry;
792
793 /* Return success */
794 return TRUE;
795}
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:28
#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 561 of file peloader.c.

565{
566 PLDR_DATA_TABLE_ENTRY DataTableEntry;
567 LIST_ENTRY *ModuleEntry;
568
569 TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName);
570
571 /* Just go through each entry in the LoadOrderList and compare loaded module's
572 name with a given name */
573 ModuleEntry = ModuleListHead->Flink;
574 while (ModuleEntry != ModuleListHead)
575 {
576 /* Get pointer to the current DTE */
577 DataTableEntry = CONTAINING_RECORD(ModuleEntry,
579 InLoadOrderLinks);
580
581 TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, base %p name '%.*ws'\n",
582 DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
583 DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer));
584
585 /* Compare names */
586 if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
587 {
588 /* Yes, found it, report pointer to the loaded module's DTE
589 to the caller and increase load count for it */
590 *LoadedEntry = DataTableEntry;
591 DataTableEntry->LoadCount++;
592 TRACE("PeLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry);
593 return TRUE;
594 }
595
596 /* Go to the next entry */
597 ModuleEntry = ModuleEntry->Flink;
598 }
599
600 /* Nothing found */
601 return FALSE;
602}
static BOOLEAN PeLdrpCompareDllName(IN PCH DllName, IN PUNICODE_STRING UnicodeName)
Definition: peloader.c:77
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 798 of file peloader.c.

801{
802 // ASSERT(ModuleListHead);
803 ASSERT(Entry);
804
805 RemoveEntryList(&Entry->InLoadOrderLinks);
806 FrLdrHeapFree(VaToPa(Entry->FullDllName.Buffer), TAG_WLDR_NAME);
807 FrLdrHeapFree(VaToPa(Entry->BaseDllName.Buffer), TAG_WLDR_NAME);
809}
#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().

◆ PeLdrInitSecurityCookie()

PVOID PeLdrInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 522 of file peloader.c.

523{
525 ULONG_PTR NewCookie;
526
527 /* Fetch address of the cookie */
529
530 if (!Cookie)
531 return NULL;
532
533 /* Check if it's a default one */
535 (*Cookie == 0))
536 {
537 /* Generate new cookie using cookie address and time as seed */
539#ifdef _WIN64
540 /* Some images expect first 16 bits to be kept clean (like in default cookie) */
541 if (NewCookie > COOKIE_MAX)
542 {
543 NewCookie >>= 16;
544 }
545#endif
546 /* If the result is 0 or the same as we got, just add one to the default value */
547 if ((NewCookie == 0) || (NewCookie == *Cookie))
548 {
549 NewCookie = DEFAULT_SECURITY_COOKIE + 1;
550 }
551
552 /* Set the new cookie value */
553 *Cookie = NewCookie;
554 }
555
556 return Cookie;
557}
ULONG ArcGetRelativeTime(VOID)
Definition: arcemul.c:33
#define ULONG_PTR
Definition: config.h:101
#define DEFAULT_SECURITY_COOKIE
Definition: peloader.c:34
static PVOID PeLdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: peloader.c:41
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14

Referenced by PeLdrpLoadAndScanReferencedDll().

◆ PeLdrLoadImage()

BOOLEAN PeLdrLoadImage ( _In_ PCSTR  FilePath,
_In_ TYPE_OF_MEMORY  MemoryType,
_Out_ PVOID ImageBasePA 
)

Loads the specified image from the file.

PeLdrLoadImage doesn't perform any additional operations on the file path, it just directly calls the file I/O routines. It then relocates the image so that it's ready to be used when paging is enabled.

Note
Addressing mode: physical.

Definition at line 823 of file peloader.c.

827{
828 ULONG FileId;
829 PVOID PhysicalBase;
830 PVOID VirtualBase = NULL;
831 UCHAR HeadersBuffer[SECTOR_SIZE * 2];
832 PIMAGE_NT_HEADERS NtHeaders;
833 PIMAGE_SECTION_HEADER SectionHeader;
834 ULONG VirtualSize, SizeOfRawData, NumberOfSections;
838
839 TRACE("PeLdrLoadImage('%s', %ld)\n", FilePath, MemoryType);
840
841 /* Open the image file */
843 if (Status != ESUCCESS)
844 {
845 WARN("ArcOpen('%s') failed. Status: %u\n", FilePath, Status);
846 return FALSE;
847 }
848
849 /* Load the first 2 sectors of the image so we can read the PE header */
850 Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
851 if (Status != ESUCCESS)
852 {
853 ERR("ArcRead('%s') failed. Status: %u\n", FilePath, Status);
854 ArcClose(FileId);
855 return FALSE;
856 }
857
858 /* Now read the MZ header to get the offset to the PE Header */
859 NtHeaders = RtlImageNtHeader(HeadersBuffer);
860 if (!NtHeaders)
861 {
862 ERR("No NT header found in \"%s\"\n", FilePath);
863 ArcClose(FileId);
864 return FALSE;
865 }
866
867 /* Ensure this is executable image */
869 {
870 ERR("Not an executable image \"%s\"\n", FilePath);
871 ArcClose(FileId);
872 return FALSE;
873 }
874
875 /* Store number of sections to read and a pointer to the first section */
876 NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
877 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
878
879 /* Try to allocate this memory; if it fails, allocate somewhere else */
880 PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
881 (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
882 MemoryType);
883
884 if (PhysicalBase == NULL)
885 {
886 /* Don't fail, allocate again at any other "low" place */
887 PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
888
889 if (PhysicalBase == NULL)
890 {
891 ERR("Failed to alloc %lu bytes for image %s\n", NtHeaders->OptionalHeader.SizeOfImage, FilePath);
892 ArcClose(FileId);
893 return FALSE;
894 }
895 }
896
897 /* This is the real image base, in form of a virtual address */
898 VirtualBase = PaToVa(PhysicalBase);
899
900 TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
901
902 /* Copy headers from already read data */
903 RtlCopyMemory(PhysicalBase, HeadersBuffer, min(NtHeaders->OptionalHeader.SizeOfHeaders, sizeof(HeadersBuffer)));
904 /* If headers are quite big, request next bytes from file */
905 if (NtHeaders->OptionalHeader.SizeOfHeaders > sizeof(HeadersBuffer))
906 {
907 Status = ArcRead(FileId, (PUCHAR)PhysicalBase + sizeof(HeadersBuffer), NtHeaders->OptionalHeader.SizeOfHeaders - sizeof(HeadersBuffer), &BytesRead);
908 if (Status != ESUCCESS)
909 {
910 ERR("ArcRead('%s') failed. Status: %u\n", FilePath, Status);
911 // UiMessageBox("Error reading headers.");
912 ArcClose(FileId);
913 goto Failure;
914 }
915 }
916
917 /*
918 * On Vista and above, a digital signature check is performed when the image
919 * has the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag set in its header.
920 * (We of course do not perform this check yet!)
921 */
922
923 /* Reload the NT Header */
924 NtHeaders = RtlImageNtHeader(PhysicalBase);
925
926 /* Load the first section */
927 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
928
929 /* Walk through each section and read it (check/fix any possible
930 bad situations, if they arise) */
931 for (i = 0; i < NumberOfSections; i++)
932 {
933 VirtualSize = SectionHeader->Misc.VirtualSize;
934 SizeOfRawData = SectionHeader->SizeOfRawData;
935
936 /* Handle a case when VirtualSize equals 0 */
937 if (VirtualSize == 0)
938 VirtualSize = SizeOfRawData;
939
940 /* If PointerToRawData is 0, then force its size to be also 0 */
941 if (SectionHeader->PointerToRawData == 0)
942 {
943 SizeOfRawData = 0;
944 }
945 else
946 {
947 /* Cut the loaded size to the VirtualSize extents */
948 if (SizeOfRawData > VirtualSize)
949 SizeOfRawData = VirtualSize;
950 }
951
952 /* Actually read the section (if its size is not 0) */
953 if (SizeOfRawData != 0)
954 {
955 /* Seek to the correct position */
956 Position.QuadPart = SectionHeader->PointerToRawData;
957 Status = ArcSeek(FileId, &Position, SeekAbsolute);
958
959 TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
960
961 /* Read this section from the file, size = SizeOfRawData */
962 Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
963 if (Status != ESUCCESS)
964 {
965 ERR("PeLdrLoadImage(): Error reading section from file!\n");
966 break;
967 }
968 }
969
970 /* Size of data is less than the virtual size: fill up the remainder with zeroes */
971 if (SizeOfRawData < VirtualSize)
972 {
973 TRACE("PeLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
974 RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
975 }
976
977 SectionHeader++;
978 }
979
980 /* We are done with the file, close it */
981 ArcClose(FileId);
982
983 /* If loading failed, return right now */
984 if (Status != ESUCCESS)
985 goto Failure;
986
987 /* Relocate the image, if it needs it */
988 if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
989 {
990 WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase);
991 Status = LdrRelocateImageWithBias(PhysicalBase,
992 (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
993 "FreeLdr",
994 ESUCCESS,
995 ESUCCESS, /* In case of conflict still return success */
996 ENOEXEC);
997 if (Status != ESUCCESS)
998 goto Failure;
999 }
1000
1001 /* Fill output parameters */
1002 *ImageBasePA = PhysicalBase;
1003
1004 TRACE("PeLdrLoadImage() done, PA = %p\n", *ImageBasePA);
1005 return TRUE;
1006
1007Failure:
1008 /* Cleanup and bail out */
1009 MmFreeMemory(PhysicalBase);
1010 return FALSE;
1011}
PCWSTR FilePath
#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:354
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 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
DWORD PointerToRawData
Definition: pedump.c:290
union _IMAGE_SECTION_HEADER::@1556 Misc
static COORD Position
Definition: mouse.c:34
char * PSTR
Definition: typedefs.h:51
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
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 136 of file peloader.c.

146{
147 ULONG Ordinal;
148 PULONG NameTable, FunctionTable;
149 PUSHORT OrdinalTable;
150 LONG High, Low, Middle, Result;
151 ULONG Hint;
152 PIMAGE_IMPORT_BY_NAME ImportData;
153 PCHAR ExportName, ForwarderName;
155
156 //TRACE("PeLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
157 // DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards);
158
159 /* Check passed DllBase param */
160 if (DllBase == NULL)
161 {
162 WARN("DllBase == NULL!\n");
163 return FALSE;
164 }
165
166 /* Convert all non-critical pointers to PA from VA */
167 ThunkData = VaToPa(ThunkData);
168
169 /* Is the reference by ordinal? */
170 if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
171 {
172 /* Yes, calculate the ordinal */
173 Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base);
174 //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
175 }
176 else
177 {
178 /* It's reference by name, we have to look it up in the export directory */
179 if (!ProcessForwards)
180 {
181 /* AddressOfData in thunk entry will become a virtual address (from relative) */
182 //TRACE("PeLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData);
183 ThunkData->u1.AddressOfData =
184 (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData);
185 //TRACE("PeLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData);
186 }
187
188 /* Get the import name */
189 ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData);
190
191 /* Get pointers to Name and Ordinal tables (RVA -> VA) */
192 NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
193 OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
194
195 //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
196 // NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals);
197
198 /* Get the hint, convert it to a physical pointer */
199 Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
200 //TRACE("HintIndex %d\n", Hint);
201
202 /* Get the export name from the hint */
203 ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));
204
205 /* If Hint is less than total number of entries in the export directory,
206 and import name == export name, then we can just get it from the OrdinalTable */
207 if ((Hint < ExportDirectory->NumberOfNames) &&
208 (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
209 {
210 Ordinal = OrdinalTable[Hint];
211 //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
212 }
213 else
214 {
215 /* It's not the easy way, we have to lookup import name in the name table.
216 Let's use a binary search for this task. */
217
218 //TRACE("PeLdrpBindImportName() looking up the import name using binary search...\n");
219
220 /* Low boundary is set to 0, and high boundary to the maximum index */
221 Low = 0;
222 High = ExportDirectory->NumberOfNames - 1;
223
224 /* Perform a binary-search loop */
225 while (High >= Low)
226 {
227 /* Divide by 2 by shifting to the right once */
228 Middle = (Low + High) / 2;
229
230 /* Get the name from the name table */
231 ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));
232
233 /* Compare the names */
234 Result = strcmp(ExportName, (PCHAR)ImportData->Name);
235
236 // TRACE("Binary search: comparing Import '__', Export '%s'\n",
237 // VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),
238 // (PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));
239
240 // TRACE("TE->u1.AOD %p, fulladdr %p\n",
241 // ThunkData->u1.AddressOfData,
242 // ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );
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
272 //TRACE("PeLdrpBindImportName() found Ordinal %d\n", Ordinal);
273 }
274 }
275
276 /* Check ordinal number for validity! */
277 if (Ordinal >= ExportDirectory->NumberOfFunctions)
278 {
279 ERR("Ordinal number is invalid!\n");
280 return FALSE;
281 }
282
283 /* Get a pointer to the function table */
284 FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));
285
286 /* Save a pointer to the function */
287 ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);
288
289 /* Is it a forwarder? (function pointer is within the export directory) */
290 ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
291 if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
292 ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
293 {
294 PLDR_DATA_TABLE_ENTRY DataTableEntry;
295 PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
296 ULONG RefExportSize;
297 CHAR ForwardDllName[256];
298
299 TRACE("PeLdrpBindImportName(): ForwarderName %s\n", ForwarderName);
300
301 /* Save the name of the forward dll */
302 RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));
303
304 /* Strip out the symbol name */
305 *strrchr(ForwardDllName, '.') = ANSI_NULL;
306
307 /* Check if the target image is already loaded */
308 if (!PeLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry))
309 {
310 /* Check if the forward dll name has an extension */
311 if (strchr(ForwardDllName, '.') == NULL)
312 {
313 /* Name does not have an extension, append '.dll' */
314 RtlStringCbCatA(ForwardDllName, sizeof(ForwardDllName), ".dll");
315 }
316
317 /* Now let's try to load it! */
319 DirectoryPath,
320 ForwardDllName,
321 Parent,
322 &DataTableEntry);
323 if (!Success)
324 {
325 ERR("PeLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n");
326 return Success;
327 }
328 }
329
330 /* Get pointer to the export directory of loaded DLL */
331 RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
333 TRUE,
335 &RefExportSize);
336
337 /* Fail if it's NULL */
338 if (RefExportDirectory)
339 {
340 UCHAR Buffer[128];
341 IMAGE_THUNK_DATA RefThunkData;
342 PIMAGE_IMPORT_BY_NAME ImportByName;
343 PCHAR ImportName;
344
345 /* Get pointer to the import name */
346 ImportName = strrchr(ForwarderName, '.') + 1;
347
348 /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
349 ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
350
351 /* Fill the name with the import name */
352 RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
353
354 /* Set Hint to 0 */
355 ImportByName->Hint = 0;
356
357 /* And finally point ThunkData's AddressOfData to that structure */
358 RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;
359
360 /* And recursively call ourselves */
362 DataTableEntry->DllBase,
363 ImageBase,
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}
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
@ 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:561
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:136
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
_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::@2134 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:409
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 77 of file peloader.c.

80{
83
84 /* First obvious check: for length of two names */
85 Length = strlen(DllName);
86
87#if DBG
88 {
89 UNICODE_STRING UnicodeNamePA;
90 UnicodeNamePA.Length = UnicodeName->Length;
91 UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
92 UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
93 TRACE("PeLdrpCompareDllName: %s and %wZ, Length = %d "
94 "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length);
95 }
96#endif
97
98 if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
99 return FALSE;
100
101 /* Store pointer to unicode string's buffer */
102 Buffer = VaToPa(UnicodeName->Buffer);
103
104 /* Loop character by character */
105 for (i = 0; i < Length; i++)
106 {
107 /* Compare two characters, uppercasing them */
108 if (toupper(*DllName) != toupper((CHAR)*Buffer))
109 return FALSE;
110
111 /* Move to the next character */
112 DllName++;
113 Buffer++;
114 }
115
116 /* Check, if strings either fully match, or match till the "." (w/o extension) */
117 if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
118 {
119 /* Yes they do */
120 return TRUE;
121 }
122
123 /* Strings don't match, return FALSE */
124 return FALSE;
125}
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().

◆ PeLdrpFetchAddressOfSecurityCookie()

static PVOID PeLdrpFetchAddressOfSecurityCookie ( PVOID  BaseAddress,
ULONG  SizeOfImage 
)
static

Definition at line 41 of file peloader.c.

42{
44 ULONG DirSize;
46
47 /* Get the pointer to the config directory */
49 TRUE,
51 &DirSize);
52
53 /* Check for sanity */
54 if (!ConfigDir ||
56 {
57 /* Invalid directory*/
58 return NULL;
59 }
60
61 /* Now get the cookie */
63
64 /* Check this cookie */
65 if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
66 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage - sizeof(*Cookie))
67 {
68 Cookie = NULL;
69 }
70
71 /* Return validated security cookie */
72 return Cookie;
73}
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672

Referenced by PeLdrInitSecurityCookie().

◆ 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 389 of file peloader.c.

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 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 VaToPa((*DataTableEntry)->BaseDllName.Buffer));
439 Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
440 if (!Success)
441 {
442 /* Cleanup and bail out */
443 ERR("PeLdrScanImportDescriptorTable() failed\n");
444 PeLdrFreeDataTableEntry(*DataTableEntry);
445 MmFreeMemory(BasePA);
446 return Success;
447 }
448
449 return TRUE;
450}
#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:605
VOID PeLdrFreeDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY Entry)
Definition: peloader.c:798
PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback
Definition: peloader.c:28
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:681
PVOID PeLdrInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: peloader.c:522
BOOLEAN PeLdrLoadImage(_In_ PCSTR FilePath, _In_ TYPE_OF_MEMORY MemoryType, _Out_ PVOID *ImageBasePA)
Loads the specified image from the file.
Definition: peloader.c:823
@ LoaderBootDriver
Definition: arc.h:185

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 453 of file peloader.c.

460{
461 PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
463 ULONG ExportSize;
464
465 TRACE("PeLdrpScanImportAddressTable(): DllBase 0x%X, "
466 "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
467
468 /* Obtain the export table from the DLL's base */
469 if (DllBase == NULL)
470 {
471 ERR("Error, DllBase == NULL!\n");
472 return FALSE;
473 }
474 else
475 {
476 ExportDirectory =
478 TRUE,
480 &ExportSize);
481 }
482
483 TRACE("PeLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory);
484
485 /* If pointer to Export Directory is */
486 if (ExportDirectory == NULL)
487 {
488 ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
489 return FALSE;
490 }
491
492 /* Go through each entry in the thunk table and bind it */
493 while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
494 {
495 /* Bind it */
497 DllBase,
498 ImageBase,
499 ThunkData,
500 ExportDirectory,
501 ExportSize,
502 FALSE,
503 DirectoryPath,
504 Parent);
505
506 /* Move to the next entry */
507 ThunkData++;
508
509 /* Return error if binding was unsuccessful */
510 if (!Success)
511 return Success;
512 }
513
514 /* Return success */
515 return TRUE;
516}
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 605 of file peloader.c.

609{
610 PLDR_DATA_TABLE_ENTRY DataTableEntry;
611 PIMAGE_IMPORT_DESCRIPTOR ImportTable;
612 ULONG ImportTableSize;
613 PCH ImportName;
615
616 /* Get a pointer to the import table of this image */
617 ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
618 TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
619
620#if DBG
621 {
622 UNICODE_STRING BaseName;
623 BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
624 BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
625 BaseName.Length = ScanDTE->BaseDllName.Length;
626 TRACE("PeLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
627 &BaseName, ImportTable);
628 }
629#endif
630
631 /* If image doesn't have any import directory - just return success */
632 if (ImportTable == NULL)
633 return TRUE;
634
635 /* Loop through all entries */
636 for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
637 {
638 /* Get pointer to the name */
639 ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
640 TRACE("PeLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);
641
642 /* In case we get a reference to ourselves - just skip it */
643 if (PeLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
644 continue;
645
646 /* Load the DLL if it is not already loaded */
647 if (!PeLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
648 {
650 DirectoryPath,
651 ImportName,
652 &ScanDTE->InLoadOrderLinks,
653 &DataTableEntry);
654 if (!Success)
655 {
656 ERR("PeLdrpLoadAndScanReferencedDll() failed\n");
657 return Success;
658 }
659 }
660
661 /* Scan its import address table */
663 DataTableEntry->DllBase,
664 ScanDTE->DllBase,
665 (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
666 DirectoryPath,
667 &ScanDTE->InLoadOrderLinks);
668
669 if (!Success)
670 {
671 ERR("PeLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
672 ImportName, DirectoryPath);
673 return Success;
674 }
675 }
676
677 return TRUE;
678}
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:453

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().