ReactOS 0.4.15-dev-8241-g63935f8
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::@2145 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, &LdrApiDefaultExtension, NULL, &RedirectedImpDescName, &ImpDescName, &RedirectedDll);
881
882 if (!NT_SUCCESS(Status))
883 {
884 /* Unrecoverable SxS failure */
885 DPRINT1("LDR: LdrpApplyFileNameRedirection failed with status %x for dll %wZ\n", Status, ImpDescName);
886 goto done;
887 }
888
889 /* Check if it's loaded */
891 ImpDescName,
892 TRUE,
893 RedirectedDll,
894 DataTableEntry))
895 {
896 /* It's already existing in the list */
897 *Existing = TRUE;
899 goto done;
900 }
901
902 /* We're loading it for the first time */
903 *Existing = FALSE;
904
905 /* Map it */
907 NULL,
908 ImpDescName->Buffer,
909 NULL,
910 TRUE,
911 RedirectedDll,
912 DataTableEntry);
913 if (!NT_SUCCESS(Status))
914 {
915 DPRINT1("LDR: LdrpMapDll failed with status %x for dll %wZ\n", Status, ImpDescName);
916 goto done;
917 }
918
919 /* Walk its import descriptor table */
921 *DataTableEntry);
922 if (!NT_SUCCESS(Status))
923 {
924 /* Add it to the in-init-order list in case of failure */
926 &(*DataTableEntry)->InInitializationOrderLinks);
927 }
928
929done:
930 RtlFreeUnicodeString(&RedirectedImpDescName);
931
932 return Status;
933}
#define VOID
Definition: acefi.h:82
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
@ 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:65
#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
NTSYSAPI NTSTATUS NTAPI LdrpApplyFileNameRedirection(_In_ PUNICODE_STRING OriginalName, _In_ PUNICODE_STRING Extension, _Inout_opt_ PUNICODE_STRING StaticString, _Inout_opt_ PUNICODE_STRING DynamicString, _Inout_ PUNICODE_STRING *NewName, _Inout_ PBOOLEAN RedirectedDll)
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:997
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:1953
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define L(x)
Definition: ntvdm.h:50
#define DPRINT
Definition: sndvol32.h:73
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:937
#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:3111
NTSTATUS NTAPI NtFlushInstructionCache(_In_ HANDLE ProcessHandle, _In_opt_ PVOID BaseAddress, _In_ SIZE_T FlushSize)
Definition: virtual.c:3044
#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:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
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::@1565 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 937 of file ldrpe.c.

