DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (6863f516ba38)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef mozilla_ModuleEvaluator_windows_h
#define mozilla_ModuleEvaluator_windows_h

#include "mozilla/glue/WindowsDllServices.h"
#include "mozilla/Authenticode.h"
#include "mozilla/Maybe.h"
#include "mozilla/ModuleVersionInfo_windows.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/Vector.h"
#include "nsString.h"

class InfallibleAllocPolicy;

namespace mozilla {

enum class ModuleTrustFlags : uint32_t {
  None = 0,
  MozillaSignature = 1,
  MicrosoftWindowsSignature = 2,
  MicrosoftVersion = 4,
  FirefoxDirectory = 8,
  FirefoxDirectoryAndVersion = 0x10,
  SystemDirectory = 0x20,
  KeyboardLayout = 0x40,
  JitPI = 0x80,
  WinSxSDirectory = 0x100,
  Xul = 0x200,
  SysWOW64Directory = 0x400,
};

MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ModuleTrustFlags);

// This class is very similar to mozilla::glue::ModuleLoadEvent, except this is
// more Gecko-friendly, and has a few more fields that enable us to evaluate
// trustworthiness.
class ModuleLoadEvent {
 public:
  class ModuleInfo {
   public:
    ModuleInfo() = delete;
    ModuleInfo(const ModuleInfo&) = default;
    ModuleInfo(ModuleInfo&&) = default;
    ModuleInfo& operator=(const ModuleInfo&) = default;
    ModuleInfo& operator=(ModuleInfo&&) = default;

    explicit ModuleInfo(uintptr_t aBase);

    // Construct from the mozilla::glue version of this class.
    explicit ModuleInfo(const glue::ModuleLoadEvent::ModuleInfo&);

    bool PopulatePathInfo();
    bool PrepForTelemetry();

    uintptr_t mBase;
    nsString mLdrName;
    nsCOMPtr<nsIFile> mFile;  // Path as reported by GetModuleFileName()
    Maybe<double> mLoadDurationMS;

    // The following members are populated as we evaluate the module.
    nsString mFilePathClean;  // Path sanitized for telemetry reporting.
    ModuleTrustFlags mTrustFlags;
    nsCString mFileVersion;
  };

  ModuleLoadEvent() = default;
  ModuleLoadEvent(ModuleLoadEvent&&) = default;

  // The standard ModuleLoadEvent copy constructor "copy everything" behavior
  // can be tweaked to suit the context using this option.
  enum class CopyOption : int {
    CopyEverything,  // Default
    CopyWithoutModules,
  };

  ModuleLoadEvent(const ModuleLoadEvent& aOther,
                  CopyOption aOption = CopyOption::CopyEverything);

  ModuleLoadEvent& operator=(ModuleLoadEvent&& aOther) = default;
  ModuleLoadEvent& operator=(const ModuleLoadEvent& aOther) = delete;

  // Copy-construct from the mozilla::glue version of this class.
  explicit ModuleLoadEvent(const glue::ModuleLoadEvent& aOther);

  // Indicates whether the DLL was already loaded before we had a chance to
  // capture live info about it such as uptime / stack / thread.
  bool mIsStartup;
  DWORD mThreadID;
  nsCString mThreadName;
  uint64_t mProcessUptimeMS;
  Vector<uintptr_t, 0, InfallibleAllocPolicy> mStack;
  Vector<ModuleInfo, 0, InfallibleAllocPolicy> mModules;
};

// This class performs trustworthiness evaluation for incoming DLLs.
class ModuleEvaluator {
  Maybe<uint64_t> mExeVersion;  // Version number of the running EXE image
  nsCOMPtr<nsIFile> mExeDirectory;
  nsCOMPtr<nsIFile> mSysDirectory;
  nsCOMPtr<nsIFile> mWinSxSDirectory;
#ifdef _M_IX86
  nsCOMPtr<nsIFile> mSysWOW64Directory;
#endif  // _M_IX86
  Vector<nsString, 0, InfallibleAllocPolicy> mKeyboardLayoutDlls;

 public:
  ModuleEvaluator();

  explicit operator bool() const {
    // We exclude mSysWOW64Directory as it may not always be present
    return mExeVersion.isSome() && mExeDirectory && mSysDirectory &&
           mWinSxSDirectory;
  }

  /**
   * Evaluates the trustworthiness of the given module and fills in remaining
   * fields in ModuleInfo.
   *
   * @param  aDllInfo [in,out] Info about the DLL in question.
   *                  The following members must be valid:
   *                  mBase
   *                  mFile
   *                  This function fills in remaining fields of aDllInfo.
   * @param  aEvent   [in] Info about the relevant event that contains this DLL.
   * @param  aSvc     [in] Pointer to the service we use for Authenticode ops
   * @return Some(true) if the given module is trusted.
   *         Some(false) if the given module is untrusted.
   *         Nothing() if there was a failure.
   */
  Maybe<bool> IsModuleTrusted(ModuleLoadEvent::ModuleInfo& aDllInfo,
                              const ModuleLoadEvent& aEvent,
                              Authenticode* aSvc) const;
};

}  // namespace mozilla

#endif  // mozilla_ModuleEvaluator_windows_h