SlimDetoursInlineHook
Places or removes one detour, and returns an HRESULT.
Syntax: SlimDetoursInlineHook ( bEnable, ppPointer, pDetour ) As Long
- bEnable
- required A Long: 1 to place the detour, 0 to remove it.
- ppPointer
- required A LongPtr variable, passed ByRef. To place a detour, it holds the address of the function’s code; to remove one, the trampoline that placing it stored there. The function changes it when it succeeds.
- pDetour
- required A LongPtr, the address of the detour.
Returns an HRESULT that SlimDetours makes from a Windows NTSTATUS code. Success is not 0: it is &H10000000, an HRESULT with only its facility bit for NTSTATUS codes set. A failure is a negative number, such as &HD0000173 for a removal whose pDetour is not the detour in place. So test the result with >= 0 for success and < 0 for failure, as the Detours procedures do.
When it places a detour, the function stores the trampoline, the address that calls the original function, in ppPointer. When it removes one, it frees the trampoline and stores the address of the function’s code in ppPointer again. When it fails, it leaves ppPointer and the function as they were.
SlimDetours changes the code with the process’s other threads suspended, and moves a thread that was in the middle of the replaced instructions, so the change is safe while other threads run.
Example
Private Declare PtrSafe Function MulDiv Lib "kernel32" (ByVal nNumber As Long, ByVal nNumerator As Long, ByVal nDenominator As Long) As Long
Private DeclareWide PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleW" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, ByVal lpProcName As String) As LongPtr
Private Delegate Function MulDivFn (ByVal nNumber As Long, ByVal nNumerator As Long, ByVal nDenominator As Long) As Long
Private pMulDiv As LongPtr
Private Function MyMulDiv(ByVal nNumber As Long, ByVal nNumerator As Long, ByVal nDenominator As Long) As Long
Dim original As MulDivFn = CType(Of MulDivFn)(pMulDiv)
Return original(nNumber, nNumerator, nDenominator) + 1
End Function
Public Sub Demo()
pMulDiv = GetProcAddress(GetModuleHandle("kernel32"), "MulDiv")
Dim hr As Long = SlimDetoursInlineHook(1, pMulDiv, AddressOf MyMulDiv)
If hr < 0 Then
Debug.Print "Not placed: &H"; Hex(hr)
Exit Sub
End If
Debug.Print MulDiv(6, 4, 3) ' 9, from MyMulDiv
hr = SlimDetoursInlineHook(0, pMulDiv, AddressOf MyMulDiv)
Debug.Print MulDiv(6, 4, 3) ' 8, from the original
End Sub
See Also
- CreateDetourAtFuncAddress function – the same, with its result turned into an error
- RemoveDetour procedure