NdrpEmbeddedPointerUnmarshall函数分析之第二次循环处理第二部分DomainSid
背景:
0: kd> dt _POLICY_ACCOUNT_DOMAIN_INFO 00096488
services!_POLICY_ACCOUNT_DOMAIN_INFO
+0x000 DomainName : _UNICODE_STRING "NTDEV-QQTQSNLDX"
+0x008 DomainSid : 0x000964d8 Void
0: kd> dt _sid
services!_SID
+0x000 Revision : UChar
+0x001 SubAuthorityCount : UChar
+0x002 IdentifierAuthority : _SID_IDENTIFIER_AUTHORITY
+0x008 SubAuthority : [1] Uint4B
1: kd> dt _sid 0x000964d8
services!_SID
+0x000 Revision : 0x1 ''
+0x001 SubAuthorityCount : 0x4 ''
+0x002 IdentifierAuthority : _SID_IDENTIFIER_AUTHORITY
+0x008 SubAuthority : [1] 0x15
1: kd> dx -id 0,0,898be250 -r1 (*((services!unsigned long (*)[1])0x964e0))
(*((services!unsigned long (*)[1])0x964e0)) [Type: unsigned long [1]]
[0] : 0x15 [Type: unsigned long]
1: kd> db 0x964e0
000964e0 15 00 00 00 0b 2e 6b 25-d5 fe fd 81 2b 5f a6 f7 ......k%....+_..
第一部分:
PFORMAT_STRING
NdrpEmbeddedPointerUnmarshall(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PFORMAT_STRING pFormat,
uchar fNewMemory )
{
for (;;)
{
if ( *pFormat == FC_END )
{
return pFormat;
}
// Check for FC_FIXED_REPEAT or FC_VARIABLE_REPEAT.
if ( *pFormat != FC_NO_REPEAT )
{
pStubMsg->MaxCount = MaxCountSave;
pStubMsg->Offset = OffsetSave;
pStubMsg->BufferMark = pBufferMark;
pFormat = NdrpEmbeddedRepeatPointerUnmarshall( pStubMsg,
pMemory,
pFormat,
fNewMemory );
// Continue to the next pointer.
continue;
}
// Compute the pointer to the current memory pointer to the data.
ppMemPtr = (uchar **)( pMemory + *((signed short *)(pFormat + 2)) );
// Compute the pointer to the pointer in the buffer.
ppBufPtr = (uchar **)(pBufferMark + *((signed short *)(pFormat + 4)));
// Increment to the pointer description.
pFormat += 6;
//
// If the incomming encapsulating memory pointer was just allocated,
// then explicitly null out the current pointer.
//
if ( fNewMemory )
*ppMemPtr = 0;
NdrpPointerUnmarshall(
pStubMsg,
(uchar**)ppMemPtr, // Memory rep written here
*ppMemPtr,
(long *)ppBufPtr, // Wire rep written here
pFormat );
第二部分:
/* 758 */
0x46, /* FC_NO_REPEAT */ //pFormat += 4 到这里了
0x5c, /* FC_PAD */
/* 760 */ NdrFcShort( 0x8 ), /* 8 */
/* 762 */ NdrFcShort( 0x8 ), /* 8 */
/* 764 */ 0x12, 0x0, /* FC_UP */
/* 766 */ NdrFcShort( 0xfe4a ), /* Offset= -438 (328) */
/* 768 */
0x5b, /* FC_END */
0: kd> r
eax=007b0a46 ebx=007b0a58 ecx=00000000 edx=000964b8 esi=0006fae0 edi=77d75480
eip=77c5241e esp=0006f930 ebp=0006f94c iopl=0 nv up ei ng nz ac pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000297
RPCRT4!NdrpEmbeddedPointerUnmarshall+0x46:
001b:77c5241e 3c46 cmp al,46h
0: kd> db 77d75480
77d75480 46 5c 08 00 08 00 12 00-4a fe 5b 06 06 08 08 5b F\......J.[....[
77d75490 1c 01 02 00 17 55 02 00-01 00 17 55 00 00 01 00 .....U.....U....
第三部分:内存指针的确定
// Compute the pointer to the current memory pointer to the data.
ppMemPtr = (uchar **)( pMemory + *((signed short *)(pFormat + 2)) );
// Compute the pointer to the pointer in the buffer.
ppBufPtr = (uchar **)(pBufferMark + *((signed short *)(pFormat + 4)));
// Increment to the pointer description.
pFormat += 6;
第四部分:
0: kd> dd 0x00096488
00096488 00000000 000964b8 00000000 00000000
第五部分:缓冲区指针位置的确定
/* 758 */
0x46, /* FC_NO_REPEAT */ //pFormat += 4 到这里了
0x5c, /* FC_PAD */
/* 760 */ NdrFcShort( 0x8 ), /* 8 */
/* 762 */ NdrFcShort( 0x8 ), /* 8 */
/* 764 */ 0x12, 0x0, /* FC_UP */
/* 766 */ NdrFcShort( 0xfe4a ), /* Offset= -438 (328) */
/* 768 */
0x5b, /* FC_END */
0: kd> dx -id 0,0,897e1020 -r1 ((RPCRT4!_MIDL_STUB_MESSAGE *)0x6fae0)
((RPCRT4!_MIDL_STUB_MESSAGE *)0x6fae0) : 0x6fae0 [Type: _MIDL_STUB_MESSAGE *]
[+0x000] RpcMsg : 0x6fab4 [Type: _RPC_MESSAGE *]
[+0x004] Buffer : 0x7b0a8e : 0x0 [Type: unsigned char *]
0: kd> db 0x7b0a8e
007b0a8e 00 00 04 00 00 00 01 04-00 00 00 00 00 05 15 00 ................
007b0a9e 00 00 0b 2e 6b 25 d5 fe-fd 81 2b 5f a6 f7 00 00 ....k%....+_....
007b0aae 00 00 0d f0 ad ba 0d f0-ad ba 0d f0 ad ba 0d f0 ................
007b0abe ad ba 0d f0 ad ba 0d f0-ad ba 0d f0 ad ba 0d f0 ................
007b0ace ad ba 0d f0 ad ba 0d f0-ad ba 0d f0 ad ba 0d f0 ................
007b0ade ad ba 0d f0 ad ba 0d f0-ad ba 0d f0 ad ba 0d f0 ................
007b0aee ad ba 0d f0 ad ba 0d f0-ad ba 0d f0 ad ba 0d f0 ................
007b0afe ad ba 0d f0 ad ba 0d f0-ad ba 0d f0 ad ba 0d f0 ................
0: kd> db 0x7b0a50
007b0a50 00 00 02 00 05 00 00 00-1e 00 20 00 b8 64 09 00 .......... ..d..
007b0a60 08 00 02 00 10 00 00 00-00 00 00 00 0f 00 00 00 ................
007b0a70 4e 00 54 00 44 00 45 00-56 00 2d 00 51 00 51 00 N.T.D.E.V.-.Q.Q.
007b0a80 54 00 51 00 53 00 4e 00-4c 00 44 00 58 00 00 00 T.Q.S.N.L.D.X...
007b0a90 04 00 00 00 01 04 00 00-00 00 00 05 15 00 00 00 ................
007b0aa0 0b 2e 6b 25 d5 fe fd 81-2b 5f a6 f7 00 00 00 00 ..k%....+_......
007b0ab0 0d f0 ad ba 0d f0 ad ba-0d f0 ad ba 0d f0 ad ba ................
红色的是控制部分,不会被拷贝。
第六部分:格式化字符串位置的确定
// Increment to the pointer description.
pFormat += 6;
/* 758 */
0x46, /* FC_NO_REPEAT */ //pFormat += 4 到这里了
0x5c, /* FC_PAD */
/* 760 */ NdrFcShort( 0x8 ), /* 8 */
/* 762 */ NdrFcShort( 0x8 ), /* 8 */
/* 764 */ 0x12, 0x0, /* FC_UP */ 这里是指针描述需要跳转到328位置看具体情况
/* 766 */ NdrFcShort( 0xfe4a ), /* Offset= -438 (328) */
/* 768 */
0x5b, /* FC_END */
第七部分:
/* 328 */
0x17, /* FC_CSTRUCT */
0x3, /* 3 */
/* 330 */ NdrFcShort( 0x8 ), /* 8 */
/* 332 */ NdrFcShort( 0xfff0 ), /* Offset= -16 (316) */
/* 334 */ 0x2, /* FC_CHAR */ /* 334 */ 0x2, /* FC_CHAR */ 不是 FC_PP
0x2, /* FC_CHAR */
/* 336 */ 0x4c, /* FC_EMBEDDED_COMPLEX */
0x0, /* 0 */
/* 338 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (306) */
/* 340 */ 0x5c, /* FC_PAD */
0x5b, /* FC_END */