Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Gurzau Raul 2018-07-04 13:01:13 +03:00
Родитель 73925a85fe 03062dd04b
Коммит 112c3bb6dd
63 изменённых файлов: 1091 добавлений и 889 удалений

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

@ -95,7 +95,8 @@ Compatibility::IsModuleVersionLessThan(HMODULE aModuleHandle,
////////////////////////////////////////////////////////////////////////////////
static WindowsDllInterceptor sUser32Interceptor;
static decltype(&InSendMessageEx) sInSendMessageExStub = nullptr;
static WindowsDllInterceptor::FuncHookType<decltype(&InSendMessageEx)>
sInSendMessageExStub;
static bool sInSendMessageExHackEnabled = false;
static PVOID sVectoredExceptionHandler = nullptr;
@ -267,11 +268,9 @@ Compatibility::Init()
if ((sConsumers & (~(UIAUTOMATION | NVDA))) &&
BrowserTabsRemoteAutostart()) {
sUser32Interceptor.Init("user32.dll");
if (!sInSendMessageExStub) {
sUser32Interceptor.AddHook("InSendMessageEx",
reinterpret_cast<intptr_t>(&InSendMessageExHook),
(void**)&sInSendMessageExStub);
}
sInSendMessageExStub.Set(sUser32Interceptor, "InSendMessageEx",
&InSendMessageExHook);
// The vectored exception handler allows us to catch exceptions ahead of any
// SEH handlers.
if (!sVectoredExceptionHandler) {

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

@ -246,7 +246,8 @@ IsDllAllowed(const UNICODE_STRING& aLeafName, void* aBaseAddress)
}
typedef decltype(&NtMapViewOfSection) NtMapViewOfSection_func;
static NtMapViewOfSection_func stub_NtMapViewOfSection;
static mozilla::CrossProcessDllInterceptor::FuncHookType<NtMapViewOfSection_func>
stub_NtMapViewOfSection;
static NTSTATUS NTAPI
patched_NtMapViewOfSection(HANDLE aSection, HANDLE aProcess, PVOID* aBaseAddress,
@ -356,9 +357,8 @@ InitializeDllBlocklistOOP(HANDLE aChildProcess)
{
mozilla::CrossProcessDllInterceptor intcpt(aChildProcess);
intcpt.Init(L"ntdll.dll");
bool ok = intcpt.AddDetour("NtMapViewOfSection",
reinterpret_cast<intptr_t>(&patched_NtMapViewOfSection),
(void**) &stub_NtMapViewOfSection);
bool ok = stub_NtMapViewOfSection.SetDetour(intcpt, "NtMapViewOfSection",
&patched_NtMapViewOfSection);
if (!ok) {
return false;
}

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

@ -995,12 +995,22 @@ nsContextMenu.prototype = {
target: this.target,
});
// Cache this because we fetch the data async
let {documentURIObject} = gContextMenuContentData;
let onMessage = (message) => {
mm.removeMessageListener("ContextMenu:SaveVideoFrameAsImage:Result", onMessage);
// FIXME can we switch this to a blob URL?
let dataURL = message.data.dataURL;
saveImageURL(dataURL, name, "SaveImageTitle", true, false,
document.documentURIObject, null, null, null,
isPrivate);
saveImageURL(dataURL, name, "SaveImageTitle",
true, // bypass cache
false, // don't skip prompt for where to save
documentURIObject, // referrer
null, // document
null, // content type
null, // content disposition
isPrivate,
this.principal);
};
mm.addMessageListener("ContextMenu:SaveVideoFrameAsImage:Result", onMessage);
},
@ -1238,13 +1248,15 @@ nsContextMenu.prototype = {
this._canvasToBlobURL(this.target).then(function(blobURL) {
saveImageURL(blobURL, "canvas.png", "SaveImageTitle",
true, false, referrerURI, null, null, null,
isPrivate);
isPrivate,
document.nodePrincipal /* system, because blob: */);
}, Cu.reportError);
} else if (this.onImage) {
urlSecurityCheck(this.mediaURL, this.principal);
saveImageURL(this.mediaURL, null, "SaveImageTitle", false,
false, referrerURI, null, gContextMenuContentData.contentType,
gContextMenuContentData.contentDisposition, isPrivate);
gContextMenuContentData.contentDisposition, isPrivate,
this.principal);
} else if (this.onVideo || this.onAudio) {
var dialogTitle = this.onVideo ? "SaveVideoTitle" : "SaveAudioTitle";
this.saveHelper(this.mediaURL, null, dialogTitle, false, doc, referrerURI,

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

@ -689,7 +689,8 @@ function saveMedia() {
var saveAnImage = function(aURIString, aChosenData, aBaseURI) {
uniqueFile(aChosenData.file);
internalSave(aURIString, null, null, null, null, false, "SaveImageTitle",
aChosenData, aBaseURI, null, false, null, gDocInfo.isContentWindowPrivate);
aChosenData, aBaseURI, null, false, null,
gDocInfo.isContentWindowPrivate, gDocInfo.principal);
};
for (var i = 0; i < rowArray.length; i++) {

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

@ -305,7 +305,8 @@ function openLinkIn(url, where, params) {
// ContentClick.jsm passes isContentWindowPrivate for saveURL instead of passing a CPOW initiatingDoc
if ("isContentWindowPrivate" in params) {
saveURL(url, null, null, true, true, aNoReferrer ? null : aReferrerURI, null, params.isContentWindowPrivate);
saveURL(url, null, null, true, true, aNoReferrer ? null : aReferrerURI,
null, params.isContentWindowPrivate, aPrincipal);
} else {
if (!aInitiatingDoc) {
Cu.reportError("openUILink/openLinkIn was called with " +

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

@ -153,7 +153,7 @@ nsMacShellService::SetDesktopBackground(Element* aElement,
loadContext = do_QueryInterface(docShell);
}
return wbp->SaveURI(imageURI, 0,
return wbp->SaveURI(imageURI, aElement->NodePrincipal(), 0,
docURI, aElement->OwnerDoc()->GetReferrerPolicy(),
nullptr, nullptr,
mBackgroundFile, loadContext);

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

@ -554,7 +554,6 @@ var saveToFile = Task.async(function* (context, reply) {
// the downloads toolbar button when the save is done.
const nsIWBP = Ci.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
nsIWBP.PERSIST_FLAGS_FORCE_ALLOW_COOKIES |
nsIWBP.PERSIST_FLAGS_BYPASS_CACHE |
nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
const isPrivate =
@ -573,7 +572,9 @@ var saveToFile = Task.async(function* (context, reply) {
isPrivate);
const listener = new DownloadListener(window, tr);
persist.progressListener = listener;
const principal = Services.scriptSecurityManager.getSystemPrincipal();
persist.savePrivacyAwareURI(sourceURI,
principal,
0,
document.documentURIObject,
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,

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

@ -355,7 +355,6 @@ async function saveToFile(window, image) {
// the downloads toolbar button when the save is done.
const nsIWBP = Ci.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
nsIWBP.PERSIST_FLAGS_FORCE_ALLOW_COOKIES |
nsIWBP.PERSIST_FLAGS_BYPASS_CACHE |
nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
const isPrivate =
@ -374,7 +373,9 @@ async function saveToFile(window, image) {
isPrivate);
const listener = new DownloadListener(window, tr);
persist.progressListener = listener;
const principal = Services.scriptSecurityManager.getSystemPrincipal();
persist.savePrivacyAwareURI(sourceURI,
principal,
0,
document.documentURIObject,
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,

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

@ -40,6 +40,8 @@ ChromeUtils.defineModuleGetter(this, "CustomizableUI",
"resource:///modules/CustomizableUI.jsm");
ChromeUtils.defineModuleGetter(this, "CustomizableWidgets",
"resource:///modules/CustomizableWidgets.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
// We don't want to spend time initializing the full loader here so we create
// our own lazy require.
@ -948,16 +950,32 @@ const JsonView = {
// Save original contents
chrome.saveBrowser(browser);
} else {
if (!message.data.startsWith("blob:null") || !browser.contentPrincipal.isNullPrincipal) {
Cu.reportError("Got invalid request to save JSON data");
return;
}
// The following code emulates saveBrowser, but:
// - Uses the given blob URL containing the custom contents to save.
// - Obtains the file name from the URL of the document, not the blob.
// - avoids passing the document and explicitly passes system principal.
// We have a blob created by a null principal to save, and the null
// principal is from the child. Null principals don't survive crossing
// over IPC, so there's no other principal that'll work.
const persistable = browser.frameLoader;
persistable.startPersistence(0, {
onDocumentReady(doc) {
const uri = chrome.makeURI(doc.documentURI, doc.characterSet);
const filename = chrome.getDefaultFileName(undefined, uri, doc, null);
chrome.internalSave(message.data, doc, filename, null, doc.contentType,
false, null, null, null, doc, false, null, undefined);
chrome.internalSave(message.data, null, filename, null, doc.contentType,
false /* bypass cache */,
null, /* filepicker title key */
null, /* file chosen */
null, /* referrer */
null, /* initiating document */
false, /* don't skip prompt for a location */
null, /* cache key */
PrivateBrowsingUtils.isBrowserPrivate(browser), /* private browsing ? */
Services.scriptSecurityManager.getSystemPrincipal());
},
onError(status) {
throw new Error("JSON Viewer's onSave failed in startPersistence");

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

@ -115,3 +115,7 @@ method console.exception
method console.timeStamp
method console.profile
method console.profileEnd
// document.open information
custom DocumentOpen calls document.open in a way that creates a new Window object
custom DocumentOpenReplace calls document.open in a way that creates a new Window object and replaces the old history entry.

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

@ -141,6 +141,7 @@ NS_IMPL_ISUPPORTS(nsContentAreaDragDropDataProvider, nsIFlavorDataProvider)
// into the file system
nsresult
nsContentAreaDragDropDataProvider::SaveURIToFile(nsIURI* inSourceURI,
nsIPrincipal* inTriggeringPrincipal,
nsIFile* inDestFile,
bool isPrivate)
{
@ -162,7 +163,8 @@ nsContentAreaDragDropDataProvider::SaveURIToFile(nsIURI* inSourceURI,
persist->SetPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION);
// referrer policy can be anything since the referrer is nullptr
return persist->SavePrivacyAwareURI(inSourceURI, 0, nullptr,
return persist->SavePrivacyAwareURI(inSourceURI,
inTriggeringPrincipal, 0, nullptr,
mozilla::net::RP_Unset,
nullptr, nullptr,
inDestFile, isPrivate);
@ -342,7 +344,9 @@ nsContentAreaDragDropDataProvider::GetFlavorData(nsITransferable *aTransferable,
bool isPrivate;
aTransferable->GetIsPrivateData(&isPrivate);
rv = SaveURIToFile(sourceURI, file, isPrivate);
nsCOMPtr<nsIPrincipal> principal;
aTransferable->GetRequestingPrincipal(getter_AddRefs(principal));
rv = SaveURIToFile(sourceURI, principal, file, isPrivate);
// send back an nsIFile
if (NS_SUCCEEDED(rv)) {
CallQueryInterface(file, aData);

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

@ -77,6 +77,7 @@ public:
NS_DECL_NSIFLAVORDATAPROVIDER
nsresult SaveURIToFile(nsIURI* inSourceURI,
nsIPrincipal* inTriggeringPrincipal,
nsIFile* inDestFile, bool isPrivate);
};

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

@ -1339,6 +1339,14 @@ nsHTMLDocument::Open(JSContext* cx,
return nullptr;
}
// At this point we know this is a valid-enough document.open() call
// and not a no-op. Increment our use counters.
SetDocumentAndPageUseCounter(eUseCounter_custom_DocumentOpen);
bool isReplace = aReplace.LowerCaseEqualsLiteral("replace");
if (isReplace) {
SetDocumentAndPageUseCounter(eUseCounter_custom_DocumentOpenReplace);
}
// Stop current loads targeted at the window this document is in.
if (mScriptGlobalObject) {
nsCOMPtr<nsIContentViewer> cv;
@ -1567,8 +1575,7 @@ nsHTMLDocument::Open(JSContext* cx,
// so, we need to tell the docshell to not create a new history
// entry for this load. Otherwise, make sure that we're doing a normal load,
// not whatever type of load was previously done on this docshell.
shell->SetLoadType(aReplace.LowerCaseEqualsLiteral("replace") ?
LOAD_NORMAL_REPLACE : LOAD_NORMAL);
shell->SetLoadType(isReplace ? LOAD_NORMAL_REPLACE : LOAD_NORMAL);
nsCOMPtr<nsIContentViewer> cv;
shell->GetContentViewer(getter_AddRefs(cv));

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

@ -197,7 +197,8 @@ typedef DWORD(WINAPI* QueryDosDeviceWFnPtr)(_In_opt_ LPCWSTR lpDeviceName,
_Out_ LPWSTR lpTargetPath,
_In_ DWORD ucchMax);
static QueryDosDeviceWFnPtr sOriginalQueryDosDeviceWFnPtr = nullptr;
static WindowsDllInterceptor::FuncHookType<QueryDosDeviceWFnPtr>
sOriginalQueryDosDeviceWFnPtr;
static std::unordered_map<std::wstring, std::wstring>* sDeviceNames = nullptr;
@ -276,9 +277,8 @@ InitializeHooks()
}
sKernel32Intercept.Init("kernelbase.dll");
sKernel32Intercept.AddHook("QueryDosDeviceW",
reinterpret_cast<intptr_t>(QueryDosDeviceWHook),
(void**)(&sOriginalQueryDosDeviceWFnPtr));
sOriginalQueryDosDeviceWFnPtr.Set(sKernel32Intercept, "QueryDosDeviceW",
&QueryDosDeviceWHook);
}
#endif

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

@ -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<User32SetWindowLongPtrA>
sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrW>
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<User32SetWindowLongA>
sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongW>
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<intptr_t>(SetWindowLongPtrAHook),
(void**) &sUser32SetWindowLongAHookStub);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongPtrW",
reinterpret_cast<intptr_t>(SetWindowLongPtrWHook),
(void**) &sUser32SetWindowLongWHookStub);
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA",
&SetWindowLongPtrAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW",
&SetWindowLongPtrWHook);
#else
if (!sUser32SetWindowLongAHookStub)
sUser32Intercept.AddHook("SetWindowLongA",
reinterpret_cast<intptr_t>(SetWindowLongAHook),
(void**) &sUser32SetWindowLongAHookStub);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongW",
reinterpret_cast<intptr_t>(SetWindowLongWHook),
(void**) &sUser32SetWindowLongWHookStub);
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongA",
&SetWindowLongAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongW",
&SetWindowLongWHook);
#endif
}

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

@ -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<CreateFileWPtr> 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<CreateFileAPtr> 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<intptr_t>(CreateFileWHookFn),
(void**) &sCreateFileWStub);
sKernel32Intercept.AddHook("CreateFileA",
reinterpret_cast<intptr_t>(CreateFileAHookFn),
(void**) &sCreateFileAStub);
sCreateFileWStub.Set(sKernel32Intercept, "CreateFileW", &CreateFileWHookFn);
sCreateFileAStub.Set(sKernel32Intercept, "CreateFileA", &CreateFileAHookFn);
}
#endif // defined(XP_WIN)

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

@ -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<FunctionHookId functionId, typename FunctionType>
class BasicFunctionHook : public FunctionHook
{
#if defined(XP_WIN)
using FuncHookType = WindowsDllInterceptor::FuncHookType<FunctionType*>;
#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<FunctionType*> mOldFunction;
#if defined(XP_WIN)
FuncHookType mStub;
#endif // defined(XP_WIN)
enum RegistrationStatus { UNREGISTERED, FAILED, SUCCEEDED };
RegistrationStatus mRegistration;
@ -170,14 +181,16 @@ BasicFunctionHook<functionId, FunctionType>::Register(int aQuirks)
return false;
}
isHooked =
dllInterceptor->AddHook(mFunctionName.Data(), reinterpret_cast<intptr_t>(mNewFunction),
reinterpret_cast<void**>(&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)));

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

@ -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<User32TrackPopupMenu> 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<decltype(&ImmGetContext)> sImm32ImmGetContextStub;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmGetCompositionStringW)> sImm32ImmGetCompositionStringStub;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmSetCandidateWindow)> sImm32ImmSetCandidateWindowStub;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmNotifyIME)> sImm32ImmNotifyIME;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmAssociateContextEx)> 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<User32SetWindowLongPtrA> sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrW> 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<User32SetWindowLongA> sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongW> 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<intptr_t>(SetWindowLongPtrAHook),
(void**) &sUser32SetWindowLongAHookStub);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongPtrW", reinterpret_cast<intptr_t>(SetWindowLongPtrWHook),
(void**) &sUser32SetWindowLongWHookStub);
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA",
&SetWindowLongPtrAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW",
&SetWindowLongPtrWHook);
#else
if (!sUser32SetWindowLongAHookStub)
sUser32Intercept.AddHook("SetWindowLongA", reinterpret_cast<intptr_t>(SetWindowLongAHook),
(void**) &sUser32SetWindowLongAHookStub);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongW", reinterpret_cast<intptr_t>(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<intptr_t>(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<intptr_t>(ImmGetContextProc),
(void**)&sImm32ImmGetContextStub);
sImm32Intercept.AddHook(
"ImmGetCompositionStringW",
reinterpret_cast<intptr_t>(ImmGetCompositionStringProc),
(void**)&sImm32ImmGetCompositionStringStub);
sImm32Intercept.AddHook(
"ImmSetCandidateWindow",
reinterpret_cast<intptr_t>(ImmSetCandidateWindowProc),
(void**)&sImm32ImmSetCandidateWindowStub);
sImm32Intercept.AddHook(
"ImmNotifyIME",
reinterpret_cast<intptr_t>(ImmNotifyIME),
(void**)&sImm32ImmNotifyIME);
sImm32Intercept.AddHook(
"ImmAssociateContextEx",
reinterpret_cast<intptr_t>(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

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

@ -57,6 +57,10 @@ skip-if = !e10s || (os == "win" && processor == "x86") || (verify && debug && (o
[browser_localStorage_e10s.js]
skip-if = !e10s || verify # This is a test of e10s functionality.
[browser_localStorage_privatestorageevent.js]
[browser_persist_cookies.js]
support-files =
set-samesite-cookies-and-redirect.sjs
mimeme.sjs
[browser_test_focus_after_modal_state.js]
skip-if = verify
support-files =

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

@ -0,0 +1,94 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.org");
const TEST_PATH2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
registerCleanupFunction(async function() {
info("Running the cleanup code");
MockFilePicker.cleanup();
Services.obs.removeObserver(checkRequest, "http-on-modify-request");
if (gTestDir && gTestDir.exists()) {
// On Windows, sometimes nsIFile.remove() throws, probably because we're
// still writing to the directory we're trying to remove, despite
// waiting for the download to complete. Just retry a bit later...
let succeeded = false;
while (!succeeded) {
try {
gTestDir.remove(true);
succeeded = true;
} catch (ex) {
await new Promise(requestAnimationFrame);
}
}
}
});
let gTestDir = null;
function checkRequest(subject) {
let httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
let spec = httpChannel.URI.spec;
// Ignore initial requests for page that sets cookies and its favicon, which may not have
// cookies.
if (httpChannel.URI.host == "example.org" && !spec.endsWith("favicon.ico") && !spec.includes("redirect.sjs")) {
let cookie = httpChannel.getRequestHeader("cookie");
is(cookie.trim(), "normalCookie=true", "Should have correct cookie in request for " + spec);
}
}
function createTemporarySaveDirectory() {
var saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
saveDir.append("testsavedir");
if (!saveDir.exists()) {
info("create testsavedir!");
saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
}
info("return from createTempSaveDir: " + saveDir.path);
return saveDir;
}
add_task(async function() {
await BrowserTestUtils.withNewTab("about:blank", async function(browser) {
Services.obs.addObserver(checkRequest, "http-on-modify-request");
BrowserTestUtils.loadURI(browser, TEST_PATH + "set-samesite-cookies-and-redirect.sjs");
// Test that the original document load doesn't send same-site cookies.
await BrowserTestUtils.browserLoaded(browser, true, TEST_PATH2 + "set-samesite-cookies-and-redirect.sjs");
// Now check the saved page.
// Create the folder the link will be saved into.
gTestDir = createTemporarySaveDirectory();
let destFile = gTestDir.clone();
MockFilePicker.displayDirectory = gTestDir;
let fileName;
MockFilePicker.showCallback = function(fp) {
info("showCallback");
fileName = fp.defaultString;
info("fileName: " + fileName);
destFile.append(fileName);
info("path: " + destFile.path);
MockFilePicker.setFiles([destFile]);
MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
info("done showCallback");
};
saveBrowser(browser);
await new Promise(async (resolve) => {
let dls = await Downloads.getList(Downloads.PUBLIC);
dls.addView({
onDownloadChanged(download) {
if (download.succeeded) {
dls.removeView(this);
dls.removeFinished();
resolve();
}
}
});
});
});
});

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

@ -0,0 +1,26 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
function handleRequest(request, response) {
let mimeType = request.queryString.match(/type=([a-z]*)/)[1];
switch (mimeType) {
case "css":
response.setHeader("Content-Type", "text/css");
response.write("#hi {color: red}");
break;
case "js":
response.setHeader("Content-Type", "application/javascript");
response.write("var foo;");
break;
case "png":
response.setHeader("Content-Type", "image/png");
response.write("");
break;
case "html":
response.setHeader("Content-Type", "text/html");
response.write("<body>I am a subframe</body>");
break;
}
}

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

@ -0,0 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
function handleRequest(request, response) {
// Set cookies and redirect for .org:
if (request.host.endsWith(".org")) {
response.setHeader("Set-Cookie", "normalCookie=true; path=/;", true);
response.setHeader("Set-Cookie", "laxHeader=true; path=/; SameSite=Lax", true);
response.setHeader("Set-Cookie", "strictHeader=true; path=/; SameSite=Strict", true);
response.write(`
<head>
<meta http-equiv='set-cookie' content='laxMeta=true; path=/; SameSite=Lax'>
<meta http-equiv='set-cookie' content='strictMeta=true; path=/; SameSite=Strict'>
</head>
<body>
<script>
document.cookie = 'laxScript=true; path=/; SameSite=Lax';
document.cookie = 'strictScript=true; path=/; SameSite=Strict';
location.href = location.href.replace(/\.org/, ".com");
</script>
</body>`);
} else {
let baseURI = "https://example.org/" + request.path.replace(/[a-z-]*\.sjs/, "mimeme.sjs?type=");
response.write(`
<link rel="stylesheet" type="text/css" href="${baseURI}css">
<iframe src="${baseURI}html"></iframe>
<script src="${baseURI}js"></script>
<img src="${baseURI}png">
`);
}
}

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

@ -10,6 +10,7 @@ include protocol PFileDescriptorSet;
include protocol PChildToParentStream; //FIXME: bug #792908
include protocol PParentToChildStream; //FIXME: bug #792908
include PBackgroundSharedTypes;
include IPCStream;
namespace mozilla {
@ -29,6 +30,7 @@ struct WebBrowserPersistDocumentAttrs {
nsString contentDisposition;
uint32_t cacheKey;
uint32_t persistFlags;
PrincipalInfo principal;
};
// IPDL doesn't have tuples, so this gives the pair of strings from

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

@ -41,6 +41,7 @@ WebBrowserPersistDocumentChild::Start(nsIWebBrowserPersistDocument* aDocument)
return;
}
nsCOMPtr<nsIPrincipal> principal;
WebBrowserPersistDocumentAttrs attrs;
nsCOMPtr<nsIInputStream> postDataStream;
#define ENSURE(e) do { \
@ -60,6 +61,10 @@ WebBrowserPersistDocumentChild::Start(nsIWebBrowserPersistDocument* aDocument)
ENSURE(aDocument->GetContentDisposition(attrs.contentDisposition()));
ENSURE(aDocument->GetCacheKey(&(attrs.cacheKey())));
ENSURE(aDocument->GetPersistFlags(&(attrs.persistFlags())));
ENSURE(aDocument->GetPrincipal(getter_AddRefs(principal)));
ENSURE(ipc::PrincipalToPrincipalInfo(principal, &(attrs.principal())));
ENSURE(aDocument->GetPostData(getter_AddRefs(postDataStream)));
#undef ENSURE

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

@ -184,6 +184,14 @@ WebBrowserPersistLocalDocument::GetPostData(nsIInputStream** aStream)
return history->GetPostData(aStream);
}
NS_IMETHODIMP
WebBrowserPersistLocalDocument::GetPrincipal(nsIPrincipal** aPrincipal)
{
nsCOMPtr<nsIPrincipal> nodePrincipal = mDocument->NodePrincipal();
nodePrincipal.forget(aPrincipal);
return NS_OK;
}
already_AddRefed<nsISHEntry>
WebBrowserPersistLocalDocument::GetHistory()
{

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

@ -9,6 +9,9 @@
#include "WebBrowserPersistResourcesParent.h"
#include "WebBrowserPersistSerializeParent.h"
#include "mozilla/Unused.h"
#include "mozilla/ipc/BackgroundUtils.h"
#include "nsIPrincipal.h"
namespace mozilla {
@ -23,6 +26,8 @@ WebBrowserPersistRemoteDocument
, mAttrs(aAttrs)
, mPostData(aPostData)
{
nsresult rv;
mPrincipal = ipc::PrincipalInfoToPrincipal(mAttrs.principal(), &rv);
}
WebBrowserPersistRemoteDocument::~WebBrowserPersistRemoteDocument()
@ -132,6 +137,14 @@ WebBrowserPersistRemoteDocument::GetPostData(nsIInputStream** aStream)
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistRemoteDocument::GetPrincipal(nsIPrincipal** aPrincipal)
{
nsCOMPtr<nsIPrincipal> nodePrincipal = mPrincipal;
nodePrincipal.forget(aPrincipal);
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistRemoteDocument::ReadResources(nsIWebBrowserPersistResourceVisitor* aVisitor)
{

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

@ -13,6 +13,8 @@
#include "nsIWebBrowserPersistDocument.h"
#include "nsIInputStream.h"
class nsIPrincipal;
// This class is the XPCOM half of the glue between the
// nsIWebBrowserPersistDocument interface and a remote document; it is
// created by WebBrowserPersistDocumentParent when (and if) it
@ -40,6 +42,7 @@ private:
WebBrowserPersistDocumentParent* mActor;
Attrs mAttrs;
nsCOMPtr<nsIInputStream> mPostData;
nsCOMPtr<nsIPrincipal> mPrincipal;
friend class WebBrowserPersistDocumentParent;
WebBrowserPersistRemoteDocument(WebBrowserPersistDocumentParent* aActor,

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

@ -12,6 +12,7 @@ interface nsIWebProgressListener;
interface nsIFile;
interface nsIChannel;
interface nsILoadContext;
interface nsIPrincipal;
/**
* Interface for persisting DOM documents and URIs to local or remote storage.
@ -65,12 +66,6 @@ interface nsIWebBrowserPersist : nsICancelable
*/
const unsigned long PERSIST_FLAGS_APPEND_TO_FILE = 32768;
/**
* Force relevant cookies to be sent with this load even if normally they
* wouldn't be.
*/
const unsigned long PERSIST_FLAGS_FORCE_ALLOW_COOKIES = 65536;
/**
* Flags governing how data is fetched and saved from the network.
* It is best to set this value explicitly unless you are prepared
@ -116,6 +111,8 @@ interface nsIWebBrowserPersist : nsICancelable
* @param aURI URI to save to file. Some implementations of this interface
* may also support <CODE>nullptr</CODE> to imply the currently
* loaded URI.
* @param aTriggeringPrincipal
* The triggering principal for the URI we're saving.
* @param aCacheKey The necko cache key integer.
* @param aReferrer The referrer URI to pass with an HTTP request or
* <CODE>nullptr</CODE>.
@ -142,7 +139,8 @@ interface nsIWebBrowserPersist : nsICancelable
*
* @throws NS_ERROR_INVALID_ARG One or more arguments was invalid.
*/
void saveURI(in nsIURI aURI, in unsigned long aCacheKey,
void saveURI(in nsIURI aURI, in nsIPrincipal aTriggeringPrincipal,
in unsigned long aCacheKey,
in nsIURI aReferrer, in unsigned long aReferrerPolicy,
in nsIInputStream aPostData,
in string aExtraHeaders, in nsISupports aFile,
@ -154,7 +152,8 @@ interface nsIWebBrowserPersist : nsICancelable
* of intermediate data, etc.)
* @see saveURI for all other parameter descriptions
*/
void savePrivacyAwareURI(in nsIURI aURI, in unsigned long aCacheKey,
void savePrivacyAwareURI(in nsIURI aURI,
in nsIPrincipal aTriggeringPrincipal, in unsigned long aCacheKey,
in nsIURI aReferrer, in unsigned long aReferrerPolicy,
in nsIInputStream aPostData,
in string aExtraHeaders, in nsISupports aFile,

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

@ -8,6 +8,7 @@
interface nsIInputStream;
interface nsIOutputStream;
interface nsIPrincipal;
interface nsITabParent;
interface nsIWebBrowserPersistResourceVisitor;
interface nsIWebBrowserPersistWriteCompletion;
@ -60,6 +61,7 @@ interface nsIWebBrowserPersistDocument : nsISupports
readonly attribute AString referrer;
readonly attribute AString contentDisposition;
readonly attribute nsIInputStream postData;
readonly attribute nsIPrincipal principal;
/**
* The cache key. Unlike in nsISHEntry, where it's wrapped in an

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

@ -83,6 +83,7 @@ struct nsWebBrowserPersist::DocData
nsCOMPtr<nsIURI> mBaseURI;
nsCOMPtr<nsIWebBrowserPersistDocument> mDocument;
nsCOMPtr<nsIURI> mFile;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCString mCharset;
};
@ -413,18 +414,20 @@ NS_IMETHODIMP nsWebBrowserPersist::SetProgressListener(
}
NS_IMETHODIMP nsWebBrowserPersist::SaveURI(
nsIURI *aURI, uint32_t aCacheKey,
nsIURI *aURI, nsIPrincipal *aPrincipal, uint32_t aCacheKey,
nsIURI *aReferrer, uint32_t aReferrerPolicy,
nsIInputStream *aPostData, const char *aExtraHeaders,
nsISupports *aFile, nsILoadContext* aPrivacyContext)
{
return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aReferrerPolicy,
aPostData, aExtraHeaders, aFile,
aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
bool isPrivate =
aPrivacyContext && aPrivacyContext->UsePrivateBrowsing();
return SavePrivacyAwareURI(aURI, aPrincipal, aCacheKey,
aReferrer, aReferrerPolicy,
aPostData, aExtraHeaders, aFile, isPrivate);
}
NS_IMETHODIMP nsWebBrowserPersist::SavePrivacyAwareURI(
nsIURI *aURI, uint32_t aCacheKey,
nsIURI *aURI, nsIPrincipal *aPrincipal, uint32_t aCacheKey,
nsIURI *aReferrer, uint32_t aReferrerPolicy,
nsIInputStream *aPostData, const char *aExtraHeaders,
nsISupports *aFile, bool aIsPrivate)
@ -439,8 +442,10 @@ NS_IMETHODIMP nsWebBrowserPersist::SavePrivacyAwareURI(
// SaveURI doesn't like broken uris.
mPersistFlags |= PERSIST_FLAGS_FAIL_ON_BROKEN_LINKS;
rv = SaveURIInternal(aURI, aCacheKey, aReferrer, aReferrerPolicy,
aPostData, aExtraHeaders, fileAsURI, false, aIsPrivate);
rv = SaveURIInternal(aURI, aPrincipal, aCacheKey,
aReferrer, aReferrerPolicy,
aPostData, aExtraHeaders, fileAsURI,
false, aIsPrivate);
return NS_FAILED(rv) ? rv : NS_OK;
}
@ -599,6 +604,13 @@ nsWebBrowserPersist::SerializeNextFile()
}
if (urisToPersist > 0) {
nsCOMPtr<nsIPrincipal> docPrincipal;
//XXXgijs I *think* this is already always true, but let's be sure.
MOZ_ASSERT(mDocList.Length() > 0,
"Should have the document for any walked URIs to persist!");
nsresult rv = mDocList.ElementAt(0)->mDocument->
GetPrincipal(getter_AddRefs(docPrincipal));
NS_ENSURE_SUCCESS_VOID(rv);
// Persist each file in the uri map. The document(s)
// will be saved after the last one of these is saved.
for (auto iter = mURIMap.Iter(); !iter.Done(); iter.Next()) {
@ -608,8 +620,6 @@ nsWebBrowserPersist::SerializeNextFile()
continue;
}
nsresult rv;
// Create a URI from the key.
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), iter.Key(),
@ -627,7 +637,7 @@ nsWebBrowserPersist::SerializeNextFile()
// The Referrer Policy doesn't matter here since the referrer is
// nullptr.
rv = SaveURIInternal(uri, 0, nullptr,
rv = SaveURIInternal(uri, docPrincipal, 0, nullptr,
mozilla::net::RP_Unset, nullptr, nullptr,
fileAsURI, true, mIsPrivate);
// If SaveURIInternal fails, then it will have called EndDownload,
@ -1324,7 +1334,8 @@ nsWebBrowserPersist::AppendPathToURI(nsIURI *aURI, const nsAString & aPath, nsCO
}
nsresult nsWebBrowserPersist::SaveURIInternal(
nsIURI *aURI, uint32_t aCacheKey, nsIURI *aReferrer,
nsIURI *aURI, nsIPrincipal* aTriggeringPrincipal,
uint32_t aCacheKey, nsIURI *aReferrer,
uint32_t aReferrerPolicy, nsIInputStream *aPostData,
const char *aExtraHeaders, nsIURI *aFile,
bool aCalcFileExt, bool aIsPrivate)
@ -1350,7 +1361,7 @@ nsresult nsWebBrowserPersist::SaveURIInternal(
nsCOMPtr<nsIChannel> inputChannel;
rv = NS_NewChannel(getter_AddRefs(inputChannel),
aURI,
nsContentUtils::GetSystemPrincipal(),
aTriggeringPrincipal,
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
nsIContentPolicy::TYPE_OTHER,
nullptr, // aPerformanceStorage
@ -1380,16 +1391,6 @@ nsresult nsWebBrowserPersist::SaveURIInternal(
}
}
if (mPersistFlags & PERSIST_FLAGS_FORCE_ALLOW_COOKIES)
{
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
do_QueryInterface(inputChannel);
if (httpChannelInternal) {
rv = httpChannelInternal->SetThirdPartyFlags(nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
}
// Set the referrer, post data and headers if any
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(inputChannel));
if (httpChannel)

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

@ -57,7 +57,8 @@ public:
private:
virtual ~nsWebBrowserPersist();
nsresult SaveURIInternal(
nsIURI *aURI, uint32_t aCacheKey, nsIURI *aReferrer,
nsIURI *aURI, nsIPrincipal* aTriggeringPrincipal,
uint32_t aCacheKey, nsIURI *aReferrer,
uint32_t aReferrerPolicy, nsIInputStream *aPostData,
const char *aExtraHeaders, nsIURI *aFile,
bool aCalcFileExt, bool aIsPrivate);

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

@ -162,7 +162,7 @@ struct ParamTraits<mozilla::mscom::COMPtrHolder<Interface, _IID>>
const bool sIsStreamPreservationNeeded = false;
#endif // defined(MOZ_CONTENT_SANDBOX)
paramType::EnvType env;
typename paramType::EnvType env;
mozilla::mscom::ProxyStreamFlags flags = sIsStreamPreservationNeeded ?
mozilla::mscom::ProxyStreamFlags::ePreservable :

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

@ -244,7 +244,7 @@ Interceptor::Create(STAUniquePtr<IUnknown> aTarget, IInterceptorSink* aSink,
detail::LiveSetAutoLock lock(GetLiveSet());
RefPtr<IWeakReference> existingWeak(std::move(GetLiveSet().Get(aTarget.get())));
RefPtr<IWeakReference> existingWeak(GetLiveSet().Get(aTarget.get()));
if (existingWeak) {
RefPtr<IWeakReferenceSource> existingStrong;
if (SUCCEEDED(existingWeak->ToStrongRef(getter_AddRefs(existingStrong)))) {
@ -891,7 +891,7 @@ Interceptor::DisconnectRemotesForTarget(IUnknown* aTarget)
// It is not an error if the interceptor doesn't exist, so we return
// S_FALSE instead of an error in that case.
RefPtr<IWeakReference> existingWeak(std::move(GetLiveSet().Get(aTarget)));
RefPtr<IWeakReference> existingWeak(GetLiveSet().Get(aTarget));
if (!existingWeak) {
return S_FALSE;
}

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

@ -2952,6 +2952,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage);
}
bool needsActiveOpacityLayer = false;
// We build an opacity item if it's not going to be drawn by SVG content, or
// SVG effects. SVG effects won't handle the opacity if we want an active
// layer (for async animations), see
@ -2959,7 +2961,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
// nsSVGIntegrationsUtils::PaintFilter.
bool useOpacity = HasVisualOpacity(effectSet) &&
!nsSVGUtils::CanOptimizeOpacity(this) &&
(!usingSVGEffects || nsDisplayOpacity::NeedsActiveLayer(aBuilder, this));
((needsActiveOpacityLayer = nsDisplayOpacity::NeedsActiveLayer(aBuilder, this)) || !usingSVGEffects);
bool useBlendMode = effects->mMixBlendMode != NS_STYLE_BLEND_NORMAL;
bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY &&
IsScrollFrameActive(aBuilder,
@ -3259,9 +3261,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
// all descendant content, but some should not be clipped.
DisplayListClipState::AutoSaveRestore opacityClipState(aBuilder);
resultList.AppendToTop(
MakeDisplayItem<nsDisplayOpacity>(aBuilder, this, &resultList,
MakeDisplayItem<nsDisplayOpacity>(aBuilder, this, &resultList,
containerItemASR,
opacityItemForEventsAndPluginsOnly));
opacityItemForEventsAndPluginsOnly,
needsActiveOpacityLayer));
if (aCreatedContainerItem) {
*aCreatedContainerItem = true;
}

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

@ -297,6 +297,7 @@ public:
aNewItem->GetChildren(),
containerASRForChildren,
aNewItem->GetPerFrameKey())) {
aNewItem->InvalidateCachedChildInfo();
mResultIsModified = true;
}
@ -401,6 +402,7 @@ public:
nsDisplayList empty;
if (mBuilder->MergeDisplayLists(&empty, item->GetChildren(), item->GetChildren(),
containerASRForChildren, item->GetPerFrameKey())) {
item->InvalidateCachedChildInfo();
mResultIsModified = true;
}
UpdateASR(item, containerASRForChildren);

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

@ -6237,11 +6237,13 @@ nsresult nsDisplayWrapper::WrapListsInPlace(nsDisplayListBuilder* aBuilder,
nsDisplayOpacity::nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot,
bool aForEventsAndPluginsOnly)
bool aForEventsAndPluginsOnly,
bool aNeedsActiveLayer)
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true)
, mOpacity(aFrame->StyleEffects()->mOpacity)
, mForEventsAndPluginsOnly(aForEventsAndPluginsOnly)
, mOpacityAppliedToChildren(false)
, mNeedsActiveLayer(aNeedsActiveLayer)
, mChildOpacityState(ChildOpacityState::Unknown)
{
MOZ_COUNT_CTOR(nsDisplayOpacity);
mState.mOpacity = mOpacity;
@ -6378,6 +6380,10 @@ CollectItemsWithOpacity(nsDisplayList* aList,
bool
nsDisplayOpacity::ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder)
{
if (mChildOpacityState == ChildOpacityState::Deferred) {
return false;
}
// Only try folding our opacity down if we have at most kMaxChildCount
// children that don't overlap and can all apply the opacity to themselves.
static const size_t kMaxChildCount = 3;
@ -6386,6 +6392,7 @@ nsDisplayOpacity::ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder)
// child display item pointers to a temporary list.
AutoTArray<nsDisplayItem*, kMaxChildCount> items;
if (!CollectItemsWithOpacity(&mList, items, kMaxChildCount)) {
mChildOpacityState = ChildOpacityState::Deferred;
return false;
}
@ -6405,6 +6412,7 @@ nsDisplayOpacity::ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder)
for (size_t i = 0; i < childCount; i++) {
for (size_t j = i+1; j < childCount; j++) {
if (children[i].bounds.Intersects(children[j].bounds)) {
mChildOpacityState = ChildOpacityState::Deferred;
return false;
}
}
@ -6414,16 +6422,13 @@ nsDisplayOpacity::ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder)
children[i].item->ApplyOpacity(aBuilder, mOpacity, mClipChain);
}
mOpacityAppliedToChildren = true;
mChildOpacityState = ChildOpacityState::Applied;
return true;
}
bool
nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
{
// ShouldFlattenAway() should be called only once during painting.
MOZ_ASSERT(!mOpacityAppliedToChildren);
if (mFrame->GetPrevContinuation() || mFrame->GetNextContinuation() ||
mFrame->HasAnyStateBits(NS_FRAME_PART_OF_IBSPLIT)) {
// If we've been split, then we might need to merge, so
@ -6431,7 +6436,7 @@ nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
return false;
}
if (NeedsActiveLayer(aBuilder, mFrame) || mOpacity == 0.0) {
if (mNeedsActiveLayer || mOpacity == 0.0) {
// If our opacity is zero then we'll discard all descendant display items
// except for layer event regions, so there's no point in doing this
// optimization (and if we do do it, then invalidations of those descendants
@ -6461,7 +6466,7 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
return LAYER_INACTIVE;
}
if (NeedsActiveLayer(aBuilder, mFrame)) {
if (mNeedsActiveLayer) {
// Returns LAYER_ACTIVE_FORCE to avoid flatterning the layer for async
// animations.
return LAYER_ACTIVE_FORCE;
@ -6649,7 +6654,7 @@ nsDisplayBlendMode::CanMerge(const nsDisplayItem* aItem) const
{
// Items for the same content element should be merged into a single
// compositing group.
if (!HasSameTypeAndClip(aItem) || !HasSameContent(aItem)) {
if (!HasDifferentFrame(aItem) || !HasSameTypeAndClip(aItem) || !HasSameContent(aItem)) {
return false;
}
@ -9365,7 +9370,7 @@ nsDisplayMask::CanMerge(const nsDisplayItem* aItem) const
{
// Items for the same content element should be merged into a single
// compositing group.
if (!HasSameTypeAndClip(aItem) || !HasSameContent(aItem)) {
if (!HasDifferentFrame(aItem) || !HasSameTypeAndClip(aItem) || !HasSameContent(aItem)) {
return false;
}

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

@ -2372,6 +2372,12 @@ public:
}
}
/**
* This function is called when an item's list of children has been omdified
* by RetaineDisplayListBuilder.
*/
virtual void InvalidateCachedChildInfo() {}
/**
* @param aSnap set to true if the edges of the rectangles of the opaque
* region would be snapped to device pixels when drawing
@ -2785,6 +2791,11 @@ public:
return mBackfaceHidden;
}
bool HasDifferentFrame(const nsDisplayItem* aOther) const
{
return mFrame != aOther->mFrame;
}
bool HasSameTypeAndClip(const nsDisplayItem* aOther) const
{
return GetPerFrameKey() == aOther->GetPerFrameKey() &&
@ -4967,6 +4978,7 @@ public:
virtual void Merge(const nsDisplayItem* aItem) override
{
MOZ_ASSERT(CanMerge(aItem));
MOZ_ASSERT(Frame() != aItem->Frame());
MergeFromTrackingMergedFrames(static_cast<const nsDisplayWrapList*>(aItem));
}
@ -5115,17 +5127,19 @@ public:
nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot,
bool aForEventsAndPluginsOnly);
bool aForEventsAndPluginsOnly,
bool aNeedsActiveLayer);
nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
const nsDisplayOpacity& aOther)
: nsDisplayWrapList(aBuilder, aOther)
, mOpacity(aOther.mOpacity)
, mForEventsAndPluginsOnly(aOther.mForEventsAndPluginsOnly)
, mOpacityAppliedToChildren(false)
, mNeedsActiveLayer(aOther.mNeedsActiveLayer)
, mChildOpacityState(ChildOpacityState::Unknown)
{
// We should not try to merge flattened opacities.
MOZ_ASSERT(!aOther.mOpacityAppliedToChildren);
MOZ_ASSERT(aOther.mChildOpacityState != ChildOpacityState::Applied);
}
#ifdef NS_BUILD_REFCNT_LOGGING
@ -5136,7 +5150,6 @@ public:
{
nsDisplayItem::RestoreState();
mOpacity = mState.mOpacity;
mOpacityAppliedToChildren = false;
}
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
@ -5145,6 +5158,8 @@ public:
return MakeDisplayItem<nsDisplayOpacity>(aBuilder, *this);
}
virtual void InvalidateCachedChildInfo() override { mChildOpacityState = ChildOpacityState::Unknown; }
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
@ -5161,7 +5176,7 @@ public:
// items for the same content element should be merged into a single
// compositing group
// aItem->GetUnderlyingFrame() returns non-null because it's nsDisplayOpacity
return HasSameTypeAndClip(aItem) && HasSameContent(aItem);
return HasDifferentFrame(aItem) && HasSameTypeAndClip(aItem) && HasSameContent(aItem);
}
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
@ -5189,7 +5204,7 @@ public:
/**
* Returns true if ShouldFlattenAway() applied opacity to children.
*/
bool OpacityAppliedToChildren() const { return mOpacityAppliedToChildren; }
bool OpacityAppliedToChildren() const { return mChildOpacityState == ChildOpacityState::Applied; }
static bool NeedsActiveLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
@ -5209,8 +5224,21 @@ private:
bool ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder);
float mOpacity;
bool mForEventsAndPluginsOnly;
bool mOpacityAppliedToChildren;
bool mForEventsAndPluginsOnly : 1;
enum class ChildOpacityState : uint8_t {
// Our child list has changed since the last time ApplyOpacityToChildren was called.
Unknown,
// Our children defer opacity handling to us.
Deferred,
// Opacity is applied to our children.
Applied
};
bool mNeedsActiveLayer : 1;
#ifndef __GNUC__
ChildOpacityState mChildOpacityState : 2;
#else
ChildOpacityState mChildOpacityState;
#endif
struct {
float mOpacity;
@ -5381,7 +5409,7 @@ public:
{
// Items for the same content element should be merged into a single
// compositing group.
return HasSameTypeAndClip(aItem) && HasSameContent(aItem)
return HasDifferentFrame(aItem) && HasSameTypeAndClip(aItem) && HasSameContent(aItem)
&& mIsForBackground == static_cast<const nsDisplayBlendContainer*>(aItem)->mIsForBackground;
}
@ -6136,7 +6164,7 @@ public:
{
// Items for the same content element should be merged into a single
// compositing group.
return HasSameTypeAndClip(aItem) && HasSameContent(aItem);
return HasDifferentFrame(aItem) && HasSameTypeAndClip(aItem) && HasSameContent(aItem);
}
virtual void Merge(const nsDisplayItem* aItem) override

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

@ -90,14 +90,14 @@ printf_stderr(const char *fmt, ...)
typedef MOZ_NORETURN_PTR void (__fastcall* BaseThreadInitThunk_func)(BOOL aIsInitialThread, void* aStartAddress, void* aThreadParam);
static BaseThreadInitThunk_func stub_BaseThreadInitThunk = nullptr;
static WindowsDllInterceptor::FuncHookType<BaseThreadInitThunk_func> stub_BaseThreadInitThunk;
typedef NTSTATUS (NTAPI *LdrLoadDll_func) (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileName, PHANDLE handle);
static LdrLoadDll_func stub_LdrLoadDll;
static WindowsDllInterceptor::FuncHookType<LdrLoadDll_func> stub_LdrLoadDll;
#ifdef _M_AMD64
typedef decltype(RtlInstallFunctionTableCallback)* RtlInstallFunctionTableCallback_func;
static RtlInstallFunctionTableCallback_func stub_RtlInstallFunctionTableCallback;
static WindowsDllInterceptor::FuncHookType<RtlInstallFunctionTableCallback_func> stub_RtlInstallFunctionTableCallback;
extern uint8_t* sMsMpegJitCodeRegionStart;
extern size_t sMsMpegJitCodeRegionSize;
@ -662,7 +662,8 @@ DllBlocklist_Initialize(uint32_t aInitFlags)
// We specifically use a detour, because there are cases where external
// code also tries to hook LdrLoadDll, and doesn't know how to relocate our
// nop space patches. (Bug 951827)
bool ok = NtDllIntercept.AddDetour("LdrLoadDll", reinterpret_cast<intptr_t>(patched_LdrLoadDll), (void**) &stub_LdrLoadDll);
bool ok = stub_LdrLoadDll.SetDetour(NtDllIntercept, "LdrLoadDll",
&patched_LdrLoadDll);
if (!ok) {
sBlocklistInitFailed = true;
@ -683,18 +684,18 @@ DllBlocklist_Initialize(uint32_t aInitFlags)
#ifdef _M_AMD64
if (!IsWin8OrLater()) {
// The crash that this hook works around is only seen on Win7.
Kernel32Intercept.AddHook("RtlInstallFunctionTableCallback",
reinterpret_cast<intptr_t>(patched_RtlInstallFunctionTableCallback),
(void**)&stub_RtlInstallFunctionTableCallback);
stub_RtlInstallFunctionTableCallback.Set(Kernel32Intercept,
"RtlInstallFunctionTableCallback",
&patched_RtlInstallFunctionTableCallback);
}
#endif
// Bug 1361410: WRusr.dll will overwrite our hook and cause a crash.
// Workaround: If we detect WRusr.dll, don't hook.
if (!GetModuleHandleW(L"WRusr.dll")) {
if(!Kernel32Intercept.AddDetour("BaseThreadInitThunk",
reinterpret_cast<intptr_t>(patched_BaseThreadInitThunk),
(void**) &stub_BaseThreadInitThunk)) {
if (!stub_BaseThreadInitThunk.SetDetour(Kernel32Intercept,
"BaseThreadInitThunk",
&patched_BaseThreadInitThunk)) {
#ifdef DEBUG
printf_stderr("BaseThreadInitThunk hook failed\n");
#endif

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

@ -42,7 +42,7 @@ public:
void Clear()
{
if (!mVMPolicy.ShouldUnhookUponDestruction()) {
if (!this->mVMPolicy.ShouldUnhookUponDestruction()) {
return;
}
@ -54,7 +54,7 @@ public:
#error "Unknown processor type"
#endif
const auto& tramps = mVMPolicy.Items();
const auto& tramps = this->mVMPolicy.Items();
for (auto&& tramp : tramps) {
// First we read the pointer to the interceptor instance.
Maybe<uintptr_t> instance = tramp.ReadEncodedPointer();
@ -80,7 +80,7 @@ public:
continue;
}
WritableTargetFunction<MMPolicyT> origBytes(mVMPolicy,
WritableTargetFunction<MMPolicyT> origBytes(this->mVMPolicy,
interceptedFn.value(), nBytes);
if (!origBytes) {
continue;
@ -135,7 +135,7 @@ public:
origBytes.Commit();
}
mVMPolicy.Clear();
this->mVMPolicy.Clear();
}
void Init(int aNumHooks = 0)
@ -148,20 +148,20 @@ public:
// Win32 allocates VM addresses at a 64KiB granularity, so by default we
// might as well utilize that entire 64KiB reservation instead of
// artifically constraining ourselves to the page size.
aNumHooks = mVMPolicy.GetAllocGranularity() / kHookSize;
aNumHooks = this->mVMPolicy.GetAllocGranularity() / kHookSize;
}
mVMPolicy.Reserve(aNumHooks);
this->mVMPolicy.Reserve(aNumHooks);
}
bool Initialized() const
{
return !!mVMPolicy;
return !!this->mVMPolicy;
}
bool AddHook(FARPROC aTargetFn, intptr_t aHookDest, void** aOrigFunc)
{
ReadOnlyTargetFunction<MMPolicyT> target(ResolveRedirectedAddress(aTargetFn));
ReadOnlyTargetFunction<MMPolicyT> target(this->ResolveRedirectedAddress(aTargetFn));
CreateTrampoline(target, aHookDest, aOrigFunc);
if (!*aOrigFunc) {

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

@ -34,13 +34,13 @@ public:
Trampoline<MMPolicy> GetNextTrampoline()
{
uint32_t offset = mNextChunkIndex * kChunkSize;
if (!MaybeCommitNextPage(offset, kChunkSize)) {
if (!this->MaybeCommitNextPage(offset, kChunkSize)) {
return nullptr;
}
Trampoline<MMPolicy> result(this, GetLocalView() + offset,
GetRemoteView() + offset, kChunkSize);
Trampoline<MMPolicy> result(this, this->GetLocalView() + offset,
this->GetRemoteView() + offset, kChunkSize);
if (!!result) {
++mNextChunkIndex;
}
@ -50,7 +50,8 @@ public:
TrampolineCollection<MMPolicy> Items() const
{
return TrampolineCollection<MMPolicy>(*this, GetLocalView(), GetRemoteView(),
return TrampolineCollection<MMPolicy>(*this, this->GetLocalView(),
this->GetRemoteView(),
kChunkSize, mNextChunkIndex);
}

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

@ -8,10 +8,12 @@
#define NS_WINDOWS_DLL_INTERCEPTOR_H_
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/NotNull.h"
#include "mozilla/Move.h"
#include "mozilla/Tuple.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/Types.h"
#include "mozilla/UniquePtr.h"
@ -82,6 +84,143 @@
namespace mozilla {
namespace interceptor {
template <typename InterceptorT, typename FuncPtrT>
class FuncHook final
{
template <typename T>
struct OriginalFunctionPtrTraits;
template <typename R, typename... Args>
struct OriginalFunctionPtrTraits<R (*)(Args...)>
{
using ReturnType = R;
};
#if defined(_M_IX86)
template <typename R, typename... Args>
struct OriginalFunctionPtrTraits<R (__stdcall*)(Args...)>
{
using ReturnType = R;
};
template <typename R, typename... Args>
struct OriginalFunctionPtrTraits<R (__fastcall*)(Args...)>
{
using ReturnType = R;
};
#endif // defined(_M_IX86)
public:
using ThisType = FuncHook<InterceptorT, FuncPtrT>;
using ReturnType = typename OriginalFunctionPtrTraits<FuncPtrT>::ReturnType;
constexpr FuncHook()
: mOrigFunc(nullptr)
, mInitOnce(INIT_ONCE_STATIC_INIT)
{
}
~FuncHook() = default;
bool Set(InterceptorT& aInterceptor, const char* aName,
FuncPtrT aHookDest)
{
LPVOID addHookOk;
InitOnceContext ctx(this, &aInterceptor, aName, aHookDest, false);
return ::InitOnceExecuteOnce(&mInitOnce, &InitOnceCallback, &ctx,
&addHookOk) && addHookOk;
}
bool SetDetour(InterceptorT& aInterceptor, const char* aName,
FuncPtrT aHookDest)
{
LPVOID addHookOk;
InitOnceContext ctx(this, &aInterceptor, aName, aHookDest, true);
return ::InitOnceExecuteOnce(&mInitOnce, &InitOnceCallback, &ctx,
&addHookOk) && addHookOk;
}
explicit operator bool() const
{
return !!mOrigFunc;
}
template <typename... ArgsType>
ReturnType operator()(ArgsType... aArgs) const
{
return mOrigFunc(std::forward<ArgsType>(aArgs)...);
}
FuncPtrT GetStub() const
{
return mOrigFunc;
}
// One-time init stuff cannot be moved or copied
FuncHook(const FuncHook&) = delete;
FuncHook(FuncHook&&) = delete;
FuncHook& operator=(const FuncHook&) = delete;
FuncHook& operator=(FuncHook&& aOther) = delete;
private:
struct MOZ_RAII InitOnceContext final
{
InitOnceContext(ThisType* aHook, InterceptorT* aInterceptor,
const char* aName, void* aHookDest, bool aForceDetour)
: mHook(aHook)
, mInterceptor(aInterceptor)
, mName(aName)
, mHookDest(aHookDest)
, mForceDetour(aForceDetour)
{
}
ThisType* mHook;
InterceptorT* mInterceptor;
const char* mName;
void* mHookDest;
bool mForceDetour;
};
private:
bool Apply(InterceptorT* aInterceptor, const char* aName, void* aHookDest)
{
return aInterceptor->AddHook(aName, reinterpret_cast<intptr_t>(aHookDest),
reinterpret_cast<void**>(&mOrigFunc));
}
bool ApplyDetour(InterceptorT* aInterceptor, const char* aName,
void* aHookDest)
{
return aInterceptor->AddDetour(aName, reinterpret_cast<intptr_t>(aHookDest),
reinterpret_cast<void**>(&mOrigFunc));
}
static BOOL CALLBACK
InitOnceCallback(PINIT_ONCE aInitOnce, PVOID aParam, PVOID* aOutContext)
{
MOZ_ASSERT(aOutContext);
bool result;
auto ctx = reinterpret_cast<InitOnceContext*>(aParam);
if (ctx->mForceDetour) {
result = ctx->mHook->ApplyDetour(ctx->mInterceptor, ctx->mName,
ctx->mHookDest);
} else {
result = ctx->mHook->Apply(ctx->mInterceptor, ctx->mName, ctx->mHookDest);
}
*aOutContext = result ? reinterpret_cast<PVOID>(1U << INIT_ONCE_CTX_RESERVED_BITS) : nullptr;
return TRUE;
}
private:
FuncPtrT mOrigFunc;
INIT_ONCE mInitOnce;
};
enum
{
kDefaultTrampolineSize = 128
@ -92,6 +231,8 @@ template <typename VMPolicy =
mozilla::interceptor::MMPolicyInProcess, kDefaultTrampolineSize>>
class WindowsDllInterceptor final
{
typedef WindowsDllInterceptor<VMPolicy> ThisType;
interceptor::WindowsDllDetourPatcher<VMPolicy> mDetourPatcher;
#if defined(_M_IX86)
interceptor::WindowsDllNopSpacePatcher<typename VMPolicy::MMPolicyT> mNopSpacePatcher;
@ -160,6 +301,7 @@ public:
// NB: We intentionally leak mModule
}
private:
/**
* Hook/detour the method aName from the DLL we set in Init so that it calls
* aHookDest instead. Returns the original method pointer in aOrigFunc
@ -219,7 +361,6 @@ public:
return AddDetour(proc, aHookDest, aOrigFunc);
}
private:
bool AddDetour(FARPROC aProc, intptr_t aHookDest, void** aOrigFunc)
{
MOZ_ASSERT(mModule && aProc);
@ -230,6 +371,14 @@ private:
return mDetourPatcher.AddHook(aProc, aHookDest, aOrigFunc);
}
public:
template <typename FuncPtrT>
using FuncHookType = FuncHook<ThisType, FuncPtrT>;
private:
template <typename InterceptorT, typename FuncPtrT>
friend class FuncHook;
};
} // namespace interceptor

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

@ -10,10 +10,33 @@
#include <wininet.h>
#include <schnlsp.h>
#include "mozilla/TypeTraits.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/WindowsVersion.h"
#include "nsWindowsDllInterceptor.h"
#include "nsWindowsHelpers.h"
NTSTATUS NTAPI NtFlushBuffersFile(HANDLE, PIO_STATUS_BLOCK);
NTSTATUS NTAPI NtReadFile(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
PIO_STATUS_BLOCK, PVOID, ULONG,
PLARGE_INTEGER, PULONG);
NTSTATUS NTAPI NtReadFileScatter(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
PIO_STATUS_BLOCK, PFILE_SEGMENT_ELEMENT, ULONG,
PLARGE_INTEGER, PULONG);
NTSTATUS NTAPI NtWriteFile(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
PIO_STATUS_BLOCK, PVOID, ULONG,
PLARGE_INTEGER, PULONG);
NTSTATUS NTAPI NtWriteFileGather(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
PIO_STATUS_BLOCK, PFILE_SEGMENT_ELEMENT, ULONG,
PLARGE_INTEGER, PULONG);
NTSTATUS NTAPI NtQueryFullAttributesFile(POBJECT_ATTRIBUTES, PVOID);
NTSTATUS NTAPI LdrLoadDll(PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileName, PHANDLE handle);
NTSTATUS NTAPI LdrUnloadDll(HMODULE);
// These pointers are disguised as PVOID to avoid pulling in obscure headers
PVOID NTAPI LdrResolveDelayLoadedAPI(PVOID, PVOID, PVOID, PVOID, PVOID, ULONG);
void CALLBACK ProcessCaretEvents(HWINEVENTHOOK, DWORD, HWND, LONG, LONG, DWORD, DWORD);
void __fastcall BaseThreadInitThunk(BOOL aIsInitialThread, void* aStartAddress, void* aThreadParam);
using namespace mozilla;
struct payload {
@ -38,7 +61,8 @@ extern "C" __declspec(dllexport) __declspec(noinline) payload rotatePayload(payl
static bool patched_func_called = false;
static payload (*orig_rotatePayload)(payload);
static WindowsDllInterceptor::FuncHookType<decltype(&rotatePayload)>
orig_rotatePayload;
static payload
patched_rotatePayload(payload p)
@ -47,11 +71,61 @@ patched_rotatePayload(payload p)
return orig_rotatePayload(p);
}
typedef bool(*HookTestFunc)(void*);
bool CheckHook(HookTestFunc aHookTestFunc, void* aOrigFunc,
const char* aDllName, const char* aFuncName)
// Invoke aFunc by taking aArg's contents and using them as aFunc's arguments
template <typename CallableT, typename... Args, typename ArgTuple = Tuple<Args...>, size_t... Indices>
decltype(auto) Apply(CallableT&& aFunc, ArgTuple&& aArgs, std::index_sequence<Indices...>)
{
if (aHookTestFunc(aOrigFunc)) {
return std::forward<CallableT>(aFunc)(Get<Indices>(std::forward<ArgTuple>(aArgs))...);
}
template <typename CallableT>
bool TestFunction(CallableT aFunc);
#define DEFINE_TEST_FUNCTION(calling_convention) \
template <typename R, typename... Args, typename... TestArgs> \
bool TestFunction(WindowsDllInterceptor::FuncHookType<R (calling_convention *)(Args...)>&& aFunc, \
bool (* aPred)(R), TestArgs... aArgs) \
{ \
using FuncHookType = WindowsDllInterceptor::FuncHookType<R (calling_convention *)(Args...)>; \
using ArgTuple = Tuple<Args...>; \
using Indices = std::index_sequence_for<Args...>; \
ArgTuple fakeArgs{ std::forward<TestArgs>(aArgs)... }; \
return aPred(Apply(std::forward<FuncHookType>(aFunc), std::forward<ArgTuple>(fakeArgs), Indices())); \
} \
\
/* Specialization for functions returning void */ \
template <typename... Args, typename PredicateT, typename... TestArgs> \
bool TestFunction(WindowsDllInterceptor::FuncHookType<void (calling_convention *)(Args...)>&& aFunc, \
PredicateT&& aPred, TestArgs... aArgs) \
{ \
using FuncHookType = WindowsDllInterceptor::FuncHookType<void (calling_convention *)(Args...)>; \
using ArgTuple = Tuple<Args...>; \
using Indices = std::index_sequence_for<Args...>; \
ArgTuple fakeArgs{ std::forward<TestArgs>(aArgs)... }; \
Apply(std::forward<FuncHookType>(aFunc), std::forward<ArgTuple>(fakeArgs), Indices()); \
return true; \
}
// C++11 allows empty arguments to macros. clang works just fine. MSVC does the
// right thing, but it also throws up warning C4003.
#if defined(_MSC_VER) && !defined(__clang__)
DEFINE_TEST_FUNCTION(__cdecl)
#else
DEFINE_TEST_FUNCTION()
#endif
#ifdef _M_IX86
DEFINE_TEST_FUNCTION(__stdcall)
DEFINE_TEST_FUNCTION(__fastcall)
#endif // _M_IX86
// Test the hooked function against the supplied predicate
template <typename OrigFuncT, typename PredicateT, typename... Args>
bool CheckHook(WindowsDllInterceptor::FuncHookType<OrigFuncT> &aOrigFunc,
const char* aDllName, const char* aFuncName, PredicateT&& aPred,
Args... aArgs)
{
if (TestFunction(std::forward<WindowsDllInterceptor::FuncHookType<OrigFuncT>>(aOrigFunc), std::forward<PredicateT>(aPred), std::forward<Args>(aArgs)...)) {
printf("TEST-PASS | WindowsDllInterceptor | "
"Executed hooked function %s from %s\n", aFuncName, aDllName);
return true;
@ -61,57 +135,235 @@ bool CheckHook(HookTestFunc aHookTestFunc, void* aOrigFunc,
return false;
}
template <size_t N>
bool TestHook(HookTestFunc funcTester, const char (&dll)[N], const char *func)
// Hook the function and optionally attempt calling it
template <typename OrigFuncT, size_t N, typename PredicateT, typename... Args>
bool TestHook(const char (&dll)[N], const char *func, PredicateT&& aPred, Args... aArgs)
{
void *orig_func;
auto orig_func(mozilla::MakeUnique<WindowsDllInterceptor::FuncHookType<OrigFuncT>>());
bool successful = false;
{
WindowsDllInterceptor TestIntercept;
TestIntercept.Init(dll);
successful = TestIntercept.AddHook(func, 0, &orig_func);
successful = orig_func->Set(TestIntercept, func, nullptr);
}
if (successful) {
printf("TEST-PASS | WindowsDllInterceptor | Could hook %s from %s\n", func, dll);
return CheckHook(funcTester, orig_func, dll, func);
if (!aPred) {
printf("TEST-SKIPPED | WindowsDllInterceptor | "
"Will not attempt to execute patched %s.\n", func);
return true;
}
return CheckHook(*orig_func, dll, func, std::forward<PredicateT>(aPred), std::forward<Args>(aArgs)...);
} else {
printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to hook %s from %s\n", func, dll);
return false;
}
}
template <size_t N>
bool TestDetour(const char (&dll)[N], const char *func)
// Detour the function and optionally attempt calling it
template <typename OrigFuncT, size_t N, typename PredicateT>
bool TestDetour(const char (&dll)[N], const char *func, PredicateT&& aPred)
{
void *orig_func;
auto orig_func(mozilla::MakeUnique<WindowsDllInterceptor::FuncHookType<OrigFuncT>>());
bool successful = false;
{
WindowsDllInterceptor TestIntercept;
TestIntercept.Init(dll);
successful = TestIntercept.AddDetour(func, 0, &orig_func);
successful = orig_func->SetDetour(TestIntercept, func, nullptr);
}
if (successful) {
printf("TEST-PASS | WindowsDllInterceptor | Could detour %s from %s\n", func, dll);
return true;
if (!aPred) {
printf("TEST-SKIPPED | WindowsDllInterceptor | "
"Will not attempt to execute patched %s.\n", func);
return true;
}
return CheckHook(*orig_func, dll, func, std::forward<PredicateT>(aPred));
} else {
printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to detour %s from %s\n", func, dll);
return false;
}
}
template <size_t N>
bool MaybeTestHook(const bool cond, HookTestFunc funcTester, const char (&dll)[N], const char* func)
// If a function pointer's type returns void*, this template converts that type
// to return uintptr_t instead, for the purposes of predicates.
template <typename FuncT>
struct SubstituteForVoidPtr
{
using Type = FuncT;
};
template <typename... Args>
struct SubstituteForVoidPtr<void* (*)(Args...)>
{
using Type = uintptr_t (*)(Args...);
};
#ifdef _M_IX86
template <typename... Args>
struct SubstituteForVoidPtr<void* (__stdcall*)(Args...)>
{
using Type = uintptr_t (__stdcall*)(Args...);
};
template <typename... Args>
struct SubstituteForVoidPtr<void* (__fastcall*)(Args...)>
{
using Type = uintptr_t (__fastcall*)(Args...);
};
#endif // _M_IX86
// Determines the function's return type
template <typename FuncT>
struct ReturnType;
template <typename R, typename... Args>
struct ReturnType<R (*)(Args...)>
{
using Type = R;
};
#ifdef _M_IX86
template <typename R, typename... Args>
struct ReturnType<R (__stdcall*)(Args...)>
{
using Type = R;
};
template <typename R, typename... Args>
struct ReturnType<R (__fastcall*)(Args...)>
{
using Type = R;
};
#endif // _M_IX86
// Predicates that may be supplied during tests
template <typename FuncT>
struct Predicates
{
using ArgType = typename ReturnType<FuncT>::Type;
template <ArgType CompVal>
static bool Equals(ArgType aValue)
{
return CompVal == aValue;
}
template <ArgType CompVal>
static bool NotEquals(ArgType aValue)
{
return CompVal != aValue;
}
template <ArgType CompVal>
static bool Ignore(ArgType aValue)
{
return true;
}
};
// Functions that return void should be ignored, so we specialize the
// Ignore predicate for that case. Use nullptr as the value to compare against.
template <typename... Args>
struct Predicates<void (*)(Args...)>
{
template <nullptr_t DummyVal>
static bool Ignore()
{
return true;
}
};
#ifdef _M_IX86
template <typename... Args>
struct Predicates<void (__stdcall*)(Args...)>
{
template <nullptr_t DummyVal>
static bool Ignore()
{
return true;
}
};
template <typename... Args>
struct Predicates<void (__fastcall*)(Args...)>
{
template <nullptr_t DummyVal>
static bool Ignore()
{
return true;
}
};
#endif // _M_IX86
// The standard test. Hook |func|, and then try executing it with all zero
// arguments, using |pred| and |comp| to determine whether the call successfully
// executed. In general, you want set pred and comp such that they return true
// when the function is returning whatever value is expected with all-zero
// arguments.
//
// Note: When |func| returns void, you must supply |Ignore| and |nullptr| as the
// |pred| and |comp| arguments, respectively.
#define TEST_HOOK(dll, func, pred, comp) \
TestHook<decltype(&func)>(#dll, #func, &Predicates<decltype(&func)>::pred<comp>)
// We need to special-case functions that return INVALID_HANDLE_VALUE
// (ie, CreateFile). Our template machinery for comparing values doesn't work
// with integer constants passed as pointers (well, it works on MSVC, but not
// clang, because that is not standard-compliant).
#define TEST_HOOK_FOR_INVALID_HANDLE_VALUE(dll, func) \
TestHook<SubstituteForVoidPtr<decltype(&func)>::Type>(#dll, #func, &Predicates<SubstituteForVoidPtr<decltype(&func)>::Type>::Equals<uintptr_t(-1)>)
// This variant allows you to explicitly supply arguments to the hooked function
// during testing. You want to provide arguments that produce the conditions that
// induce the function to return a value that is accepted by your predicate.
#define TEST_HOOK_PARAMS(dll, func, pred, comp, ...) \
TestHook<decltype(&func)>(#dll, #func, &Predicates<decltype(&func)>::pred<comp>, __VA_ARGS__)
// This is for cases when we want to hook |func|, but it is unsafe to attempt
// to execute the function in the context of a test.
#define TEST_HOOK_SKIP_EXEC(dll, func) \
TestHook<decltype(&func)>(#dll, #func, reinterpret_cast<bool (*)(typename ReturnType<decltype(&func)>::Type)>(NULL))
// The following three variants are identical to the previous macros,
// however the forcibly use a Detour on 32-bit Windows. On 64-bit Windows,
// these macros are identical to their TEST_HOOK variants.
#define TEST_DETOUR(dll, func, pred, comp) \
TestDetour<decltype(&func)>(#dll, #func, &Predicates<decltype(&func)>::pred<comp>)
#define TEST_DETOUR_PARAMS(dll, func, pred, comp, ...) \
TestDetour<decltype(&func)>(#dll, #func, &Predicates<decltype(&func)>::pred<comp>, __VA_ARGS__)
#define TEST_DETOUR_SKIP_EXEC(dll, func) \
TestDetour<decltype(&func)>(#dll, #func, reinterpret_cast<bool (*)(typename ReturnType<decltype(&func)>::Type)>(NULL))
template <typename OrigFuncT, size_t N, typename PredicateT, typename... Args>
bool MaybeTestHook(const bool cond, const char (&dll)[N], const char *func, PredicateT&& aPred, Args... aArgs)
{
if (!cond) {
printf("TEST-SKIPPED | WindowsDllInterceptor | Skipped hook test for %s from %s\n", func, dll);
return true;
}
return TestHook(funcTester, dll, func);
return TestHook<OrigFuncT>(dll, func, std::forward<PredicateT>(aPred), std::forward<Args>(aArgs)...);
}
// Like TEST_HOOK, but the test is only executed when cond is true.
#define MAYBE_TEST_HOOK(cond, dll, func, pred, comp) \
MaybeTestHook<decltype(&func)>(cond, #dll, #func, &Predicates<decltype(&func)>::pred<comp>)
#define MAYBE_TEST_HOOK_PARAMS(cond, dll, func, pred, comp, ...) \
MaybeTestHook<decltype(&func)>(cond, #dll, #func, &Predicates<decltype(&func)>::pred<comp>, __VA_ARGS__)
#define MAYBE_TEST_HOOK_SKIP_EXEC(cond, dll, func) \
MaybeTestHook<decltype(&func)>(cond, #dll, #func, reinterpret_cast<bool (*)(typename ReturnType<decltype(&func)>::Type)>(NULL))
bool ShouldTestTipTsf()
{
if (!IsWin8OrLater()) {
@ -147,455 +399,6 @@ bool ShouldTestTipTsf()
return true;
}
// These test the patched function returned by the DLL
// interceptor. They check that the patched assembler preamble does
// something sane. The parameter is a pointer to the patched function.
bool TestGetWindowInfo(void* aFunc)
{
auto patchedGetWindowInfo =
reinterpret_cast<decltype(&GetWindowInfo)>(aFunc);
return patchedGetWindowInfo(0, 0) == FALSE;
}
bool TestSetWindowLongPtr(void* aFunc)
{
auto patchedSetWindowLongPtr =
reinterpret_cast<decltype(&SetWindowLongPtr)>(aFunc);
return patchedSetWindowLongPtr(0, 0, 0) == 0;
}
bool TestSetWindowLong(void* aFunc)
{
auto patchedSetWindowLong =
reinterpret_cast<decltype(&SetWindowLong)>(aFunc);
return patchedSetWindowLong(0, 0, 0) == 0;
}
bool TestTrackPopupMenu(void* aFunc)
{
auto patchedTrackPopupMenu =
reinterpret_cast<decltype(&TrackPopupMenu)>(aFunc);
return patchedTrackPopupMenu(0, 0, 0, 0, 0, 0, 0) == 0;
}
bool TestNtFlushBuffersFile(void* aFunc)
{
typedef NTSTATUS(WINAPI *NtFlushBuffersFileType)(HANDLE, PIO_STATUS_BLOCK);
auto patchedNtFlushBuffersFile =
reinterpret_cast<NtFlushBuffersFileType>(aFunc);
patchedNtFlushBuffersFile(0, 0);
return true;
}
bool TestNtCreateFile(void* aFunc)
{
auto patchedNtCreateFile =
reinterpret_cast<decltype(&NtCreateFile)>(aFunc);
return patchedNtCreateFile(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0;
}
bool TestNtReadFile(void* aFunc)
{
typedef NTSTATUS(WINAPI *NtReadFileType)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
PIO_STATUS_BLOCK, PVOID, ULONG,
PLARGE_INTEGER, PULONG);
auto patchedNtReadFile =
reinterpret_cast<NtReadFileType>(aFunc);
return patchedNtReadFile(0, 0, 0, 0, 0, 0, 0, 0, 0) != 0;
}
bool TestNtReadFileScatter(void* aFunc)
{
typedef NTSTATUS(WINAPI *NtReadFileScatterType)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
PIO_STATUS_BLOCK, PFILE_SEGMENT_ELEMENT, ULONG,
PLARGE_INTEGER, PULONG);
auto patchedNtReadFileScatter =
reinterpret_cast<NtReadFileScatterType>(aFunc);
return patchedNtReadFileScatter(0, 0, 0, 0, 0, 0, 0, 0, 0) != 0;
}
bool TestNtWriteFile(void* aFunc)
{
typedef NTSTATUS(WINAPI *NtWriteFileType)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
PIO_STATUS_BLOCK, PVOID, ULONG,
PLARGE_INTEGER, PULONG);
auto patchedNtWriteFile =
reinterpret_cast<NtWriteFileType>(aFunc);
return patchedNtWriteFile(0, 0, 0, 0, 0, 0, 0, 0, 0) != 0;
}
bool TestNtWriteFileGather(void* aFunc)
{
typedef NTSTATUS(WINAPI *NtWriteFileGatherType)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
PIO_STATUS_BLOCK, PFILE_SEGMENT_ELEMENT, ULONG,
PLARGE_INTEGER, PULONG);
auto patchedNtWriteFileGather =
reinterpret_cast<NtWriteFileGatherType>(aFunc);
return patchedNtWriteFileGather(0, 0, 0, 0, 0, 0, 0, 0, 0) != 0;
}
bool TestNtQueryFullAttributesFile(void* aFunc)
{
typedef NTSTATUS(WINAPI *NtQueryFullAttributesFileType)(POBJECT_ATTRIBUTES,
PVOID);
auto patchedNtQueryFullAttributesFile =
reinterpret_cast<NtQueryFullAttributesFileType>(aFunc);
return patchedNtQueryFullAttributesFile(0, 0) != 0;
}
bool TestLdrUnloadDll(void* aFunc)
{
typedef NTSTATUS (NTAPI *LdrUnloadDllType)(HMODULE);
auto patchedLdrUnloadDll = reinterpret_cast<LdrUnloadDllType>(aFunc);
return patchedLdrUnloadDll(0) != 0;
}
bool TestLdrResolveDelayLoadedAPI(void* aFunc)
{
// These pointers are disguised as PVOID to avoid pulling in obscure headers
typedef PVOID (WINAPI *LdrResolveDelayLoadedAPIType)(PVOID, PVOID, PVOID,
PVOID, PVOID, ULONG);
auto patchedLdrResolveDelayLoadedAPI =
reinterpret_cast<LdrResolveDelayLoadedAPIType>(aFunc);
// No idea how to call this API. Flags==99 is just an arbitrary number that
// doesn't crash when the other params are null.
return patchedLdrResolveDelayLoadedAPI(0, 0, 0, 0, 0, 99) == 0;
}
#ifdef _M_AMD64
bool TestRtlInstallFunctionTableCallback(void* aFunc)
{
auto patchedRtlInstallFunctionTableCallback =
reinterpret_cast<decltype(RtlInstallFunctionTableCallback)*>(aFunc);
return patchedRtlInstallFunctionTableCallback(0, 0, 0, 0, 0, 0) == FALSE;
}
#endif
bool TestSetUnhandledExceptionFilter(void* aFunc)
{
auto patchedSetUnhandledExceptionFilter =
reinterpret_cast<decltype(&SetUnhandledExceptionFilter)>(aFunc);
// Retrieve the current filter as we set the new filter to null, then restore the current filter.
LPTOP_LEVEL_EXCEPTION_FILTER current = patchedSetUnhandledExceptionFilter(0);
patchedSetUnhandledExceptionFilter(current);
return true;
}
bool TestVirtualAlloc(void* aFunc)
{
auto patchedVirtualAlloc =
reinterpret_cast<decltype(&VirtualAlloc)>(aFunc);
return patchedVirtualAlloc(0, 0, 0, 0) == 0;
}
bool TestMapViewOfFile(void* aFunc)
{
auto patchedMapViewOfFile =
reinterpret_cast<decltype(&MapViewOfFile)>(aFunc);
return patchedMapViewOfFile(0, 0, 0, 0, 0) == 0;
}
bool TestCreateDIBSection(void* aFunc)
{
auto patchedCreateDIBSection =
reinterpret_cast<decltype(&CreateDIBSection)>(aFunc);
// MSDN is wrong here. This does not return ERROR_INVALID_PARAMETER. It
// sets the value of GetLastError to ERROR_INVALID_PARAMETER.
// CreateDIBSection returns 0 on error.
return patchedCreateDIBSection(0, 0, 0, 0, 0, 0) == 0;
}
bool TestCreateFileW(void* aFunc)
{
auto patchedCreateFileW =
reinterpret_cast<decltype(&CreateFileW)>(aFunc);
return patchedCreateFileW(0, 0, 0, 0, 0, 0, 0) == INVALID_HANDLE_VALUE;
}
bool TestCreateFileA(void* aFunc)
{
auto patchedCreateFileA =
reinterpret_cast<decltype(&CreateFileA)>(aFunc);
// return patchedCreateFileA(0, 0, 0, 0, 0, 0, 0) == INVALID_HANDLE_VALUE;
printf("TEST-SKIPPED | WindowsDllInterceptor | "
"Will not attempt to execute patched CreateFileA -- patched method is known to fail.\n");
return true;
}
bool TestQueryDosDeviceW(void* aFunc)
{
auto patchedQueryDosDeviceW =
reinterpret_cast<decltype(&QueryDosDeviceW)>(aFunc);
return patchedQueryDosDeviceW(nullptr, nullptr, 0) == 0;
}
bool TestInSendMessageEx(void* aFunc)
{
auto patchedInSendMessageEx =
reinterpret_cast<decltype(&InSendMessageEx)>(aFunc);
patchedInSendMessageEx(0);
return true;
}
bool TestImmGetContext(void* aFunc)
{
auto patchedImmGetContext =
reinterpret_cast<decltype(&ImmGetContext)>(aFunc);
patchedImmGetContext(0);
return true;
}
bool TestImmGetCompositionStringW(void* aFunc)
{
auto patchedImmGetCompositionStringW =
reinterpret_cast<decltype(&ImmGetCompositionStringW)>(aFunc);
patchedImmGetCompositionStringW(0, 0, 0, 0);
return true;
}
bool TestImmSetCandidateWindow(void* aFunc)
{
auto patchedImmSetCandidateWindow =
reinterpret_cast<decltype(&ImmSetCandidateWindow)>(aFunc);
// return patchedImmSetCandidateWindow(0, 0) == 0;
// ImmSetCandidateWindow crashes if given bad parameters.
printf("TEST-SKIPPED | WindowsDllInterceptor | "
"Will not attempt to execute patched ImmSetCandidateWindow.\n");
return true;
}
bool TestImmNotifyIME(void* aFunc)
{
auto patchedImmNotifyIME =
reinterpret_cast<decltype(&ImmNotifyIME)>(aFunc);
return patchedImmNotifyIME(0, 0, 0, 0) == 0;
}
bool TestGetSaveFileNameW(void* aFunc)
{
auto patchedGetSaveFileNameWType =
reinterpret_cast<decltype(&GetSaveFileNameW)>(aFunc);
patchedGetSaveFileNameWType(0);
return true;
}
bool TestGetOpenFileNameW(void* aFunc)
{
auto patchedGetOpenFileNameWType =
reinterpret_cast<decltype(&GetOpenFileNameW)>(aFunc);
patchedGetOpenFileNameWType(0);
return true;
}
bool TestGetKeyState(void* aFunc)
{
auto patchedGetKeyState =
reinterpret_cast<decltype(&GetKeyState)>(aFunc);
patchedGetKeyState(0);
return true;
}
bool TestSendMessageTimeoutW(void* aFunc)
{
auto patchedSendMessageTimeoutW =
reinterpret_cast<decltype(&SendMessageTimeoutW)>(aFunc);
return patchedSendMessageTimeoutW(0, 0, 0, 0, 0, 0, 0) == 0;
}
bool TestProcessCaretEvents(void* aFunc)
{
auto patchedProcessCaretEvents =
reinterpret_cast<WINEVENTPROC>(aFunc);
patchedProcessCaretEvents(0, 0, 0, 0, 0, 0, 0);
return true;
}
bool TestSetCursorPos(void* aFunc)
{
// SetCursorPos has some issues in automation -- see bug 1368033.
// For that reason, we don't check the return value -- we only
// check that the method runs without producing an exception.
auto patchedSetCursorPos =
reinterpret_cast<decltype(&SetCursorPos)>(aFunc);
patchedSetCursorPos(512, 512);
return true;
}
static DWORD sTlsIndex = 0;
bool TestTlsAlloc(void* aFunc)
{
auto patchedTlsAlloc =
reinterpret_cast<decltype(&TlsAlloc)>(aFunc);
sTlsIndex = patchedTlsAlloc();
return sTlsIndex != TLS_OUT_OF_INDEXES;
}
bool TestTlsFree(void* aFunc)
{
auto patchedTlsFree =
reinterpret_cast<decltype(&TlsFree)>(aFunc);
return sTlsIndex != 0 && patchedTlsFree(sTlsIndex);
}
bool TestCloseHandle(void* aFunc)
{
auto patchedCloseHandle =
reinterpret_cast<decltype(&CloseHandle)>(aFunc);
return patchedCloseHandle(0) == FALSE;
}
bool TestDuplicateHandle(void* aFunc)
{
auto patchedDuplicateHandle =
reinterpret_cast<decltype(&DuplicateHandle)>(aFunc);
return patchedDuplicateHandle(0, 0, 0, 0, 0, 0, 0) == FALSE;
}
bool TestPrintDlgW(void* aFunc)
{
auto patchedPrintDlgW =
reinterpret_cast<decltype(&PrintDlgW)>(aFunc);
patchedPrintDlgW(0);
return true;
}
bool TestInternetConnectA(void* aFunc)
{
auto patchedInternetConnectA =
reinterpret_cast<decltype(&InternetConnectA)>(aFunc);
return patchedInternetConnectA(0, 0, 0, 0, 0, 0, 0, 0) == 0;
}
HINTERNET sInternet = 0;
bool TestInternetOpenA(void* aFunc)
{
auto patchedInternetOpenA =
reinterpret_cast<decltype(&InternetOpenA)>(aFunc);
sInternet = patchedInternetOpenA(0, 0, 0, 0, 0);
return sInternet != 0;
}
bool TestInternetCloseHandle(void* aFunc)
{
auto patchedInternetCloseHandle =
reinterpret_cast<decltype(&InternetCloseHandle)>(aFunc);
return patchedInternetCloseHandle(sInternet);
}
bool TestInternetQueryDataAvailable(void* aFunc)
{
auto patchedInternetQueryDataAvailable =
reinterpret_cast<decltype(&InternetQueryDataAvailable)>(aFunc);
return patchedInternetQueryDataAvailable(0, 0, 0, 0) == FALSE;
}
bool TestInternetReadFile(void* aFunc)
{
auto patchedInternetReadFile =
reinterpret_cast<decltype(&InternetReadFile)>(aFunc);
return patchedInternetReadFile(0, 0, 0, 0) == FALSE;
}
bool TestInternetWriteFile(void* aFunc)
{
auto patchedInternetWriteFile =
reinterpret_cast<decltype(&InternetWriteFile)>(aFunc);
return patchedInternetWriteFile(0, 0, 0, 0) == FALSE;
}
bool TestInternetSetOptionA(void* aFunc)
{
auto patchedInternetSetOptionA =
reinterpret_cast<decltype(&InternetSetOptionA)>(aFunc);
return patchedInternetSetOptionA(0, 0, 0, 0) == FALSE;
}
bool TestHttpAddRequestHeadersA(void* aFunc)
{
auto patchedHttpAddRequestHeadersA =
reinterpret_cast<decltype(&HttpAddRequestHeadersA)>(aFunc);
return patchedHttpAddRequestHeadersA(0, 0, 0, 0) == FALSE;
}
bool TestHttpOpenRequestA(void* aFunc)
{
auto patchedHttpOpenRequestA =
reinterpret_cast<decltype(&HttpOpenRequestA)>(aFunc);
return patchedHttpOpenRequestA(0, 0, 0, 0, 0, 0, 0, 0) == 0;
}
bool TestHttpQueryInfoA(void* aFunc)
{
auto patchedHttpQueryInfoA =
reinterpret_cast<decltype(&HttpQueryInfoA)>(aFunc);
return patchedHttpQueryInfoA(0, 0, 0, 0, 0) == FALSE;
}
bool TestHttpSendRequestA(void* aFunc)
{
auto patchedHttpSendRequestA =
reinterpret_cast<decltype(&HttpSendRequestA)>(aFunc);
return patchedHttpSendRequestA(0, 0, 0, 0, 0) == FALSE;
}
bool TestHttpSendRequestExA(void* aFunc)
{
auto patchedHttpSendRequestExA =
reinterpret_cast<decltype(&HttpSendRequestExA)>(aFunc);
return patchedHttpSendRequestExA(0, 0, 0, 0, 0) == FALSE;
}
bool TestHttpEndRequestA(void* aFunc)
{
auto patchedHttpEndRequestA =
reinterpret_cast<decltype(&HttpEndRequestA)>(aFunc);
return patchedHttpEndRequestA(0, 0, 0, 0) == FALSE;
}
bool TestInternetQueryOptionA(void* aFunc)
{
auto patchedInternetQueryOptionA =
reinterpret_cast<decltype(&InternetQueryOptionA)>(aFunc);
return patchedInternetQueryOptionA(0, 0, 0, 0) == FALSE;
}
bool TestInternetErrorDlg(void* aFunc)
{
auto patchedInternetErrorDlg =
reinterpret_cast<decltype(&InternetErrorDlg)>(aFunc);
return patchedInternetErrorDlg(0, 0, 0, 0, 0) == ERROR_INVALID_HANDLE;
}
CredHandle sCredHandle;
bool TestAcquireCredentialsHandleA(void* aFunc)
{
auto patchedAcquireCredentialsHandleA =
reinterpret_cast<decltype(&AcquireCredentialsHandleA)>(aFunc);
SCHANNEL_CRED cred;
memset(&cred, 0, sizeof(cred));
cred.dwVersion = SCHANNEL_CRED_VERSION;
return patchedAcquireCredentialsHandleA(0, UNISP_NAME, SECPKG_CRED_OUTBOUND,
0, &cred, 0, 0, &sCredHandle, 0) == S_OK;
}
bool TestQueryCredentialsAttributesA(void* aFunc)
{
auto patchedQueryCredentialsAttributesA =
reinterpret_cast<decltype(&QueryCredentialsAttributesA)>(aFunc);
return patchedQueryCredentialsAttributesA(&sCredHandle, 0, 0) == SEC_E_UNSUPPORTED_FUNCTION;
}
bool TestFreeCredentialsHandle(void* aFunc)
{
auto patchedFreeCredentialsHandle =
reinterpret_cast<decltype(&FreeCredentialsHandle)>(aFunc);
return patchedFreeCredentialsHandle(&sCredHandle) == S_OK;
}
int main()
{
LARGE_INTEGER start;
@ -615,7 +418,7 @@ int main()
{
WindowsDllInterceptor ExeIntercept;
ExeIntercept.Init("TestDllInterceptor.exe");
if (ExeIntercept.AddHook("rotatePayload", reinterpret_cast<intptr_t>(patched_rotatePayload), (void**) &orig_rotatePayload)) {
if (orig_rotatePayload.Set(ExeIntercept, "rotatePayload", &patched_rotatePayload)) {
printf("TEST-PASS | WindowsDllInterceptor | Hook added\n");
} else {
printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to add hook\n");
@ -659,85 +462,85 @@ int main()
}
#endif
if (TestHook(TestGetWindowInfo, "user32.dll", "GetWindowInfo") &&
if (TEST_HOOK(user32.dll, GetWindowInfo, Equals, FALSE) &&
#ifdef _WIN64
TestHook(TestSetWindowLongPtr, "user32.dll", "SetWindowLongPtrA") &&
TestHook(TestSetWindowLongPtr, "user32.dll", "SetWindowLongPtrW") &&
TEST_HOOK(user32.dll, SetWindowLongPtrA, Equals, 0) &&
TEST_HOOK(user32.dll, SetWindowLongPtrW, Equals, 0) &&
#else
TestHook(TestSetWindowLong, "user32.dll", "SetWindowLongA") &&
TestHook(TestSetWindowLong, "user32.dll", "SetWindowLongW") &&
TEST_HOOK(user32.dll, SetWindowLongA, Equals, 0) &&
TEST_HOOK(user32.dll, SetWindowLongW, Equals, 0) &&
#endif
TestHook(TestTrackPopupMenu, "user32.dll", "TrackPopupMenu") &&
TEST_HOOK(user32.dll, TrackPopupMenu, Equals, FALSE) &&
#ifdef _M_IX86
// We keep this test to hook complex code on x86. (Bug 850957)
TestHook(TestNtFlushBuffersFile, "ntdll.dll", "NtFlushBuffersFile") &&
TEST_HOOK(ntdll.dll, NtFlushBuffersFile, NotEquals, 0) &&
#endif
TestHook(TestNtCreateFile, "ntdll.dll", "NtCreateFile") &&
TestHook(TestNtReadFile, "ntdll.dll", "NtReadFile") &&
TestHook(TestNtReadFileScatter, "ntdll.dll", "NtReadFileScatter") &&
TestHook(TestNtWriteFile, "ntdll.dll", "NtWriteFile") &&
TestHook(TestNtWriteFileGather, "ntdll.dll", "NtWriteFileGather") &&
TestHook(TestNtQueryFullAttributesFile, "ntdll.dll", "NtQueryFullAttributesFile") &&
TEST_HOOK(ntdll.dll, NtCreateFile, NotEquals, 0) &&
TEST_HOOK(ntdll.dll, NtReadFile, NotEquals, 0) &&
TEST_HOOK(ntdll.dll, NtReadFileScatter, NotEquals, 0) &&
TEST_HOOK(ntdll.dll, NtWriteFile, NotEquals, 0) &&
TEST_HOOK(ntdll.dll, NtWriteFileGather, NotEquals, 0) &&
TEST_HOOK(ntdll.dll, NtQueryFullAttributesFile, NotEquals, 0) &&
#ifndef MOZ_ASAN
// Bug 733892: toolkit/crashreporter/nsExceptionHandler.cpp
// This fails on ASan because the ASan runtime already hooked this function
TestHook(TestSetUnhandledExceptionFilter, "kernel32.dll", "SetUnhandledExceptionFilter") &&
TEST_HOOK(kernel32.dll, SetUnhandledExceptionFilter, Ignore, nullptr) &&
#endif
#ifdef _M_IX86
// Bug 670967: xpcom/base/AvailableMemoryTracker.cpp
TestHook(TestVirtualAlloc, "kernel32.dll", "VirtualAlloc") &&
TestHook(TestMapViewOfFile, "kernel32.dll", "MapViewOfFile") &&
TestHook(TestCreateDIBSection, "gdi32.dll", "CreateDIBSection") &&
TestHook(TestCreateFileW, "kernel32.dll", "CreateFileW") && // see Bug 1316415
TEST_HOOK(kernel32.dll, VirtualAlloc, Equals, nullptr) &&
TEST_HOOK(kernel32.dll, MapViewOfFile, Equals, nullptr) &&
TEST_HOOK(gdi32.dll, CreateDIBSection, Equals, nullptr) &&
TEST_HOOK_FOR_INVALID_HANDLE_VALUE(kernel32.dll, CreateFileW) &&
#endif
TestHook(TestCreateFileA, "kernel32.dll", "CreateFileA") &&
TestHook(TestQueryDosDeviceW, "kernelbase.dll", "QueryDosDeviceW") &&
TestDetour("user32.dll", "CreateWindowExW") &&
TestHook(TestInSendMessageEx, "user32.dll", "InSendMessageEx") &&
TestHook(TestImmGetContext, "imm32.dll", "ImmGetContext") &&
TestHook(TestImmGetCompositionStringW, "imm32.dll", "ImmGetCompositionStringW") &&
TestHook(TestImmSetCandidateWindow, "imm32.dll", "ImmSetCandidateWindow") &&
TestHook(TestImmNotifyIME, "imm32.dll", "ImmNotifyIME") &&
TestHook(TestGetSaveFileNameW, "comdlg32.dll", "GetSaveFileNameW") &&
TestHook(TestGetOpenFileNameW, "comdlg32.dll", "GetOpenFileNameW") &&
TEST_HOOK_FOR_INVALID_HANDLE_VALUE(kernel32.dll, CreateFileA) &&
TEST_HOOK(kernelbase.dll, QueryDosDeviceW, Equals, 0) &&
TEST_DETOUR(user32.dll, CreateWindowExW, Equals, nullptr) &&
TEST_HOOK(user32.dll, InSendMessageEx, Equals, ISMEX_NOSEND) &&
TEST_HOOK(imm32.dll, ImmGetContext, Equals, nullptr) &&
TEST_HOOK(imm32.dll, ImmGetCompositionStringW, Ignore, 0) &&
TEST_HOOK_SKIP_EXEC(imm32.dll, ImmSetCandidateWindow) &&
TEST_HOOK(imm32.dll, ImmNotifyIME, Equals, 0) &&
TEST_HOOK(comdlg32.dll, GetSaveFileNameW, Ignore, FALSE) &&
TEST_HOOK(comdlg32.dll, GetOpenFileNameW, Ignore, FALSE) &&
#ifdef _M_X64
TestHook(TestGetKeyState, "user32.dll", "GetKeyState") && // see Bug 1316415
TestHook(TestLdrUnloadDll, "ntdll.dll", "LdrUnloadDll") &&
MaybeTestHook(IsWin8OrLater(), TestLdrResolveDelayLoadedAPI, "ntdll.dll", "LdrResolveDelayLoadedAPI") &&
MaybeTestHook(!IsWin8OrLater(), TestRtlInstallFunctionTableCallback, "kernel32.dll", "RtlInstallFunctionTableCallback") &&
TestHook(TestPrintDlgW, "comdlg32.dll", "PrintDlgW") &&
TEST_HOOK(user32.dll, GetKeyState, Ignore, 0) && // see Bug 1316415
TEST_HOOK(ntdll.dll, LdrUnloadDll, NotEquals, 0) &&
MAYBE_TEST_HOOK_SKIP_EXEC(IsWin8OrLater(), ntdll.dll, LdrResolveDelayLoadedAPI) &&
MAYBE_TEST_HOOK(!IsWin8OrLater(), kernel32.dll, RtlInstallFunctionTableCallback, Equals, FALSE) &&
TEST_HOOK(comdlg32.dll, PrintDlgW, Ignore, 0) &&
#endif
MaybeTestHook(ShouldTestTipTsf(), TestProcessCaretEvents, "tiptsf.dll", "ProcessCaretEvents") &&
MAYBE_TEST_HOOK(ShouldTestTipTsf(), tiptsf.dll, ProcessCaretEvents, Ignore, nullptr) &&
#ifdef _M_IX86
TestHook(TestSendMessageTimeoutW, "user32.dll", "SendMessageTimeoutW") &&
TEST_HOOK(user32.dll, SendMessageTimeoutW, Equals, 0) &&
#endif
TestHook(TestSetCursorPos, "user32.dll", "SetCursorPos") &&
TestHook(TestTlsAlloc, "kernel32.dll", "TlsAlloc") &&
TestHook(TestTlsFree, "kernel32.dll", "TlsFree") &&
TestHook(TestCloseHandle, "kernel32.dll", "CloseHandle") &&
TestHook(TestDuplicateHandle, "kernel32.dll", "DuplicateHandle") &&
TEST_HOOK(user32.dll, SetCursorPos, NotEquals, FALSE) &&
TEST_HOOK(kernel32.dll, TlsAlloc, NotEquals, TLS_OUT_OF_INDEXES) &&
TEST_HOOK_PARAMS(kernel32.dll, TlsFree, Equals, FALSE, TLS_OUT_OF_INDEXES) &&
TEST_HOOK(kernel32.dll, CloseHandle, Equals, FALSE) &&
TEST_HOOK(kernel32.dll, DuplicateHandle, Equals, FALSE) &&
TestHook(TestInternetOpenA, "wininet.dll", "InternetOpenA") &&
TestHook(TestInternetCloseHandle, "wininet.dll", "InternetCloseHandle") &&
TestHook(TestInternetConnectA, "wininet.dll", "InternetConnectA") &&
TestHook(TestInternetQueryDataAvailable, "wininet.dll", "InternetQueryDataAvailable") &&
TestHook(TestInternetReadFile, "wininet.dll", "InternetReadFile") &&
TestHook(TestInternetWriteFile, "wininet.dll", "InternetWriteFile") &&
TestHook(TestInternetSetOptionA, "wininet.dll", "InternetSetOptionA") &&
TestHook(TestHttpAddRequestHeadersA, "wininet.dll", "HttpAddRequestHeadersA") &&
TestHook(TestHttpOpenRequestA, "wininet.dll", "HttpOpenRequestA") &&
TestHook(TestHttpQueryInfoA, "wininet.dll", "HttpQueryInfoA") &&
TestHook(TestHttpSendRequestA, "wininet.dll", "HttpSendRequestA") &&
TestHook(TestHttpSendRequestExA, "wininet.dll", "HttpSendRequestExA") &&
TestHook(TestHttpEndRequestA, "wininet.dll", "HttpEndRequestA") &&
TestHook(TestInternetQueryOptionA, "wininet.dll", "InternetQueryOptionA") &&
TEST_HOOK(wininet.dll, InternetOpenA, NotEquals, nullptr) &&
TEST_HOOK(wininet.dll, InternetCloseHandle, Equals, FALSE) &&
TEST_HOOK(wininet.dll, InternetConnectA, Equals, nullptr) &&
TEST_HOOK(wininet.dll, InternetQueryDataAvailable, Equals, FALSE) &&
TEST_HOOK(wininet.dll, InternetReadFile, Equals, FALSE) &&
TEST_HOOK(wininet.dll, InternetWriteFile, Equals, FALSE) &&
TEST_HOOK(wininet.dll, InternetSetOptionA, Equals, FALSE) &&
TEST_HOOK(wininet.dll, HttpAddRequestHeadersA, Equals, FALSE) &&
TEST_HOOK(wininet.dll, HttpOpenRequestA, Equals, nullptr) &&
TEST_HOOK(wininet.dll, HttpQueryInfoA, Equals, FALSE) &&
TEST_HOOK(wininet.dll, HttpSendRequestA, Equals, FALSE) &&
TEST_HOOK(wininet.dll, HttpSendRequestExA, Equals, FALSE) &&
TEST_HOOK(wininet.dll, HttpEndRequestA, Equals, FALSE) &&
TEST_HOOK(wininet.dll, InternetQueryOptionA, Equals, FALSE) &&
TestHook(TestAcquireCredentialsHandleA, "sspicli.dll", "AcquireCredentialsHandleA") &&
TestHook(TestQueryCredentialsAttributesA, "sspicli.dll", "QueryCredentialsAttributesA") &&
TestHook(TestFreeCredentialsHandle, "sspicli.dll", "FreeCredentialsHandle") &&
TEST_HOOK(sspicli.dll, AcquireCredentialsHandleA, NotEquals, SEC_E_OK) &&
TEST_HOOK(sspicli.dll, QueryCredentialsAttributesA, NotEquals, SEC_E_OK) &&
TEST_HOOK(sspicli.dll, FreeCredentialsHandle, NotEquals, SEC_E_OK) &&
TestDetour("kernel32.dll", "BaseThreadInitThunk") &&
TestDetour("ntdll.dll", "LdrLoadDll")) {
TEST_DETOUR_SKIP_EXEC(kernel32.dll, BaseThreadInitThunk) &&
TEST_DETOUR_SKIP_EXEC(ntdll.dll, LdrLoadDll)) {
printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n");
LARGE_INTEGER end, freq;

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

@ -11,19 +11,19 @@
using std::wstring;
static void* gOrigReturnResult;
extern "C" __declspec(dllexport) int
ReturnResult()
{
return 2;
}
static mozilla::CrossProcessDllInterceptor::FuncHookType<decltype(&ReturnResult)>
gOrigReturnResult;
static int
ReturnResultHook()
{
auto origFn = reinterpret_cast<decltype(&ReturnResult)>(gOrigReturnResult);
if (origFn() != 2) {
if (gOrigReturnResult() != 2) {
return 3;
}
@ -73,9 +73,7 @@ int ParentMain()
mozilla::CrossProcessDllInterceptor intcpt(childProcess.get());
intcpt.Init("TestDllInterceptorCrossProcess.exe");
if (!intcpt.AddHook("ReturnResult",
reinterpret_cast<intptr_t>(&ReturnResultHook),
&gOrigReturnResult)) {
if (!gOrigReturnResult.Set(intcpt, "ReturnResult", &ReturnResultHook)) {
printf("TEST-UNEXPECTED-FAIL | DllInterceptorCrossProcess | Failed to add hook\n");
return 1;
}

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

@ -69,7 +69,7 @@ On Error GoTo 0
' Download installer
On Error Resume Next
Download "https://conemu.github.io/install2.ps1", "install2.ps1"
conemuSettingsURI = "https://api.pub.build.mozilla.org/tooltool/sha512/9aa384ecc8025a974999e913c83064b3b797e05d19806e62ef558c8300e4c3f72967e9464ace59759f76216fc2fc66f338a1e5cdea3b9aa264529487f091d929"
conemuSettingsURI = "https://tooltool.mozilla-releng.net/sha512/9aa384ecc8025a974999e913c83064b3b797e05d19806e62ef558c8300e4c3f72967e9464ace59759f76216fc2fc66f338a1e5cdea3b9aa264529487f091d929"
' Run installer
errorCode = shell.Run("powershell.exe -NoProfile -ExecutionPolicy Unrestricted set dst '" & conemuPath & "'; set ver 'stable'; set lnk 'Mozilla Development Shell'; set xml '" & conemuSettingsURI & "'; set run $FALSE; .\install2.ps1", 0, true)
' Delete ConEmu installer

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

@ -15,7 +15,7 @@ namespace mozilla {
namespace sandboxing {
typedef BOOL(WINAPI* CloseHandle_func) (HANDLE hObject);
static CloseHandle_func stub_CloseHandle = nullptr;
static WindowsDllInterceptor::FuncHookType<CloseHandle_func> stub_CloseHandle;
typedef BOOL(WINAPI* DuplicateHandle_func)(HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
@ -24,7 +24,8 @@ typedef BOOL(WINAPI* DuplicateHandle_func)(HANDLE hSourceProcessHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions);
static DuplicateHandle_func stub_DuplicateHandle = nullptr;
static WindowsDllInterceptor::FuncHookType<DuplicateHandle_func>
stub_DuplicateHandle;
static BOOL WINAPI
patched_CloseHandle(HANDLE hObject)
@ -62,17 +63,14 @@ EnableHandleCloseMonitoring()
{
Kernel32Intercept.Init("kernel32.dll");
bool hooked =
Kernel32Intercept.AddHook("CloseHandle",
reinterpret_cast<intptr_t>(patched_CloseHandle),
(void**)&stub_CloseHandle);
stub_CloseHandle.Set(Kernel32Intercept, "CloseHandle", &patched_CloseHandle);
if (!hooked) {
return false;
}
hooked =
Kernel32Intercept.AddHook("DuplicateHandle",
reinterpret_cast<intptr_t>(patched_DuplicateHandle),
(void**)&stub_DuplicateHandle);
stub_DuplicateHandle.Set(Kernel32Intercept, "DuplicateHandle",
&patched_DuplicateHandle);
if (!hooked) {
return false;
}

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

@ -23,7 +23,7 @@ config = {
# from android_common.py
"download_tooltool": True,
"download_minidump_stackwalk": True,
"tooltool_servers": ['https://api.pub.build.mozilla.org/tooltool/'],
"tooltool_servers": ['https://tooltool.mozilla-releng.net/'],
# minidump_tooltool_manifest_path is relative to workspace/build/tests/
"minidump_tooltool_manifest_path": "config/tooltool-manifests/linux64/releng.manifest",
"xpcshell_extra": "--remoteTestRoot=/data/local/tests",

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

@ -29,7 +29,7 @@ config = {
# ToolTool
"tooltool_manifest_src": 'browser\\config\\tooltool-manifests\\{}\\releng.manifest'.format(platform),
'tooltool_url': 'https://api.pub.build.mozilla.org/tooltool/',
'tooltool_url': 'https://tooltool.mozilla-releng.net/',
'tooltool_cache': os.environ.get('TOOLTOOL_CACHE'),
'run_configure': False,

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

@ -29,7 +29,7 @@ config = {
# ToolTool
"tooltool_manifest_src": 'browser\\config\\tooltool-manifests\\{}\\releng.manifest'.format(platform),
'tooltool_url': 'https://api.pub.build.mozilla.org/tooltool/',
'tooltool_url': 'https://tooltool.mozilla-releng.net/',
'tooltool_cache': os.environ.get('TOOLTOOL_CACHE'),
'run_configure': False,

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

@ -986,6 +986,7 @@ nsWebBrowser::SetProgressListener(nsIWebProgressListener* aProgressListener)
NS_IMETHODIMP
nsWebBrowser::SaveURI(nsIURI* aURI,
nsIPrincipal* aPrincipal,
uint32_t aCacheKey,
nsIURI* aReferrer,
uint32_t aReferrerPolicy,
@ -995,12 +996,14 @@ nsWebBrowser::SaveURI(nsIURI* aURI,
nsILoadContext* aPrivacyContext)
{
return SavePrivacyAwareURI(
aURI, aCacheKey, aReferrer, aReferrerPolicy, aPostData, aExtraHeaders,
aFile, aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
aURI, aPrincipal, aCacheKey, aReferrer, aReferrerPolicy, aPostData,
aExtraHeaders, aFile,
aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
}
NS_IMETHODIMP
nsWebBrowser::SavePrivacyAwareURI(nsIURI* aURI,
nsIPrincipal* aPrincipal,
uint32_t aCacheKey,
nsIURI* aReferrer,
uint32_t aReferrerPolicy,
@ -1038,8 +1041,9 @@ nsWebBrowser::SavePrivacyAwareURI(nsIURI* aURI,
mPersist->SetPersistFlags(mPersistFlags);
mPersist->GetCurrentState(&mPersistCurrentState);
rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aReferrerPolicy,
aPostData, aExtraHeaders, aFile, aIsPrivate);
rv = mPersist->SavePrivacyAwareURI(uri, aPrincipal, aCacheKey,
aReferrer, aReferrerPolicy, aPostData,
aExtraHeaders, aFile, aIsPrivate);
if (NS_FAILED(rv)) {
mPersist = nullptr;
}

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

@ -283,7 +283,8 @@ function promiseStartLegacyDownload(aSourceUrl, aOptions) {
// Start the actual download process.
persist.savePrivacyAwareURI(
sourceURI, 0, referrer, Ci.nsIHttpChannel.REFERRER_POLICY_UNSAFE_URL,
sourceURI, Services.scriptSecurityManager.getSystemPrincipal(),
0, referrer, Ci.nsIHttpChannel.REFERRER_POLICY_UNSAFE_URL,
null, null, targetFile, isPrivate);
}).catch(do_report_unexpected_exception);

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

@ -226,7 +226,11 @@ var gViewSourceUtils = {
webBrowserPersist.persistFlags = this.mnsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
webBrowserPersist.progressListener = this.viewSourceProgressListener;
let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_NO_REFERRER;
webBrowserPersist.savePrivacyAwareURI(uri, null, null, referrerPolicy, null, null, file, data.isPrivate);
let ssm = Services.scriptSecurityManager;
let principal = ssm.createCodebasePrincipal(data.uri,
browser.contentPrincipal.originAttributes);
webBrowserPersist.savePrivacyAwareURI(uri, principal, null, null,
referrerPolicy, null, null, file, data.isPrivate);
let helperService = Cc["@mozilla.org/uriloader/external-helper-app-service;1"]
.getService(Ci.nsPIExternalAppLauncher);

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

@ -62,14 +62,15 @@ function forbidCPOW(arg, func, argname) {
// - A linked document using Alt-click Save Link As...
//
function saveURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
aSkipPrompt, aReferrer, aSourceDocument, aIsContentWindowPrivate) {
aSkipPrompt, aReferrer, aSourceDocument,
aIsContentWindowPrivate, aPrincipal) {
forbidCPOW(aURL, "saveURL", "aURL");
forbidCPOW(aReferrer, "saveURL", "aReferrer");
// Allow aSourceDocument to be a CPOW.
internalSave(aURL, null, aFileName, null, null, aShouldBypassCache,
aFilePickerTitleKey, null, aReferrer, aSourceDocument,
aSkipPrompt, null, aIsContentWindowPrivate);
aSkipPrompt, null, aIsContentWindowPrivate, aPrincipal);
}
// Just like saveURL, but will get some info off the image before
@ -112,7 +113,7 @@ const nsISupportsCString = Ci.nsISupportsCString;
*/
function saveImageURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
aSkipPrompt, aReferrer, aDoc, aContentType, aContentDisp,
aIsContentWindowPrivate) {
aIsContentWindowPrivate, aPrincipal) {
forbidCPOW(aURL, "saveImageURL", "aURL");
forbidCPOW(aReferrer, "saveImageURL", "aReferrer");
@ -156,7 +157,7 @@ function saveImageURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
internalSave(aURL, null, aFileName, aContentDisp, aContentType,
aShouldBypassCache, aFilePickerTitleKey, null, aReferrer,
null, aSkipPrompt, null, aIsContentWindowPrivate);
aDoc, aSkipPrompt, null, aIsContentWindowPrivate, aPrincipal);
}
// This is like saveDocument, but takes any browser/frame-like element
@ -331,11 +332,15 @@ XPCOMUtils.defineConstant(this, "kSaveAsType_Text", kSaveAsType_Text);
* This parameter is provided when the aInitiatingDocument is not a
* real document object. Stores whether aInitiatingDocument.defaultView
* was private or not.
* @param aPrincipal [optional]
* This parameter is provided when neither aDocument nor
* aInitiatingDocument is provided. Used to determine what level of
* privilege to load the URI with.
*/
function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
aContentType, aShouldBypassCache, aFilePickerTitleKey,
aChosenData, aReferrer, aInitiatingDocument, aSkipPrompt,
aCacheKey, aIsContentWindowPrivate) {
aCacheKey, aIsContentWindowPrivate, aPrincipal) {
forbidCPOW(aURL, "internalSave", "aURL");
forbidCPOW(aReferrer, "internalSave", "aReferrer");
forbidCPOW(aCacheKey, "internalSave", "aCacheKey");
@ -411,8 +416,17 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
: aInitiatingDocument.isPrivate;
}
// We have to cover the cases here where we were either passed an explicit
// principal, or a 'real' document (with a nodePrincipal property), or an
// nsIWebBrowserPersistDocument which has a principal property.
let sourcePrincipal =
aPrincipal ||
(aDocument && (aDocument.nodePrincipal || aDocument.principal)) ||
(aInitiatingDocument && aInitiatingDocument.nodePrincipal);
var persistArgs = {
sourceURI,
sourcePrincipal,
sourceReferrer: aReferrer,
sourceDocument: useSaveDocument ? aDocument : null,
targetContentType: (saveAsType == kSaveAsType_Text) ? "text/plain" : null,
@ -463,8 +477,7 @@ function internalPersist(persistArgs) {
// Calculate persist flags.
const nsIWBP = Ci.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
nsIWBP.PERSIST_FLAGS_FORCE_ALLOW_COOKIES;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
if (persistArgs.bypassCache)
persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_BYPASS_CACHE;
else
@ -511,6 +524,7 @@ function internalPersist(persistArgs) {
persistArgs.targetContentType, encodingFlags, kWrapColumn);
} else {
persist.savePrivacyAwareURI(persistArgs.sourceURI,
persistArgs.sourcePrincipal,
persistArgs.sourceCacheKey,
persistArgs.sourceReferrer,
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,

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

@ -36,7 +36,8 @@ add_task(async function preferred_API() {
return image.href;
});
saveImageURL(url, "image.jpg", null, true, false, null, null, null, null, false);
saveImageURL(url, "image.jpg", null, true, false, null, null, null, null,
false, gBrowser.contentPrincipal);
let channel = gBrowser.contentDocumentAsCPOW.docShell.currentDocumentChannel;
if (channel) {
ok(true, channel.QueryInterface(Ci.nsIHttpChannelInternal)

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

@ -4,10 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
SOURCES += [
'../google-breakpad/src/common/windows/http_upload.cc',
]
Library('google_breakpad_libxul_s')
FINAL_LIBRARY = 'xul'
@ -22,14 +18,12 @@ LOCAL_INCLUDES += [
include('/toolkit/crashreporter/google-breakpad/src/common/windows/objs.mozbuild')
include('/toolkit/crashreporter/breakpad-client/windows/handler/objs.mozbuild')
include('/toolkit/crashreporter/breakpad-client/windows/sender/objs.mozbuild')
include('/toolkit/crashreporter/breakpad-client/windows/crash_generation/objs.mozbuild')
include('/toolkit/crashreporter/breakpad-client/windows/common/objs.mozbuild')
SOURCES += objs_common
SOURCES += objs_crash_generation
SOURCES += objs_handler
SOURCES += objs_sender
SOURCES += objs_client_common
DisableStlWrapping()

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

@ -24,10 +24,20 @@ if CONFIG['OS_ARCH'] == 'WINNT':
UNIFIED_SOURCES += [
'crashreporter_win.cpp',
]
include('/toolkit/crashreporter/google-breakpad/src/common/windows/objs.mozbuild')
include('/toolkit/crashreporter/breakpad-client/windows/sender/objs.mozbuild')
include('/toolkit/crashreporter/breakpad-client/windows/crash_generation/objs.mozbuild')
include('/toolkit/crashreporter/breakpad-client/windows/common/objs.mozbuild')
SOURCES += objs_common
SOURCES += objs_sender
SOURCES += objs_crash_generation
SOURCES += objs_client_common
SOURCES += [
'../google-breakpad/src/common/windows/http_upload.cc',
]
DEFINES['UNICODE'] = True
DEFINES['_UNICODE'] = True
USE_LIBS += [
'google_breakpad_libxul_s',
'nss',
]
OS_LIBS += [

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

@ -338,7 +338,8 @@ nsTArray<nsAutoPtr<DelayedNote> >* gDelayedAnnotations;
// reporter is loaded instead (in case it became unloaded somehow)
typedef LPTOP_LEVEL_EXCEPTION_FILTER (WINAPI *SetUnhandledExceptionFilter_func)
(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
static SetUnhandledExceptionFilter_func stub_SetUnhandledExceptionFilter = 0;
static WindowsDllInterceptor::FuncHookType<SetUnhandledExceptionFilter_func>
stub_SetUnhandledExceptionFilter;
static LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = nullptr;
static WindowsDllInterceptor gKernel32Intercept;
static bool gBlockUnhandledExceptionFilter = true;
@ -1639,9 +1640,9 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
// protect the crash reporter from being unloaded
gBlockUnhandledExceptionFilter = true;
gKernel32Intercept.Init("kernel32.dll");
bool ok = gKernel32Intercept.AddHook("SetUnhandledExceptionFilter",
reinterpret_cast<intptr_t>(patched_SetUnhandledExceptionFilter),
(void**) &stub_SetUnhandledExceptionFilter);
bool ok = stub_SetUnhandledExceptionFilter.Set(gKernel32Intercept,
"SetUnhandledExceptionFilter",
&patched_SetUnhandledExceptionFilter);
#ifdef DEBUG
if (!ok)

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

@ -971,7 +971,8 @@ function _persistImage(sourceURL, localFileName, successCallback) {
persist.progressListener = new _persistProgressListener(successCallback);
persist.saveURI(sourceURI, 0,
let sourcePrincipal = Services.scriptSecurityManager.createCodebasePrincipal(sourceURI, {});
persist.saveURI(sourceURI, sourcePrincipal, 0,
null, Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
null, null, targetURI, null);
}

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

@ -6,7 +6,7 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
echo "To complete this script you will need the following tokens from https://api.pub.build.mozilla.org/tokenauth/"
echo "To complete this script you will need the following tokens from https://mozilla-releng.net/tokens"
echo " - tooltool.upload.public"
echo " - tooltool.download.public"
echo ""
@ -14,7 +14,7 @@ read -p "Are these tokens visible at the above URL (y/n)?" choice
case "$choice" in
y|Y )
echo ""
echo "1. Go to https://api.pub.build.mozilla.org/"
echo "1. Go to https://mozilla-releng.net"
echo "2. Log in using your Mozilla LDAP account."
echo "3. Click on \"Tokens.\""
echo "4. Issue a user token with the permissions tooltool.upload.public and tooltool.download.public."
@ -49,10 +49,10 @@ tar cvz -f eslint-plugin-mozilla.tar.gz node_modules
echo "Adding eslint-plugin-mozilla.tar.gz to tooltool..."
rm -f manifest.tt
../../../../python/mozbuild/mozbuild/action/tooltool.py add --visibility public --unpack eslint-plugin-mozilla.tar.gz --url="https://api.pub.build.mozilla.org/tooltool/"
../../../../python/mozbuild/mozbuild/action/tooltool.py add --visibility public --unpack eslint-plugin-mozilla.tar.gz --url="https://tooltool.mozilla-releng.net/"
echo "Uploading eslint-plugin-mozilla.tar.gz to tooltool..."
../../../../python/mozbuild/mozbuild/action/tooltool.py upload --authentication-file=~/.tooltool-token --message "node_modules folder update for tools/lint/eslint/eslint-plugin-mozilla" --url="https://api.pub.build.mozilla.org/tooltool/"
../../../../python/mozbuild/mozbuild/action/tooltool.py upload --authentication-file=~/.tooltool-token --message "node_modules folder update for tools/lint/eslint/eslint-plugin-mozilla" --url="https://tooltool.mozilla-releng.net/"
echo "Cleaning up..."
rm eslint-plugin-mozilla.tar.gz

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

@ -6,7 +6,7 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
echo "To complete this script you will need the following tokens from https://api.pub.build.mozilla.org/tokenauth/"
echo "To complete this script you will need the following tokens from https://mozilla-releng.net/tokens"
echo " - tooltool.upload.public"
echo " - tooltool.download.public"
echo ""
@ -14,7 +14,7 @@ read -p "Are these tokens visible at the above URL (y/n)?" choice
case "$choice" in
y|Y )
echo ""
echo "1. Go to https://api.pub.build.mozilla.org/"
echo "1. Go to https://mozilla-releng.net"
echo "2. Log in using your Mozilla LDAP account."
echo "3. Click on \"Tokens.\""
echo "4. Issue a user token with the permissions tooltool.upload.public and tooltool.download.public."
@ -56,10 +56,10 @@ tar cvz --exclude=eslint-plugin-mozilla --exclude=eslint-plugin-spidermonkey-js
echo "Adding eslint.tar.gz to tooltool..."
rm tools/lint/eslint/manifest.tt
./python/mozbuild/mozbuild/action/tooltool.py add --visibility public --unpack eslint.tar.gz --url="https://api.pub.build.mozilla.org/tooltool/"
./python/mozbuild/mozbuild/action/tooltool.py add --visibility public --unpack eslint.tar.gz --url="https://tooltool.mozilla-releng.net/"
echo "Uploading eslint.tar.gz to tooltool..."
./python/mozbuild/mozbuild/action/tooltool.py upload --authentication-file=~/.tooltool-token --message "node_modules folder update for tools/lint/eslint" --url="https://api.pub.build.mozilla.org/tooltool/"
./python/mozbuild/mozbuild/action/tooltool.py upload --authentication-file=~/.tooltool-token --message "node_modules folder update for tools/lint/eslint" --url="https://tooltool.mozilla-releng.net/"
echo "Cleaning up..."
mv manifest.tt tools/lint/eslint/manifest.tt

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

@ -303,7 +303,8 @@ Registers::SyncPopulate()
static WindowsDllInterceptor NtDllIntercept;
typedef NTSTATUS (NTAPI *LdrUnloadDll_func)(HMODULE module);
static LdrUnloadDll_func stub_LdrUnloadDll;
static WindowsDllInterceptor::FuncHookType<LdrUnloadDll_func>
stub_LdrUnloadDll;
static NTSTATUS NTAPI
patched_LdrUnloadDll(HMODULE module)
@ -318,7 +319,8 @@ patched_LdrUnloadDll(HMODULE module)
typedef PVOID (WINAPI *LdrResolveDelayLoadedAPI_func)(PVOID ParentModuleBase,
PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook,
PVOID ThunkAddress, ULONG Flags);
static LdrResolveDelayLoadedAPI_func stub_LdrResolveDelayLoadedAPI;
static WindowsDllInterceptor::FuncHookType<LdrResolveDelayLoadedAPI_func>
stub_LdrResolveDelayLoadedAPI;
static PVOID WINAPI
patched_LdrResolveDelayLoadedAPI(PVOID ParentModuleBase,
@ -336,20 +338,12 @@ patched_LdrResolveDelayLoadedAPI(PVOID ParentModuleBase,
void
InitializeWin64ProfilerHooks()
{
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
NtDllIntercept.Init("ntdll.dll");
NtDllIntercept.AddHook("LdrUnloadDll",
reinterpret_cast<intptr_t>(patched_LdrUnloadDll),
(void**)&stub_LdrUnloadDll);
stub_LdrUnloadDll.Set(NtDllIntercept, "LdrUnloadDll", &patched_LdrUnloadDll);
if (IsWin8OrLater()) { // LdrResolveDelayLoadedAPI was introduced in Win8
NtDllIntercept.AddHook("LdrResolveDelayLoadedAPI",
reinterpret_cast<intptr_t>(patched_LdrResolveDelayLoadedAPI),
(void**)&stub_LdrResolveDelayLoadedAPI);
stub_LdrResolveDelayLoadedAPI.Set(NtDllIntercept,
"LdrResolveDelayLoadedAPI",
&patched_LdrResolveDelayLoadedAPI);
}
}
#endif // defined(GP_PLAT_amd64_windows)

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

@ -352,9 +352,6 @@ static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
// General purpose user32.dll hook object
static WindowsDllInterceptor sUser32Intercept;
// AddHook success checks
static mozilla::Maybe<bool> sHookedGetWindowInfo;
// 2 pixel offset for eTransparencyBorderlessGlass which equals the size of
// the default window border Windows paints. Glass will be extended inward
// this distance to remove the border.
@ -461,17 +458,17 @@ private:
if (!IsWin10OrLater() && GetModuleHandle(L"tiptsf.dll") &&
!sProcessCaretEventsStub) {
sTipTsfInterceptor.Init("tiptsf.dll");
DebugOnly<bool> ok = sTipTsfInterceptor.AddHook("ProcessCaretEvents",
reinterpret_cast<intptr_t>(&ProcessCaretEventsHook),
(void**) &sProcessCaretEventsStub);
DebugOnly<bool> ok = sProcessCaretEventsStub.Set(sTipTsfInterceptor,
"ProcessCaretEvents",
&ProcessCaretEventsHook);
MOZ_ASSERT(ok);
}
if (!sSendMessageTimeoutWStub) {
sUser32Intercept.Init("user32.dll");
DebugOnly<bool> hooked = sUser32Intercept.AddHook("SendMessageTimeoutW",
reinterpret_cast<intptr_t>(&SendMessageTimeoutWHook),
(void**) &sSendMessageTimeoutWStub);
DebugOnly<bool> hooked = sSendMessageTimeoutWStub.Set(sUser32Intercept,
"SendMessageTimeoutW",
&SendMessageTimeoutWHook);
MOZ_ASSERT(hooked);
}
}
@ -556,8 +553,10 @@ private:
}
static WindowsDllInterceptor sTipTsfInterceptor;
static WINEVENTPROC sProcessCaretEventsStub;
static decltype(&SendMessageTimeoutW) sSendMessageTimeoutWStub;
static WindowsDllInterceptor::FuncHookType<WINEVENTPROC>
sProcessCaretEventsStub;
static WindowsDllInterceptor::FuncHookType<decltype(&SendMessageTimeoutW)>
sSendMessageTimeoutWStub;
static StaticAutoPtr<TIPMessageHandler> sInstance;
HHOOK mHook;
@ -566,8 +565,10 @@ private:
};
WindowsDllInterceptor TIPMessageHandler::sTipTsfInterceptor;
WINEVENTPROC TIPMessageHandler::sProcessCaretEventsStub;
decltype(&SendMessageTimeoutW) TIPMessageHandler::sSendMessageTimeoutWStub;
WindowsDllInterceptor::FuncHookType<WINEVENTPROC>
TIPMessageHandler::sProcessCaretEventsStub;
WindowsDllInterceptor::FuncHookType<decltype(&SendMessageTimeoutW)>
TIPMessageHandler::sSendMessageTimeoutWStub;
StaticAutoPtr<TIPMessageHandler> TIPMessageHandler::sInstance;
} // namespace mozilla
@ -2472,7 +2473,7 @@ nsWindow::ResetLayout()
// margins are set.
static const wchar_t kManageWindowInfoProperty[] = L"ManageWindowInfoProperty";
typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
static GetWindowInfoPtr sGetWindowInfoPtrStub = nullptr;
static WindowsDllInterceptor::FuncHookType<GetWindowInfoPtr> sGetWindowInfoPtrStub;
BOOL WINAPI
GetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
@ -2500,18 +2501,15 @@ nsWindow::UpdateGetWindowInfoCaptionStatus(bool aActiveCaption)
if (!mWnd)
return;
if (sHookedGetWindowInfo.isNothing()) {
sUser32Intercept.Init("user32.dll");
sHookedGetWindowInfo =
Some(sUser32Intercept.AddHook("GetWindowInfo",
reinterpret_cast<intptr_t>(GetWindowInfoHook),
(void**) &sGetWindowInfoPtrStub));
if (!sHookedGetWindowInfo.value()) {
return;
}
sUser32Intercept.Init("user32.dll");
sGetWindowInfoPtrStub.Set(sUser32Intercept, "GetWindowInfo",
&GetWindowInfoHook);
if (!sGetWindowInfoPtrStub) {
return;
}
// Update our internally tracked caption status
SetPropW(mWnd, kManageWindowInfoProperty,
SetPropW(mWnd, kManageWindowInfoProperty,
reinterpret_cast<HANDLE>(static_cast<INT_PTR>(aActiveCaption) + 1));
}

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

@ -84,16 +84,14 @@ volatile PRIntervalTime sLastLowMemoryNotificationTime;
// These are function pointers to the functions we wrap in Init().
void* (WINAPI* sVirtualAllocOrig)(LPVOID aAddress, SIZE_T aSize,
DWORD aAllocationType, DWORD aProtect);
static WindowsDllInterceptor::FuncHookType<decltype(&VirtualAlloc)>
sVirtualAllocOrig;
void* (WINAPI* sMapViewOfFileOrig)(HANDLE aFileMappingObject,
DWORD aDesiredAccess, DWORD aFileOffsetHigh,
DWORD aFileOffsetLow, SIZE_T aNumBytesToMap);
static WindowsDllInterceptor::FuncHookType<decltype(&MapViewOfFile)>
sMapViewOfFileOrig;
HBITMAP(WINAPI* sCreateDIBSectionOrig)(HDC aDC, const BITMAPINFO* aBitmapInfo,
UINT aUsage, VOID** aBits,
HANDLE aSection, DWORD aOffset);
static WindowsDllInterceptor::FuncHookType<decltype(&CreateDIBSection)>
sCreateDIBSectionOrig;
/**
* Fire a memory pressure event if we were not under memory pressure yet, or
@ -645,17 +643,12 @@ Init()
// VirtualAllocHook from reentering itself.
if (!PR_GetEnv("MOZ_PGO_INSTRUMENTED")) {
sKernel32Intercept.Init("Kernel32.dll");
sKernel32Intercept.AddHook("VirtualAlloc",
reinterpret_cast<intptr_t>(VirtualAllocHook),
reinterpret_cast<void**>(&sVirtualAllocOrig));
sKernel32Intercept.AddHook("MapViewOfFile",
reinterpret_cast<intptr_t>(MapViewOfFileHook),
reinterpret_cast<void**>(&sMapViewOfFileOrig));
sVirtualAllocOrig.Set(sKernel32Intercept, "VirtualAlloc", &VirtualAllocHook);
sMapViewOfFileOrig.Set(sKernel32Intercept, "MapViewOfFile", &MapViewOfFileHook);
sGdi32Intercept.Init("Gdi32.dll");
sGdi32Intercept.AddHook("CreateDIBSection",
reinterpret_cast<intptr_t>(CreateDIBSectionHook),
reinterpret_cast<void**>(&sCreateDIBSectionOrig));
sCreateDIBSectionOrig.Set(sGdi32Intercept, "CreateDIBSection",
&CreateDIBSectionHook);
}
sInitialized = true;

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

@ -209,13 +209,20 @@ WinIOAutoObservation::Filename(nsAString& aFilename)
/*************************** IO Interposing Methods ***************************/
// Function pointers to original functions
static NtCreateFileFn gOriginalNtCreateFile;
static NtReadFileFn gOriginalNtReadFile;
static NtReadFileScatterFn gOriginalNtReadFileScatter;
static NtWriteFileFn gOriginalNtWriteFile;
static NtWriteFileGatherFn gOriginalNtWriteFileGather;
static NtFlushBuffersFileFn gOriginalNtFlushBuffersFile;
static NtQueryFullAttributesFileFn gOriginalNtQueryFullAttributesFile;
static WindowsDllInterceptor::FuncHookType<NtCreateFileFn>
gOriginalNtCreateFile;
static WindowsDllInterceptor::FuncHookType<NtReadFileFn>
gOriginalNtReadFile;
static WindowsDllInterceptor::FuncHookType<NtReadFileScatterFn>
gOriginalNtReadFileScatter;
static WindowsDllInterceptor::FuncHookType<NtWriteFileFn>
gOriginalNtWriteFile;
static WindowsDllInterceptor::FuncHookType<NtWriteFileGatherFn>
gOriginalNtWriteFileGather;
static WindowsDllInterceptor::FuncHookType<NtFlushBuffersFileFn>
gOriginalNtFlushBuffersFile;
static WindowsDllInterceptor::FuncHookType<NtQueryFullAttributesFileFn>
gOriginalNtQueryFullAttributesFile;
static NTSTATUS NTAPI
InterposedNtCreateFile(PHANDLE aFileHandle,
@ -448,34 +455,21 @@ InitPoisonIOInterposer()
// Initialize dll interceptor and add hooks
sNtDllInterceptor.Init("ntdll.dll");
sNtDllInterceptor.AddHook(
"NtCreateFile",
reinterpret_cast<intptr_t>(InterposedNtCreateFile),
reinterpret_cast<void**>(&gOriginalNtCreateFile));
sNtDllInterceptor.AddHook(
"NtReadFile",
reinterpret_cast<intptr_t>(InterposedNtReadFile),
reinterpret_cast<void**>(&gOriginalNtReadFile));
sNtDllInterceptor.AddHook(
"NtReadFileScatter",
reinterpret_cast<intptr_t>(InterposedNtReadFileScatter),
reinterpret_cast<void**>(&gOriginalNtReadFileScatter));
sNtDllInterceptor.AddHook(
"NtWriteFile",
reinterpret_cast<intptr_t>(InterposedNtWriteFile),
reinterpret_cast<void**>(&gOriginalNtWriteFile));
sNtDllInterceptor.AddHook(
"NtWriteFileGather",
reinterpret_cast<intptr_t>(InterposedNtWriteFileGather),
reinterpret_cast<void**>(&gOriginalNtWriteFileGather));
sNtDllInterceptor.AddHook(
"NtFlushBuffersFile",
reinterpret_cast<intptr_t>(InterposedNtFlushBuffersFile),
reinterpret_cast<void**>(&gOriginalNtFlushBuffersFile));
sNtDllInterceptor.AddHook(
"NtQueryFullAttributesFile",
reinterpret_cast<intptr_t>(InterposedNtQueryFullAttributesFile),
reinterpret_cast<void**>(&gOriginalNtQueryFullAttributesFile));
gOriginalNtCreateFile.Set(sNtDllInterceptor, "NtCreateFile",
&InterposedNtCreateFile);
gOriginalNtReadFile.Set(sNtDllInterceptor, "NtReadFile",
&InterposedNtReadFile);
gOriginalNtReadFileScatter.Set(sNtDllInterceptor, "NtReadFileScatter",
&InterposedNtReadFileScatter);
gOriginalNtWriteFile.Set(sNtDllInterceptor, "NtWriteFile",
&InterposedNtWriteFile);
gOriginalNtWriteFileGather.Set(sNtDllInterceptor, "NtWriteFileGather",
&InterposedNtWriteFileGather);
gOriginalNtFlushBuffersFile.Set(sNtDllInterceptor, "NtFlushBuffersFile",
&InterposedNtFlushBuffersFile);
gOriginalNtQueryFullAttributesFile.Set(sNtDllInterceptor,
"NtQueryFullAttributesFile",
&InterposedNtQueryFullAttributesFile);
}
void