#include <debug.h>
/* GLOBALS *******************************************************************/
-ULONG LdrpFatalHardErrorCount;
-PVOID LdrpManifestProberRoutine;
-/* PROTOTYPES ****************************************************************/
+PVOID LdrpManifestProberRoutine;
+ULONG LdrpNormalSnap;
-#define IMAGE_REL_BASED_HIGH3ADJ 11
+/* FUNCTIONS *****************************************************************/
-NTSTATUS
+VOID
NTAPI
-LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
- IN LPSTR ImportName,
- IN PVOID DllBase,
- OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry,
- OUT PBOOLEAN Existing);
+AVrfPageHeapDllNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
+{
+ /* Check if page heap dll notification is turned on */
+ if (!(RtlpDphGlobalFlags & DPH_FLAG_DLL_NOTIFY))
+ return;
-/* FUNCTIONS *****************************************************************/
+ /* We don't support this flag currently */
+ UNIMPLEMENTED;
+}
NTSTATUS
NTAPI
IN PIMAGE_IMPORT_DESCRIPTOR IatEntry,
IN BOOLEAN EntriesValid)
{
- PIMAGE_EXPORT_DIRECTORY ExportDirectory;
- ULONG ExportSize;
PVOID Iat;
- SIZE_T ImportSize;
- ULONG IatSize;
- //PPEB Peb = NtCurrentPeb();
NTSTATUS Status;
PIMAGE_THUNK_DATA OriginalThunk, FirstThunk;
- LPSTR ImportName;
- ULONG ForwarderChain;
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_SECTION_HEADER SectionHeader;
- ULONG i, Rva;
- ULONG OldProtect;
-
+ PIMAGE_EXPORT_DIRECTORY ExportDirectory;
+ LPSTR ImportName;
+ ULONG ForwarderChain, i, Rva, OldProtect, IatSize, ExportSize;
+ SIZE_T ImportSize;
DPRINT("LdrpSnapIAT(%wZ %wZ %p %d)\n", &ExportLdrEntry->BaseDllName, &ImportLdrEntry->BaseDllName, IatEntry, EntriesValid);
/* Get export directory */
&ExportSize);
/* Make sure it has one */
- if (!ExportDirectory) return STATUS_INVALID_IMAGE_FORMAT;
+ if (!ExportDirectory)
+ {
+ /* Fail */
+ DbgPrint("LDR: %wZ doesn't contain an EXPORT table\n",
+ &ExportLdrEntry->BaseDllName);
+ return STATUS_INVALID_IMAGE_FORMAT;
+ }
/* Get the IAT */
Iat = RtlImageDirectoryEntryToData(ImportLdrEntry->DllBase,
{
/* Get the NT Header and the first section */
NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase);
+ if (!NtHeader) return STATUS_INVALID_IMAGE_FORMAT;
SectionHeader = IMAGE_FIRST_SECTION(NtHeader);
/* Get the RVA of the import directory */
IatSize = SectionHeader->Misc.VirtualSize;
/* Deal with Watcom and other retarded compilers */
- if (!IatSize)
- IatSize = SectionHeader->SizeOfRawData;
+ if (!IatSize) IatSize = SectionHeader->SizeOfRawData;
/* Found it, get out */
break;
}
/* If we still don't have an IAT, that's bad */
- if (!Iat) return STATUS_INVALID_IMAGE_FORMAT;
+ if (!Iat)
+ {
+ /* Fail */
+ DbgPrint("LDR: Unable to unprotect IAT for %wZ (Image Base %p)\n",
+ &ImportLdrEntry->BaseDllName,
+ ImportLdrEntry->DllBase);
+ return STATUS_INVALID_IMAGE_FORMAT;
+ }
/* Set the right size */
ImportSize = IatSize;
&ImportSize,
PAGE_READWRITE,
&OldProtect);
- if (!NT_SUCCESS(Status)) return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ DbgPrint("LDR: Unable to unprotect IAT for %wZ (Status %x)\n",
+ &ImportLdrEntry->BaseDllName,
+ Status);
+ return Status;
+ }
/* Check if the Thunks are already valid */
if (EntriesValid)
if (Stale)
{
/* It was, so find the IAT entry for it */
+ ++LdrpNormalSnap;
ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
NTAPI
LdrpHandleOneOldFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
IN PLDR_DATA_TABLE_ENTRY LdrEntry,
- IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry)
+ IN PIMAGE_IMPORT_DESCRIPTOR *ImportEntry)
{
- //ULONG IatSize, i;
LPSTR ImportName;
NTSTATUS Status;
- BOOLEAN AlreadyLoaded = FALSE, StaticEntriesValid = FALSE, SkipSnap = FALSE;
+ BOOLEAN AlreadyLoaded = FALSE;
PLDR_DATA_TABLE_ENTRY DllLdrEntry;
PIMAGE_THUNK_DATA FirstThunk;
PPEB Peb = NtCurrentPeb();
/* Get the import name's VA */
- ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name);
+ ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + (*ImportEntry)->Name);
/* Get the first thunk */
FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrEntry->DllBase +
- ImportEntry->FirstThunk);
+ (*ImportEntry)->FirstThunk);
/* Make sure it's valid */
if (!FirstThunk->u1.Function) goto SkipEntry;
LdrEntry->DllBase,
&DllLdrEntry,
&AlreadyLoaded);
- if (!NT_SUCCESS(Status)) return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ if (ShowSnaps)
+ {
+ DbgPrint("LDR: LdrpWalkImportTable - LdrpLoadImportModule failed "
+ "on import %s with status %x\n",
+ ImportName,
+ Status);
+ }
+
+ /* Return */
+ return Status;
+ }
/* Show debug message */
if (ShowSnaps)
ImportName);
}
- /* Check if the image was bound when compiled */
- if (ImportEntry->OriginalFirstThunk)
- {
- /* It was, so check if the static IAT entries are still valid */
- if ((ImportEntry->TimeDateStamp) &&
- (ImportEntry->TimeDateStamp == DllLdrEntry->TimeDateStamp) &&
- (!(DllLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE)))
- {
- /* Show debug message */
- if (ShowSnaps)
- {
- DPRINT1("LDR: Snap bypass %s from %wZ\n",
- ImportName,
- &LdrEntry->BaseDllName);
- }
-
- /*
- * They are still valid, so we can skip snapping them.
- * Additionally, if we have no forwarders, we are totally
- * done.
- */
- if (ImportEntry->ForwarderChain == -1)
- {
- /* Totally skip LdrpSnapIAT */
- SkipSnap = TRUE;
- }
- else
- {
- /* Set this so LdrpSnapIAT will only do forwarders */
- StaticEntriesValid = TRUE;
- }
- }
- }
-
/* Check if it wasn't already loaded */
+ ++LdrpNormalSnap;
if (!AlreadyLoaded)
{
/* Add the DLL to our list */
&DllLdrEntry->InInitializationOrderModuleList);
}
- /* Check if we should snap at all */
- if (!SkipSnap)
+ /* Now snap the IAT Entry */
+ Status = LdrpSnapIAT(DllLdrEntry, LdrEntry, *ImportEntry, FALSE);
+ if (!NT_SUCCESS(Status))
{
- /* Now snap the IAT Entry */
- Status = LdrpSnapIAT(DllLdrEntry,
- LdrEntry,
- ImportEntry,
- StaticEntriesValid);
- if (!NT_SUCCESS(Status)) return Status;
+ /* Fail */
+ if (ShowSnaps)
+ {
+ DbgPrint("LDR: LdrpWalkImportTable - LdrpSnapIAT #2 failed with "
+ "status %x\n",
+ Status);
+ }
+
+ /* Return */
+ return Status;
}
SkipEntry:
+ /* Move on */
+ (*ImportEntry)++;
return STATUS_SUCCESS;
}
NTSTATUS Status;
/* Check for Name and Thunk */
- while (ImportEntry->Name && ImportEntry->FirstThunk)
+ while ((ImportEntry->Name) && (ImportEntry->FirstThunk))
{
/* Parse this descriptor */
Status = LdrpHandleOneOldFormatImportDescriptor(DllPath,
LdrEntry,
- ImportEntry);
+ &ImportEntry);
if (!NT_SUCCESS(Status)) return Status;
-
- /* Move to the next entry */
- ImportEntry++;
}
/* Done */
return STATUS_SUCCESS;
}
-USHORT NTAPI
-LdrpNameToOrdinal(LPSTR ImportName,
- ULONG NumberOfNames,
- PVOID ExportBase,
- PULONG NameTable,
- PUSHORT OrdinalTable)
+USHORT
+NTAPI
+LdrpNameToOrdinal(IN LPSTR ImportName,
+ IN ULONG NumberOfNames,
+ IN PVOID ExportBase,
+ IN PULONG NameTable,
+ IN PUSHORT OrdinalTable)
{
- ULONG Start, End, Next;
- LONG CmpResult;
+ LONG Start, End, Next, CmpResult;
/* Use classical binary search to find the ordinal */
- Start = 0;
+ Start = Next = 0;
End = NumberOfNames - 1;
while (End >= Start)
{
/* We didn't find, update our range then */
if (CmpResult < 0)
+ {
End = Next - 1;
+ }
else if (CmpResult > 0)
+ {
Start = Next + 1;
+ }
}
/* If end is before start, then the search failed */
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry = NULL;
PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
ULONG BoundSize, IatSize;
-
DPRINT("LdrpWalkImportDescriptor('%S' %x)\n", DllPath, LdrEntry);
/* Set up the Act Ctx */
+ RtlZeroMemory(&ActCtx, sizeof(ActCtx));
ActCtx.Size = sizeof(ActCtx);
- ActCtx.Format = 1;
- RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
+ ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER;
/* Check if we have a manifest prober routine */
if (LdrpManifestProberRoutine)
/* Get the Active ActCtx */
Status = RtlGetActiveActivationContext(&LdrEntry->EntryPointActivationContext);
- if (!NT_SUCCESS(Status)) return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ /* Exit */
+ DbgPrintEx(51, // DPFLTR_SXS_ID
+ DPFLTR_WARNING_LEVEL,
+ "LDR: RtlGetActiveActivationContext() failed; ntstatus = "
+ "0x%08lx\n",
+ Status);
+ return Status;
+ }
/* Activate the ActCtx */
RtlActivateActivationContextUnsafeFast(&ActCtx,
&IatSize);
/* Check if we got at least one */
- if (BoundEntry || ImportEntry)
+ if ((BoundEntry) || (ImportEntry))
{
/* Do we have a Bound IAT */
if (BoundEntry)
/* Check if Page Heap was enabled */
if (Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS)
{
- /* FIXME */
- DPRINT1("We don't support Page Heaps yet!\n");
+ /* Initialize target DLL */
+ AVrfPageHeapDllNotification(LdrEntry);
}
/* Check if Application Verifier was enabled */
return Status;
}
+/* FIXME: This function is missing SxS support and has wrong prototype */
NTSTATUS
NTAPI
LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,