ReactOS 0.4.15-dev-7842-g558ab78
ldrpe.c File Reference
#include <ntdll.h>
#include <debug.h>
Include dependency graph for ldrpe.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI LdrpSnapIAT (IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, IN PLDR_DATA_TABLE_ENTRY ImportLdrEntry, IN PIMAGE_IMPORT_DESCRIPTOR IatEntry, IN BOOLEAN EntriesValid)
 
NTSTATUS NTAPI LdrpHandleOneNewFormatImportDescriptor (IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_BOUND_IMPORT_DESCRIPTOR *BoundEntryPtr, IN PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry)
 
NTSTATUS NTAPI LdrpHandleNewFormatImportDescriptors (IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry)
 
NTSTATUS NTAPI LdrpHandleOneOldFormatImportDescriptor (IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_IMPORT_DESCRIPTOR *ImportEntry)
 
NTSTATUS NTAPI LdrpHandleOldFormatImportDescriptors (IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry)
 
USHORT NTAPI LdrpNameToOrdinal (IN LPSTR ImportName, IN ULONG NumberOfNames, IN PVOID ExportBase, IN PULONG NameTable, IN PUSHORT OrdinalTable)
 
NTSTATUS NTAPI LdrpWalkImportDescriptor (IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI LdrpLoadImportModule (IN PWSTR DllPath OPTIONAL, IN LPSTR ImportName, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry, OUT PBOOLEAN Existing)
 
NTSTATUS NTAPI LdrpSnapThunk (IN PVOID ExportBase, IN PVOID ImportBase, IN PIMAGE_THUNK_DATA OriginalThunk, IN OUT PIMAGE_THUNK_DATA Thunk, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN Static, IN LPSTR DllName)
 

Variables

PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine
 
ULONG LdrpNormalSnap
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file ldrpe.c.

Function Documentation

◆ LdrpHandleNewFormatImportDescriptors()

NTSTATUS NTAPI LdrpHandleNewFormatImportDescriptors ( IN LPWSTR DllPath  OPTIONAL,
IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR  BoundEntry 
)

Definition at line 492 of file ldrpe.c.

495{
496 PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry = BoundEntry;
498
499 /* Make sure we have a name */
500 while (BoundEntry->OffsetModuleName)
501 {
502 /* Parse this descriptor */
504 LdrEntry,
505 &BoundEntry,
506 FirstEntry);
507 if (!NT_SUCCESS(Status)) return Status;
508 }
509
510 /* Done */
511 return STATUS_SUCCESS;
512}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_BOUND_IMPORT_DESCRIPTOR *BoundEntryPtr, IN PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry)
Definition: ldrpe.c:259
static const char const char * DllPath
Definition: image.c:34
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by LdrpWalkImportDescriptor().

◆ LdrpHandleOldFormatImportDescriptors()

NTSTATUS NTAPI LdrpHandleOldFormatImportDescriptors ( IN LPWSTR DllPath  OPTIONAL,
IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN PIMAGE_IMPORT_DESCRIPTOR  ImportEntry 
)

Definition at line 606 of file ldrpe.c.

609{
611
612 /* Check for Name and Thunk */
613 while ((ImportEntry->Name) && (ImportEntry->FirstThunk))
614 {
615 /* Parse this descriptor */
617 LdrEntry,
618 &ImportEntry);
619 if (!NT_SUCCESS(Status)) return Status;
620 }
621
622 /* Done */
623 return STATUS_SUCCESS;
624}
NTSTATUS NTAPI LdrpHandleOneOldFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_IMPORT_DESCRIPTOR *ImportEntry)
Definition: ldrpe.c:516

Referenced by LdrpWalkImportDescriptor().

◆ LdrpHandleOneNewFormatImportDescriptor()

NTSTATUS NTAPI LdrpHandleOneNewFormatImportDescriptor ( IN LPWSTR DllPath  OPTIONAL,
IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntryPtr,
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR  FirstEntry 
)

Definition at line 259 of file ldrpe.c.

263{
264 LPSTR ImportName = NULL, BoundImportName, ForwarderName;
266 BOOLEAN AlreadyLoaded = FALSE, Stale;
267 PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
268 PLDR_DATA_TABLE_ENTRY DllLdrEntry, ForwarderLdrEntry;
269 PIMAGE_BOUND_FORWARDER_REF ForwarderEntry;
272 ULONG i, IatSize;
273
274 /* Get the pointer to the bound entry */
275 BoundEntry = *BoundEntryPtr;
276
277 /* Get the name's VA */
278 BoundImportName = (LPSTR)FirstEntry + BoundEntry->OffsetModuleName;
279
280 /* Show debug message */
281 if (ShowSnaps)
282 {
283 DPRINT1("LDR: %wZ bound to %s\n", &LdrEntry->BaseDllName, BoundImportName);
284 }
285
286 /* Load the module for this entry */
288 BoundImportName,
289 &DllLdrEntry,
290 &AlreadyLoaded);
291 if (!NT_SUCCESS(Status))
292 {
293 /* Show debug message */
294 if (ShowSnaps)
295 {
296 DPRINT1("LDR: %wZ failed to load import module %s; status = %x\n",
297 &LdrEntry->BaseDllName,
298 BoundImportName,
299 Status);
300 }
301 goto Quickie;
302 }
303
304 /* Check if it wasn't already loaded */
305 if (!AlreadyLoaded)
306 {
307 /* Add it to our list */
309 &DllLdrEntry->InInitializationOrderLinks);
310 }
311
312 /* Check if the Bound Entry is now invalid */
313 if ((BoundEntry->TimeDateStamp != DllLdrEntry->TimeDateStamp) ||
314 (DllLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE))
315 {
316 /* Show debug message */
317 if (ShowSnaps)
318 {
319 DPRINT1("LDR: %wZ has stale binding to %s\n",
320 &LdrEntry->BaseDllName,
321 BoundImportName);
322 }
323
324 /* Remember it's become stale */
325 Stale = TRUE;
326 }
327 else
328 {
329 /* Show debug message */
330 if (ShowSnaps)
331 {
332 DPRINT1("LDR: %wZ has correct binding to %s\n",
333 &LdrEntry->BaseDllName,
334 BoundImportName);
335 }
336
337 /* Remember it's valid */
338 Stale = FALSE;
339 }
340
341 /* Get the forwarders */
342 ForwarderEntry = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1);
343
344 /* Loop them */
345 for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++)
346 {
347 /* Get the name */
348 ForwarderName = (LPSTR)FirstEntry + ForwarderEntry->OffsetModuleName;
349
350 /* Show debug message */
351 if (ShowSnaps)
352 {
353 DPRINT1("LDR: %wZ bound to %s via forwarder(s) from %wZ\n",
354 &LdrEntry->BaseDllName,
355 ForwarderName,
356 &DllLdrEntry->BaseDllName);
357 }
358
359 /* Load the module */
361 ForwarderName,
362 &ForwarderLdrEntry,
363 &AlreadyLoaded);
364 if (NT_SUCCESS(Status))
365 {
366 /* Loaded it, was it already loaded? */
367 if (!AlreadyLoaded)
368 {
369 /* Add it to our list */
371 &ForwarderLdrEntry->InInitializationOrderLinks);
372 }
373 }
374
375 /* Check if the Bound Entry is now invalid */
376 if (!(NT_SUCCESS(Status)) ||
377 (ForwarderEntry->TimeDateStamp != ForwarderLdrEntry->TimeDateStamp) ||
378 (ForwarderLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE))
379 {
380 /* Show debug message */
381 if (ShowSnaps)
382 {
383 DPRINT1("LDR: %wZ has stale binding to %s\n",
384 &LdrEntry->BaseDllName,
385 ForwarderName);
386 }
387
388 /* Remember it's become stale */
389 Stale = TRUE;
390 }
391 else
392 {
393 /* Show debug message */
394 if (ShowSnaps)
395 {
396 DPRINT1("LDR: %wZ has correct binding to %s\n",
397 &LdrEntry->BaseDllName,
398 ForwarderName);
399 }
400
401 /* Remember it's valid */
402 Stale = FALSE;
403 }
404
405 /* Move to the next one */
406 ForwarderEntry++;
407 }
408
409 /* Set the next bound entry to the forwarder */
410 FirstEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)ForwarderEntry;
411
412 /* Check if the binding was stale */
413 if (Stale)
414 {
415 /* It was, so find the IAT entry for it */
417 ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
418 TRUE,
420 &IatSize);
421
422 /* Make sure it has a name */
423 while (ImportEntry->Name)
424 {
425 /* Get the name */
426 ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name);
427
428 /* Compare it */
429 if (!_stricmp(ImportName, BoundImportName)) break;
430
431 /* Move to next entry */
432 ImportEntry++;
433 }
434
435 /* If we didn't find a name, fail */
436 if (!ImportEntry->Name)
437 {
438 /* Show debug message */
439 if (ShowSnaps)
440 {
441 DPRINT1("LDR: LdrpWalkImportTable - failing with"
442 "STATUS_OBJECT_NAME_INVALID due to no import descriptor name\n");
443 }
444
445 /* Return error */
447 goto Quickie;
448 }
449
450 /* Show debug message */
451 if (ShowSnaps)
452 {
453 DPRINT1("LDR: Stale Bind %s from %wZ\n",
454 ImportName,
455 &LdrEntry->BaseDllName);
456 }
457
458 /* Snap the IAT Entry*/
459 Status = LdrpSnapIAT(DllLdrEntry,
460 LdrEntry,
461 ImportEntry,
462 FALSE);
463
464 /* Make sure we didn't fail */
465 if (!NT_SUCCESS(Status))
466 {
467 /* Show debug message */
468 if (ShowSnaps)
469 {
470 DPRINT1("LDR: %wZ failed to load import module %s; status = %x\n",
471 &LdrEntry->BaseDllName,
472 BoundImportName,
473 Status);
474 }
475
476 /* Return */
477 goto Quickie;
478 }
479 }
480
481 /* All done */
483
484Quickie:
485 /* Write where we are now and return */
486 *BoundEntryPtr = FirstEntry;
487 return Status;
488}
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
#define _stricmp
Definition: cat.c:22
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
PPEB Peb
Definition: dllmain.c:27
#define InsertTailList(ListHead, Entry)
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
NTSTATUS NTAPI LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, IN PLDR_DATA_TABLE_ENTRY ImportLdrEntry, IN PIMAGE_IMPORT_DESCRIPTOR IatEntry, IN BOOLEAN EntriesValid)
Definition: ldrpe.c:26
ULONG LdrpNormalSnap
Definition: ldrpe.c:19
NTSTATUS NTAPI LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, IN LPSTR ImportName, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry, OUT PBOOLEAN Existing)
Definition: ldrpe.c:808
#define LDRP_IMAGE_NOT_AT_BASE
Definition: ldrtypes.h:51
if(dx< 0)
Definition: linetemp.h:194
BOOLEAN ShowSnaps
Definition: ldrinit.c:81
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
Definition: btrfs_drv.h:1876
LIST_ENTRY InInitializationOrderLinks
Definition: ldrtypes.h:140
ULONG Flags
Definition: ntddk_ex.h:207
ULONG TimeDateStamp
Definition: btrfs_drv.h:1889
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
LIST_ENTRY InInitializationOrderModuleList
Definition: ldrtypes.h:122
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
struct _IMAGE_BOUND_FORWARDER_REF * PIMAGE_BOUND_FORWARDER_REF
struct _IMAGE_BOUND_IMPORT_DESCRIPTOR * PIMAGE_BOUND_IMPORT_DESCRIPTOR
char * LPSTR
Definition: xmlstorage.h:182

Referenced by LdrpHandleNewFormatImportDescriptors().

◆ LdrpHandleOneOldFormatImportDescriptor()

NTSTATUS NTAPI LdrpHandleOneOldFormatImportDescriptor ( IN LPWSTR DllPath  OPTIONAL,
IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry 
)

Definition at line 516 of file ldrpe.c.

519{
520 LPSTR ImportName;
522 BOOLEAN AlreadyLoaded = FALSE;
523 PLDR_DATA_TABLE_ENTRY DllLdrEntry;
524 PIMAGE_THUNK_DATA FirstThunk;
526
527 /* Get the import name's VA */
528 ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + (*ImportEntry)->Name);
529
530 /* Get the first thunk */
531 FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrEntry->DllBase +
532 (*ImportEntry)->FirstThunk);
533
534 /* Make sure it's valid */
535 if (!FirstThunk->u1.Function) goto SkipEntry;
536
537 /* Show debug message */
538 if (ShowSnaps)
539 {
540 DPRINT1("LDR: %s used by %wZ\n",
541 ImportName,
542 &LdrEntry->BaseDllName);
543 }
544
545 /* Load the module associated to it */
547 ImportName,
548 &DllLdrEntry,
549 &AlreadyLoaded);
550 if (!NT_SUCCESS(Status))
551 {
552 /* Fail */
553 if (ShowSnaps)
554 {
555 DbgPrint("LDR: LdrpWalkImportTable - LdrpLoadImportModule failed "
556 "on import %s with status %x\n",
557 ImportName,
558 Status);
559 }
560
561 /* Return */
562 return Status;
563 }
564
565 /* Show debug message */
566 if (ShowSnaps)
567 {
568 DPRINT1("LDR: Snapping imports for %wZ from %s\n",
569 &LdrEntry->BaseDllName,
570 ImportName);
571 }
572
573 /* Check if it wasn't already loaded */
575 if (!AlreadyLoaded)
576 {
577 /* Add the DLL to our list */
579 &DllLdrEntry->InInitializationOrderLinks);
580 }
581
582 /* Now snap the IAT Entry */
583 Status = LdrpSnapIAT(DllLdrEntry, LdrEntry, *ImportEntry, FALSE);
584 if (!NT_SUCCESS(Status))
585 {
586 /* Fail */
587 if (ShowSnaps)
588 {
589 DbgPrint("LDR: LdrpWalkImportTable - LdrpSnapIAT #2 failed with "
590 "status %x\n",
591 Status);
592 }
593
594 /* Return */
595 return Status;
596 }
597
598SkipEntry:
599 /* Move on */
600 (*ImportEntry)++;
601 return STATUS_SUCCESS;
602}
#define DbgPrint
Definition: hal.h:12
PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA
Definition: ntimage.h:566
union _IMAGE_THUNK_DATA32::@2129 u1

Referenced by LdrpHandleOldFormatImportDescriptors().

◆ LdrpLoadImportModule()

NTSTATUS NTAPI LdrpLoadImportModule ( IN PWSTR DllPath  OPTIONAL,
IN LPSTR  ImportName,
OUT PLDR_DATA_TABLE_ENTRY DataTableEntry,
OUT PBOOLEAN  Existing 
)

Definition at line 808 of file ldrpe.c.

812{
814 PUNICODE_STRING ImpDescName;
815 const WCHAR *p;
816 BOOLEAN GotExtension;
817 WCHAR c;
820 PTEB Teb = NtCurrentTeb();
821 UNICODE_STRING RedirectedImpDescName;
822 BOOLEAN RedirectedDll;
823
824 DPRINT("LdrpLoadImportModule('%S' '%s' %p %p)\n", DllPath, ImportName, DataTableEntry, Existing);
825
826 RedirectedDll = FALSE;
827 RtlInitEmptyUnicodeString(&RedirectedImpDescName, NULL, 0);
828
829 /* Convert import descriptor name to unicode string */
830 ImpDescName = &Teb->StaticUnicodeString;
831 RtlInitAnsiString(&AnsiString, ImportName);
833 if (!NT_SUCCESS(Status)) return Status;
834
835 /* Find the extension, if present */
836 p = ImpDescName->Buffer + ImpDescName->Length / sizeof(WCHAR) - 1;
837 GotExtension = FALSE;
838 while (p >= ImpDescName->Buffer)
839 {
840 c = *p--;
841 if (c == L'.')
842 {
843 GotExtension = TRUE;
844 break;
845 }
846 else if (c == L'\\')
847 {
848 break;
849 }
850 }
851
852 /* If no extension was found, add the default extension */
853 if (!GotExtension)
854 {
855 /* Check that we have space to add one */
856 if ((ImpDescName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >=
857 sizeof(Teb->StaticUnicodeBuffer))
858 {
859 /* No space to add the extension */
862 "LDR: %s - Dll name missing extension; with extension "
863 "added the name is too long\n"
864 " ImpDescName: (@ %p) \"%wZ\"\n"
865 " ImpDescName->Length: %u\n",
867 ImpDescName,
868 ImpDescName,
869 ImpDescName->Length);
871 }
872
873 /* Add it. Needs to be null terminated, thus the length check above */
876 }
877
878 /* Check if the SxS Assemblies specify another file */
880 ImpDescName,
882 NULL,
883 &RedirectedImpDescName,
884 &ImpDescName,
885 NULL,
886 NULL,
887 NULL);
888
889 /* Check success */
890 if (NT_SUCCESS(Status))
891 {
892 /* Let Ldrp know */
893 RedirectedDll = TRUE;
894 }
896 {
897 /* Unrecoverable SxS failure */
898 DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImpDescName);
899 goto done;
900 }
901
902 /* Check if it's loaded */
904 ImpDescName,
905 TRUE,
906 RedirectedDll,
907 DataTableEntry))
908 {
909 /* It's already existing in the list */
910 *Existing = TRUE;
912 goto done;
913 }
914
915 /* We're loading it for the first time */
916 *Existing = FALSE;
917
918 /* Map it */
920 NULL,
921 ImpDescName->Buffer,
922 NULL,
923 TRUE,
924 RedirectedDll,
925 DataTableEntry);
926 if (!NT_SUCCESS(Status))
927 {
928 DPRINT1("LDR: LdrpMapDll failed with status %x for dll %wZ\n", Status, ImpDescName);
929 goto done;
930 }
931
932 /* Walk its import descriptor table */
934 *DataTableEntry);
935 if (!NT_SUCCESS(Status))
936 {
937 /* Add it to the in-init-order list in case of failure */
939 &(*DataTableEntry)->InInitializationOrderLinks);
940 }
941
942done:
943 RtlFreeUnicodeString(&RedirectedImpDescName);
944
945 return Status;
946}
#define VOID
Definition: acefi.h:82
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
NTSYSAPI NTSTATUS NTAPI RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, IN PUNICODE_STRING OriginalName, IN PUNICODE_STRING Extension, IN OUT PUNICODE_STRING StaticString, IN OUT PUNICODE_STRING DynamicString, IN OUT PUNICODE_STRING *NewName, IN PULONG NewFlags, IN PSIZE_T FileNameSize, IN PSIZE_T RequiredLength)
Definition: libsupp.c:818
@ AnsiString
Definition: dnslib.h:19
@ DPFLTR_LDR_ID
Definition: dpfilter.h:113
#define __FUNCTION__
Definition: types.h:116
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
NTSYSAPI PEB *WINAPI RtlGetCurrentPeb(void)
Definition: libsupp.c:63
#define NtCurrentTeb
#define c
Definition: ke_i.h:80
NTSTATUS NTAPI LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ldrpe.c:670
NTSYSAPI ULONG __cdecl DbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ _Printf_format_string_ PCSTR Format,...)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define UNICODE_NULL
NTSTATUS NTAPI LdrpMapDll(IN PWSTR SearchPath OPTIONAL, IN PWSTR DllPath2, IN PWSTR DllName OPTIONAL, IN PULONG DllCharacteristics, IN BOOLEAN Static, IN BOOLEAN Redirect, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
Definition: ldrutils.c:1023
UNICODE_STRING LdrApiDefaultExtension
Definition: ldrapi.c:22
BOOLEAN NTAPI LdrpCheckForLoadedDll(IN PWSTR DllPath, IN PUNICODE_STRING DllName, IN BOOLEAN Flag, IN BOOLEAN RedirectedDll, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1979
#define STATUS_SXS_KEY_NOT_FOUND
Definition: ntstatus.h:1389
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define L(x)
Definition: ntvdm.h:50
#define DPRINT
Definition: sndvol32.h:71
Definition: compat.h:836
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:877
UNICODE_STRING StaticUnicodeString
Definition: compat.h:876
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by LdrpHandleOneNewFormatImportDescriptor(), and LdrpHandleOneOldFormatImportDescriptor().

◆ LdrpNameToOrdinal()

USHORT NTAPI LdrpNameToOrdinal ( IN LPSTR  ImportName,
IN ULONG  NumberOfNames,
IN PVOID  ExportBase,
IN PULONG  NameTable,
IN PUSHORT  OrdinalTable 
)

Definition at line 628 of file ldrpe.c.

633{
634 LONG Start, End, Next, CmpResult;
635
636 /* Use classical binary search to find the ordinal */
637 Start = Next = 0;
638 End = NumberOfNames - 1;
639 while (End >= Start)
640 {
641 /* Next will be exactly between Start and End */
642 Next = (Start + End) >> 1;
643
644 /* Compare this name with the one we need to find */
645 CmpResult = strcmp(ImportName, (PCHAR)((ULONG_PTR)ExportBase + NameTable[Next]));
646
647 /* We found our entry if result is 0 */
648 if (!CmpResult) break;
649
650 /* We didn't find, update our range then */
651 if (CmpResult < 0)
652 {
653 End = Next - 1;
654 }
655 else if (CmpResult > 0)
656 {
657 Start = Next + 1;
658 }
659 }
660
661 /* If end is before start, then the search failed */
662 if (End < Start) return -1;
663
664 /* Return found name */
665 return OrdinalTable[Next];
666}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
long LONG
Definition: pedump.c:60
char * PCHAR
Definition: typedefs.h:51
@ Start
Definition: partlist.h:33

Referenced by LdrpSnapThunk().

◆ LdrpSnapIAT()

NTSTATUS NTAPI LdrpSnapIAT ( IN PLDR_DATA_TABLE_ENTRY  ExportLdrEntry,
IN PLDR_DATA_TABLE_ENTRY  ImportLdrEntry,
IN PIMAGE_IMPORT_DESCRIPTOR  IatEntry,
IN BOOLEAN  EntriesValid 
)

Definition at line 26 of file ldrpe.c.

30{
31 PVOID Iat;
33 PIMAGE_THUNK_DATA OriginalThunk, FirstThunk;
34 PIMAGE_NT_HEADERS NtHeader;
35 PIMAGE_SECTION_HEADER SectionHeader;
36 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
37 LPSTR ImportName;
38 ULONG ForwarderChain, i, Rva, OldProtect, IatSize, ExportSize;
39 SIZE_T ImportSize;
40 DPRINT("LdrpSnapIAT(%wZ %wZ %p %u)\n", &ExportLdrEntry->BaseDllName, &ImportLdrEntry->BaseDllName, IatEntry, EntriesValid);
41
42 /* Get export directory */
43 ExportDirectory = RtlImageDirectoryEntryToData(ExportLdrEntry->DllBase,
44 TRUE,
46 &ExportSize);
47
48 /* Make sure it has one */
49 if (!ExportDirectory)
50 {
51 /* Fail */
52 DbgPrint("LDR: %wZ doesn't contain an EXPORT table\n",
53 &ExportLdrEntry->BaseDllName);
55 }
56
57 /* Get the IAT */
58 Iat = RtlImageDirectoryEntryToData(ImportLdrEntry->DllBase,
59 TRUE,
61 &IatSize);
62 ImportSize = IatSize;
63
64 /* Check if we don't have one */
65 if (!Iat)
66 {
67 /* Get the NT Header and the first section */
68 NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase);
69 if (!NtHeader) return STATUS_INVALID_IMAGE_FORMAT;
70 SectionHeader = IMAGE_FIRST_SECTION(NtHeader);
71
72 /* Get the RVA of the import directory */
74
75 /* Make sure we got one */
76 if (Rva)
77 {
78 /* Loop all the sections */
79 for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
80 {
81 /* Check if we are inside this section */
82 if ((Rva >= SectionHeader->VirtualAddress) &&
83 (Rva < (SectionHeader->VirtualAddress +
84 SectionHeader->SizeOfRawData)))
85 {
86 /* We are, so set the IAT here */
87 Iat = (PVOID)((ULONG_PTR)(ImportLdrEntry->DllBase) +
88 SectionHeader->VirtualAddress);
89
90 /* Set the size */
91 IatSize = SectionHeader->Misc.VirtualSize;
92
93 /* Deal with Watcom and other retarded compilers */
94 if (!IatSize) IatSize = SectionHeader->SizeOfRawData;
95
96 /* Found it, get out */
97 break;
98 }
99
100 /* No match, move to the next section */
101 SectionHeader++;
102 }
103 }
104
105 /* If we still don't have an IAT, that's bad */
106 if (!Iat)
107 {
108 /* Fail */
109 DbgPrint("LDR: Unable to unprotect IAT for %wZ (Image Base %p)\n",
110 &ImportLdrEntry->BaseDllName,
111 ImportLdrEntry->DllBase);
113 }
114
115 /* Set the right size */
116 ImportSize = IatSize;
117 }
118
119 /* Unprotect the IAT */
121 &Iat,
122 &ImportSize,
124 &OldProtect);
125 if (!NT_SUCCESS(Status))
126 {
127 /* Fail */
128 DbgPrint("LDR: Unable to unprotect IAT for %wZ (Status %x)\n",
129 &ImportLdrEntry->BaseDllName,
130 Status);
131 return Status;
132 }
133
134 /* Check if the Thunks are already valid */
135 if (EntriesValid)
136 {
137 /* We'll only do forwarders. Get the import name */
138 ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase + IatEntry->Name);
139
140 /* Get the list of forwarders */
141 ForwarderChain = IatEntry->ForwarderChain;
142
143 /* Loop them */
144 while (ForwarderChain != -1)
145 {
146 /* Get the cached thunk VA*/
147 OriginalThunk = (PIMAGE_THUNK_DATA)
148 ((ULONG_PTR)ImportLdrEntry->DllBase +
149 IatEntry->OriginalFirstThunk +
150 (ForwarderChain * sizeof(IMAGE_THUNK_DATA)));
151
152 /* Get the first thunk */
153 FirstThunk = (PIMAGE_THUNK_DATA)
154 ((ULONG_PTR)ImportLdrEntry->DllBase +
155 IatEntry->FirstThunk +
156 (ForwarderChain * sizeof(IMAGE_THUNK_DATA)));
157
158 /* Get the Forwarder from the thunk */
159 ForwarderChain = (ULONG)FirstThunk->u1.Ordinal;
160
161 /* Snap the thunk */
163 {
164 Status = LdrpSnapThunk(ExportLdrEntry->DllBase,
165 ImportLdrEntry->DllBase,
166 OriginalThunk,
167 FirstThunk,
168 ExportDirectory,
169 ExportSize,
170 TRUE,
171 ImportName);
172
173 /* Move to the next thunk */
174 FirstThunk++;
176 {
177 /* Fail with the SEH error */
179 } _SEH2_END;
180
181 /* If we messed up, exit */
182 if (!NT_SUCCESS(Status)) break;
183 }
184 }
185 else if (IatEntry->FirstThunk)
186 {
187 /* Full snapping. Get the First thunk */
188 FirstThunk = (PIMAGE_THUNK_DATA)
189 ((ULONG_PTR)ImportLdrEntry->DllBase +
190 IatEntry->FirstThunk);
191
192 /* Get the NT Header */
193 NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase);
194
195 /* Get the Original thunk VA, watch out for weird images */
196 if ((IatEntry->Characteristics < NtHeader->OptionalHeader.SizeOfHeaders) ||
197 (IatEntry->Characteristics >= NtHeader->OptionalHeader.SizeOfImage))
198 {
199 /* Refuse it, this is a strange linked file */
200 OriginalThunk = FirstThunk;
201 }
202 else
203 {
204 /* Get the address from the field and convert to VA */
205 OriginalThunk = (PIMAGE_THUNK_DATA)
206 ((ULONG_PTR)ImportLdrEntry->DllBase +
207 IatEntry->OriginalFirstThunk);
208 }
209
210 /* Get the Import name VA */
211 ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase +
212 IatEntry->Name);
213
214 /* Loop while it's valid */
215 while (OriginalThunk->u1.AddressOfData)
216 {
217 /* Snap the Thunk */
219 {
220 Status = LdrpSnapThunk(ExportLdrEntry->DllBase,
221 ImportLdrEntry->DllBase,
222 OriginalThunk,
223 FirstThunk,
224 ExportDirectory,
225 ExportSize,
226 TRUE,
227 ImportName);
228
229 /* Next thunks */
230 OriginalThunk++;
231 FirstThunk++;
233 {
234 /* Fail with the SEH error */
236 } _SEH2_END;
237
238 /* If we failed the snap, break out */
239 if (!NT_SUCCESS(Status)) break;
240 }
241 }
242
243 /* Protect the IAT again */
245 &Iat,
246 &ImportSize,
247 OldProtect,
248 &OldProtect);
249
250 /* Also flush out the cache */
252
253 /* Return to Caller */
254 return Status;
255}
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define RtlImageNtHeader
Definition: compat.h:806
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSTATUS NTAPI LdrpSnapThunk(IN PVOID ExportBase, IN PVOID ImportBase, IN PIMAGE_THUNK_DATA OriginalThunk, IN OUT PIMAGE_THUNK_DATA Thunk, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN Static, IN LPSTR DllName)
Definition: ldrpe.c:950
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define NtCurrentProcess()
Definition: nt_native.h:1657
IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA
Definition: ntimage.h:565
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
NTSTATUS NTAPI NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UnsafeBaseAddress, IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG UnsafeOldAccessProtection)
Definition: virtual.c:3159
NTSTATUS NTAPI NtFlushInstructionCache(_In_ HANDLE ProcessHandle, _In_opt_ PVOID BaseAddress, _In_ SIZE_T FlushSize)
Definition: virtual.c:3092
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define IMAGE_DIRECTORY_ENTRY_IAT
Definition: pedump.c:271
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
union _IMAGE_SECTION_HEADER::@1555 Misc
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by LdrpHandleOneNewFormatImportDescriptor(), and LdrpHandleOneOldFormatImportDescriptor().

