tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ModuleLoadFrame.cpp (4956B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      6 
      7 #include "ModuleLoadFrame.h"
      8 
      9 #include "LoaderPrivateAPI.h"
     10 
     11 namespace mozilla {
     12 namespace freestanding {
     13 
     14 ModuleLoadFrame::ModuleLoadFrame(PCUNICODE_STRING aRequestedDllName)
     15    : mPrev(sTopFrame.get()),
     16      mContext(nullptr),
     17      mLSPSubstitutionRequired(false),
     18      mLoadNtStatus(STATUS_UNSUCCESSFUL),
     19      mLoadInfo(aRequestedDllName) {
     20  EnsureInitialized();
     21  sTopFrame.set(this);
     22 
     23  gLoaderPrivateAPI.NotifyBeginDllLoad(mLoadInfo, &mContext, aRequestedDllName);
     24 }
     25 
     26 ModuleLoadFrame::ModuleLoadFrame(nt::AllocatedUnicodeString&& aSectionName,
     27                                 const void* aMapBaseAddr, NTSTATUS aNtStatus,
     28                                 ModuleLoadInfo::Status aLoadStatus,
     29                                 bool aIsDependent)
     30    : mPrev(sTopFrame.get()),
     31      mContext(nullptr),
     32      mLSPSubstitutionRequired(false),
     33      mLoadNtStatus(aNtStatus),
     34      mLoadInfo(std::move(aSectionName), aMapBaseAddr, aLoadStatus,
     35                aIsDependent) {
     36  sTopFrame.set(this);
     37 
     38  gLoaderPrivateAPI.NotifyBeginDllLoad(&mContext, mLoadInfo.mSectionName);
     39 }
     40 
     41 ModuleLoadFrame::~ModuleLoadFrame() {
     42  gLoaderPrivateAPI.NotifyEndDllLoad(mContext, mLoadNtStatus,
     43                                     std::move(mLoadInfo));
     44  sTopFrame.set(mPrev);
     45 }
     46 
     47 /* static */
     48 void ModuleLoadFrame::NotifyLSPSubstitutionRequired(
     49    PCUNICODE_STRING aLeafName) {
     50  ModuleLoadFrame* topFrame = sTopFrame.get();
     51  if (!topFrame) {
     52    return;
     53  }
     54 
     55  topFrame->SetLSPSubstitutionRequired(aLeafName);
     56 }
     57 
     58 void ModuleLoadFrame::SetLSPSubstitutionRequired(PCUNICODE_STRING aLeafName) {
     59  MOZ_ASSERT(!mLoadInfo.mBaseAddr);
     60  if (mLoadInfo.mBaseAddr) {
     61    // If mBaseAddr is not null then |this| has already seen a module load. This
     62    // should not be the case for a LSP substitution, so we bail.
     63    return;
     64  }
     65 
     66  // Save aLeafName, as it will be used by SetLoadStatus when invoking
     67  // SubstituteForLSP
     68  mLoadInfo.mRequestedDllName = aLeafName;
     69  mLSPSubstitutionRequired = true;
     70 }
     71 
     72 /* static */
     73 void ModuleLoadFrame::NotifySectionMap(
     74    nt::AllocatedUnicodeString&& aSectionName, const void* aMapBaseAddr,
     75    NTSTATUS aMapNtStatus, ModuleLoadInfo::Status aLoadStatus,
     76    bool aIsDependent) {
     77  ModuleLoadFrame* topFrame = sTopFrame.get();
     78  if (!topFrame) {
     79    // The only time that this data is useful is during initial mapping of
     80    // the executable's dependent DLLs. If mozglue is present then
     81    // IsDefaultObserver will return false, indicating that we are beyond
     82    // initial process startup.
     83    if (gLoaderPrivateAPI.IsDefaultObserver()) {
     84      OnBareSectionMap(std::move(aSectionName), aMapBaseAddr, aMapNtStatus,
     85                       aLoadStatus, aIsDependent);
     86    }
     87    return;
     88  }
     89 
     90  topFrame->OnSectionMap(std::move(aSectionName), aMapBaseAddr, aMapNtStatus,
     91                         aLoadStatus, aIsDependent);
     92 }
     93 
     94 /* static */
     95 bool ModuleLoadFrame::ExistsTopFrame() { return !!sTopFrame.get(); }
     96 
     97 void ModuleLoadFrame::OnSectionMap(nt::AllocatedUnicodeString&& aSectionName,
     98                                   const void* aMapBaseAddr,
     99                                   NTSTATUS aMapNtStatus,
    100                                   ModuleLoadInfo::Status aLoadStatus,
    101                                   bool aIsDependent) {
    102  if (mLoadInfo.mBaseAddr) {
    103    // If mBaseAddr is not null then |this| has already seen a module load. This
    104    // means that we are witnessing a bare section map.
    105    OnBareSectionMap(std::move(aSectionName), aMapBaseAddr, aMapNtStatus,
    106                     aLoadStatus, aIsDependent);
    107    return;
    108  }
    109 
    110  mLoadInfo.mSectionName = std::move(aSectionName);
    111  mLoadInfo.mBaseAddr = aMapBaseAddr;
    112  mLoadInfo.mStatus = aLoadStatus;
    113 }
    114 
    115 /* static */
    116 void ModuleLoadFrame::OnBareSectionMap(
    117    nt::AllocatedUnicodeString&& aSectionName, const void* aMapBaseAddr,
    118    NTSTATUS aMapNtStatus, ModuleLoadInfo::Status aLoadStatus,
    119    bool aIsDependent) {
    120  // We call the special constructor variant that is used for bare mappings.
    121  ModuleLoadFrame frame(std::move(aSectionName), aMapBaseAddr, aMapNtStatus,
    122                        aLoadStatus, aIsDependent);
    123 }
    124 
    125 NTSTATUS ModuleLoadFrame::SetLoadStatus(NTSTATUS aNtStatus,
    126                                        PHANDLE aOutHandle) {
    127  mLoadNtStatus = aNtStatus;
    128 
    129  if (!mLSPSubstitutionRequired) {
    130    return aNtStatus;
    131  }
    132 
    133  if (!gLoaderPrivateAPI.SubstituteForLSP(mLoadInfo.mRequestedDllName,
    134                                          aOutHandle)) {
    135    return aNtStatus;
    136  }
    137 
    138  return STATUS_SUCCESS;
    139 }
    140 
    141 SafeThreadLocal<ModuleLoadFrame*> ModuleLoadFrame::sTopFrame;
    142 
    143 }  // namespace freestanding
    144 }  // namespace mozilla