зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland on a CLOSED TREE
This commit is contained in:
Коммит
7543d11ee1
|
@ -150,18 +150,6 @@ class MOZ_TRIVIAL_CTOR_DTOR MMPolicyBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if defined(NIGHTLY_BUILD)
|
|
||||||
Maybe<DetourError> mLastError;
|
|
||||||
const Maybe<DetourError>& GetLastError() const { return mLastError; }
|
|
||||||
template <typename... Args>
|
|
||||||
void SetLastError(Args&&... aArgs) {
|
|
||||||
mLastError = Some(DetourError(std::forward<Args>(aArgs)...));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template <typename... Args>
|
|
||||||
void SetLastError(Args&&... aArgs) {}
|
|
||||||
#endif // defined(NIGHTLY_BUILD)
|
|
||||||
|
|
||||||
DWORD ComputeAllocationSize(const uint32_t aRequestedSize) const {
|
DWORD ComputeAllocationSize(const uint32_t aRequestedSize) const {
|
||||||
MOZ_ASSERT(aRequestedSize);
|
MOZ_ASSERT(aRequestedSize);
|
||||||
DWORD result = aRequestedSize;
|
DWORD result = aRequestedSize;
|
||||||
|
@ -309,17 +297,15 @@ class MOZ_TRIVIAL_CTOR_DTOR MMPolicyBase {
|
||||||
* large.
|
* large.
|
||||||
*/
|
*/
|
||||||
PVOID FindRegion(HANDLE aProcess, const size_t aDesiredBytesLen,
|
PVOID FindRegion(HANDLE aProcess, const size_t aDesiredBytesLen,
|
||||||
const uint8_t* aRangeMin, const uint8_t* aRangeMax) {
|
const uint8_t* aRangeMin, const uint8_t* aRangeMax) const {
|
||||||
const DWORD kGranularity = GetAllocGranularity();
|
const DWORD kGranularity = GetAllocGranularity();
|
||||||
MOZ_ASSERT(aDesiredBytesLen >= kGranularity);
|
MOZ_ASSERT(aDesiredBytesLen >= kGranularity);
|
||||||
if (!aDesiredBytesLen) {
|
if (!aDesiredBytesLen) {
|
||||||
SetLastError(MMPOLICY_RESERVE_FINDREGION_INVALIDLEN);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(aRangeMin < aRangeMax);
|
MOZ_ASSERT(aRangeMin < aRangeMax);
|
||||||
if (aRangeMin >= aRangeMax) {
|
if (aRangeMin >= aRangeMax) {
|
||||||
SetLastError(MMPOLICY_RESERVE_FINDREGION_INVALIDRANGE);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,8 +341,6 @@ class MOZ_TRIVIAL_CTOR_DTOR MMPolicyBase {
|
||||||
reinterpret_cast<const uint8_t*>(mbi.BaseAddress) + mbi.RegionSize;
|
reinterpret_cast<const uint8_t*>(mbi.BaseAddress) + mbi.RegionSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastError(MMPOLICY_RESERVE_FINDREGION_VIRTUALQUERY_ERROR,
|
|
||||||
::GetLastError());
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,14 +363,10 @@ class MOZ_TRIVIAL_CTOR_DTOR MMPolicyBase {
|
||||||
PVOID Reserve(HANDLE aProcess, const uint32_t aSize,
|
PVOID Reserve(HANDLE aProcess, const uint32_t aSize,
|
||||||
const ReserveFnT& aReserveFn,
|
const ReserveFnT& aReserveFn,
|
||||||
const ReserveRangeFnT& aReserveRangeFn,
|
const ReserveRangeFnT& aReserveRangeFn,
|
||||||
const Maybe<Span<const uint8_t>>& aBounds) {
|
const Maybe<Span<const uint8_t>>& aBounds) const {
|
||||||
if (!aBounds) {
|
if (!aBounds) {
|
||||||
// No restrictions, let the OS choose the base address
|
// No restrictions, let the OS choose the base address
|
||||||
PVOID ret = aReserveFn(aProcess, nullptr, aSize);
|
return aReserveFn(aProcess, nullptr, aSize);
|
||||||
if (!ret) {
|
|
||||||
SetLastError(MMPOLICY_RESERVE_NOBOUND_RESERVE_ERROR, ::GetLastError());
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* lowerBound = GetLowerBound(aBounds.ref());
|
const uint8_t* lowerBound = GetLowerBound(aBounds.ref());
|
||||||
|
@ -424,11 +404,8 @@ class MOZ_TRIVIAL_CTOR_DTOR MMPolicyBase {
|
||||||
// If we run out of attempts, we fall through to the default case where
|
// If we run out of attempts, we fall through to the default case where
|
||||||
// the system chooses any base address it wants. In that case, the hook
|
// the system chooses any base address it wants. In that case, the hook
|
||||||
// will be set on a best-effort basis.
|
// will be set on a best-effort basis.
|
||||||
PVOID ret = aReserveFn(aProcess, nullptr, aSize);
|
|
||||||
if (!ret) {
|
return aReserveFn(aProcess, nullptr, aSize);
|
||||||
SetLastError(MMPOLICY_RESERVE_FINAL_RESERVE_ERROR, ::GetLastError());
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -825,13 +802,11 @@ class MMPolicyOutOfProcess : public MMPolicyBase {
|
||||||
uint32_t Reserve(const uint32_t aSize,
|
uint32_t Reserve(const uint32_t aSize,
|
||||||
const Maybe<Span<const uint8_t>>& aBounds) {
|
const Maybe<Span<const uint8_t>>& aBounds) {
|
||||||
if (!aSize || !mProcess) {
|
if (!aSize || !mProcess) {
|
||||||
SetLastError(MMPOLICY_RESERVE_INVALIDARG);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRemoteView) {
|
if (mRemoteView) {
|
||||||
MOZ_ASSERT(mReservationSize >= aSize);
|
MOZ_ASSERT(mReservationSize >= aSize);
|
||||||
SetLastError(MMPOLICY_RESERVE_ZERO_RESERVATIONSIZE);
|
|
||||||
return mReservationSize;
|
return mReservationSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,14 +816,12 @@ class MMPolicyOutOfProcess : public MMPolicyBase {
|
||||||
PAGE_EXECUTE_READWRITE | SEC_RESERVE, 0,
|
PAGE_EXECUTE_READWRITE | SEC_RESERVE, 0,
|
||||||
mReservationSize, nullptr);
|
mReservationSize, nullptr);
|
||||||
if (!mMapping) {
|
if (!mMapping) {
|
||||||
SetLastError(MMPOLICY_RESERVE_CREATEFILEMAPPING, ::GetLastError());
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLocalView = static_cast<uint8_t*>(
|
mLocalView = static_cast<uint8_t*>(
|
||||||
::MapViewOfFile(mMapping, FILE_MAP_WRITE, 0, 0, 0));
|
::MapViewOfFile(mMapping, FILE_MAP_WRITE, 0, 0, 0));
|
||||||
if (!mLocalView) {
|
if (!mLocalView) {
|
||||||
SetLastError(MMPOLICY_RESERVE_MAPVIEWOFFILE, ::GetLastError());
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,16 +121,6 @@ class WindowsDllPatcherBase {
|
||||||
return mVMPolicy.IsPageAccessible(aAddress);
|
return mVMPolicy.IsPageAccessible(aAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(NIGHTLY_BUILD)
|
|
||||||
const Maybe<DetourError>& GetLastError() const {
|
|
||||||
return mVMPolicy.GetLastError();
|
|
||||||
}
|
|
||||||
#endif // defined(NIGHTLY_BUILD)
|
|
||||||
template <typename... Args>
|
|
||||||
void SetLastError(Args&&... aArgs) {
|
|
||||||
mVMPolicy.SetLastError(std::forward<Args>(aArgs)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VMPolicy mVMPolicy;
|
VMPolicy mVMPolicy;
|
||||||
};
|
};
|
||||||
|
|
|
@ -128,6 +128,10 @@ class WindowsDllDetourPatcher final
|
||||||
using PrimitiveT = WindowsDllDetourPatcherPrimitive<MMPolicyT>;
|
using PrimitiveT = WindowsDllDetourPatcherPrimitive<MMPolicyT>;
|
||||||
Maybe<DetourFlags> mFlags;
|
Maybe<DetourFlags> mFlags;
|
||||||
|
|
||||||
|
#if defined(NIGHTLY_BUILD)
|
||||||
|
Maybe<DetourError> mLastError;
|
||||||
|
#endif // defined(NIGHTLY_BUILD)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
explicit WindowsDllDetourPatcher(Args&&... aArgs)
|
explicit WindowsDllDetourPatcher(Args&&... aArgs)
|
||||||
|
@ -140,6 +144,15 @@ class WindowsDllDetourPatcher final
|
||||||
WindowsDllDetourPatcher& operator=(const WindowsDllDetourPatcher&) = delete;
|
WindowsDllDetourPatcher& operator=(const WindowsDllDetourPatcher&) = delete;
|
||||||
WindowsDllDetourPatcher& operator=(WindowsDllDetourPatcher&&) = delete;
|
WindowsDllDetourPatcher& operator=(WindowsDllDetourPatcher&&) = delete;
|
||||||
|
|
||||||
|
#if defined(NIGHTLY_BUILD)
|
||||||
|
const Maybe<DetourError>& GetLastError() const { return mLastError; }
|
||||||
|
void SetLastError(DetourResultCode aError) {
|
||||||
|
mLastError = Some(DetourError(aError));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void SetLastError(DetourResultCode) {}
|
||||||
|
#endif // defined(NIGHTLY_BUILD)
|
||||||
|
|
||||||
void Clear() {
|
void Clear() {
|
||||||
if (!this->mVMPolicy.ShouldUnhookUponDestruction()) {
|
if (!this->mVMPolicy.ShouldUnhookUponDestruction()) {
|
||||||
return;
|
return;
|
||||||
|
@ -540,11 +553,9 @@ class WindowsDllDetourPatcher final
|
||||||
#endif // defined(_M_X64)
|
#endif // defined(_M_X64)
|
||||||
|
|
||||||
Maybe<TrampPoolT> maybeTrampPool = this->mVMPolicy.Reserve(pivot, distance);
|
Maybe<TrampPoolT> maybeTrampPool = this->mVMPolicy.Reserve(pivot, distance);
|
||||||
#if defined(NIGHTLY_BUILD)
|
if (!maybeTrampPool) {
|
||||||
if (!maybeTrampPool && this->GetLastError().isNothing()) {
|
|
||||||
SetLastError(DetourResultCode::DETOUR_PATCHER_DO_RESERVE_ERROR);
|
SetLastError(DetourResultCode::DETOUR_PATCHER_DO_RESERVE_ERROR);
|
||||||
}
|
}
|
||||||
#endif // defined(NIGHTLY_BUILD)
|
|
||||||
return maybeTrampPool;
|
return maybeTrampPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,19 +943,18 @@ class WindowsDllDetourPatcher final
|
||||||
#if defined(NIGHTLY_BUILD)
|
#if defined(NIGHTLY_BUILD)
|
||||||
origBytes.Rewind();
|
origBytes.Rewind();
|
||||||
SetLastError(DetourResultCode::DETOUR_PATCHER_CREATE_TRAMPOLINE_ERROR);
|
SetLastError(DetourResultCode::DETOUR_PATCHER_CREATE_TRAMPOLINE_ERROR);
|
||||||
DetourError& lastError = *this->mVMPolicy.mLastError;
|
|
||||||
size_t bytesToCapture = std::min(
|
size_t bytesToCapture = std::min(
|
||||||
ArrayLength(lastError.mOrigBytes),
|
ArrayLength(mLastError->mOrigBytes),
|
||||||
static_cast<size_t>(PrimitiveT::GetWorstCaseRequiredBytesToPatch()));
|
static_cast<size_t>(PrimitiveT::GetWorstCaseRequiredBytesToPatch()));
|
||||||
# if defined(_M_ARM64)
|
# if defined(_M_ARM64)
|
||||||
size_t numInstructionsToCapture = bytesToCapture / sizeof(uint32_t);
|
size_t numInstructionsToCapture = bytesToCapture / sizeof(uint32_t);
|
||||||
auto origBytesDst = reinterpret_cast<uint32_t*>(lastError.mOrigBytes);
|
auto origBytesDst = reinterpret_cast<uint32_t*>(mLastError->mOrigBytes);
|
||||||
for (size_t i = 0; i < numInstructionsToCapture; ++i) {
|
for (size_t i = 0; i < numInstructionsToCapture; ++i) {
|
||||||
origBytesDst[i] = origBytes.ReadNextInstruction();
|
origBytesDst[i] = origBytes.ReadNextInstruction();
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
for (size_t i = 0; i < bytesToCapture; ++i) {
|
for (size_t i = 0; i < bytesToCapture; ++i) {
|
||||||
lastError.mOrigBytes[i] = origBytes[i];
|
mLastError->mOrigBytes[i] = origBytes[i];
|
||||||
}
|
}
|
||||||
# endif // defined(_M_ARM64)
|
# endif // defined(_M_ARM64)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -229,12 +229,7 @@ class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FuncHookCrossProcess final {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = CopyStubToChildProcess(origFunc, aProcess);
|
return CopyStubToChildProcess(origFunc, aProcess);
|
||||||
if (!ret) {
|
|
||||||
aInterceptor.SetLastError(FUNCHOOKCROSSPROCESS_COPYSTUB_ERROR,
|
|
||||||
::GetLastError());
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetDetour(HANDLE aProcess, InterceptorT& aInterceptor, const char* aName,
|
bool SetDetour(HANDLE aProcess, InterceptorT& aInterceptor, const char* aName,
|
||||||
|
@ -245,12 +240,7 @@ class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FuncHookCrossProcess final {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = CopyStubToChildProcess(origFunc, aProcess);
|
return CopyStubToChildProcess(origFunc, aProcess);
|
||||||
if (!ret) {
|
|
||||||
aInterceptor.SetLastError(FUNCHOOKCROSSPROCESS_COPYSTUB_ERROR,
|
|
||||||
::GetLastError());
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit operator bool() const { return !!mOrigFunc; }
|
explicit operator bool() const { return !!mOrigFunc; }
|
||||||
|
@ -376,10 +366,6 @@ class WindowsDllInterceptor final
|
||||||
return mDetourPatcher.GetLastError();
|
return mDetourPatcher.GetLastError();
|
||||||
}
|
}
|
||||||
#endif // defined(NIGHTLY_BUILD)
|
#endif // defined(NIGHTLY_BUILD)
|
||||||
template <typename... Args>
|
|
||||||
void SetLastError(Args&&... aArgs) {
|
|
||||||
return mDetourPatcher.SetLastError(std::forward<Args>(aArgs)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr static uint32_t GetWorstCaseRequiredBytesToPatch() {
|
constexpr static uint32_t GetWorstCaseRequiredBytesToPatch() {
|
||||||
return WindowsDllDetourPatcherPrimitive<
|
return WindowsDllDetourPatcherPrimitive<
|
||||||
|
|
|
@ -235,16 +235,6 @@ enum DetourResultCode : uint32_t {
|
||||||
DETOUR_PATCHER_INVALID_TRAMPOLINE,
|
DETOUR_PATCHER_INVALID_TRAMPOLINE,
|
||||||
DETOUR_PATCHER_WRITE_POINTER_ERROR,
|
DETOUR_PATCHER_WRITE_POINTER_ERROR,
|
||||||
DETOUR_PATCHER_CREATE_TRAMPOLINE_ERROR,
|
DETOUR_PATCHER_CREATE_TRAMPOLINE_ERROR,
|
||||||
FUNCHOOKCROSSPROCESS_COPYSTUB_ERROR,
|
|
||||||
MMPOLICY_RESERVE_INVALIDARG,
|
|
||||||
MMPOLICY_RESERVE_ZERO_RESERVATIONSIZE,
|
|
||||||
MMPOLICY_RESERVE_CREATEFILEMAPPING,
|
|
||||||
MMPOLICY_RESERVE_MAPVIEWOFFILE,
|
|
||||||
MMPOLICY_RESERVE_NOBOUND_RESERVE_ERROR,
|
|
||||||
MMPOLICY_RESERVE_FINDREGION_INVALIDLEN,
|
|
||||||
MMPOLICY_RESERVE_FINDREGION_INVALIDRANGE,
|
|
||||||
MMPOLICY_RESERVE_FINDREGION_VIRTUALQUERY_ERROR,
|
|
||||||
MMPOLICY_RESERVE_FINAL_RESERVE_ERROR,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(NIGHTLY_BUILD)
|
#if defined(NIGHTLY_BUILD)
|
||||||
|
@ -255,12 +245,6 @@ struct DetourError {
|
||||||
uint8_t mOrigBytes[16];
|
uint8_t mOrigBytes[16];
|
||||||
explicit DetourError(DetourResultCode aError)
|
explicit DetourError(DetourResultCode aError)
|
||||||
: mErrorCode(aError), mOrigBytes{} {}
|
: mErrorCode(aError), mOrigBytes{} {}
|
||||||
DetourError(DetourResultCode aError, DWORD aWin32Error)
|
|
||||||
: mErrorCode(aError), mOrigBytes{} {
|
|
||||||
static_assert(sizeof(mOrigBytes) >= sizeof(aWin32Error),
|
|
||||||
"Can't fit a DWORD in mOrigBytes");
|
|
||||||
*reinterpret_cast<DWORD*>(mOrigBytes) = aWin32Error;
|
|
||||||
}
|
|
||||||
operator WindowsError() const {
|
operator WindowsError() const {
|
||||||
return WindowsError::FromHResult(mErrorCode);
|
return WindowsError::FromHResult(mErrorCode);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче