зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1503538: Part 4 - Add injected static import blocking to launcher process; r=mhowell
Depends on D27145 Differential Revision: https://phabricator.services.mozilla.com/D27146 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1a74deabad
Коммит
5b40d0b92a
|
@ -7,6 +7,7 @@
|
|||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ImportDir.h"
|
||||
#include "mozilla/NativeNt.h"
|
||||
#include "mozilla/Types.h"
|
||||
#include "mozilla/WindowsDllBlocklist.h"
|
||||
|
@ -304,9 +305,14 @@ static NTSTATUS NTAPI patched_NtMapViewOfSection(
|
|||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
LauncherVoidResult InitializeDllBlocklistOOP(HANDLE aChildProcess) {
|
||||
LauncherVoidResult InitializeDllBlocklistOOP(const wchar_t* aFullImagePath,
|
||||
HANDLE aChildProcess) {
|
||||
mozilla::CrossProcessDllInterceptor intcpt(aChildProcess);
|
||||
intcpt.Init(L"ntdll.dll");
|
||||
bool ok = stub_NtMapViewOfSection.SetDetour(
|
||||
|
@ -325,32 +331,36 @@ LauncherVoidResult InitializeDllBlocklistOOP(HANDLE aChildProcess) {
|
|||
// linked into ntdll, so we obtain the IAT from our own executable and graft
|
||||
// it onto the child process's IAT, thus enabling the child process's hook to
|
||||
// safely make its ntdll calls.
|
||||
mozilla::nt::PEHeaders ourExeImage(::GetModuleHandleW(nullptr));
|
||||
|
||||
HMODULE ourModule;
|
||||
#if defined(_MSC_VER)
|
||||
ourModule = reinterpret_cast<HMODULE>(&__ImageBase);
|
||||
#else
|
||||
ourModule = ::GetModuleHandleW(nullptr);
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
mozilla::nt::PEHeaders ourExeImage(ourModule);
|
||||
if (!ourExeImage) {
|
||||
return LAUNCHER_ERROR_FROM_WIN32(ERROR_BAD_EXE_FORMAT);
|
||||
}
|
||||
|
||||
PIMAGE_IMPORT_DESCRIPTOR impDesc = ourExeImage.GetIATForModule("ntdll.dll");
|
||||
if (!impDesc) {
|
||||
// As part of our mitigation of binary tampering, copy our import directory
|
||||
// from the original in our executable file.
|
||||
LauncherVoidResult importDirRestored =
|
||||
RestoreImportDirectory(aFullImagePath, ourExeImage, aChildProcess,
|
||||
ourModule);
|
||||
if (importDirRestored.isErr()) {
|
||||
return importDirRestored;
|
||||
}
|
||||
|
||||
Maybe<nt::PEHeaders::IATThunks> ntdllThunks =
|
||||
ourExeImage.GetIATThunksForModule("ntdll.dll");
|
||||
if (!ntdllThunks) {
|
||||
return LAUNCHER_ERROR_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
// This is the pointer we need to write
|
||||
auto firstIatThunk =
|
||||
ourExeImage.template RVAToPtr<PIMAGE_THUNK_DATA>(impDesc->FirstThunk);
|
||||
if (!firstIatThunk) {
|
||||
return LAUNCHER_ERROR_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
// Find the length by iterating through the table until we find a null entry
|
||||
PIMAGE_THUNK_DATA curIatThunk = firstIatThunk;
|
||||
while (mozilla::nt::PEHeaders::IsValid(curIatThunk)) {
|
||||
++curIatThunk;
|
||||
}
|
||||
|
||||
ptrdiff_t iatLength =
|
||||
(curIatThunk - firstIatThunk) * sizeof(IMAGE_THUNK_DATA);
|
||||
|
||||
PIMAGE_THUNK_DATA firstIatThunk = ntdllThunks.value().mFirstThunk;
|
||||
SIZE_T iatLength = ntdllThunks.value().Length();
|
||||
SIZE_T bytesWritten;
|
||||
|
||||
{ // Scope for prot
|
||||
|
@ -362,7 +372,7 @@ LauncherVoidResult InitializeDllBlocklistOOP(HANDLE aChildProcess) {
|
|||
|
||||
ok = !!::WriteProcessMemory(aChildProcess, firstIatThunk, firstIatThunk,
|
||||
iatLength, &bytesWritten);
|
||||
if (!ok) {
|
||||
if (!ok || bytesWritten != iatLength) {
|
||||
return LAUNCHER_ERROR_FROM_LAST();
|
||||
}
|
||||
}
|
||||
|
@ -371,7 +381,7 @@ LauncherVoidResult InitializeDllBlocklistOOP(HANDLE aChildProcess) {
|
|||
uint32_t newFlags = eDllBlocklistInitFlagWasBootstrapped;
|
||||
ok = !!::WriteProcessMemory(aChildProcess, &gBlocklistInitFlags, &newFlags,
|
||||
sizeof(newFlags), &bytesWritten);
|
||||
if (!ok) {
|
||||
if (!ok || bytesWritten != sizeof(newFlags)) {
|
||||
return LAUNCHER_ERROR_FROM_LAST();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
LauncherVoidResult InitializeDllBlocklistOOP(HANDLE aChildProcess);
|
||||
LauncherVoidResult InitializeDllBlocklistOOP(const wchar_t* aFullImagePath,
|
||||
HANDLE aChildProcess);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
*
|
||||
* @return Ok if browser startup should proceed
|
||||
*/
|
||||
static mozilla::LauncherVoidResult PostCreationSetup(HANDLE aChildProcess,
|
||||
static mozilla::LauncherVoidResult PostCreationSetup(const wchar_t* aFullImagePath,
|
||||
HANDLE aChildProcess,
|
||||
HANDLE aChildMainThread,
|
||||
const bool aIsSafeMode) {
|
||||
// The launcher process's DLL blocking code is incompatible with ASAN because
|
||||
|
@ -50,7 +51,7 @@ static mozilla::LauncherVoidResult PostCreationSetup(HANDLE aChildProcess,
|
|||
#if defined(MOZ_ASAN) || defined(_M_ARM64)
|
||||
return mozilla::Ok();
|
||||
#else
|
||||
return mozilla::InitializeDllBlocklistOOP(aChildProcess);
|
||||
return mozilla::InitializeDllBlocklistOOP(aFullImagePath, aChildProcess);
|
||||
#endif // defined(MOZ_ASAN) || defined(_M_ARM64)
|
||||
}
|
||||
|
||||
|
@ -332,7 +333,8 @@ Maybe<int> LauncherMain(int& argc, wchar_t* argv[],
|
|||
nsAutoHandle mainThread(pi.hThread);
|
||||
|
||||
LauncherVoidResult setupResult =
|
||||
PostCreationSetup(process.get(), mainThread.get(), isSafeMode.value());
|
||||
PostCreationSetup(argv[0], process.get(), mainThread.get(),
|
||||
isSafeMode.value());
|
||||
if (setupResult.isErr()) {
|
||||
HandleLauncherError(setupResult);
|
||||
::TerminateProcess(process.get(), 1);
|
||||
|
|
Загрузка…
Ссылка в новой задаче