This is a pretty straightforward patch; we add `WindowsIATPatcher` to
implement the actual IAT patching, and use a partial specialization of
`FuncHook` to account for the underlying differences in implementation vs our
existing interceptor code.
Differential Revision: https://phabricator.services.mozilla.com/D57831
--HG--
extra : moz-landing-system : lando
Strictly speaking, the import descriptor includes more than just the IAT,
so renaming this method to reflect that.
Differential Revision: https://phabricator.services.mozilla.com/D57830
--HG--
extra : moz-landing-system : lando
This is a pretty straightforward patch; we add `WindowsIATPatcher` to
implement the actual IAT patching, and use a partial specialization of
`FuncHook` to account for the underlying differences in implementation vs our
existing interceptor code.
Differential Revision: https://phabricator.services.mozilla.com/D57831
--HG--
extra : moz-landing-system : lando
Strictly speaking, the import descriptor includes more than just the IAT,
so renaming this method to reflect that.
Differential Revision: https://phabricator.services.mozilla.com/D57830
--HG--
extra : moz-landing-system : lando
This changeset is a simple find and replace of `MOZ_FALLTHROUGH` and `[[fallthrough]]`.
Unfortunately, the MOZ_FALLTHROUGH_ASSERT macro (to assert on case fallthrough in debug builds) is still necessary after switching from [[clang::fallthrough]] to [[fallthrough]] because:
* MOZ_ASSERT(false) followed by [[fallthrough]] triggers a -Wunreachable-code warning in DEBUG builds
* but MOZ_ASSERT(false) without [[fallthrough]] triggers a -Wimplicit-fallthrough warning in NDEBUG builds.
Differential Revision: https://phabricator.services.mozilla.com/D56440
--HG--
extra : moz-landing-system : lando
mov byte ptr support was added in bug 1382251 but did not properly count the instruction size. It was missing the 1-byte operand, which causes the rest of the trampoline to be garbage.
Differential Revision: https://phabricator.services.mozilla.com/D55744
--HG--
extra : moz-landing-system : lando
CloseHandle has a jump followed by enough `nop`s to fit a 10-byte patch but not enough to fit the default 13-byte patch when running Windows 8 or 8.1. This patch tells the interceptor to use a 10-byte patch on those OSs.
Differential Revision: https://phabricator.services.mozilla.com/D55535
--HG--
extra : moz-landing-system : lando
For now, there is no flag to actually allow it, but this is the
code-side changes to allow the linker being disabled.
Differential Revision: https://phabricator.services.mozilla.com/D54074
--HG--
extra : moz-landing-system : lando
This patch adds the following pattern to our x64 detour so that we can hook APIs
even though a target is already detoured by another application.
```
mov rax, imm64
push rax
ret
```
We already have `PatchIfTargetIsRecognizedTrampoline` to detour the pattern
`mov; jmp`. There is another variation using `push rax;ret` to jump.
Differential Revision: https://phabricator.services.mozilla.com/D53877
--HG--
extra : moz-landing-system : lando
`patched_NtMapViewOfSection` uses the process default heap to copy a string.
However, `patched_NtMapViewOfSection` can be invoked even before the process
heap is initialized. One example we found is Windows Defender's EAF, with
which "verifier.dll" is loaded before the process heap is initialized.
This patch adds a check whether the heap is initialized or not in
`patched_NtMapViewOfSection` and `NativeNtBlockSet::Add`. This also minimizes
the usage of the heap, i.e. not copying a string when we block a dll.
Differential Revision: https://phabricator.services.mozilla.com/D51028
--HG--
extra : moz-landing-system : lando
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
Defines an android-only version of nsTraceRefcnt::WalkTheStack that takes a function callback, which outputs the stack frame buffer to `__android_log_print`. Also uses `__wrap_dladdr` in MozDescribeCodeAddress, which outputs slightly more informative data for the stack trace (instead of instances of '???/??? [???]').
Differential Revision: https://phabricator.services.mozilla.com/D46868
--HG--
extra : moz-landing-system : lando
Defines an android-only version of nsTraceRefcnt::WalkTheStack that takes a function callback, which outputs the stack frame buffer to `__android_log_print`. Also uses `__wrap_dladdr` in MozDescribeCodeAddress, which outputs slightly more informative data for the stack trace (instead of instances of '???/??? [???]').
Differential Revision: https://phabricator.services.mozilla.com/D46868
--HG--
extra : moz-landing-system : lando
* At this point our DLL blocking infra is complicated enough that I decided to
bite the bullet and move all of this code out of `mozglue/build` and into its
own subdirectory, `mozglue/dllservices`.
* We delete the original `UntrustedDllsHandler` code which is now obsolete.
* We implement mozglue's `LoaderObserver`:
** When this observer registers itself with the launcher process API, it
receives a vector containing all saved records of loaded DLLs that happened
until that moment.
** This code handles profiler labels and stackwalking suppression.
** Once a load has completed, we either pass the load on to XUL for further
processing, or save it for later if XUL is not initialized yet.
* mozglue has its own `ModuleLoadFrame` implementation for the legacy blocklist.
* `DllServicesBase` is updated to support the new interfaces.
* We implement `FallbackLoaderAPI` for `plugin-container`, `xpcshell`, and
any other non-`firefox` processes that do not have a launcher process
providing a loader API.
* We add some wide to UTF8 conversion functions.
Depends on D43157
Differential Revision: https://phabricator.services.mozilla.com/D43158
--HG--
rename : mozglue/build/Authenticode.cpp => mozglue/dllservices/Authenticode.cpp
rename : mozglue/build/Authenticode.h => mozglue/dllservices/Authenticode.h
rename : browser/app/winlauncher/freestanding/LoaderAPIInterfaces.h => mozglue/dllservices/LoaderAPIInterfaces.h
rename : browser/app/winlauncher/freestanding/ModuleLoadInfo.h => mozglue/dllservices/ModuleLoadInfo.h
rename : browser/app/winlauncher/NtLoaderAPI.h => mozglue/dllservices/NtLoaderAPI.h
rename : mozglue/build/WindowsDllBlocklist.cpp => mozglue/dllservices/WindowsDllBlocklist.cpp
rename : mozglue/build/WindowsDllBlocklist.h => mozglue/dllservices/WindowsDllBlocklist.h
rename : mozglue/build/WindowsDllBlocklistCommon.h => mozglue/dllservices/WindowsDllBlocklistCommon.h
rename : mozglue/build/WindowsDllBlocklistDefs.in => mozglue/dllservices/WindowsDllBlocklistDefs.in
rename : mozglue/build/WindowsDllServices.h => mozglue/dllservices/WindowsDllServices.h
rename : mozglue/build/gen_dll_blocklist_defs.py => mozglue/dllservices/gen_dll_blocklist_defs.py
rename : mozglue/build/moz.build => mozglue/dllservices/moz.build
rename : mozglue/build/MozglueUtils.h => mozglue/misc/WinUtils.h
extra : moz-landing-system : lando
This patch adds the following:
* The `AllocatedUnicodeString` class which encapsulates a `UNICODE_STRING` and
owns its buffer. The buffers are null-terminated so that they may be used as
C-style strings without modification.
** We do not allow either creation or copying within XUL
* `RtlGetCurrentThreadId` and a test to validate it, so that we may obtain the
current thread ID directly from the `TEB` when we do not yet have access to
kernel32.
* An implementation of `SRWLock` that uses Rtl instead of Win32 so that we may
use them before we have access to Win32 DLLs.
* A memory allocation policy that uses Rtl heap functions so that we may use
MFBT `Vector` in code that might not yet have access to Win32 heap functions.
Differential Revision: https://phabricator.services.mozilla.com/D43155
--HG--
extra : moz-landing-system : lando
* At this point our DLL blocking infra is complicated enough that I decided to
bite the bullet and move all of this code out of `mozglue/build` and into its
own subdirectory, `mozglue/dllservices`.
* We delete the original `UntrustedDllsHandler` code which is now obsolete.
* We implement mozglue's `LoaderObserver`:
** When this observer registers itself with the launcher process API, it
receives a vector containing all saved records of loaded DLLs that happened
until that moment.
** This code handles profiler labels and stackwalking suppression.
** Once a load has completed, we either pass the load on to XUL for further
processing, or save it for later if XUL is not initialized yet.
* mozglue has its own `ModuleLoadFrame` implementation for the legacy blocklist.
* `DllServicesBase` is updated to support the new interfaces.
* We implement `FallbackLoaderAPI` for `plugin-container`, `xpcshell`, and
any other non-`firefox` processes that do not have a launcher process
providing a loader API.
* We add some wide to UTF8 conversion functions.
Differential Revision: https://phabricator.services.mozilla.com/D43158
--HG--
rename : mozglue/build/Authenticode.cpp => mozglue/dllservices/Authenticode.cpp
rename : mozglue/build/Authenticode.h => mozglue/dllservices/Authenticode.h
rename : mozglue/build/WindowsDllBlocklist.cpp => mozglue/dllservices/WindowsDllBlocklist.cpp
rename : mozglue/build/WindowsDllBlocklist.h => mozglue/dllservices/WindowsDllBlocklist.h
rename : mozglue/build/WindowsDllBlocklistCommon.h => mozglue/dllservices/WindowsDllBlocklistCommon.h
rename : mozglue/build/WindowsDllBlocklistDefs.in => mozglue/dllservices/WindowsDllBlocklistDefs.in
rename : mozglue/build/WindowsDllServices.h => mozglue/dllservices/WindowsDllServices.h
rename : mozglue/build/gen_dll_blocklist_defs.py => mozglue/dllservices/gen_dll_blocklist_defs.py
rename : mozglue/build/moz.build => mozglue/dllservices/moz.build
rename : mozglue/build/MozglueUtils.h => mozglue/misc/WinUtils.h
extra : moz-landing-system : lando
This patch adds the following:
* The `AllocatedUnicodeString` class which encapsulates a `UNICODE_STRING` and
owns its buffer. The buffers are null-terminated so that they may be used as
C-style strings without modification.
** We do not allow either creation or copying within XUL
* `RtlGetCurrentThreadId` and a test to validate it, so that we may obtain the
current thread ID directly from the `TEB` when we do not yet have access to
kernel32.
* An implementation of `SRWLock` that uses Rtl instead of Win32 so that we may
use them before we have access to Win32 DLLs.
* A memory allocation policy that uses Rtl heap functions so that we may use
MFBT `Vector` in code that might not yet have access to Win32 heap functions.
Differential Revision: https://phabricator.services.mozilla.com/D43155
--HG--
extra : moz-landing-system : lando
* At this point our DLL blocking infra is complicated enough that I decided to
bite the bullet and move all of this code out of `mozglue/build` and into its
own subdirectory, `mozglue/dllservices`.
* We delete the original `UntrustedDllsHandler` code which is now obsolete.
* We implement mozglue's `LoaderObserver`:
** When this observer registers itself with the launcher process API, it
receives a vector containing all saved records of loaded DLLs that happened
until that moment.
** This code handles profiler labels and stackwalking suppression.
** Once a load has completed, we either pass the load on to XUL for further
processing, or save it for later if XUL is not initialized yet.
* mozglue has its own `ModuleLoadFrame` implementation for the legacy blocklist.
* `DllServicesBase` is updated to support the new interfaces.
* We implement `FallbackLoaderAPI` for `plugin-container`, `xpcshell`, and
any other non-`firefox` processes that do not have a launcher process
providing a loader API.
* We add some wide to UTF8 conversion functions.
Differential Revision: https://phabricator.services.mozilla.com/D43158
--HG--
rename : mozglue/build/Authenticode.cpp => mozglue/dllservices/Authenticode.cpp
rename : mozglue/build/Authenticode.h => mozglue/dllservices/Authenticode.h
rename : mozglue/build/WindowsDllBlocklist.cpp => mozglue/dllservices/WindowsDllBlocklist.cpp
rename : mozglue/build/WindowsDllBlocklist.h => mozglue/dllservices/WindowsDllBlocklist.h
rename : mozglue/build/WindowsDllBlocklistCommon.h => mozglue/dllservices/WindowsDllBlocklistCommon.h
rename : mozglue/build/WindowsDllBlocklistDefs.in => mozglue/dllservices/WindowsDllBlocklistDefs.in
rename : mozglue/build/WindowsDllServices.h => mozglue/dllservices/WindowsDllServices.h
rename : mozglue/build/gen_dll_blocklist_defs.py => mozglue/dllservices/gen_dll_blocklist_defs.py
rename : mozglue/build/moz.build => mozglue/dllservices/moz.build
rename : mozglue/build/MozglueUtils.h => mozglue/misc/WinUtils.h
extra : moz-landing-system : lando
This patch adds the following:
* The `AllocatedUnicodeString` class which encapsulates a `UNICODE_STRING` and
owns its buffer. The buffers are null-terminated so that they may be used as
C-style strings without modification.
** We do not allow either creation or copying within XUL
* `RtlGetCurrentThreadId` and a test to validate it, so that we may obtain the
current thread ID directly from the `TEB` when we do not yet have access to
kernel32.
* An implementation of `SRWLock` that uses Rtl instead of Win32 so that we may
use them before we have access to Win32 DLLs.
* A memory allocation policy that uses Rtl heap functions so that we may use
MFBT `Vector` in code that might not yet have access to Win32 heap functions.
Differential Revision: https://phabricator.services.mozilla.com/D43155
--HG--
extra : moz-landing-system : lando
This is showing up with hooks that are set both by the launcher process and by
the browser process when starting early DLL blocklist init on content processes:
* The browser's copy of mOrigFunc was set by the launcher process.
* The browser is setting a hook in the new child process, which writes to the
child's mOrigFunc.
* But FuncHookCrossProcess also writes that pointer to the browser's mOrigFunc,
thus corrupting the browser process's copy of the pointer.
For in-process hooks, we want to immediately write the stub pointer to its final
location; this is not an issue for cross-process hooks since the child process
is suspended when we do this and the parent process can't call the stub; there
is no possibility of a race.
Differential Revision: https://phabricator.services.mozilla.com/D46615
--HG--
extra : moz-landing-system : lando
* At this point our DLL blocking infra is complicated enough that I decided to
bite the bullet and move all of this code out of `mozglue/build` and into its
own subdirectory, `mozglue/dllservices`.
* We delete the original `UntrustedDllsHandler` code which is now obsolete.
* We implement mozglue's `LoaderObserver`:
** When this observer registers itself with the launcher process API, it
receives a vector containing all saved records of loaded DLLs that happened
until that moment.
** This code handles profiler labels and stackwalking suppression.
** Once a load has completed, we either pass the load on to XUL for further
processing, or save it for later if XUL is not initialized yet.
* mozglue has its own `ModuleLoadFrame` implementation for the legacy blocklist.
* `DllServicesBase` is updated to support the new interfaces.
* We implement `FallbackLoaderAPI` for `plugin-container`, `xpcshell`, and
any other non-`firefox` processes that do not have a launcher process
providing a loader API.
* We add some wide to UTF8 conversion functions.
Differential Revision: https://phabricator.services.mozilla.com/D43158
--HG--
rename : mozglue/build/Authenticode.cpp => mozglue/dllservices/Authenticode.cpp
rename : mozglue/build/Authenticode.h => mozglue/dllservices/Authenticode.h
rename : mozglue/build/WindowsDllBlocklist.cpp => mozglue/dllservices/WindowsDllBlocklist.cpp
rename : mozglue/build/WindowsDllBlocklist.h => mozglue/dllservices/WindowsDllBlocklist.h
rename : mozglue/build/WindowsDllBlocklistCommon.h => mozglue/dllservices/WindowsDllBlocklistCommon.h
rename : mozglue/build/WindowsDllBlocklistDefs.in => mozglue/dllservices/WindowsDllBlocklistDefs.in
rename : mozglue/build/WindowsDllServices.h => mozglue/dllservices/WindowsDllServices.h
rename : mozglue/build/gen_dll_blocklist_defs.py => mozglue/dllservices/gen_dll_blocklist_defs.py
rename : mozglue/build/moz.build => mozglue/dllservices/moz.build
rename : mozglue/build/MozglueUtils.h => mozglue/misc/WinUtils.h
extra : moz-landing-system : lando
This patch adds the following:
* The `AllocatedUnicodeString` class which encapsulates a `UNICODE_STRING` and
owns its buffer. The buffers are null-terminated so that they may be used as
C-style strings without modification.
** We do not allow either creation or copying within XUL
* `RtlGetCurrentThreadId` and a test to validate it, so that we may obtain the
current thread ID directly from the `TEB` when we do not yet have access to
kernel32.
* An implementation of `SRWLock` that uses Rtl instead of Win32 so that we may
use them before we have access to Win32 DLLs.
* A memory allocation policy that uses Rtl heap functions so that we may use
MFBT `Vector` in code that might not yet have access to Win32 heap functions.
Differential Revision: https://phabricator.services.mozilla.com/D43155
--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
Whereas previously MozDescribeCodeAddress would have handled demangling,
we need to explicitly do that from our new GetFunction method. The string we
generate is now more useful for the profiler to merge -- having dropped the
address in the previous patch, and the file & line number and library in this
patch.
While we're at it, try to demangle Rust symbols too.
Ideally we'd add Rust symbol handling to DemangleSymbol in
StackWalk.cpp, but that lives in mozglue, which currently cannot have
any Rust crate dependencies.
Differential Revision: https://phabricator.services.mozilla.com/D43142
--HG--
extra : moz-landing-system : lando
While mozglue continues to be the correct location for calling the affected
code in this patch, the calls requiring profiler labels will soon be
originating from firefox.exe via the launcher process.
mozglue will be supplying the launcher process with an interface that consists
of what are effectively "OnBeginDllLoad" and "OnEndDllLoad" callback
notifications; obviously an RAII class is not going to be useful for that case.
We still want to keep the RAII stuff around, however, since we still need it
for cases where we need to fall back to using the legacy DLL blocklist.
Differential Revision: https://phabricator.services.mozilla.com/D41807
--HG--
extra : moz-landing-system : lando
While mozglue continues to be the correct location for calling the affected
code in this patch, the calls requiring stackwalk suppression will soon be
originating from firefox.exe via the launcher process.
mozglue will be supplying the launcher process with an interface that consists
of what are effectively "OnBeginDllLoad" and "OnEndDllLoad" callback
notifications; obviously an RAII class is not going to be useful for that case.
We still want to keep the RAII stuff around, however, since we still need it
for cases where we need to fall back to using the legacy DLL blocklist.
Differential Revision: https://phabricator.services.mozilla.com/D41808
--HG--
extra : moz-landing-system : lando
This patch does two things:
1. We refactor the resolution of function pointer and return type so that we
may support additional calling conventions besides just __stdcall;
2. We refactor DynamicallyLinkedFunctionPtr into a base class, and create
StaticDynamicallyLinkedFunctionPtr to specifically handle the static local
use case.
Differential Revision: https://phabricator.services.mozilla.com/D40885
--HG--
extra : moz-landing-system : lando
Profilers will soon be able to set/reset entry&exit functions at different
times, but simultaneously other code may want to use AutoProfilerLabel, so we
need to make this all thread-safe.
All shared static information is now encapsulated in an RAII class that enforces
proper locking before giving access to this information.
Also added a "generation" count, so that if an AutoProfilerLabel is in-flight
when entry&exit functions are changed, the context given by the old entry
function will not be passed to a mismatched new exit function.
Differential Revision: https://phabricator.services.mozilla.com/D34807
--HG--
extra : moz-landing-system : lando
`ProfilingStack*` happens to be the information that the current Gecko Profiler
entry function wants to forward to the exit function, but AutoProfilerLabel does
not really need to know about that.
Changing it to `void*`, so that we can later use different entry/exit functions
that use different context types.
Differential Revision: https://phabricator.services.mozilla.com/D34806
--HG--
extra : moz-landing-system : lando
This patch modifies arm64 so that detours are peformed via two passes:
1. The first pass uses a null trampoline to count how many bytes are available
for patching the original function.
2. If we have >= 16 bytes to patch, we reuse existing trampoline space. If we
have less than 16 bytes to patch, we reserve trampoline space within 128MB
of the function, allowing for a 4 byte patch.
3. Then we recurse, this time using a real trampoline.
Note that we still do a single-pass on x86(-64).
Differential Revision: https://phabricator.services.mozilla.com/D32193
--HG--
extra : moz-landing-system : lando
A null trampoline is just a trampoline that is not backed by a VM reservation.
These are used for tracking the number of bytes that are needed to make a patch.
This patch also contains the changes needed to work with TrampolinePool.
Differential Revision: https://phabricator.services.mozilla.com/D32192
--HG--
extra : moz-landing-system : lando
VMSharingPolicyShared needs to become much smarter. This patch modifies that
policy to track different VM reservations and reuse them whenever possible.
We add TrampolinePools to abstract away the differences between VM policies
with respect to the caller who is making the reservation.
Differential Revision: https://phabricator.services.mozilla.com/D32191
--HG--
extra : moz-landing-system : lando
In order to support 4-byte patches on ARM64, we need to be able to reserve
trampoline space within +/- 128 MB of the beginning of a function.
These changes allow us to make such reservations using OS APIs when
available.
Differential Revision: https://phabricator.services.mozilla.com/D32190
--HG--
extra : moz-landing-system : lando