欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > KAPC的前世今生--(下)下RPCRT4!NMP_SyncSendRecv函数分析

KAPC的前世今生--(下)下RPCRT4!NMP_SyncSendRecv函数分析

2025/4/5 11:54:01 来源:https://blog.csdn.net/sitelist/article/details/146995878  浏览:    关键词:KAPC的前世今生--(下)下RPCRT4!NMP_SyncSendRecv函数分析

第一部分:nt!KiDeliverApc函数调用nt!IopCompleteRequest函数后准备返回
1: kd> kv
 # ChildEBP RetAddr  Args to Child              
00 ba3eec18 80a3c83b 896e4e40 ba3eec64 ba3eec58 nt!IopCompleteRequest+0x3a3 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\iomgr\internal.c @ 1568]
01 ba3eec68 80a44106 00000000 00000000 00000000 nt!KiDeliverApc+0xc5 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ke\apcsup.c @ 283]
02 ba3eecac 80a35ea9 00000000 00000000 00000001 nt!KiSwapThread+0x642 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\thredsup.c @ 2004]
03 ba3eece0 80d1f189 894e9800 00000006 ba3eed01 nt!KeWaitForSingleObject+0x2d7 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ke\wait.c @ 1161]
04 ba3eed44 80afbcb2 00000255 00000000 00000000 nt!NtWaitForSingleObject+0xcd (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ob\obwait.c @ 402]
05 ba3eed44 7ffe0304 00000255 00000000 00000000 nt!_KiSystemService+0x13f (FPO: [0,3] TrapFrame @ ba3eed64) (CONV: cdecl) [d:\srv03rtm\base\ntos\ke\i386\trap.asm @ 1328]
06 0006f5e4 77f2fbc8 77e64045 00000255 00000000 SharedUserData!SystemCallStub+0x4 (FPO: [0,0,0])
07 0006f5e8 77e64045 00000255 00000000 00000000 ntdll!NtWaitForSingleObject+0xc (FPO: [3,0,0]) [d:\srv03rtm\base\ntdll\daytona\obj\i386\usrstubs.asm @ 2371]
08 0006f658 77c6f002 00000255 ffffffff 00000000 kernel32!WaitForSingleObjectEx+0xac (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\win32\client\synch.c @ 1237]
09 0006f678 77c6f1bb 006c1a00 00000000 ffffffff RPCRT4!UTIL_WaitForSyncIO+0x1f (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\runtime\trans\common\util.cxx @ 233]
0a 0006f69c 77c727d8 006c19cc 006c1a00 0006f6c4 RPCRT4!UTIL_GetOverlappedResultEx+0xbf (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\runtime\trans\common\util.cxx @ 370]
0b 0006f6c8 77bf4f4b 000003e5 00000050 006c12b8 RPCRT4!NMP_SyncSendRecv+0xd5 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\runtime\trans\common\nptrans.cxx @ 1995]
0c 0006f6f4 77bf53ce 006dadd0 00000000 00000050 RPCRT4!OSF_CCONNECTION::TransSendReceive+0xb9 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 3365]
0d 0006f77c 77bf5c76 006c12b8 006c1a90 00000001 RPCRT4!OSF_CCONNECTION::SendFragment+0x32c (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 6012]
0e 0006f7d4 77bfc0ca 00000000 ffffffff 0006f818 RPCRT4!OSF_CCALL::SendNextFragment+0x29b (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 9631]
0f 0006f81c 77bfc397 0006f8b8 0006f860 000006bf RPCRT4!OSF_CCALL::FastSendReceive+0x162 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 8222]
10 0006f83c 77bfcbac 0006f8b8 0006f860 77e47889 RPCRT4!OSF_CCALL::SendReceiveHelper+0xe1 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 8539]
11 0006f868 77bf1ca2 006c12d0 0006f8e4 0006f8b8 RPCRT4!OSF_CCALL::SendReceive+0x4c (FPO: [Non-Fpo]) (CONV: thiscall) [d:\srv03rtm\com\rpc\runtime\mtrt\osfclnt.cxx @ 8603]
12 0006f884 77c3f764 0006f8b8 77d80220 0006fc8c RPCRT4!I_RpcSendReceive+0xba (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\runtime\mtrt\msgapi.cxx @ 79]
13 0006f89c 77c7ed10 0006f8e4 006c1308 000b5378 RPCRT4!NdrSendReceive+0x47 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\com\rpc\ndr20\auxilary.cxx @ 1269]
14 0006fc6c 77dc194a 77d80220 77d7f61c 0006fc8c RPCRT4!NdrClientCall2+0x1f7 (FPO: [Non-Fpo]) (CONV: cdecl) [d:\srv03rtm\com\rpc\ndr20\cltcall.cxx @ 1033]
15 0006fc84 77dbec35 006dab50 0006fd8c 00008000 ADVAPI32!ROpenServiceW+0x17 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\client\svcctl_c.c @ 399]
16 0006fccc 77dc10f1 006dab50 0006fd8c 00008000 ADVAPI32!OpenServiceW+0x26 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\client\scwrap.cxx @ 723]
17 0006fd4c 77dc16c1 00000298 0006fd78 00000216 ADVAPI32!ScDispatcherLoop+0x17e (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\client\scapi.cxx @ 910]
18 0006ffac 01003221 00084d00 00000000 00000000 ADVAPI32!StartServiceCtrlDispatcherW+0x121 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\client\scapi.cxx @ 705]
19 0006ffc0 77e62c34 00000000 00000000 7ffdf000 svchost!wmainCRTStartup+0xa2 (FPO: [0,0,3]) (CONV: stdcall) [d:\srv03rtm\base\screg\sc\svchost\svchost.c @ 1369]
1a 0006fff0 00000000 0100317f 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\win32\client\support.c @ 580]

