当前位置: 首页 > java >正文

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

http://www.xdnf.cn/news/2475.html

相关文章:

  • 【Nginx】负载均衡配置详解
  • 互联网大厂Java求职面试:从Java核心到微服务的深度探索
  • 【Android】硬件合成器 HWC
  • 4月27日日记
  • 基于spssau分析工具spss的简介
  • LeetCode 2444、1906、2682 题解(枚举右,维护左,前缀和)
  • 4.27算法题
  • AI-Browser适用于 ChatGPT、Gemini、Claude、DeepSeek、Grok的客户端开源应用程序,集成了 Monaco 编辑器。
  • adb push 报错:CreateProcess failure, error 123
  • 成功案例|探秘奶牛氧化应激,组学测序如何洞察微生物的 “一举一动”?
  • OpenFeign服务接口调用
  • 使用Three.js搭建自己的3Dweb模型(从0到1无废话版本)
  • [特殊字符] SQL注入攻击的常见写法及危害
  • Zookeeper断开连接时分布式锁释放问题的解决方案
  • 基于深度学习的智能交通流量监控与预测系统设计与实现
  • vue3 vite打包后动态修改打包后的请求路径,无需打多个包给后端
  • 从基础到实战的量化交易全流程学习:1.3 数学与统计学基础——概率与统计基础 | 数字特征
  • 常用第三方库:shared_preferences数据持久化
  • 基于大模型的急性化脓性阑尾炎全程诊疗预测与方案研究
  • 【音视频】视频解码实战
  • RAG(Retrieval-Augmented Generation,检索增强生成)
  • CSDN编辑文章时如何自动生成目录
  • 生成式人工智能认证(GAI认证)含金量怎么样?
  • 雪铁龙C5车机系统恢复
  • Java使用微信云服务HTTP API操作微信云开发数据库
  • Redis 缓存并发问题深度解析:击穿、雪崩与穿透防治指南
  • Java + Seleium4.X + TestNG自动化技术
  • 第三方软件检测报告:热门办公软件评估及功能表现如何?
  • Linux用户管理
  • 内存四区(堆)