Jump to content

DirectWrite Replace vTable entry


Recommended Posts

Hi, I am trying to replace an entry in vTable with my own function, but I am failing. Following is the interface example.

Global Const $tagIDWriteFactory = "GetSystemFontCollection hresult(ptr*;bool);" & _
        "CreateCustomFontCollection hresult(struct*;struct*;uint;ptr*);" & _
        "RegisterFontCollectionLoader hresult(struct*);" & _
        "UnregisterFontCollectionLoader hresult(struct*);" & _
        "CreateFontFileReference hresult(wstr;struct*;ptr*);" & _
        "CreateCustomFontFileReference hresult(struct*;uint;struct*;ptr*);" & _
        "CreateFontFace hresult(uint;uint;struct*;uint;uint;ptr*);" & _
        "CreateRenderingParams hresult(ptr*);" & _
        "CreateMonitorRenderingParams hresult(handle;ptr*);" & _
        "CreateCustomRenderingParams hresult(float;float;float;uint;uint;ptr*);" & _
        "RegisterFontFileLoader hresult(struct*);" & _
        "UnregisterFontFileLoader hresult(struct*);" & _
        "CreateTextFormat hresult(wstr;struct*;uint;uint;uint;float;wstr;ptr*);" & _
        "CreateTypography hresult(ptr*);" & _
        "GetGdiInterop hresult(ptr*);" & _
        "CreateTextLayout hresult(wstr;uint;struct*;float;float;ptr*);" & _
        "CreateGdiCompatibleTextLayout hresult(wstr;uint;struct*;float;float;float;struct*;bool;ptr*);" & _
        "CreateEllipsisTrimmingSign hresult(struct*;ptr*);" & _
        "CreateTextAnalyzer hresult(ptr*);" & _
        "CreateNumberSubstitution hresult(uint;wstr;bool;ptr*);" & _
        "CreateGlyphRunAnalysis hresult(struct*;float;struct*;uint;uint;float;float;ptr*);"

For testing purposes I was trying to replace GetGdiInterop. If I calculate offset like this (Method_ordinal_number+3-1)*4 then my method does not get called. Am I calculating offset wrongly? Which is the correct way for calculating offsets?

ReplaceVTableFuncPtr was copied from Accessing AutoIt Variables.

I downloaded Direct2D from German forum https://autoit.de/wcf/attachment/82843-direct2d-7z/

_DWrite_Replace_vTable.au3

Link to post
Share on other sites

From looking at the code you attached my first suggestion would be to add in some error checking bc it could fail virtually anywhere and you'd have no idea where its falling apart.  

what exactly is happening here? $ptest doesn't appear to be defined anywhere...

Local $pNewFuncTest=DllCallbackGetPtr(DllCallbackRegister( "GetGdiInterop", "long", "ptr*" )), $pTest  ;<============

i'm assuming that you had to of had this working in some previous test that you commented out .  i'm not sure where you got that equation to calculate an offset but i'm pretty sure that it should be

basepointer + (N * sizeof(pointer))           N being the number of elements to shift...

Edited by markyrocks
Link to post
Share on other sites
Posted (edited)

@markyrocks Thank you for response. I have added error checking in current script. No apparent errors show up. Unmodified GetGdiInterOp returns pointer to an object. $pTest should receive value of that pointer.

What would be the values of base pointer and N? I just checked that the above equation I got from an example of Accessing AutoIt Variables. Currently I have (15+3-1)*4. 3 is for 3 members of IUnknown interface, -1 is because first pointer has offset 0 and 15 is the ordinal number for GetGdiInterOp from the IDWriteFactory. Following is example from "Accessing AutoIt Variables":

;#AutoIt3Wrapper_UseX64=y

#include <Array.au3>
#include <StructureConstants.au3>

#include "..\..\..\Includes\Utilities.au3"

Global Const $sCLSID_CUIAutomation = "{FF48DBA4-60EF-4201-AA87-54103EEF594E}"

Global Const $sIID_IUIAutomation = "{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}"
Global Const $stag_IUIAutomation = _
    "CompareElements hresult(ptr;ptr;long*);" & _
    "CompareRuntimeIds hresult(ptr;ptr;long*);" & _
    "GetRootElement hresult(ptr*);" & _
    "ElementFromHandle hresult(hwnd;ptr*);" & _
    "ElementFromPoint hresult(struct;ptr*);" & _
    "GetFocusedElement hresult(ptr*);" & _
    "GetRootElementBuildCache hresult(ptr;ptr*);" & _
    "ElementFromHandleBuildCache hresult(hwnd;ptr;ptr*);" & _
    "ElementFromPointBuildCache hresult(struct;ptr;ptr*);" & _
    "GetFocusedElementBuildCache hresult(ptr;ptr*);" & _
    "CreateTreeWalker hresult(ptr;ptr*);" & _
    "ControlViewWalker hresult(ptr*);" & _
    "ContentViewWalker hresult(ptr*);" & _
    "RawViewWalker hresult(ptr*);" & _
    "RawViewCondition hresult(ptr*);" & _
    "ControlViewCondition hresult(ptr*);" & _
    "ContentViewCondition hresult(ptr*);" & _
    "CreateCacheRequest hresult(ptr*);" & _
    "CreateTrueCondition hresult(ptr*);" & _
    "CreateFalseCondition hresult(ptr*);" & _
    "CreatePropertyCondition hresult(int;variant;ptr*);" & _
    "CreatePropertyConditionEx hresult(int;variant;long;ptr*);" & _
    "CreateAndCondition hresult(ptr;ptr;ptr*);" & _
    "CreateAndConditionFromArray hresult(ptr;ptr*);" & _
    "CreateAndConditionFromNativeArray hresult(ptr;int;ptr*);" & _
    "CreateOrCondition hresult(ptr;ptr;ptr*);" & _
    "CreateOrConditionFromArray hresult(ptr;ptr*);" & _
    "CreateOrConditionFromNativeArray hresult(ptr;int;ptr*);" & _
    "CreateNotCondition hresult(ptr;ptr*);" & _
    "AddAutomationEventHandler hresult(int;ptr;long;ptr;ptr);" & _
    "RemoveAutomationEventHandler hresult(int;ptr;ptr);" & _
    "AddPropertyChangedEventHandlerNativeArray hresult(ptr;long;ptr;ptr;struct*;int);" & _
    "AddPropertyChangedEventHandler hresult(ptr;long;ptr;ptr;ptr);" & _
    "RemovePropertyChangedEventHandler hresult(ptr;ptr);" & _
    "AddStructureChangedEventHandler hresult(ptr;long;ptr;ptr);" & _
    "RemoveStructureChangedEventHandler hresult(ptr;ptr);" & _
    "AddFocusChangedEventHandler hresult(ptr;ptr);" & _
    "RemoveFocusChangedEventHandler hresult(ptr);" & _
    "RemoveAllEventHandlers hresult();" & _
    "IntNativeArrayToSafeArray hresult(int;int;ptr*);" & _
    "IntSafeArrayToNativeArray hresult(ptr;int*;int*);" & _
    "RectToVariantEx hresult(struct*;variant*);" & _ ; <<<< RectToVariant >>>>
    "VariantToRect hresult(variant;struct*);" & _
    "SafeArrayToRectNativeArray hresult(ptr;struct*;int*);" & _
    "CreateProxyFactoryEntry hresult(ptr;ptr*);" & _
    "ProxyFactoryMapping hresult(ptr*);" & _
    "GetPropertyProgrammaticName hresult(int;bstr*);" & _
    "GetPatternProgrammaticName hresult(int;bstr*);" & _
    "PollForPotentialSupportedPatterns hresult(ptr;ptr*;ptr*);" & _
    "PollForPotentialSupportedProperties hresult(ptr;ptr*;ptr*);" & _
    "CheckNotSupported hresult(variant;long*);" & _
    "ReservedNotSupportedValue hresult(ptr*);" & _
    "ReservedMixedAttributeValue hresult(ptr*);" & _
    "ElementFromIAccessible hresult(idispatch;int;ptr*);" & _
    "ElementFromIAccessibleBuildCache hresult(iaccessible;int;ptr;ptr*);"

Global $pRectToVariant ; Original RectToVariant function pointer

Opt( "MustDeclareVars", 1 )

Example1()

Func Example1()
    ; Create UIAutomation object
    Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $stag_IUIAutomation )

    ; Replace RectToVariant with RectToVariantEx
    ; And get original RectToVariant function pointer
    Local $pRectToVariantEx = DllCallbackGetPtr( DllCallbackRegister( "RectToVariantEx", "long", "ptr;ptr;ptr*" ) )
    $pRectToVariant = ReplaceVTableFuncPtr( Ptr( $oUIAutomation() ), ( 3 + 42 - 1 ) * ( @AutoItX64 ? 8 : 4 ), $pRectToVariantEx )

    ; Create rectangle structure
    Local $tRect = DllStructCreate( $tagRECT )
    DllStructSetData( $tRect, "Left",    100 )
    DllStructSetData( $tRect, "Top",     200 )
    DllStructSetData( $tRect, "Right",  3000 )
    DllStructSetData( $tRect, "Bottom", 4000 )

    ; Output array
    Local $aArray

    ; Execute RectToVariantEx method
    $oUIAutomation.RectToVariantEx( $tRect, $aArray )

    ; Display array
    _ArrayDisplay( $aArray )
EndFunc

Func RectToVariantEx( $pSelf, $pRect, $pVariant )
    ; Here it's possible to debug and modify parameters after conver-
    ; sions on function entry but before the original method is executed.

    ; Execute original RectToVariant method
    Local $aRet = DllCallAddress( "long", $pRectToVariant, "ptr", $pSelf, @AutoItX64 ? "struct*" : "struct", DllStructCreate( $tagRECT, $pRect ), "ptr", $pVariant )
    ; Note that no COM conversions are applied neither to DllCall nor DllCallAddress functions

    ; Here it's possible to debug and modify parameters after the origi-
    ; nal method is executed but before conversions on function exit.

    Return $aRet[0]
EndFunc

Here is new code with error checking

#include "..\Direct2D.au3"
#include "..\DirectWrite.au3"
;derived from _DWrite_Factory_Create
Global $oError = ObjEvent("AutoIt.Error", "_ErrFunc")
Func _ErrFunc()
    ConsoleWrite("COM Error, ScriptLine(" & $oError.ScriptLine & ") : Number 0x" & Hex($oError.Number, 8) & " - " & $oError.WinDescription & @CRLF)
EndFunc   ;==>_ErrFunc
Global $pOldFuncTest

_Example()

Func _Example()

    Local $sString = "Hello World"

    Local $hGui = GUICreate("Direct2D", 800, 300)
    Local $oFactory = _D2D_Factory_Create()
    Local $oRender = _D2D_Factory_CreateHwndRenderTarget($oFactory, $hGui)
    Local $oBrush = _D2D_RenderTarget_CreateSolidColorBrush($oRender, 1, 1, 0)

    Local $oDW_Factory = _DWrite_Factory_Create()
    Local $oDW_Format = _DWrite_Factory_CreateTextFormat($oDW_Factory, "Arial", 128)


    Local $pObj=Ptr($oDW_Factory), $pTest
    $hCallback=DllCallbackRegister( "GetGdiInterop", "long", "ptr;ptr*" )
    If @error Then MsgBox(0,"DllCallbackRegister error",@error)
    Local $pNewFuncTest=DllCallbackGetPtr($hCallback)
    If @error Then MsgBox(0,"DllCallbackGetPtr error",@error)
    $pOldFuncTest=ReplaceVTableFuncPtr($pObj,(15+3-1)*4,$pNewFuncTest);3 from IUnknown, -1 - first offset iz zero;(15+3-1)*4
    ;24 prints 'Caught'
    For $i=1 To 7
        ConsoleWrite($i & "=")
        ConsoleWrite(ObjName($oDW_Factory,$i) & @CRLF)
    Next

    $oDW_Factory.GetGdiInterop($pTest)
    MsgBox(0,"After test","There should be single 'Caught' at the console")
    GUISetState()


    $oRender.BeginDraw()
    _D2D_RenderTarget_Clear($oRender, 0, 0, 0.3)
    _D2D_RenderTarget_DrawText($oRender, $sString, $oDW_Format, 0, 0, 800, 300, $oBrush)
    $oRender.EndDraw(0, 0)


    While GUIGetMsg() <> -3
    WEnd

    $oDW_Format = 0
    $oDW_Factory = 0

    $oBrush = 0
    $oRender = 0
    $oFactory = 0

    GUIDelete($hGui)
