NDIS IM – change packet content

Home Forums Discussions General Discussion NDIS IM – change packet content

This topic contains 6 replies, has 2 voices, and was last updated by  Alexey 9 years, 9 months ago.

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
    Moderator

    Вряд ли кто-то сможет что-либо по этому отписать, поскольку неясно даже где и с каким кодом падает. Хотя бы выход с !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
    Moderator

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

    #6534

    Alexey
    Participant

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

    #6535

    Vadim Smirnov
    Moderator

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

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

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

    #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.