Skip to content

Commit 6efc247

Browse files
mamoreau-devolutionsawakecoding
authored andcommitted
handle vtable differences in ITSPropertySet
1 parent 82560f4 commit 6efc247

File tree

3 files changed

+158
-27
lines changed

3 files changed

+158
-27
lines changed

dll/MsRdpEx.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ static bool g_AxHookEnabled = true;
2020
static bool g_IsOOBClient = false;
2121
static bool g_IsClientProcess = false;
2222

23-
static MsRdpEx_mstscax g_mstscax = { 0 };
24-
static MsRdpEx_rdclientax g_rdclientax = { 0 };
23+
MsRdpEx_mstscax g_mstscax = { 0 };
24+
MsRdpEx_rdclientax g_rdclientax = { 0 };
2525

2626
HRESULT STDAPICALLTYPE DllCanUnloadNow()
2727
{

dll/RdpSettings.cpp

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99

1010
#include <intrin.h>
1111

12+
#include "MsRdpEx.h"
1213
#include "TSObjects.h"
1314

1415
extern "C" const GUID IID_ITSPropertySet;
1516

17+
extern MsRdpEx_mstscax g_mstscax;
18+
extern MsRdpEx_rdclientax g_rdclientax;
19+
1620
static bool g_TSPropertySet_Hooked = false;
1721

1822
static ITSPropertySet_SetBoolProperty Real_ITSPropertySet_SetBoolProperty = NULL;
@@ -129,8 +133,8 @@ static HRESULT Hook_ITSPropertySet_SetStringProperty(ITSPropertySet* This, const
129133
HRESULT hr;
130134

131135
char* propValueA = _com_util::ConvertBSTRToString((BSTR) propValue);
132-
133136
MsRdpEx_LogPrint(TRACE, "ITSPropertySet::SetStringProperty(%s, \"%s\")", propName, propValueA);
137+
delete[] propValueA;
134138

135139
hr = Real_ITSPropertySet_SetStringProperty(This, propName, propValue);
136140

@@ -143,7 +147,14 @@ static HRESULT Hook_ITSPropertySet_GetStringProperty(ITSPropertySet* This, const
143147

144148
hr = Real_ITSPropertySet_GetStringProperty(This, propName, propValue);
145149

146-
MsRdpEx_LogPrint(TRACE, "ITSPropertySet::GetStringProperty(%s)", propName);
150+
if (SUCCEEDED(hr)) {
151+
char* propValueA = _com_util::ConvertBSTRToString((BSTR)*propValue);
152+
MsRdpEx_LogPrint(TRACE, "ITSPropertySet::GetStringProperty(%s, \"%s\")", propName, propValueA);
153+
delete[] propValueA;
154+
}
155+
else {
156+
MsRdpEx_LogPrint(TRACE, "ITSPropertySet::GetStringProperty(%s), hr = 0x%08X", propName, hr);
157+
}
147158

148159
return hr;
149160
}
@@ -173,22 +184,39 @@ static HRESULT Hook_ITSPropertySet_GetSecureStringProperty(ITSPropertySet* This,
173184
return hr;
174185
}
175186

176-
static bool TSPropertySet_Hook(ITSPropertySet* pTSPropertySet)
187+
static bool TSPropertySet_Hook(ITSPropertySet* pTSPropertySet, ITSPropertySetVtbl30* vtbl30, ITSPropertySetVtbl32* vtbl32)
177188
{
178189
LONG error;
179190

191+
if (!pTSPropertySet || (!vtbl30 && !vtbl32))
192+
return false;
193+
180194
DetourRestoreAfterWith();
181195
DetourTransactionBegin();
182196
DetourUpdateThread(GetCurrentThread());
183197

184-
Real_ITSPropertySet_SetBoolProperty = pTSPropertySet->vtbl->SetBoolProperty;
185-
Real_ITSPropertySet_GetBoolProperty = pTSPropertySet->vtbl->GetBoolProperty;
186-
Real_ITSPropertySet_SetIntProperty = pTSPropertySet->vtbl->SetIntProperty;
187-
Real_ITSPropertySet_GetIntProperty = pTSPropertySet->vtbl->GetIntProperty;
188-
Real_ITSPropertySet_SetStringProperty = pTSPropertySet->vtbl->SetStringProperty;
189-
Real_ITSPropertySet_GetStringProperty = pTSPropertySet->vtbl->GetStringProperty;
190-
Real_ITSPropertySet_SetSecureStringProperty = pTSPropertySet->vtbl->SetSecureStringProperty;
191-
Real_ITSPropertySet_GetSecureStringProperty = pTSPropertySet->vtbl->GetSecureStringProperty;
198+
if (vtbl32)
199+
{
200+
Real_ITSPropertySet_SetBoolProperty = vtbl32->SetBoolProperty;
201+
Real_ITSPropertySet_GetBoolProperty = vtbl32->GetBoolProperty;
202+
Real_ITSPropertySet_SetIntProperty = vtbl32->SetIntProperty;
203+
Real_ITSPropertySet_GetIntProperty = vtbl32->GetIntProperty;
204+
Real_ITSPropertySet_SetStringProperty = vtbl32->SetStringProperty;
205+
Real_ITSPropertySet_GetStringProperty = vtbl32->GetStringProperty;
206+
Real_ITSPropertySet_SetSecureStringProperty = vtbl32->SetSecureStringProperty;
207+
Real_ITSPropertySet_GetSecureStringProperty = vtbl32->GetSecureStringProperty;
208+
}
209+
else if (vtbl30)
210+
{
211+
Real_ITSPropertySet_SetBoolProperty = vtbl30->SetBoolProperty;
212+
Real_ITSPropertySet_GetBoolProperty = vtbl30->GetBoolProperty;
213+
Real_ITSPropertySet_SetIntProperty = vtbl30->SetIntProperty;
214+
Real_ITSPropertySet_GetIntProperty = vtbl30->GetIntProperty;
215+
Real_ITSPropertySet_SetStringProperty = vtbl30->SetStringProperty;
216+
Real_ITSPropertySet_GetStringProperty = vtbl30->GetStringProperty;
217+
Real_ITSPropertySet_SetSecureStringProperty = vtbl30->SetSecureStringProperty;
218+
Real_ITSPropertySet_GetSecureStringProperty = vtbl30->GetSecureStringProperty;
219+
}
192220

193221
DetourAttach((PVOID*)(&Real_ITSPropertySet_SetBoolProperty), Hook_ITSPropertySet_SetBoolProperty);
194222
DetourAttach((PVOID*)(&Real_ITSPropertySet_GetBoolProperty), Hook_ITSPropertySet_GetBoolProperty);
@@ -212,9 +240,27 @@ class CMsRdpPropertySet : public IMsRdpExtendedSettings
212240
m_pUnknown = pUnknown;
213241
pUnknown->QueryInterface(IID_ITSPropertySet, (LPVOID*)&m_pTSPropertySet);
214242

215-
if (!g_TSPropertySet_Hooked) {
216-
TSPropertySet_Hook(m_pTSPropertySet);
217-
g_TSPropertySet_Hooked = true;
243+
if (m_pTSPropertySet)
244+
{
245+
if (MsRdpEx_IsAddressInRdclientAxModule(m_pTSPropertySet->vtbl))
246+
{
247+
DWORD version = g_rdclientax.tscCtlVer;
248+
249+
if (version >= 5326) {
250+
m_vtbl32 = (ITSPropertySetVtbl32*)m_pTSPropertySet->vtbl;
251+
} else {
252+
m_vtbl30 = (ITSPropertySetVtbl30*)m_pTSPropertySet->vtbl;
253+
}
254+
}
255+
else
256+
{
257+
m_vtbl30 = (ITSPropertySetVtbl30*)m_pTSPropertySet->vtbl;
258+
}
259+
260+
if (!g_TSPropertySet_Hooked) {
261+
TSPropertySet_Hook(m_pTSPropertySet, m_vtbl30, m_vtbl32);
262+
g_TSPropertySet_Hooked = true;
263+
}
218264
}
219265
}
220266

@@ -308,6 +354,8 @@ class CMsRdpPropertySet : public IMsRdpExtendedSettings
308354
return SetBStrProperty(propName, pValue->bstrVal);
309355
}
310356

357+
delete[] propName;
358+
311359
return E_INVALIDARG;
312360
}
313361

@@ -336,6 +384,8 @@ class CMsRdpPropertySet : public IMsRdpExtendedSettings
336384
}
337385
}
338386

