ReactOS 0.4.17-dev-116-ga4b6fe9
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_ PCSTR DllName, _In_ PCUNICODE_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 (_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)
 
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)
 
BOOLEAN PeLdrInitializeModuleList (VOID)
 
PVOID PeLdrInitSecurityCookie (PLDR_DATA_TABLE_ENTRY LdrEntry)
 
BOOLEAN PeLdrCheckForLoadedDll (_Inout_ PLIST_ENTRY ModuleListHead, _In_ PCSTR 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 BaseVA, OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
 
VOID PeLdrFreeDataTableEntry (_In_ PLDR_DATA_TABLE_ENTRY Entry)
 
BOOLEAN PeLdrLoadImageEx (_In_ PCSTR FilePath, _In_ TYPE_OF_MEMORY MemoryType, _Out_ PVOID *ImageBasePA, _In_ BOOLEAN KernelMapping)
 Loads the specified image from the file.
 
BOOLEAN PeLdrLoadImage (_In_ PCSTR FilePath, _In_ TYPE_OF_MEMORY MemoryType, _Out_ PVOID *ImageBasePA)
 
BOOLEAN PeLdrLoadBootImage (_In_ PCSTR FilePath, _In_ PCSTR BaseDllName, _Out_ PVOID *ImageBase, _Out_ PLDR_DATA_TABLE_ENTRY *DataTableEntry)
 

Variables

LIST_ENTRY FrLdrModuleList
 
PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL
 

Macro Definition Documentation

◆ DEFAULT_SECURITY_COOKIE

#define DEFAULT_SECURITY_COOKIE   0xBB40E64E

Definition at line 36 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  BaseVA,
OUT PLDR_DATA_TABLE_ENTRY NewEntry 
)

Definition at line 706 of file peloader.c.

712{
713 PVOID BasePA = VaToPa(BaseVA);
714 PWSTR BaseDllNameBuffer, Buffer;
715 PLDR_DATA_TABLE_ENTRY DataTableEntry;
716 PIMAGE_NT_HEADERS NtHeaders;
718
719 TRACE("PeLdrAllocateDataTableEntry('%s', '%s', %p)\n",
720 BaseDllName, FullDllName, BasePA);
721
722 /* Allocate memory for a data table entry, zero-initialize it */
725 if (DataTableEntry == NULL)
726 return FALSE;
727
728 /* Get NT headers from the image */
729 NtHeaders = RtlImageNtHeader(BasePA);
730
731 /* Initialize corresponding fields of DTE based on NT headers value */
732 RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
733 DataTableEntry->DllBase = BaseVA;
734 DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
735 DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
736 DataTableEntry->SectionPointer = 0;
737 DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
738
739 /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
740 by simple conversion - copying each character */
741 Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
743 if (Buffer == NULL)
744 {
745 FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
746 return FALSE;
747 }
748
749 /* Save Buffer, in case of later failure */
750 BaseDllNameBuffer = Buffer;
751
752 DataTableEntry->BaseDllName.Length = Length;
753 DataTableEntry->BaseDllName.MaximumLength = Length;
754 DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
755
757 Length /= sizeof(WCHAR);
758 while (Length--)
759 {
760 *Buffer++ = *BaseDllName++;
761 }
762
763 /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
764 using the same method */
765 Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
767 if (Buffer == NULL)
768 {
769 FrLdrHeapFree(BaseDllNameBuffer, TAG_WLDR_NAME);
770 FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
771 return FALSE;
772 }
773
774 DataTableEntry->FullDllName.Length = Length;
775 DataTableEntry->FullDllName.MaximumLength = Length;
776 DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
777
779 Length /= sizeof(WCHAR);
780 while (Length--)
781 {
782 *Buffer++ = *FullDllName++;
783 }
784
785 /* Initialize what's left - LoadCount which is 1, and set Flags so that
786 we know this entry is processed */
787 DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
788 DataTableEntry->LoadCount = 1;
789
790 /* Honour the FORCE_INTEGRITY flag */
792 {
793 /*
794 * On Vista and above, the LDRP_IMAGE_INTEGRITY_FORCED flag must be set
795 * if IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY is set in the image header.
796 * This is done after the image has been loaded and the digital signature
797 * check has passed successfully. (We do not do it yet!)
798 *
799 * Several OS functionality depend on the presence of this flag.
800 * For example, when using Object-Manager callbacks the latter will call
801 * MmVerifyCallbackFunction() to verify whether the flag is present.
802 * If not callbacks will not work.
803 * (See Windows Internals Part 1, 6th edition, p. 176.)
804 */
805 DataTableEntry->Flags |= LDRP_IMAGE_INTEGRITY_FORCED;
806 }
807
808 /* Insert this DTE to a list in the LPB */
810 TRACE("Inserting DTE %p, name='%.*S' DllBase=%p\n", DataTableEntry,
811 DataTableEntry->BaseDllName.Length / sizeof(WCHAR),
812 VaToPa(DataTableEntry->BaseDllName.Buffer),
813 DataTableEntry->DllBase);
814
815 /* Save pointer to a newly allocated and initialized entry */
816 *NewEntry = DataTableEntry;
817
818 /* Return success */
819 return TRUE;
820}
VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: heap.c:539
PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: heap.c:533
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
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
#define InsertTailList(ListHead, Entry)
#define RVA(m, b)
Definition: freeldr.h:35
#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:45
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:48
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:264
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY
Definition: ntimage.h:456
short WCHAR
Definition: pedump.c:58
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:147
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:142
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:149
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

Referenced by LoadModule(), PeLdrInitializeModuleList(), PeLdrLoadBootImage(), PeLdrpLoadAndScanReferencedDll(), and WinLdrLoadDeviceDriver().

◆ PeLdrCheckForLoadedDll()

BOOLEAN PeLdrCheckForLoadedDll ( _Inout_ PLIST_ENTRY  ModuleListHead,
_In_ PCSTR  DllName,
_Out_ PLDR_DATA_TABLE_ENTRY LoadedEntry 
)

Definition at line 581 of file peloader.c.

585{
586 PLIST_ENTRY ModuleEntry;
587 PLDR_DATA_TABLE_ENTRY DataTableEntry;
588
589 TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName);
590
591 /* Go through each entry in the LoadOrderList and
592 * compare the module's name with the given name */
593 for (ModuleEntry = ModuleListHead->Flink;
594 ModuleEntry != ModuleListHead;
595 ModuleEntry = ModuleEntry->Flink)
596 {
597 /* Get a pointer to the current DTE */
598 DataTableEntry = CONTAINING_RECORD(ModuleEntry,
600 InLoadOrderLinks);
601
602 TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, Base %p, Name '%.*S'\n",
603 DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
604 DataTableEntry->BaseDllName.Length / sizeof(WCHAR),
605 VaToPa(DataTableEntry->BaseDllName.Buffer));
606
607 /* Compare names */
608 if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
609 {
610 /* Found it, return a pointer to the loaded module's
611 * DTE to the caller and increase its load count */
612 *LoadedEntry = DataTableEntry;
613 DataTableEntry->LoadCount++;
614 TRACE("PeLdrCheckForLoadedDll: LoadedEntry 0x%p\n", DataTableEntry);
615 return TRUE;
616 }
617 }
618
619 /* Nothing found */
620 return FALSE;
621}
static BOOLEAN PeLdrpCompareDllName(_In_ PCSTR DllName, _In_ PCUNICODE_STRING UnicodeName)
Definition: peloader.c:78
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 823 of file peloader.c.

826{
827 // ASSERT(ModuleListHead);
828 ASSERT(Entry);
829
830 RemoveEntryList(&Entry->InLoadOrderLinks);
831 FrLdrHeapFree(VaToPa(Entry->FullDllName.Buffer), TAG_WLDR_NAME);
832 FrLdrHeapFree(VaToPa(Entry->BaseDllName.Buffer), TAG_WLDR_NAME);
834}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ASSERT(a)
Definition: mode.c:44
Entry
Definition: section.c:5216

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

◆ PeLdrInitializeModuleList()

BOOLEAN PeLdrInitializeModuleList ( VOID  )

Definition at line 522 of file peloader.c.

523{
524 PLDR_DATA_TABLE_ENTRY FreeldrDTE;
525
527
528 /* Allocate a data table entry for freeldr.sys */
530 "freeldr.sys",
531 "freeldr.sys",
533 &FreeldrDTE))
534 {
535 /* Cleanup and bail out */
536 ERR("Failed to allocate DTE for freeldr\n");
537 return FALSE;
538 }
539
540 return TRUE;
541}
#define ERR(fmt,...)
Definition: precomp.h:57
#define __ImageBase
Definition: crt_handler.c:22
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
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:706
LIST_ENTRY FrLdrModuleList
Definition: peloader.c:28

Referenced by BootMain(), and EfiEntry().

◆ PeLdrInitSecurityCookie()

PVOID PeLdrInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 544 of file peloader.c.

545{
547 ULONG_PTR NewCookie;
548
549 /* Fetch address of the cookie */
551 if (!Cookie)
552 return NULL;
553
554 /* Check if it's a default one */
555 if ((*Cookie == DEFAULT_SECURITY_COOKIE) || (*Cookie == 0))
556 {
557 /* Generate new cookie using cookie address and time as seed */
559#ifdef _WIN64
560 /* Some images expect first 16 bits to be kept clean (like in default cookie) */
561 if (NewCookie > COOKIE_MAX)
562 {
563 NewCookie >>= 16;
564 }
565#endif
566 /* If the result is 0 or the same as we got, just add one to the default value */
567 if ((NewCookie == 0) || (NewCookie == *Cookie))
568 {
569 NewCookie = DEFAULT_SECURITY_COOKIE + 1;
570 }
571
572 /* Set the new cookie value */
573 *Cookie = NewCookie;
574 }
575
576 return Cookie;
577}
ULONG ArcGetRelativeTime(VOID)
Definition: arcemul.c:33
#define ULONG_PTR
Definition: config.h:101
#define DEFAULT_SECURITY_COOKIE
Definition: peloader.c:36
static PVOID PeLdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: peloader.c:43
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().

◆ PeLdrLoadBootImage()

BOOLEAN PeLdrLoadBootImage ( _In_ PCSTR  FilePath,
_In_ PCSTR  BaseDllName,
_Out_ PVOID ImageBase,
_Out_ PLDR_DATA_TABLE_ENTRY DataTableEntry 
)

Definition at line 1047 of file peloader.c.

1052{
1054
1055 /* Load the image as a bootloader image */
1058 ImageBase,
1059 FALSE);
1060 if (!Success)
1061 {
1062 WARN("Failed to load boot image '%s'\n", FilePath);
1063 return FALSE;
1064 }
1065
1066 /* Allocate a DTE */
1068 BaseDllName,
1069 FilePath,
1070 *ImageBase,
1071 DataTableEntry);
1072 if (!Success)
1073 {
1074 /* Cleanup and bail out */
1075 ERR("Failed to allocate DTE for '%s'\n", FilePath);
1076 MmFreeMemory(*ImageBase);
1077 return FALSE;
1078 }
1079
1080 /* Resolve imports */
1082 if (!Success)
1083 {
1084 /* Cleanup and bail out */
1085 ERR("Failed to resolve imports for '%s'\n", FilePath);
1086 PeLdrFreeDataTableEntry(*DataTableEntry);
1087 MmFreeMemory(*ImageBase);
1088 return FALSE;
1089 }
1090
1091 return TRUE;
1092}
PCWSTR FilePath
unsigned char BOOLEAN
Definition: actypes.h:127
#define WARN(fmt,...)
Definition: precomp.h:61
VOID MmFreeMemory(PVOID MemoryPointer)
Definition: mm.c:215
@ Success
Definition: eventcreate.c:712
BOOLEAN PeLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH DirectoryPath, IN PLDR_DATA_TABLE_ENTRY ScanDTE)
Definition: peloader.c:624
VOID PeLdrFreeDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY Entry)
Definition: peloader.c:823
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:848
@ LoaderLoadedProgram
Definition: arc.h:297

Referenced by LoadBootDeviceDriver(), and LoadRosload().

◆ PeLdrLoadImage()

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

Definition at line 1038 of file peloader.c.

1042{
1043 return PeLdrLoadImageEx(FilePath, MemoryType, ImageBasePA, TRUE);
1044}

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

◆ PeLdrLoadImageEx()

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

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

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

Referenced by PeLdrLoadBootImage(), and PeLdrLoadImage().

◆ PeLdrpBindImportName()

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

Definition at line 137 of file peloader.c.

