From 0f899ac198b1ba90f6cba3680b5ee956037d71b6 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Wed, 27 Jun 2018 11:50:50 -0600 Subject: [PATCH] Bug 1460022: Part 7 - Update plugin code to work with revised DLL interceptor interface; r=handyman --- dom/plugins/base/nsPluginNativeWindowWin.cpp | 36 ++++---- dom/plugins/ipc/FunctionHook.cpp | 21 +---- dom/plugins/ipc/FunctionHook.h | 27 ++++-- dom/plugins/ipc/PluginInstanceChild.cpp | 97 +++++++------------- 4 files changed, 73 insertions(+), 108 deletions(-) diff --git a/dom/plugins/base/nsPluginNativeWindowWin.cpp b/dom/plugins/base/nsPluginNativeWindowWin.cpp index fc7f0ea72345..570b99e52610 100644 --- a/dom/plugins/base/nsPluginNativeWindowWin.cpp +++ b/dom/plugins/base/nsPluginNativeWindowWin.cpp @@ -357,8 +357,10 @@ typedef LONG_PTR (WINAPI *User32SetWindowLongPtrW)(HWND hWnd, int nIndex, LONG_PTR dwNewLong); -static User32SetWindowLongPtrA sUser32SetWindowLongAHookStub = nullptr; -static User32SetWindowLongPtrW sUser32SetWindowLongWHookStub = nullptr; +static WindowsDllInterceptor::FuncHookType + sUser32SetWindowLongAHookStub; +static WindowsDllInterceptor::FuncHookType + sUser32SetWindowLongWHookStub; #else typedef LONG (WINAPI *User32SetWindowLongA)(HWND hWnd, @@ -368,8 +370,10 @@ typedef LONG (WINAPI *User32SetWindowLongW)(HWND hWnd, int nIndex, LONG dwNewLong); -static User32SetWindowLongA sUser32SetWindowLongAHookStub = nullptr; -static User32SetWindowLongW sUser32SetWindowLongWHookStub = nullptr; +static WindowsDllInterceptor::FuncHookType + sUser32SetWindowLongAHookStub; +static WindowsDllInterceptor::FuncHookType + sUser32SetWindowLongWHookStub; #endif static inline bool SetWindowLongHookCheck(HWND hWnd, @@ -448,23 +452,15 @@ HookSetWindowLongPtr() { sUser32Intercept.Init("user32.dll"); #ifdef _WIN64 - if (!sUser32SetWindowLongAHookStub) - sUser32Intercept.AddHook("SetWindowLongPtrA", - reinterpret_cast(SetWindowLongPtrAHook), - (void**) &sUser32SetWindowLongAHookStub); - if (!sUser32SetWindowLongWHookStub) - sUser32Intercept.AddHook("SetWindowLongPtrW", - reinterpret_cast(SetWindowLongPtrWHook), - (void**) &sUser32SetWindowLongWHookStub); + sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA", + &SetWindowLongPtrAHook); + sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW", + &SetWindowLongPtrWHook); #else - if (!sUser32SetWindowLongAHookStub) - sUser32Intercept.AddHook("SetWindowLongA", - reinterpret_cast(SetWindowLongAHook), - (void**) &sUser32SetWindowLongAHookStub); - if (!sUser32SetWindowLongWHookStub) - sUser32Intercept.AddHook("SetWindowLongW", - reinterpret_cast(SetWindowLongWHook), - (void**) &sUser32SetWindowLongWHookStub); + sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongA", + &SetWindowLongAHook); + sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongW", + &SetWindowLongWHook); #endif } diff --git a/dom/plugins/ipc/FunctionHook.cpp b/dom/plugins/ipc/FunctionHook.cpp index d5e29ec14f18..3d4733a19277 100644 --- a/dom/plugins/ipc/FunctionHook.cpp +++ b/dom/plugins/ipc/FunctionHook.cpp @@ -168,13 +168,13 @@ typedef HANDLE (WINAPI *CreateFileWPtr)(LPCWSTR aFname, DWORD aAccess, LPSECURITY_ATTRIBUTES aSecurity, DWORD aCreation, DWORD aFlags, HANDLE aFTemplate); -static CreateFileWPtr sCreateFileWStub = nullptr; +static WindowsDllInterceptor::FuncHookType sCreateFileWStub; typedef HANDLE (WINAPI *CreateFileAPtr)(LPCSTR aFname, DWORD aAccess, DWORD aShare, LPSECURITY_ATTRIBUTES aSecurity, DWORD aCreation, DWORD aFlags, HANDLE aFTemplate); -static CreateFileAPtr sCreateFileAStub = nullptr; +static WindowsDllInterceptor::FuncHookType sCreateFileAStub; // Windows 8 RTM (kernelbase's version is 6.2.9200.16384) doesn't call // CreateFileW from CreateFileA. @@ -263,7 +263,7 @@ CreateFileWHookFn(LPCWSTR aFname, DWORD aAccess, DWORD aShare, aSecurity, TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, - NULL); + nullptr); if (replacement == INVALID_HANDLE_VALUE) { break; } @@ -300,23 +300,12 @@ CreateFileWHookFn(LPCWSTR aFname, DWORD aAccess, DWORD aShare, void FunctionHook::HookProtectedMode() { - // Make sure we only do this once. - static bool sRunOnce = false; - if (sRunOnce) { - return; - } - sRunOnce = true; - // Legacy code. Uses the nsWindowsDLLInterceptor directly instead of // using the FunctionHook sKernel32Intercept.Init("kernel32.dll"); MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin); - sKernel32Intercept.AddHook("CreateFileW", - reinterpret_cast(CreateFileWHookFn), - (void**) &sCreateFileWStub); - sKernel32Intercept.AddHook("CreateFileA", - reinterpret_cast(CreateFileAHookFn), - (void**) &sCreateFileAStub); + sCreateFileWStub.Set(sKernel32Intercept, "CreateFileW", &CreateFileWHookFn); + sCreateFileAStub.Set(sKernel32Intercept, "CreateFileA", &CreateFileAHookFn); } #endif // defined(XP_WIN) diff --git a/dom/plugins/ipc/FunctionHook.h b/dom/plugins/ipc/FunctionHook.h index c9b30dd0643a..06baf6acdad8 100644 --- a/dom/plugins/ipc/FunctionHook.h +++ b/dom/plugins/ipc/FunctionHook.h @@ -9,6 +9,7 @@ #include "IpdlTuple.h" #include "base/process.h" +#include "mozilla/Atomics.h" #if defined(XP_WIN) #include "nsWindowsDllInterceptor.h" @@ -96,12 +97,19 @@ typedef bool(ShouldHookFunc)(int aQuirks); template class BasicFunctionHook : public FunctionHook { +#if defined(XP_WIN) + using FuncHookType = WindowsDllInterceptor::FuncHookType; +#endif // defined(XP_WIN) + public: BasicFunctionHook(const char* aModuleName, const char* aFunctionName, FunctionType* aOldFunction, - FunctionType* aNewFunction) : - mOldFunction(aOldFunction), mRegistration(UNREGISTERED), mModuleName(aModuleName), - mFunctionName(aFunctionName), mNewFunction(aNewFunction) + FunctionType* aNewFunction) + : mOldFunction(aOldFunction) + , mRegistration(UNREGISTERED) + , mModuleName(aModuleName) + , mFunctionName(aFunctionName) + , mNewFunction(aNewFunction) { MOZ_ASSERT(mOldFunction); MOZ_ASSERT(mNewFunction); @@ -128,7 +136,10 @@ protected: // Once the function is hooked, this field will take the value of a pointer to // a function that performs the old behavior. Before that, it is a pointer to // the original function. - FunctionType* mOldFunction; + Atomic mOldFunction; +#if defined(XP_WIN) + FuncHookType mStub; +#endif // defined(XP_WIN) enum RegistrationStatus { UNREGISTERED, FAILED, SUCCEEDED }; RegistrationStatus mRegistration; @@ -170,14 +181,16 @@ BasicFunctionHook::Register(int aQuirks) return false; } - isHooked = - dllInterceptor->AddHook(mFunctionName.Data(), reinterpret_cast(mNewFunction), - reinterpret_cast(&mOldFunction)); + isHooked = mStub.Set(*dllInterceptor, mFunctionName.Data(), mNewFunction); #endif if (isHooked) { +#if defined(XP_WIN) + mOldFunction = mStub.GetStub(); +#endif mRegistration = SUCCEEDED; } + HOOK_LOG(LogLevel::Debug, ("Registering to intercept function '%s' : '%s'", mFunctionName.Data(), SuccessMsg(isHooked))); diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 47e779a6072c..bab3067be6ee 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -73,21 +73,17 @@ typedef BOOL (WINAPI *User32TrackPopupMenu)(HMENU hMenu, CONST RECT *prcRect); static WindowsDllInterceptor sUser32Intercept; static HWND sWinlessPopupSurrogateHWND = nullptr; -static User32TrackPopupMenu sUser32TrackPopupMenuStub = nullptr; +static WindowsDllInterceptor::FuncHookType sUser32TrackPopupMenuStub; static WindowsDllInterceptor sImm32Intercept; -static decltype(ImmGetContext)* sImm32ImmGetContextStub = nullptr; -static decltype(ImmGetCompositionStringW)* sImm32ImmGetCompositionStringStub = - nullptr; -static decltype(ImmSetCandidateWindow)* sImm32ImmSetCandidateWindowStub = - nullptr; -static decltype(ImmNotifyIME)* sImm32ImmNotifyIME = nullptr; -static decltype(ImmAssociateContextEx)* sImm32ImmAssociateContextExStub = - nullptr; +static WindowsDllInterceptor::FuncHookType sImm32ImmGetContextStub; +static WindowsDllInterceptor::FuncHookType sImm32ImmGetCompositionStringStub; +static WindowsDllInterceptor::FuncHookType sImm32ImmSetCandidateWindowStub; +static WindowsDllInterceptor::FuncHookType sImm32ImmNotifyIME; +static WindowsDllInterceptor::FuncHookType sImm32ImmAssociateContextExStub; + static PluginInstanceChild* sCurrentPluginInstance = nullptr; static const HIMC sHookIMC = (const HIMC)0xefefefef; -static bool sPopupMenuHookSet; -static bool sSetWindowLongHookSet; using mozilla::gfx::SharedDIB; @@ -1793,8 +1789,8 @@ typedef LONG_PTR (WINAPI *User32SetWindowLongPtrW)(HWND hWnd, int nIndex, LONG_PTR dwNewLong); -static User32SetWindowLongPtrA sUser32SetWindowLongAHookStub = nullptr; -static User32SetWindowLongPtrW sUser32SetWindowLongWHookStub = nullptr; +static WindowsDllInterceptor::FuncHookType sUser32SetWindowLongAHookStub; +static WindowsDllInterceptor::FuncHookType sUser32SetWindowLongWHookStub; #else typedef LONG (WINAPI *User32SetWindowLongA)(HWND hWnd, @@ -1804,8 +1800,8 @@ typedef LONG (WINAPI *User32SetWindowLongW)(HWND hWnd, int nIndex, LONG dwNewLong); -static User32SetWindowLongA sUser32SetWindowLongAHookStub = nullptr; -static User32SetWindowLongW sUser32SetWindowLongWHookStub = nullptr; +static WindowsDllInterceptor::FuncHookType sUser32SetWindowLongAHookStub; +static WindowsDllInterceptor::FuncHookType sUser32SetWindowLongWHookStub; #endif extern LRESULT CALLBACK @@ -1915,27 +1911,17 @@ PluginInstanceChild::HookSetWindowLongPtr() return; } - // Only pass through here once - if (sSetWindowLongHookSet) { - return; - } - sSetWindowLongHookSet = true; - sUser32Intercept.Init("user32.dll"); #ifdef _WIN64 - if (!sUser32SetWindowLongAHookStub) - sUser32Intercept.AddHook("SetWindowLongPtrA", reinterpret_cast(SetWindowLongPtrAHook), - (void**) &sUser32SetWindowLongAHookStub); - if (!sUser32SetWindowLongWHookStub) - sUser32Intercept.AddHook("SetWindowLongPtrW", reinterpret_cast(SetWindowLongPtrWHook), - (void**) &sUser32SetWindowLongWHookStub); + sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA", + &SetWindowLongPtrAHook); + sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW", + &SetWindowLongPtrWHook); #else - if (!sUser32SetWindowLongAHookStub) - sUser32Intercept.AddHook("SetWindowLongA", reinterpret_cast(SetWindowLongAHook), - (void**) &sUser32SetWindowLongAHookStub); - if (!sUser32SetWindowLongWHookStub) - sUser32Intercept.AddHook("SetWindowLongW", reinterpret_cast(SetWindowLongWHook), - (void**) &sUser32SetWindowLongWHookStub); + sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongA", + &SetWindowLongAHook); + sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongW", + &SetWindowLongWHook); #endif } @@ -2003,19 +1989,13 @@ PluginInstanceChild::InitPopupMenuHook() return; } - // Only pass through here once - if (sPopupMenuHookSet) { - return; - } - sPopupMenuHookSet = true; - // Note, once WindowsDllInterceptor is initialized for a module, // it remains initialized for that particular module for it's // lifetime. Additional instances are needed if other modules need // to be hooked. sUser32Intercept.Init("user32.dll"); - sUser32Intercept.AddHook("TrackPopupMenu", reinterpret_cast(TrackPopupHookProc), - (void**) &sUser32TrackPopupMenuStub); + sUser32TrackPopupMenuStub.Set(sUser32Intercept, "TrackPopupMenu", + &TrackPopupHookProc); } void @@ -2157,36 +2137,23 @@ PluginInstanceChild::InitImm32Hook() return; } - if (sImm32ImmGetContextStub) { - return; - } - // When using windowless plugin, IMM API won't work due ot OOP. // // ImmReleaseContext on Windows 7+ just returns TRUE only, so we don't // need to hook this. sImm32Intercept.Init("imm32.dll"); - sImm32Intercept.AddHook( - "ImmGetContext", - reinterpret_cast(ImmGetContextProc), - (void**)&sImm32ImmGetContextStub); - sImm32Intercept.AddHook( - "ImmGetCompositionStringW", - reinterpret_cast(ImmGetCompositionStringProc), - (void**)&sImm32ImmGetCompositionStringStub); - sImm32Intercept.AddHook( - "ImmSetCandidateWindow", - reinterpret_cast(ImmSetCandidateWindowProc), - (void**)&sImm32ImmSetCandidateWindowStub); - sImm32Intercept.AddHook( - "ImmNotifyIME", - reinterpret_cast(ImmNotifyIME), - (void**)&sImm32ImmNotifyIME); - sImm32Intercept.AddHook( - "ImmAssociateContextEx", - reinterpret_cast(ImmAssociateContextExProc), - (void**)&sImm32ImmAssociateContextExStub); + sImm32ImmGetContextStub.Set(sImm32Intercept, "ImmGetContext", + &ImmGetContextProc); + sImm32ImmGetCompositionStringStub.Set(sImm32Intercept, + "ImmGetCompositionStringW", + &ImmGetCompositionStringProc); + sImm32ImmSetCandidateWindowStub.Set(sImm32Intercept, + "ImmSetCandidateWindow", + &ImmSetCandidateWindowProc); + sImm32ImmNotifyIME.Set(sImm32Intercept, "ImmNotifyIME", &ImmNotifyIME); + sImm32ImmAssociateContextExStub.Set(sImm32Intercept, "ImmAssociateContextEx", + &ImmAssociateContextExProc); } void