387+
delete[] propName;
388+
339389
return hr;
340390
}
341391

@@ -356,19 +406,29 @@ class CMsRdpPropertySet : public IMsRdpExtendedSettings
356406
}
357407

358408
HRESULT __stdcall GetVBoolProperty(const char* propName, VARIANT_BOOL* propValue) {
359-
HRESULT hr;
409+
HRESULT hr = E_FAIL;
360410
int iVal = 0;
361-
hr = m_pTSPropertySet->vtbl->GetBoolProperty(m_pTSPropertySet, propName, &iVal);
411+
412+
if (m_vtbl32) {
413+
hr = m_vtbl32->GetBoolProperty(m_pTSPropertySet, propName, &iVal);
414+
} else if (m_vtbl30) {
415+
hr = m_vtbl30->GetBoolProperty(m_pTSPropertySet, propName, &iVal);
416+
}
417+
362418
*propValue = iVal ? VARIANT_TRUE : VARIANT_FALSE;
363419
return hr;
364420
}
365421

366422
HRESULT __stdcall GetBStrProperty(const char* propName, BSTR* propValue) {
367-
HRESULT hr;
423+
HRESULT hr = E_FAIL;
368424
BSTR bstrVal = NULL;
369425
WCHAR* wstrVal = NULL;
370426

371-
hr = m_pTSPropertySet->vtbl->GetStringProperty(m_pTSPropertySet, propName, &wstrVal);
427+
if (m_vtbl32) {
428+
hr = m_vtbl32->GetStringProperty(m_pTSPropertySet, propName, &wstrVal);
429+
} else if (m_vtbl30) {
430+
hr = m_vtbl30->GetStringProperty(m_pTSPropertySet, propName, &wstrVal);
431+
}
372432

373433
if (hr != S_OK)
374434
return hr;
@@ -382,6 +442,8 @@ class CMsRdpPropertySet : public IMsRdpExtendedSettings
382442
ULONG m_refCount;
383443
IUnknown* m_pUnknown;
384444
ITSPropertySet* m_pTSPropertySet;
445+
ITSPropertySetVtbl30* m_vtbl30 = NULL;
446+
ITSPropertySetVtbl32* m_vtbl32 = NULL;
385447
};
386448

