Bug 1460022: Part 7 - Update plugin code to work with revised DLL interceptor interface; r=handyman

This commit is contained in:
Aaron Klotz 2018-06-27 11:50:50 -06:00
Родитель 6d8cf290f7
Коммит 0f899ac198
4 изменённых файлов: 73 добавлений и 108 удалений

Просмотреть файл

@ -357,8 +357,10 @@ typedef LONG_PTR
(WINAPI *User32SetWindowLongPtrW)(HWND hWnd, (WINAPI *User32SetWindowLongPtrW)(HWND hWnd,
int nIndex, int nIndex,
LONG_PTR dwNewLong); LONG_PTR dwNewLong);
static User32SetWindowLongPtrA sUser32SetWindowLongAHookStub = nullptr; static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrA>
static User32SetWindowLongPtrW sUser32SetWindowLongWHookStub = nullptr; sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrW>
sUser32SetWindowLongWHookStub;
#else #else
typedef LONG typedef LONG
(WINAPI *User32SetWindowLongA)(HWND hWnd, (WINAPI *User32SetWindowLongA)(HWND hWnd,
@ -368,8 +370,10 @@ typedef LONG
(WINAPI *User32SetWindowLongW)(HWND hWnd, (WINAPI *User32SetWindowLongW)(HWND hWnd,
int nIndex, int nIndex,
LONG dwNewLong); LONG dwNewLong);
static User32SetWindowLongA sUser32SetWindowLongAHookStub = nullptr; static WindowsDllInterceptor::FuncHookType<User32SetWindowLongA>
static User32SetWindowLongW sUser32SetWindowLongWHookStub = nullptr; sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongW>
sUser32SetWindowLongWHookStub;
#endif #endif
static inline bool static inline bool
SetWindowLongHookCheck(HWND hWnd, SetWindowLongHookCheck(HWND hWnd,
@ -448,23 +452,15 @@ HookSetWindowLongPtr()
{ {
sUser32Intercept.Init("user32.dll"); sUser32Intercept.Init("user32.dll");
#ifdef _WIN64 #ifdef _WIN64
if (!sUser32SetWindowLongAHookStub) sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA",
sUser32Intercept.AddHook("SetWindowLongPtrA", &SetWindowLongPtrAHook);
reinterpret_cast<intptr_t>(SetWindowLongPtrAHook), sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW",
(void**) &sUser32SetWindowLongAHookStub); &SetWindowLongPtrWHook);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongPtrW",
reinterpret_cast<intptr_t>(SetWindowLongPtrWHook),
(void**) &sUser32SetWindowLongWHookStub);
#else #else
if (!sUser32SetWindowLongAHookStub) sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongA",
sUser32Intercept.AddHook("SetWindowLongA", &SetWindowLongAHook);
reinterpret_cast<intptr_t>(SetWindowLongAHook), sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongW",
(void**) &sUser32SetWindowLongAHookStub); &SetWindowLongWHook);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongW",
reinterpret_cast<intptr_t>(SetWindowLongWHook),
(void**) &sUser32SetWindowLongWHookStub);
#endif #endif
} }

Просмотреть файл

@ -168,13 +168,13 @@ typedef HANDLE (WINAPI *CreateFileWPtr)(LPCWSTR aFname, DWORD aAccess,
LPSECURITY_ATTRIBUTES aSecurity, LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags, DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate); HANDLE aFTemplate);
static CreateFileWPtr sCreateFileWStub = nullptr; static WindowsDllInterceptor::FuncHookType<CreateFileWPtr> sCreateFileWStub;
typedef HANDLE (WINAPI *CreateFileAPtr)(LPCSTR aFname, DWORD aAccess, typedef HANDLE (WINAPI *CreateFileAPtr)(LPCSTR aFname, DWORD aAccess,
DWORD aShare, DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity, LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags, DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate); HANDLE aFTemplate);
static CreateFileAPtr sCreateFileAStub = nullptr; static WindowsDllInterceptor::FuncHookType<CreateFileAPtr> sCreateFileAStub;
// Windows 8 RTM (kernelbase's version is 6.2.9200.16384) doesn't call // Windows 8 RTM (kernelbase's version is 6.2.9200.16384) doesn't call
// CreateFileW from CreateFileA. // CreateFileW from CreateFileA.
@ -263,7 +263,7 @@ CreateFileWHookFn(LPCWSTR aFname, DWORD aAccess, DWORD aShare,
aSecurity, TRUNCATE_EXISTING, aSecurity, TRUNCATE_EXISTING,
FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_TEMPORARY |
FILE_FLAG_DELETE_ON_CLOSE, FILE_FLAG_DELETE_ON_CLOSE,
NULL); nullptr);
if (replacement == INVALID_HANDLE_VALUE) { if (replacement == INVALID_HANDLE_VALUE) {
break; break;
} }
@ -300,23 +300,12 @@ CreateFileWHookFn(LPCWSTR aFname, DWORD aAccess, DWORD aShare,
void FunctionHook::HookProtectedMode() 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 // Legacy code. Uses the nsWindowsDLLInterceptor directly instead of
// using the FunctionHook // using the FunctionHook
sKernel32Intercept.Init("kernel32.dll"); sKernel32Intercept.Init("kernel32.dll");
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin); MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin);
sKernel32Intercept.AddHook("CreateFileW", sCreateFileWStub.Set(sKernel32Intercept, "CreateFileW", &CreateFileWHookFn);
reinterpret_cast<intptr_t>(CreateFileWHookFn), sCreateFileAStub.Set(sKernel32Intercept, "CreateFileA", &CreateFileAHookFn);
(void**) &sCreateFileWStub);
sKernel32Intercept.AddHook("CreateFileA",
reinterpret_cast<intptr_t>(CreateFileAHookFn),
(void**) &sCreateFileAStub);
} }
#endif // defined(XP_WIN) #endif // defined(XP_WIN)

