ReactOS 0.4.16-dev-816-g135a9a9
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 709 of file peloader.c.

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

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

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

829{
830 // ASSERT(ModuleListHead);
831 ASSERT(Entry);
832
833 RemoveEntryList(&Entry->InLoadOrderLinks);
834 FrLdrHeapFree(VaToPa(Entry->FullDllName.Buffer), TAG_WLDR_NAME);
835 FrLdrHeapFree(VaToPa(Entry->BaseDllName.Buffer), TAG_WLDR_NAME);
837}
#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 LoadWindowsCore(), PeLdrLoadBootImage(), PeLdrpLoadAndScanReferencedDll(), and WinLdrLoadDeviceDriver().

◆ PeLdrInitializeModuleList()

BOOLEAN PeLdrInitializeModuleList ( VOID  )

Definition at line 525 of file peloader.c.

526{
527 PLDR_DATA_TABLE_ENTRY FreeldrDTE;
528
530
531 /* Allocate a data table entry for freeldr.sys */
533 "freeldr.sys",
534 "freeldr.sys",
536 &FreeldrDTE))
537 {
538 /* Cleanup and bail out */
539 ERR("Failed to allocate DTE for freeldr\n");
540 return FALSE;
541 }
542
543 return TRUE;
544}
#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:709
LIST_ENTRY FrLdrModuleList
Definition: peloader.c:28

Referenced by BootMain().

◆ PeLdrInitSecurityCookie()

PVOID PeLdrInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 547 of file peloader.c.

548{
550 ULONG_PTR NewCookie;
551
552 /* Fetch address of the cookie */
554
555 if (!Cookie)
556 return NULL;
557
558 /* Check if it's a default one */
560 (*Cookie == 0))
561 {
562 /* Generate new cookie using cookie address and time as seed */
564#ifdef _WIN64
565 /* Some images expect first 16 bits to be kept clean (like in default cookie) */
566 if (NewCookie > COOKIE_MAX)
567 {
568 NewCookie >>= 16;
569 }
570#endif
571 /* If the result is 0 or the same as we got, just add one to the default value */
572 if ((NewCookie == 0) || (NewCookie == *Cookie))
573 {
574 NewCookie = DEFAULT_SECURITY_COOKIE + 1;
575 }
576
577 /* Set the new cookie value */
578 *Cookie = NewCookie;
579 }
580
581 return Cookie;
582}
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 1052 of file peloader.c.

1057{
1059
1060 /* Load the image as a bootloader image */
1063 ImageBase,
1064 FALSE);
1065 if (!Success)
1066 {
1067 WARN("Failed to load boot image '%s'\n", FilePath);
1068 return FALSE;
1069 }
1070
1071 /* Allocate a DTE */
1073 BaseDllName,
1074 FilePath,
1075 *ImageBase,
1076 DataTableEntry);
1077 if (!Success)
1078 {
1079 /* Cleanup and bail out */
1080 ERR("Failed to allocate DTE for '%s'\n", FilePath);
1081 MmFreeMemory(*ImageBase);
1082 return FALSE;
1083 }
1084
1085 /* Resolve imports */
1087 if (!Success)
1088 {
1089 /* Cleanup and bail out */
1090 ERR("Failed to resolve imports for '%s'\n", FilePath);
1091 PeLdrFreeDataTableEntry(*DataTableEntry);
1092 MmFreeMemory(*ImageBase);
1093 return FALSE;
1094 }
1095
1096 return TRUE;
1097}
PCWSTR FilePath
unsigned char BOOLEAN
#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:629
VOID PeLdrFreeDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY Entry)
Definition: peloader.c:826
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:851
@ LoaderLoadedProgram
Definition: arc.h:178

Referenced by LoadBootDeviceDriver(), and LoadRosload().

◆ PeLdrLoadImage()

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

Definition at line 1043 of file peloader.c.

1047{
1048 return PeLdrLoadImageEx(FilePath, MemoryType, ImageBasePA, TRUE);
1049}

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

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

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

Definition at line 79 of file peloader.c.

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

44{
46 ULONG DirSize;
48
49 /* Get the pointer to the config directory */
51 TRUE,
53 &DirSize);
54
55 /* Check for sanity */
56 if (!ConfigDir ||
58 {
59 /* Invalid directory*/
60 return NULL;
61 }
62
63 /* Now get the cookie */
65
66 /* Check this cookie */
67 if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
68 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage - sizeof(*Cookie))
69 {
70 Cookie = NULL;
71 }
72
73 /* Return validated security cookie */
74 return Cookie;
75}
#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:680

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 PaToVa(BasePA),
422 DataTableEntry);
423 if (!Success)
424 {
425 /* Cleanup and bail out */
426 ERR("PeLdrAllocateDataTableEntry('%s') failed\n", FullDllName);
427 MmFreeMemory(BasePA);
428 return Success;
429 }
430
431 /* Init security cookie */
432 PeLdrInitSecurityCookie(*DataTableEntry);
433
434 (*DataTableEntry)->Flags |= LDRP_DRIVER_DEPENDENT_DLL;
435
436 /* Scan its dependencies too */
437 TRACE("PeLdrScanImportDescriptorTable() calling ourselves for '%.*S'\n",
438 (*DataTableEntry)->BaseDllName.Length / sizeof(WCHAR),
439 VaToPa((*DataTableEntry)->BaseDllName.Buffer));
440 Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
441 if (!Success)
442 {
443 /* Cleanup and bail out */
444 ERR("PeLdrScanImportDescriptorTable() failed\n");
445 PeLdrFreeDataTableEntry(*DataTableEntry);
446 MmFreeMemory(BasePA);
447 return Success;
448 }
449
450 return TRUE;
451}
#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:547
BOOLEAN PeLdrLoadImage(_In_ PCSTR FilePath, _In_ TYPE_OF_MEMORY MemoryType, _Out_ PVOID *ImageBasePA)
Definition: peloader.c:1043
@ LoaderBootDriver
Definition: arc.h:185

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

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

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

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