148{
149 ULONG Ordinal;
150 PULONG NameTable, FunctionTable;
151 PUSHORT OrdinalTable;
152 LONG High, Low, Middle, Result;
153 ULONG Hint;
154 PIMAGE_IMPORT_BY_NAME ImportData;
155 PCHAR ExportName, ForwarderName;
157
158 //TRACE("PeLdrpBindImportName(): "
159 // "DllBase 0x%p, ImageBase 0x%p, ThunkName 0x%p, ThunkData 0x%p, ExportDirectory 0x%p, ExportSize %d, ProcessForwards 0x%X\n",
160 // DllBase, ImageBase, ThunkName, ThunkData, ExportDirectory, ExportSize, ProcessForwards);
161
162 /* Check passed DllBase */
163 if (!DllBase)
164 {
165 WARN("DllBase == NULL\n");
166 return FALSE;
167 }
168
169 /* Convert all non-critical pointers to PA from VA */
170 ThunkName = VaToPa(ThunkName);
171 ThunkData = VaToPa(ThunkData);
172
173 /* Is the reference by ordinal? */
174 if (IMAGE_SNAP_BY_ORDINAL(ThunkName->u1.Ordinal) && !ProcessForwards)
175 {
176 /* Yes, calculate the ordinal */
177 Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkName->u1.Ordinal) - (UINT32)ExportDirectory->Base);
178 //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
179 }
180 else
181 {
182 /* It's reference by name, we have to look it up in the export directory */
183 if (!ProcessForwards)
184 {
185 /* AddressOfData in thunk entry will become a virtual address (from relative) */
186 //TRACE("PeLdrpBindImportName(): ThunkName->u1.AOD was %p\n", ThunkName->u1.AddressOfData);
187 ThunkName->u1.AddressOfData =
188 (ULONG_PTR)RVA(ImageBase, ThunkName->u1.AddressOfData);
189 //TRACE("PeLdrpBindImportName(): ThunkName->u1.AOD became %p\n", ThunkName->u1.AddressOfData);
190 }
191
192 /* Get the import name, convert it to a physical pointer */
193 ImportData = VaToPa((PVOID)ThunkName->u1.AddressOfData);
194
195 /* Get pointers to Name and Ordinal tables (RVA -> VA) */
196 NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
197 OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
198
199 //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
200 // NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals);
201
202 /* Get the hint */
203 Hint = ImportData->Hint;
204 //TRACE("HintIndex %d\n", Hint);
205
206 /* Get the export name from the hint */
207 ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));
208
209 /* If Hint is less than total number of entries in the export directory,
210 and import name == export name, then we can just get it from the OrdinalTable */
211 if ((Hint < ExportDirectory->NumberOfNames) &&
212 (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
213 {
214 Ordinal = OrdinalTable[Hint];
215 //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
216 }
217 else
218 {
219 /* It's not the easy way, we have to lookup import name in the name table.
220 Let's use a binary search for this task. */
221
222 //TRACE("PeLdrpBindImportName() looking up the import name using binary search...\n");
223
224 /* Low boundary is set to 0, and high boundary to the maximum index */
225 Low = 0;
226 High = ExportDirectory->NumberOfNames - 1;
227
228 /* Perform a binary-search loop */
229 while (High >= Low)
230 {
231 /* Divide by 2 by shifting to the right once */
232 Middle = (Low + High) / 2;
233
234 /* Get the name from the name table */
235 ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));
236
237 /* Compare the names */
238 Result = strcmp(ExportName, (PCHAR)ImportData->Name);
239
240 // TRACE("Binary search: comparing Import '%s', Export '%s'\n",
241 // (PCHAR)ImportData->Name, ExportName);
242
243 /* Depending on result of strcmp, perform different actions */
244 if (Result > 0)
245 {
246 /* Adjust top boundary */
247 High = Middle - 1;
248 }
249 else if (Result < 0)
250 {
251 /* Adjust bottom boundary */
252 Low = Middle + 1;
253 }
254 else
255 {
256 /* Yay, found it! */
257 break;
258 }
259 }
260
261 /* If high boundary is less than low boundary, then no result found */
262 if (High < Low)
263 {
264 ERR("Did not find export '%s'!\n", (PCHAR)ImportData->Name);
265 return FALSE;
266 }
267
268 /* Everything alright, get the ordinal */
269 Ordinal = OrdinalTable[Middle];
270 //TRACE("PeLdrpBindImportName() found Ordinal %d\n", Ordinal);
271 }
272 }
273
274 /* Check ordinal number for validity! */
275 if (Ordinal >= ExportDirectory->NumberOfFunctions)
276 {
277 ERR("Ordinal number is invalid!\n");
278 return FALSE;
279 }
280
281 /* Get a pointer to the function table */
282 FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));
283
284 /* Save a pointer to the function */
285 ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);
286
287 /* Is it a forwarder? (function pointer is within the export directory) */
288 ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
289 if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
290 ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
291 {
292 PLDR_DATA_TABLE_ENTRY DataTableEntry;
293 PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
294 ULONG RefExportSize;
295 CHAR ForwardDllName[256];
296
297 TRACE("PeLdrpBindImportName(): ForwarderName %s\n", ForwarderName);
298
299 /* Save the name of the forward dll */
300 RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));
301
302 /* Strip out the symbol name */
303 *strrchr(ForwardDllName, '.') = ANSI_NULL;
304
305 /* Check if the target image is already loaded */
306 if (!PeLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry))
307 {
308 /* Check if the forward dll name has an extension */
309 if (strchr(ForwardDllName, '.') == NULL)
310 {
311 /* Name does not have an extension, append '.dll' */
312 RtlStringCbCatA(ForwardDllName, sizeof(ForwardDllName), ".dll");
313 }
314
315 /* Now let's try to load it! */
317 DirectoryPath,
318 ForwardDllName,
319 Parent,
320 &DataTableEntry);
321 if (!Success)
322 {
323 ERR("PeLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n");
324 return Success;
325 }
326 }
327
328 /* Get pointer to the export directory of loaded DLL */
329 RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
331 TRUE,
333 &RefExportSize);
334 if (RefExportDirectory)
335 {
336 UCHAR Buffer[128];
337 IMAGE_THUNK_DATA RefThunkData;
338 PIMAGE_IMPORT_BY_NAME ImportByName;
339 PCHAR ImportName;
340
341 /* Get pointer to the import name */
342 ImportName = strrchr(ForwarderName, '.') + 1;
343
344 /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
345 ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
346
347 /* Fill the name with the import name */
348 RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
349
350 /* Set Hint to 0 */
351 ImportByName->Hint = 0;
352
353 /* And finally point ThunkData's AddressOfData to that structure */
354 RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;
355
356 /* And recursively call ourselves */
358 DataTableEntry->DllBase,
359 ImageBase,
360 &RefThunkData,
361 &RefThunkData,
362 RefExportDirectory,
363 RefExportSize,
364 TRUE,
365 DirectoryPath,
366 Parent);
367
368 /* Fill out the ThunkData with data from RefThunkData */
369 ThunkData->u1 = RefThunkData.u1;
370
371 /* Return what we got from the recursive call */
372 return Success;
373 }
374 else
375 {
376 /* Fail if ExportDirectory is NULL */
377 return FALSE;
378 }
379 }
380
381 /* Success! */
382 return TRUE;
383}
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
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3286
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
#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
char CHAR
Definition: pedump.c:57
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
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:137
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:386
BOOLEAN PeLdrCheckForLoadedDll(_Inout_ PLIST_ENTRY ModuleListHead, _In_ PCSTR DllName, _Out_ PLDR_DATA_TABLE_ENTRY *LoadedEntry)
Definition: peloader.c:581
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
union _IMAGE_THUNK_DATA32::@2335 u1
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
uint32_t UINT32
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
static WLX_DISPATCH_VERSION_1_4 FunctionTable
Definition: wlx.c:747
_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

