This patch introduces a class `CrossExecTransferManager` to manage the data
transfer from the current process to a remote process via `WriteProcessMemory`.
The class also encapsulates a logic to bridge the gap between two executable's
imagebase.
Differential Revision: https://phabricator.services.mozilla.com/D94652
The earlier fix ea452bb92e6a proved the executable's imagebase in a child
process is not always the same as the local imagebase. This patch applies
the new approach to retieve the imagebase from a handle to all channels.
Interestingly, we observed the launcher failures at `VirtualProtectEx` only
when launching a sandboxed process, not when launching the browser process.
In the long term, we may need to take care of all `WriteProcessMemory` calls
for a child process for greater safety, but given that observation, this
patch only updates `RestoreImportDirectory` and `InitializeDllBlocklistOOP`.
Differential Revision: https://phabricator.services.mozilla.com/D90316
Our data indicates when the browser process populates a newly-created child process,
`VirtualProtectEx` may fail with `ERROR_INVALID_ADDRESS` for some unknown reason.
One possible cause is the parameter `aRemoteExeImage` of `RestoreImportDirectory`
was wrong i.e. pointing to an invalid address. We simply pass the local process's
imagebase as `aRemoteExeImage` based on the assumption that the same executable is
mapped onto the same address in a different process, but it may not be guaranteed.
To deal with that potential case, we could retrieve a correct imagebase from the handle
of a remote process as we do for the plugin process. Since we're not so sure about
the root cause or the effectiveness of this fix, we run it only when the first
attempt to `VirtualProtectEx` failed in Nightly. Once it's confirmed, we promote this
to a permanent fix.
Differential Revision: https://phabricator.services.mozilla.com/D89502
This patch adds a boolean field `mIsDependent` indicating whether a module was
loaded via the executable's Import Directory Table or not.
This patch also partially reverts Bug 1587539, moving a logic to detect Import
Directory tampering to `PEHeaders`'s ctor. With this, we can skip generating
a map of the executable's dependent modules if no tampering is detected.
Differential Revision: https://phabricator.services.mozilla.com/D66274
This patch adds a function to get an exported function in a remote process.
We need this implementation to address Bug 1604008, Bug 1608645, and Bug 1610790.
When `WindowsDllInterceptor` detours a function in a remote process, we used the
native `GetProcAddress` locally, and then detours the returned address in the
target process. The problem is if the caller's export table was modified, the
address returned from `GetProcAddress` might be invalid in the target process,
which is Bug 1604008.
I implemented `GetProcAddress` depending on both local and remote process image,
but it caused two regressions Bug 1608645 and Bug 1610790 because multiple
applications modify firefox's export table in multiple ways, such as replacing
an entry of EAT, replacing an RVA to Export section, or etc.
With this patch, we can use `PEExportSection<MMPolicy>::GetProcAddress` to get
an exported function in a remote process without relying on any local data so
that it's not impacted by modification of the local export table.
Differential Revision: https://phabricator.services.mozilla.com//D62315
Depends on D62314
This patch adds a function to get an exported function in a remote process.
We need this implementation to address Bug 1604008, Bug 1608645, and Bug 1610790.
When `WindowsDllInterceptor` detours a function in a remote process, we used the
native `GetProcAddress` locally, and then detours the returned address in the
target process. The problem is if the caller's export table was modified, the
address returned from `GetProcAddress` might be invalid in the target process,
which is Bug 1604008.
I implemented `GetProcAddress` depending on both local and remote process image,
but it caused two regressions Bug 1608645 and Bug 1610790 because multiple
applications modify firefox's export table in multiple ways, such as replacing
an entry of EAT, replacing an RVA to Export section, or etc.
With this patch, we can use `PEExportSection<MMPolicy>::GetProcAddress` to get
an exported function in a remote process without relying on any local data so
that it's not impacted by modification of the local export table.
Differential Revision: https://phabricator.services.mozilla.com/D62315
Depends on D62314
--HG--
extra : rebase_source : 3088f5997a2097ef22ce8567783375e5f7866ab2
Some applications tamper Import Directory entry of a loaded executable image
to pretend static dependency on their module. We have `RestoreImportDirectory`
to revert it in the browser process. If tampering happened in the launcher
process, however, we failed to get an IAT thunk address via `GetIATThunksForModule`
because it could be located outside the mapped image.
With this patch, we skip bounds check in `GetIATThunksForModule` if we detect
tampering in the launcher process. We can proceed safely because it's expected
that Import Directory is still valid though it's located outside.
Differential Revision: https://phabricator.services.mozilla.com/D49690
--HG--
extra : moz-landing-system : lando
`WindowsErrorResult` is a class to hold either a value or a Windows error
code based on the `Result` template. We also have `LauncherResult` for the
same purpose, which was introduced as a part of the launcher process feature
afterward. The difference is `LauncherResult` holds a filename and line
number along with an error code.
This patch integrates LauncherResult.h into WinHeaderOnlyUtils.h so that we
can use `LauncherResult` more broadly.
Differential Revision: https://phabricator.services.mozilla.com/D44512
--HG--
extra : moz-landing-system : lando