RPC_STATUS
RPC_ENTRY
NMP_SyncSendRecv(
    IN RPC_TRANSPORT_CONNECTION ThisConnection,
    IN UINT InputBufferSize,
    IN BUFFER InputBuffer,
    OUT PUINT pOutputBufferSize,
    OUT BUFFER *pOutputBuffer
    )
{

   b = TransactNamedPipe(p->Conn.Handle,
                          InputBuffer,
                          InputBufferSize,
                          p->pReadBuffer,
                          bytes,
                          &bytes,
                          &p->Read.ol
                          );


    if (!b)
        {
        status = GetLastError();
        if (status == ERROR_IO_PENDING)
            {
            status = UTIL_GetOverlappedResult(p,
                                              &p->Read.ol,
                                              &bytes);
            }
        else
            {
            ASSERT(status != RPC_S_OK);
            }
        }
    else
        {
        status = RPC_S_OK;
        }

    if (status == RPC_S_OK)
        {
        // Success - got the whole reply in the transact

        *pOutputBuffer = p->pReadBuffer;
        p->pReadBuffer = 0;
        *pOutputBufferSize = bytes;

        ASSERT(bytes == MessageLength((PCONN_RPC_HEADER)*pOutputBuffer));

        return(RPC_S_OK);
        }


第二部分:设置事件

1: kd> dv
         Object = 0x894e9800
     WaitReason = UserRequest (0n6)
       WaitMode = 0n1 ''
      Alertable = 0x00 ''
        Timeout = 0x00000000
        DueTime = {-5026319169582360600}
    CurrentPrcb = 0xf7737120
   OriginalTime = 0x00000000
 StackSwappable = 1
        NewTime = {-2207181079913080607}
1: kd> dt KMUTANT 0x894e9800
GDI32!KMUTANT
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 MutantListEntry  : _LIST_ENTRY [ 0xa060006 - 0x20646156 ]
   +0x018 OwnerThread      : 0x89784b8b _KTHREAD
   +0x01c Abandoned        : 0x90 ''
   +0x01d ApcDisable       : 0xe2 ''
1: kd> dx -id 0,0,89838358 -r1 (*((GDI32!_DISPATCHER_HEADER *)0x894e9800))
(*((GDI32!_DISPATCHER_HEADER *)0x894e9800))                 [Type: _DISPATCHER_HEADER]
    [+0x000] Type             : 0x0 [Type: unsigned char]
    [+0x001] Absolute         : 0x0 [Type: unsigned char]
    [+0x002] Size             : 0x4 [Type: unsigned char]
    [+0x003] Inserted         : 0x0 [Type: unsigned char]
    [+0x003] DebugActive      : 0x0 [Type: unsigned char]
    [+0x000] Lock             : 262144 [Type: long]
    [+0x004] SignalState      : 1 [Type: long]
    [+0x008] WaitListHead     [Type: _LIST_ENTRY]
1: kd> dx -id 0,0,89838358 -r1 (*((GDI32!_LIST_ENTRY *)0x894e9808))
(*((GDI32!_LIST_ENTRY *)0x894e9808))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x894e9808 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x894e9808 [Type: _LIST_ENTRY *]


typedef enum _KOBJECTS {
    EventNotificationObject = 0,
    EventSynchronizationObject = 1,
    MutantObject = 2,


第三部分:返回到nt!KeWaitForSingleObject函数后


NTSTATUS
KeWaitForSingleObject (
    IN PVOID Object,
    IN KWAIT_REASON WaitReason,
    IN KPROCESSOR_MODE WaitMode,
    IN BOOLEAN Alertable,
    IN PLARGE_INTEGER Timeout OPTIONAL
    )

{
            //
            // If the signal state is greater than zero, then satisfy the wait.
            //

            } else if (Objectx->Header.SignalState > 0) {
                KiWaitSatisfyOther(Objectx);
                WaitStatus = (NTSTATUS)(0);
                goto NoWait;        //等待事件对象有信号了
            }


#define KiWaitSatisfyOther(_Object_) {                                       \
    if (((_Object_)->Header.Type & DISPATCHER_OBJECT_TYPE_MASK) == EventSynchronizationObject) { \
        (_Object_)->Header.SignalState = 0;                                  \
                                                                             \
    } else if ((_Object_)->Header.Type == SemaphoreObject) {                 \
        (_Object_)->Header.SignalState -= 1;                                 \
                                                                             \
    }                                                                        \
}


            InsertTailList(&Objectx->Header.WaitListHead, &WaitBlock->WaitListEntry);


            KiSetContextSwapBusy(Thread);
            KiUnlockDispatcherDatabaseFromSynchLevel();
            WaitStatus = (NTSTATUS)KiSwapThread(Thread, CurrentPrcb);


第四部分:客户端调用nt!KiUnwaitThread函数里面会调用KiUnlinkThread函数脱链


1: kd> kv 4
 # ChildEBP RetAddr  Args to Child              
00 f794abbc 80a3cc41 00000001 896e4e40 896e4e40 nt!KiUnwaitThread+0x7 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\waitsup.c @ 158]
01 f794abe0 80a3758e 896e4e00 00000000 00000000 nt!KiInsertQueueApc+0x1a9 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\apcsup.c @ 602]
02 f794abfc 80a26c44 896e4e40 895a7ca8 00000000 nt!KeInsertQueueApc+0x80 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ke\apcobj.c @ 302]
03 f794ac30 baaf531e 895a5038 8979ef68 00000000 nt!IopfCompleteRequest+0x244 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\io\iomgr\iosubs.c @ 3688]

