pythonc++comwindows-runtimeida

Using WinRT Interface in Python


ref: ISystemMediaTransportControlsInterop

I compiled a dll about ISystemMediaTransportControlsInterop::GetForWindow. I use IDA to decompile it. Then I wrote the C-like code as Python. I believe that I was wrote them in a right way. But sadly, I met a pointer error. I know it's because SMTC_Interop_GetForWindow function address is incorrect, but I don't know why.

Python log:

RoInit: 0
String Create: 0, SMTCInterop: c_void_p(None)
RoGetActivationFactory: 0, SMTCInterop: c_void_p(7948368)
Traceback (most recent call last):
  File "D:\儿子文件\编程\python\PyCharm项目\WinSMTC\test.py", line 56, in <module>
    TestFunc()
  File "D:\儿子文件\编程\python\PyCharm项目\WinSMTC\test.py", line 45, in TestFunc
    GetForWindow(Create_SMTC_Window(), smtc_obj)
  File "D:\儿子文件\编程\python\PyCharm项目\WinSMTC\test.py", line 26, in GetForWindow
    result = SMTC_Interop_GetForWindow(smtc_interop.value, hwnd, ctypes.byref(REF_IID), ctypes.byref(smtc_obj))
OSError: exception: access violation writing 0x00007FFBED118788

Python Code(key func):

def GetForWindow(hwnd: int, smtc_obj: ctypes.c_void_p):
    result = RoInitialize(RO_INIT_MULTITHREADED)
    print("RoInit:", result)
    smtc_interop = VoidPtr()
    h_string = HSTRING()
    result = WindowsCreateString(String("Windows.Media.SystemMediaTransportControls"), ctypes.c_uint32(42),
                                 ctypes.byref(h_string))
    print(f"String Create: {result}, SMTCInterop: {smtc_interop}")
    result = RoGetActivationFactory(h_string, ctypes.byref(IID_SystemMediaTransportControls),
                                    ctypes.byref(smtc_interop))
    print(f"RoGetActivationFactory: {result}, SMTCInterop: {smtc_interop}")
    SMTC_Interop_GetForWindow = ctypes.CFUNCTYPE(ctypes.c_int64, ctypes.c_int64, ctypes.c_int32, ctypes.POINTER(ctypes.c_int64),
                                                 ctypes.POINTER(ctypes.c_void_p))(ctypes.cast(smtc_interop.value, ctypes.POINTER(ctypes.c_int64)).contents.value + 48)
    result = SMTC_Interop_GetForWindow(smtc_interop.value, hwnd, ctypes.byref(REF_IID), ctypes.byref(smtc_obj))

IDA Func Code(to the key func): IDA Func Code

You can download Dll Source Code & Dll File & IDA Debug File & Test Python Code in here


Solution

  • The error suggests you're trying to write to memory that's not accessible. The main problem is in this line:

    SMTC_Interop_GetForWindow = ctypes.CFUNCTYPE(...)(ctypes.cast(smtc_interop.value, ctypes.POINTER(ctypes.c_int64)).contents.value + 48)
    

    Change it with

    vtable_ptr = ctypes.cast(smtc_interop.value, ctypes.POINTER(ctypes.c_void_p)).contents.value
    method_ptr = ctypes.cast(vtable_ptr + 3 * 8, ctypes.POINTER(ctypes.c_void_p)).contents.value
    SMTC_Interop_GetForWindow = ctypes.CFUNCTYPE(ctypes.c_int64, ctypes.c_void_p, ctypes.c_int32, ctypes.POINTER(ctypes.c_int64), ctypes.POINTER(ctypes.c_void_p))(method_ptr)
    

    This approach should resolve the error as it accesses the function pointer through the vtable structure rather than using a direct offset from the interface pointer.