ReactOS  0.4.13-dev-1174-gdff75d7
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, 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)
 
static BOOLEAN PeLdrpScanImportAddressTable (IN OUT PLIST_ENTRY ModuleListHead, IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA ThunkData, IN PCSTR DirectoryPath)
 
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)
 
BOOLEAN PeLdrLoadImage (IN PCHAR FileName, IN TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA)
 

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

580 {
581  PVOID BaseVA = PaToVa(BasePA);
582  PWSTR Buffer;
583  PLDR_DATA_TABLE_ENTRY DataTableEntry;
584  PIMAGE_NT_HEADERS NtHeaders;
585  USHORT Length;
586 
587  TRACE("PeLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
588  BaseDllName, FullDllName, BasePA);
589 
590  /* Allocate memory for a data table entry, zero-initialize it */
592  TAG_WLDR_DTE);
593  if (DataTableEntry == NULL)
594  return FALSE;
595  RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
596 
597  /* Get NT headers from the image */
598  NtHeaders = RtlImageNtHeader(BasePA);
599 
600  /* Initialize corresponding fields of DTE based on NT headers value */
601  DataTableEntry->DllBase = BaseVA;
602  DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
603  DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
604  DataTableEntry->SectionPointer = 0;
605  DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
606 
607  /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
608  by simple conversion - copying each character */
609  Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
611  if (Buffer == NULL)
612  {
613  FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
614  return FALSE;
615  }
617 
618  DataTableEntry->BaseDllName.Length = Length;
619  DataTableEntry->BaseDllName.MaximumLength = Length;
620  DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
621  while (*BaseDllName != 0)
622  {
623  *Buffer++ = *BaseDllName++;
624  }
625 
626  /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
627  using the same method */
628  Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
630  if (Buffer == NULL)
631  {
632  FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
633  return FALSE;
634  }
636 
637  DataTableEntry->FullDllName.Length = Length;
638  DataTableEntry->FullDllName.MaximumLength = Length;
639  DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
640  while (*FullDllName != 0)
641  {
642  *Buffer++ = *FullDllName++;
643  }
644 
645  /* Initialize what's left - LoadCount which is 1, and set Flags so that
646  we know this entry is processed */
647  DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
648  DataTableEntry->LoadCount = 1;
649 
650  /* Insert this DTE to a list in the LPB */
652  TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n", DataTableEntry,
653  DataTableEntry->BaseDllName.Length / 2,
654  VaToPa(DataTableEntry->BaseDllName.Buffer),
655  DataTableEntry->DllBase);
656 
657  /* Save pointer to a newly allocated and initialized entry */
658  *NewEntry = DataTableEntry;
659 
660  /* Return success */
661  return TRUE;
662 }
#define TAG_WLDR_DTE
Definition: winldr.h:13
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:43
#define TRUE
Definition: types.h:120
FORCEINLINE VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: mm.h:170
USHORT MaximumLength
Definition: env_spec_w32.h:370
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
uint16_t * PWSTR
Definition: typedefs.h:54
ULONG SizeOfImage
Definition: ldrtypes.h:142
#define InsertTailList(ListHead, Entry)
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
PVOID DllBase
Definition: btrfs_drv.h:1784
PVOID EntryPoint
Definition: ntddk_ex.h:203
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:246
#define TAG_WLDR_NAME
Definition: winldr.h:15
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: mm.h:163
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
ULONG CheckSum
Definition: btrfs_drv.h:1790
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
struct _LDR_DATA_TABLE_ENTRY * PLDR_DATA_TABLE_ENTRY
Definition: btrfs_drv.h:1780
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:137
#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:1786
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
#define RtlImageNtHeader
Definition: compat.h:457
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
ULONG Flags
Definition: ntddk_ex.h:207
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
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 456 of file peloader.c.

