ModuleLoadFrame.h (3586B)
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 #ifndef mozilla_freestanding_ModuleLoadFrame_h 8 #define mozilla_freestanding_ModuleLoadFrame_h 9 10 #include "mozilla/LoaderAPIInterfaces.h" 11 #include "mozilla/NativeNt.h" 12 13 #include "SafeThreadLocal.h" 14 15 namespace mozilla { 16 namespace freestanding { 17 18 /** 19 * This class holds information about a DLL load at a particular frame in the 20 * current thread's stack. Each instance adds itself to a thread-local linked 21 * list of ModuleLoadFrames, enabling us to query information about the 22 * previous module load on the stack. 23 */ 24 class MOZ_RAII ModuleLoadFrame final { 25 public: 26 /** 27 * This constructor is for use by the LdrLoadDll hook. 28 */ 29 explicit ModuleLoadFrame(PCUNICODE_STRING aRequestedDllName); 30 ~ModuleLoadFrame(); 31 32 static void NotifyLSPSubstitutionRequired(PCUNICODE_STRING aLeafName); 33 34 /** 35 * This static method is called by the NtMapViewOfSection hook. 36 */ 37 static void NotifySectionMap(nt::AllocatedUnicodeString&& aSectionName, 38 const void* aMapBaseAddr, NTSTATUS aMapNtStatus, 39 ModuleLoadInfo::Status aLoadStatus, 40 bool aIsDependent); 41 static bool ExistsTopFrame(); 42 43 /** 44 * Called by the LdrLoadDll hook to indicate the status of the load and for 45 * us to provide a substitute output handle if necessary. 46 */ 47 NTSTATUS SetLoadStatus(NTSTATUS aNtStatus, PHANDLE aOutHandle); 48 49 ModuleLoadFrame(const ModuleLoadFrame&) = delete; 50 ModuleLoadFrame(ModuleLoadFrame&&) = delete; 51 ModuleLoadFrame& operator=(const ModuleLoadFrame&) = delete; 52 ModuleLoadFrame& operator=(ModuleLoadFrame&&) = delete; 53 54 private: 55 /** 56 * Called by OnBareSectionMap to construct a frame for a bare load. 57 */ 58 ModuleLoadFrame(nt::AllocatedUnicodeString&& aSectionName, 59 const void* aMapBaseAddr, NTSTATUS aNtStatus, 60 ModuleLoadInfo::Status aLoadStatus, bool aIsDependent); 61 62 void SetLSPSubstitutionRequired(PCUNICODE_STRING aLeafName); 63 void OnSectionMap(nt::AllocatedUnicodeString&& aSectionName, 64 const void* aMapBaseAddr, NTSTATUS aMapNtStatus, 65 ModuleLoadInfo::Status aLoadStatus, bool aIsDependent); 66 67 /** 68 * A "bare" section mapping is one that was mapped without the code passing 69 * through a call to ntdll!LdrLoadDll. This method is invoked when we detect 70 * that condition. 71 */ 72 static void OnBareSectionMap(nt::AllocatedUnicodeString&& aSectionName, 73 const void* aMapBaseAddr, NTSTATUS aMapNtStatus, 74 ModuleLoadInfo::Status aLoadStatus, 75 bool aIsDependent); 76 77 private: 78 // Link to the previous frame 79 ModuleLoadFrame* mPrev; 80 // Pointer to context managed by the nt::LoaderObserver implementation 81 void* mContext; 82 // Set to |true| when we need to block a WinSock LSP 83 bool mLSPSubstitutionRequired; 84 // NTSTATUS code from the |LdrLoadDll| call 85 NTSTATUS mLoadNtStatus; 86 // Telemetry information that will be forwarded to the nt::LoaderObserver 87 ModuleLoadInfo mLoadInfo; 88 89 // Head of the linked list 90 static SafeThreadLocal<ModuleLoadFrame*> sTopFrame; 91 }; 92 93 } // namespace freestanding 94 } // namespace mozilla 95 96 #endif // mozilla_freestanding_ModuleLoadFrame_h