Referenced by PeLdrpBindImportName(), and PeLdrpScanImportAddressTable().

◆ PeLdrpCompareDllName()

static BOOLEAN PeLdrpCompareDllName ( _In_ PCSTR  DllName,
_In_ PCUNICODE_STRING  UnicodeName 
)
static

Definition at line 78 of file peloader.c.

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

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

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

392{
393 CHAR FullDllName[256];
395 PVOID BasePA = NULL;
396
397 /* Prepare the full path to the file to be loaded */
398 RtlStringCbCopyA(FullDllName, sizeof(FullDllName), DirectoryPath);
399 RtlStringCbCatA(FullDllName, sizeof(FullDllName), ImportName);
400
401 TRACE("Loading referenced DLL: %s\n", FullDllName);
402
405
406 /* Load the image */
408 if (!Success)
409 {
410 ERR("PeLdrLoadImage('%s') failed\n", FullDllName);
411 return Success;
412 }
413
414 /* Allocate DTE for newly loaded DLL */
416 ImportName,
418 PaToVa(BasePA),
419 DataTableEntry);
420 if (!Success)
421 {
422 /* Cleanup and bail out */
423 ERR("PeLdrAllocateDataTableEntry('%s') failed\n", FullDllName);
424 MmFreeMemory(BasePA);
425 return Success;
426 }
427
428 /* Init security cookie */
429 PeLdrInitSecurityCookie(*DataTableEntry);
430
431 (*DataTableEntry)->Flags |= LDRP_DRIVER_DEPENDENT_DLL;
432
433 /* Scan its dependencies too */
434 TRACE("PeLdrScanImportDescriptorTable() calling ourselves for '%.*S'\n",
435 (*DataTableEntry)->BaseDllName.Length / sizeof(WCHAR),
436 VaToPa((*DataTableEntry)->BaseDllName.Buffer));
437 Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
438 if (!Success)
439 {
440 /* Cleanup and bail out */
441 ERR("PeLdrScanImportDescriptorTable() failed\n");
442 PeLdrFreeDataTableEntry(*DataTableEntry);
443 MmFreeMemory(BasePA);
444 return Success;
445 }
446
447 return TRUE;
448}
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:60
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback
Definition: peloader.c:30
PVOID PeLdrInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: peloader.c:544
BOOLEAN PeLdrLoadImage(_In_ PCSTR FilePath, _In_ TYPE_OF_MEMORY MemoryType, _Out_ PVOID *ImageBasePA)
Definition: peloader.c:1038
@ LoaderBootDriver
Definition: arc.h:304