460 {
461  PLDR_DATA_TABLE_ENTRY DataTableEntry;
462  LIST_ENTRY *ModuleEntry;
463 
464  TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName);
465 
466  /* Just go through each entry in the LoadOrderList and compare loaded module's
467  name with a given name */
468  ModuleEntry = ModuleListHead->Flink;
469  while (ModuleEntry != ModuleListHead)
470  {
471  /* Get pointer to the current DTE */
472  DataTableEntry = CONTAINING_RECORD(ModuleEntry,
474  InLoadOrderLinks);
475 
476  TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, base %p name '%.*ws'\n",
477  DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
478  DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer));
479 
480  /* Compare names */
481  if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
482  {
483  /* Yes, found it, report pointer to the loaded module's DTE
484  to the caller and increase load count for it */
485  *LoadedEntry = DataTableEntry;
486  DataTableEntry->LoadCount++;
487  TRACE("PeLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry);
488  return TRUE;
489  }
490 
491  /* Go to the next entry */
492  ModuleEntry = ModuleEntry->Flink;
493  }
494 
495  /* Nothing found */
496  return FALSE;
497 }
#define TRUE
Definition: types.h:120
PVOID DllBase
Definition: btrfs_drv.h:1784
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:119
#define TRACE(s)
Definition: solgame.cpp:4
Definition: btrfs_drv.h:1780
Definition: typedefs.h:117
static BOOLEAN PeLdrpCompareDllName(IN PCH DllName, IN PUNICODE_STRING UnicodeName)
Definition: peloader.c:30
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:144
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().

◆ PeLdrLoadImage()

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

Definition at line 672 of file peloader.c.

676 {
677  ULONG FileId;
678  PVOID PhysicalBase;
679  PVOID VirtualBase = NULL;
680  UCHAR HeadersBuffer[SECTOR_SIZE * 2];
681  PIMAGE_NT_HEADERS NtHeaders;
682  PIMAGE_SECTION_HEADER SectionHeader;
683  ULONG VirtualSize, SizeOfRawData, NumberOfSections;
686  ULONG i, BytesRead;
687 
688  TRACE("PeLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
689 
690  /* Open the image file */
691  Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
692  if (Status != ESUCCESS)
693  {
694  WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName, Status);
695  return FALSE;
696  }
697 
698  /* Load the first 2 sectors of the image so we can read the PE header */
699  Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
700  if (Status != ESUCCESS)
701  {
702  ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
703  UiMessageBox("Error reading from file.");
704  ArcClose(FileId);
705  return FALSE;
706  }
707 
708  /* Now read the MZ header to get the offset to the PE Header */
709  NtHeaders = RtlImageNtHeader(HeadersBuffer);
710  if (!NtHeaders)
711  {
712  ERR("No NT header found in \"%s\"\n", FileName);
713  UiMessageBox("Error: No NT header found.");
714  ArcClose(FileId);
715  return FALSE;
716  }
717 
718  /* Ensure this is executable image */
719  if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0))
720  {
721  ERR("Not an executable image \"%s\"\n", FileName);
722  UiMessageBox("Not an executable image.");
723  ArcClose(FileId);
724  return FALSE;
725  }
726 
727  /* Store number of sections to read and a pointer to the first section */
728  NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
729  SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
730 
731  /* Try to allocate this memory, if fails - allocate somewhere else */
732  PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
733  (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
734  MemoryType);
735 
736  if (PhysicalBase == NULL)
737  {
738  /* It's ok, we don't panic - let's allocate again at any other "low" place */
739  PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
740 
741  if (PhysicalBase == NULL)
742  {
743  ERR("Failed to alloc %lu bytes for image %s\n", NtHeaders->OptionalHeader.SizeOfImage, FileName);
744  UiMessageBox("Failed to alloc pages for image.");
745  ArcClose(FileId);
746  return FALSE;
747  }
748  }
749 
750  /* This is the real image base - in form of a virtual address */
751  VirtualBase = PaToVa(PhysicalBase);
752 
753  TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
754 
755  /* Set to 0 position and fully load the file image */
756  Position.QuadPart = 0;
757  Status = ArcSeek(FileId, &Position, SeekAbsolute);
758  if (Status != ESUCCESS)
759  {
760  ERR("ArcSeek(File: '%s') failed. Status: 0x%lx\n", FileName, Status);
761  UiMessageBox("Error seeking the start of a file.");
762  ArcClose(FileId);
763  return FALSE;
764  }
765 
766  Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead);
767  if (Status != ESUCCESS)
768  {
769  ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
770  UiMessageBox("Error reading headers.");
771  ArcClose(FileId);
772  return FALSE;
773  }
774 
775  /* Reload the NT Header */
776  NtHeaders = RtlImageNtHeader(PhysicalBase);
777 
778  /* Load the first section */
779  SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
780 
781  /* Fill output parameters */
782  *ImageBasePA = PhysicalBase;
783 
784  /* Walk through each section and read it (check/fix any possible
785  bad situations, if they arise) */
786  for (i = 0; i < NumberOfSections; i++)
787  {
788  VirtualSize = SectionHeader->Misc.VirtualSize;
789  SizeOfRawData = SectionHeader->SizeOfRawData;
790 
791  /* Handle a case when VirtualSize equals 0 */
792  if (VirtualSize == 0)
793  VirtualSize = SizeOfRawData;
794 
795  /* If PointerToRawData is 0, then force its size to be also 0 */
796  if (SectionHeader->PointerToRawData == 0)
797  {
798  SizeOfRawData = 0;
799  }
800  else
801  {
802  /* Cut the loaded size to the VirtualSize extents */
803  if (SizeOfRawData > VirtualSize)
804  SizeOfRawData = VirtualSize;
805  }
806 
807  /* Actually read the section (if its size is not 0) */
808  if (SizeOfRawData != 0)
809  {
810  /* Seek to the correct position */
811  Position.LowPart = SectionHeader->PointerToRawData;
812  Status = ArcSeek(FileId, &Position, SeekAbsolute);
813 
814  TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
815 
816  /* Read this section from the file, size = SizeOfRawData */
817  Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
818  if (Status != ESUCCESS)
819  {
820  ERR("PeLdrLoadImage(): Error reading section from file!\n");
821  break;
822  }
823  }
824 
825  /* Size of data is less than the virtual size - fill up the remainder with zeroes */
826  if (SizeOfRawData < VirtualSize)
827  {
828  TRACE("PeLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
829  RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
830  }
831 
832  SectionHeader++;
833  }
834 
835  /* We are done with the file - close it */
836  ArcClose(FileId);
837 
838  /* If loading failed - return right now */
839  if (Status != ESUCCESS)
840  return FALSE;
841 
842  /* Relocate the image, if it needs it */
843  if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
844  {
845  WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase);
846  return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
847  (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
848  "FreeLdr",
849  TRUE,
850  TRUE, /* in case of conflict still return success */
851  FALSE);
852  }
853 
854  TRACE("PeLdrLoadImage() done, PA = %p\n", *ImageBasePA);
855  return TRUE;
856 }
#define TRUE
Definition: types.h:120
Definition: arc.h:32
static COORD Position
Definition: mouse.c:34
unsigned char * PUCHAR
Definition: retypes.h:3
#define WARN(fmt,...)
Definition: debug.h:111
ULONG ARC_STATUS
Definition: arc.h:4
DWORD PointerToRawData
Definition: pedump.c:290
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
uint32_t ULONG_PTR
Definition: typedefs.h:63
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 IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
#define KSEG0_BASE
Definition: ketypes.h:273
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:320
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#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
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
signed char * PSTR
Definition: retypes.h:7
union _IMAGE_SECTION_HEADER::@1527 Misc
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:218
#define RtlImageNtHeader
Definition: compat.h:457
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:261
#define SECTOR_SIZE
Definition: fs.h:22
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255

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

Definition at line 88 of file peloader.c.

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

Referenced by PeLdrpScanImportAddressTable().

◆ PeLdrpCompareDllName()

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

Definition at line 30 of file peloader.c.

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

Referenced by PeLdrCheckForLoadedDll(), and PeLdrScanImportDescriptorTable().

◆ PeLdrpLoadAndScanReferencedDll()

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

Definition at line 338 of file peloader.c.

343 {
344  CHAR FullDllName[256];
346  PVOID BasePA = NULL;
347 
348  /* Prepare the full path to the file to be loaded */
349  strcpy(FullDllName, DirectoryPath);
350  strcat(FullDllName, ImportName);
351 
352  TRACE("Loading referenced DLL: %s\n", FullDllName);
353 
354  /* Load the image */
356  if (!Success)
357  {
358  ERR("PeLdrLoadImage() failed\n");
359  return Success;
360  }
361 
362  /* Allocate DTE for newly loaded DLL */
364  ImportName,
365  FullDllName,
366  BasePA,
367  DataTableEntry);
368  if (!Success)
369  {
370  ERR("PeLdrAllocateDataTableEntry() failed\n");
371  return Success;
372  }
373 
374  /* Scan its dependencies too */
375  TRACE("PeLdrScanImportDescriptorTable() calling ourselves for %S\n",
376  VaToPa((*DataTableEntry)->BaseDllName.Buffer));
377  Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
378  if (!Success)
379  {
380  ERR("PeLdrScanImportDescriptorTable() failed\n");
381  return Success;
382  }
383 
384  return TRUE;
385 }
#define TRUE
Definition: types.h:120
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
BOOLEAN PeLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH DirectoryPath, IN PLDR_DATA_TABLE_ENTRY ScanDTE)
Definition: peloader.c:500
char CHAR
Definition: xmlstorage.h:175
BOOLEAN PeLdrLoadImage(IN PCHAR FileName, IN TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA)
Definition: peloader.c:672
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:246
#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:574
#define ERR(fmt,...)
Definition: debug.h:109
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23

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

