RPCRT4!NdrConformantStructUnmarshall函数分析的一个例子处理第二部分DomainSid
第一部分:
PFORMAT_STRING
NdrpEmbeddedPointerUnmarshall(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PFORMAT_STRING pFormat,
uchar fNewMemory )
{
NdrpPointerUnmarshall(
pStubMsg,
(uchar**)ppMemPtr, // Memory rep written here
*ppMemPtr,
(long *)ppBufPtr, // Wire rep written here
pFormat );
0: kd> p
RPCRT4!NdrpEmbeddedPointerUnmarshall+0x89:
001b:77c52461 e8393fffff call RPCRT4!NdrpPointerUnmarshall (77c4639f)
0: kd> t
RPCRT4!NdrpPointerUnmarshall:
001b:77c4639f 55 push ebp
0: kd> g
Breakpoint 5 hit
RPCRT4!NdrConformantStructUnmarshall:
001b:77c44859 55 push ebp
0: kd> kc
#
00 RPCRT4!NdrConformantStructUnmarshall
01 RPCRT4!NdrpPointerUnmarshall
02 RPCRT4!NdrpEmbeddedPointerUnmarshall
03 RPCRT4!NdrSimpleStructUnmarshall
04 RPCRT4!NdrpUnionUnmarshall
05 RPCRT4!NdrNonEncapsulatedUnionUnmarshall
06 RPCRT4!NdrpPointerUnmarshall
07 RPCRT4!NdrPointerUnmarshall
08 RPCRT4!NdrpPointerUnmarshall
09 RPCRT4!NdrPointerUnmarshall
0a RPCRT4!NdrpClientUnMarshal
0b RPCRT4!NdrClientCall2
0c ADVAPI32!LsarQueryInformationPolicy
0d ADVAPI32!LsaQueryInformationPolicy
0e services!ScGetAccountDomainInfo
0f services!ScInitServiceAccount
10 services!SvcctrlMain
11 services!main
12 services!mainCRTStartup
13 kernel32!BaseProcessStart
0: kd> dv
pStubMsg = 0x0006fae0
ppMemory = 0x00096490
pFormat = 0x77d752d2 "???"
fMustAlloc = 0x01 ''
StructSize = 0x77d752d2
fIsEmbeddedStruct = 0x00 ''
pCorrMemorySave = 0x77d75440 "???"
0: kd> db 0x77d752d2
77d752d2 17 03 08 00 f0 ff 02 02-4c 00 e0 ff 5c 5b 1b 00 ........L...\[..
第二部分:
第二部分A:内存指针ppMemory
ppMemory = 0x00096490
0: kd> dd 0x00096488
00096488 00000000 000964b8 00000000 00000000
第二部分B:缓冲区指针
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%....+_....
第二部分C:格式化字符串指针pFormat
/* 328 */
0x17, /* FC_CSTRUCT */
0x3, /* 3 */
/* 330 */ NdrFcShort( 0x8 ), /* 8 */
/* 332 */ NdrFcShort( 0xfff0 ), /* Offset= -16 (316) */
/* 334 */ 0x2, /* FC_CHAR */
0x2, /* FC_CHAR */
/* 336 */ 0x4c, /* FC_EMBEDDED_COMPLEX */
0x0, /* 0 */
/* 338 */ NdrFcShort( 0xffe0 ), /* Offset= -32 (306) */
/* 340 */ 0x5c, /* FC_PAD */
0x5b, /* FC_END */
第三部分:
// Add the size of the conformant array to the structure size.
// check for possible mulitplication overflow attack here.
StructSize += MultiplyWithOverflowCheck( (ulong)pStubMsg->MaxCount, *((ushort *)(pFormatArray + 2) ) );
// check for overflow when calculating the total size.
#if defined(_X86_)
ULONG MultiplyWithOverflowCheck( ULONG_PTR Count, ULONG_PTR ELemSize )
{
register UINT32 IsOverFlowed = 0;
NDR_CORRUPTION_ASSERT( Count < 0x80000000, "invalid count" );
NDR_CORRUPTION_ASSERT( ELemSize < 0x80000000 , "invalid element size" );
ULONG res = Count * ELemSize;
__asm
{
jno skip;
mov IsOverFlowed, 1;
skip:
}
if ( IsOverFlowed || res > 0x7fffffff )
RpcRaiseException( RPC_X_INVALID_BOUND );
return res;
}
第四部分:pStubMsg->MaxCount的确定
pStubMsg->Buffer4字节对齐之后变为eax=007b0a90
else
{
// Align the buffer for unmarshalling the conformance count.
ALIGN(pStubMsg->Buffer,3); 4字节对齐
pStubMsg->MaxCount = *((ulong * &)pStubMsg->Buffer)++;
}
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x1c:
001b:77c44875 8b4304 mov eax,dword ptr [ebx+4]
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> r
eax=77be2800 ebx=0006fae0 ecx=00000017 edx=fffffe4a esi=0006fae0 edi=00096490
eip=77c44875 esp=0006f8e0 ebp=0006f8e8 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
RPCRT4!NdrConformantStructUnmarshall+0x1c:
001b:77c44875 8b4304 mov eax,dword ptr [ebx+4] ds:0023:0006fae4=007b0a8e
0: kd> dd 0006fae0
0006fae0 0006fab4 007b0a8e 007b0a50 007b0ab0
#define ALIGN(buffer,increment) \
(((ULONG_PTR)buffer + increment) & ~ increment)
4字节对齐
// Align the buffer for unmarshalling the conformance count.
ALIGN(pStubMsg->Buffer,3);
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x1f:
001b:77c44878 83c003 add eax,3
0: kd> r
eax=007b0a8e ebx=0006fae0 ecx=00000017 edx=fffffe4a esi=0006fae0 edi=00096490
eip=77c44878 esp=0006f8e0 ebp=0006f8e8 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
RPCRT4!NdrConformantStructUnmarshall+0x1f:
001b:77c44878 83c003 add eax,3
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x22:
001b:77c4487b 83e0fc and eax,0FFFFFFFCh
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x25:
001b:77c4487e 894304 mov dword ptr [ebx+4],eax
0: kd> r
eax=007b0a90 ebx=0006fae0 ecx=00000017 edx=fffffe4a esi=0006fae0 edi=00096490
eax=007b0a90=pStubMsg->Buffer
第五部分:pStubMsg->Buffer再加4变为eax=007b0a94
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x28:
001b:77c44881 8b08 mov ecx,dword ptr [eax]
0: kd> r
eax=007b0a90 ebx=0006fae0 ecx=00000017 edx=fffffe4a esi=0006fae0 edi=00096490
eip=77c44881 esp=0006f8e0 ebp=0006f8e8 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
RPCRT4!NdrConformantStructUnmarshall+0x28:
001b:77c44881 8b08 mov ecx,dword ptr [eax] ds:0023:007b0a90=00000004
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x2a:
001b:77c44883 83c004 add eax,4
0: kd> r
eax=007b0a90 ebx=0006fae0 ecx=00000004
pStubMsg->MaxCount = *((ulong * &)pStubMsg->Buffer)++;
}
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x2d:
001b:77c44886 894b3c mov dword ptr [ebx+3Ch],ecx
0: kd> r
eax=007b0a94 ebx=0006fae0 ecx=00000004
结果:
pStubMsg->MaxCount = 4
((ulong * &)pStubMsg->Buffer)++
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x30:
001b:77c44889 894304 mov dword ptr [ebx+4],eax
0: kd> r
eax=007b0a94 ebx=0006fae0
0: kd> db 0x7b0a8e
007b0a8e 00 00 04 00 00 00
pStubMsg->Buffer=
0: kd> db 007b0a94
007b0a94 01 04 00 00 00 00 00 05-15 00 00 00 0b 2e 6b 25 ..............k%
第六部分:StructSize的初步确定
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x43:
001b:77c4489c 23c8 and ecx,eax
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x45:
001b:77c4489e 47 inc edi
0: kd> r
eax=fffffffc ebx=0006fae0 ecx=007b0a94 edx=fffffe4a esi=0006fae0 edi=77d752d2
// Increment format string to structure size field.
pFormat += 2;
0: kd> db 77d752d2
77d752d2 17 03 08 00 f0 ff 02 02-4c 00 e0 ff 5c 5b 1b 00 ........L...\[..
// Get flat struct size and increment format string.
StructSize = (ulong) *((ushort * &)pFormat)++; =8
0: kd> r
eax=00000008 ebx=0006fae0 ecx=007b0a94 edx=fffffe4a esi=0006fae0 edi=77d752d6
pFormat=edi=77d752d6
第七部分:pFormatArray和数组每个元素的大小是4个字节
0: kd> db 77d752d6
77d752d6 f0 ff
// Get the conformant array's description.
pFormatArray = pFormat + *((signed short *)pFormat);=
pFormatArray=
/* 316 */
0x1b, /* FC_CARRAY */
0x3, /* 3 */
/* 318 */ NdrFcShort( 0x4 ), /* 4 */ 数组元素的大小是4个字节。
/* 320 */ 0x4, /* Corr desc: FC_USMALL */
0x0, /* */
/* 322 */ NdrFcShort( 0xfff9 ), /* -7 */
/* 324 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 326 */ 0x8, /* FC_LONG */
0x5b, /* FC_END */
0: kd> db 77d752c6
77d752c6 1b 03 04 00 04 00 f9 ff-01 00 08 5b 17 03 08 00 ...........[....
第八部分:StructSize再加0x10个字节(4*4)
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x8f:
001b:77c448e8 0fb74602 movzx eax,word ptr [esi+2]
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x93:
001b:77c448ec 50 push eax
0: kd> r
eax=00000004 ebx=0006fae0 ecx=77d752ca edx=00000001 esi=77d752c6 edi=77d752d6
eip=77c448ec esp=0006f8d8 ebp=0006f8e8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
RPCRT4!NdrConformantStructUnmarshall+0x93:
001b:77c448ec 50 push eax
0: kd> db 77d752c6
77d752c6 1b 03 04 00
// Add the size of the conformant array to the structure size.
// check for possible mulitplication overflow attack here.
StructSize += MultiplyWithOverflowCheck( (ulong)pStubMsg->MaxCount, *((ushort *)(pFormatArray + 2) ) );
pFormatArray + 2地址处的值为4
4*4=16
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%....+_..
0: kd> db 007b0a94
007b0a94 01 04 00 00 00 00 00 05-15 00 00 00 0b 2e 6b 25 ..............k%
007b0aa4 d5 fe fd 81 2b 5f a6 f7
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x94:
001b:77c448ed ff733c push dword ptr [ebx+3Ch]
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x97:
001b:77c448f0 e867b3ffff call RPCRT4!MultiplyWithOverflowCheck (77c3fc5c)
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0x9c:
001b:77c448f5 014510 add dword ptr [ebp+10h],eax
0: kd> r
eax=00000010
MultiplyWithOverflowCheck( (ulong)pStubMsg->MaxCount, *((ushort *)(pFormatArray + 2) ) );
返回值=0x10
0: kd> r
eax=00000010 ebx=0006fae0 ecx=77d752ca edx=00000001 esi=77d752c6 edi=77d752d6
eip=77c448f5 esp=0006f8d8 ebp=0006f8e8 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!NdrConformantStructUnmarshall+0x9c:
001b:77c448f5 014510 add dword ptr [ebp+10h],eax ss:0023:0006f8f8=00000008
0: kd> dd 0006f8e8+10
0006f8f8 00000008
StructSize += 0x10
第九部分:拷贝内存的源地址
//
// Remember where we're going to copy from.
//
pBufferStart = pStubMsg->Buffer;
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 : 0x7b0a94 : 0x1 [Type: unsigned char *]
0: kd> db 0x7b0a94
007b0a94 01 04 00 00 00 00 00 05-15 00 00 00 0b 2e 6b 25 ..............k%
第十部分:分配内存0x18个字节
// Initialize the memory pointer if needed.
if ( fMustAlloc )
{
*ppMemory = (uchar *) NdrAllocate( pStubMsg, StructSize );
}
0: kd> dx -id 0,0,897e1020 -r1 ((RPCRT4!NDR_ALLOC_ALL_NODES_CONTEXT *)0x964fc)
((RPCRT4!NDR_ALLOC_ALL_NODES_CONTEXT *)0x964fc) : 0x964fc [Type: NDR_ALLOC_ALL_NODES_CONTEXT *]
[+0x000] AllocAllNodesMemory : 0x964d8 : 0x0 [Type: unsigned char *]
[+0x004] AllocAllNodesMemoryBegin : 0x96488 : 0x0 [Type: unsigned char *]
[+0x008] AllocAllNodesMemoryEnd : 0x964fc : 0xd8 [Type: unsigned char *]
void * RPC_ENTRY
NdrAllocate(
PMIDL_STUB_MESSAGE pStubMsg,
size_t Len )
{
void * pMemory;
if ( pStubMsg->pAllocAllNodesContext )
{
//
// We must guarantee 4 byte alignment on NT and MAC.
//
#if defined(__RPC_WIN64__)
ALIGN(pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory,7);
#else
ALIGN(pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory,3);
#endif
// Get the pointer.
pMemory = pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory;
// Increment the block pointer.
pStubMsg->pAllocAllNodesContext->AllocAllNodesMemory += Len;
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0xd7:
001b:77c44930 e84eafffff call RPCRT4!NdrAllocate (77c3f883)
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0xdc:
001b:77c44935 8b4d0c mov ecx,dword ptr [ebp+0Ch]
0: kd> r
eax=000964d8 ebx=0006fae0 ecx=000964fc edx=000964f0 esi=007b0a94 edi=77d752d8
eip=77c44935 esp=0006f8d8 ebp=0006f8e8 iopl=0 nv up ei ng nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293
RPCRT4!NdrConformantStructUnmarshall+0xdc:
001b:77c44935 8b4d0c mov ecx,dword ptr [ebp+0Ch] ss:0023:0006f8f4=00096490
0: kd> dd 0x00096488
00096488 00000000 000964b8 00000000
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0xdf:
001b:77c44938 8901 mov dword ptr [ecx],eax
0: kd> p
RPCRT4!NdrConformantStructUnmarshall+0xe1:
001b:77c4493a eb10 jmp RPCRT4!NdrConformantStructUnmarshall+0xf3 (77c4494c)
0: kd> dd 0x00096488
00096488 00000000 000964b8 000964d8
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 : 0x7b0aac : 0x0 [Type: unsigned char *]
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%....+_......
第十一部分:拷贝内存
0: kd> dd 0x00096488
00096488 00000000 000964b8 000964d8 00000000
00096498 00000000 00000000 00000000 00000000
000964a8 00000000 00000000 00000000 00000000
000964b8 0054004e 00450044 002d0056 00510051
000964c8 00510054 004e0053 0044004c 00000058
000964d8 00000000 00000000 00000000 00000000
000964e8 00000000 00000000 00000000 00000000
000964f8 00000000 000964f0 00096488 000964fc
// Copy the struct if we're not using the rpc buffer.
if ( *ppMemory != pBufferStart )
{
RpcpMemoryCopy( *ppMemory,
pBufferStart,
StructSize );
}
0: kd> dd 0x00096488
00096488 00000000 000964b8 000964d8 00000000
00096498 00000000 00000000 00000000 00000000
000964a8 00000000 00000000 00000000 00000000
000964b8 0054004e 00450044 002d0056 00510051
000964c8 00510054 004e0053 0044004c 00000058
000964d8 00000401 05000000 00000015 256b2e0b
000964e8 81fdfed5 f7a65f2b 00000000 00000000
000964f8 00000000 000964f0 00096488 000964fc