RDPWD!WDWParseUserData函数分析之Loop through user data–非常重要
参考:
21:19:13.859 892CDCFC.E13610C8 TermDD: IcaDefeferenceChannel: cc 5, vc 31, ref 2
21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WD_Ioctl 0816 Got TSHARE_CONF_CONNECT IOCtl
21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWParseUser 1484 GCC_H221_NONSTANDARD_KEY
44 75 63 61 Duca
21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWParseUser 1615 Our client's User Data
01 C0 D4 00 04 00 08 00 40 06 38 04 01 CA 03 AA ……..@.8…..
04 08 00 00 CE 0E 00 00 4F 00 53 00 2D 00 32 00 ……..O.S.-.2.
30 00 32 00 35 00 30 00 37 00 30 00 31 00 58 00 0.2.5.0.7.0.1.X.
45 00 42 00 4C 00 00 00 04 00 00 00 00 00 00 00 E.B.L………..
0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 01 CA 01 00 00 00 00 00 18 00 07 00 …………….
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 04 C0 0C 00 0D 00 00 00 00 00 00 00 …………….
02 C0 0C 00 1B 00 00 00 00 00 00 00 03 C0 2C 00 …………..,.
03 00 00 00 72 64 70 64 72 00 00 00 00 00 80 80 ….rdpdr…….
63 6C 69 70 72 64 72 00 00 00 A0 C0 72 64 70 73 cliprdr…..rdps
6E 64 00 00 00 00 00 C0 nd……
21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWParseUser 1631 Core data
01 C0 D4 00 04 00 08 00 40 06 38 04 01 CA 03 AA ……..@.8…..
04 08 00 00 CE 0E 00 00 4F 00 53 00 2D 00 32 00 ……..O.S.-.2.
30 00 32 00 35 00 30 00 37 00 30 00 31 00 58 00 0.2.5.0.7.0.1.X.
45 00 42 00 4C 00 00 00 04 00 00 00 00 00 00 00 E.B.L………..
0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 01 CA 01 00 00 00 00 00 18 00 07 00 …………….
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 ….
21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWParseUser 1674 Cluster data
04 C0 0C 00 0D 00 00 00 00 00 00 00 …………
21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWParseUser 1650 Security data
02 C0 0C 00 1B 00 00 00 00 00 00 00 …………
21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWParseUser 1662 Net data
03 C0 2C 00 03 00 00 00 72 64 70 64 72 00 00 00 ..,…..rdpdr…
00 00 80 80 63 6C 69 70 72 64 72 00 00 00 A0 C0 ….cliprdr…..
72 64 70 73 6E 64 00 00 00 00 00 C0 rdpsnd……
参考:
21:57:02.484 89617F7C.E31087D0 TShrSRV: TSrvInitWD entry
21:57:02.484 89410AD4.E178D118 GCC: mcsCallback exit – 0x0
21:57:02.484 89410AD4.E178D118 TermDD: IcaReferenceChannel: cc 5, vc 31, ref 1
21:57:02.484 89617F7C.E31087D0 TShrSRV: Performing WDTShare connection info exchange
21:57:02.484 89410AD4.E178D118 TermDD: IcaDefeferenceChannel: cc 5, vc 31, ref 2
21:57:02.484 89617F7C.E31087D0 TShrSRV: TSrvInitWDConnectInfo entry
21:57:02.484 89617F7C.E31087D0 TShrSRV: Allocated 0x80 bytes to recieve WDTShare return data
21:57:02.484 89617F7C.E31087D0 TShrSRV: Performing connect (size=128)
21:57:02.484 89617F7C.E31087D0 TermDD: IcaDeviceControlStack, fc 2304 (enter)
21:57:02.484 89617F7C.E31087D0 RDP E1026010 WD_Ioctl 0489 IOCTL_TSHARE_CONF_CONNECT (2304)
21:57:02.484 89617F7C.E31087D0 RDP E1026010 WD_Ioctl 0816 Got TSHARE_CONF_CONNECT IOCtl
Breakpoint 12 hit
RDPWD!WDWParseUserData:
b9d45f20 55 push ebp
0: kd> kc
#
00 RDPWD!WDWParseUserData
01 RDPWD!WDWConfConnect
02 RDPWD!WD_Ioctl
03 termdd!_IcaCallSd
04 termdd!_IcaCallStack
05 termdd!IcaDeviceControlStack
06 termdd!IcaDeviceControl
07 termdd!IcaDispatch
08 nt!IofCallDriver
09 nt!IopSynchronousServiceTail
0a nt!IopXxxControlFile
0b nt!NtDeviceIoControlFile
0c nt!_KiSystemService
0d SharedUserData!SystemCallStub
0e ntdll!NtDeviceIoControlFile
0f icaapi!IcaIoControl
10 icaapi!_IcaStackIoControlWorker
11 icaapi!IcaStackIoControl
12 rdpwsx!TSrvInitWDConnectInfo
13 rdpwsx!TSrvInitWD
14 rdpwsx!TSrvConfCreateResp
15 rdpwsx!TSrvDoConnectResponse
16 rdpwsx!TSrvDoConnect
17 rdpwsx!TSrvStackConnect
18 rdpwsx!WsxIcaStackIoControl
19 termsrv!WsxStackIoControl
1a icaapi!_IcaStackIoControl
1b icaapi!_IcaStackWaitForIca
1c icaapi!IcaStackConnectionAccept
1d termsrv!TransferConnectionToIdleWinStation
1e termsrv!WinStationTransferThread
1f kernel32!BaseThreadStart
0: kd> dv
pTSWd = 0xe1026010
pUserData = 0x00d632f0
UserDataLen = 0x154
pHeader = 0x00000000
cbParsedData = 0
ppClientCoreData = 0xb9c28484
ppClientSecurityData = 0xb9c28488
ppClientNetData = 0xb9c2848c
ppClientClusterData = 0xb9c28474
clientH221Key = char [5] “???”
trc_fn = 0xb9c28be0 “???”
trc_file = 0x00000030 “— memory read error at address 0x00000030 —“
dataLen = 0xb9d226b0
success = 0n-1990576696
pStr = 0x895c6ae0 “???”
pClientUserData = 0xb9c28494
__fnname = char [17] “WDWParseUserData”
pEnd = 0x00000000
pOctet = 0xb9d45f21
keyLen = 8
0: kd> dx -r1 ((RDPWD!_USERDATAINFO *)0xd632f0)
((RDPWD!_USERDATAINFO *)0xd632f0) : 0xd632f0 [Type: _USERDATAINFO *]
[+0x000] cbSize : 0x154 [Type: unsigned long]
[+0x004] version : 0x0 [Type: unsigned long]
[+0x008] hDomain : 0xd63f88 [Type: void *]
[+0x00c] ulUserDataMembers : 0x1 [Type: unsigned long]
[+0x010] rgUserData [Type: GCCUserData [1]]
0: kd> dx -r1 (*((RDPWD!GCCUserData (*)[1])0xd63300))
(*((RDPWD!GCCUserData (*)[1])0xd63300)) [Type: GCCUserData [1]]
[0] [Type: GCCUserData]
0: kd> dx -r1 (*((RDPWD!GCCUserData *)0xd63300))
(*((RDPWD!GCCUserData *)0xd63300)) [Type: GCCUserData]
[+0x000] key [Type: GCCObjectKey]
[+0x00c] octet_string : 0x34 [Type: GCCOctetString *]
0: kd> dx -r1 (*((RDPWD!GCCObjectKey *)0xd63300))
(*((RDPWD!GCCObjectKey *)0xd63300)) [Type: GCCObjectKey]
[+0x000] key_type : GCC_H221_NONSTANDARD_KEY (2) [Type: GCCObjectKeyType]
[+0x004] u [Type: __unnamed]
0: kd> dx -r1 (*((RDPWD!__unnamed *)0xd63304))
(*((RDPWD!__unnamed *)0xd63304)) [Type: __unnamed]
[+0x000] object_id [Type: GCCLongString]
[+0x000] h221_non_standard_id [Type: GCCOctetString]
0: kd> dx -r1 (*((RDPWD!GCCOctetString *)0xd63304))
(*((RDPWD!GCCOctetString *)0xd63304)) [Type: GCCOctetString]
[+0x000] octet_string_length : 0x4 [Type: unsigned short]
[+0x004] octet_string : 0x30 : Unable to read memory at Address 0x30 [Type: unsigned char *]
0: kd> dx -r1 ((RDPWD!unsigned char *)0x30)
((RDPWD!unsigned char *)0x30) : 0x30 : Unable to read memory at Address 0x30 [Type: unsigned char *]
Unable to read memory at Address 0x30
0: kd> db 0xd63304
00d63304 04 00 fc 70 30 00 00 00-34 00 00 00 00 00 00 00 …p0…4…….
00d63314 00 00 00 00 00 00 00 00-00 00 00 00 44 75 63 61 …………Duca
00d63324 18 01 00 00 3c 00 00 00-01 c0 d4 00 04 00 08 00 ….<………..
00d63334 40 06 38 04 01 ca 03 aa-04 08 00 00 ce 0e 00 00 @.8………….
00d63344 57 00 49 00 4e 00 37 00-2d 00 32 00 30 00 32 00 W.I.N.7.-.2.0.2.
00d63354 34 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 4……………
00d63364 04 00 00 00 00 00 00 00-0c 00 00 00 00 00 00 00 …………….
00d63374 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
/****************************************************************************/
/* H221 keys. */
/****************************************************************************/
#define H221_KEY_LEN 4
#define SERVER_H221_KEY “McDn”
#define CLIENT_H221_KEY “Duca”
char clientH221Key[] = CLIENT_H221_KEY;
// Actual GCC user data so parse it to make sure it's good.
if (pHeader == NULL) {
// We assume the data length was checked by the caller for at least
// the length of the USERDATAINFO header. We have to validate the rest.
// We are expecting exactly 1 piece of user data.
if (pUserData->ulUserDataMembers == 1) {
// Check that it has a non-standard key.
pClientUserData = &(pUserData->rgUserData[0]);
0: kd> dv pClientUserData
pClientUserData = 0x00d63300
0: kd> dx -r1 ((RDPWD!GCCUserData *)0xd63300)
((RDPWD!GCCUserData *)0xd63300) : 0xd63300 [Type: GCCUserData *]
[+0x000] key [Type: GCCObjectKey]
[+0x00c] octet_string : 0x34 [Type: GCCOctetString *]
if (pClientUserData->key.key_type == GCC_H221_NONSTANDARD_KEY) {
// Check it has our non-standard key.
keyLen = pClientUserData->key.u.h221_non_standard_id.
octet_string_length;
pStr = (unsigned char *)((BYTE *)pUserData +
(UINT_PTR)pClientUserData->key.u.
h221_non_standard_id.octet_string);
0: kd> dv pStr
pStr = 0x00d63320 “Duca???”
0: kd> dx -r1 (*((RDPWD!GCCOctetString *)0xd63304))
(*((RDPWD!GCCOctetString *)0xd63304)) [Type: GCCOctetString]
[+0x000] octet_string_length : 0x4 [Type: unsigned short]
[+0x004] octet_string : 0x30 : Unable to read memory at Address 0x30 [Type: unsigned char *]
0x30是字符串octet_string的偏移
0: kd> dv
pTSWd = 0xe1026010
pUserData = 0x00d632f0
0: kd> db 0x00d632f0
00d632f0 54 01 00 00 00 00 00 00-88 3f d6 00 01 00 00 00 T……..?……
00d63300 02 00 00 00 04 00 fc 70-30 00 00 00 34 00 00 00 …….p0…4…
00d63310 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d63320 44 75 63 61 18 01 00 00-3c 00 00 00 01 c0 d4 00 Duca….<…….
TRC_DATA_DBG(“GCC_H221_NONSTANDARD_KEY”, pStr, keyLen);
0: kd> p
RDPWD!WDWParseUserData+0xcf:
b9d45fef 52 push edx
0: kd> p
RDPWD!WDWParseUserData+0xd0:
b9d45ff0 e88b85ffff call RDPWD!TRC_TraceLine (b9d3e580)
0: kd> p
21:57:02.500 89617F7C.E31087D0 RDP E1026010 WDWParseUser 1484 GCC_H221_NONSTANDARD_KEY
RDPWD!WDWParseUserData+0xd5:
b9d45ff5 8b45fc mov eax,dword ptr [ebp-4]
0: kd> p
RDPWD!WDWParseUserData+0xe8:
b9d46008 e83bec0200 call RDPWD!IcaStackTraceBuffer (b9d74c48)
0: kd> p
44 75 63 61 Duca
RDPWD!WDWParseUserData+0xed:
b9d4600d 837dfc04 cmp dword ptr [ebp-4],4
参考:
21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWParseUser 1484 GCC_H221_NONSTANDARD_KEY
44 75 63 61 Duca
参考:
if ((keyLen != sizeof(clientH221Key) – 1) ||
((PBYTE)pStr < (PBYTE)pUserData) ||
((PBYTE)pStr+keyLen > (PBYTE)(pUserData) + UserDataLen)) {
TRC_ERR((TB, “Invalid key buffer %d %p”, keyLen, pStr));
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
DC_QUIT;
}
if (strncmp(pStr, clientH221Key, sizeof(clientH221Key) – 1)) {
TRC_ERR((TB, “Wrong key %*s”, pStr));
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
DC_QUIT;
}
上面是检验是否是字符串:Duca
// This is our client data.
// Save the domain handle for later.
pTSWd->hDomain = pUserData->hDomain;
// Parse the user data. Make sure the octet string is well-formed.
// pClientUserData->octet_string is an offset from the start of the
0: kd> dv
pTSWd = 0xe1026010
pUserData = 0x00d632f0
UserDataLen = 0x154
0: kd> dx -r1 ((RDPWD!_USERDATAINFO *)0xd632f0)
((RDPWD!_USERDATAINFO *)0xd632f0) : 0xd632f0 [Type: _USERDATAINFO *]
[+0x000] cbSize : 0x154 [Type: unsigned long]
[+0x004] version : 0x0 [Type: unsigned long]
[+0x008] hDomain : 0xd63f88 [Type: void *]
[+0x00c] ulUserDataMembers : 0x1 [Type: unsigned long]
[+0x010] rgUserData [Type: GCCUserData [1]]
0: kd> dx -r1 ((RDPWD!tagTSHARE_WD *)0xe1026010)
((RDPWD!tagTSHARE_WD *)0xe1026010) : 0xe1026010 [Type: tagTSHARE_WD *]
[+0x000] hDomainKernel : 0xe306c540 [Type: void *]
[+0x004] pContext : 0x895a35dc [Type: _SDCONTEXT *]
[+0x008] dead : 0x0 [Type: unsigned char]
[+0x009] bInShadowShare : 0x0 [Type: unsigned char]
[+0x00a] HotkeyVk : 0x0 [Type: unsigned char]
[+0x00c] HotkeyModifiers : 0x0 [Type: unsigned short]
[+0x010] pShadowInfo : 0x0 [Type: tagSHADOW_INFO *]
[+0x014] pShadowCert : 0x0 [Type: _SHADOWCERT *]
[+0x018] pShadowRandom : 0x0 [Type: _CLIENTRANDOM *]
[+0x01c] pUserData : 0x0 [Type: _USERDATAINFO *]
[+0x020] shadowState : 0x0 [Type: unsigned int]
[+0x024] pProtocolStatus : 0x89526588 [Type: _PROTOCOLSTATUS *]
[+0x028] desktopHeight : 0x0 [Type: unsigned int]
[+0x02c] desktopWidth : 0x0 [Type: unsigned int]
[+0x030] desktopBpp : 0x0 [Type: unsigned int]
[+0x034] supportedBpps : 0x0 [Type: unsigned int]
[+0x038] maxServerBpp : 0x10 [Type: unsigned int]
[+0x03c] ritTimer : 0x0 [Type: _KTIMER *]
[+0x040] pConnEvent : 0x89478628 [Type: _KEVENT *]
[+0x044] pCreateEvent : 0x89478638 [Type: _KEVENT *]
[+0x048] pSecEvent : 0x89478648 [Type: _KEVENT *]
[+0x04c] pSessKeyEvent : 0x89478658 [Type: _KEVENT *]
[+0x050] pClientDisconnectEvent : 0x89478668 [Type: _KEVENT *]
[+0x054] SessKeyCreationStatus : 0 [Type: long]
[+0x058] dcShare : 0x0 [Type: void *]
[+0x05c] pSmInfo : 0xe10267c8 [Type: void *]
[+0x060] pNMInfo : 0xe1026e30 [Type: void *]
[+0x064] pSLicenseHandle : 0x0 [Type: void *]
[+0x068] shareClassInit : 0x0 [Type: unsigned char]
[+0x069] connected : 0x0 [Type: unsigned char]
[+0x06a] shareCreated : 0x0 [Type: unsigned char]
[+0x06c] hDomain : 0x0 [Type: void *]
// Validate data length
if ((UINT_PTR)pClientUserData->octet_string < sizeof(USERDATAINFO))
{
TRC_ERR((TB,”UserData octet_string offset %p too short”,
pClientUserData->octet_string));
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
DC_QUIT;
}
0: kd> dx -r1 ((RDPWD!_USERDATAINFO *)0xd632f0)
((RDPWD!_USERDATAINFO *)0xd632f0) : 0xd632f0 [Type: _USERDATAINFO *]
[+0x000] cbSize : 0x154 [Type: unsigned long]
[+0x004] version : 0x0 [Type: unsigned long]
[+0x008] hDomain : 0xd63f88 [Type: void *]
[+0x00c] ulUserDataMembers : 0x1 [Type: unsigned long]
[+0x010] rgUserData [Type: GCCUserData [1]]
0: kd> dt GCCUserData 0x00d632f0+0x10
rdpwsx!GCCUserData
+0x000 key : GCCObjectKey
+0x00c octet_string : 0x00000034 GCCOctetString
0: kd> dx -id 0,0,89515c28 -r1 (*((rdpwsx!GCCObjectKey *)0xd63300))
(*((rdpwsx!GCCObjectKey *)0xd63300)) [Type: GCCObjectKey]
[+0x000] key_type : GCC_H221_NONSTANDARD_KEY (2) [Type: GCCObjectKeyType]
[+0x004] u [Type: __unnamed]
pOctet = (GCCOctetString UNALIGNED *)((PBYTE)pUserData +
(UINT_PTR)pClientUserData->octet_string);
0: kd> dt GCCOctetString 0x00d632f0+0x34
rdpwsx!GCCOctetString
+0x000 octet_string_length : 0x118
+0x004 octet_string : 0x0000003c “— memory read error at address 0x0000003c —“
0: kd> db 0x00d632f0
00d632f0 54 01 00 00 00 00 00 00-88 3f d6 00 01 00 00 00 T……..?……
00d63300 02 00 00 00 04 00 fc 70-30 00 00 00 34 00 00 00 …….p0…4…
00d63310 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d63320 44 75 63 61 18 01 00 00-3c 00 00 00 01 c0 d4 00 Duca….<…….
00d63330 04 00 08 00 40 06 38 04-01 ca 03 aa 04 08 00 00 ….@.8………
00d63340 ce 0e 00 00 57 00 49 00-4e 00 37 00 2d 00 32 00 ….W.I.N.7.-.2.
00d63350 30 00 32 00 34 00 00 00-00 00 00 00 00 00 00 00 0.2.4………..
00d63360 00 00 00 00 04 00 00 00-00 00 00 00 0c 00 00 00 …………….
0: kd> dv pOctet
pOctet = 0x00d63324
0: kd> dx -r1 ((RDPWD!GCCOctetString *)0xd63324)
((RDPWD!GCCOctetString *)0xd63324) : 0xd63324 [Type: GCCOctetString *]
[+0x000] octet_string_length : 0x118 [Type: unsigned short]
[+0x004] octet_string : 0x3c : Unable to read memory at Address 0x3c [Type: unsigned char *]
pHeader = (PRNS_UD_HEADER)((PBYTE)pUserData +
(UINT_PTR)pOctet->octet_string);
dataLen = pOctet->octet_string_length;
typedef struct tagRNS_UD_HEADER
{
TSUINT16 type;
TSUINT16 length;
} RNS_UD_HEADER;
0: kd> dt RNS_UD_HEADER 0x00d632f0+0x3c
rdpwsx!RNS_UD_HEADER
+0x000 type : 0xc001
+0x002 length : 0xd4
// We assume that the pre-parsed data is trusted.
pEnd = (PRNS_UD_HEADER)((PBYTE)pHeader + dataLen);
0: kd> dv pEnd
pEnd = 0x00d63444
0: kd> dv pHeader
pHeader = 0x00d6332c
dataLen = 0x118
0: kd> ?0x00d6332c+118
Evaluate expression: 14038084 = 00d63444
/****************************************************************************/
/* User data identifiers */
/****************************************************************************/
/****************************************************************************/
/* Client to Server IDs */
/****************************************************************************/
#define RNS_UD_CS_CORE_ID 0xc001
#define RNS_UD_CS_SEC_ID 0xc002
#define RNS_UD_CS_NET_ID 0xc003
#define TS_UD_CS_CLUSTER_ID 0xC004
// Loop through user data, extracting each piece.
do {
switch (pHeader->type) {
case RNS_UD_CS_CORE_ID:
// Beta2 Client core user data did not include the new
// field postBeta2ColorDepth, so check that the length of
// the incoming user data is at least this long.
// The WDWConnect parses this data and it checks the length we
// supply before it derefs parameters that are declared after
// postBeta2ColorDepth in the struct.
if (pHeader->length >=
(FIELDOFFSET(RNS_UD_CS_CORE, postBeta2ColorDepth) +
FIELDSIZE(RNS_UD_CS_CORE, postBeta2ColorDepth))) {
*ppClientCoreData = (PRNS_UD_CS_CORE)pHeader;
TRC_DATA_DBG(“Core data”, pHeader, pHeader->length);
}
else {
TRC_ERR((TB, “Core data not long enough — old client?”));
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
DC_QUIT;
}
break;
case RNS_UD_CS_SEC_ID:
// Old clients don't have the extEncryptionMethods.
// The extEncryptionMethods field is used only for french locale.
// We have to allow buffers that don't have space for extEncryptionMethods
// because the buffer will be processed in SM_Connect and there we take care of shorter fields.
// Nothing else processes this buffer after SM_Connect at this point.
if (pHeader->length >= FIELDOFFSET(RNS_UD_CS_SEC,encryptionMethods)
+ FIELDSIZE(RNS_UD_CS_SEC,encryptionMethods)) {
*ppClientSecurityData = (PRNS_UD_CS_SEC)pHeader;
TRC_DATA_DBG(“Security data”, pHeader, pHeader->length);
} else {
TRC_ERR((TB, “Security data not long enough”));
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
DC_QUIT;
}
break;
case RNS_UD_CS_NET_ID:
if (pHeader->length >= sizeof(RNS_UD_CS_NET)) {
*ppClientNetData = (PRNS_UD_CS_NET)pHeader;
TRC_DATA_DBG(“Net data”, pHeader, pHeader->length);
} else {
TRC_ERR((TB, “Net data not long enough”));
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
DC_QUIT;
}
break;
case TS_UD_CS_CLUSTER_ID:
if (pHeader->length >=sizeof(TS_UD_CS_CLUSTER)) {
*ppClientClusterData = (TS_UD_CS_CLUSTER *)pHeader;
TRC_DATA_DBG(“Cluster data”, pHeader, pHeader->length);
} else {
TRC_ERR((TB, “Cluster data not long enough”));
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
DC_QUIT;
}
break;
default:
TRC_ERR((TB, “Unknown user data type %d”, pHeader->type));
TRC_DATA_ERR(“Unknown user data”, pHeader, pHeader->length);
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
break;
}
if ((PBYTE)pHeader + pHeader->length < (PBYTE)pHeader) {
// we detected a length that causes overflow
TRC_ERR((TB, “Header length too big! Overflow detected !”));
WDW_LogAndDisconnect(pTSWd, TRUE,
Log_RDP_BadUserData, (PBYTE)pUserData, UserDataLen);
DC_QUIT;
}
// We check the zero length now after we update the pHeader value.
// Otherwize we will exit with an error when we actually check the sizes.
// don't get stuck here for ever…
if (pHeader->length == 0) {
TRC_ERR((TB, “header length was zero!”));
break;
}
// Move on to the next user data string.
pHeader = (PRNS_UD_HEADER)((PBYTE)pHeader + pHeader->length);
} while ((pHeader +1) <= pEnd);
0: kd> db 0x00d632f0
00d632f0 54 01 00 00 00 00 00 00-88 3f d6 00 01 00 00 00 T……..?……
00d63300 02 00 00 00 04 00 fc 70-30 00 00 00 34 00 00 00 …….p0…4…
00d63310 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d63320 44 75 63 61 18 01 00 00-3c 00 00 00 01 c0 d4 00 Duca….<…….
00d63330 04 00 08 00 40 06 38 04-01 ca 03 aa 04 08 00 00 ….@.8………
00d63340 ce 0e 00 00 57 00 49 00-4e 00 37 00 2d 00 32 00 ….W.I.N.7.-.2.
00d63350 30 00 32 00 34 00 00 00-00 00 00 00 00 00 00 00 0.2.4………..
00d63360 00 00 00 00 04 00 00 00-00 00 00 00 0c 00 00 00 …………….
0: kd> db 0x00d632f0+80
00d63370 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d63380 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d63390 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d633a0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d633b0 01 ca 01 00 00 00 00 00-18 00 07 00 01 00 00 00 …………….
00d633c0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d633d0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d633e0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
0: kd> db 0x00d632f0+80*2
00d633f0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d63400 04 c0 0c 00 0d 00 00 00-00 00 00 00 02 c0 0c 00 …………….
00d63410 1b 00 00 00 00 00 00 00-03 c0 2c 00 03 00 00 00 ……….,…..
00d63420 72 64 70 64 72 00 00 00-00 00 80 80 63 6c 69 70 rdpdr…….clip
00d63430 72 64 72 00 00 00 a0 c0-72 64 70 73 6e 64 00 00 rdr…..rdpsnd..
00d63440 00 00 00 c0 00 00 00 00-32 00 2c 00 01 01 10 00 ……..2.,…..
00d63450 00 00 00 00 04 00 08 00-68 2b d6 00 01 00 00 00 ……..h+……
00d63460 02 00 00 00 04 00 00 00-70 34 d6 00 74 34 d6 00 ……..p4..t4..
总的所有内容部分:
TRC_DATA_DBG(“Our client's User Data”, pHeader, dataLen);
0: kd> p
21:57:02.578 89617F7C.E31087D0 RDP E1026010 WDWParseUser 1615 Our client's User Data
01 C0 D4 00 04 00 08 00 40 06 38 04 01 CA 03 AA ……..@.8…..
04 08 00 00 CE 0E 00 00 57 00 49 00 4E 00 37 00 ……..W.I.N.7.
2D 00 32 00 30 00 32 00 34 00 00 00 00 00 00 00 -.2.0.2.4…….
00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 …………….
0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 01 CA 01 00 00 00 00 00 18 00 07 00 …………….
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 04 C0 0C 00 0D 00 00 00 00 00 00 00 …………….
02 C0 0C 00 1B 00 00 00 00 00 00 00 03 C0 2C 00 …………..,.
03 00 00 00 72 64 70 64 72 00 00 00 00 00 80 80 ….rdpdr…….
63 6C 69 70 72 64 72 00 00 00 A0 C0 72 64 70 73 cliprdr…..rdps
6E 64 00 00 00 00 00 C0 nd……
case RNS_UD_CS_CORE_ID:
// Beta2 Client core user data did not include the new
// field postBeta2ColorDepth, so check that the length of
// the incoming user data is at least this long.
// The WDWConnect parses this data and it checks the length we
// supply before it derefs parameters that are declared after
// postBeta2ColorDepth in the struct.
if (pHeader->length >=
(FIELDOFFSET(RNS_UD_CS_CORE, postBeta2ColorDepth) +
FIELDSIZE(RNS_UD_CS_CORE, postBeta2ColorDepth))) {
*ppClientCoreData = (PRNS_UD_CS_CORE)pHeader;
TRC_DATA_DBG(“Core data”, pHeader, pHeader->length);
}
0: kd> p
21:57:02.593 89617F7C.E31087D0 RDP E1026010 WDWParseUser 1631 Core data
01 C0 D4 00 04 00 08 00 40 06 38 04 01 CA 03 AA ……..@.8…..
04 08 00 00 CE 0E 00 00 57 00 49 00 4E 00 37 00 ……..W.I.N.7.
2D 00 32 00 30 00 32 00 34 00 00 00 00 00 00 00 -.2.0.2.4…….
00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 …………….
0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 01 CA 01 00 00 00 00 00 18 00 07 00 …………….
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
00 00 00 00 ….
0: kd> dt RNS_UD_CS_CORE 0x00d6332c
rdpwsx!RNS_UD_CS_CORE
+0x000 header : tagRNS_UD_HEADER
+0x004 version : 0x80004
+0x008 desktopWidth : 0x640
+0x00a desktopHeight : 0x438
+0x00c colorDepth : 0xca01
+0x00e SASSequence : 0xaa03
+0x010 keyboardLayout : 0x804
+0x014 clientBuild : 0xece
+0x018 clientName : [16] 0x57
+0x038 keyboardType : 4
+0x03c keyboardSubType : 0
+0x040 keyboardFunctionKey : 0xc
+0x044 imeFileName : [32] 0
+0x084 postBeta2ColorDepth : 0xca01
+0x086 clientProductId : 1
+0x088 serialNumber : 0
+0x08c highColorDepth : 0x18
+0x08e supportedColorDepths : 7
+0x090 earlyCapabilityFlags : 1
+0x092 clientDigProductId : [32] 0
0: kd> dx -id 0,0,89515c28 -r1 (*((rdpwsx!unsigned short (*)[16])0xd63344))
(*((rdpwsx!unsigned short (*)[16])0xd63344)) [Type: unsigned short [16]]
[0] : 0x57 [Type: unsigned short]
[1] : 0x49 [Type: unsigned short]
[2] : 0x4e [Type: unsigned short]
[3] : 0x37 [Type: unsigned short]
[4] : 0x2d [Type: unsigned short]
[5] : 0x32 [Type: unsigned short]
[6] : 0x30 [Type: unsigned short]
[7] : 0x32 [Type: unsigned short]
[8] : 0x34 [Type: unsigned short]
[9] : 0x0 [Type: unsigned short]
[10] : 0x0 [Type: unsigned short]
[11] : 0x0 [Type: unsigned short]
[12] : 0x0 [Type: unsigned short]
[13] : 0x0 [Type: unsigned short]
[14] : 0x0 [Type: unsigned short]
[15] : 0x0 [Type: unsigned short]
0: kd> db 0xd63344
00d63344 57 00 49 00 4e 00 37 00-2d 00 32 00 30 00 32 00 W.I.N.7.-.2.0.2.
00d63354 34 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 4……………
00d63364 04 00 00 00 00 00 00 00-0c 00 00 00 00 00 00 00 …………….
00d63374 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d63384 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d63394 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
00d633a4 00 00 00 00 00 00 00 00-00 00 00 00 01 ca 01 00 …………….
00d633b4 00 00 00 00 18 00 07 00-01 00 00 00 00 00 00 00 …………….
0: kd> dx -id 0,0,89515c28 -r1 (*((rdpwsx!unsigned short (*)[32])0xd63370))
(*((rdpwsx!unsigned short (*)[32])0xd63370)) [Type: unsigned short [32]]
[0] : 0x0 [Type: unsigned short]
[1] : 0x0 [Type: unsigned short]
[2] : 0x0 [Type: unsigned short]
[3] : 0x0 [Type: unsigned short]
[4] : 0x0 [Type: unsigned short]
[5] : 0x0 [Type: unsigned short]
[6] : 0x0 [Type: unsigned short]
[7] : 0x0 [Type: unsigned short]
[8] : 0x0 [Type: unsigned short]
[9] : 0x0 [Type: unsigned short]
[10] : 0x0 [Type: unsigned short]
[11] : 0x0 [Type: unsigned short]
[12] : 0x0 [Type: unsigned short]
[13] : 0x0 [Type: unsigned short]
[14] : 0x0 [Type: unsigned short]
[15] : 0x0 [Type: unsigned short]
[16] : 0x0 [Type: unsigned short]
[17] : 0x0 [Type: unsigned short]
[18] : 0x0 [Type: unsigned short]
[19] : 0x0 [Type: unsigned short]
[20] : 0x0 [Type: unsigned short]
[21] : 0x0 [Type: unsigned short]
[22] : 0x0 [Type: unsigned short]
[23] : 0x0 [Type: unsigned short]
[24] : 0x0 [Type: unsigned short]
[25] : 0x0 [Type: unsigned short]
[26] : 0x0 [Type: unsigned short]
[27] : 0x0 [Type: unsigned short]
[28] : 0x0 [Type: unsigned short]
[29] : 0x0 [Type: unsigned short]
[30] : 0x0 [Type: unsigned short]
[31] : 0x0 [Type: unsigned short]
0: kd> dx -id 0,0,89515c28 -r1 (*((rdpwsx!unsigned short (*)[32])0xd633be))
(*((rdpwsx!unsigned short (*)[32])0xd633be)) [Type: unsigned short [32]]
[0] : 0x0 [Type: unsigned short]
[1] : 0x0 [Type: unsigned short]
[2] : 0x0 [Type: unsigned short]
[3] : 0x0 [Type: unsigned short]
[4] : 0x0 [Type: unsigned short]
[5] : 0x0 [Type: unsigned short]
[6] : 0x0 [Type: unsigned short]
[7] : 0x0 [Type: unsigned short]
[8] : 0x0 [Type: unsigned short]
[9] : 0x0 [Type: unsigned short]
[10] : 0x0 [Type: unsigned short]
[11] : 0x0 [Type: unsigned short]
[12] : 0x0 [Type: unsigned short]
[13] : 0x0 [Type: unsigned short]
[14] : 0x0 [Type: unsigned short]
[15] : 0x0 [Type: unsigned short]
[16] : 0x0 [Type: unsigned short]
[17] : 0x0 [Type: unsigned short]
[18] : 0x0 [Type: unsigned short]
[19] : 0x0 [Type: unsigned short]
[20] : 0x0 [Type: unsigned short]
[21] : 0x0 [Type: unsigned short]
[22] : 0x0 [Type: unsigned short]
[23] : 0x0 [Type: unsigned short]
[24] : 0x0 [Type: unsigned short]
[25] : 0x0 [Type: unsigned short]
[26] : 0x0 [Type: unsigned short]
[27] : 0x0 [Type: unsigned short]
[28] : 0x0 [Type: unsigned short]
[29] : 0x0 [Type: unsigned short]
[30] : 0x0 [Type: unsigned short]
[31] : 0x0 [Type: unsigned short]
case TS_UD_CS_CLUSTER_ID:
if (pHeader->length >=sizeof(TS_UD_CS_CLUSTER)) {
*ppClientClusterData = (TS_UD_CS_CLUSTER *)pHeader;
TRC_DATA_DBG(“Cluster data”, pHeader, pHeader->length);
} else {
0: kd> p
21:57:02.625 89617F7C.E31087D0 RDP E1026010 WDWParseUser 1674 Cluster data
04 C0 0C 00 0D 00 00 00 00 00 00 00 …………
0: kd> dt TS_UD_CS_CLUSTER 0x00d63400
RDPWD!TS_UD_CS_CLUSTER
+0x000 header : tagRNS_UD_HEADER
+0x004 Flags : 0xd
+0x008 RedirectedSessionID : 0
0: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!tagRNS_UD_HEADER *)0xd63400))
(*((RDPWD!tagRNS_UD_HEADER *)0xd63400)) [Type: tagRNS_UD_HEADER]
[+0x000] type : 0xc004 [Type: unsigned short]
[+0x002] length : 0xc [Type: unsigned short]
case RNS_UD_CS_SEC_ID:
// Old clients don't have the extEncryptionMethods.
// The extEncryptionMethods field is used only for french locale.
// We have to allow buffers that don't have space for extEncryptionMethods
// because the buffer will be processed in SM_Connect and there we take care of shorter fields.
// Nothing else processes this buffer after SM_Connect at this point.
if (pHeader->length >= FIELDOFFSET(RNS_UD_CS_SEC,encryptionMethods)
+ FIELDSIZE(RNS_UD_CS_SEC,encryptionMethods)) {
*ppClientSecurityData = (PRNS_UD_CS_SEC)pHeader;
TRC_DATA_DBG(“Security data”, pHeader, pHeader->length);
} else {
0: kd> p
21:57:02.671 89617F7C.E31087D0 RDP E1026010 WDWParseUser 1650 Security data
02 C0 0C 00 1B 00 00 00 00 00 00 00 …………
0: kd> dt RNS_UD_CS_SEC 0x00d6340c
RDPWD!RNS_UD_CS_SEC
+0x000 header : tagRNS_UD_HEADER
+0x004 encryptionMethods : 0x1b
+0x008 extEncryptionMethods : 0
0: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!tagRNS_UD_HEADER *)0xd6340c))
(*((RDPWD!tagRNS_UD_HEADER *)0xd6340c)) [Type: tagRNS_UD_HEADER]
[+0x000] type : 0xc002 [Type: unsigned short]
[+0x002] length : 0xc [Type: unsigned short]
/****************************************************************************/
/* Encryption levels – bit field. */
/****************************************************************************/
#define SM_40BIT_ENCRYPTION_FLAG 0x01
#define SM_128BIT_ENCRYPTION_FLAG 0x02
#define SM_56BIT_ENCRYPTION_FLAG 0x08
#define SM_FIPS_ENCRYPTION_FLAG 0x10
case RNS_UD_CS_NET_ID:
if (pHeader->length >= sizeof(RNS_UD_CS_NET)) {
*ppClientNetData = (PRNS_UD_CS_NET)pHeader;
TRC_DATA_DBG(“Net data”, pHeader, pHeader->length);
} else {
0: kd> p
21:57:02.734 89617F7C.E31087D0 RDP E1026010 WDWParseUser 1662 Net data
03 C0 2C 00 03 00 00 00 72 64 70 64 72 00 00 00 ..,…..rdpdr…
00 00 80 80 63 6C 69 70 72 64 72 00 00 00 A0 C0 ….cliprdr…..
72 64 70 73 6E 64 00 00 00 00 00 C0 rdpsnd……
0: kd> dt RNS_UD_CS_NET 0x00d63418
RDPWD!RNS_UD_CS_NET
+0x000 header : tagRNS_UD_HEADER
+0x004 channelCount : 3
0: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!tagRNS_UD_HEADER *)0xd63418))
(*((RDPWD!tagRNS_UD_HEADER *)0xd63418)) [Type: tagRNS_UD_HEADER]
[+0x000] type : 0xc003 [Type: unsigned short]
[+0x002] length : 0x2c [Type: unsigned short]
0: kd> db 0x00d63418
00d63418 03 c0 2c 00 03 00 00 00-72 64 70 64 72 00 00 00 ..,…..rdpdr…
00d63428 00 00 80 80 63 6c 69 70-72 64 72 00 00 00 a0 c0 ….cliprdr…..
00d63438 72 64 70 73 6e 64 00 00-00 00 00 c0 00 00 00 00 rdpsnd……….
3个通道:
rdpdr
cliprdr
rdpsnd
// Make sure we found all our client data. Note that Net and
// Cluster data blocks are optional – RDP4 client doesn't send Net data,
// RDP4 and 5 don't send Cluster data.
if ((*ppClientSecurityData == NULL) || (*ppClientCoreData == NULL)) {
TRC_ERR((TB,”<%p> Security [%p] or Core [%p] data missing”,
pUserData ? pUserData->hDomain : 0,
*ppClientSecurityData, *ppClientCoreData));
DC_QUIT;
}
ppClientSecurityData和ppClientCoreData必须得有
success = TRUE;
DC_EXIT_POINT:
DC_END_FN();
return success;
} /















暂无评论内容