1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
/* -*- 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_freestanding_SharedSection_h
#define mozilla_freestanding_SharedSection_h
#include "mozilla/NativeNt.h"
#include "mozilla/interceptor/MMPolicies.h"
namespace mozilla {
namespace freestanding {
// This class calculates RVAs of kernel32's functions and transfers them
// to a target process, where the transferred RVAs are resolved into
// function addresses so that the target process can use them after
// kernel32.dll is loaded and before IAT is resolved.
class MOZ_TRIVIAL_CTOR_DTOR Kernel32ExportsSolver final
: public interceptor::MMPolicyInProcessEarlyStage::Kernel32Exports {
enum class State {
Uninitialized,
Initialized,
Resolved,
} mState;
static ULONG NTAPI ResolveOnce(PRTL_RUN_ONCE aRunOnce, PVOID aParameter,
PVOID*);
void ResolveInternal();
public:
Kernel32ExportsSolver() = default;
Kernel32ExportsSolver(const Kernel32ExportsSolver&) = delete;
Kernel32ExportsSolver(Kernel32ExportsSolver&&) = delete;
Kernel32ExportsSolver& operator=(const Kernel32ExportsSolver&) = delete;
Kernel32ExportsSolver& operator=(Kernel32ExportsSolver&&) = delete;
bool IsInitialized() const;
bool IsResolved() const;
void Init();
void Resolve(RTL_RUN_ONCE& aRunOnce);
};
// This class manages a section which is created in the launcher process and
// mapped in the browser process and the sandboxed processes. The section's
// layout is represented as SharedSection::Layout.
//
// (1) Kernel32's functions required for MMPolicyInProcessEarlyStage
// Formatted as Kernel32ExportsSolver.
//
// (2) Array of NT paths of the executable's dependent modules
// Formatted as a null-delimited wide-character string set ending with
// an empty string.
//
// +--------------------------------------------------------------+
// | (1) | FlushInstructionCache |
// | | GetModuleHandleW |
// | | GetSystemInfo |
// | | VirtualProtect |
// | | State [Uninitialized|Initialized|Resolved] |
// +--------------------------------------------------------------+
// | (2) | L"NT path 1" |
// | | L"NT path 2" |
// | | ... |
// | | L"" |
// +--------------------------------------------------------------+
class MOZ_TRIVIAL_CTOR_DTOR SharedSection final {
// As we define a global variable of this class and use it in our blocklist
// which is excuted in a process's early stage. If we have a complex dtor,
// the static initializer tries to register that dtor with onexit() of
// ucrtbase.dll which is not loaded yet, resulting in crash. Thus, we have
// a raw handle and a pointer as a static variable and manually release them
// by calling Reset() where possible.
static HANDLE sSectionHandle;
static void* sWriteCopyView;
static constexpr size_t kSharedViewSize = 0x1000;
public:
struct Layout final {
Kernel32ExportsSolver mK32Exports;
wchar_t mModulePathArray[1];
Layout() = delete; // disallow instantiation
};
// Replace |sSectionHandle| with a given handle.
static void Reset(HANDLE aNewSecionObject = sSectionHandle);
// Replace |sSectionHandle| with a new readonly handle.
static void ConvertToReadOnly();
// Create a new writable section and initialize the Kernel32ExportsSolver
// part.
static LauncherVoidResult Init(const nt::PEHeaders& aPEHeaders);
// Append a new string to the |sSectionHandle|
static LauncherVoidResult AddDepenentModule(PCUNICODE_STRING aNtPath);
// Map |sSectionHandle| to a copy-on-write page and return its address.
static LauncherResult<Layout*> GetView();
// Transfer |sSectionHandle| to a process associated with |aTransferMgr|.
static LauncherVoidResult TransferHandle(
nt::CrossExecTransferManager& aTransferMgr, DWORD aDesiredAccess,
HANDLE* aDestinationAddress = &sSectionHandle);
};
extern SharedSection gSharedSection;
extern RTL_RUN_ONCE gK32ExportsResolveOnce;
} // namespace freestanding
} // namespace mozilla
#endif // mozilla_freestanding_SharedSection_h
|