EndFunc   ;==>_Example

Func GetGdiInterop($pSelf, $oParam1)
    ConsoleWrite("Caught" & @CRLF)
    Local $test
;~  $iResult=DllCallAddress("long",$pOldFuncTest,"ptr",$pSelf,"ptr*",$test)
;~  ConsoleWrite("$iResult=" & $iResult & @CRLF)
;~  $oParam1=ObjCreateInterface($pGDIInterOp,$sIID_IDWriteGdiInterop,$tagIDWriteGdiInterop)
    Return 0
EndFunc

; Copied from "Hooking into the IDispatch interface" by monoceres
; https://www.autoitscript.com/forum/index.php?showtopic=107678
Func ReplaceVTableFuncPtr( $pVTable, $iOffset, $pNewFunc )
    Local $pPointer = DllStructGetData( DllStructCreate( "ptr", $pVTable ), 1 ) + $iOffset, $PAGE_EXECUTE_READWRITE = 0x40
    Local $pOldFunc = DllStructGetData( DllStructCreate( "ptr", $pPointer ), 1 ) ; Get the original function pointer in VTable
    If @error Then MsgBox(0,"Error 1",@error)
    Local $aRet = DllCall( "Kernel32.dll", "int", "VirtualProtect", "ptr", $pPointer, "long", @AutoItX64 ? 8 : 4, "dword", $PAGE_EXECUTE_READWRITE, "dword*", 0 ) ; Unprotect memory
    If @error Then MsgBox(0,"Error 2",@error)
    If Not IsArray($aRet) Then MsgBox(0,"Error 2b","")
    DllStructSetData( DllStructCreate( "ptr", $pPointer ), 1, $pNewFunc ) ; Replace function pointer in VTable with $pNewFunc function pointer
    If @error Then MsgBox(0,"Error 3",@error)
    $aRet2=DllCall( "Kernel32.dll", "int", "VirtualProtect", "ptr", $pPointer, "long", @AutoItX64 ? 8 : 4, "dword", $aRet[4], "dword*", 0 ) ; Protect memory
    If @error Then MsgBox(0,"Error 4",@error)
    If Not IsArray($aRet2) Then MsgBox(0,"Error 4b","")
    Return $pOldFunc ; Return original function pointer
EndFunc

 

Edited by ahmet
Link to post
Share on other sites

This is basic pointer math the base number is not going to be 0 if it is then its broken bc thats just NULL.  

What we're talking about is a VMT which is a virtual method table .  This table is basically and array that contains pointers to functions.  the base is going to be the address to whatever the first function is.  So just like in array math it would be VMT[0]....the next one [1]  all the way up to N<~~ so N being the element number.  

these functions have sizes im assuming 4 bytes thats most likely where you're getting 4 from. For the sake of argument we'll say the base address is 0x000000FF or 255

So 255 to 258 would occupy the 0 element.  259-262 the second (I cant count in hex sry)

To get to the address you're looking for its definitely base+(N*sizeof(pointer) 

 

from 0x000000FF + (18*4) = 0x00000147  or 327. 

