Skip to content

Commit

Permalink
Bug 1451511: Add cross-process function hooking to DLL interceptor; r…
Browse files Browse the repository at this point in the history
…=handyman
  • Loading branch information
dblohm7 committed Apr 4, 2018
1 parent f9a5fd5 commit 340df59
Show file tree
Hide file tree
Showing 10 changed files with 786 additions and 36 deletions.
2 changes: 1 addition & 1 deletion ipc/mscom/AgileReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

#include "mozilla/mscom/AgileReference.h"

#include "DynamicallyLinkedFunctionPtr.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
#include "mozilla/Assertions.h"
#include "mozilla/Move.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
* 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/. */

#ifndef mozilla_mscom_DynamicallyLinkedFunctionPtr_h
#define mozilla_mscom_DynamicallyLinkedFunctionPtr_h
#ifndef mozilla_DynamicallyLinkedFunctionPtr_h
#define mozilla_DynamicallyLinkedFunctionPtr_h

#include "mozilla/Move.h"
#include <windows.h>

namespace mozilla {
namespace mscom {

template <typename T>
class DynamicallyLinkedFunctionPtr;
Expand Down Expand Up @@ -68,8 +67,7 @@ class DynamicallyLinkedFunctionPtr<R (__stdcall*)(Args...)>
FunctionPtrT mFunction;
};

} // namespace mscom
} // namespace mozilla

#endif // mozilla_mscom_DynamicallyLinkedFunctionPtr_h
#endif // mozilla_DynamicallyLinkedFunctionPtr_h

131 changes: 131 additions & 0 deletions mozglue/misc/WindowsMapRemoteView.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "mozilla/WindowsMapRemoteView.h"

#include "mozilla/Assertions.h"
#include "mozilla/DynamicallyLinkedFunctionPtr.h"

#include <winternl.h>

#if (NTDDI_VERSION < NTDDI_WIN10_RS2)

// MapViewOfFile2 is just an inline function that calls MapViewOfFileNuma2 with
// its preferred node set to NUMA_NO_PREFERRED_NODE
PVOID WINAPI
MapViewOfFileNuma2(HANDLE aFileMapping, HANDLE aProcess, ULONG64 aOffset,
PVOID aBaseAddress, SIZE_T aViewSize, ULONG aAllocationType,
ULONG aPageProtection, ULONG aPreferredNode);

BOOL WINAPI
UnmapViewOfFile2(HANDLE aProcess, PVOID aBaseAddress, ULONG aUnmapFlags);

#endif // (NTDDI_VERSION < NTDDI_WIN10_RS2)

enum SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
};

NTSTATUS NTAPI
NtMapViewOfSection(HANDLE aSection, HANDLE aProcess, PVOID* aBaseAddress,
ULONG_PTR aZeroBits, SIZE_T aCommitSize,
PLARGE_INTEGER aSectionOffset, PSIZE_T aViewSize,
SECTION_INHERIT aInheritDisposition, ULONG aAllocationType,
ULONG aProtectionFlags);

NTSTATUS NTAPI
NtUnmapViewOfSection(HANDLE aProcess, PVOID aBaseAddress);

static DWORD
GetWin32ErrorCode(NTSTATUS aNtStatus)
{
static const mozilla::DynamicallyLinkedFunctionPtr<decltype(&RtlNtStatusToDosError)>
pRtlNtStatusToDosError(L"ntdll.dll", "RtlNtStatusToDosError");

MOZ_ASSERT(!!pRtlNtStatusToDosError);
if (!pRtlNtStatusToDosError) {
return ERROR_GEN_FAILURE;
}

return pRtlNtStatusToDosError(aNtStatus);
}

namespace mozilla {

MFBT_API void*
MapRemoteViewOfFile(HANDLE aFileMapping, HANDLE aProcess, ULONG64 aOffset,
PVOID aBaseAddress, SIZE_T aViewSize, ULONG aAllocationType,
ULONG aProtectionFlags)
{
static const DynamicallyLinkedFunctionPtr<decltype(&MapViewOfFileNuma2)>
pMapViewOfFileNuma2(L"Api-ms-win-core-memory-l1-1-5.dll", "MapViewOfFileNuma2");

if (!!pMapViewOfFileNuma2) {
return pMapViewOfFileNuma2(aFileMapping, aProcess, aOffset, aBaseAddress,
aViewSize, aAllocationType, aProtectionFlags,
NUMA_NO_PREFERRED_NODE);
}

static const DynamicallyLinkedFunctionPtr<decltype(&NtMapViewOfSection)>
pNtMapViewOfSection(L"ntdll.dll", "NtMapViewOfSection");

MOZ_ASSERT(!!pNtMapViewOfSection);
if (!pNtMapViewOfSection) {
return nullptr;
}

// For the sake of consistency, we only permit the same flags that
// MapViewOfFileNuma2 allows
if (aAllocationType != 0 && aAllocationType != MEM_RESERVE &&
aAllocationType != MEM_LARGE_PAGES) {
::SetLastError(ERROR_INVALID_PARAMETER);
return nullptr;
}

NTSTATUS ntStatus;

LARGE_INTEGER offset;
offset.QuadPart = aOffset;

ntStatus = pNtMapViewOfSection(aFileMapping, aProcess, &aBaseAddress, 0, 0,
&offset, &aViewSize, ViewUnmap,
aAllocationType, aProtectionFlags);
if (NT_SUCCESS(ntStatus)) {
::SetLastError(ERROR_SUCCESS);
return aBaseAddress;
}

::SetLastError(GetWin32ErrorCode(ntStatus));
return nullptr;
}

MFBT_API bool
UnmapRemoteViewOfFile(HANDLE aProcess, PVOID aBaseAddress)
{
static const DynamicallyLinkedFunctionPtr<decltype(&UnmapViewOfFile2)>
pUnmapViewOfFile2(L"kernel32.dll", "UnmapViewOfFile2");

if (!!pUnmapViewOfFile2) {
return !!pUnmapViewOfFile2(aProcess, aBaseAddress, 0);
}

static const DynamicallyLinkedFunctionPtr<decltype(&NtUnmapViewOfSection)>
pNtUnmapViewOfSection(L"ntdll.dll", "NtUnmapViewOfSection");

MOZ_ASSERT(!!pNtUnmapViewOfSection);
if (!pNtUnmapViewOfSection) {
return false;
}

NTSTATUS ntStatus = pNtUnmapViewOfSection(aProcess, aBaseAddress);
::SetLastError(GetWin32ErrorCode(ntStatus));
return NT_SUCCESS(ntStatus);
}

} // namespace mozilla

26 changes: 26 additions & 0 deletions mozglue/misc/WindowsMapRemoteView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef mozilla_WindowsMapRemoteView_h
#define mozilla_WindowsMapRemoteView_h

#include "mozilla/Types.h"

#include <windows.h>

namespace mozilla {

MFBT_API PVOID
MapRemoteViewOfFile(HANDLE aFileMapping, HANDLE aProcess, ULONG64 aOffset,
PVOID aBaseAddress, SIZE_T aViewSize, ULONG aAllocationType,
ULONG aProtectionFlags);

MFBT_API bool
UnmapRemoteViewOfFile(HANDLE aProcess, PVOID aBaseAddress);

} // namespace mozilla

#endif // mozilla_WindowsMapRemoteView_h
Loading

0 comments on commit 340df59

Please sign in to comment.