In Win7 and later, some exported functions in kernel32.dll are just a stub
jumping to a function in kernelbase.dll. After the fix for Bug 1642626,
our detour resolves such a stub in kernel32.dll and detours a corresponding function in
kernelbase.dll. This new behavior caused a problem in Win8 when we detour
`DuplicateHandle` because our detour cannot handle the assembly pattern of
`KERNELBASE!DuplicateHandle`.
Win8's `KERNELBASE!DuplicateHandle` has jump instructions whose destination is
within the region where we move instructions to a trampoline.
In the example below, the address `000007f954ad271c` is a destination of the
`JMP` instructions, but when we detour `KERNELBASE!DuplicateHandle`, we move
the original instructions to a trampoline, and that address will point to
an invalid instruction, jumping to which address causes a crash.
A proposed fix is to detour `KERNEL32!DuplicateHandle` without resolving redirection,
that is the behavior before bug 1642626.
```
KERNEL32!DuplicateHandle:
000007f9`54cd2d5c ff2556b61100 jmp qword ptr [KERNEL32!_imp_DuplicateHandle] --> KERNELBASE!DuplicateHandle
```
```
KERNELBASE!DuplicateHandle:
000007f9`54ad2710 4883ec48 sub rsp,48h
000007f9`54ad2714 4c8bd1 mov r10,rcx
000007f9`54ad2717 83faf4 cmp edx,0FFFFFFF4h
000007f9`54ad271a 733b jae KERNELBASE!DuplicateHandle+0x43 (000007f9`54ad2757)
000007f9`54ad271c 8b842480000000 mov eax,dword ptr [rsp+80h]
...
000007f9`54b8f0de 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f0e7 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f0eb 488b5220 mov rdx,qword ptr [rdx+20h]
000007f9`54b8f0ef e92836f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
000007f9`54b8f0f4 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f0fd 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f101 488b5228 mov rdx,qword ptr [rdx+28h]
000007f9`54b8f105 e91236f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
000007f9`54b8f10a 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f113 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f117 488b5230 mov rdx,qword ptr [rdx+30h]
000007f9`54b8f11b e9fc35f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
```
Differential Revision: https://phabricator.services.mozilla.com/D88136
Hopefully the comments in the actual code are enough to explain what is going
on here.
NOTE: this patch does not represent a finished skeleton UI. There are some
questions in comments within the code, and generally I'm seeking feedback on
whether the overall approach seems sane or not. Gijs, I'm including you for
feedback on whether you think this is maintainable by more frontend-oriented
folks, and Molly, I'm including you for feedback on whether the justification
for writing to a raw pixel buffer seems sound or not, and a general review of
the approach.
Differential Revision: https://phabricator.services.mozilla.com/D86447
See bug for justification. This patch aims to display a blank window prior to
loading/prefetching xul.dll. It also has a placeholder for drawing a
skeleton UI into that window. Note that this is disabled by default based on
a registry value, as there are still kinks to work out (for instance, what
happens if we aren't actually going to display a window, because, say, Firefox
is already running.) This just gives a basic implementation to dogfood, and
facilitates distributing work across multiple contributors.
Onto the details. The patch achieves its goal by creating a window and
assigning its handle to a static variable, which will be consumed inside
nsWindow::Create by the first toplevel window we want to make. nsWindow::Create
will take ownership of the window handle, restyle it to its own liking, and
then proceed as if everything is normal and it had created the window itself.
Differential Revision: https://phabricator.services.mozilla.com/D86263
This change makes everything compile and presumably has some tiny effect on
performance. We also take the opportunity to ensure that the compiler won't
optimize out our inline asm by making the asm volatile and indicating that
it touches memory.
Differential Revision: https://phabricator.services.mozilla.com/D86594
After the fix for bug 1642626, we need to detour `KERNELBASE!CloseHandle`
instead of K32's stub, which contains `JAE rel32`.
I also found a mistake in the fix for bug 1642626. When we put a conditional
jump in a trampoline, we need to reverse a condition, but the JAE case mistakenly
filled JAE straight. This patch corrects it to filling JB.
Differential Revision: https://phabricator.services.mozilla.com/D85477
CLOSED TREE
We don't need these macros anymore, for two reasons:
1. We have static analysis to provide the same sort of checks via `MOZ_RAII`
and friends.
2. clang now warns for the "temporary that should have been a declaration" case.
The extra requirements on class construction also show up during debug tests
as performance problems.
This change was automated by using the following sed script:
```
# Remove declarations in classes.
/MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER/d
/MOZ_GUARD_OBJECT_NOTIFIER_INIT/d
# Remove individual macros, carefully.
{
# We don't have to worry about substrings here because the closing
# parenthesis "anchors" the match.
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)/)/g;
# Remove the longer identifier first.
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT//g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM//g;
}
# Remove the actual include.
\@# *include "mozilla/GuardObjects.h"@d
```
and running:
```
find . -name \*.cpp -o -name \*.h | grep -v 'GuardObjects.h' |xargs sed -i -f script 2>/dev/null
mach clang-format
```
Differential Revision: https://phabricator.services.mozilla.com/D85168
We don't need these macros anymore, for two reasons:
1. We have static analysis to provide the same sort of checks via `MOZ_RAII`
and friends.
2. clang now warns for the "temporary that should have been a declaration" case.
The extra requirements on class construction also show up during debug tests
as performance problems.
This change was automated by using the following sed script:
```
# Remove declarations in classes.
/MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER/d
/MOZ_GUARD_OBJECT_NOTIFIER_INIT/d
# Remove individual macros, carefully.
{
# We don't have to worry about substrings here because the closing
# parenthesis "anchors" the match.
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)/)/g;
# Remove the longer identifier first.
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT//g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM//g;
}
# Remove the actual include.
\@# *include "mozilla/GuardObjects.h"@d
```
and running:
```
find . -name \*.cpp -o -name \*.h | grep -v 'GuardObjects.h' |xargs sed -i -f script 2>/dev/null
mach clang-format
```
Differential Revision: https://phabricator.services.mozilla.com/D85168
This requires a workaround for the use of __wrap_dladdr, which can't be
used in logalloc-replay. The workaround involves making __wrap_dladdr
expand to dladdr, but that makes the definition ElfLinker.h conflict
with the one in the Android system headers, so we change it to match,
and adjust ElfLinker.cpp accordingly.
And while here, fix the condition in mozglue/misc to match the condition
around including Linker.h in StackWalk.cpp itself.
Differential Revision: https://phabricator.services.mozilla.com/D82648
AVG AntiVirus hooks ntdll!NtMapViewOfSection by planting two JMP instructions,
jumping to a trampoline area first, then jumping to aswhook.dll.
```
ntdll!NtMapViewOfSection:
00007ffa`6d77c560 e9d33cfebf jmp 00007ffa`2d760238
00007ffa`2d760238 ff25f2ffffff jmp qword ptr [00007ffa`2d760230] --> 00007ffa`541e2ad0
aswhook+0x2ad0:
00007ffa`541e2ad0 4055 push rbp
00007ffa`541e2ad2 53 push rbx
00007ffa`541e2ad3 56 push rsi
```
With this patch, our detour can detour on top of that pattern. The first part is
to remove the MEM_IMAGE check from IsPageAccessible. The second part is to introduce
a loop in ResolveRedirectedAddress to resolve a chain of jumps.
Differential Revision: https://phabricator.services.mozilla.com/D81582
This patch moves the logics of jump detection from ResolveRedirectedAddress to
ReadOnlyTargetFunction to simplify ReadOnlyTargetFunction.
Differential Revision: https://phabricator.services.mozilla.com/D81580
This header is using `MOZ_RAII` and `MFBT_ABI` from `Attributes.h` and
`Types.h`, respectively, so it should include those headers.
Differential Revision: https://phabricator.services.mozilla.com/D81600
If EAF+ is enabled for firefox.exe, the process does not launch because we parse
the PE headers of ntdll.dll at startup, which is prohibited by EAF+.
With this patch, we skip two operations when EAF+ is enabled.
The first one is to cache ntdll's IAT at startup. Because EAF+ is expected to
prevent an injected module from parsing PE headers and modifying IAT, we can skip
this caching safely.
The second one is to load ntdll's debug information for the profiler. With this
patch, the profiler's callstack will not show a raw address instead of a symbol
name. It's a bad side effect, but much better than startup crash.
Differential Revision: https://phabricator.services.mozilla.com/D76959
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
Also move MOZ_MUST_USE before function declarations' specifiers and return type. While clang and gcc's __attribute__((warn_unused_result)) can appear before, between, or after function specifiers and return types, the [[nodiscard]] attribute must precede the function specifiers.
Differential Revision: https://phabricator.services.mozilla.com/D70631
--HG--
extra : moz-landing-system : lando
This commit removes `test_fix_stack_using_bpsyms.py`. That test can't easily be
modified to work with `fix_stacks.py` because it relies on internal
implementation details of `fix_stack_using_bpsym.py`. The unit testing done in
the `fix-stacks` repo provides test coverage that is as good or better.
Differential Revision: https://phabricator.services.mozilla.com/D66924
--HG--
extra : moz-landing-system : lando
Please double check that I am using this correctly. I believe we are
seeing the crash in the linked bug because we are not handling hardware
faults when reading from the memory mapped file. This patch just wraps
all accesses in the MMAP_FAULT_HANDLER_ macros.
Depends on D53042
Differential Revision: https://phabricator.services.mozilla.com/D53043
--HG--
rename : modules/libjar/MmapFaultHandler.cpp => mozglue/misc/MmapFaultHandler.cpp
rename : modules/libjar/MmapFaultHandler.h => mozglue/misc/MmapFaultHandler.h
extra : moz-landing-system : lando
This patch introduces `Kernel32ExportsSolver` which calculates RVAs of
kernel32's functions and transfers them to a target process, where the
transferred RVAs are resolved into function addresses.
Depends on D68346
Differential Revision: https://phabricator.services.mozilla.com/D68347
--HG--
extra : moz-landing-system : lando
This patch introduces a new DLL interceptor `WindowsDllEntryPointInterceptor`
which applies a hook to a target function without backing up the original
function code.
Depends on D68345
Differential Revision: https://phabricator.services.mozilla.com/D68346
--HG--
extra : moz-landing-system : lando
This patch introduces a new policy `MMPolicyInProcessEarlyStage` which does
not consume any functions imported from kernel32.dll so that we can use it
in a process's early stage i.e. before IAT is resolved.
Depends on D68344
Differential Revision: https://phabricator.services.mozilla.com/D68345
--HG--
extra : moz-landing-system : lando
`WindowsDllDetourPatcher::CreateTrampoline` does not only create a trampoline
region but also applies a patch on an original function. This patch extracts
the patching part as separate functions.
Differential Revision: https://phabricator.services.mozilla.com/D68344
--HG--
extra : moz-landing-system : lando
This patch moves the instantiation of `PEHeaders` from `CheckBlockInfo` to
`IsDllAllowed` so that `IsDllAllowed` can use an instance of `PEHeaders`.
Depends on D68342
Differential Revision: https://phabricator.services.mozilla.com/D68343
--HG--
extra : moz-landing-system : lando
This patch introduces `nt::VirtualQuery` which consumes only ntdll's functions
to reduce dependency in `MMPolicy` on kernel32.dll. With this, `MMPolicy` still
depends on kernel32.dll, that will be solved by a coming patch.
Differential Revision: https://phabricator.services.mozilla.com/D68342
--HG--
extra : moz-landing-system : lando
This patch introduces `Kernel32ExportsSolver` which calculates RVAs of
kernel32's functions and transfers them to a target process, where the
transferred RVAs are resolved into function addresses.
Depends on D68346
Differential Revision: https://phabricator.services.mozilla.com/D68347
--HG--
extra : moz-landing-system : lando
This patch introduces a new DLL interceptor `WindowsDllEntryPointInterceptor`
which applies a hook to a target function without backing up the original
function code.
Depends on D68345
Differential Revision: https://phabricator.services.mozilla.com/D68346
--HG--
extra : moz-landing-system : lando
This patch introduces a new policy `MMPolicyInProcessEarlyStage` which does
not consume any functions imported from kernel32.dll so that we can use it
in a process's early stage i.e. before IAT is resolved.
Depends on D68344
Differential Revision: https://phabricator.services.mozilla.com/D68345
--HG--
extra : moz-landing-system : lando
`WindowsDllDetourPatcher::CreateTrampoline` does not only create a trampoline
region but also applies a patch on an original function. This patch extracts
the patching part as separate functions.
Depends on D68343
Differential Revision: https://phabricator.services.mozilla.com/D68344
--HG--
extra : moz-landing-system : lando
This patch moves the instantiation of `PEHeaders` from `CheckBlockInfo` to
`IsDllAllowed` so that `IsDllAllowed` can use an instance of `PEHeaders`.
Depends on D68342
Differential Revision: https://phabricator.services.mozilla.com/D68343
--HG--
extra : moz-landing-system : lando
This patch introduces `nt::VirtualQuery` which consumes only ntdll's functions
to reduce dependency in `MMPolicy` on kernel32.dll. With this, `MMPolicy` still
depends on kernel32.dll, that will be solved by a coming patch.
Differential Revision: https://phabricator.services.mozilla.com/D68342
--HG--
extra : moz-landing-system : lando
When our detour processes instructions, we pass `ReadOnlyTargetFunction` to
`CountPrefixBytes` to determine whether a lock prefix exists or not.
In that case, we don't need to pass both `ReadOnlyTargetFunction` and an offset
as a parameter because `ReadOnlyTargetFunction` has an offset as a member.
Differential Revision: https://phabricator.services.mozilla.com/D69360
--HG--
extra : moz-landing-system : lando
Please double check that I am using this correctly. I believe we are
seeing the crash in the linked bug because we are not handling hardware
faults when reading from the memory mapped file. This patch just wraps
all accesses in the MMAP_FAULT_HANDLER_ macros.
Depends on D53042
Differential Revision: https://phabricator.services.mozilla.com/D53043
--HG--
rename : modules/libjar/MmapFaultHandler.cpp => mozglue/misc/MmapFaultHandler.cpp
rename : modules/libjar/MmapFaultHandler.h => mozglue/misc/MmapFaultHandler.h
extra : moz-landing-system : lando
Also adds missing includes in some files, these were previously only transivitely
included through mozilla/TypeTraits.h.
Differential Revision: https://phabricator.services.mozilla.com/D68561
--HG--
extra : moz-landing-system : lando