387449
CMsRdpExtendedSettings::CMsRdpExtendedSettings(IUnknown* pUnknown, GUID* pSessionId)
@@ -498,7 +560,7 @@ HRESULT __stdcall CMsRdpExtendedSettings::put_Property(BSTR bstrPropertyName, VA
498560
hr = this->SetKdcProxyUrl(propValue);
499561
}
500562

501-
free(propValue);
563+
delete[] propValue;
502564
hr = S_OK;
503565
}
504566
else if (MsRdpEx_StringEquals(propName, "EnableMouseJiggler"))
@@ -540,6 +602,7 @@ HRESULT __stdcall CMsRdpExtendedSettings::put_Property(BSTR bstrPropertyName, VA
540602

541603
char* propValueA = _com_util::ConvertBSTRToString((BSTR)pValue->bstrVal);
542604
strncpy_s(m_KeyboardHookToggleShortcutKey, propValueA, sizeof(m_KeyboardHookToggleShortcutKey) - 1);
605+
delete[] propValueA;
543606

544607
hr = S_OK;
545608
}
@@ -548,12 +611,14 @@ HRESULT __stdcall CMsRdpExtendedSettings::put_Property(BSTR bstrPropertyName, VA
548611
if (pValue->vt == VT_BSTR) {
549612
char* propValueA = _com_util::ConvertBSTRToString((BSTR)pValue->bstrVal);
550613
MsRdpEx_LogPrint(TRACE, "CMsRdpExtendedSettings::put_Property(%s, \"%s\")", propName, propValueA);
614+
delete[] propValueA;
551615
}
552616

553617
hr = m_pMsRdpExtendedSettings->put_Property(bstrPropertyName, pValue);
554618
}
555619

556620
end:
621+
delete[] propName;
557622
return hr;
558623
}
559624

@@ -645,6 +710,8 @@ HRESULT __stdcall CMsRdpExtendedSettings::get_Property(BSTR bstrPropertyName, VA
645710
hr = m_pMsRdpExtendedSettings->get_Property(bstrPropertyName, pValue);
646711
}
647712

713+
delete[] propName;
714+
648715
return hr;
649716
}
650717