1: kd> dt kTHREAD 89510898
ntdll!KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 MutantListHead   : _LIST_ENTRY [ 0x895108a8 - 0x895108a8 ]
   +0x018 InitialStack     : 0xba3ef000 Void
   +0x01c StackLimit       : 0xba3eb000 Void
   +0x020 KernelStack      : 0xba3eec5c Void
   +0x024 ThreadLock       : 0
   +0x028 ContextSwitches  : 0xa1
   +0x02c State            : 0x2 ''

   +0x054 WaitBlockList    : 0x89510938 _KWAIT_BLOCK

1: kd> dx -id 0,0,89838358 -r1 ((ntdll!_KWAIT_BLOCK *)0x89510938)
((ntdll!_KWAIT_BLOCK *)0x89510938)                 : 0x89510938 [Type: _KWAIT_BLOCK *]
    [+0x000] WaitListEntry    [Type: _LIST_ENTRY]
    [+0x008] Thread           : 0x89510898 [Type: _KTHREAD *]
    [+0x00c] Object           : 0x894e9800 [Type: void *]
    [+0x010] NextWaitBlock    : 0x89510938 [Type: _KWAIT_BLOCK *]        NextWaitBlock    : 0x89510938
    [+0x014] WaitKey          : 0x0 [Type: unsigned short]
    [+0x016] WaitType         : 0x1 [Type: unsigned short]

VOID
FASTCALL
KiUnwaitThread (
    IN PRKTHREAD Thread,
    IN LONG_PTR WaitStatus,
    IN KPRIORITY Increment
    )
{

    //
    // Unlink thread from the appropriate wait queues and set the wait
    // completion status.
    //

    KiUnlinkThread(Thread, WaitStatus);

    //
    // Set unwait priority adjustment parameters.
    //

    ASSERT(Increment >= 0);

    Thread->AdjustIncrement = (SCHAR)Increment;
    Thread->AdjustReason = (UCHAR)AdjustUnwait;

    //
    // Ready the thread for execution.
    //

    KiReadyThread(Thread);
    return;
}


FORCEINLINE
VOID
FASTCALL
KiUnlinkThread (
    IN PRKTHREAD Thread,
    IN LONG_PTR WaitStatus
    )
{

    PKQUEUE Queue;
    PKTIMER Timer;
    PRKWAIT_BLOCK WaitBlock;

    //
    // Set wait completion status, remove wait blocks from object wait
    // lists, and remove thread from wait list.
    //

    Thread->WaitStatus |= WaitStatus;
    WaitBlock = Thread->WaitBlockList;
    do {
        RemoveEntryList(&WaitBlock->WaitListEntry);


第五部分:什么时候设置事件为有信号状态?

1: kd> dt _irp 0x896e4e40-40
GDI32!_IRP
   +0x000 Type             : 0n6
   +0x002 Size             : 0x94
   +0x004 MdlAddress       : (null)
   +0x008 Flags            : 0x870
   +0x00c AssociatedIrp    : __unnamed
   +0x010 ThreadListEntry  : _LIST_ENTRY [ 0x89510ab0 - 0x89510ab0 ]
   +0x018 IoStatus         : _IO_STATUS_BLOCK
   +0x020 RequestorMode    : 1 ''
   +0x021 PendingReturned  : 0x1 ''
   +0x022 StackCount       : 1 ''
   +0x023 CurrentLocation  : 3 ''
   +0x024 Cancel           : 0 ''
   +0x025 CancelIrql       : 0 ''
   +0x026 ApcEnvironment   : 0 ''
   +0x027 AllocationFlags  : 0xc ''
   +0x028 UserIosb         : 0x006c1a00 _IO_STATUS_BLOCK
   +0x02c UserEvent        : 0x894e9800 _KEVENT            UserEvent        : 0x894e9800

VOID
IopCompleteRequest(
    IN PKAPC Apc,
    IN PKNORMAL_ROUTINE *NormalRoutine,
    IN PVOID *NormalContext,
    IN PVOID *SystemArgument1,
    IN PVOID *SystemArgument2
    )
{

        if (irp->UserEvent) {
            (VOID) KeSetEvent( irp->UserEvent, 0, FALSE );


00 nt!IopCompleteRequest
01 nt!KiDeliverApc
02 nt!KiSwapThread
03 nt!KeWaitForSingleObject
04 nt!NtWaitForSingleObject
05 nt!_KiSystemService
06 SharedUserData!SystemCallStub
07 ntdll!NtWaitForSingleObject
08 kernel32!WaitForSingleObjectEx
09 RPCRT4!UTIL_WaitForSyncIO
0a RPCRT4!UTIL_GetOverlappedResultEx
0b RPCRT4!NMP_SyncSendRecv


1: kd> dt kTHREAD 89510898
ntdll!KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 MutantListHead   : _LIST_ENTRY [ 0x895108a8 - 0x895108a8 ]
   +0x018 InitialStack     : 0xba3ef000 Void
   +0x01c StackLimit       : 0xba3eb000 Void
   +0x020 KernelStack      : 0xba3eec5c Void
   +0x024 ThreadLock       : 0
   +0x028 ContextSwitches  : 0xa1
   +0x02c State            : 0x2 ''

   +0x054 WaitBlockList    : 0x89510938 _KWAIT_BLOCK
 
1: kd> dx -id 0,0,89838358 -r1 ((ntdll!_KWAIT_BLOCK *)0x89510938)
((ntdll!_KWAIT_BLOCK *)0x89510938)                 : 0x89510938 [Type: _KWAIT_BLOCK *]
    [+0x000] WaitListEntry    [Type: _LIST_ENTRY]
    [+0x008] Thread           : 0x89510898 [Type: _KTHREAD *]
    [+0x00c] Object           : 0x894e9800 [Type: void *]            //Object           : 0x894e9800
    [+0x010] NextWaitBlock    : 0x89510938 [Type: _KWAIT_BLOCK *]
    [+0x014] WaitKey          : 0x0 [Type: unsigned short]
    [+0x016] WaitType         : 0x1 [Type: unsigned short]

第六部分:
    if (status == RPC_S_OK)
        {
        // Success - got the whole reply in the transact

        *pOutputBuffer = p->pReadBuffer;
        p->pReadBuffer = 0;
        *pOutputBufferSize = bytes;

        ASSERT(bytes == MessageLength((PCONN_RPC_HEADER)*pOutputBuffer));

        return(RPC_S_OK);
        }

1: kd> dt NMP_CONNECTION 006c19cc
RPCRT4!NMP_CONNECTION
   +0x000 __VFN_table : 0x77bed498
   +0x004 type             : 0
   +0x008 id               : 0n3
   +0x00c fAborted         : 0n0
   +0x010 ObjectList       : _LIST_ENTRY [ 0xbaadf00d - 0xbaadf00d ]
   +0x018 Conn             : BASE_CONNECTION::__unnamed
   +0x01c StartingWriteIo  : 0n0
   +0x020 StartingReadIo   : 0n0
   +0x024 iPostSize        : 0x400
   +0x028 maxReadBuffer    : 0x400
   +0x02c iLastRead        : 0
   +0x030 Read             : BASE_OVERLAPPED
   +0x04c pReadBuffer      : 0x006c1408  "???"
   +0x050 pAddress         : (null)
1: kd> dd 0x006c1408
006c1408  03020005 00000010 00000030 0000005d
006c1418  00000018 00000000 00000000 e160751f
006c1428  45e3ef7f 690413a0 b8ade145 00000000
006c1438  8a885d04 11c91ceb 0008e89f 6048102b
006c1448  00000002 0054004e 00410020 00540055
006c1458  004f0048 00490052 00590054 00000000
006c1468  00000001 05000000 00000001 000b4ee8
006c1478  00000001 00000001 000e000c 000b4efc

1: kd> dt rpcconn_common 0x006c1408
RPCRT4!rpcconn_common
   +0x000 rpc_vers         : 0x5 ''
   +0x001 rpc_vers_minor   : 0 ''
   +0x002 PTYPE            : 0x2 ''
   +0x003 pfc_flags        : 0x3 ''
   +0x004 drep             : [4]  "???"
   +0x008 frag_length      : 0x30
   +0x00a auth_length      : 0
   +0x00c call_id          : 0x5d

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词