the address of 0 is probably the entry point of the program.  Scrolling though that thread theres a bazillion examples and test scripts.  for testing purposes loop through each entry and replace them one by one until you get it working.  

 

Link to post
Share on other sites

 

$oDW_Factory.GetGdiInterop($pTest)
ConsoleWrite($point&@CRLF)
ConsoleWrite(Ptr($pTest))
Global $test ,$pointtest
if Ptr($pTest) > $point Then
   Do
      $test = $test - 1
      $pointtest = Ptr($pTest) + $test
   Until  $pointtest  = $point
   MsgBox(0,"",$pointtest)
Else
    Do
      $test = $test + 1
      $pointtest = Ptr($pTest) + $test
   Until  $pointtest  = $point
   MsgBox(0,"",$pointtest)
   EndIf

output:

GetGdiInterop = 0x0661E8F0
$pTest = 0x0661E8F0

Edited by ad777

iam ِAutoit programmer.

best thing in life is to use your Brain to

Achieve

everything you want.

Link to post
Share on other sites

markyrocks;i did'nt get what he want exactly,i was thinking he want direct address or something.

iam ِAutoit programmer.

best thing in life is to use your Brain to

Achieve

everything you want.

Link to post
Share on other sites
Posted (edited)

I have already looked at the subclassing examples from above link.

It is important, but I have forgotten to mention that I have already tried following:

$pOldFuncTest=ReplaceVTableFuncPtr($pObj,($iCustomOffset+3-1)*4,$pNewFuncTest)

I iterated through $iCustomOffset in a way that I restarted script each time with new value.

If I use following then the script fails at the ObjName.

$pOldFuncTest=ReplaceVTableFuncPtr($pObj,0,$pNewFuncTest)

Currently if I use 5 or 6 for $iCustomOffset(20 or 24 offset) then my replacement function gets called which is not what I want. With value of 5 script crashes. With value of 6 then  _D2D_RenderTarget_Clear also calls my replacement function. I might try with more offsets for now.

 

Edited by ahmet
Link to post
Share on other sites
Local $pPointer = DllStructGetData( DllStructCreate( "ptr", $pVTable ), 1 ) + $iOffset, $PAGE_EXECUTE_READWRITE = 0x40

I'm not trying to be rude but looking at the above tells me that there's a fundamental flaw in either your ability to understand what you are doing or the code is such a mess that you're confusing yourself.   Please explain to me what exactly you are trying to accomplish in the above lines?    It looks like you are grabbing the value of the pointer that the pp** points to and adding the offset to that value.   I can almost certainly assure you that is incorrect.   The v table is a block of sequential memory addresses (pointers) that contain pointers to other functions.   Theres no guarantee that the addresses of those other functions are sequential and actually points to the instructions on what the function is  going to do hence the assembly.  There's not even any guarantee of the size depending on the amount of instructions.  Based on what I see so far you should probably take a few steps back and figure out what you are receiving as a return from d2d_factorycreate() bc if you have to use ptr() on it then it could be broken from there.   I mean snap open up a program that analyzes the memory.  You should literally be able to attach to the dll and see what is where.  And for the love of Beavis simplify the code a bit.  

Link to post
Share on other sites
Posted (edited)

@markyrocks thank you for your efforts to help. That line that you wrote is copied from the forum. Following example works. It uses same function. Also example from my second post works.

;#AutoIt3Wrapper_UseX64=y

#include <Array.au3>
#include <StructureConstants.au3>

#include "..\..\..\Includes\Utilities.au3"

Global Const $sCLSID_CUIAutomation = "{FF48DBA4-60EF-4201-AA87-54103EEF594E}"

