-
Notifications
You must be signed in to change notification settings - Fork 444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix ID2D1Device5/6 hook offsets #938
Conversation
ID2D1Device4 has two additional interface members: Set and GetMaximumColorGlyphCacheMemory. These two were unaccounted for in HookDevice, leading to crashes when any of these functions were called.
MyDebug(L"ID2D1Device5 hooked"); | ||
} | ||
CComPtr<ID2D1Device6> ptr7; | ||
hr = (d2dDevice)->QueryInterface(&ptr7); | ||
if SUCCEEDED(hr) { | ||
HOOK(ptr7, CreateDeviceContext7, 18); | ||
HOOK(ptr7, CreateDeviceContext7, 20); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have received a number of crash reports for Windows Terminal Preview 1.18 when MacType is being used. While debugging I found that this occurs whenever we call ID2D1Device4::SetMaximumColorGlyphCacheMemory
.
I don't understand how MacType or even just how EasyHook works, but I noticed that the indices for these two members seem to be highly inconsistent with the others, when you list them up (copied out of the D2D headers and simplified):
MIDL_INTERFACE("00000000-0000-0000-C000-000000000046") IUnknown
{
/* 0 */ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) = 0;
/* 1 */ virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0;
/* 2 */ virtual ULONG STDMETHODCALLTYPE Release( void) = 0;
};
interface DX_DECLARE_INTERFACE("2cd90691-12e2-11dc-9fed-001143a055f9") ID2D1Resource : public IUnknown
{
/* 3 */ STDMETHOD_(void, GetFactory)(_Outptr_ ID2D1Factory **factory) CONST PURE;
};
interface DX_DECLARE_INTERFACE("47dd575d-ac05-4cdd-8049-9b02cd16f44c") ID2D1Device : public ID2D1Resource
{
/* 4 */ STDMETHOD(CreateDeviceContext)(D2D1_DEVICE_CONTEXT_OPTIONS options, _COM_Outptr_ ID2D1DeviceContext **deviceContext) PURE;
/* 5 */ STDMETHOD(CreatePrintControl)(_In_ IWICImagingFactory *wicFactory, _In_ IPrintDocumentPackageTarget *documentTarget, _In_opt_ CONST D2D1_PRINT_CONTROL_PROPERTIES *printControlProperties, _COM_Outptr_ ID2D1PrintControl **printControl) PURE;
/* 6 */ STDMETHOD_(void, SetMaximumTextureMemory)(UINT64 maximumInBytes) PURE;
/* 7 */ STDMETHOD_(UINT64, GetMaximumTextureMemory)() CONST PURE;
/* 8 */ STDMETHOD_(void, ClearResources)(UINT32 millisecondsSinceUse = 0) PURE;
};
interface DX_DECLARE_INTERFACE("d21768e1-23a4-4823-a14b-7c3eba85d658") ID2D1Device1 : public ID2D1Device
{
/* 9 */ STDMETHOD_(D2D1_RENDERING_PRIORITY, GetRenderingPriority)() PURE;
/* 10 */ STDMETHOD_(void, SetRenderingPriority)(D2D1_RENDERING_PRIORITY renderingPriority) PURE;
/* 11 */ STDMETHOD(CreateDeviceContext)(D2D1_DEVICE_CONTEXT_OPTIONS options, _COM_Outptr_ ID2D1DeviceContext1 **deviceContext1) PURE;
};
interface DX_DECLARE_INTERFACE("a44472e1-8dfb-4e60-8492-6e2861c9ca8b") ID2D1Device2 : public ID2D1Device1
{
/* 12 */ STDMETHOD(CreateDeviceContext)(D2D1_DEVICE_CONTEXT_OPTIONS options, _COM_Outptr_ ID2D1DeviceContext2 **deviceContext2) PURE;
/* 13 */ STDMETHOD_(void, FlushDeviceContexts)(_In_ ID2D1Bitmap *bitmap) PURE;
/* 14 */ STDMETHOD(GetDxgiDevice)(_COM_Outptr_ IDXGIDevice **dxgiDevice) PURE;
};
interface DX_DECLARE_INTERFACE("852f2087-802c-4037-ab60-ff2e7ee6fc01") ID2D1Device3 : public ID2D1Device2
{
/* 15 */ STDMETHOD(CreateDeviceContext)(D2D1_DEVICE_CONTEXT_OPTIONS options, _COM_Outptr_ ID2D1DeviceContext3 **deviceContext3) PURE;
};
interface DX_DECLARE_INTERFACE("d7bdb159-5683-4a46-bc9c-72dc720b858b") ID2D1Device4 : public ID2D1Device3
{
/* 16 */ STDMETHOD(CreateDeviceContext)(D2D1_DEVICE_CONTEXT_OPTIONS options, _COM_Outptr_ ID2D1DeviceContext4 **deviceContext4) PURE;
/* 17 */ STDMETHOD_(void, SetMaximumColorGlyphCacheMemory)(UINT64 maximumInBytes) PURE;
/* 18 */ STDMETHOD_(UINT64, GetMaximumColorGlyphCacheMemory)() CONST PURE;
};
interface DX_DECLARE_INTERFACE("d55ba0a4-6405-4694-aef5-08ee1a4358b4") ID2D1Device5 : public ID2D1Device4
{
/* 19 */ STDMETHOD(CreateDeviceContext)(D2D1_DEVICE_CONTEXT_OPTIONS options, _COM_Outptr_ ID2D1DeviceContext5 **deviceContext5) PURE;
};
interface DX_DECLARE_INTERFACE("7bfef914-2d75-4bad-be87-e18ddb077b6d") ID2D1Device6 : public ID2D1Device5
{
/* 20 */ STDMETHOD(CreateDeviceContext)(D2D1_DEVICE_CONTEXT_OPTIONS options, _COM_Outptr_ ID2D1DeviceContext6 **deviceContext6) PURE;
};
I've not tested this change, but I'm still very confident about the correctness of this fix.
Basically, these indices are the index of the function pointers in their respective vtable. We use easyhook to find the actual function and hijack it to our function. If the indice is wrong, then the wrong function will be intercepted, and the data could be corrupted. |
Confirmed that vtbl index for ID2D1Device5/6 is incorrect because of the two functions introduced by ID2D1Device4. |
Published as a preview release. |
Thank you so much for your help! |
This adds a check for whether MacType is injected and whether it's a known bad version (pre-2023). In that case we avoid calling the known faulty `ID2D1Device4` interface. We could avoid it in general to fix the issue without a warning (it's only a very mild optimization), but on the other hand, the bug that MacType has is a very serious one and it's probably better overall to suggest users to update. See: snowie2000/mactype#938 ## Validation Steps Performed * MacType 2021.1-RC1 results in a warning and no crash ✅ * MacType 2023.5.31 results in no warning ✅ --------- Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
This adds a check for whether MacType is injected and whether it's a known bad version (pre-2023). In that case we avoid calling the known faulty `ID2D1Device4` interface. We could avoid it in general to fix the issue without a warning (it's only a very mild optimization), but on the other hand, the bug that MacType has is a very serious one and it's probably better overall to suggest users to update. See: snowie2000/mactype#938 * MacType 2021.1-RC1 results in a warning and no crash ✅ * MacType 2023.5.31 results in no warning ✅ --------- Co-authored-by: Dustin L. Howett <duhowett@microsoft.com> (cherry picked from commit 9317d42) Service-Card-Id: 92687128 Service-Version: 1.20
This adds a check for whether MacType is injected and whether it's a known bad version (pre-2023). In that case we avoid calling the known faulty `ID2D1Device4` interface. We could avoid it in general to fix the issue without a warning (it's only a very mild optimization), but on the other hand, the bug that MacType has is a very serious one and it's probably better overall to suggest users to update. See: snowie2000/mactype#938 ## Validation Steps Performed * MacType 2021.1-RC1 results in a warning and no crash ✅ * MacType 2023.5.31 results in no warning ✅ --------- Co-authored-by: Dustin L. Howett <duhowett@microsoft.com> (cherry picked from commit 9317d42) Service-Card-Id: 92687129 Service-Version: 1.21
ID2D1Device4 has two additional interface members: Set and
GetMaximumColorGlyphCacheMemory. These two were unaccounted for in
HookDevice, leading to crashes when any of these functions were called.