Поделиться через


Идентификация вызывающего объекта из потока сервера

Можно определить, что сделало вызов RPC, даже если у вас есть единственная информация о потоке сервера, который обслуживал вызов.

Это может быть очень полезно, например, чтобы узнать, кто передал недопустимые параметры в вызов RPC.

В зависимости от того, какая последовательность протоколов используется этим конкретным вызовом, можно получить разную степень детализации. Некоторые протоколы (например, NetBios) не содержат этих сведений.

Идентификация вызывающего объекта из потока сервера

  1. Запустите отладчик пользовательского режима с потоком сервера в качестве целевого объекта.

  2. Получение идентификатора процесса с помощью | (Состояние процесса) Команды:

    0:001> |
      0     id: 3d4 name: rtsvr.exe
    
  3. Получите активные вызовы в этом процессе с помощью расширения !rpcexts.getcallinfo . (Описание синтаксиса см. на странице справочника.) Необходимо указать идентификатор процесса 0x3D4:

    0:001> !rpcexts.getcallinfo 0 0 FFFF 3d4
    Searching for call info ...
    PID  CELL ID   ST PNO IFSTART  THRDCELL  CALLFLAG CALLID   LASTTIME CONN/CLN
    ----------------------------------------------------------------------------
    03d4 0000.0004 02 000 19bb5061 0000.0002 00000001 00000001 00a1aced 0000.0003
    

    Найдите вызовы с состоянием 02 или 01 (отправленные или активные). В этом примере процесс имеет только один вызов. Если бы их было больше, необходимо было бы использовать расширение !rpcexts.getdbgcell с номером ячейки в столбце THRDCELL. Это позволит изучить идентификаторы потоков, чтобы определить, какой вызов вас интересует.

  4. Узнав, какой вызов вас интересует, просмотрите номер ячейки в столбце CONN/CLN. Это идентификатор ячейки объекта соединения. В этом случае номер ячейки — 0000,0003. Передайте этот номер ячейки и идентификатор процесса в !rpcexts.getdbgcell:

    0:001> !rpcexts.getdbgcell 3d4 0.3
    Getting cell info ...
    Connection
    Connection flags: Exclusive
    Authentication Level: Default
    Authentication Service: None
    Last Transmit Fragment Size: 24 (0x6F56D)
    Endpoint for the connection: 0x0.1
    Last send time (in seconds since boot):10595.565 (0x2963.235)
    Last receive time (in seconds since boot):10595.565 (0x2963.235)
    Getting endpoint info ...
    Process object for caller is 0xFF9DF5F0
    

Это расширение будет отображать все доступные сведения о клиенте этого подключения. Объем фактических сведений зависит от используемого транспорта.

В этом примере в качестве транспорта используются локальные именованные каналы, а также отображается адрес объекта процесса вызывающего объекта. При подключении отладчика ядра (или запуске локального отладчика ядра) можно использовать расширение !process для интерпретации этого адреса процесса.

Если в качестве транспорта используется LRPC, отображаются идентификатор процесса и идентификатор потока вызывающего объекта.

Если в качестве транспорта используется ПРОТОКОЛ TCP, отобразится IP-адрес вызывающей стороны.

Если в качестве транспорта используются удаленные именованные каналы, информация не будет доступна.

Примечание В предыдущем примере показано, как найти поток клиента, если вы знаете поток сервера. Пример обратного метода см. в разделе Анализ проблемы с зависавшим вызовом.