Global Const $sIID_IUIAutomation = "{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}"
Global Const $stag_IUIAutomation = _
    "CompareElements hresult(ptr;ptr;long*);" & _
    "CompareRuntimeIds hresult(ptr;ptr;long*);" & _
    "GetRootElement hresult(ptr*);" & _
    "ElementFromHandle hresult(hwnd;ptr*);" & _
    "ElementFromPoint hresult(struct;ptr*);" & _
    "GetFocusedElement hresult(ptr*);" & _
    "GetRootElementBuildCache hresult(ptr;ptr*);" & _
    "ElementFromHandleBuildCache hresult(hwnd;ptr;ptr*);" & _
    "ElementFromPointBuildCache hresult(struct;ptr;ptr*);" & _
    "GetFocusedElementBuildCache hresult(ptr;ptr*);" & _
    "CreateTreeWalker hresult(ptr;ptr*);" & _
    "ControlViewWalker hresult(ptr*);" & _
    "ContentViewWalker hresult(ptr*);" & _
    "RawViewWalker hresult(ptr*);" & _
    "RawViewCondition hresult(ptr*);" & _
    "ControlViewCondition hresult(ptr*);" & _
    "ContentViewCondition hresult(ptr*);" & _
    "CreateCacheRequest hresult(ptr*);" & _
    "CreateTrueCondition hresult(ptr*);" & _
    "CreateFalseCondition hresult(ptr*);" & _
    "CreatePropertyCondition hresult(int;variant;ptr*);" & _
    "CreatePropertyConditionEx hresult(int;variant;long;ptr*);" & _
    "CreateAndCondition hresult(ptr;ptr;ptr*);" & _
    "CreateAndConditionFromArray hresult(ptr;ptr*);" & _
    "CreateAndConditionFromNativeArray hresult(ptr;int;ptr*);" & _
    "CreateOrCondition hresult(ptr;ptr;ptr*);" & _
    "CreateOrConditionFromArray hresult(ptr;ptr*);" & _
    "CreateOrConditionFromNativeArray hresult(ptr;int;ptr*);" & _
    "CreateNotCondition hresult(ptr;ptr*);" & _
    "AddAutomationEventHandler hresult(int;ptr;long;ptr;ptr);" & _
    "RemoveAutomationEventHandler hresult(int;ptr;ptr);" & _
    "AddPropertyChangedEventHandlerNativeArray hresult(ptr;long;ptr;ptr;struct*;int);" & _
    "AddPropertyChangedEventHandler hresult(ptr;long;ptr;ptr;ptr);" & _
    "RemovePropertyChangedEventHandler hresult(ptr;ptr);" & _
    "AddStructureChangedEventHandler hresult(ptr;long;ptr;ptr);" & _
    "RemoveStructureChangedEventHandler hresult(ptr;ptr);" & _
    "AddFocusChangedEventHandler hresult(ptr;ptr);" & _
    "RemoveFocusChangedEventHandler hresult(ptr);" & _
    "RemoveAllEventHandlers hresult();" & _
    "IntNativeArrayToSafeArray hresult(int;int;ptr*);" & _
    "IntSafeArrayToNativeArray hresult(ptr;int*;int*);" & _
    "RectToVariantEx hresult(struct*;variant*);" & _ ; <<<< RectToVariant >>>>
    "VariantToRect hresult(variant;struct*);" & _
    "SafeArrayToRectNativeArray hresult(ptr;struct*;int*);" & _
    "CreateProxyFactoryEntry hresult(ptr;ptr*);" & _
    "ProxyFactoryMapping hresult(ptr*);" & _
    "GetPropertyProgrammaticName hresult(int;bstr*);" & _
    "GetPatternProgrammaticName hresult(int;bstr*);" & _
    "PollForPotentialSupportedPatterns hresult(ptr;ptr*;ptr*);" & _
    "PollForPotentialSupportedProperties hresult(ptr;ptr*;ptr*);" & _
    "CheckNotSupported hresult(variant;long*);" & _
    "ReservedNotSupportedValue hresult(ptr*);" & _
    "ReservedMixedAttributeValue hresult(ptr*);" & _
    "ElementFromIAccessible hresult(idispatch;int;ptr*);" & _
    "ElementFromIAccessibleBuildCache hresult(iaccessible;int;ptr;ptr*);"

