Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Deep Clone injection (Outbound network) doesn't work

Haitham_ElkhiderHaitham_Elkhider Member Posts: 16
Im hooking FWPM_LAYER_OUTBOUND_IPPACKET_V4, and the filter is empty there, so I should capture every single packet going outside. The problem Deep Cloning and injection WITHOUT Modification doesn't work for me, I get invoked in the completion function and things seems ok, also I have registered a callout at FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD Layer, just to see if my injected packets are getting discarded for any reason, but nothing shows up in there .

(Am I looking at the correct discard layer ? )

What I get is any browsing or any network activity stops, like the packets are not even making it through .

void
TLInspectOutboundNetworkClassify(
_In_ const FWPS_INCOMING_VALUES* inFixedValues,
_In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
_Inout_opt_ void* layerData,
_In_ const FWPS_FILTER* filter,
_In_ UINT64 flowContext,
_Inout_ FWPS_CLASSIFY_OUT* classifyOut
)
{
FWPS_PACKET_INJECTION_STATE packetState;

packetState = FwpsQueryPacketInjectionState(
gNetworkInjectionHandle,
layerData,
NULL
);

if ((packetState == FWPS_PACKET_INJECTED_BY_SELF) ||
(packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF))
{
classifyOut->actionType = FWP_ACTION_PERMIT;
if (filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)
{
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
}
return;
}

classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;

//classifyOut->actionType = FWP_ACTION_PERMIT;

PNET_BUFFER_LIST pClonedNBL = NULL, pOrgNBL = layerData;

NTSTATUS status = STATUS_SUCCESS;

status = FwpsAllocateCloneNetBufferList(
pOrgNBL,
NULL,
NULL,
0,
&pClonedNBL
);

if (!NT_SUCCESS(status))
{
if (pClonedNBL != NULL)
{
FwpsFreeCloneNetBufferList(pClonedNBL, 0);
}
return;
}

PNET_BUFFER_LIST pNewNbl = NULL;
PNET_BUFFER pNetBuffer = NULL;

const UINT32 BUFFER_SIZE = 2048;
for (pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pClonedNBL);
pNetBuffer != NULL;
pNetBuffer = NET_BUFFER_NEXT_NB(pNetBuffer))
{
BYTE* pBuffer = 0;

HLPR_NEW_ARRAY(pBuffer,BYTE,BUFFER_SIZE,'TAG5');

if (pBuffer == 0) continue;

PVOID pContiguousData = 0;
PVOID pBuffer_IPHEADER = NULL;
PVOID pBuffer_TRANSPORTHEADER = NULL;

pBuffer_IPHEADER = ExAllocatePoolWithTag(NonPagedPool, 400, 'TAG1');
pBuffer_TRANSPORTHEADER = ExAllocatePoolWithTag(NonPagedPool, 400, 'TAG2');

PVOID pBuffer_PAYLOAD = ExAllocatePoolWithTag(NonPagedPool, 1500, 'TAG3');
UINT32 ip = 0, transport = 0;

///////////////////////////////////////////
//////////// IP HEADER ////////////////////
if (pNetBuffer != NULL)
{
pContiguousData = NdisGetDataBuffer(pNetBuffer,
inMetaValues->ipHeaderSize,
pBuffer,
1,
0);

if (pContiguousData == NULL)
{
status = STATUS_NO_MEMORY;
return;
}

if (pContiguousData != NULL)
RtlCopyMemory(pBuffer_IPHEADER, pContiguousData, inMetaValues->ipHeaderSize);

NdisAdvanceNetBufferDataStart(pNetBuffer, inMetaValues->ipHeaderSize, 0, NULL);
ip = inMetaValues->ipHeaderSize;
pContiguousData = NULL;

}
///////////////////////////////////////////
//////////// TRANSPORT HEADER /////////////
if (pNetBuffer != NULL)
{
pContiguousData = NdisGetDataBuffer(pNetBuffer,
inMetaValues->transportHeaderSize,
pBuffer,
1,
0);

if (pContiguousData != NULL)
RtlCopyMemory(pBuffer_TRANSPORTHEADER, pContiguousData, inMetaValues->transportHeaderSize);

NdisAdvanceNetBufferDataStart(pNetBuffer, inMetaValues->transportHeaderSize, FALSE, NULL);

transport = inMetaValues->transportHeaderSize;
pContiguousData = NULL;
}
///////////////////////////////////////////
//////////// PAYLOAD// ////////////////////
if (pNetBuffer != NULL)
{
pContiguousData = NdisGetDataBuffer(pNetBuffer,
NET_BUFFER_DATA_LENGTH(pNetBuffer),
pBuffer,
1,
0);

if (pContiguousData != NULL)
RtlCopyMemory(pBuffer_PAYLOAD, pContiguousData, NET_BUFFER_DATA_LENGTH(pNetBuffer));

pContiguousData = NULL;
}
PMDL p1 = NULL, p2 = NULL, p3 = NULL;
p1 = IoAllocateMdl(pBuffer_IPHEADER, inMetaValues->ipHeaderSize, FALSE, FALSE, NULL);
if(p1 != NULL) MmBuildMdlForNonPagedPool(p1);

inMetaValues->ipHeaderSize;
p2 = IoAllocateMdl(pBuffer_TRANSPORTHEADER, inMetaValues->transportHeaderSize, FALSE, FALSE, NULL);
if (p2 != NULL) MmBuildMdlForNonPagedPool(p1);

inMetaValues->transportHeaderSize;
p3 = IoAllocateMdl(pBuffer_PAYLOAD, NET_BUFFER_DATA_LENGTH(pNetBuffer), FALSE, FALSE, NULL);
if (p3 != NULL) MmBuildMdlForNonPagedPool(p1);


p1->Next = p2;
p2->Next = p3;

if ( p1 == NULL || p2 == NULL || p3 == NULL)
{
status = STATUS_NO_MEMORY;
return;
}

status = FwpsAllocateNetBufferAndNetBufferList(g_pNDISPoolData->nblPoolHandle, 0, 0, p1, 0,
NET_BUFFER_DATA_LENGTH(pNetBuffer) + inMetaValues->transportHeaderSize + inMetaValues->ipHeaderSize, &pNewNbl);
if (!NT_SUCCESS(status))
return;

if (p1 != NULL) IoFreeMdl(p1);
if (p2 != NULL) IoFreeMdl(p2);
if (p3 != NULL) IoFreeMdl(p3);

HLPR_DELETE_ARRAY(pBuffer, 'TAG5');
ExFreePoolWithTag(pBuffer_IPHEADER, 'TAG1');
ExFreePoolWithTag(pBuffer_TRANSPORTHEADER, 'TAG2');
ExFreePoolWithTag(pBuffer_PAYLOAD, 'TAG3');

if (pNetBuffer != NULL)
NdisRetreatNetBufferDataStart(pNetBuffer, transport + ip, FALSE, NULL);

}

status = FwpsInjectNetworkSendAsync0(
gNetworkInjectionHandle,
NULL,
0,
UNSPECIFIED_COMPARTMENT_ID,//inMetaValues->compartmentId, //
pNewNbl,
TLInspectNetworkInjectComplete,
NULL
);

if (pClonedNBL != NULL)
{
FwpsFreeCloneNetBufferList(pClonedNBL, 0);
}

return;
}
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA