NDIS IM – change packet content

Home Forums Discussions General NDIS IM – change packet content

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #5168
    Alexey
    Participant

      необходимо послать в сеть измененный пакет.
      что делается сейчас:
      MiniportSend:
      1) NdisAllocatePacket и прочие действия из passthru (NdisSetPacketFlags, NdisIMCopySendPerPacketInfo, …)
      2) данные из tcpip.sys копируются в свою память (проходимся по всем буферам в пакете), пересчитывается crc и прочая бытовуха
      3) NdisAllocateBuffer – скармливаем ему память, куда скопированы измененные данные
      4) вызываем NdisUnchainBufferAtBack в цикле над собственным пакетом
      5) добавляем свой буфер (он всего один) NdisChainBufferAtFront
      6) NdisSend

      ProtocolSendComplete:
      7) NdisIMCopySendCompletePerPacketInfo
      8) NdisFreeBuffer – освобождаем наш буфер, выделенный в п.3
      9) NdisDprFreePacket(MyPacket)
      10) NdisMSendComplete

      и вот здесь мы падаем, но не на всех системах. где я неправ?
      у меня подозрение на NdisIMCopySendCompletePerPacketInfo – вероятно надо как-то по-другому копировать данные.
      заранее спасибо.

      #6531
      Vadim Smirnov
      Keymaster

        Вряд ли кто-то сможет что-либо по этому отписать, поскольку неясно даже где и с каким кодом падает. Хотя бы выход с !analyze-v запостил…

        #6532
        Alexey
        Participant

          pdb потерялся оригинальный, но место падения выделено ниже
          windbg:

          DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)<br />
          An attempt was made to access a pageable (or completely invalid) address at an<br />
          interrupt request level (IRQL) that is too high.  This is usually<br />
          caused by drivers using improper addresses.<br />
          If kernel debugger is available get stack backtrace.<br />
          Arguments:<br />
          Arg1: 00000000, memory referenced<br />
          Arg2: 00000002, IRQL<br />
          Arg3: 00000000, value 0 = read operation, 1 = write operation<br />
          Arg4: ee649577, address which referenced memory<br />
          <br />
          Debugging Details:
          <hr class="bbcode_rule" />
          <br />
          <br />
          READ_ADDRESS:  00000000<br />
          <br />
          CURRENT_IRQL:  2<br />
          <br />
          FAULTING_IP:<br />
          tcpip!FreeIPPacket+127<br />
          ee649577 8b3f            mov     edi,dword ptr [edi]<br />
          <br />
          DEFAULT_BUCKET_ID:  DRIVER_FAULT<br />
          <br />
          BUGCHECK_STR:  0xD1<br />
          <br />
          PROCESS_NAME:  test_app<br />
          <br />
          TRAP_FRAME:  f78ffd9c -- (.trap fffffffff78ffd9c)<br />
          ErrCode = 00000000<br />
          eax=00000000 ebx=00000000 ecx=00000000 edx=028a0002 esi=83418b38 edi=00000000<br />
          eip=ee649577 esp=f78ffe10 ebp=f78ffe20 iopl=0         nv up ei pl zr na pe nc<br />
          cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246<br />
          tcpip!FreeIPPacket+0x127:<br />
          ee649577 8b3f            mov     edi,dword ptr [edi]  ds:0023:00000000=????????<br />
          Resetting default scope<br />
          <br />
          LAST_CONTROL_TRANSFER:  from ee649577 to 80543930<br />
          <br />
          STACK_TEXT:<br />
          f78ffd9c ee649577 badb0d00 028a0002 8489d860 nt!KiTrap0E+0x238<br />
          f78ffe20 ee649680 00418b38 00000001 00000000 tcpip!FreeIPPacket+0x127<br />
          f78ffe58 ee64981d 83ad9890 00418b38 00000000 tcpip!IPSendComplete+0x79<br />
          f78ffe7c f71e8c1c 00000001 833fa06c 00000000 tcpip!ARPSendComplete+0xf6<br />
          f78ffea0 f6e37b69 83d68850 83418b38 00000000 NDIS!ndisMSendCompleteX+0x8d<br />
          f78ffec0 f71e8c1c 84903640 01418b38 00000000 psched!ClSendComplete+0x67<br />
          f78ffee4 f6e96c30 83d5f950 83418b38 00000000 NDIS!ndisMSendCompleteX+0x8d<br />
          WARNING: Stack unwind information not available. Following frames may be wrong.<br />
          f78fff18 f71e8c1c 83b785f8 8341cc58 00000000 ugnat+0xfc30<br />
          f78fff3c f759392b 848a0aa8 8341cc58 00000000 NDIS!ndisMSendCompleteX+0x8d<br />
          f78fff88 f7593a9e f78fffcc 00000000 848a0aa8 dlkfet5b+0x392b<br />
          f78fffb4 f71ebf09 83476000 7c90109a f77609c0 dlkfet5b+0x3a9e<br />
          f78fffcc 805450bf 834760b0 8347609c 00000000 NDIS!ndisMDpcX+0x21<br />
          f78ffff4 80544c2b eb175d44 00000000 00000000 nt!KiRetireDpcList+0x61<br />
          f78ffff8 eb175d44 00000000 00000000 00000000 nt!KiDispatchInterrupt+0x2b<br />
          80544c2b 00000000 00000009 0081850f bb830000 0xeb175d44<br />
          <br />
          <br />
          STACK_COMMAND:  kb<br />
          <br />
          FOLLOWUP_IP:<br />
          ugnat+fc30<br />
          f6e96c30 8b45fc          mov     eax,dword ptr [ebp-4]<br />
          <br />
          SYMBOL_STACK_INDEX:  7<br />
          <br />
          FOLLOWUP_NAME:  MachineOwner<br />
          <br />
          MODULE_NAME: ugnat<br />
          <br />
          IMAGE_NAME:  ugnat.sys<br />
          <br />
          DEBUG_FLR_IMAGE_TIMESTAMP:  47a6d247<br />
          <br />
          SYMBOL_NAME:  ugnat+fc30<br />
          <br />
          FAILURE_BUCKET_ID:  0xD1_ugnat+fc30<br />
          <br />
          BUCKET_ID:  0xD1_ugnat+fc30<br />
          <br />
          Followup: MachineOwner

          ф-ция, отключение которой устраняет ошибку:

          void ModifyPacketDataBuffers(struct LSNDISFL_PACKET *pLsNdisPacket)<br />
          {<br />
          PNDIS_PACKET MyPacket = pLsNdisPacket->packetData.pSrcPacket;<br />
          PNDIS_BUFFER pCurBuffer = NULL;<br />
          NDIS_STATUS Status;<br />
          <br />
          // allocate our buffer<br />
          NdisAllocateBuffer(&Status, (PNDIS_BUFFER*)&pLsNdisPacket->packetData.pNdisBuffer,<br />
          g_bufferPool, &pLsNdisPacket->header[0], pLsNdisPacket->packSize);<br />
          if(!pLsNdisPacket->packetData.pNdisBuffer)<br />
          {<br />
          DEBUG_COMMON("ModifyPacketDataBuffers - NdisAllocateBuffer failed, 0x%Xn", Status);<br />
          return;<br />
          }<br />
          <br />
          // unchain all buffers<br />
          do<br />
          {<br />
          NdisUnchainBufferAtBack(MyPacket, &pCurBuffer);<br />
          }<br />
          while(pCurBuffer);<br />
          <br />
          // chain our buffer<br />
          NdisChainBufferAtFront(MyPacket, pLsNdisPacket->packetData.pNdisBuffer);<br />
          }

          ProtocolSendComplete:

          VOID<br />
          PtSendComplete(<br />
          IN	NDIS_HANDLE			ProtocolBindingContext,<br />
          IN  PNDIS_PACKET		Packet,<br />
          IN  NDIS_STATUS			Status<br />
          )<br />
          {<br />
          PADAPT			pAdapt =(PADAPT)ProtocolBindingContext;<br />
          PNDIS_PACKET	OriginalPacket = NULL;<br />
          PNDIS_BUFFER	pDataBuffer = NULL;<br />
          UCHAR*			pData = NULL;<br />
          PNDIS_BUFFER	pHdrBuffer = NULL;<br />
          UCHAR*			pHdr = NULL;<br />
          UINT			currLen = 0;<br />
          <br />
          struct LSNDISFL_PACKET* pLsNdisPacket = NULL;<br />
          <br />
          if ( Packet->Private.Pool != g_packetPool)<br />
          {<br />
          // packet from MPSend<br />
          pAdapt = pAdapt->pPrimaryAdapt;<br />
          pLsNdisPacket = (struct LSNDISFL_PACKET*)((PRSVD)Packet->ProtocolReserved)->pLsNdisPacket;<br />
          OriginalPacket = pLsNdisPacket->packetData.pOriginalPacket;<br />
          <br />
          NdisIMCopySendCompletePerPacketInfo (OriginalPacket, Packet);<br />
          if(pLsNdisPacket->packetData.pNdisBuffer)<br />
          {<br />
          // free allocated buffer<br />
          NdisFreeBuffer(pLsNdisPacket->packetData.pNdisBuffer);<br />
          pLsNdisPacket->packetData.pNdisBuffer = NULL;<br />
          }<br />
          NdisDprFreePacket(Packet);<br />
          <br />
          -->>> crash here	NdisMSendComplete(pAdapt->MiniportHandle,<br />
          OriginalPacket, Status);<br />
          FreeLsPacket(pLsNdisPacket);<br />
          }<br />
          else<br />
          {<br />
          // [skipped]<br />
          }<br />
          }
          #6533
          Vadim Smirnov
          Keymaster

            Судя пр крашу пакет переданный в NdisMSendComplete уже не валиден. Какой статус был возвращен из MiniportSend? Используется ли MiniportSendPackets?

            #6534
            Alexey
            Participant

              NdisSend returns NDIS_STATUS_PENDING, MiniportSend соответственно такой же. MiniportSendPackets не реализован.
              может ли происходить такое из-за того, что реальный отправляемый пакет отличается по длине от исходного?
              подсчет tcp checksum на всех адаптерах отключен.

              #6535
              Vadim Smirnov
              Keymaster

                может ли происходить такое из-за того, что реальный отправляемый пакет отличается по длине от исходного?

                Нет, скорее уж потому что ты каким-то образом поломал оригинальный пакет… Падает то система на освобождении оригинального пакета…

                Где-то что-то сделано неверно, но вот что и где…

                #6536
                Alexey
                Participant

                  все, разобрался.
                  нельзя вызывать NdisUnchainXXX, если одни и те же буферы аттачатся к двум разным пакетам – в буфере меняется по крайней мере указатель Next, и для второго пакета цепочка буферов может быть нарушена.
                  ручками занулил Private.Head & Private.Tail, потом приаттачил свой буфер, все заработало.
                  всем спасибо.

                Viewing 7 posts - 1 through 7 (of 7 total)
                • You must be logged in to reply to this topic.