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

📄 utils.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:

  while (Entry != ModuleListHead)
    {
      ModulePtr = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

      DPRINT("Scanning %wZ at %p\n", &ModulePtr->BaseDllName, ModulePtr->DllBase);

      if ((Address >= ModulePtr->DllBase) &&
          ((ULONG_PTR)Address <= ((ULONG_PTR)ModulePtr->DllBase + ModulePtr->SizeOfImage)))
        {
          *Module = ModulePtr;
          RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
          return(STATUS_SUCCESS);
        }

      Entry = Entry->Flink;
    }

  DPRINT("Failed to find module entry.\n");

  RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
  return(STATUS_NO_MORE_ENTRIES);
}


/***************************************************************************
 * NAME                                                         LOCAL
 *      LdrFindEntryForName
 *
 * DESCRIPTION
 *
 * ARGUMENTS
 *
 * RETURN VALUE
 *
 * REVISIONS
 *
 * NOTE
 *
 */
static NTSTATUS
LdrFindEntryForName(PUNICODE_STRING Name,
                    PLDR_DATA_TABLE_ENTRY *Module,
                    BOOLEAN Ref)
{
  PLIST_ENTRY ModuleListHead;
  PLIST_ENTRY Entry;
  PLDR_DATA_TABLE_ENTRY ModulePtr;
  BOOLEAN ContainsPath;
  UNICODE_STRING AdjustedName;
  unsigned i;

  DPRINT("LdrFindEntryForName(Name %wZ)\n", Name);

  if (NtCurrentPeb()->Ldr == NULL)
    return(STATUS_NO_MORE_ENTRIES);

  RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
  ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
  Entry = ModuleListHead->Flink;
  if (Entry == ModuleListHead)
    {
      RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
      return(STATUS_NO_MORE_ENTRIES);
    }

  // NULL is the current process
  if (Name == NULL)
    {
      *Module = ExeModule;
      RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
      return(STATUS_SUCCESS);
    }

  LdrAdjustDllName (&AdjustedName, Name, FALSE);

  ContainsPath = (AdjustedName.Length >= 2 * sizeof(WCHAR) && L':' == AdjustedName.Buffer[1]);
  for (i = 0; ! ContainsPath && i < AdjustedName.Length / sizeof(WCHAR); i++)
    {
      ContainsPath = L'\\' == AdjustedName.Buffer[i] ||
                     L'/' == AdjustedName.Buffer[i];
    }

  if (LdrpLastModule)
    {
      if ((! ContainsPath &&
           0 == RtlCompareUnicodeString(&LdrpLastModule->BaseDllName, &AdjustedName, TRUE)) ||
          (ContainsPath &&
           0 == RtlCompareUnicodeString(&LdrpLastModule->FullDllName, &AdjustedName, TRUE)))
        {
          *Module = LdrpLastModule;
          if (Ref && (*Module)->LoadCount != 0xFFFF)
            {
              (*Module)->LoadCount++;
            }
          RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
          RtlFreeUnicodeString(&AdjustedName);
          return(STATUS_SUCCESS);
        }
    }
  while (Entry != ModuleListHead)
    {
      ModulePtr = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

      DPRINT("Scanning %wZ %wZ\n", &ModulePtr->BaseDllName, &AdjustedName);

      if ((! ContainsPath &&
           0 == RtlCompareUnicodeString(&ModulePtr->BaseDllName, &AdjustedName, TRUE)) ||
          (ContainsPath &&
           0 == RtlCompareUnicodeString(&ModulePtr->FullDllName, &AdjustedName, TRUE)))
        {
          *Module = LdrpLastModule = ModulePtr;
          if (Ref && ModulePtr->LoadCount != 0xFFFF)
            {
              ModulePtr->LoadCount++;
            }
          RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
          RtlFreeUnicodeString(&AdjustedName);
          return(STATUS_SUCCESS);
        }

      Entry = Entry->Flink;
    }

  DPRINT("Failed to find dll %wZ\n", Name);
  RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
  RtlFreeUnicodeString(&AdjustedName);
  return(STATUS_NO_MORE_ENTRIES);
}

/**********************************************************************
 * NAME                                                         LOCAL
 *      LdrFixupForward
 *
 * DESCRIPTION
 *
 * ARGUMENTS
 *
 * RETURN VALUE
 *
 * REVISIONS
 *
 * NOTE
 *
 */
static PVOID
LdrFixupForward(PCHAR ForwardName)
{
   CHAR NameBuffer[128];
   UNICODE_STRING DllName;
   NTSTATUS Status;
   PCHAR p;
   PLDR_DATA_TABLE_ENTRY Module;
   PVOID BaseAddress;

   strcpy(NameBuffer, ForwardName);
   p = strchr(NameBuffer, '.');
   if (p != NULL)
     {
        *p = 0;

        DPRINT("Dll: %s  Function: %s\n", NameBuffer, p+1);
        RtlCreateUnicodeStringFromAsciiz (&DllName,
                                          NameBuffer);

        Status = LdrFindEntryForName (&DllName, &Module, FALSE);
        /* FIXME:
         *   The caller (or the image) is responsible for loading of the dll, where the function is forwarded.
         */
        if (!NT_SUCCESS(Status))
          {
             ULONG Flags = LDRP_PROCESS_CREATION_TIME;
             Status = LdrLoadDll(NULL,
                                 &Flags,
                                 &DllName,
                                 &BaseAddress);
             if (NT_SUCCESS(Status))
               {
                 Status = LdrFindEntryForName (&DllName, &Module, FALSE);
               }
          }
        RtlFreeUnicodeString (&DllName);
        if (!NT_SUCCESS(Status))
          {
            DPRINT1("LdrFixupForward: failed to load %s\n", NameBuffer);
            return NULL;
          }

        DPRINT("BaseAddress: %p\n", Module->DllBase);

        return LdrGetExportByName(Module->DllBase, (PUCHAR)(p+1), -1);
     }

   return NULL;
}


/**********************************************************************
 * NAME                                                         LOCAL
 *      LdrGetExportByOrdinal
 *
 * DESCRIPTION
 *
 * ARGUMENTS
 *
 * RETURN VALUE
 *
 * REVISIONS
 *
 * NOTE
 *
 */
static PVOID
LdrGetExportByOrdinal (
        PVOID   BaseAddress,
        ULONG   Ordinal
        )
{
        PIMAGE_EXPORT_DIRECTORY ExportDir;
        ULONG                   ExportDirSize;
        PDWORD                  * ExFunctions;
        PVOID                   Function;

        ExportDir = (PIMAGE_EXPORT_DIRECTORY)
                RtlImageDirectoryEntryToData (BaseAddress,
                                              TRUE,
                                              IMAGE_DIRECTORY_ENTRY_EXPORT,
                                              &ExportDirSize);


        ExFunctions = (PDWORD *)
                RVA(
                        BaseAddress,
                        ExportDir->AddressOfFunctions
                        );
        DPRINT(
                "LdrGetExportByOrdinal(Ordinal %lu) = %p\n",
                Ordinal,
                RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
                );

        Function = (0 != ExFunctions[Ordinal - ExportDir->Base]
                    ? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
                    : NULL);

        if (((ULONG)Function >= (ULONG)ExportDir) &&
            ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
          {
             DPRINT("Forward: %s\n", (PCHAR)Function);
             Function = LdrFixupForward((PCHAR)Function);
          }

        return Function;
}


/**********************************************************************
 * NAME                                                         LOCAL
 *      LdrGetExportByName
 *
 * DESCRIPTION
 *
 * ARGUMENTS
 *
 * RETURN VALUE
 *
 * REVISIONS
 *
 * NOTE
 *  AddressOfNames and AddressOfNameOrdinals are paralell tables,
 *  both with NumberOfNames entries.
 *
 */
static PVOID
LdrGetExportByName(PVOID BaseAddress,
                   PUCHAR SymbolName,
                   WORD Hint)
{
   PIMAGE_EXPORT_DIRECTORY      ExportDir;
   PDWORD                       * ExFunctions;
   PDWORD                       * ExNames;
   USHORT                       * ExOrdinals;
   PVOID                        ExName;
   ULONG                        Ordinal;
   PVOID                        Function;
   LONG minn, maxn;
   ULONG ExportDirSize;

   DPRINT("LdrGetExportByName %p %s %hu\n", BaseAddress, SymbolName, Hint);

   ExportDir = (PIMAGE_EXPORT_DIRECTORY)
     RtlImageDirectoryEntryToData(BaseAddress,
                                  TRUE,
                                  IMAGE_DIRECTORY_ENTRY_EXPORT,
                                  &ExportDirSize);
   if (ExportDir == NULL)
     {
        DPRINT1("LdrGetExportByName(): no export directory, "
                "can't lookup %s/%hu!\n", SymbolName, Hint);
        return NULL;
     }


   //The symbol names may be missing entirely
   if (ExportDir->AddressOfNames == 0)
   {
      DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
      return NULL;
   }

   /*
    * Get header pointers
    */
   ExNames = (PDWORD *)RVA(BaseAddress,
                           ExportDir->AddressOfNames);
   ExOrdinals = (USHORT *)RVA(BaseAddress,
                              ExportDir->AddressOfNameOrdinals);
   ExFunctions = (PDWORD *)RVA(BaseAddress,
                               ExportDir->AddressOfFunctions);

   /*
    * Check the hint first
    */
   if (Hint < ExportDir->NumberOfNames)
     {
        ExName = RVA(BaseAddress, ExNames[Hint]);
        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
          {
             Ordinal = ExOrdinals[Hint];
             Function = RVA(BaseAddress, ExFunctions[Ordinal]);
             if (((ULONG)Function >= (ULONG)ExportDir) &&
                 ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
               {
                  DPRINT("Forward: %s\n", (PCHAR)Function);
                  Function = LdrFixupForward((PCHAR)Function);
                  if (Function == NULL)
                    {
                      DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
                    }
                  return Function;
               }
             if (Function != NULL)
               return Function;
          }
     }

   /*
    * Binary search
    */
   minn = 0;
   maxn = ExportDir->NumberOfNames - 1;
   while (minn <= maxn)
     {
        LONG mid;
        LONG res;

        mid = (minn + maxn) / 2;

        ExName = RVA(BaseAddress, ExNames[mid]);
        res = strcmp(ExName, (PCHAR)SymbolName);
        if (res == 0)
          {
             Ordinal = ExOrdinals[mid];
             Function = RVA(BaseAddress, ExFunctions[Ordinal]);
             if (((ULONG)Function >= (ULONG)ExportDir) &&
                 ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
               {
                  DPRINT("Forward: %s\n", (PCHAR)Function);
                  Function = LdrFixupForward((PCHAR)Function);
                  if (Function == NULL)
                    {
                      DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
                    }
                  return Function;
               }
             if (Function != NULL)
               return Function;
          }
        else if (minn == maxn)
          {
             DPRINT("LdrGetExportByName(): binary search failed\n");
             break;
          }
        else if (res > 0)
          {
             maxn = mid - 1;
          }
        else
          {
             minn = mid + 1;
          }
     }

   DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
   return (PVOID)NULL;
}


/**********************************************************************
 * NAME                                                         LOCAL
 *      LdrPerformRelocations
 *

⌨️ 快捷键说明

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