⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
 * DESCRIPTION
 *      Compute the entry point for every symbol the DLL imports
 *      from other modules.
 *
 * ARGUMENTS
 *
 * RETURN VALUE
 *
 * REVISIONS
 *
 * NOTE
 *
 */
static NTSTATUS
LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
                IN PLDR_DATA_TABLE_ENTRY Module)
{
   PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
   PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectoryCurrent;
   PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptor;
   PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
   PIMAGE_TLS_DIRECTORY TlsDirectory;
   ULONG TlsSize = 0;
   NTSTATUS Status;
   PLDR_DATA_TABLE_ENTRY ImportedModule;
   PCHAR ImportedName;
   ULONG Size;

   DPRINT("LdrFixupImports(SearchPath %S, Module %p)\n", SearchPath, Module);

   /* Check for tls data */
   TlsDirectory = (PIMAGE_TLS_DIRECTORY)
                     RtlImageDirectoryEntryToData(Module->DllBase,
                                                  TRUE,
                                                  IMAGE_DIRECTORY_ENTRY_TLS,
                                                  &Size);
   if (TlsDirectory)
     {
       TlsSize = TlsDirectory->EndAddressOfRawData
                   - TlsDirectory->StartAddressOfRawData
                   + TlsDirectory->SizeOfZeroFill;
       if (TlsSize > 0 &&
           NtCurrentPeb()->Ldr->Initialized)
         {
           TRACE_LDR("Trying to load dynamicly %wZ which contains a tls directory\n",
                     &Module->BaseDllName);
           return STATUS_UNSUCCESSFUL;
         }
     }
   /*
    * Process each import module.
    */
   ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
                              RtlImageDirectoryEntryToData(Module->DllBase,
                                                           TRUE,
                                                           IMAGE_DIRECTORY_ENTRY_IMPORT,
                                                           &Size);

   BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
                              RtlImageDirectoryEntryToData(Module->DllBase,
                                                           TRUE,
                                                           IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
                                                           &Size);

   if (BoundImportDescriptor != NULL && ImportModuleDirectory == NULL)
     {
       DPRINT1("%wZ has only a bound import directory\n", &Module->BaseDllName);
       return STATUS_UNSUCCESSFUL;
     }
   if (BoundImportDescriptor)
     {
       DPRINT("BoundImportDescriptor %p\n", BoundImportDescriptor);

       BoundImportDescriptorCurrent = BoundImportDescriptor;
       while (BoundImportDescriptorCurrent->OffsetModuleName)
         {
           ImportedName = (PCHAR)BoundImportDescriptor + BoundImportDescriptorCurrent->OffsetModuleName;
           TRACE_LDR("%wZ bound to %s\n", &Module->BaseDllName, ImportedName);
           Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
           if (!NT_SUCCESS(Status))
             {
               DPRINT1("failed to load %s\n", ImportedName);
               return Status;
             }
           if (Module == ImportedModule)
             {
               LdrpDecrementLoadCount(Module, FALSE);
             }
           if (ImportedModule->TimeDateStamp != BoundImportDescriptorCurrent->TimeDateStamp)
             {
               TRACE_LDR("%wZ has stale binding to %wZ\n",
                         &Module->BaseDllName, &ImportedModule->BaseDllName);
               Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
               if (!NT_SUCCESS(Status))
                 {
                   DPRINT1("failed to import %s\n", ImportedName);
                   return Status;
                 }
             }
           else
             {
               BOOLEAN WrongForwarder;
               WrongForwarder = FALSE;
               if (ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
                 {
                   TRACE_LDR("%wZ has stale binding to %s\n",
                             &Module->BaseDllName, ImportedName);
                 }
               else
                 {
                   TRACE_LDR("%wZ has correct binding to %wZ\n",
                           &Module->BaseDllName, &ImportedModule->BaseDllName);
                 }
               if (BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs)
                 {
                   PIMAGE_BOUND_FORWARDER_REF BoundForwarderRef;
                   ULONG i;
                   PLDR_DATA_TABLE_ENTRY ForwarderModule;
                   PCHAR ForwarderName;

                   BoundForwarderRef = (PIMAGE_BOUND_FORWARDER_REF)(BoundImportDescriptorCurrent + 1);
                   for (i = 0; i < BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs; i++, BoundForwarderRef++)
                     {
                       ForwarderName = (PCHAR)BoundImportDescriptor + BoundForwarderRef->OffsetModuleName;
                       TRACE_LDR("%wZ bound to %s via forwardes from %s\n",
                                 &Module->BaseDllName, ForwarderName, ImportedName);
                       Status = LdrpGetOrLoadModule(SearchPath, ForwarderName, &ForwarderModule, TRUE);
                       if (!NT_SUCCESS(Status))
                         {
                           DPRINT1("failed to load %s\n", ForwarderName);
                           return Status;
                         }
                       if (Module == ImportedModule)
                         {
                           LdrpDecrementLoadCount(Module, FALSE);
                         }
                       if (ForwarderModule->TimeDateStamp != BoundForwarderRef->TimeDateStamp ||
                           ForwarderModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
                         {
                           TRACE_LDR("%wZ has stale binding to %s\n",
                                     &Module->BaseDllName, ForwarderName);
                           WrongForwarder = TRUE;
                         }
                       else
                         {
                           TRACE_LDR("%wZ has correct binding to %s\n",
                                     &Module->BaseDllName, ForwarderName);
                         }
                     }
                 }
               if (WrongForwarder ||
                   ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
                 {
                   Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
                   if (!NT_SUCCESS(Status))
                     {
                       DPRINT1("failed to import %s\n", ImportedName);
                       return Status;
                     }
                 }
               else if (ImportedModule->Flags & LDRP_IMAGE_NOT_AT_BASE)
                 {
                   TRACE_LDR("Adjust imports for %s from %wZ\n",
                             ImportedName, &Module->BaseDllName);
                   Status = LdrpAdjustImportDirectory(Module, ImportedModule, ImportedName);
                   if (!NT_SUCCESS(Status))
                   {
                     DPRINT1("failed to adjust import entries for %s\n", ImportedName);
                     return Status;
                   }
                 }
               else if (WrongForwarder)
                 {
                   /*
                    * FIXME:
                    *   Update only forwarders
                    */
                   TRACE_LDR("Stale BIND %s from %wZ\n",
                             ImportedName, &Module->BaseDllName);
                   Status = LdrpProcessImportDirectory(Module, ImportedModule, ImportedName);
                   if (!NT_SUCCESS(Status))
                     {
                       DPRINT1("faild to import %s\n", ImportedName);
                       return Status;
                     }
                 }
               else
                 {
                   /* nothing to do */
                 }
             }
           BoundImportDescriptorCurrent += BoundImportDescriptorCurrent->NumberOfModuleForwarderRefs + 1;
         }
     }
   else if (ImportModuleDirectory)
     {
       DPRINT("ImportModuleDirectory %p\n", ImportModuleDirectory);

       ImportModuleDirectoryCurrent = ImportModuleDirectory;
       while (ImportModuleDirectoryCurrent->Name)
         {
           ImportedName = (PCHAR)Module->DllBase + ImportModuleDirectoryCurrent->Name;
           TRACE_LDR("%wZ imports functions from %s\n", &Module->BaseDllName, ImportedName);

           Status = LdrpGetOrLoadModule(SearchPath, ImportedName, &ImportedModule, TRUE);
           if (!NT_SUCCESS(Status))
             {
               DPRINT1("failed to load %s\n", ImportedName);
               return Status;
             }
           if (Module == ImportedModule)
             {
               LdrpDecrementLoadCount(Module, FALSE);
             }

           TRACE_LDR("Initializing imports for %wZ from %s\n",
                     &Module->BaseDllName, ImportedName);
           Status = LdrpProcessImportDirectoryEntry(Module, ImportedModule, ImportModuleDirectoryCurrent);
           if (!NT_SUCCESS(Status))
             {
               DPRINT1("failed to import %s\n", ImportedName);
               return Status;
             }
           ImportModuleDirectoryCurrent++;
         }
     }

   if (TlsDirectory && TlsSize > 0)
     {
       LdrpAcquireTlsSlot(Module, TlsSize, FALSE);
     }

   return STATUS_SUCCESS;
}


/**********************************************************************
 * NAME
 *      LdrPEStartup
 *
 * DESCRIPTION
 *      1. Relocate, if needed the EXE.
 *      2. Fixup any imported symbol.
 *      3. Compute the EXE's entry point.
 *
 * ARGUMENTS
 *      ImageBase
 *              Address at which the EXE's image
 *              is loaded.
 *
 *      SectionHandle
 *              Handle of the section that contains
 *              the EXE's image.
 *
 * RETURN VALUE
 *      NULL on error; otherwise the entry point
 *      to call for initializing the DLL.
 *
 * REVISIONS
 *
 * NOTE
 *      04.01.2004 hb Previous this function was used for all images (dll + exe).
 *                    Currently the function is only used for the exe.
 */
PEPFUNC LdrPEStartup (PVOID  ImageBase,
                      HANDLE SectionHandle,
                      PLDR_DATA_TABLE_ENTRY* Module,
                      PWSTR FullDosName)
{
   NTSTATUS             Status;
   PEPFUNC              EntryPoint = NULL;
   PIMAGE_DOS_HEADER    DosHeader;
   PIMAGE_NT_HEADERS    NTHeaders;
   PLDR_DATA_TABLE_ENTRY tmpModule;

   DPRINT("LdrPEStartup(ImageBase %p SectionHandle %p)\n",
           ImageBase, SectionHandle);

   /*
    * Overlay DOS and WNT headers structures
    * to the DLL's image.
    */
   DosHeader = (PIMAGE_DOS_HEADER) ImageBase;
   NTHeaders = (PIMAGE_NT_HEADERS) ((ULONG_PTR)ImageBase + DosHeader->e_lfanew);

   /*
    * If the base address is different from the
    * one the DLL is actually loaded, perform any
    * relocation.
    */
   if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase)
     {
       DPRINT("LDR: Performing relocations\n");
       Status = LdrPerformRelocations(NTHeaders, ImageBase);
       if (!NT_SUCCESS(Status))
         {
           DPRINT1("LdrPerformRelocations() failed\n");
           return NULL;
         }
     }

   if (Module != NULL)
     {
       *Module = LdrAddModuleEntry(ImageBase, NTHeaders, FullDosName);
       (*Module)->SectionPointer = SectionHandle;
     }
   else
     {
       Module = &tmpModule;
       Status = LdrFindEntryForAddress(ImageBase, Module);
       if (!NT_SUCCESS(Status))
         {
           return NULL;
         }
     }

   if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase)
     {
       (*Module)->Flags |= LDRP_IMAGE_NOT_AT_BASE;
     }

   /*
    * If the DLL's imports symbols from other
    * modules, fixup the imported calls entry points.
    */
   DPRINT("About to fixup imports\n");
   Status = LdrFixupImports(NULL, *Module);
   if (!NT_SUCCESS(Status))
     {
       DPRINT1("LdrFixupImports() failed for %wZ\n", &(*Module)->BaseDllName);
       return NULL;
     }
   DPRINT("Fixup done\n");
   RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
   Status = LdrpInitializeTlsForProccess();
   if (NT_SUCCESS(Status))
     {
       Status = LdrpAttachProcess();
     }
   if (NT_SUCCESS(Status))
     {
       LdrpTlsCallback(*Module, DLL_PROCESS_ATTACH);
     }


   RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
   if (!NT_SUCCESS(Status))
     {
       return NULL;
     }

   /*
    * Compute the DLL's entry point's address.
    */
   DPRINT("ImageBase = %p\n", ImageBase);
   DPRINT("AddressOfEntryPoint = 0x%lx\n",(ULONG)NTHeaders->OptionalHeader.AddressOfEntryPoint);
   if (NTHeaders->OptionalHeader.AddressOfEntryPoint != 0)
     {
        EntryPoint = (PEPFUNC) ((ULONG_PTR)ImageBase
                           + NTHeaders->OptionalHeader.AddressOfEntryPoint);
     }
   DPRINT("LdrPEStartup() = %p\n",EntryPoint);
   return EntryPoint;
}

static NTSTATUS
LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
               IN ULONG LoadFlags,
               IN PUNICODE_STRING Name,
               PLDR_DATA_TABLE_ENTRY *Module,
               PVOID *BaseAddress OPTIONAL)
{
    UNICODE_STRING AdjustedName;
    UNICODE_STRING FullDosName;
    NTSTATUS Status;
    PLDR_DATA_TABLE_ENTRY tmpModule;
    HANDLE SectionHandle;
    ULONG ViewSize;
    PVOID ImageBase;
    PIMAGE_NT_HEADERS NtHeaders;
    BOOLEAN MappedAsDataFile;
    PVOID ArbitraryUserPointer;

    if (Module == NULL)
      {
        Module = &tmpModule;
      }
    /* adjust the full dll name */
    LdrAdjustDllName(&AdjustedName, Name, FALSE);

    DPRINT("%wZ\n", &AdjustedName);

    MappedAsDataFile = FALSE;
    /* Test if dll is already loaded */
    Status = LdrFindEntryForName(&AdjustedName, Module, TRUE);
    if (NT_SUCCESS(Status))
      {
        RtlFreeUnicodeString(&AdjustedName);
        if (NULL != BaseAddress)
          {
            *BaseAddress = (*Module)->DllBase;
          }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -