ReactOS  0.4.15-dev-3745-g356babc
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)
 
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 585 of file peloader.c.

591 {
592  PVOID BaseVA = PaToVa(BasePA);
593  PWSTR BaseDllNameBuffer, Buffer;
594  PLDR_DATA_TABLE_ENTRY DataTableEntry;
595  PIMAGE_NT_HEADERS NtHeaders;
596  USHORT Length;
597 
598  TRACE("PeLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
599  BaseDllName, FullDllName, BasePA);
600 
601  /* Allocate memory for a data table entry, zero-initialize it */
603  TAG_WLDR_DTE);
604  if (DataTableEntry == NULL)
605  return FALSE;
606 
607  /* Get NT headers from the image */
608  NtHeaders = RtlImageNtHeader(BasePA);
609 
610  /* Initialize corresponding fields of DTE based on NT headers value */
611  RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
612  DataTableEntry->DllBase = BaseVA;
613  DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
614  DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
615  DataTableEntry->SectionPointer = 0;
616  DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
617 
618  /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
619  by simple conversion - copying each character */
620  Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
622  if (Buffer == NULL)
623  {
624  FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
625  return FALSE;
626  }
627 
628  /* Save Buffer, in case of later failure */
629  BaseDllNameBuffer = Buffer;
630 
631  DataTableEntry->BaseDllName.Length = Length;
632  DataTableEntry->BaseDllName.MaximumLength = Length;
633  DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
634 
636  Length /= sizeof(WCHAR);
637  while (Length--)
638  {
639  *Buffer++ = *BaseDllName++;
640  }
641 
642  /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
643  using the same method */
644  Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
646  if (Buffer == NULL)
647  {
648  FrLdrHeapFree(BaseDllNameBuffer, TAG_WLDR_NAME);
649  FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
650  return FALSE;
651  }
652 
653  DataTableEntry->FullDllName.Length = Length;
654  DataTableEntry->FullDllName.MaximumLength = Length;
655  DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
656 
658  Length /= sizeof(WCHAR);
659  while (Length--)
660  {
661  *Buffer++ = *FullDllName++;
662  }
663 
664  /* Initialize what's left - LoadCount which is 1, and set Flags so that
665  we know this entry is processed */
666  DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
667  DataTableEntry->LoadCount = 1;
668 
669  /* Honour the FORCE_INTEGRITY flag */
671  {
672  /*
673  * On Vista and above, the LDRP_IMAGE_INTEGRITY_FORCED flag must be set
674  * if IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY is set in the image header.
675  * This is done after the image has been loaded and the digital signature
676  * check has passed successfully. (We do not do it yet!)
677  *
678  * Several OS functionality depend on the presence of this flag.
679  * For example, when using Object-Manager callbacks the latter will call
680  * MmVerifyCallbackFunction() to verify whether the flag is present.
681  * If not callbacks will not work.
682  * (See Windows Internals Part 1, 6th edition, p. 176.)
683  */
684  DataTableEntry->Flags |= LDRP_IMAGE_INTEGRITY_FORCED;
685  }
686 
687  /* Insert this DTE to a list in the LPB */
689  TRACE("Inserting DTE %p, name='%.*S' DllBase=%p\n", DataTableEntry,
690  DataTableEntry->BaseDllName.Length / sizeof(WCHAR),
691  VaToPa(DataTableEntry->BaseDllName.Buffer),
692  DataTableEntry->DllBase);
693 
694  /* Save pointer to a newly allocated and initialized entry */
695  *NewEntry = DataTableEntry;
696 
697  /* Return success */
698  return TRUE;
699 }
#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:1926
#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:1932
struct _LDR_DATA_TABLE_ENTRY * PLDR_DATA_TABLE_ENTRY
Definition: btrfs_drv.h:1922
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:1928
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 465 of file peloader.c.

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

◆ PeLdrLoadImage()

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

Definition at line 709 of file peloader.c.

713 {
714  ULONG FileId;
715  PVOID PhysicalBase;
716  PVOID VirtualBase = NULL;
717  UCHAR HeadersBuffer[SECTOR_SIZE * 2];
718  PIMAGE_NT_HEADERS NtHeaders;
719  PIMAGE_SECTION_HEADER SectionHeader;
720  ULONG VirtualSize, SizeOfRawData, NumberOfSections;
723  ULONG i, BytesRead;
724 
725  TRACE("PeLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
726 
727  /* Open the image file */
728  Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
729  if (Status != ESUCCESS)
730  {
731  WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName, Status);
732  return FALSE;
733  }
734 
735  /* Load the first 2 sectors of the image so we can read the PE header */
736  Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
737  if (Status != ESUCCESS)
738  {
739  ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
740  UiMessageBox("Error reading from file.");
741  ArcClose(FileId);
742  return FALSE;
743  }
744 
745  /* Now read the MZ header to get the offset to the PE Header */
746  NtHeaders = RtlImageNtHeader(HeadersBuffer);
747  if (!NtHeaders)
748  {
749  ERR("No NT header found in \"%s\"\n", FileName);
750  UiMessageBox("Error: No NT header found.");
751  ArcClose(FileId);
752  return FALSE;
753  }
754 
755  /* Ensure this is executable image */
756  if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0))
757  {
758  ERR("Not an executable image \"%s\"\n", FileName);
759  UiMessageBox("Not an executable image.");
760  ArcClose(FileId);
761  return FALSE;
762  }
763 
764  /* Store number of sections to read and a pointer to the first section */
765  NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
766  SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
767 
768  /* Try to allocate this memory, if fails - allocate somewhere else */
769  PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
770  (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
771  MemoryType);
772 
773  if (PhysicalBase == NULL)
774  {
775  /* It's ok, we don't panic - let's allocate again at any other "low" place */
776  PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
777 
778  if (PhysicalBase == NULL)
779  {
780  ERR("Failed to alloc %lu bytes for image %s\n", NtHeaders->OptionalHeader.SizeOfImage, FileName);
781  UiMessageBox("Failed to alloc pages for image.");
782  ArcClose(FileId);
783  return FALSE;
784  }
785  }
786 
787  /* This is the real image base - in form of a virtual address */
788  VirtualBase = PaToVa(PhysicalBase);
789 
790  TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
791 
792  /* Copy headers from already read data */
793  RtlCopyMemory(PhysicalBase, HeadersBuffer, min(NtHeaders->OptionalHeader.SizeOfHeaders, sizeof(HeadersBuffer)));
794  /* If headers are quite big, request next bytes from file */
795  if (NtHeaders->OptionalHeader.SizeOfHeaders > sizeof(HeadersBuffer))
796  {
797  Status = ArcRead(FileId, (PUCHAR)PhysicalBase + sizeof(HeadersBuffer), NtHeaders->OptionalHeader.SizeOfHeaders - sizeof(HeadersBuffer), &BytesRead);
798  if (Status != ESUCCESS)
799  {
800  ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
801  UiMessageBox("Error reading headers.");
802  ArcClose(FileId);
803  return FALSE;
804  }
805  }
806 
807  /*
808  * On Vista and above, a digital signature check is performed when the image
809  * has the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag set in its header.
810  * (We of course do not perform this check yet!)
811  */
812 
813  /* Reload the NT Header */
814  NtHeaders = RtlImageNtHeader(PhysicalBase);
815 
816  /* Load the first section */
817  SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
818 
819  /* Fill output parameters */
820  *ImageBasePA = PhysicalBase;
821 
822  /* Walk through each section and read it (check/fix any possible
823  bad situations, if they arise) */
824  for (i = 0; i < NumberOfSections; i++)
825  {
826  VirtualSize = SectionHeader->Misc.VirtualSize;
827  SizeOfRawData = SectionHeader->SizeOfRawData;
828 
829  /* Handle a case when VirtualSize equals 0 */
830  if (VirtualSize == 0)
831  VirtualSize = SizeOfRawData;
832 
833  /* If PointerToRawData is 0, then force its size to be also 0 */
834  if (SectionHeader->PointerToRawData == 0)
835  {
836  SizeOfRawData = 0;
837  }
838  else
839  {
840  /* Cut the loaded size to the VirtualSize extents */
841  if (SizeOfRawData > VirtualSize)
842  SizeOfRawData = VirtualSize;
843  }
844 
845  /* Actually read the section (if its size is not 0) */
846  if (SizeOfRawData != 0)
847  {
848  /* Seek to the correct position */
849  Position.QuadPart = SectionHeader->PointerToRawData;
850  Status = ArcSeek(FileId, &Position, SeekAbsolute);
851 
852  TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
853 
854  /* Read this section from the file, size = SizeOfRawData */
855  Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
856  if (Status != ESUCCESS)
857  {
858  ERR("PeLdrLoadImage(): Error reading section from file!\n");
859  break;
860  }
861  }
862 
863  /* Size of data is less than the virtual size - fill up the remainder with zeroes */
864  if (SizeOfRawData < VirtualSize)
865  {
866  TRACE("PeLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
867  RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
868  }
869 
870  SectionHeader++;
871  }
872 
873  /* We are done with the file - close it */
874  ArcClose(FileId);
875 
876  /* If loading failed - return right now */
877  if (Status != ESUCCESS)
878  return FALSE;
879 
880  /* Relocate the image, if it needs it */
881  if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
882  {
883  WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase);
884  return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
885  (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
886  "FreeLdr",
887  TRUE,
888  TRUE, /* in case of conflict still return success */
889  FALSE);
890  }
891 
892  TRACE("PeLdrLoadImage() done, PA = %p\n", *ImageBasePA);
893  return TRUE;
894 }
union _IMAGE_SECTION_HEADER::@1507 Misc
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:277
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:320
unsigned char BOOLEAN
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
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#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
#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 89 of file peloader.c.

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

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 }
_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 342 of file peloader.c.

348 {
349  CHAR FullDllName[256];
351  PVOID BasePA = NULL;
352 
353  /* Prepare the full path to the file to be loaded */
354  strcpy(FullDllName, DirectoryPath);
355  strcat(FullDllName, ImportName);
356 
357  TRACE("Loading referenced DLL: %s\n", FullDllName);
358 
359  /* Load the image */
361  if (!Success)
362  {
363  ERR("PeLdrLoadImage() failed\n");
364  return Success;
365  }
366 
367  /* Allocate DTE for newly loaded DLL */
369  ImportName,
370  FullDllName,
371  BasePA,
372  DataTableEntry);
373  if (!Success)
374  {
375  ERR("PeLdrAllocateDataTableEntry() failed\n");
376  return Success;
377  }
378 
379  (*DataTableEntry)->Flags |= LDRP_DRIVER_DEPENDENT_DLL;
380 
381  /* Scan its dependencies too */
382  TRACE("PeLdrScanImportDescriptorTable() calling ourselves for %S\n",
383  VaToPa((*DataTableEntry)->BaseDllName.Buffer));
384  Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry);
385  if (!Success)
386  {
387  ERR("PeLdrScanImportDescriptorTable() failed\n");
388  return Success;
389  }
390 
391  return TRUE;
392 }
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#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:509
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
BOOLEAN PeLdrLoadImage(IN PCHAR FileName, IN TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA)
Definition: peloader.c:709
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:585
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
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,
IN PLIST_ENTRY  Parent 
)
static

Definition at line 395 of file peloader.c.

402 {
403  PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
405  ULONG ExportSize;
406 
407  TRACE("PeLdrpScanImportAddressTable(): DllBase 0x%X, "
408  "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
409 
410  /* Obtain the export table from the DLL's base */
411  if (DllBase == NULL)
412  {
413  ERR("Error, DllBase == NULL!\n");
414  return FALSE;
415  }
416  else
417  {
418  ExportDirectory =
420  TRUE,
422  &ExportSize);
423  }
424 
425  TRACE("PeLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory);
426 
427  /* If pointer to Export Directory is */
428  if (ExportDirectory == NULL)
429  {
430  ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
431  return FALSE;
432  }
433 
434  /* Go through each entry in the thunk table and bind it */
435  while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
436  {
437  /* Bind it */
439  DllBase,
440  ImageBase,
441  ThunkData,
442  ExportDirectory,
443  ExportSize,
444  FALSE,
445  DirectoryPath,
446  Parent);
447 
448  /* Move to the next entry */
449  ThunkData++;
450 
451  /* Return error if binding was unsuccessful */
452  if (!Success)
453  return Success;
454  }
455 
456  /* Return success */
457  return TRUE;
458 }
#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:89
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 509 of file peloader.c.

513 {
514  PLDR_DATA_TABLE_ENTRY DataTableEntry;
515  PIMAGE_IMPORT_DESCRIPTOR ImportTable;
516  ULONG ImportTableSize;
517  PCH ImportName;
519 
520  /* Get a pointer to the import table of this image */
521  ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
522  TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
523 
524 #if DBG
525  {
526  UNICODE_STRING BaseName;
527  BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
528  BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
529  BaseName.Length = ScanDTE->BaseDllName.Length;
530  TRACE("PeLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
531  &BaseName, ImportTable);
532  }
533 #endif
534 
535  /* If image doesn't have any import directory - just return success */
536  if (ImportTable == NULL)
537  return TRUE;
538 
539  /* Loop through all entries */
540  for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
541  {
542  /* Get pointer to the name */
543  ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
544  TRACE("PeLdrScanImportDescriptorTable(): Looking at %s\n", ImportName);
545 
546  /* In case we get a reference to ourselves - just skip it */
547  if (PeLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
548  continue;
549 
550  /* Load the DLL if it is not already loaded */
551  if (!PeLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
552  {
554  DirectoryPath,
555  ImportName,
556  &ScanDTE->InLoadOrderLinks,
557  &DataTableEntry);
558  if (!Success)
559  {
560  ERR("PeLdrpLoadAndScanReferencedDll() failed\n");
561  return Success;
562  }
563  }
564 
565  /* Scan its import address table */
567  DataTableEntry->DllBase,
568  ScanDTE->DllBase,
569  (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
570  DirectoryPath,
571  &ScanDTE->InLoadOrderLinks);
572 
573  if (!Success)
574  {
575  ERR("PeLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n",
576  ImportName, DirectoryPath);
577  return Success;
578  }
579  }
580 
581  return TRUE;
582 }
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:465
PVOID DllBase
Definition: btrfs_drv.h:1926
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:1922
static BOOLEAN PeLdrpCompareDllName(IN PCH DllName, IN PUNICODE_STRING UnicodeName)
Definition: peloader.c:30
#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:395
#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:342

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