◆ LdrpSnapThunk()

NTSTATUS NTAPI LdrpSnapThunk ( IN PVOID  ExportBase,
IN PVOID  ImportBase,
IN PIMAGE_THUNK_DATA  OriginalThunk,
IN OUT PIMAGE_THUNK_DATA  Thunk,
IN PIMAGE_EXPORT_DIRECTORY  ExportDirectory,
IN ULONG  ExportSize,
IN BOOLEAN  Static,
IN LPSTR  DllName 
)

Definition at line 950 of file ldrpe.c.

958{
959 BOOLEAN IsOrdinal;
960 USHORT Ordinal;
961 ULONG OriginalOrdinal = 0;
962 PIMAGE_IMPORT_BY_NAME AddressOfData;
963 PULONG NameTable;
964 PUSHORT OrdinalTable;
965 LPSTR ImportName = NULL, DotPosition;
966 USHORT Hint;
968 ULONG_PTR HardErrorParameters[3];
969 UNICODE_STRING HardErrorDllName, HardErrorEntryPointName;
970 ANSI_STRING TempString;
971 ULONG Mask;
973 PULONG AddressOfFunctions;
974 UNICODE_STRING TempUString;
975 ANSI_STRING ForwarderName;
976 PANSI_STRING ForwardName;
977 PVOID ForwarderHandle;
978 ULONG ForwardOrdinal;
979
980 /* Check if the snap is by ordinal */
981 if ((IsOrdinal = IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)))
982 {
983 /* Get the ordinal number, and its normalized version */
984 OriginalOrdinal = IMAGE_ORDINAL(OriginalThunk->u1.Ordinal);
985 Ordinal = (USHORT)(OriginalOrdinal - ExportDirectory->Base);
986 }
987 else
988 {
989 /* First get the data VA */
990 AddressOfData = (PIMAGE_IMPORT_BY_NAME)
991 ((ULONG_PTR)ImportBase +
992 ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff));
993
994 /* Get the name */
995 ImportName = (LPSTR)AddressOfData->Name;
996
997 /* Now get the VA of the Name and Ordinal Tables */
998 NameTable = (PULONG)((ULONG_PTR)ExportBase +
999 (ULONG_PTR)ExportDirectory->AddressOfNames);
1000 OrdinalTable = (PUSHORT)((ULONG_PTR)ExportBase +
1001 (ULONG_PTR)ExportDirectory->AddressOfNameOrdinals);
1002
1003 /* Get the hint */
1004 Hint = AddressOfData->Hint;
1005
1006 /* Try to get a match by using the hint */
1007 if (((ULONG)Hint < ExportDirectory->NumberOfNames) &&
1008 (!strcmp(ImportName, ((LPSTR)((ULONG_PTR)ExportBase + NameTable[Hint])))))
1009 {
1010 /* We got a match, get the Ordinal from the hint */
1011 Ordinal = OrdinalTable[Hint];
1012 }
1013 else
1014 {
1015 /* Well bummer, hint didn't work, do it the long way */
1016 Ordinal = LdrpNameToOrdinal(ImportName,
1017 ExportDirectory->NumberOfNames,
1018 ExportBase,
1019 NameTable,
1020 OrdinalTable);
1021 }
1022 }
1023
1024 /* Check if the ordinal is invalid */
1025 if ((ULONG)Ordinal >= ExportDirectory->NumberOfFunctions)
1026 {
1027FailurePath:
1028 /* Is this a static snap? */
1029 if (Static)
1030 {
1031 UNICODE_STRING SnapTarget;
1032 PLDR_DATA_TABLE_ENTRY LdrEntry;
1033
1034 /* What was the module we were searching in */
1035 RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown");
1036
1037 /* What was the module we were searching for */
1038 if (LdrpCheckForLoadedDllHandle(ImportBase, &LdrEntry))
1039 SnapTarget = LdrEntry->BaseDllName;
1040 else
1041 RtlInitUnicodeString(&SnapTarget, L"Unknown");
1042
1043 /* Inform the debug log */
1044 if (IsOrdinal)
1045 DPRINT1("Failed to snap ordinal %Z!0x%x for %wZ\n", &TempString, OriginalOrdinal, &SnapTarget);
1046 else
1047 DPRINT1("Failed to snap %Z!%s for %wZ\n", &TempString, ImportName, &SnapTarget);
1048
1049 /* These are critical errors. Setup a string for the DLL name */
1050 RtlAnsiStringToUnicodeString(&HardErrorDllName, &TempString, TRUE);
1051
1052 /* Set it as the parameter */
1053 HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllName;
1054 Mask = 2;
1055
1056 /* Check if we have an ordinal */
1057 if (IsOrdinal)
1058 {
1059 /* Then set the ordinal as the 1st parameter */
1060 HardErrorParameters[0] = OriginalOrdinal;
1061 }
1062 else
1063 {
1064 /* We don't, use the entrypoint. Set up a string for it */
1065 RtlInitAnsiString(&TempString, ImportName);
1066 RtlAnsiStringToUnicodeString(&HardErrorEntryPointName,
1067 &TempString,
1068 TRUE);
1069
1070 /* Set it as the parameter */
1071 HardErrorParameters[0] = (ULONG_PTR)&HardErrorEntryPointName;
1072 Mask = 3;
1073 }
1074
1075 /* Raise the error */
1078 2,
1079 Mask,
1080 HardErrorParameters,
1081 OptionOk,
1082 &Response);
1083
1084 /* Increase the error count */
1086
1087 /* Free our string */
1088 RtlFreeUnicodeString(&HardErrorDllName);
1089 if (!IsOrdinal)
1090 {
1091 /* Free our second string. Return entrypoint error */
1092 RtlFreeUnicodeString(&HardErrorEntryPointName);
1094 }
1095
1096 /* Return ordinal error */
1098 }
1099 else
1100 {
1101 /* Inform the debug log */
1102 if (IsOrdinal)
1103 DPRINT("Non-fatal: Failed to snap ordinal 0x%x\n", OriginalOrdinal);
1104 else
1105 DPRINT("Non-fatal: Failed to snap %s\n", ImportName);
1106 }
1107
1108 /* Set this as a bad DLL */
1109 Thunk->u1.Function = (ULONG_PTR)0xffbadd11;
1110
1111 /* Return the right error code */
1112 Status = IsOrdinal ? STATUS_ORDINAL_NOT_FOUND :
1114 }
1115 else
1116 {
1117 /* The ordinal seems correct, get the AddressOfFunctions VA */
1118 AddressOfFunctions = (PULONG)
1119 ((ULONG_PTR)ExportBase +
1120 (ULONG_PTR)ExportDirectory->AddressOfFunctions);
1121
1122 /* Write the function pointer*/
1123 Thunk->u1.Function = (ULONG_PTR)ExportBase + AddressOfFunctions[Ordinal];
1124
1125 /* Make sure it's within the exports */
1126 if ((Thunk->u1.Function > (ULONG_PTR)ExportDirectory) &&
1127 (Thunk->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
1128 {
1129 /* Get the Import and Forwarder Names */
1130 ImportName = (LPSTR)Thunk->u1.Function;
1131
1132 DotPosition = strchr(ImportName, '.');
1133 ASSERT(DotPosition != NULL);
1134 if (!DotPosition)
1135 goto FailurePath;
1136
1137 ForwarderName.Buffer = ImportName;
1138 ForwarderName.Length = (USHORT)(DotPosition - ImportName);
1139 ForwarderName.MaximumLength = ForwarderName.Length;
1140 Status = RtlAnsiStringToUnicodeString(&TempUString,
1141 &ForwarderName,
1142 TRUE);
1143
1144 /* Make sure the conversion was OK */
1145 if (NT_SUCCESS(Status))
1146 {
1148 UNICODE_STRING StaticString, *RedirectedImportName;
1149 BOOLEAN Redirected = FALSE;
1150
1151 RtlInitEmptyUnicodeString(&StaticString, StringBuffer, sizeof(StringBuffer));
1152
1153 /* Check if the SxS Assemblies specify another file */
1155 &TempUString,
1157 &StaticString,
1158 NULL,
1159 &RedirectedImportName,
1160 NULL,
1161 NULL,
1162 NULL);
1163 if (NT_SUCCESS(Status))
1164 {
1165 if (ShowSnaps)
1166 {
1167 DPRINT1("LDR: %Z got redirected to %wZ\n", &ForwarderName, RedirectedImportName);
1168 }
1169 /* Let Ldrp know */
1170 Redirected = TRUE;
1171 }
1172 else
1173 {
1174 RedirectedImportName = &TempUString;
1175 }
1176
1177 /* Load the forwarder */
1178 Status = LdrpLoadDll(Redirected,
1179 NULL,
1180 NULL,
1181 RedirectedImportName,
1182 &ForwarderHandle,
1183 FALSE);
1184
1185 RtlFreeUnicodeString(&TempUString);
1186 }
1187
1188 /* If the load or conversion failed, use the failure path */
1189 if (!NT_SUCCESS(Status)) goto FailurePath;
1190
1191 /* Now set up a name for the actual forwarder dll */
1192 RtlInitAnsiString(&ForwarderName,
1193 ImportName + ForwarderName.Length + sizeof(CHAR));
1194
1195 /* Check if it's an ordinal forward */
1196 if ((ForwarderName.Length > 1) && (*ForwarderName.Buffer == '#'))
1197 {
1198 /* We don't have an actual function name */
1199 ForwardName = NULL;
1200
1201 /* Convert the string into an ordinal */
1202 Status = RtlCharToInteger(ForwarderName.Buffer + sizeof(CHAR),
1203 0,
1204 &ForwardOrdinal);
1205
1206 /* If this fails, then error out */
1207 if (!NT_SUCCESS(Status)) goto FailurePath;
1208 }
1209 else
1210 {
1211 /* Import by name */
1212 ForwardName = &ForwarderName;
1213 ForwardOrdinal = 0;
1214 }
1215
1216 /* Get the pointer */
1217 Status = LdrpGetProcedureAddress(ForwarderHandle,
1218 ForwardName,
1219 ForwardOrdinal,
1220 (PVOID*)&Thunk->u1.Function,
1221 FALSE);
1222 /* If this fails, then error out */
1223 if (!NT_SUCCESS(Status)) goto FailurePath;
1224 }
1225 else
1226 {
1227 /* It's not within the exports, let's hope it's valid */
1228 if (!AddressOfFunctions[Ordinal]) goto FailurePath;
1229 }
1230
1231 /* If we got here, then it's success */
1233 }
1234
1235 /* Return status */
1236 return Status;
1237}
IN PUNICODE_STRING StaticString
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define MAX_PATH
Definition: compat.h:34
#define ULONG_PTR
Definition: config.h:101
unsigned int Mask
Definition: fpcontrol.c:82
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:551
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
USHORT NTAPI LdrpNameToOrdinal(IN LPSTR ImportName, IN ULONG NumberOfNames, IN PVOID ExportBase, IN PULONG NameTable, IN PUSHORT OrdinalTable)
Definition: ldrpe.c:628
#define ASSERT(a)
Definition: mode.c:44
@ OptionOk
Definition: extypes.h:187
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI RtlCharToInteger(PCSZ String, ULONG Base, PULONG Value)
Definition: unicode.c:261
BOOLEAN LdrpInLdrInit
Definition: ldrinit.c:30
BOOLEAN NTAPI LdrpCheckForLoadedDllHandle(IN PVOID Base, OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
Definition: ldrutils.c:1621
NTSTATUS NTAPI LdrpLoadDll(IN BOOLEAN Redirected, IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress, IN BOOLEAN CallInit)
Definition: ldrutils.c:2435
NTSTATUS NTAPI LdrpGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress, _In_ BOOLEAN ExecuteInit)
Definition: ldrutils.c:2252
ULONG LdrpFatalHardErrorCount
Definition: ldrinit.c:83
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
#define STATUS_ORDINAL_NOT_FOUND
Definition: ntstatus.h:548
#define STATUS_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:549
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
unsigned short USHORT
Definition: pedump.c:61
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
Definition: ncftp.h:89
Definition: window.h:585
USHORT MaximumLength
Definition: env_spec_w32.h:377
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
char CHAR
Definition: xmlstorage.h:175

