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

Go to the source code of this file.

Functions

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

Variables

PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL
 

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( PELOADER  )

◆ PeLdrAllocateDataTableEntry()

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

Definition at line 598 of file peloader.c.

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

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

◆ PeLdrCheckForLoadedDll()

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

Definition at line 478 of file peloader.c.

482 {
483  PLDR_DATA_TABLE_ENTRY DataTableEntry;
484  LIST_ENTRY *ModuleEntry;
485 
486  TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName);
487 
488  /* Just go through each entry in the LoadOrderList and compare loaded module's
489  name with a given name */
490  ModuleEntry = ModuleListHead->Flink;
491  while (ModuleEntry != ModuleListHead)
492  {
493  /* Get pointer to the current DTE */
494  DataTableEntry = CONTAINING_RECORD(ModuleEntry,
496  InLoadOrderLinks);
497 
498  TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, base %p name '%.*ws'\n",
499  DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
500  DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer));
501 
502  /* Compare names */
503  if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
504  {
505  /* Yes, found it, report pointer to the loaded module's DTE
506  to the caller and increase load count for it */
507  *LoadedEntry = DataTableEntry;
508  DataTableEntry->LoadCount++;
509  TRACE("PeLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry);
510  return TRUE;
511  }
512 
513  /* Go to the next entry */
514  ModuleEntry = ModuleEntry->Flink;
515  }
516 
517  /* Nothing found */
518  return FALSE;
519 }
#define TRUE
Definition: types.h:120
PVOID DllBase
Definition: btrfs_drv.h:1870
#define FALSE
Definition: types.h:117
PVOID EntryPoint
Definition: ntddk_ex.h:203
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
Definition: btrfs_drv.h:1866
Definition: typedefs.h:119
static BOOLEAN PeLdrpCompareDllName(IN PCH DllName, IN PUNICODE_STRING UnicodeName)
Definition: peloader.c:35
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23
USHORT LoadCount
Definition: ntddk_ex.h:208

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

◆ PeLdrFreeDataTableEntry()

VOID PeLdrFreeDataTableEntry ( _In_ PLDR_DATA_TABLE_ENTRY  Entry)

Definition at line 715 of file peloader.c.

718 {
719  // ASSERT(ModuleListHead);
720  ASSERT(Entry);
721 
722  RemoveEntryList(&Entry->InLoadOrderLinks);
723  FrLdrHeapFree(VaToPa(Entry->FullDllName.Buffer), TAG_WLDR_NAME);
724  FrLdrHeapFree(VaToPa(Entry->BaseDllName.Buffer), TAG_WLDR_NAME);
726 }
#define TAG_WLDR_DTE
Definition: winldr.h:13
FORCEINLINE VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: mm.h:181
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define TAG_WLDR_NAME
Definition: winldr.h:15
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
base of all file and directory entries
Definition: entries.h:82

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

◆ PeLdrLoadImage()

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

Definition at line 736 of file peloader.c.

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

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

◆ PeLdrpBindImportName()

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

Definition at line 94 of file peloader.c.

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

Referenced by PeLdrpScanImportAddressTable().

◆ PeLdrpCompareDllName()

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

Definition at line 35 of file peloader.c.

38 {
39  PWSTR Buffer;
40  SIZE_T i, Length;
41 
42  /* First obvious check: for length of two names */
43  Length = strlen(DllName);
44 
45 #if DBG
46  {
47  UNICODE_STRING UnicodeNamePA;
48  UnicodeNamePA.Length = UnicodeName->Length;
49  UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
50  UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
51  TRACE("PeLdrpCompareDllName: %s and %wZ, Length = %d "
52  "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length);
53  }
54 #endif
55 
56  if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
57  return FALSE;
58 
59  /* Store pointer to unicode string's buffer */
60  Buffer = VaToPa(UnicodeName->Buffer);
61 
62  /* Loop character by character */
63  for (i = 0; i < Length; i++)
64  {
65  /* Compare two characters, uppercasing them */
66  if (toupper(*DllName) != toupper((CHAR)*Buffer))
67  return FALSE;
68 
69  /* Move to the next character */
70  DllName++;
71  Buffer++;
72  }
73 
74  /* Check, if strings either fully match, or match till the "." (w/o extension) */
75  if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
76  {
77  /* Yes they do */
78  return TRUE;
79  }
80 
81  /* Strings don't match, return FALSE */
82  return FALSE;
83 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
USHORT MaximumLength
Definition: env_spec_w32.h:370
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
char CHAR
Definition: xmlstorage.h:175
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1303
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
Definition: bufpool.h:45
int toupper(int c)
Definition: utclib.c:881
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
ULONG_PTR SIZE_T
Definition: typedefs.h:80
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
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15

Referenced by PeLdrCheckForLoadedDll(), and PeLdrScanImportDescriptorTable().

◆ PeLdrpLoadAndScanReferencedDll()

static BOOLEAN PeLdrpLoadAndScanReferencedDll ( IN OUT PLIST_ENTRY  ModuleListHead,
IN PCCH  DirectoryPath,
IN PCH  ImportName,
IN PLIST_ENTRY Parent  OPTIONAL,
OUT PLDR_DATA_TABLE_ENTRY DataTableEntry 
)
static

Definition at line 347 of file peloader.c.

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

Referenced by PeLdrpBindImportName(), and PeLdrScanImportDescriptorTable().

◆ PeLdrpScanImportAddressTable()

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

Definition at line 408 of file peloader.c.

415 {
416  PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
418  ULONG ExportSize;
419 
420  TRACE("PeLdrpScanImportAddressTable(): DllBase 0x%X, "
421  "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
422 
423  /* Obtain the export table from the DLL's base */
424  if (DllBase == NULL)
425  {
426  ERR("Error, DllBase == NULL!\n");
427  return FALSE;
428  }
429  else
430  {
431  ExportDirectory =
433  TRUE,
435  &ExportSize);
436  }
437 
438  TRACE("PeLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory);
439 
440  /* If pointer to Export Directory is */
441  if (ExportDirectory == NULL)
442  {
443  ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
444  return FALSE;
445  }
446 
447  /* Go through each entry in the thunk table and bind it */
448  while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
449  {
450  /* Bind it */
452  DllBase,
453  ImageBase,
454  ThunkData,
455  ExportDirectory,
456  ExportSize,
457  FALSE,
458  DirectoryPath,
459  Parent);
460 
461  /* Move to the next entry */
462  ThunkData++;
463 
464  /* Return error if binding was unsuccessful */
465  if (!Success)
466  return Success;
467  }
468 
469  /* Return success */
470  return TRUE;
471 }
#define TRUE
Definition: types.h:120
static BOOLEAN PeLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead, IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA ThunkData, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN ProcessForwards, IN PCSTR DirectoryPath, IN PLIST_ENTRY Parent)
Definition: peloader.c:94
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:728
GLdouble u1
Definition: glext.h:8308
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define TRACE(s)
Definition: solgame.cpp:4
#define RtlImageDirectoryEntryToData
Definition: compat.h:668
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define ERR(fmt,...)
Definition: debug.h:110
struct _IMAGE_EXPORT_DIRECTORY * PIMAGE_EXPORT_DIRECTORY
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23

Referenced by PeLdrScanImportDescriptorTable().

◆ PeLdrScanImportDescriptorTable()

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

Definition at line 522 of file peloader.c.

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

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

Variable Documentation

◆ PeLdrImportDllLoadCallback

PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL

Definition at line 28 of file peloader.c.

Referenced by LoadAndBootWindowsCommon(), and PeLdrpLoadAndScanReferencedDll().