11/*
22 * KNSoft.SlimDetours (https://github.com/KNSoft/KNSoft.SlimDetours) Function Table Hook Implementation
3- *
4- * Hook function address in a read-only table, used by COM/IAT/EAT/ ... hooking.
5- *
3+ *
4+ * Hook function address in a read-only table, used by COM/IAT/... hooking.
5+ *
66 * Copyright (c) KNSoft.org (https://github.com/KNSoft). All rights reserved.
77 * Licensed under the MIT license.
88 */
@@ -75,11 +75,11 @@ detour_hook_table_funcs(
7575 Method = Add2Ptr (pFuncTable , pHooks [i ].ulOffset );
7676 if (bEnable )
7777 {
78- * pHooks [i ].ppOriginal = * Method ;
79- * Method = pHooks [i ].pDetour ;
78+ * pHooks [i ].ppOldFunc = * Method ;
79+ * Method = pHooks [i ].pNewFunc ;
8080 } else
8181 {
82- * Method = * pHooks [i ].ppOriginal ;
82+ * Method = * pHooks [i ].ppOldFunc ;
8383 }
8484 }
8585
@@ -89,32 +89,105 @@ detour_hook_table_funcs(
8989
9090HRESULT
9191NTAPI
92- SlimDetoursSetTableHook (
92+ SlimDetoursFuncTableHook (
9393 _In_ PVOID * pFuncTable ,
9494 _In_ ULONG ulOffset ,
95- _Out_ PVOID * ppOriginal ,
96- _In_ PVOID pDetour )
95+ _Out_opt_ PVOID * ppOldFunc ,
96+ _In_ PVOID pNewFunc )
9797{
98- return HRESULT_FROM_NT (detour_hook_table_func (pFuncTable , ulOffset , ppOriginal , pDetour ));
98+ return HRESULT_FROM_NT (detour_hook_table_func (pFuncTable , ulOffset , ppOldFunc , pNewFunc ));
9999}
100100
101101HRESULT
102102NTAPI
103- SlimDetoursUnsetTableHook (
103+ SlimDetoursFuncTableHooks (
104+ _In_ BOOL bEnable ,
104105 _In_ PVOID * pFuncTable ,
105- _In_ ULONG ulOffset ,
106- _In_ PVOID pOriginal )
106+ _In_ ULONG ulCount ,
107+ _Inout_updates_ ( ulCount ) PDETOUR_FUNC_TABLE_HOOK pHooks )
107108{
108- return HRESULT_FROM_NT (detour_hook_table_func ( pFuncTable , ulOffset , NULL , pOriginal ));
109+ return HRESULT_FROM_NT (detour_hook_table_funcs ( bEnable , pFuncTable , ulCount , pHooks ));
109110}
110111
112+ /* COM Hook */
113+
114+ typedef
115+ _Check_return_
116+ HRESULT
117+ STDAPICALLTYPE
118+ FN_CoCreateInstanceEx (
119+ _In_ REFCLSID Clsid ,
120+ _In_opt_ IUnknown * punkOuter ,
121+ _In_ DWORD dwClsCtx ,
122+ _In_opt_ COSERVERINFO * pServerInfo ,
123+ _In_ DWORD dwCount ,
124+ _Inout_updates_ (dwCount ) MULTI_QI * pResults );
125+
126+ static PVOID g_hComBase = NULL ;
127+
128+ static CONST UNICODE_STRING g_usCombaseDllName = RTL_CONSTANT_STRING (L"combase.dll" );
129+ static CONST ANSI_STRING g_asCoCreateInstanceEx = RTL_CONSTANT_STRING ("CoCreateInstanceEx" );
130+ static FN_CoCreateInstanceEx * g_pfnCoCreateInstanceEx = NULL ;
131+
132+ static PS_RUNONCE g_stRunOnceCombaseInit = PS_RUNONCE_INIT ;
133+ static NTSTATUS g_lCombaseInitStatus = STATUS_UNSUCCESSFUL ;
134+
111135HRESULT
112136NTAPI
113- SlimDetoursEnableTableHooks (
137+ SlimDetoursCOMHooks (
114138 _In_ BOOL bEnable ,
115- _In_ PVOID * pFuncTable ,
139+ _In_ REFCLSID rCLSID ,
140+ _In_ REFCLSID rIID ,
116141 _In_ ULONG ulCount ,
117142 _Inout_updates_ (ulCount ) PDETOUR_FUNC_TABLE_HOOK pHooks )
118143{
119- return HRESULT_FROM_NT (detour_hook_table_funcs (bEnable , pFuncTable , ulCount , pHooks ));
144+ NTSTATUS Status ;
145+ HRESULT hr ;
146+ MULTI_QI MQI = { rIID };
147+
148+ /* Initialize combase.dll */
149+ if (PS_RunOnceBegin (& g_stRunOnceCombaseInit ))
150+ {
151+ Status = LdrLoadDll (NULL , NULL , (PUNICODE_STRING )& g_usCombaseDllName , & g_hComBase );
152+ if (!NT_SUCCESS (Status ))
153+ {
154+ goto _Init_Exit ;
155+ }
156+ Status = LdrGetProcedureAddress (g_hComBase , (PANSI_STRING )& g_asCoCreateInstanceEx , 0 , (PVOID * )& g_pfnCoCreateInstanceEx );
157+ if (!NT_SUCCESS (Status ))
158+ {
159+ LdrUnloadDll (g_hComBase );
160+ g_hComBase = NULL ;
161+ goto _Init_Exit ;
162+ }
163+ Status = STATUS_SUCCESS ;
164+ _Init_Exit :
165+ g_lCombaseInitStatus = Status ;
166+ PS_RunOnceEnd (& g_stRunOnceCombaseInit , Status == STATUS_SUCCESS );
167+ }
168+ if (!NT_SUCCESS (g_lCombaseInitStatus ))
169+ {
170+ return HRESULT_FROM_NT (g_lCombaseInitStatus );
171+ }
172+
173+ /* Create COM Object and set VTable Hooks */
174+ hr = g_pfnCoCreateInstanceEx (rCLSID , NULL , CLSCTX_ALL , NULL , 1 , & MQI );
175+ if (FAILED (hr ))
176+ {
177+ goto _Create_Fail_0 ;
178+ }
179+ _Analysis_assume_ (MQI .pItf != NULL );
180+ Status = detour_hook_table_funcs (bEnable , (PVOID * )MQI .pItf -> lpVtbl , ulCount , pHooks );
181+ if (!NT_SUCCESS (Status ))
182+ {
183+ hr = HRESULT_FROM_NT (Status );
184+ goto _Create_Fail_1 ;
185+ }
186+ hr = S_OK ;
187+
188+ /* Cleanup */
189+ _Create_Fail_1 :
190+ MQI .pItf -> lpVtbl -> Release (MQI .pItf );
191+ _Create_Fail_0 :
192+ return hr ;
120193}
0 commit comments