@@ -653,6 +720,7 @@ HRESULT __stdcall CMsRdpExtendedSettings::get_Property(BSTR bstrPropertyName, VA
653720
HRESULT __stdcall CMsRdpExtendedSettings::put_CoreProperty(BSTR bstrPropertyName, VARIANT* pValue) {
654721
char* propName = _com_util::ConvertBSTRToString(bstrPropertyName);
655722
MsRdpEx_LogPrint(DEBUG, "CMsRdpExtendedSettings::put_CoreProperty(%s)", propName);
723+
delete[] propName;
656724

657725
if (!m_CoreProps)
658726
return E_INVALIDARG;
@@ -663,6 +731,7 @@ HRESULT __stdcall CMsRdpExtendedSettings::put_CoreProperty(BSTR bstrPropertyName
663731
HRESULT __stdcall CMsRdpExtendedSettings::get_CoreProperty(BSTR bstrPropertyName, VARIANT* pValue) {
664732
char* propName = _com_util::ConvertBSTRToString(bstrPropertyName);
665733
MsRdpEx_LogPrint(DEBUG, "CMsRdpExtendedSettings::get_CoreProperty(%s)", propName);
734+
delete[] propName;
666735

667736
if (!m_CoreProps)
668737
return E_INVALIDARG;
@@ -673,6 +742,7 @@ HRESULT __stdcall CMsRdpExtendedSettings::get_CoreProperty(BSTR bstrPropertyName
673742
HRESULT __stdcall CMsRdpExtendedSettings::put_BaseProperty(BSTR bstrPropertyName, VARIANT* pValue) {
674743
char* propName = _com_util::ConvertBSTRToString(bstrPropertyName);
675744
MsRdpEx_LogPrint(DEBUG, "CMsRdpExtendedSettings::put_BaseProperty(%s)", propName);
745+
delete[] propName;
676746

677747
if (!m_BaseProps)
678748
return E_INVALIDARG;
@@ -683,6 +753,7 @@ HRESULT __stdcall CMsRdpExtendedSettings::put_BaseProperty(BSTR bstrPropertyName
683753
HRESULT __stdcall CMsRdpExtendedSettings::get_BaseProperty(BSTR bstrPropertyName, VARIANT* pValue) {
684754
char* propName = _com_util::ConvertBSTRToString(bstrPropertyName);
685755
MsRdpEx_LogPrint(DEBUG, "CMsRdpExtendedSettings::get_BaseProperty(%s)", propName);
756+
delete[] propName;
686757

687758
if (!m_BaseProps)
688759
return E_INVALIDARG;

dll/TSObjects.h

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,21 @@ typedef HRESULT(__stdcall* ITSPropertySet_SetSecureStringProperty)(ITSPropertySe
5959
typedef HRESULT(__stdcall* ITSPropertySet_GetSecureStringProperty)(ITSPropertySet* This, const char* propName, WCHAR** propValue, uint32_t* propLength);
6060

6161
typedef struct ITSPropertySetVtbl
62+
{
63+
HRESULT(__stdcall* QueryInterface)(ITSPropertySet* This, REFIID riid, void** ppvObject);
64+
ULONG(__stdcall* AddRef)(ITSPropertySet* This);
65+
ULONG(__stdcall* Release)(ITSPropertySet* This);
66+
HRESULT(__stdcall* SetProperty)(ITSPropertySet* This, const char* propName, void* propValue);
67+
HRESULT(__stdcall* SetBoolProperty)(ITSPropertySet* This, const char* propName, int propValue);
68+
HRESULT(__stdcall* SetIntProperty)(ITSPropertySet* This, const char* propName, int propValue);
69+
HRESULT(__stdcall* SetIUnknownProperty)(ITSPropertySet* This, const char* propName, void* propValue);
70+
HRESULT(__stdcall* SetStringProperty)(ITSPropertySet* This, const char* propName, WCHAR* propValue);
71+
HRESULT(__stdcall* SetSecureStringProperty)(ITSPropertySet* This, const char* propName, WCHAR* propValue);
72+
HRESULT(__stdcall* SetUlongPtrProperty)(ITSPropertySet* This, const char* propName, ULONG_PTR propValue);
73+
// everything after this can change depending on the vtable
74+
} ITSPropertySetVtbl;
75+
76+
typedef struct ITSPropertySetVtbl30
6277
{
6378
HRESULT(__stdcall* QueryInterface)(ITSPropertySet* This, REFIID riid, void** ppvObject);
6479
ULONG(__stdcall* AddRef)(ITSPropertySet* This);
@@ -78,12 +93,57 @@ typedef struct ITSPropertySetVtbl
7893
HRESULT(__stdcall* GetStringProperty)(ITSPropertySet* This, const char* propName, WCHAR** propValue);
7994
HRESULT(__stdcall* GetSecureStringProperty)(ITSPropertySet* This, const char* propName, WCHAR** propValue, uint32_t* propLength);
8095
HRESULT(__stdcall* GetUlongPtrProperty)(ITSPropertySet* This, const char* propName, ULONG_PTR* propValue);
81-
HRESULT(__stdcall* EnterReadLock)(ITSPropertySet* This);
82-
HRESULT(__stdcall* LeaveReadLock)(ITSPropertySet* This);
83-
HRESULT(__stdcall* EnterWriteLock)(ITSPropertySet* This);
84-
HRESULT(__stdcall* LeaveWriteLock)(ITSPropertySet* This);
85-
HRESULT(__stdcall* RevertToDefaults)(ITSPropertySet* This);
86-
} ITSPropertySetVtbl;
96+
// EnterReadLock
97+
// LeaveReadLock
98+
// EnterWriteLock
99+
// LeaveWriteLock
100+
// RevertToDefaults
101+
// IsAutoLocking
102+
// IsPropSetWritable
103+
// LockPropSetForWrite
104+
// InternalPreSetProperty
105+
// InternalPostSetProperty
106+
// InternalPreGetProperty
107+
// InternalPostGetProperty
108+
} ITSPropertySetVtbl30;
109+
110+
// rdclientax.dll 1.2.5326.0+
111+
112+
typedef struct ITSPropertySetVtbl32
113+
{
114+
HRESULT(__stdcall* QueryInterface)(ITSPropertySet* This, REFIID riid, void** ppvObject);
115+
ULONG(__stdcall* AddRef)(ITSPropertySet* This);
116+
ULONG(__stdcall* Release)(ITSPropertySet* This);
117+
HRESULT(__stdcall* SetProperty)(ITSPropertySet* This, const char* propName, void* propValue);
118+
HRESULT(__stdcall* SetBoolProperty)(ITSPropertySet* This, const char* propName, int propValue);
119+
HRESULT(__stdcall* SetIntProperty)(ITSPropertySet* This, const char* propName, int propValue);
120+
HRESULT(__stdcall* SetIUnknownProperty)(ITSPropertySet* This, const char* propName, void* propValue);
121+
HRESULT(__stdcall* SetStringProperty)(ITSPropertySet* This, const char* propName, WCHAR* propValue);
122+
HRESULT(__stdcall* SetSecureStringProperty)(ITSPropertySet* This, const char* propName, WCHAR* propValue);
123+
HRESULT(__stdcall* SetUlongPtrProperty)(ITSPropertySet* This, const char* propName, ULONG_PTR propValue);
124+
HRESULT(__stdcall* GetProperty0)(ITSPropertySet* This, const char* propName, void* a1); // new function
125+
HRESULT(__stdcall* GetProperty1)(ITSPropertySet* This, const char* propName, WCHAR* a1, int a2);
126+
HRESULT(__stdcall* GetProperty2)(ITSPropertySet* This, const char* propName, uint32_t* a1);
127+
HRESULT(__stdcall* GetIntProperty)(ITSPropertySet* This, const char* propName, int* propValue);
128+
HRESULT(__stdcall* GetIUnknownProperty)(ITSPropertySet* This, const char* propName, IUnknown** propValue);
129+
HRESULT(__stdcall* GetBoolProperty)(ITSPropertySet* This, const char* propName, int* propValue);
130+
HRESULT(__stdcall* GetStringProperty)(ITSPropertySet* This, const char* propName, WCHAR** propValue);
131+
HRESULT(__stdcall* GetSecureStringProperty)(ITSPropertySet* This, const char* propName, WCHAR** propValue, uint32_t* propLength);
132+
HRESULT(__stdcall* GetUlongPtrProperty)(ITSPropertySet* This, const char* propName, ULONG_PTR* propValue);
133+
// EnterReadLock
134+
// LeaveReadLock
135+
// EnterWriteLock
136+
// LeaveWriteLock
137+
// RevertToDefaults
138+
// IsAutoLocking
139+
// IsPropSetWritable
140+
// LockPropSetForWrite
141+
// InternalPreSetProperty
142+
// InternalPostSetProperty
143+
// InternalPreGetProperty
144+
// InternalPostGetProperty
145+
// UnknownLastOrPadding
146+
} ITSPropertySetVtbl32;
87147

88148
struct _ITSPropertySet
89149
{

0 commit comments

Comments
 (0)