945{
946 BOOLEAN IsOrdinal;
947 USHORT Ordinal;
948 ULONG OriginalOrdinal = 0;
949 PIMAGE_IMPORT_BY_NAME AddressOfData;
950 PULONG NameTable;
951 PUSHORT OrdinalTable;
952 LPSTR ImportName = NULL, DotPosition;
953 USHORT Hint;
955 ULONG_PTR HardErrorParameters[3];
956 UNICODE_STRING HardErrorDllName, HardErrorEntryPointName;
957 ANSI_STRING TempString;
958 ULONG Mask;
960 PULONG AddressOfFunctions;
961 UNICODE_STRING TempUString;
962 ANSI_STRING ForwarderName;
963 PANSI_STRING ForwardName;
964 PVOID ForwarderHandle;
965 ULONG ForwardOrdinal;
966
967 /* Check if the snap is by ordinal */
968 if ((IsOrdinal = IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)))
969 {
970 /* Get the ordinal number, and its normalized version */
971 OriginalOrdinal = IMAGE_ORDINAL(OriginalThunk->u1.Ordinal);
972 Ordinal = (USHORT)(OriginalOrdinal - ExportDirectory->Base);
973 }
974 else
975 {
976 /* First get the data VA */
977 AddressOfData = (PIMAGE_IMPORT_BY_NAME)
978 ((ULONG_PTR)ImportBase +
979 ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff));
980
981 /* Get the name */
982 ImportName = (LPSTR)AddressOfData->Name;
983
984 /* Now get the VA of the Name and Ordinal Tables */
985 NameTable = (PULONG)((ULONG_PTR)ExportBase +
986 (ULONG_PTR)ExportDirectory->AddressOfNames);
987 OrdinalTable = (PUSHORT)((ULONG_PTR)ExportBase +
988 (ULONG_PTR)ExportDirectory->AddressOfNameOrdinals);
989
990 /* Get the hint */
991 Hint = AddressOfData->Hint;
992
993 /* Try to get a match by using the hint */
994 if (((ULONG)Hint < ExportDirectory->NumberOfNames) &&
995 (!strcmp(ImportName, ((LPSTR)((ULONG_PTR)ExportBase + NameTable[Hint])))))
996 {
997 /* We got a match, get the Ordinal from the hint */
998 Ordinal = OrdinalTable[Hint];
999 }
1000 else
1001 {
1002 /* Well bummer, hint didn't work, do it the long way */
1003 Ordinal = LdrpNameToOrdinal(ImportName,
1004 ExportDirectory->NumberOfNames,
1005 ExportBase,
1006 NameTable,
1007 OrdinalTable);
1008 }
1009 }
1010
1011 /* Check if the ordinal is invalid */
1012 if ((ULONG)Ordinal >= ExportDirectory->NumberOfFunctions)
1013 {
1014FailurePath:
1015 /* Is this a static snap? */
1016 if (Static)
1017 {
1018 UNICODE_STRING SnapTarget;
1019 PLDR_DATA_TABLE_ENTRY LdrEntry;
1020
1021 /* What was the module we were searching in */
1022 RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown");
1023
1024 /* What was the module we were searching for */
1025 if (LdrpCheckForLoadedDllHandle(ImportBase, &LdrEntry))
1026 SnapTarget = LdrEntry->BaseDllName;
1027 else
1028 RtlInitUnicodeString(&SnapTarget, L"Unknown");
1029
1030 /* Inform the debug log */
1031 if (IsOrdinal)
1032 DPRINT1("Failed to snap ordinal %Z!0x%x for %wZ\n", &TempString, OriginalOrdinal, &SnapTarget);
1033 else
1034 DPRINT1("Failed to snap %Z!%s for %wZ\n", &TempString, ImportName, &SnapTarget);
1035
1036 /* These are critical errors. Setup a string for the DLL name */
1037 RtlAnsiStringToUnicodeString(&HardErrorDllName, &TempString, TRUE);
1038
1039 /* Set it as the parameter */
1040 HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllName;
1041 Mask = 2;
1042
1043 /* Check if we have an ordinal */
1044 if (IsOrdinal)
1045 {
1046 /* Then set the ordinal as the 1st parameter */
1047 HardErrorParameters[0] = OriginalOrdinal;
1048 }
1049 else
1050 {
1051 /* We don't, use the entrypoint. Set up a string for it */
1052 RtlInitAnsiString(&TempString, ImportName);
1053 RtlAnsiStringToUnicodeString(&HardErrorEntryPointName,
1054 &TempString,
1055 TRUE);
1056
1057 /* Set it as the parameter */
1058 HardErrorParameters[0] = (ULONG_PTR)&HardErrorEntryPointName;
1059 Mask = 3;
1060 }
1061
1062 /* Raise the error */
1065 2,
1066 Mask,
1067 HardErrorParameters,
1068 OptionOk,
1069 &Response);
1070
1071 /* Increase the error count */
1073
1074 /* Free our string */
1075 RtlFreeUnicodeString(&HardErrorDllName);
1076 if (!IsOrdinal)
1077 {
1078 /* Free our second string. Return entrypoint error */
1079 RtlFreeUnicodeString(&HardErrorEntryPointName);
1081 }
1082
1083 /* Return ordinal error */
1085 }
1086 else
1087 {
1088 /* Inform the debug log */
1089 if (IsOrdinal)
1090 DPRINT("Non-fatal: Failed to snap ordinal 0x%x\n", OriginalOrdinal);
1091 else
1092 DPRINT("Non-fatal: Failed to snap %s\n", ImportName);
1093 }
1094
1095 /* Set this as a bad DLL */
1096 Thunk->u1.Function = (ULONG_PTR)0xffbadd11;
1097
1098 /* Return the right error code */
1099 Status = IsOrdinal ? STATUS_ORDINAL_NOT_FOUND :
1101 }
1102 else
1103 {
1104 /* The ordinal seems correct, get the AddressOfFunctions VA */
1105 AddressOfFunctions = (PULONG)
1106 ((ULONG_PTR)ExportBase +
1107 (ULONG_PTR)ExportDirectory->AddressOfFunctions);
1108
1109 /* Write the function pointer*/
1110 Thunk->u1.Function = (ULONG_PTR)ExportBase + AddressOfFunctions[Ordinal];
1111
1112 /* Make sure it's within the exports */
1113 if ((Thunk->u1.Function > (ULONG_PTR)ExportDirectory) &&
1114 (Thunk->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
1115 {
1116 /* Get the Import and Forwarder Names */
1117 ImportName = (LPSTR)Thunk->u1.Function;
1118
1119 DotPosition = strchr(ImportName, '.');
1120 ASSERT(DotPosition != NULL);
1121 if (!DotPosition)
1122 goto FailurePath;
1123
1124 ForwarderName.Buffer = ImportName;
1125 ForwarderName.Length = (USHORT)(DotPosition - ImportName);
1126 ForwarderName.MaximumLength = ForwarderName.Length;
1127 Status = RtlAnsiStringToUnicodeString(&TempUString,
1128 &ForwarderName,
1129 TRUE);
1130
1131 /* Make sure the conversion was OK */
1132 if (NT_SUCCESS(Status))
1133 {
1135 UNICODE_STRING StaticString, *RedirectedImportName;
1136 BOOLEAN Redirected = FALSE;
1137
1138 RtlInitEmptyUnicodeString(&StaticString, StringBuffer, sizeof(StringBuffer));
1139
1140 /* Check if the SxS Assemblies specify another file */
1142 &TempUString, &LdrApiDefaultExtension, &StaticString, NULL, &RedirectedImportName, &Redirected);
1143
1144 if (NT_SUCCESS(Status) && Redirected)
1145 {
1146 if (ShowSnaps)
1147 DPRINT1("LDR: %Z got redirected to %wZ\n", &ForwarderName, RedirectedImportName);
1148 }
1149 else
1150 {
1151 RedirectedImportName = &TempUString;
1152 }
1153
1154 /* Load the forwarder */
1155 Status = LdrpLoadDll(Redirected,
1156 NULL,
1157 NULL,
1158 RedirectedImportName,
1159 &ForwarderHandle,
1160 FALSE);
1161
1162 RtlFreeUnicodeString(&TempUString);
1163 }
1164
1165 /* If the load or conversion failed, use the failure path */
1166 if (!NT_SUCCESS(Status)) goto FailurePath;
1167
1168 /* Now set up a name for the actual forwarder dll */
1169 RtlInitAnsiString(&ForwarderName,
1170 ImportName + ForwarderName.Length + sizeof(CHAR));
1171
1172 /* Check if it's an ordinal forward */
1173 if ((ForwarderName.Length > 1) && (*ForwarderName.Buffer == '#'))
1174 {
1175 /* We don't have an actual function name */
1176 ForwardName = NULL;
1177
1178 /* Convert the string into an ordinal */
1179 Status = RtlCharToInteger(ForwarderName.Buffer + sizeof(CHAR),
1180 0,
1181 &ForwardOrdinal);
1182
1183 /* If this fails, then error out */
1184 if (!NT_SUCCESS(Status)) goto FailurePath;
1185 }
1186 else
1187 {
1188 /* Import by name */
1189 ForwardName = &ForwarderName;
1190 ForwardOrdinal = 0;
1191 }
1192
1193 /* Get the pointer */
1194 Status = LdrpGetProcedureAddress(ForwarderHandle,
1195 ForwardName,
1196 ForwardOrdinal,
1197 (PVOID*)&Thunk->u1.Function,
1198 FALSE);
1199 /* If this fails, then error out */
1200 if (!NT_SUCCESS(Status)) goto FailurePath;
1201 }
1202 else
1203 {
1204 /* It's not within the exports, let's hope it's valid */
1205 if (!AddressOfFunctions[Ordinal]) goto FailurePath;
1206 }
1207
1208 /* If we got here, then it's success */
1210 }
1211
1212 /* Return status */
1213 return Status;
1214}
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:1595
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:2409
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:2226
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 */
731 RtlActivateActivationContextUnsafeFast(&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 */
798 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
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:5528
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
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