RDPWD!WDWConnect函数分析之RDPWD!WDWParseUserData函数得到用户数据之后到RDPWD!SM_Init

RDPWD!WDWConnect函数分析之RDPWD!WDWParseUserData函数得到用户数据之后到RDPWD!SM_Init

第一部分:

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:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0305 Client version is 0x80004

21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0328 ErrorInfoPDU supported = 1

21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0346 Client requests color depth 24, server limit 16

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0350 Limiting requested color depth...

21:19:13.875 892767D4.E11B61D0 RDP+E10C2010+WDWConnect +0374+Restricted requested color depth 24 to 16
21:19:13.875 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0431 16 BPP (565)

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0502 Client supports load balance redirection

RDPWD: New: ShareClass at E88E0A90, size=1392

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 WDWNewShareC 2528 Created Share Class

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Init 0234 encryption level is 2

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Init 0265 Encrypting

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Init 0308 Encryption methods supported 0000001b: Level 2

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Init 0365 Set state from SM_STATE_STARTED to SM_STATE_INITIALIZED

21:19:13.875 892767D4.E11B61D0 RDP+E10C2010+SM_Connect +0500+Client supports encryption: 1b

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0502 Server supports encryption: 1b

21:19:13.875 892767D4.E11B61D0 RDP+E10C2010+SM_Connect +0639+Encryption Method=2, Level=2, Display=1

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0650 Init Fips succeed

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0689 Set state from SM_STATE_INITIALIZED to SM_STATE_NM_CONNECTING

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0691 Connect to Network Manager

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0181 Net User 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:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0185 Protocol version 0x80004 (0x8/0x4)

21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 0 (was 0): rdpdr

21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 1 (was 1): cliprdr

21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0247 Channel 2 (was 2): rdpsnd

21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0289 Attach User

21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0303 AttachUser OK, hUser E88724C8

21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0312 Attached as user 3ea, hUser E88724C8

21:19:13.890 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0336 Joined broadcast channel 3eb (hChannel E167E190) OK

21:19:13.906 892767D4.E11B61D0 RDP E10C2010 NM_Connect 0356 Joined user channel (hChannel E8872614) OK

第二部分:

21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0305 Client version is 0x80004

21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0328 ErrorInfoPDU supported = 1

21:19:13.859 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0346 Client requests color depth 24, server limit 16

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0350 Limiting requested color depth...

21:19:13.875 892767D4.E11B61D0 RDP+E10C2010+WDWConnect +0374+Restricted requested color depth 24 to 16

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0431 16 BPP (565)

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 WDWConnect 0502 Client supports load balance redirection

NTSTATUS WDWConnect(

PTSHARE_WD pTSWd,

PRNS_UD_CS_CORE pClientCoreData,

PRNS_UD_CS_SEC pClientSecurityData,

PRNS_UD_CS_NET pClientNetData,

PTS_UD_CS_CLUSTER pClientClusterData,

PSD_IOCTL pSdIoctl,

BOOLEAN bOldShadow)

{

NTSTATUS status = STATUS_SUCCESS;

BOOL smInit = FALSE;

DC_BEGIN_FN("WDWConnect");

// Get the required values from the core user data.

pTSWd->version = pClientCoreData->version;

pTSWd->desktopWidth = pClientCoreData->desktopWidth;

pTSWd->desktopHeight = pClientCoreData->desktopHeight;

// We only support 4096 x 2048

if (pTSWd->desktopHeight > 2048)

pTSWd->desktopHeight = 2048;

if (pTSWd->desktopWidth > 4096)

pTSWd->desktopWidth = 4096;

// Checks the client software for compatibility and rejects if not

// equivalent to server software.

TRC_NRM((TB, "Client version is %#lx", pClientCoreData->version));

if (_RNS_MAJOR_VERSION(pClientCoreData->version) != RNS_UD_MAJOR_VERSION) {

TRC_ERR((TB, "Unmatching software version, expected %#lx got %#lx",

RNS_UD_VERSION, pClientCoreData->version));

status = RPC_NT_INVALID_VERS_OPTION;

DC_QUIT;

}

if(pClientCoreData->header.length >=

(FIELDOFFSET(RNS_UD_CS_CORE, earlyCapabilityFlags) +

FIELDSIZE(RNS_UD_CS_CORE, earlyCapabilityFlags))) {

//

// Does client support extended error reporting PDU

//

pTSWd->bSupportErrorInfoPDU = (pClientCoreData->earlyCapabilityFlags &

RNS_UD_CS_SUPPORT_ERRINFO_PDU) ?

TRUE : FALSE;

}

else

{

pTSWd->bSupportErrorInfoPDU = FALSE;

}

TRC_NRM((TB, "ErrorInfoPDU supported = %d", pTSWd->bSupportErrorInfoPDU));

#ifdef DC_HICOLOR

// Work out high color support.

if (pClientCoreData->header.length >=

(FIELDOFFSET(RNS_UD_CS_CORE, supportedColorDepths) +

FIELDSIZE(RNS_UD_CS_CORE, supportedColorDepths))) {

long maxServerBpp;

long limitedBpp;

// Store off the supported color depths.

pTSWd->supportedBpps = pClientCoreData->supportedColorDepths;

// Client may want other than 4 or 8bpp, so lets see what we can

// do. First up is to see what limits are imposed at this end.

maxServerBpp = pTSWd->maxServerBpp;

TRC_NRM((TB, "Client requests color depth %u, server limit %d",

pClientCoreData->highColorDepth, maxServerBpp));

// Now see if we can allow the requested value.

if (pClientCoreData->highColorDepth > maxServerBpp) {

TRC_NRM((TB, "Limiting requested color depth..."));

switch (maxServerBpp) {

case 16:

if (pClientCoreData->supportedColorDepths &

RNS_UD_16BPP_SUPPORT) {

limitedBpp = 16;

break;

}

// deliberate fall through!

case 15:

if (pClientCoreData->supportedColorDepths &

RNS_UD_15BPP_SUPPORT) {

limitedBpp = 15;

break;

}

// deliberate fall through!

default:

limitedBpp = 8;

break;

}

TRC_ALT((TB, "Restricted requested color depth %d to %d",

pClientCoreData->highColorDepth, maxServerBpp));

pClientCoreData->highColorDepth = (UINT16)limitedBpp;

}

// Now set up the proper color depth from the (possibly

// restricted) high color value.

if (pClientCoreData->highColorDepth == 24)

pClientCoreData->colorDepth = RNS_UD_COLOR_24BPP;

else if (pClientCoreData->highColorDepth == 16)

pClientCoreData->colorDepth = RNS_UD_COLOR_16BPP_565;

else if (pClientCoreData->highColorDepth == 15)

pClientCoreData->colorDepth = RNS_UD_COLOR_16BPP_555;

else if (pClientCoreData->highColorDepth == 4)

pClientCoreData->colorDepth = RNS_UD_COLOR_4BPP;

else

pClientCoreData->colorDepth = RNS_UD_COLOR_8BPP;

}

else {

// No hicolor support.

pTSWd->supportedBpps = 0;

#endif

// A beta2 Server rejects Clients with a color depth of 4bpp.

// Therefore a new field, postBeta2ColorDepth, is added, which can be

// 4bpp. If this field exists, use it instead of colorDepth.

if (pClientCoreData->header.length >=

(FIELDOFFSET(RNS_UD_CS_CORE, postBeta2ColorDepth) +

FIELDSIZE(RNS_UD_CS_CORE, postBeta2ColorDepth))) {

TRC_NRM((TB, "Post-beta2 color depth id %#x",

pClientCoreData->postBeta2ColorDepth));

pClientCoreData->colorDepth = pClientCoreData->postBeta2ColorDepth;

}

#ifdef DC_HICOLOR

}

#endif

if (pClientCoreData->colorDepth == RNS_UD_COLOR_8BPP) {

TRC_NRM((TB, "8 BPP"));

pTSWd->desktopBpp = 8;

}

else if (pClientCoreData->colorDepth == RNS_UD_COLOR_4BPP) {

TRC_NRM((TB, "4 BPP"));

pTSWd->desktopBpp = 4;

}

else if (pClientCoreData->colorDepth == RNS_UD_COLOR_16BPP_555) {

#ifdef DC_HICOLOR

TRC_NRM((TB, "15 BPP (16 BPP, 555)"));

pTSWd->desktopBpp = 15;

#else

// May want to save whether it's 555 or 565.

TRC_NRM((TB, "16 BPP 555"));

pTSWd->desktopBpp = 16;

#endif

}

else if (pClientCoreData->colorDepth == RNS_UD_COLOR_16BPP_565) {

#ifdef DC_HICOLOR

TRC_NRM((TB, "16 BPP (565)"));

#else
TRC_NRM((TB, "16 BPP 565"));

#endif

pTSWd->desktopBpp = 16;

}

else if (pClientCoreData->colorDepth == RNS_UD_COLOR_24BPP) {

TRC_NRM((TB, "24 BPP"));

pTSWd->desktopBpp = 24;

}

else {

TRC_ERR((TB, "Unknown BPP %x returned by client",

pClientCoreData->colorDepth));

status = STATUS_UNSUCCESSFUL;

DC_QUIT;

}

pTSWd->sas = pClientCoreData->SASSequence;

pTSWd->kbdLayout = pClientCoreData->keyboardLayout;

pTSWd->clientBuild = pClientCoreData->clientBuild;

// here we don't copy the last character in the buffer because

// we force zero termination later by writting a 0 at the end;
memcpy(pTSWd->clientName, pClientCoreData->clientName,
sizeof(pTSWd->clientName)-sizeof(pTSWd->clientName[0]));

pTSWd->clientName[sizeof(pTSWd->clientName)

/ sizeof(pTSWd->clientName[0]) - 1] = 0;

pTSWd->keyboardType = pClientCoreData->keyboardType;

pTSWd->keyboardSubType = pClientCoreData->keyboardSubType;

pTSWd->keyboardFunctionKey = pClientCoreData->keyboardFunctionKey;

// here we don't copy the last character in the buffer because

// we force zero termination later by writting a 0 at the end;
memcpy(pTSWd->imeFileName, pClientCoreData->imeFileName,
sizeof(pTSWd->imeFileName)-sizeof(pTSWd->imeFileName[0]));

pTSWd->imeFileName[sizeof(pTSWd->imeFileName)

/ sizeof(pTSWd->imeFileName[0]) - 1] = 0;

pTSWd->clientDigProductId[0] = 0;

// Win2000 Post Beta 3 fields added

if (pClientCoreData->header.length >=

(FIELDOFFSET(RNS_UD_CS_CORE, serialNumber) +

FIELDSIZE(RNS_UD_CS_CORE, serialNumber))) {

pTSWd->clientProductId = pClientCoreData->clientProductId;

pTSWd->serialNumber = pClientCoreData->serialNumber;

//shadow loop fix

if (pClientCoreData->header.length >=

(FIELDOFFSET(RNS_UD_CS_CORE, clientDigProductId) +

FIELDSIZE(RNS_UD_CS_CORE, clientDigProductId))) {

// here we don't copy the last character in the buffer because

// we force zero termination later by writting a 0 at the end;

memcpy( pTSWd->clientDigProductId,

pClientCoreData->clientDigProductId,

sizeof(pTSWd->clientDigProductId)

-sizeof(pTSWd->clientDigProductId[0]));

pTSWd->clientDigProductId[sizeof(pTSWd->clientDigProductId)

/ sizeof(pTSWd->clientDigProductId[0]) -1] = 0;

}

}

// Parse and store the client's cluster support info, if provided.

// If not present, the memset here will implicitly set FALSE the flags

// for the client cluster capabilities. Note we do not have the

// username and domain available yet (it comes in the info packet

// later) so we cannot fill out the username and domain yet.

if (pClientClusterData != NULL) {

if (pClientClusterData->Flags & TS_CLUSTER_REDIRECTION_SUPPORTED) {

TRC_NRM((TB,"Client supports load balance redirection"));

pTSWd->bClientSupportsRedirection = TRUE;

}

if (pClientClusterData->Flags &

TS_CLUSTER_REDIRECTED_SESSIONID_FIELD_VALID) {

TRC_NRM((TB,"Client has been load-balanced to this server, "

"sessid=%u", pClientClusterData->RedirectedSessionID));

pTSWd->bRequestedSessionIDFieldValid = TRUE;

pTSWd->RequestedSessionID =

pClientClusterData->RedirectedSessionID;

if (pClientClusterData->Flags & TS_CLUSTER_REDIRECTED_SMARTCARD) {

pTSWd->bUseSmartcardLogon = TRUE;

}

}

// The 2..5 bits (start from 0) are the PDU version

pTSWd->ClientRedirectionVersion = ((pClientClusterData->Flags & 0x3C) >> 2);

}

第三部分:

D:\123>grep "WDWConnect" -nr D:\srv03rtm\termsrv

D:\srv03rtm\termsrv/drivers/rdp/inc/nwdwint.h:70:NTSTATUS WDWConnect(PTSHARE_WD, PRNS_UD_CS_CORE, PRNS_UD_CS_SEC,

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:259:/* Name: WDWConnect */

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:278:NTSTATUS WDWConnect(

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:290: DC_BEGIN_FN("WDWConnect");

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:590:} /* WDWConnect */

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:665: status = WDWConnect(pTSWd, pClientCoreData, pClientSecurityData,

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:1001: status = WDWConnect(pTSWd,

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:1624: // The WDWConnect parses this data and it checks the length we

NTSTATUS WDWConfConnect(PTSHARE_WD pTSWd, PSD_IOCTL pSdIoctl)

{

// Parse the input data.

if (WDWParseUserData(pTSWd, (PUSERDATAINFO)pSdIoctl->InputBuffer, DataLen,

NULL, 0, &pClientCoreData, &pClientSecurityData,

&pClientNetData, &pClientClusterData)) {

status = WDWConnect(pTSWd, pClientCoreData, pClientSecurityData,

pClientNetData, pClientClusterData, pSdIoctl, FALSE);

}

第四部分:

RDPWD: New: ShareClass at E88E0A90, size=1392

D:\123>grep "New: ShareClass" -nr D:\srv03rtm\termsrv

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/as_conf.cpp:46: KdPrint(("RDPWD: New: ShareClass at %p, size=%u\n", ptr, nSize));

void * __cdecl operator new(size_t nSize)

{

PVOID ptr;

if ((sizeof(nSize)) >= PAGE_SIZE) {

KdPrint(("RDPWD: **** Note ShareClass allocation size %u is above "

"page size %u, wasting %u\n", sizeof(ShareClass), PAGE_SIZE,

PAGE_SIZE - (nSize % PAGE_SIZE)));

}

ptr = COM_Malloc(nSize);

if (ptr != NULL) {

KdPrint(("RDPWD: New: ShareClass at %p, size=%u\n", ptr, nSize));

}

return ptr;

}

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 WDWNewShareC 2528 Created Share Class

NTSTATUS WDWNewShareClass(PTSHARE_WD pTSWd)

{

NTSTATUS status = STATUS_SUCCESS;

ShareClass *pSC;

DC_BEGIN_FN("WDWNewShareClass");

#ifdef DC_HICOLOR

pSC = new ShareClass(pTSWd, pTSWd->desktopHeight, pTSWd->desktopWidth,

pTSWd->desktopBpp, pTSWd->pSmInfo);

#else

pSC = new ShareClass(pTSWd, pTSWd->desktopHeight, pTSWd->desktopWidth,

8, pTSWd->pSmInfo);

#endif

if (pSC != NULL) {

TRC_NRM((TB, "Created Share Class"));

pTSWd->dcShare = (PVOID)pSC;

}

else {

TRC_ERR((TB, "Failed to create Share Class"));

status = STATUS_NO_MEMORY;

}

DC_END_FN();

return status;

} /* WDWNewShareClass */

第五部分:

// Bring up SM.

status = SM_Init(pTSWd->pSmInfo, pTSWd, bOldShadow);

if (NT_SUCCESS(status)) {

smInit = TRUE;

}

RDPCALL SM_Init函数里面的SM意思是安全管理Security Manager

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Init 0234 encryption level is 2

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Init 0265 Encrypting

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Init 0308 Encryption methods supported 0000001b: Level 2

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Init 0365 Set state from SM_STATE_STARTED to SM_STATE_INITIALIZED

/****************************************************************************/

/* asmapi.c */

/* */

/* Security Manager API */

/* */

/* Copyright (C) 1997-1999 Microsoft Corporation */

/****************************************************************************/

NTSTATUS RDPCALL SM_Init(PVOID pSMHandle,

PTSHARE_WD pWDHandle,

BOOLEAN bOldShadow)

{

BOOL rc;

NTSTATUS status = STATUS_UNSUCCESSFUL;

unsigned i;

unsigned regRc;

PSM_HANDLE_DATA pRealSMHandle = (PSM_HANDLE_DATA)pSMHandle;

INT32 regValue;

OBJECT_ATTRIBUTES ObjectAttributes;

UNICODE_STRING UnicodeString;

static UINT32 keyInfoBuffer[16];

ULONG keyInfoLength;

HANDLE RegistryKeyHandle;

PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;

DC_BEGIN_FN("SM_Init");

SM_CHECK_STATE(SM_EVT_INIT);

/************************************************************************/

/* Store the WDW Handle before we do anything else, as we can't trace */

/* until we do so. */

/************************************************************************/

pRealSMHandle->pWDHandle = pWDHandle;

pRealSMHandle->bForwardDataToSC = FALSE;

/************************************************************************/

/* Get default DONTDISPLAYLASTUSERNAME setting */

/************************************************************************/

pWDHandle->fDontDisplayLastUserName = FALSE;

RtlInitUnicodeString(&UnicodeString, W2K_GROUP_POLICY_WINLOGON_KEY);

InitializeObjectAttributes(&ObjectAttributes,

&UnicodeString,

OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,

NULL,

NULL);

status = ZwOpenKey(&RegistryKeyHandle, GENERIC_READ, &ObjectAttributes);

if (NT_SUCCESS(status)) {

RtlInitUnicodeString(&UnicodeString, WIN_DONTDISPLAYLASTUSERNAME );

KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)keyInfoBuffer;

status = ZwQueryValueKey(RegistryKeyHandle,

&UnicodeString,

KeyValuePartialInformation,

KeyValueInformation,

sizeof(keyInfoBuffer),

&keyInfoLength);

// For W2K the value should be a DWORD.

if ((NT_SUCCESS(status)) &&

(KeyValueInformation->Type == REG_DWORD) &&

(KeyValueInformation->DataLength >= sizeof(DWORD))) {

pWDHandle->fDontDisplayLastUserName =

(BOOLEAN)(*(PDWORD)(KeyValueInformation->Data) == 1);

}

ZwClose(RegistryKeyHandle);

}

// Starting with W2K the place where the DontDislpayLastUserName policy

// is store has moved to another key (W2K_GROUP_POLICY_WINLOGON_KEY). But

// we still have to look at the old key in case we could not read the

// value in the post W2K key (the policy is not definde). We want to follow

// the winlogon behavior in the console.

// In case there is a value set in the new policy key we will use that

// value. In case there isn't one we look in the old place. As I said this

// is what winlogon does.

//

if (!NT_SUCCESS(status)) {

RtlInitUnicodeString(&UnicodeString, WINLOGON_KEY);

InitializeObjectAttributes(&ObjectAttributes,

&UnicodeString,

OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,

NULL,

NULL);

status = ZwOpenKey(&RegistryKeyHandle, GENERIC_READ, &ObjectAttributes);

if (NT_SUCCESS(status)) {

RtlInitUnicodeString(&UnicodeString, WIN_DONTDISPLAYLASTUSERNAME );

KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)keyInfoBuffer;

status = ZwQueryValueKey(RegistryKeyHandle,

&UnicodeString,

KeyValuePartialInformation,

KeyValueInformation,

sizeof(keyInfoBuffer),

&keyInfoLength);

if (NT_SUCCESS(status)) {

pWDHandle->fDontDisplayLastUserName =

(BOOLEAN)(KeyValueInformation->Data[0] == '1');

}

ZwClose(RegistryKeyHandle);

}

}

/************************************************************************/
/* We don't run without encryption in a retail build */
/************************************************************************/
/*在零售版本中,我们不会在没有加密的情况下运行,(可以不加密运行,速度是不是快些?)*/

TRC_NRM((TB, "encryption level is %d", pRealSMHandle->encryptionLevel));

if (pRealSMHandle->encryptionLevel < 1)

{

TRC_ALT((TB, "Forcing encryption back to level 1!"));

pRealSMHandle->encryptionLevel = 1;

}

#ifdef INSTRUM_TRACK_DISCARDED

pRealSMHandle->nDiscardNonVCPDUWhenDead = 0;

pRealSMHandle->nDiscardPDUBadState = 0;

pRealSMHandle->nDiscardVCDataWhenDead = 0;

#endif

if (pRealSMHandle->encryptionLevel == 0) {

TRC_ALT((TB, "Not encrypting"));

pRealSMHandle->encryptionMethodsSupported = 0;

pRealSMHandle->encrypting = FALSE;

pRealSMHandle->encryptDisplayData = FALSE;

pRealSMHandle->encryptingLicToClient = FALSE;

pRealSMHandle->encryptionMethodSelected = 0;

pRealSMHandle->frenchClient = FALSE;

pRealSMHandle->recvdClientRandom = FALSE;

pRealSMHandle->bSessionKeysMade = FALSE;

pRealSMHandle->encryptHeaderLen = 0;

pRealSMHandle->encryptHeaderLenIfForceEncrypt = sizeof(RNS_SECURITY_HEADER1);

}

else {

pRealSMHandle->encrypting = TRUE;

pRealSMHandle->frenchClient = FALSE;

TRC_NRM((TB, "Encrypting"));

/********************************************************************/

/* encrypt the display data if encryptionLevel is 2 (or above). */

/********************************************************************/

if (pRealSMHandle->encryptionLevel == 1) {

pRealSMHandle->encryptDisplayData = FALSE;

pRealSMHandle->encryptHeaderLen = sizeof(RNS_SECURITY_HEADER);

pRealSMHandle->encryptHeaderLenIfForceEncrypt = sizeof(RNS_SECURITY_HEADER1);

TRC_NRM((TB, "Displaydata not encrypted"));

}

else {

pRealSMHandle->encryptDisplayData = TRUE;

pRealSMHandle->encryptHeaderLen = sizeof(RNS_SECURITY_HEADER1);

}

/********************************************************************/

/* for down level compatibility, support both 40bit, 56bit */

/* and 128bit default. */

/********************************************************************/

pRealSMHandle->encryptionMethodsSupported =

SM_128BIT_ENCRYPTION_FLAG |

SM_56BIT_ENCRYPTION_FLAG |

SM_40BIT_ENCRYPTION_FLAG |

SM_FIPS_ENCRYPTION_FLAG;

/********************************************************************/

/* encrypt 128bit and above if encryptionLevel is 3 */

/********************************************************************/

if (pRealSMHandle->encryptionLevel == 3) {

pRealSMHandle->encryptionMethodsSupported =

SM_128BIT_ENCRYPTION_FLAG | SM_FIPS_ENCRYPTION_FLAG;

}

/********************************************************************/

/* encrypt in FIPS only if encryption level is 4 or above. */

/********************************************************************/

if (pRealSMHandle->encryptionLevel >= 4) {

pRealSMHandle->encryptionMethodsSupported = SM_FIPS_ENCRYPTION_FLAG;

}

TRC_NRM((TB, "Encryption methods supported %08lx: Level %ld\n",

pRealSMHandle->encryptionMethodsSupported,

pRealSMHandle->encryptionLevel));

/********************************************************************/

/* initally set the encryption method selected as */

/* SM_56BIT_ENCRYPTION_FLAG, later it will be set according to the */

/* client support. */

/********************************************************************/

pRealSMHandle->encryptionMethodSelected = SM_56BIT_ENCRYPTION_FLAG;

/********************************************************************/

/* misc init. */

/********************************************************************/

pRealSMHandle->recvdClientRandom = FALSE;

pRealSMHandle->bSessionKeysMade = FALSE;

}

/************************************************************************/

/* We do not know the certificate type used in the key exchange till */

/* after the exchange has taken place. */

/************************************************************************/

/*在密钥交换发生之前,我们并不知道交换中使用的证书类型。 */

pRealSMHandle->CertType = CERT_TYPE_INVALID;

#ifdef USE_LICENSE

/************************************************************************/

/* Initialize the Server license manager */

/************************************************************************/

pRealSMHandle->pLicenseHandle = SLicenseInit();

if (!pRealSMHandle->pLicenseHandle)

{

TRC_ERR((TB, "Failed to initialize License Manager"));

DC_QUIT;

}

pWDHandle->pSLicenseHandle = pRealSMHandle->pLicenseHandle;

#endif

/************************************************************************/

/* Initialize the console buffer stuff */

/************************************************************************/

InitializeListHead(&pRealSMHandle->consoleBufferList);

pRealSMHandle->consoleBufferCount = 0;

/************************************************************************/

/* Finally, initialize the Network Manager */

/************************************************************************/

rc = NM_Init(pRealSMHandle->pWDHandle->pNMInfo,

pSMHandle,

pWDHandle,

pWDHandle->hDomainKernel);

if (!rc)

{

TRC_ERR((TB, "Failed to init NM"));

DC_QUIT;

}

/************************************************************************/

/* Update the state */

/************************************************************************/
SM_SET_STATE(SM_STATE_INITIALIZED);

/************************************************************************/

/* All worked */

/************************************************************************/

status = STATUS_SUCCESS;

DC_EXIT_POINT:

/************************************************************************/

/* If anything failed, clean up. Must be done after calling */

/* FreeContextBuffer as this clears the function table. */

/************************************************************************/

if (!NT_SUCCESS(status))

{

TRC_ERR((TB, "Something failed - clean up"));

SMFreeInitResources(pRealSMHandle);

}

DC_END_FN();

return(status);

} /* SM_Init */

// This is the new key that is used by winlogon starting with W2K

#define W2K_GROUP_POLICY_WINLOGON_KEY \

L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\" \

L"CurrentVersion\\Policies\\System"

#define WIN_DONTDISPLAYLASTUSERNAME L"DontDisplayLastUserName"

第六部分:

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0689 Set state from SM_STATE_INITIALIZED to SM_STATE_NM_CONNECTING

/****************************************************************************/

/* SM_SET_STATE - set the SLCstate */

/****************************************************************************/

#define SM_SET_STATE(newstate) \

{ \

TRC_NRM((TB, "Set state from %s to %s", \
smStateName[pRealSMHandle->state], smStateName[newstate])); \

pRealSMHandle->state = newstate; \

}

0: kd> x RDPWD!smStateName

b9d81548 RDPWD!smStateName = char [8][25]

0: kd> dx -r1 (*((RDPWD!char (*)[8][25])0xb9d81548))

(*((RDPWD!char (*)[8][25])0xb9d81548)) [Type: char [8][25]]

0\] : "SM_STATE_STARTED" \[Type: char \[25\]

1\] : "SM_STATE_INITIALIZED" \[Type: char \[25\]

2\] : "SM_STATE_NM_CONNECTING" \[Type: char \[25\]

3\] : "SM_STATE_SM_CONNECTING" \[Type: char \[25\]

4\] : "SM_STATE_SM_LICENSING" \[Type: char \[25\]

5\] : "SM_STATE_CONNECTED" \[Type: char \[25\]

6\] : "SM_STATE_SC_REGISTERED" \[Type: char \[25\]

7\] : "SM_STATE_DISCONNECTING" \[Type: char \[25\]

第七部分:

参考:pRealSMHandle->encryptionLevel的由来,在IoControlCode=49的时候就赋值了,现在是49之后的IoControlCode=18
D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwcpp.cpp:3615: pRealSMHandle->encryptionLevel = pConfigData->encryptionLevel;

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwcpp.cpp:3620: TRC_DBG((TB, "Encryption level: %d", pRealSMHandle->encryptionLevel));

21:19:13.734 892767D4.E11B61D0 RDP E10C2010 WD_Ioctl 0678 Got Set Trace IOCtl

21:19:13.734 892767D4.E11B61D0 ICADD: IcaDeviceControlConnection, fc 0, 0x0

21:19:13.734 892767D4.E11B61D0 TERMSRV: Enter WsxIcaIoControl, IoControlCode=49

Breakpoint 19 hit

rdpwsx!WsxIcaStackIoControl:

001b:70fbf35c 55 push ebp

0: kd> g

21:19:13.734 892767D4.E11B61D0 TShrSRV: WsxIcaStackIoControl entry

21:19:13.734 892767D4.E11B61D0 TShrSRV: 00D75938:00000000 IoctlDetail: Ioctl 0x3800c7 (UNKNOWN_ICA_IOCTL)

21:19:13.734 892767D4.E11B61D0 TShrSRV: pvContext=00D75938, hIca=0000041C, hStack=000E27A8

21:19:13.734 892767D4.E11B61D0 TShrSRV: pInBuffer=0248F5F4, InBufferSize=0x4, pOutBuffer=00000000, OutBufferSize=0x0

21:19:13.734 892767D4.E11B61D0 TermDD: IcaDeviceControlStack, fc 49 (enter)

21:19:13.734 892767D4.E11B61D0 RDP E10C2010 WD_Ioctl 0489 Unknown Ioctl (49)

21:19:13.734 892767D4.E11B61D0 RDP E10C2010 WD_Ioctl 0774 Got stack config data

21:19:13.734 892767D4.E11B61D0 RDP E10C2010 WDWSetConfig 3613 Max Color Depth support: 16

21:19:13.734 892767D4.E11B61D0 RDP E10C2010 WDWSetConfig 3619 Encryption after logon: 0
21:19:13.734 892767D4.E11B61D0 RDP E10C2010 WDWSetConfig 3620 Encryption level: 2

21:19:13.734 892767D4.E11B61D0 RDP E10C2010 WDWSetConfig 3623 AutoReconnect disabled: 0

参考:

第八部分:

BOOL RDPCALL NM_Init(PVOID pNMHandle,

PVOID pSMHandle,

PTSHARE_WD pWDHandle,

DomainHandle hDomainKernel)

{

PNM_HANDLE_DATA pRealNMHandle = (PNM_HANDLE_DATA)pNMHandle;

DC_BEGIN_FN("NM_Init");

/************************************************************************/

/* WARNING: Don't trace before storing the WD Handle */

/************************************************************************/

pRealNMHandle->pWDHandle = pWDHandle;

pRealNMHandle->pSMHandle = pSMHandle;

pRealNMHandle->pContext = pWDHandle->pContext;

pRealNMHandle->hDomain = hDomainKernel;

DC_END_FN();

return(TRUE);

} /* NM_Init */

第九部分:

D:\123>grep "SM_Connect" -nr D:\srv03rtm\termsrv

D:\srv03rtm\termsrv/drivers/rdp/inc/asmapi.h:36:NTSTATUS RDPCALL SM_Connect(PVOID pSMHandle,

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/asmapi.c:463:/* Name: SM_Connect */

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/asmapi.c:480:NTSTATUS RDPCALL SM_Connect(PVOID pSMHandle,

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/asmapi.c:490: DC_BEGIN_FN("SM_Connect");

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/asmapi.c:730:} /* SM_Connect */

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/asmdata.c:53:/* | | | SM_Connecting */

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:552: status = SM_Connect(pTSWd->pSmInfo, pClientSecurityData, pClientNetData,

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:555: TRC_ERR((TB, "SM_Connect failed: rc=%lx", status));

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:1645: // because the buffer will be processed in SM_Connect and there we take care of shorter fields.

D:\srv03rtm\termsrv/drivers/rdp/rdpwd/nwdwint.c:1646: // Nothing else processes this buffer after SM_Connect at this point.

前瞻:

NTSTATUS WDWConnect(

PTSHARE_WD pTSWd,

PRNS_UD_CS_CORE pClientCoreData,

PRNS_UD_CS_SEC pClientSecurityData,

PRNS_UD_CS_NET pClientNetData,

PTS_UD_CS_CLUSTER pClientClusterData,

PSD_IOCTL pSdIoctl,

BOOLEAN bOldShadow)

{

// Tell SM we're done here.

status = SM_Connect(pTSWd->pSmInfo, pClientSecurityData, pClientNetData,

bOldShadow);

if (status != STATUS_SUCCESS) {

TRC_ERR((TB, "SM_Connect failed: rc=%lx", status));

DC_QUIT;

}

21:19:13.875 892767D4.E11B61D0 RDP+E10C2010+SM_Connect +0500+Client supports encryption: 1b
21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0502 Server supports encryption: 1b

21:19:13.875 892767D4.E11B61D0 RDP+E10C2010+SM_Connect +0639+Encryption Method=2, Level=2, Display=1

21:19:13.875 892767D4.E11B61D0 RDP E10C2010 SM_Connect 0650 Init Fips succeed

NTSTATUS RDPCALL SM_Connect(PVOID pSMHandle,

PRNS_UD_CS_SEC pUserDataIn,

PRNS_UD_CS_NET pNetUserData,

BOOLEAN bOldShadow)

{

NTSTATUS status = STATUS_SUCCESS;

BOOL rc = FALSE;

PSM_HANDLE_DATA pRealSMHandle = (PSM_HANDLE_DATA)pSMHandle;

UINT32 encMethodPicked = 0;

DC_BEGIN_FN("SM_Connect");

SM_CHECK_STATE(SM_EVT_CONNECT);

pRealSMHandle->pUserData = NULL;

/************************************************************************/

/* pick a matching encryption method. */

/************************************************************************/

TRC_ALT((TB, "Client supports encryption: %lx",

pUserDataIn->encryptionMethods));

TRC_NRM((TB, "Server supports encryption: %lx",

pRealSMHandle->encryptionMethodsSupported));

相关推荐
sitelist2 天前
RDPWD!SM_Connect函数里面的SM_CHECK_STATE和RDPWD!smStatetable全局变量的关系
smstatetable·sm_check_state·sm_connect