Definition at line 388 of file peloader.c.

394 {
395  PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
397  ULONG ExportSize;
398 
399  TRACE("PeLdrpScanImportAddressTable(): DllBase 0x%X, "
400  "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
401 
402  /* Obtain the export table from the DLL's base */
403  if (DllBase == NULL)
404  {
405  ERR("Error, DllBase == NULL!\n");
406  return FALSE;
407  }
408  else
409  {
410  ExportDirectory =
412  TRUE,
414  &ExportSize);
415  }
416 
417  TRACE("PeLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory);
418 
419  /* If pointer to Export Directory is */
420  if (ExportDirectory == NULL)
421  {
422  ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
423  return FALSE;
424  }
425 
426  /* Go through each entry in the thunk table and bind it */
427  while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
428  {
429  /* Bind it */
431  DllBase,
432  ImageBase,
433  ThunkData,
434  ExportDirectory,
435  ExportSize,
436  FALSE,
437  DirectoryPath);
438 
439  /* Move to the next entry */
440  ThunkData++;
441 
442  /* Return error if binding was unsuccessful */
443  if (!Success)
444  return Success;
445  }
446 
447  /* Return success */
448  return TRUE;
449 }
#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)
Definition: peloader.c:88
GLdouble u1
Definition: glext.h:8308
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:140
#define ERR(fmt,...)
Definition: debug.h:109
struct _IMAGE_EXPORT_DIRECTORY * PIMAGE_EXPORT_DIRECTORY
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 500 of file peloader.c.

504 {
505  PLDR_DATA_TABLE_ENTRY DataTableEntry;
506  PIMAGE_IMPORT_DESCRIPTOR ImportTable;
507  ULONG ImportTableSize;
508  PCH ImportName;
510 
511  /* Get a pointer to the import table of this image */
512  ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
513  TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
514 
515 #if DBG
516  {
517  UNICODE_STRING BaseName;
518  BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
519  BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
520  BaseName.Length = ScanDTE->BaseDllName.Length;
521  TRACE("PeLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
522  &BaseName, ImportTable);
523  }
524 #endif
525 
526  /* If image doesn't have any import directory - just return success */
527  if (ImportTable == NULL)
528  return TRUE;
529 
530  /* Loop through all entries */
531  for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
532  {
533  /* Get pointer to the name */
534  ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
535  TRACE("PeLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);
536 
537  /* In case we get a reference to ourselves - just skip it */
538  if (PeLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
539  continue;
540 
541  /* Load the DLL if it is not already loaded */
542  if (!PeLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
543  {
545  DirectoryPath,
546  ImportName,
547  &DataTableEntry);
548  if (!Success)
549  {
550  ERR("PeLdrpLoadAndScanReferencedDll() failed\n");
551  return Success;
552  }
553  }
554 
555  /* Scan its import address table */
557  DataTableEntry->DllBase,
558  ScanDTE->DllBase,
559  (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
560  DirectoryPath);
561 
562  if (!Success)
563  {
564  ERR("PeLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
565  ImportName, DirectoryPath);
566  return Success;
567  }
568  }
569 
570  return TRUE;
571 }
#define TRUE
Definition: types.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370
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:456
PVOID DllBase
Definition: btrfs_drv.h:1784
CHAR * PCH
Definition: ntbasedef.h:398
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static BOOLEAN PeLdrpLoadAndScanReferencedDll(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH DirectoryPath, IN PCH ImportName, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: peloader.c:338
#define TRACE(s)
Definition: solgame.cpp:4
#define RtlImageDirectoryEntryToData
Definition: compat.h:460
Definition: btrfs_drv.h:1780
static BOOLEAN PeLdrpCompareDllName(IN PCH DllName, IN PUNICODE_STRING UnicodeName)
Definition: peloader.c:30
#define ERR(fmt,...)
Definition: debug.h:109
#define RVA(m, b)
Definition: freeldr.h:24
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
DWORD RVA
Definition: compat.h:903
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
static BOOLEAN PeLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead, IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA ThunkData, IN PCSTR DirectoryPath)
Definition: peloader.c:388
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23

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