Global $pRectToVariant ; Original RectToVariant function pointer

Opt( "MustDeclareVars", 1 )

Example1()

Func Example1()
    ; Create UIAutomation object
    Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $stag_IUIAutomation )

    ; Replace RectToVariant with RectToVariantEx
    ; And get original RectToVariant function pointer
    Local $pRectToVariantEx = DllCallbackGetPtr( DllCallbackRegister( "RectToVariantEx", "long", "ptr;ptr;ptr*" ) )
    $pRectToVariant = ReplaceVTableFuncPtr( Ptr( $oUIAutomation() ), ( 3 + 42 - 1 ) * ( @AutoItX64 ? 8 : 4 ), $pRectToVariantEx )

    ; Create rectangle structure
    Local $tRect = DllStructCreate( $tagRECT )
    DllStructSetData( $tRect, "Left",    100 )
    DllStructSetData( $tRect, "Top",     200 )
    DllStructSetData( $tRect, "Right",  3000 )
    DllStructSetData( $tRect, "Bottom", 4000 )

    ; Output array
    Local $aArray

    ; Execute RectToVariantEx method
    $oUIAutomation.RectToVariantEx( $tRect, $aArray )

    ; Display array
    _ArrayDisplay( $aArray )
EndFunc

Func RectToVariantEx( $pSelf, $pRect, $pVariant )
    ; Here it's possible to debug and modify parameters after conver-
    ; sions on function entry but before the original method is executed.

    ; Execute original RectToVariant method
    Local $aRet = DllCallAddress( "long", $pRectToVariant, "ptr", $pSelf, @AutoItX64 ? "struct*" : "struct", DllStructCreate( $tagRECT, $pRect ), "ptr", $pVariant )
    ; Note that no COM conversions are applied neither to DllCall nor DllCallAddress functions

    ; Here it's possible to debug and modify parameters after the origi-
    ; nal method is executed but before conversions on function exit.

    Return $aRet[0]
EndFunc

Ptr() function I am using because above example uses it and it works, but as it looks it can not be applied in my example with Direct2DWrite. I tried hooking into GetRootElement above and it worked. Only difference that I could see between my example and the one above is that the object in the latter is created from CLSID, while my example uses address to object pointer.

I have modified function and now it seems to work.

Func _DWrite_Factory_Create()
    Local $tIID_IDWriteFactory = _WinAPI_GUIDFromString($sIID_IDWriteFactory)

    Local $aResult = DllCall($__g_hDWriteDLL, "int", "DWriteCreateFactory", "uint", 0, "struct*", $tIID_IDWriteFactory, "ptr*", 0)
    If @error Or $aResult[0] Then Return SetError(1, 1, False)

    Local $oObj = ObjCreateInterface($aResult[3], $sIID_IDWriteFactory, $tagIDWriteFactory)
    If Not IsObj($oObj) Then Return SetError($DWRITEERR_OBJFAIL, 2, False)
    Local $aRet[2]=[$oObj, $aResult[3]];<---- Now function returns this, I use second argument as a first rgument to ReplaceVTableFuncPtr
    Return $aRet
EndFunc   ;==>_IDWriteFactory_Create

Is there other way of retrieving this pointer instead of rewriting all functions?

Edited by ahmet
Link to post
Share on other sites
46 minutes ago, ahmet said:

@markyrocks 

 

 

Is there other way of retrieving this pointer instead of rewriting all functions?

I could not tell you atm bc I don't have the original scripts in front of me atm. I'd still love to see the fixed version of the replace vtable function.   As a word of caution there's no guarantee posted examples work or still work.  That thread is almost 12 years old so undoubtedly the rules of the language have evolved.   I've personally never seen a function call in any language that looked like this...  func(a,b,c) , d

Maybe the parenthesis was cut off somehow but they appeared balanced...idk maybe I been staring at code too long.

Anyways, glad to help. Yw

Edited by markyrocks
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...