Referenced by PeLdrpBindImportName(), and PeLdrScanImportDescriptorTable().

◆ PeLdrpScanImportAddressTable()

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

Definition at line 451 of file peloader.c.

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

628{
629 PLDR_DATA_TABLE_ENTRY DataTableEntry;
630 PIMAGE_IMPORT_DESCRIPTOR ImportTable;
631 ULONG ImportTableSize;
632 PCH ImportName;
634
635 /* Get a pointer to the import table of this image */
636 ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)
637 RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
638 TRUE,
640 &ImportTableSize);
641
642#if DBG
643 {
644 UNICODE_STRING BaseName;
645 BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
646 BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
647 BaseName.Length = ScanDTE->BaseDllName.Length;
648 TRACE("PeLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%p\n",
649 &BaseName, ImportTable);
650 }
651#endif
652
653 /* If the image doesn't have any import directory, just return success */
654 if (!ImportTable)
655 return TRUE;
656
657 /* Loop through all the entries */
658 for (;(ImportTable->Name != 0) && (ImportTable->OriginalFirstThunk != 0);ImportTable++)
659 {
660 PIMAGE_THUNK_DATA ThunkName = RVA(ScanDTE->DllBase, ImportTable->OriginalFirstThunk);
661 PIMAGE_THUNK_DATA ThunkData = RVA(ScanDTE->DllBase, ImportTable->FirstThunk);
662
663 /* Get pointer to the name */
664 ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
665 TRACE("PeLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);
666
667 /* In case we get a reference to ourselves - just skip it */
668 if (PeLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
669 continue;
670
671 /* Load the DLL if it is not already loaded */
672 if (!PeLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
673 {
675 DirectoryPath,
676 ImportName,
677 &ScanDTE->InLoadOrderLinks,
678 &DataTableEntry);
679 if (!Success)
680 {
681 ERR("PeLdrpLoadAndScanReferencedDll() failed\n");
682 return Success;
683 }
684 }
685
686 /* Scan its import address table */
688 DataTableEntry->DllBase,
689 ScanDTE->DllBase,
690 ThunkName,
691 ThunkData,
692 DirectoryPath,
693 &ScanDTE->InLoadOrderLinks);
694 if (!Success)
695 {
696 ERR("PeLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
697 ImportName, DirectoryPath);
698 return Success;
699 }
700 }
701
702 return TRUE;
703}
CHAR * PCH
Definition: ntbasedef.h:403
struct _IMAGE_IMPORT_DESCRIPTOR * PIMAGE_IMPORT_DESCRIPTOR
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
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:451

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

Variable Documentation

◆ FrLdrModuleList

LIST_ENTRY FrLdrModuleList

Definition at line 28 of file peloader.c.

Referenced by PeLdrInitializeModuleList(), and PeLdrLoadBootImage().

◆ PeLdrImportDllLoadCallback

PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL

Definition at line 30 of file peloader.c.

Referenced by LoadAndBootWindowsCommon(), and PeLdrpLoadAndScanReferencedDll().