RDPWD!MCSAttachUserRequest函数分析之RDPWD!Domain结构中的ChannelList和UserAttachmentList
第一部分:
1: kd> kc
00 RDPWD!MCSAttachUserRequest
01 RDPWD!NM_Connect
02 RDPWD!SM_Connect
03 RDPWD!WDWConnect
04 RDPWD!WDWConfConnect
05 RDPWD!WD_Ioctl
06 termdd!_IcaCallSd
07 termdd!_IcaCallStack
08 termdd!IcaDeviceControlStack
09 termdd!IcaDeviceControl
0a termdd!IcaDispatch
0b nt!IofCallDriver
0c nt!IopSynchronousServiceTail
0d nt!IopXxxControlFile
0e nt!NtDeviceIoControlFile
0f nt!_KiSystemService
10 SharedUserData!SystemCallStub
11 ntdll!NtDeviceIoControlFile
12 icaapi!IcaIoControl
13 icaapi!_IcaStackIoControlWorker
14 icaapi!IcaStackIoControl
15 rdpwsx!TSrvInitWDConnectInfo
16 rdpwsx!TSrvInitWD
17 rdpwsx!TSrvConfCreateResp
18 rdpwsx!TSrvDoConnectResponse
19 rdpwsx!TSrvDoConnect
1a rdpwsx!TSrvStackConnect
1b rdpwsx!WsxIcaStackIoControl
1c termsrv!WsxStackIoControl
1d icaapi!_IcaStackIoControl
1e icaapi!_IcaStackWaitForIca
1f icaapi!IcaStackConnectionAccept
20 termsrv!TransferConnectionToIdleWinStation
21 termsrv!WinStationTransferThread
22 kernel32!BaseThreadStart
1: kd> dv
hDomain = 0xe1143540
UserCallback = 0xb9d34970
SDCallback = 0xb9d1e8f0
UserDefined = 0xe116ee30
phUser = 0xb9a103c8
pMaxSendSize = 0xb9a103ac
pbCompleted = 0xb9a103cf "???"
1: kd> dt RDPWD!Domain 0xe1143540
+0x000 pContext : 0x895b736c _SDCONTEXT
+0x004 StackClass : 0 ( Stack_Primary )
+0x008 StatusDead : 0 ''
+0x00c PseudoRefCount : 0n1
+0x010 StackMode : 0
+0x014 bChannelBound : 0y1
+0x014 bCanSendData : 0y1
+0x014 bT120StartReceived : 0y1
+0x014 bDPumReceivedNotInput : 0y0
+0x014 bEndConnectionPacketReceived : 0y0
+0x014 bTopProvider : 0y1
+0x014 bCurrentPacketFastPath : 0y0
+0x018 pSMData : 0xe116e7c8 Void
+0x01c ReceiveBufSize : 0x800
+0x020 pReassembleData : (null)
+0x024 StoredDataLength : 0
+0x028 PacketDataLength : 0
+0x02c PacketHeaderLength : 4
+0x030 pStat : 0x895efa58 _PROTOCOLSTATUS
+0x034 ChannelList : SList
+0x068 MaxX224DataSize : 0xfff8
+0x06c X224SourcePort : 0
+0x070 MaxSendSize : 0xffef
+0x074 UserAttachmentList : SList
+0x0a8 DomParams : DomainParameters
+0x0c8 NextAvailDynChannel : 0x3ea
+0x0cc State : 0n3
+0x0d0 DelayedDPumReason : 0
+0x0d4 pBrokenEvent : (null)
+0x0d8 shadowChannel : 0
+0x0dc PreallocUA : [2] UserAttachment
+0x174 PreallocChannel : [5] MCSChannel
+0x2b4 PacketBuf : [1] ""
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!SList *)0xe11435b4))
(*((RDPWD!SList *)0xe11435b4)) [Type: SList]
+0x000\] Hdr \[Type: _SListHeader
+0x014\] InitialList \[Type: _SListNode \[4\]
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListHeader *)0xe11435b4))
(*((RDPWD!_SListHeader *)0xe11435b4)) [Type: _SListHeader]
+0x000\] NEntries : 0x0 \[Type: unsigned int
+0x004\] MaxEntries : 0x4 \[Type: unsigned int
+0x008\] HeadOffset : 0x0 \[Type: unsigned int
+0x00c\] CurrOffset : 0xffffffff \[Type: unsigned int
+0x010\] Entries : 0xe11435c8 \[Type: _SListNode \*
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!DomainParameters *)0xe11435e8))
(*((RDPWD!DomainParameters *)0xe11435e8)) [Type: DomainParameters]
+0x000\] MaxChannels : 0x22 \[Type: unsigned int
+0x004\] MaxUsers : 0x3 \[Type: unsigned int
+0x008\] MaxTokens : 0x0 \[Type: unsigned int
+0x00c\] NumPriorities : 0x1 \[Type: unsigned int
+0x010\] MinThroughput : 0x0 \[Type: unsigned int
+0x014\] MaxDomainHeight : 0x1 \[Type: unsigned int
+0x018\] MaxPDUSize : 0xfff8 \[Type: unsigned int
+0x01c\] ProtocolVersion : 0x2 \[Type: unsigned int
// Check against domain max users param.
if (SListGetEntries(&pDomain->UserAttachmentList) ==
pDomain->DomParams.MaxUsers) {
ErrOut(pDomain->pContext, "AttachUserReq(): Too many users");
return MCS_TOO_MANY_USERS;
}
#define SListGetEntries(pSL) ((pSL)->Hdr.NEntries)
NumPreallocUA domain.h (termsrv\drivers\rdp\inc)
// Primary remote user and local user.
#define NumPreallocUA 2
// Allocate a UserAttachment. Try the prealloc list first.
pUA = NULL;
for (i = 0; i < NumPreallocUA; i++) {
if (!pDomain->PreallocUA[i].bInUse) {
pUA = &pDomain->PreallocUA[i];
pUA->bInUse = TRUE;
}
}
1: kd> dt RDPWD!Domain 0xe1143540
+0x0dc PreallocUA : [2] UserAttachment
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!UserAttachment (*)[2])0xe114361c))
(*((RDPWD!UserAttachment (*)[2])0xe114361c)) [Type: UserAttachment [2]]
0\] \[Type: UserAttachment
1\] \[Type: UserAttachment
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!UserAttachment *)0xe114361c))
(*((RDPWD!UserAttachment *)0xe114361c)) [Type: UserAttachment]
+0x000\] pDomain : 0x0 \[Type: _Domain \*
+0x004\] bLocal : 0x0 \[Type: unsigned char
+0x005\] bPreallocated : 0x1 \[Type: unsigned char
+0x006\] bInUse : 0x0 \[Type: unsigned char\] //\[+0x006\] bInUse : 0x0 \[+0x008\] UserDefined : 0x0 \[Type: void \*
+0x00c\] UserID : 0x0 \[Type: unsigned int
+0x010\] JoinedChannelList \[Type: SList
+0x044\] Callback : 0x0 \[Type: void (\*)(void \*,unsigned int,void \*,void \*)
+0x048\] SDCallback : 0x0 \[Type: unsigned char (\*)(unsigned char \*,unsigned int,void \*,void \*,unsigned char,void \*,MCSPriority,unsigned int,unsigned int)
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!UserAttachment *)0xe1143668))
(*((RDPWD!UserAttachment *)0xe1143668)) [Type: UserAttachment]
+0x000\] pDomain : 0x0 \[Type: _Domain \*
+0x004\] bLocal : 0x0 \[Type: unsigned char
+0x005\] bPreallocated : 0x1 \[Type: unsigned char
+0x006\] bInUse : 0x0 \[Type: unsigned char\] //\[+0x006\] bInUse : 0x0 \[+0x008\] UserDefined : 0x0 \[Type: void \*
+0x00c\] UserID : 0x0 \[Type: unsigned int
+0x010\] JoinedChannelList \[Type: SList
+0x044\] Callback : 0x0 \[Type: void (\*)(void \*,unsigned int,void \*,void \*)
+0x048\] SDCallback : 0x0 \[Type: unsigned char (\*)(unsigned char \*,unsigned int,void \*,void \*,unsigned char,void \*,MCSPriority,unsigned int,unsigned int)
+0x010\] JoinedChannelList 1: kd\> dx -id 0,0,89515c28 -r1 (\*((RDPWD!SList \*)0xe1143678)) (\*((RDPWD!SList \*)0xe1143678)) \[Type: SList
+0x000\] Hdr \[Type: _SListHeader
+0x014\] InitialList \[Type: _SListNode \[4\]
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListHeader *)0xe1143678))
(*((RDPWD!_SListHeader *)0xe1143678)) [Type: _SListHeader]
+0x000\] NEntries : 0x0 \[Type: unsigned int
+0x004\] MaxEntries : 0x0 \[Type: unsigned int
+0x008\] HeadOffset : 0x0 \[Type: unsigned int
+0x00c\] CurrOffset : 0x0 \[Type: unsigned int
+0x010\] Entries : 0x0 \[Type: _SListNode \*
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListNode (*)[4])0xe114368c))
(*((RDPWD!_SListNode (*)[4])0xe114368c)) [Type: _SListNode [4]]
0\] \[Type: _SListNode
1\] \[Type: _SListNode
2\] \[Type: _SListNode
3\] \[Type: _SListNode
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListNode *)0xe114368c))
(*((RDPWD!_SListNode *)0xe114368c)) [Type: _SListNode]
+0x000\] Key : 0x0 \[Type: unsigned int
+0x004\] Value : 0x0 \[Type: void \*
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListNode *)0xe1143694))
(*((RDPWD!_SListNode *)0xe1143694)) [Type: _SListNode]
+0x000\] Key : 0x0 \[Type: unsigned int
+0x004\] Value : 0x0 \[Type: void \*
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListNode *)0xe114369c))
(*((RDPWD!_SListNode *)0xe114369c)) [Type: _SListNode]
+0x000\] Key : 0x0 \[Type: unsigned int
+0x004\] Value : 0x0 \[Type: void \*
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListNode *)0xe11436a4))
(*((RDPWD!_SListNode *)0xe11436a4)) [Type: _SListNode]
+0x000\] Key : 0x0 \[Type: unsigned int
+0x004\] Value : 0x0 \[Type: void \*
if (pUA != NULL) {
// Store info in UA.
pUA->UserDefined = UserDefined;
SListInit(&pUA->JoinedChannelList, DefaultNumChannels);
pUA->pDomain = pDomain;
pUA->Callback = UserCallback;
pUA->SDCallback = SDCallback;
}
void SListInit(PSList pSL, unsigned NItems)
{
// Initialize the private member variables. Use preallocated array for
// initial node array.
pSL->Hdr.NEntries = 0;
pSL->Hdr.MaxEntries = SListDefaultNumEntries;
pSL->Hdr.HeadOffset = 0;
pSL->Hdr.CurrOffset = 0xFFFFFFFF;
pSL->Hdr.Entries = pSL->InitialList;
}
第二部分:
// Allocate a UserAttachment. Try the prealloc list first.
pUA = NULL;
for (i = 0; i < NumPreallocUA; i++) {
if (!pDomain->PreallocUA[i].bInUse) {
pUA = &pDomain->PreallocUA[i];
pUA->bInUse = TRUE;
}
} //之后:
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!UserAttachment (*)[2])0xe114361c))
(*((RDPWD!UserAttachment (*)[2])0xe114361c)) [Type: UserAttachment [2]]
0\] \[Type: UserAttachment
1\] \[Type: UserAttachment
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!UserAttachment *)0xe114361c))
(*((RDPWD!UserAttachment *)0xe114361c)) [Type: UserAttachment]
+0x000\] pDomain : 0x0 \[Type: _Domain \*
+0x004\] bLocal : 0x0 \[Type: unsigned char
+0x005\] bPreallocated : 0x1 \[Type: unsigned char
+0x006\] bInUse : 0x1 \[Type: unsigned char
+0x008\] UserDefined : 0x0 \[Type: void \*
+0x00c\] UserID : 0x0 \[Type: unsigned int
+0x010\] JoinedChannelList \[Type: SList
+0x044\] Callback : 0x0 \[Type: void (\*)(void \*,unsigned int,void \*,void \*)
+0x048\] SDCallback : 0x0 \[Type: unsigned char (\*)(unsigned char \*,unsigned int,void \*,void \*,unsigned char,void \*,MCSPriority,unsigned int,unsigned int)
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!UserAttachment *)0xe1143668))
(*((RDPWD!UserAttachment *)0xe1143668)) [Type: UserAttachment]
+0x000\] pDomain : 0x0 \[Type: _Domain \*
+0x004\] bLocal : 0x0 \[Type: unsigned char
+0x005\] bPreallocated : 0x1 \[Type: unsigned char
+0x006\] bInUse : 0x1 \[Type: unsigned char
+0x008\] UserDefined : 0x0 \[Type: void \*
+0x00c\] UserID : 0x0 \[Type: unsigned int
+0x010\] JoinedChannelList \[Type: SList
+0x044\] Callback : 0x0 \[Type: void (\*)(void \*,unsigned int,void \*,void \*)
+0x048\] SDCallback : 0x0 \[Type: unsigned char (\*)(unsigned char \*,unsigned int,void \*,void \*,unsigned char,void \*,MCSPriority,unsigned int,unsigned int)
1: kd> r
eax=e11436ba ebx=8947eef8 ecx=00000000 edx=e1143540 esi=e1143668 edi=e1143540
eip=b9d79909 esp=b9a10368 ebp=b9a10374 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
RDPWD!MCSAttachUserRequest+0x67:
b9d79909 85f6 test esi,esi
1: kd> dt UserAttachment e1143668
RDPWD!UserAttachment
+0x000 pDomain : (null)
+0x004 bLocal : 0 ''
+0x005 bPreallocated : 0x1 ''
+0x006 bInUse : 0x1 ''
+0x008 UserDefined : (null)
+0x00c UserID : 0
+0x010 JoinedChannelList : SList
+0x044 Callback : (null)
+0x048 SDCallback : (null)
if (pUA != NULL) {
// Store info in UA.
pUA->UserDefined = UserDefined;
SListInit(&pUA->JoinedChannelList, DefaultNumChannels);
pUA->pDomain = pDomain;
pUA->Callback = UserCallback;
pUA->SDCallback = SDCallback;
} //之后:
1: kd> dt UserAttachment e1143668
RDPWD!UserAttachment
+0x000 pDomain : (null)
+0x004 bLocal : 0 ''
+0x005 bPreallocated : 0x1 ''
+0x006 bInUse : 0x1 ''
+0x008 UserDefined : 0xe116ee30 Void
+0x00c UserID : 0
+0x010 JoinedChannelList : SList
+0x044 Callback : (null)
+0x048 SDCallback : (null)
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!SList *)0xe1143678))
(*((RDPWD!SList *)0xe1143678)) [Type: SList]
+0x000\] Hdr \[Type: _SListHeader
+0x014\] InitialList \[Type: _SListNode \[4\]
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListHeader *)0xe1143678))
(*((RDPWD!_SListHeader *)0xe1143678)) [Type: _SListHeader]
+0x000\] NEntries : 0x0 \[Type: unsigned int
+0x004\] MaxEntries : 0x4 \[Type: unsigned int
+0x008\] HeadOffset : 0x0 \[Type: unsigned int
+0x00c\] CurrOffset : 0xffffffff \[Type: unsigned int
+0x010\] Entries : 0xe114368c \[Type: _SListNode \*
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListNode (*)[4])0xe114368c))
(*((RDPWD!_SListNode (*)[4])0xe114368c)) [Type: _SListNode [4]]
0\] \[Type: _SListNode
1\] \[Type: _SListNode
2\] \[Type: _SListNode
3\] \[Type: _SListNode
参考:
BOOL RDPCALL NM_Connect(PVOID pNMHandle, PRNS_UD_CS_NET pUserDataIn)
{
MCSErr = MCSAttachUserRequest(pRealNMHandle->hDomain,
NM_MCSUserCallback,
SM_MCSSendDataCallback,
pNMHandle,
&UserHandleTemp,
&MaxSendSizeTemp,
(BOOLEAN *)(&bCompleted));
参考:
typedef struct tagNM_HANDLE_DATA
{
/************************************************************************/
/* pSMHandle MUST be first here to allow SM_MCSSendDataCallback() to */
/* get its context pointer through double-indirection. */
/************************************************************************/
PVOID pSMHandle;
PTSHARE_WD pWDHandle;
PSDCONTEXT pContext;
UserHandle hUser;
ChannelID channelID;
ChannelHandle hChannel;
DomainHandle hDomain;
UINT32 connectStatus;
UINT32 userID;
UINT32 maxPDUSize;
BOOL dead;
/************************************************************************/
/* Virtual channel information */
/* - channelCount - number of channels in this session */
/* - channelArrayCount - number of entries in the array */
/* - channelData - information held for each channel */
/* */
/* Channel 7 is used by RDPDD. I want to use the virtual channel ID as */
/* an index into channelData, hence entry 7 is left blank. If there are */
/* more than 7 channels, channelArrayCount will be channelCount + 1. */
/************************************************************************/
UINT channelCount;
UINT channelArrayCount;
NM_CHANNEL_DATA channelData[VIRTUAL_MAXIMUM];
} NM_HANDLE_DATA, *PNM_HANDLE_DATA;
1: kd> dv
hDomain = 0xe1143540
UserCallback = 0xb9d34970
SDCallback = 0xb9d1e8f0
UserDefined = 0xe116ee30
// Allocate new UserID.
pUA->UserID = GetNewDynamicChannel(pDomain);
if (pUA->UserID == 0) {
ErrOut(pDomain->pContext, "AttachUser: Unable to get new dyn channel");
MCSErr = MCS_TOO_MANY_CHANNELS;
goto PostAllocUA;
}
// Gets a new dynamic channel number, but does not add it to channel list.
// Returns 0 if none available.
ChannelID GetNewDynamicChannel(Domain *pDomain)
{
if (SListGetEntries(&pDomain->ChannelList) >=
pDomain->DomParams.MaxChannels)
return 0;
pDomain->NextAvailDynChannel++;
ASSERT(pDomain->NextAvailDynChannel <= 65535);
return (pDomain->NextAvailDynChannel - 1);
}
1: kd> dt RDPWD!Domain 0xe1143540
+0x000 pContext : 0x895b736c _SDCONTEXT
+0x004 StackClass : 0 ( Stack_Primary )
+0x008 StatusDead : 0 ''
+0x00c PseudoRefCount : 0n1
+0x010 StackMode : 0
+0x014 bChannelBound : 0y1
+0x014 bCanSendData : 0y1
+0x014 bT120StartReceived : 0y1
+0x014 bDPumReceivedNotInput : 0y0
+0x014 bEndConnectionPacketReceived : 0y0
+0x014 bTopProvider : 0y1
+0x014 bCurrentPacketFastPath : 0y0
+0x018 pSMData : 0xe116e7c8 Void
+0x01c ReceiveBufSize : 0x800
+0x020 pReassembleData : (null)
+0x024 StoredDataLength : 0
+0x028 PacketDataLength : 0
+0x02c PacketHeaderLength : 4
+0x030 pStat : 0x895efa58 _PROTOCOLSTATUS
+0x034 ChannelList : SList
+0x068 MaxX224DataSize : 0xfff8
+0x06c X224SourcePort : 0
+0x070 MaxSendSize : 0xffef
+0x074 UserAttachmentList : SList
+0x0a8 DomParams : DomainParameters
+0x0c8 NextAvailDynChannel : 0x3ea //pDomain->NextAvailDynChannel
+0x0cc State : 0n3
+0x0d0 DelayedDPumReason : 0
+0x0d4 pBrokenEvent : (null)
+0x0d8 shadowChannel : 0
+0x0dc PreallocUA : [2] UserAttachment
+0x174 PreallocChannel : [5] MCSChannel
+0x2b4 PacketBuf : [1] ""
1: kd> dt UserAttachment e1143668
RDPWD!UserAttachment
+0x000 pDomain : 0xe1143540 _Domain
+0x004 bLocal : 0x1 ''
+0x005 bPreallocated : 0x1 ''
+0x006 bInUse : 0x1 ''
+0x008 UserDefined : 0xe116ee30 Void
+0x00c UserID : 0x3ea //+0x00c UserID : 0x3ea
+0x010 JoinedChannelList : SList
+0x044 Callback : 0xb9d34970 void RDPWD!NM_MCSUserCallback+0
+0x048 SDCallback : 0xb9d1e8f0 unsigned char RDPWD!SM_MCSSendDataCallback+0
1: kd> dt RDPWD!Domain 0xe1143540
+0x000 pContext : 0x895b736c _SDCONTEXT
+0x004 StackClass : 0 ( Stack_Primary )
+0x0c8 NextAvailDynChannel : 0x3eb
// Allocate a Channel. Try the prealloc list first.
pMCSChannel = NULL;
for (i = 0; i < NumPreallocChannel; i++) {
if (!pDomain->PreallocChannel[i].bInUse) {
pMCSChannel = &pDomain->PreallocChannel[i];
pMCSChannel->bInUse = TRUE;
}
}
// Primary remote user and local user.
#define NumPreallocUA 2
// One channel for each of remote and local user, plus share, clipboard, and
// printer redir channels.
#define NumPreallocChannel (NumPreallocUA + 3)
1: kd> dt RDPWD!Domain 0xe1143540
+0x0dc PreallocUA : [2] UserAttachment
+0x174 PreallocChannel : [5] MCSChannel
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel (*)[5])0xe11436b4))
(*((RDPWD!MCSChannel (*)[5])0xe11436b4)) [Type: MCSChannel [5]]
0\] \[Type: MCSChannel
1\] \[Type: MCSChannel
2\] \[Type: MCSChannel
3\] \[Type: MCSChannel
4\] \[Type: MCSChannel
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe11436b4))
(*((RDPWD!MCSChannel *)0xe11436b4)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x0 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe11436f4))
(*((RDPWD!MCSChannel *)0xe11436f4)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x0 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe1143774))
(*((RDPWD!MCSChannel *)0xe1143774)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x0 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe1143774))
(*((RDPWD!MCSChannel *)0xe1143774)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x0 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe11437b4))
(*((RDPWD!MCSChannel *)0xe11437b4)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x0 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
// Allocate a Channel. Try the prealloc list first.
pMCSChannel = NULL;
for (i = 0; i < NumPreallocChannel; i++) {
if (!pDomain->PreallocChannel[i].bInUse) {
pMCSChannel = &pDomain->PreallocChannel[i];
pMCSChannel->bInUse = TRUE;
}
}//之后:
+0x174 PreallocChannel : [5] MCSChannel
+0x2b4 PacketBuf : [1] ""
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel (*)[5])0xe11436b4))
(*((RDPWD!MCSChannel (*)[5])0xe11436b4)) [Type: MCSChannel [5]]
0\] \[Type: MCSChannel
1\] \[Type: MCSChannel
2\] \[Type: MCSChannel
3\] \[Type: MCSChannel
4\] \[Type: MCSChannel
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe11436b4))
(*((RDPWD!MCSChannel *)0xe11436b4)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x1 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe11436f4))
(*((RDPWD!MCSChannel *)0xe11436f4)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x1 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe1143734))
(*((RDPWD!MCSChannel *)0xe1143734)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x1 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe1143774))
(*((RDPWD!MCSChannel *)0xe1143774)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x1 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe11437b4))
(*((RDPWD!MCSChannel *)0xe11437b4)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 0 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x1 \[Type: unsigned char
+0x03c\] ID : 0x0 \[Type: unsigned int
1: kd> r
eax=e114382d ebx=e11437b4 ecx=00000000 edx=e1143540 esi=e1143668 edi=e1143540
eip=b9d799a1 esp=b9a10368 ebp=b9a10374 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
RDPWD!MCSAttachUserRequest+0xff:
b9d799a1 85db test ebx,ebx
pMCSChanne=ebx=e11437b4 最后一个
if (pMCSChannel != NULL) {
pMCSChannel->Type = Channel_UserID;
pMCSChannel->ID = pUA->UserID;
SListInit(&pMCSChannel->UserList, DefaultNumChannels);
}
// Types of channels possible in the MCSChannel struct below.
#define Channel_Unused 0
#define Channel_Static 1
#define Channel_UserID 2
#define Channel_Assigned 3
#define Channel_Convened 4
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!MCSChannel *)0xe11437b4))
(*((RDPWD!MCSChannel *)0xe11437b4)) [Type: MCSChannel]
+0x000\] UserList \[Type: SList
+0x034\] Type : 2 \[Type: int
+0x038\] bPreallocated : 0x1 \[Type: unsigned char
+0x039\] bInUse : 0x1 \[Type: unsigned char
+0x03c\] ID : 0x3ea \[Type: unsigned int
1: kd> dt RDPWD!MCSChannel 0xe11437b4
+0x000 UserList : SList
+0x034 Type : 0n2
+0x038 bPreallocated : 0x1 ''
+0x039 bInUse : 0x1 ''
+0x03c ID : 0x3ea
if (SListAppend(&pDomain->ChannelList, pMCSChannel->ID, pMCSChannel)) {
// Add user attachment to attachment list.
第三部分:
/*
* Append
* Inserts a value at the end of a list. Returns FALSE on error.
*/
BOOLEAN SListAppend(PSList pSL, UINT_PTR NewKey, void *NewValue)
{
unsigned Temp;
if (pSL->Hdr.NEntries < pSL->Hdr.MaxEntries ||
(pSL->Hdr.NEntries >= pSL->Hdr.MaxEntries && SListExpand(pSL))) {
Temp = pSL->Hdr.HeadOffset + pSL->Hdr.NEntries;
if (Temp >= pSL->Hdr.MaxEntries)
Temp -= pSL->Hdr.MaxEntries;
pSL->Hdr.Entries[Temp].Key = NewKey;
pSL->Hdr.Entries[Temp].Value = NewValue;
pSL->Hdr.NEntries++;
return TRUE;
}
else {
return FALSE;
}
}
1: kd> dt RDPWD!Domain 0xe1143540
+0x034 ChannelList : SList
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!SList *)0xe1143574))
(*((RDPWD!SList *)0xe1143574)) [Type: SList]
+0x000\] Hdr \[Type: _SListHeader
+0x014\] InitialList \[Type: _SListNode \[4\]
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListHeader *)0xe1143574))
(*((RDPWD!_SListHeader *)0xe1143574)) [Type: _SListHeader]
+0x000\] NEntries : 0x0 \[Type: unsigned int
+0x004\] MaxEntries : 0x4 \[Type: unsigned int
+0x008\] HeadOffset : 0x0 \[Type: unsigned int
+0x00c\] CurrOffset : 0xffffffff \[Type: unsigned int
+0x010\] Entries : 0xe1143588 \[Type: _SListNode \*
1: kd> dx -id 0,0,89515c28 -r1 ((RDPWD!_SListNode *)0xe1143588)
((RDPWD!_SListNode *)0xe1143588) : 0xe1143588 [Type: _SListNode *]
+0x000\] Key : 0x0 \[Type: unsigned int
+0x004\] Value : 0x0 \[Type: void \*
SListAppend(&pDomain->ChannelList, pMCSChannel->ID, pMCSChannel) 之后:
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!SList *)0xe1143574))
(*((RDPWD!SList *)0xe1143574)) [Type: SList]
+0x000\] Hdr \[Type: _SListHeader
+0x014\] InitialList \[Type: _SListNode \[4\]
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListHeader *)0xe1143574))
(*((RDPWD!_SListHeader *)0xe1143574)) [Type: _SListHeader]
+0x000\] NEntries : 0x1 \[Type: unsigned int
+0x004\] MaxEntries : 0x4 \[Type: unsigned int
+0x008\] HeadOffset : 0x0 \[Type: unsigned int
+0x00c\] CurrOffset : 0xffffffff \[Type: unsigned int
+0x010\] Entries : 0xe1143588 \[Type: _SListNode \*
1: kd> dx -id 0,0,89515c28 -r1 ((RDPWD!_SListNode *)0xe1143588)
((RDPWD!_SListNode *)0xe1143588) : 0xe1143588 [Type: _SListNode *]
+0x000\] Key : 0x3ea \[Type: unsigned int
+0x004\] Value : 0xe11437b4 \[Type: void \*
if (SListAppend(&pDomain->UserAttachmentList, (UINT_PTR)pUA, pUA)) {
之后:
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!SList *)0xe11435b4))
(*((RDPWD!SList *)0xe11435b4)) [Type: SList]
+0x000\] Hdr \[Type: _SListHeader
+0x014\] InitialList \[Type: _SListNode \[4\]
1: kd> dx -id 0,0,89515c28 -r1 (*((RDPWD!_SListHeader *)0xe11435b4))
(*((RDPWD!_SListHeader *)0xe11435b4)) [Type: _SListHeader]
+0x000\] NEntries : 0x1 \[Type: unsigned int
+0x004\] MaxEntries : 0x4 \[Type: unsigned int
+0x008\] HeadOffset : 0x0 \[Type: unsigned int
+0x00c\] CurrOffset : 0xffffffff \[Type: unsigned int
+0x010\] Entries : 0xe11435c8 \[Type: _SListNode \*
1: kd> dx -id 0,0,89515c28 -r1 ((RDPWD!_SListNode *)0xe11435c8)
((RDPWD!_SListNode *)0xe11435c8) : 0xe11435c8 [Type: _SListNode *]
+0x000\] Key : 0xe1143668 \[Type: unsigned int
+0x004\] Value : 0xe1143668 \[Type: void \*
*phUser = pUA;
1: kd> dv
hDomain = 0xe1143574
UserCallback = 0xb9d34970
SDCallback = 0xb9d1e8f0
UserDefined = 0xe116ee30
phUser = 0xb9a103c8
pMaxSendSize = 0xb9a103ac
pbCompleted = 0xb9a103cf ""
1: kd> dx -r1 ((RDPWD!void * *)0xb9a103c8)
((RDPWD!void * *)0xb9a103c8) : 0xb9a103c8 [Type: void * *]
0xe1143668 [Type: void *]
if (pDomain->bTopProvider) {
// The action is complete, there is no need for a callback.
*pbCompleted = TRUE;
}
总结:下面的结构修改了5处:
1: kd> dt RDPWD!Domain 0xe1143540
+0x000 pContext : 0x895b736c _SDCONTEXT
+0x004 StackClass : 0 ( Stack_Primary )
+0x008 StatusDead : 0 ''
+0x00c PseudoRefCount : 0n1
+0x010 StackMode : 0
+0x014 bChannelBound : 0y1
+0x014 bCanSendData : 0y1
+0x014 bT120StartReceived : 0y1
+0x014 bDPumReceivedNotInput : 0y0
+0x014 bEndConnectionPacketReceived : 0y0
+0x014 bTopProvider : 0y1
+0x014 bCurrentPacketFastPath : 0y0
+0x018 pSMData : 0xe116e7c8 Void
+0x01c ReceiveBufSize : 0x800
+0x020 pReassembleData : (null)
+0x024 StoredDataLength : 0
+0x028 PacketDataLength : 0
+0x02c PacketHeaderLength : 4
+0x030 pStat : 0x895efa58 _PROTOCOLSTATUS
+0x034 ChannelList : SList //第1处
+0x068 MaxX224DataSize : 0xfff8
+0x06c X224SourcePort : 0
+0x070 MaxSendSize : 0xffef
+0x074 UserAttachmentList : SList //第2处
+0x0a8 DomParams : DomainParameters
+0x0c8 NextAvailDynChannel : 0x3eb //第3处
+0x0cc State : 0n3
+0x0d0 DelayedDPumReason : 0
+0x0d4 pBrokenEvent : (null)
+0x0d8 shadowChannel : 0
+0x0dc PreallocUA : [2] UserAttachment //第4处
+0x174 PreallocChannel : [5] MCSChannel //第5处
+0x2b4 PacketBuf : [1] ""