Impact: A recent bug report on the Mozilla Firefox issue tracker
(https://bugzilla.mozilla.org/show_bug.cgi?id=1798707) identifies a
crash in the Firefox browser caused by an invalid memory access
performed by ExplorerPatcher (https://crash-stats.mozilla.org/signature/?signature=explorerpatcher.amd64.dll%20|%20%3Cunknown%20in%20Windows.UI.FileExplorer.dll%3E%20|%20explorerpatcher.amd64.dll%20|%20RtlpFindEntry%20|%20RtlpAllocateHeap%20|%20RtlpAllocateHeapInternal%20|%20explorerpatcher.amd64.dll%20|%20RtlDosApplyFileIsolationRedirection_Ustr%20|%20LdrpApplyFileNameRed...&date=%3E%3D2022-11-02T20%3A44%3A00.000Z&date=%3C2022-11-16T20%3A44%3A00.000Z).
This might happen only when the "Register as shell extension: option
is used, and ExplorerPatcher is injected in other processes. Testing
was unable to reproduce the issue, but looking on the crash logs it
was determined that it likely happens in "VnPatchDelayIAT", where
the memory is patched regardless of whether the protection level
actually succeeded changing or not. The call is suspected to fail
when certain antivirus solutions are used, although a clear test case
with this scenario could not be determined.
Also, code review determined that a race condition might happen in both
"VnPatchIAT" and "VnPatchDelayIAT", where some other thread might
unload the module while the code works with it, attempting to patch the
requested function.
Description: The issue has been addressed by improved checks and
ensuring the module is not unloaded while the functions work with it.
The program only attempts to patch the memory if the previous
protection change call actually succeeded. Additionally, the module
reference count is increased prior to working with it when attempting
the patch, in order to prevent other threads from successfully
unloading it. The proposed changes should harden the code against
unexpected behavior and should address the crashes experienced when
the code runs in other processes, including Firefox.
Changes in this version:
* [Store layout window flags in single variable](633fb2c51a)
* [Use external variable to detect if desktop is foreground](4b9ff84436)
* [Fix regression when detecting foreground window changes](8ab7a45162)
* [Draw DWM-like placeholder when window has zero width or height](764a2913b4)
* [Enforce a minimum size for a window rectangle](bc8b04e451)