Bug 1603974 - Part 5: Introduce WindowsDllEntryPointInterceptor. r=mhowell

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 commit is contained in:
Toshihito Kikuchi 2020-04-08 14:27:02 +00:00
parent b01c4ba875
commit c0c91e1726
3 changed files with 48 additions and 0 deletions

View File

@ -764,6 +764,12 @@ class MOZ_RAII PEHeaders final {
void SetImportDirectoryTampered() { mIsImportDirectoryTampered = true; }
FARPROC GetEntryPoint() const {
// Use the unchecked version because the entrypoint may be tampered.
return RVAToPtrUnchecked<FARPROC>(
mPeHeader->OptionalHeader.AddressOfEntryPoint);
}
private:
enum class BoundsCheckPolicy { Default, Skip };

View File

@ -100,6 +100,21 @@ class WindowsDllDetourPatcherPrimitive {
const WindowsDllDetourPatcherPrimitive&) = delete;
WindowsDllDetourPatcherPrimitive& operator=(
WindowsDllDetourPatcherPrimitive&&) = delete;
bool AddIrreversibleHook(const MMPolicyT& aMMPolicy, FARPROC aTargetFn,
intptr_t aHookDest) {
ReadOnlyTargetFunction<MMPolicyT> targetReadOnly(aMMPolicy, aTargetFn);
WritableTargetFunction<MMPolicyT> targetWritable(
targetReadOnly.Promote(GetWorstCaseRequiredBytesToPatch()));
if (!targetWritable) {
return false;
}
ApplyDefaultPatch(targetWritable, aHookDest);
return targetWritable.Commit();
}
};
template <typename VMPolicy>

View File

@ -717,6 +717,33 @@ class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS
FuncPtrT mOrigFunc;
};
/**
* This class applies an irreversible patch to jump to a target function
* without backing up the original function.
*/
class WindowsDllEntryPointInterceptor final {
using DllMainFn = BOOL(WINAPI*)(HINSTANCE, DWORD, LPVOID);
using MMPolicyT = MMPolicyInProcessEarlyStage;
MMPolicyT mMMPolicy;
public:
explicit WindowsDllEntryPointInterceptor(
const MMPolicyT::Kernel32Exports& aK32Exports)
: mMMPolicy(aK32Exports) {}
bool Set(const nt::PEHeaders& aHeaders, DllMainFn aDestination) {
if (!aHeaders) {
return false;
}
WindowsDllDetourPatcherPrimitive<MMPolicyT> patcher;
return patcher.AddIrreversibleHook(
mMMPolicy, aHeaders.GetEntryPoint(),
reinterpret_cast<uintptr_t>(aDestination));
}
};
} // namespace interceptor
using WindowsDllInterceptor = interceptor::WindowsDllInterceptor<>;