Просмотреть файл

@ -9,6 +9,7 @@
#include "IpdlTuple.h" #include "IpdlTuple.h"
#include "base/process.h" #include "base/process.h"
#include "mozilla/Atomics.h"
#if defined(XP_WIN) #if defined(XP_WIN)
#include "nsWindowsDllInterceptor.h" #include "nsWindowsDllInterceptor.h"
@ -96,12 +97,19 @@ typedef bool(ShouldHookFunc)(int aQuirks);
template<FunctionHookId functionId, typename FunctionType> template<FunctionHookId functionId, typename FunctionType>
class BasicFunctionHook : public FunctionHook class BasicFunctionHook : public FunctionHook
{ {
#if defined(XP_WIN)
using FuncHookType = WindowsDllInterceptor::FuncHookType<FunctionType*>;
#endif // defined(XP_WIN)
public: public:
BasicFunctionHook(const char* aModuleName, BasicFunctionHook(const char* aModuleName,
const char* aFunctionName, FunctionType* aOldFunction, const char* aFunctionName, FunctionType* aOldFunction,
FunctionType* aNewFunction) : FunctionType* aNewFunction)
mOldFunction(aOldFunction), mRegistration(UNREGISTERED), mModuleName(aModuleName), : mOldFunction(aOldFunction)
mFunctionName(aFunctionName), mNewFunction(aNewFunction) , mRegistration(UNREGISTERED)
, mModuleName(aModuleName)
, mFunctionName(aFunctionName)
, mNewFunction(aNewFunction)
{ {
MOZ_ASSERT(mOldFunction); MOZ_ASSERT(mOldFunction);
MOZ_ASSERT(mNewFunction); MOZ_ASSERT(mNewFunction);
@ -128,7 +136,10 @@ protected:
// Once the function is hooked, this field will take the value of a pointer to // 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 // a function that performs the old behavior. Before that, it is a pointer to
// the original function. // the original function.
FunctionType* mOldFunction; Atomic<FunctionType*> mOldFunction;
#if defined(XP_WIN)
FuncHookType mStub;
#endif // defined(XP_WIN)
enum RegistrationStatus { UNREGISTERED, FAILED, SUCCEEDED }; enum RegistrationStatus { UNREGISTERED, FAILED, SUCCEEDED };
RegistrationStatus mRegistration; RegistrationStatus mRegistration;
@ -170,14 +181,16 @@ BasicFunctionHook<functionId, FunctionType>::Register(int aQuirks)
return false; return false;
} }
isHooked = isHooked = mStub.Set(*dllInterceptor, mFunctionName.Data(), mNewFunction);
dllInterceptor->AddHook(mFunctionName.Data(), reinterpret_cast<intptr_t>(mNewFunction),
reinterpret_cast<void**>(&mOldFunction));
#endif #endif
if (isHooked) { if (isHooked) {
#if defined(XP_WIN)
mOldFunction = mStub.GetStub();
#endif
mRegistration = SUCCEEDED; mRegistration = SUCCEEDED;
} }
HOOK_LOG(LogLevel::Debug, HOOK_LOG(LogLevel::Debug,
("Registering to intercept function '%s' : '%s'", mFunctionName.Data(), ("Registering to intercept function '%s' : '%s'", mFunctionName.Data(),
SuccessMsg(isHooked))); SuccessMsg(isHooked)));

Просмотреть файл

@ -73,21 +73,17 @@ typedef BOOL (WINAPI *User32TrackPopupMenu)(HMENU hMenu,
CONST RECT *prcRect); CONST RECT *prcRect);
static WindowsDllInterceptor sUser32Intercept; static WindowsDllInterceptor sUser32Intercept;
static HWND sWinlessPopupSurrogateHWND = nullptr; static HWND sWinlessPopupSurrogateHWND = nullptr;
static User32TrackPopupMenu sUser32TrackPopupMenuStub = nullptr; static WindowsDllInterceptor::FuncHookType<User32TrackPopupMenu> sUser32TrackPopupMenuStub;
static WindowsDllInterceptor sImm32Intercept; static WindowsDllInterceptor sImm32Intercept;
static decltype(ImmGetContext)* sImm32ImmGetContextStub = nullptr; static WindowsDllInterceptor::FuncHookType<decltype(&ImmGetContext)> sImm32ImmGetContextStub;
static decltype(ImmGetCompositionStringW)* sImm32ImmGetCompositionStringStub = static WindowsDllInterceptor::FuncHookType<decltype(&ImmGetCompositionStringW)> sImm32ImmGetCompositionStringStub;
nullptr; static WindowsDllInterceptor::FuncHookType<decltype(&ImmSetCandidateWindow)> sImm32ImmSetCandidateWindowStub;
static decltype(ImmSetCandidateWindow)* sImm32ImmSetCandidateWindowStub = static WindowsDllInterceptor::FuncHookType<decltype(&ImmNotifyIME)> sImm32ImmNotifyIME;
nullptr; static WindowsDllInterceptor::FuncHookType<decltype(&ImmAssociateContextEx)> sImm32ImmAssociateContextExStub;
static decltype(ImmNotifyIME)* sImm32ImmNotifyIME = nullptr;
static decltype(ImmAssociateContextEx)* sImm32ImmAssociateContextExStub =
nullptr;
static PluginInstanceChild* sCurrentPluginInstance = nullptr; static PluginInstanceChild* sCurrentPluginInstance = nullptr;
static const HIMC sHookIMC = (const HIMC)0xefefefef; static const HIMC sHookIMC = (const HIMC)0xefefefef;
static bool sPopupMenuHookSet;
static bool sSetWindowLongHookSet;
using mozilla::gfx::SharedDIB; using mozilla::gfx::SharedDIB;
@ -1793,8 +1789,8 @@ typedef LONG_PTR
(WINAPI *User32SetWindowLongPtrW)(HWND hWnd, (WINAPI *User32SetWindowLongPtrW)(HWND hWnd,
int nIndex, int nIndex,
LONG_PTR dwNewLong); LONG_PTR dwNewLong);
static User32SetWindowLongPtrA sUser32SetWindowLongAHookStub = nullptr; static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrA> sUser32SetWindowLongAHookStub;
static User32SetWindowLongPtrW sUser32SetWindowLongWHookStub = nullptr; static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrW> sUser32SetWindowLongWHookStub;
#else #else
typedef LONG typedef LONG
(WINAPI *User32SetWindowLongA)(HWND hWnd, (WINAPI *User32SetWindowLongA)(HWND hWnd,
@ -1804,8 +1800,8 @@ typedef LONG
(WINAPI *User32SetWindowLongW)(HWND hWnd, (WINAPI *User32SetWindowLongW)(HWND hWnd,
int nIndex, int nIndex,
LONG dwNewLong); LONG dwNewLong);
static User32SetWindowLongA sUser32SetWindowLongAHookStub = nullptr; static WindowsDllInterceptor::FuncHookType<User32SetWindowLongA> sUser32SetWindowLongAHookStub;
static User32SetWindowLongW sUser32SetWindowLongWHookStub = nullptr; static WindowsDllInterceptor::FuncHookType<User32SetWindowLongW> sUser32SetWindowLongWHookStub;
#endif #endif
extern LRESULT CALLBACK extern LRESULT CALLBACK
@ -1915,27 +1911,17 @@ PluginInstanceChild::HookSetWindowLongPtr()
return; return;
} }
// Only pass through here once
if (sSetWindowLongHookSet) {
return;
}
sSetWindowLongHookSet = true;
sUser32Intercept.Init("user32.dll"); sUser32Intercept.Init("user32.dll");
#ifdef _WIN64 #ifdef _WIN64
if (!sUser32SetWindowLongAHookStub) sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA",
sUser32Intercept.AddHook("SetWindowLongPtrA", reinterpret_cast<intptr_t>(SetWindowLongPtrAHook), &SetWindowLongPtrAHook);
(void**) &sUser32SetWindowLongAHookStub); sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW",
if (!sUser32SetWindowLongWHookStub) &SetWindowLongPtrWHook);
sUser32Intercept.AddHook("SetWindowLongPtrW", reinterpret_cast<intptr_t>(SetWindowLongPtrWHook),
(void**) &sUser32SetWindowLongWHookStub);
#else #else
if (!sUser32SetWindowLongAHookStub) sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongA",
sUser32Intercept.AddHook("SetWindowLongA", reinterpret_cast<intptr_t>(SetWindowLongAHook), &SetWindowLongAHook);
(void**) &sUser32SetWindowLongAHookStub); sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongW",
if (!sUser32SetWindowLongWHookStub) &SetWindowLongWHook);
sUser32Intercept.AddHook("SetWindowLongW", reinterpret_cast<intptr_t>(SetWindowLongWHook),
(void**) &sUser32SetWindowLongWHookStub);
#endif #endif
} }
@ -2003,19 +1989,13 @@ PluginInstanceChild::InitPopupMenuHook()
return; return;
} }
// Only pass through here once
if (sPopupMenuHookSet) {
return;
}
sPopupMenuHookSet = true;
// Note, once WindowsDllInterceptor is initialized for a module, // Note, once WindowsDllInterceptor is initialized for a module,
// it remains initialized for that particular module for it's // it remains initialized for that particular module for it's
// lifetime. Additional instances are needed if other modules need // lifetime. Additional instances are needed if other modules need
// to be hooked. // to be hooked.
sUser32Intercept.Init("user32.dll"); sUser32Intercept.Init("user32.dll");
sUser32Intercept.AddHook("TrackPopupMenu", reinterpret_cast<intptr_t>(TrackPopupHookProc), sUser32TrackPopupMenuStub.Set(sUser32Intercept, "TrackPopupMenu",
(void**) &sUser32TrackPopupMenuStub); &TrackPopupHookProc);
} }
void void
@ -2157,36 +2137,23 @@ PluginInstanceChild::InitImm32Hook()
return; return;
} }
if (sImm32ImmGetContextStub) {
return;
}
// When using windowless plugin, IMM API won't work due ot OOP. // When using windowless plugin, IMM API won't work due ot OOP.
// //
// ImmReleaseContext on Windows 7+ just returns TRUE only, so we don't // ImmReleaseContext on Windows 7+ just returns TRUE only, so we don't
// need to hook this. // need to hook this.
sImm32Intercept.Init("imm32.dll"); sImm32Intercept.Init("imm32.dll");
sImm32Intercept.AddHook( sImm32ImmGetContextStub.Set(sImm32Intercept, "ImmGetContext",
"ImmGetContext", &ImmGetContextProc);
reinterpret_cast<intptr_t>(ImmGetContextProc), sImm32ImmGetCompositionStringStub.Set(sImm32Intercept,
(void**)&sImm32ImmGetContextStub); "ImmGetCompositionStringW",
sImm32Intercept.AddHook( &ImmGetCompositionStringProc);
"ImmGetCompositionStringW", sImm32ImmSetCandidateWindowStub.Set(sImm32Intercept,
reinterpret_cast<intptr_t>(ImmGetCompositionStringProc), "ImmSetCandidateWindow",
(void**)&sImm32ImmGetCompositionStringStub); &ImmSetCandidateWindowProc);
sImm32Intercept.AddHook( sImm32ImmNotifyIME.Set(sImm32Intercept, "ImmNotifyIME", &ImmNotifyIME);
"ImmSetCandidateWindow", sImm32ImmAssociateContextExStub.Set(sImm32Intercept, "ImmAssociateContextEx",
reinterpret_cast<intptr_t>(ImmSetCandidateWindowProc), &ImmAssociateContextExProc);
(void**)&sImm32ImmSetCandidateWindowStub);
sImm32Intercept.AddHook(
"ImmNotifyIME",
reinterpret_cast<intptr_t>(ImmNotifyIME),
(void**)&sImm32ImmNotifyIME);
sImm32Intercept.AddHook(
"ImmAssociateContextEx",
reinterpret_cast<intptr_t>(ImmAssociateContextExProc),
(void**)&sImm32ImmAssociateContextExStub);
} }
void void