RDPWD!WDWParseUserData函数分析之Loop through user data–非常重要

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;

} /

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
听到风的海的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容