Referenced by LdrpGetProcedureAddress(), and LdrpSnapIAT().

◆ LdrpWalkImportDescriptor()

NTSTATUS NTAPI LdrpWalkImportDescriptor ( IN LPWSTR DllPath  OPTIONAL,
IN PLDR_DATA_TABLE_ENTRY  LdrEntry 
)

Definition at line 670 of file ldrpe.c.

672{
673 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
675 NTSTATUS Status = STATUS_SUCCESS, Status2;
677 PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
678 ULONG BoundSize, IatSize;
679
680 DPRINT("LdrpWalkImportDescriptor - BEGIN (%wZ %p '%S')\n", &LdrEntry->BaseDllName, LdrEntry, DllPath);
681
682 /* Set up the Act Ctx */
683 RtlZeroMemory(&ActCtx, sizeof(ActCtx));
684 ActCtx.Size = sizeof(ActCtx);
686
687 /* Check if we have a manifest prober routine */
689 {
690 /* Probe the DLL for its manifest. Some details are omitted */
691 Status2 = LdrpManifestProberRoutine(LdrEntry->DllBase, LdrEntry->FullDllName.Buffer, &LdrEntry->EntryPointActivationContext);
692
693 if (!NT_SUCCESS(Status2) &&
694 Status2 != STATUS_NO_SUCH_FILE &&
699 {
700 /* Some serious issue */
701 //Status = Status2; // FIXME: Ignore that error for now
704 "LDR: LdrpWalkImportDescriptor() failed to probe %wZ for its "
705 "manifest, ntstatus = 0x%08lx\n",
706 &LdrEntry->FullDllName, Status2);
707 }
708 }
709
710 /* Check if we failed above */
711 if (!NT_SUCCESS(Status)) return Status;
712
713 /* Get the Active ActCtx */
714 if (!LdrEntry->EntryPointActivationContext)
715 {
716 Status = RtlGetActiveActivationContext(&LdrEntry->EntryPointActivationContext);
717
718 if (!NT_SUCCESS(Status))
719 {
720 /* Exit */
723 "LDR: RtlGetActiveActivationContext() failed; ntstatus = "
724 "0x%08lx\n",
725 Status);
726 return Status;
727 }
728 }
729
730 /* Activate the ActCtx */
732 LdrEntry->EntryPointActivationContext);
733
734 /* Check if we were redirected */
735 if (!(LdrEntry->Flags & LDRP_REDIRECTED))
736 {
737 /* Get the Bound IAT */
738 BoundEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
739 TRUE,
741 &BoundSize);
742 }
743
744 /* Get the regular IAT, for fallback */
745 ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
746 TRUE,
748 &IatSize);
749
750 /* Check if we got at least one */
751 if ((BoundEntry) || (ImportEntry))
752 {
753 /* Do we have a Bound IAT */
754 if (BoundEntry)
755 {
756 /* Handle the descriptor */
758 LdrEntry,
759 BoundEntry);
760 }
761 else
762 {
763 /* Handle the descriptor */
765 LdrEntry,
766 ImportEntry);
767 }
768
769 /* Check the status of the handlers */
770 if (NT_SUCCESS(Status))
771 {
772 /* Check for Per-DLL Heap Tagging */
774 {
775 /* FIXME */
776 DPRINT1("We don't support Per-DLL Heap Tagging yet!\n");
777 }
778
779 /* Check if Page Heap was enabled */
781 {
782 /* Initialize target DLL */
784 }
785
786 /* Check if Application Verifier was enabled */
788 {
789 AVrfDllLoadNotification(LdrEntry);
790 }
791
792 /* Just to be safe */
794 }
795 }
796
797 /* Release the activation context */
799
800 DPRINT("LdrpWalkImportDescriptor - END (%wZ %p)\n", &LdrEntry->BaseDllName, LdrEntry);
801
802 /* Return status */
803 return Status;
804}
@ DPFLTR_SXS_ID
Definition: dpfilter.h:79
#define FLG_HEAP_PAGE_ALLOCS
Definition: pstypes.h:84
#define FLG_APPLICATION_VERIFIER
Definition: pstypes.h:64
#define FLG_HEAP_ENABLE_TAG_BY_DLL
Definition: pstypes.h:70
NTSYSAPI NTSTATUS WINAPI RtlGetActiveActivationContext(HANDLE *)
Definition: actctx.c:5482
NTSTATUS NTAPI LdrpHandleOldFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry)
Definition: ldrpe.c:606
PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine
Definition: ldrpe.c:18
NTSTATUS NTAPI LdrpHandleNewFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry)
Definition: ldrpe.c:492
#define LDRP_REDIRECTED
Definition: ldrtypes.h:58
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
#define DPFLTR_WARNING_LEVEL
Definition: kdtypes.h:31
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
VOID NTAPI AVrfDllLoadNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: verifier.c:294
VOID NTAPI AVrfPageHeapDllNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: verifier.c:361
#define STATUS_RESOURCE_LANG_NOT_FOUND
Definition: ntstatus.h:648
#define STATUS_RESOURCE_NAME_NOT_FOUND
Definition: ntstatus.h:375
#define STATUS_RESOURCE_TYPE_NOT_FOUND
Definition: ntstatus.h:374
#define STATUS_RESOURCE_DATA_NOT_FOUND
Definition: ntstatus.h:373
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
Definition: pedump.c:270
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame, IN PVOID Context)
Definition: actctx.c:5934
PRTL_ACTIVATION_CONTEXT_STACK_FRAME FASTCALL RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
Definition: actctx.c:6011
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137

Referenced by LdrpInitializeProcess(), LdrpLoadDll(), and LdrpLoadImportModule().

Variable Documentation

◆ LdrpManifestProberRoutine

PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine

Definition at line 18 of file ldrpe.c.

Referenced by LdrpWalkImportDescriptor(), and LdrSetDllManifestProber().

◆ LdrpNormalSnap

ULONG LdrpNormalSnap