永发信息网

LoadLibrary一个DLL时,系统做了哪些事

答案:2  悬赏:30  手机版
解决时间 2021-03-18 07:37
  • 提问者网友:浮克旳回音
  • 2021-03-17 08:14
LoadLibrary一个DLL时,系统做了哪些事
最佳答案
  • 五星知识达人网友:风格不统一
  • 2021-03-17 09:33
上源代码

  主要功能:启动NotePad,在NotePad进程里创建RemoteThread加载我们自己的DLL,DLL加载时创建一个托盘,SubClass NotePad的主窗口,在标题栏上画一个Button。


  HMODULE
  LoadLibraryW(
  LPCWSTR lpwLibFileName
  )
  {
  return LoadLibraryExW( lpwLibFileName, NULL, 0 );
  }

  HMODULE
  LoadLibraryExW(
  LPCWSTR lpwLibFileName,
  HANDLE hFile,
  DWORD dwFlags
  )

  {
  LPWSTR TrimmedDllName;
  LPWSTR AllocatedPath;
  NTSTATUS Status;
  HMODULE hModule;
  UNICODE_STRING DllName_U, AppPathDllName_U;
  UNICODE_STRING AllocatedPath_U;
  ULONG DllCharacteristics;
  extern PLDR_DATA_TABLE_ENTRY BasepExeLdrEntry;

  TrimmedDllName = NULL;
  DllCharacteristics = 0;
  if (dwFlags & DONT_RESOLVE_DLL_REFERENCES) {
  DllCharacteristics |= IMAGE_FILE_EXECUTABLE_IMAGE;
  }

  RtlInitUnicodeString(&DllName_U, lpwLibFileName);

  //
  // Quick check to see if dll being loaded is the main exe. For some reason
  // hook stuff tends to do this and this is worst path through the loader
  //

  if ( !(dwFlags & LOAD_LIBRARY_AS_DATAFILE) && BasepExeLdrEntry && (DllName_U.Length == BasepExeLdrEntry->FullDllName.Length) ){
  if ( RtlEqualUnicodeString(&DllName_U,&BasepExeLdrEntry->FullDllName,TRUE) ) {
  return (HMODULE)BasepExeLdrEntry->DllBase;
  }
  }

  //
  // check to see if there are trailing spaces in the dll name (Win95 compat)
  //
  if ( DllName_U.Length && DllName_U.Buffer[(DllName_U.Length-1)>>1] == (WCHAR)' ') {
  TrimmedDllName = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TMP_TAG ), DllName_U.MaximumLength);
  if ( !TrimmedDllName ) {
  BaseSetLastNTError(STATUS_NO_MEMORY);
  return NULL;
  }
  RtlCopyMemory(TrimmedDllName,DllName_U.Buffer,DllName_U.MaximumLength);
  DllName_U.Buffer = TrimmedDllName;
  while (DllName_U.Length && DllName_U.Buffer[(DllName_U.Length-1)>>1] == (WCHAR)' ') {
  DllName_U.Buffer[(DllName_U.Length-1)>>1] = UNICODE_NULL;
  DllName_U.Length -= sizeof(WCHAR);
  DllName_U.MaximumLength -= sizeof(WCHAR);
  }
  }

  //
  // If DLL redirection is on for this application, we check to see if the DLL requested
  // (without path qualification) exists in the app. (EXE) folder. If so, we load that.
  // Else we fall back to regular search logic.
  //

  if (gDoDllRedirection && DllName_U.Length) {
  Status = ComputeRedirectedDllName(&DllName_U, &AppPathDllName_U) ;
  if(!NT_SUCCESS(Status)) {
  if ( TrimmedDllName ) {
  RtlFreeHeap(RtlProcessHeap(), 0, TrimmedDllName);
  }

  BaseSetLastNTError(Status);
  return NULL;
  }

  if (RtlDoesFileExists_U(AppPathDllName_U.Buffer)) {
  DllName_U.Buffer = AppPathDllName_U.Buffer ;
  DllName_U.MaximumLength = AppPathDllName_U.MaximumLength ;
  DllName_U.Length = AppPathDllName_U.Length;
  }
  }

  //
  // Determine the path that the program was created from
  //

  AllocatedPath = BaseComputeProcessDllPath(
  dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH ? DllName_U.Buffer : NULL,
  GetEnvironmentStringsW()
  );
  if ( !AllocatedPath ) {
  Status = STATUS_NO_MEMORY;
  if ( TrimmedDllName ) {
  RtlFreeHeap(RtlProcessHeap(), 0, TrimmedDllName);
  }
  goto bail;
  }
  RtlInitUnicodeString(&AllocatedPath_U, AllocatedPath);
  try {
  if (dwFlags & LOAD_LIBRARY_AS_DATAFILE) {
  #ifdef WX86
  // LdrGetDllHandle clears UseKnownWx86Dll, but the value is
  // needed again by LdrLoadDll.
  BOOLEAN Wx86KnownDll = NtCurrentTeb()->Wx86Thread.UseKnownWx86Dll;
  #endif
  Status = LdrGetDllHandle(
  AllocatedPath_U.Buffer,
  NULL,
  &DllName_U,
  (PVOID *)&hModule
  );
  if (NT_SUCCESS( Status )) {
  #ifdef WX86
  NtCurrentTeb()->Wx86Thread.UseKnownWx86Dll = Wx86KnownDll;
  #endif
  goto alreadyLoaded;
  }

  Status = BasepLoadLibraryAsDataFile( AllocatedPath_U.Buffer,
  &DllName_U,
  (PVOID *)&hModule
  );
  }
  else {
  alreadyLoaded:
  Status = LdrLoadDll(
  AllocatedPath_U.Buffer,
  &DllCharacteristics,
  &DllName_U,
  (PVOID *)&hModule
  );
  }
  if ( TrimmedDllName ) {
  RtlFreeHeap(RtlProcessHeap(), 0, TrimmedDllName);
  TrimmedDllName = NULL;
  }
  RtlFreeHeap(RtlProcessHeap(), 0, AllocatedPath);
  }
  except (EXCEPTION_EXECUTE_HANDLER) {
  Status = GetExceptionCode();
  if ( TrimmedDllName ) {
  RtlFreeHeap(RtlProcessHeap(), 0, TrimmedDllName);
  }
  RtlFreeHeap(RtlProcessHeap(), 0, AllocatedPath);
  }
  bail:
  if (gDoDllRedirection) {
  // We would have bailed had we not been able to allocate this buffer in re-direction case.
  RtlFreeHeap(RtlProcessHeap(), 0, AppPathDllName_U.Buffer);
  }

  if (!NT_SUCCESS(Status) ) {
  BaseSetLastNTError(Status);
  return NULL;
  }
  else {
  return hModule;
  }
  }

  NTSTATUS
  BasepLoadLibraryAsDataFile(
  IN PWSTR DllPath OPTIONAL,
  IN PUNICODE_STRING DllName,
  OUT PVOID *DllHandle
  )

  {
  WCHAR FullPath[ MAX_PATH ];
  PWSTR FilePart;
  HANDLE FileHandle;
  HANDLE MappingHandle;
  LPVOID DllBase;
  PIMAGE_NT_HEADERS NtHeaders;
  PTEB Teb;

  Teb = NtCurrentTeb();

  *DllHandle = NULL;
  if (!SearchPathW( DllPath,
  DllName->Buffer,
  L".DLL",
  MAX_PATH,
  FullPath,
  &FilePart
  )
  ) {
  return Teb->LastStatusValue;
  }

  FileHandle = CreateFileW( FullPath,
  GENERIC_READ,
  FILE_SHARE_READ | FILE_SHARE_DELETE,
  NULL,
  OPEN_EXISTING,
  0,
  NULL
  );

  if (FileHandle == INVALID_HANDLE_VALUE) {
  return Teb->LastStatusValue;
  }

  MappingHandle = CreateFileMappingW( FileHandle,
  NULL,
  PAGE_READONLY,
  0,
  0,
  NULL
  );
  CloseHandle( FileHandle );
  if (MappingHandle == NULL) {
  return Teb->LastStatusValue;
  }

  DllBase = MapViewOfFileEx( MappingHandle,
  FILE_MAP_READ,
  0,
  0,
  0,
  NULL
  );
  CloseHandle( MappingHandle );
  if (DllBase == NULL) {
  return Teb->LastStatusValue;
  }

  NtHeaders = RtlImageNtHeader( DllBase );
  if (NtHeaders == NULL) {
  UnmapViewOfFile( DllBase );
  return STATUS_INVALID_IMAGE_FORMAT;
  }

  *DllHandle = (HANDLE)((ULONG_PTR)DllBase | 0x00000001);
  LdrLoadAlternateResourceModule(*DllHandle, FullPath);

  return STATUS_SUCCESS;
  }

  NTSTATUS
  LdrLoadDll (
  IN PWSTR DllPath OPTIONAL,
  IN PULONG DllCharacteristics OPTIONAL,
  IN PUNICODE_STRING DllName,
  OUT PVOID *DllHandle
  ){
  return LdrpLoadDll(DllPath,DllCharacteristics,DllName,DllHandle,TRUE);
  }
全部回答
  • 1楼网友:春色三分
  • 2021-03-17 10:18
我是来看评论的
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