?? hooked_fn.c
字號(hào):
NdisAllocateBuffer(&status, &hdr_buffer, g_buffer_pool, HeaderBuffer, HeaderBufferSize);
if (status != NDIS_STATUS_SUCCESS) {
KdPrint(("[ndis_hk] new_ReceiveHandler: NdisAllocateBuffer: 0x%x!\n", status));
status = NDIS_STATUS_NOT_ACCEPTED;
__leave;
}
NdisAllocateBuffer(&status, &data_buffer, g_buffer_pool, LookaheadBuffer, LookaheadBufferSize);
if (status != NDIS_STATUS_SUCCESS) {
KdPrint(("[ndis_hk] new_ReceiveHandler: NdisAllocateBuffer: 0x%x!\n", status));
status = NDIS_STATUS_NOT_ACCEPTED;
__leave;
}
NdisAllocatePacket(&status, &packet, g_packet_pool);
if (status != NDIS_STATUS_SUCCESS) {
KdPrint(("[ndis_hk] new_ReceiveHandler: NdisAllocatePacket: 0x%x!\n", status));
status = NDIS_STATUS_NOT_ACCEPTED;
__leave;
}
NdisChainBufferAtFront(packet, data_buffer);
NdisChainBufferAtFront(packet, hdr_buffer);
// filter it!
result = filter_packet(DIRECTION_IN, adapter->adapter_index, packet);
} else {
// get the whole frame! (use NdisTransferData)
// NOTE: NdisTransferData CAN return NDIS_STATUS_PENDING but pointers are only valid
// in context of current call. That's because we're allocating memory (slow way).
buf = malloc_np(HeaderBufferSize + PacketSize);
if (buf == NULL) {
KdPrint(("[ndis_hk] new_ReceiveHandler: malloc_np!\n"));
status = NDIS_STATUS_NOT_ACCEPTED;
__leave;
}
// copy header
memcpy(buf, HeaderBuffer, HeaderBufferSize);
// make buffer
NdisAllocateBuffer(&status, &hdr_buffer, g_buffer_pool, buf, HeaderBufferSize);
if (status != NDIS_STATUS_SUCCESS) {
KdPrint(("[ndis_hk] new_ReceiveHandler: NdisAllocateBuffer: 0x%x!\n", status));
status = NDIS_STATUS_NOT_ACCEPTED;
__leave;
}
NdisAllocateBuffer(&status, &data_buffer, g_buffer_pool, (char *)buf + HeaderBufferSize, PacketSize);
if (status != NDIS_STATUS_SUCCESS) {
KdPrint(("[ndis_hk] new_ReceiveHandler: NdisAllocateBuffer: 0x%x!\n", status));
status = NDIS_STATUS_NOT_ACCEPTED;
__leave;
}
NdisAllocatePacket(&status, &packet, g_packet_pool);
if (status != NDIS_STATUS_SUCCESS) {
KdPrint(("[ndis_hk] new_ReceiveHandler: NdisAllocatePacket: 0x%x!\n", status));
status = NDIS_STATUS_NOT_ACCEPTED;
__leave;
}
NdisChainBufferAtFront(packet, data_buffer);
PROTOCOL_RESERVED(packet)->buffer = hdr_buffer; // save hdr_buffer for completion
// call _original_ NdisTransferData (see ndis.h for definition of NdisTransferData)
status = adapter->old_TransferDataHandler(
((PNDIS_OPEN_BLOCK)(adapter->NdisBindingHandle))->MacBindingHandle,
MacReceiveContext, 0, PacketSize, packet, &bytes);
if (status == NDIS_STATUS_SUCCESS) {
// chain header at the first of packet
NdisChainBufferAtFront(packet, hdr_buffer);
// got the whole packet for filter!
result = filter_packet(DIRECTION_IN, adapter->adapter_index, packet);
} else if (status == NDIS_STATUS_PENDING) {
result = FALSE; // wait for NdisTransferDataComplete to be called
status = NDIS_STATUS_SUCCESS;
// don't free packet and buffers
buf = NULL;
hdr_buffer = NULL;
data_buffer = NULL;
packet = NULL;
} else
result = FALSE; // drop the packet
}
} __except((status = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER)) {
KdPrint(("[ndis_hk] new_ReceiveHandler: exception 0x%x!\n", status));
status = NDIS_STATUS_NOT_ACCEPTED;
result = FALSE;
}
if (result) {
// call original handler (specify fake MacReceiveContext = buf see new_TransferDataHandler)
if (buf == NULL) {
// LookaheadBufferSize == PacketSize
status = PCHARS_OLD_CHARS(pchars)->ReceiveHandler(ProtocolBindingContext,
(NDIS_HANDLE)LookaheadBuffer, HeaderBuffer, HeaderBufferSize,
LookaheadBuffer, LookaheadBufferSize, LookaheadBufferSize);
} else {
// LookaheadBufferSize < PacketSize
status = PCHARS_OLD_CHARS(pchars)->ReceiveHandler(ProtocolBindingContext,
(NDIS_HANDLE)((char *)buf + HeaderBufferSize), HeaderBuffer, HeaderBufferSize,
(char *)buf + HeaderBufferSize, PacketSize, PacketSize);
}
}
// cleanup
if (buf != NULL)
free(buf);
if (hdr_buffer != NULL)
NdisFreeBuffer(hdr_buffer);
if (data_buffer != NULL)
NdisFreeBuffer(data_buffer);
if (packet != NULL)
NdisFreePacket(packet);
return status;
}
/**
* Hooked TransferDataCompleteHandler from NDIS_PROTOCOL_CHARACTERISTICS.
* This function is called _only_ when we manually call original NdisTransferData and this
* function returns NDIS_STATUS_PENDING. We got the whole packet and call original
* ReceiveHandler.
* We call original ReceiveHandler with our buffer as MacReceiveContext. If protocol driver want to
* call hooked NdisTransferData we extract data for him from this buffer.
*/
VOID
new_TransferDataCompleteHandler(
struct PROTOCOL_CHARS *pchars, /* added by ASM stub */
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred)
{
struct ADAPTER_PROTOCOL *adapter;
PNDIS_BUFFER hdr_buffer, data_buffer;
void *buf;
ULONG data_size, hdr_size;
_CHECK_PCHARS(pchars);
// XXX Somebody, please test the code below. I never seen it's called
_TEST_ME_
// get adapter
for (adapter = pchars->adapter; adapter != NULL; adapter = adapter->next)
if (adapter->ProtocolBindingContext == ProtocolBindingContext)
break;
// this function can be called only for our packet! (is it true?)
NdisQueryPacket(Packet, NULL, NULL, &data_buffer, NULL);
hdr_buffer = PROTOCOL_RESERVED(Packet)->buffer;
// chain header buffer at the begin of packet
NdisChainBufferAtFront(Packet, hdr_buffer);
// A HACK! actually NDIS_BUFFER is MDL!
buf = MmGetSystemAddressForMdl(hdr_buffer);
NdisQueryBuffer(hdr_buffer, NULL, &hdr_size);
NdisQueryBuffer(data_buffer, NULL, &data_size);
if (adapter != NULL) {
// can't use UNICODE %S to output (see DbgPrint documentation)
KdPrint(("[ndis_hk] new_TransferDataCompleteHandler: (%d) pkt %u; bytes %u\n",
adapter->adapter_index,
hdr_size + data_size, BytesTransferred));
// filter packet
if (filter_packet(DIRECTION_IN, adapter->adapter_index, Packet)) {
// call original receive handler with packet (don't care about status)
PCHARS_OLD_CHARS(pchars)->ReceiveHandler(ProtocolBindingContext,
(NDIS_HANDLE)((char *)buf + hdr_size), buf, hdr_size,
(char *)buf + hdr_size, data_size, data_size);
}
}
// cleanup
free(buf);
NdisFreeBuffer(hdr_buffer);
NdisFreeBuffer(data_buffer);
NdisFreePacket(Packet);
}
/**
* Hooked ReceivePacketHandler from NDIS_PROTOCOL_CHARACTERISTICS.
* NDIS miniport driver indicates packet using new-style packet transfer.
* We got the whole packet! We can filter it and call original handler if we want.
*/
INT
new_ReceivePacketHandler(
struct PROTOCOL_CHARS *pchars, /* added by ASM stub */
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet)
{
struct ADAPTER_PROTOCOL *adapter;
_CHECK_PCHARS(pchars);
// get adapter
for (adapter = pchars->adapter; adapter != NULL; adapter = adapter->next)
if (adapter->ProtocolBindingContext == ProtocolBindingContext)
break;
if (adapter != NULL) {
// can't use UNICODE %S to output (see DbgPrint documentation)
KdPrint(("[ndis_hk] new_ReceivePacketHandler: (%d)\n",
adapter->adapter_index));
if (adapter->adapter_index != 0 &&
!filter_packet(DIRECTION_IN, adapter->adapter_index, Packet)) {
KdPrint(("[ndis_hk] new_ReceivePacketHandler: DROP!\n"));
return 0;
}
} else
KdPrint(("[ndis_hk] new_ReceivePacketHandler: adapter not found!\n"));
// call original handler
return PCHARS_OLD_CHARS(pchars)->ReceivePacketHandler(ProtocolBindingContext, Packet);
}
/**
* Hooked SendCompleteHandler from NDIS_PROTOCOL_CHARACTERISTICS.
* Check if it is completion for our call of NdisSend free our buffer and don't call original handler.
*/
VOID
new_SendCompleteHandler(
struct PROTOCOL_CHARS *pchars, /* added by ASM stub */
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status)
{
struct protocol_reserved *pr = PROTOCOL_RESERVED(Packet);
_CHECK_PCHARS(pchars);
/** @todo maybe using magic as ProtocolReserved is not stable solution... */
if (pr->magic == send_out_packet) {
// our completion! free buffer & packet
KdPrint(("[ndis_hk] new_SendCompleteHandler(our packet): Status 0x%x\n", Status));
free(pr->data);
NdisFreeBuffer(pr->buffer);
NdisFreePacket(Packet);
} else {
// call original handler
if (PCHARS_OLD_CHARS(pchars)->SendCompleteHandler != NULL)
PCHARS_OLD_CHARS(pchars)->SendCompleteHandler(ProtocolBindingContext, Packet, Status);
}
}
/**
* Hooked RequestCompleteHandler from NDIS_PROTOCOL_CHARACTERISTICS.
* Check if it is completion for our call of NdisRequest set event and don't call original handler.
*/
VOID
new_RequestCompleteHandler(
struct PROTOCOL_CHARS *pchars, /* added by ASM stub */
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status)
{
if (NdisRequest == g_request.pend_req) {
// it's our request
KdPrint(("[ndis_hk] new_RequestCompleteHandler(our request): Status 0x%x\n", Status));
g_request.status = Status;
NdisSetEvent(&g_request.event);
} else {
// call original handler
if (PCHARS_OLD_CHARS(pchars)->RequestCompleteHandler != NULL)
PCHARS_OLD_CHARS(pchars)->RequestCompleteHandler(ProtocolBindingContext, NdisRequest, Status);
}
}
/**
* Hooked PnPEventHandler from NDIS_PROTOCOL_CHARACTERISTICS.
* Call pnp_event() in filter chain
*/
NDIS_STATUS
new_PnPEventHandler(
struct PROTOCOL_CHARS *pchars, /* added by ASM stub */
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT NetPnPEvent)
{
struct ADAPTER_PROTOCOL *adapter;
NDIS_STATUS status;
_CHECK_PCHARS(pchars);
// get adapter
for (adapter = pchars->adapter; adapter != NULL; adapter = adapter->next)
if (adapter->ProtocolBindingContext == ProtocolBindingContext)
break;
if (adapter != NULL)
status = call_pnp_events(adapter->adapter_index, NetPnPEvent);
else
status = NDIS_STATUS_SUCCESS;
if (status == NDIS_STATUS_SUCCESS) {
// call original handler
status = PCHARS_OLD_CHARS(pchars)->PnPEventHandler(ProtocolBindingContext, NetPnPEvent);
}
return status;
}
/*
* --- NDIS functions from NDIS_OPEN_BLOCK ---
*/
/**
* Hooked SendHandler (NdisSend) from NDIS_OPEN_BLOCK.
* Filter packet and maybe call original handler
*/
NDIS_STATUS
new_SendHandler(
struct ADAPTER_PROTOCOL *adapter, /* added by ASM stub */
IN NDIS_HANDLE MacBindingHandle,
IN PNDIS_PACKET Packet)
{
// we get pchars only to check adapter
_CHECK_PCHARS(adapter->pchars);
// can't use UNICODE %S to output (see DbgPrint documentation)
KdPrint(("[ndis_hk] new_SendHandler: (%d)\n", adapter->adapter_index));
if (adapter->adapter_index != 0 &&
!filter_packet(DIRECTION_OUT, adapter->adapter_index, Packet)) {
KdPrint(("[ndis_hk] new_SendHandler: DENY!\n"));
return NDIS_STATUS_SUCCESS; // let protocol driver to think it's all right
}
return adapter->old_SendHandler(MacBindingHandle, Packet);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -