⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drivertool.c

📁 一个截取网络包的驱动。它与DDK文档正是NDIS中间驱动不同
💻 C
字号:
////////////////////////////////////////
//		该文件是一些辅助工具函数
//
////////////////////////////////////////



//网络与主机字节的转换函数
ULONG UTIL_htonl( ULONG hostlong )
{
	PUCHAR pBuffer;
	ULONG	nResult;
	UCHAR	c, *pResult;

	pBuffer = (PUCHAR )&hostlong;

	if( !pBuffer )
	{
		return( 0L );
	}

	pResult = (UCHAR * )&nResult;

	c = ((UCHAR * )pBuffer)[ 0 ];
	((UCHAR * )pResult)[ 0 ] = ((UCHAR * )pBuffer)[ 3 ];
	((UCHAR * )pResult)[ 3 ] = c;

	c = ((UCHAR * )pBuffer)[ 1 ];
	((UCHAR * )pResult)[ 1 ] = ((UCHAR * )pBuffer)[ 2 ];
	((UCHAR * )pResult)[ 2 ] = c;

	return( nResult );
}

USHORT UTIL_htons( USHORT hostshort )
{
	PUCHAR	pBuffer;
	USHORT	nResult;

	nResult = 0;
	pBuffer = (PUCHAR )&hostshort;

	nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
		| ( pBuffer[ 1 ] & 0x00FF );

	return( nResult );
}

//从Packet偏移nOffset位置起读nNumberOfBytesToRead字节并放入lpBuffer中,lpNumberOfBytesRead为实际读的字节数
void ReadOnPacket(PNDIS_PACKET Packet, PUCHAR lpBuffer, ULONG nNumberOfBytesToRead, ULONG nOffset, PULONG lpNumberOfBytesRead)
{
   PNDIS_BUFFER    CurrentBuffer;
   UINT            nBufferCount, TotalPacketLength;
   PUCHAR          VirtualAddress;
   UINT            CurrentLength, CurrentOffset;
   UINT            AmountToMove;

   *lpNumberOfBytesRead = 0;
   if (!nNumberOfBytesToRead)
      return;

   // Query Packet
   NdisQueryPacket(
      (PNDIS_PACKET )Packet,
      (PUINT )NULL,           // Physical Buffer Count
      (PUINT )&nBufferCount,  // Buffer Count
      &CurrentBuffer,         // First Buffer
      &TotalPacketLength      // TotalPacketLength
      );

   // Query The First Buffer
   NdisQueryBuffer(
      CurrentBuffer,
      (void**)&VirtualAddress,
      &CurrentLength
      );

   CurrentOffset = 0;

   while( nOffset || nNumberOfBytesToRead )
   {
      while( !CurrentLength )
      {
         NdisGetNextBuffer(
            CurrentBuffer,
            &CurrentBuffer
            );

         // If we've reached the end of the packet.  We return with what
         // we've done so far (which must be shorter than requested).
         if (!CurrentBuffer)
            return;

         NdisQueryBuffer(
            CurrentBuffer,
            (void**)&VirtualAddress,
            &CurrentLength
            );

         CurrentOffset = 0;
      }

      if( nOffset )
      {
         // Compute how much data to move from this fragment
         if( CurrentLength > nOffset )
            CurrentOffset = nOffset;
         else
            CurrentOffset = CurrentLength;

         nOffset -= CurrentOffset;
         CurrentLength -= CurrentOffset;
      }

      if( nOffset )
      {
         CurrentLength = 0;
         continue;
      }

      if( !CurrentLength )
      {
         continue;
      }

      // Compute how much data to move from this fragment
      if (CurrentLength > nNumberOfBytesToRead)
         AmountToMove = nNumberOfBytesToRead;
      else
         AmountToMove = CurrentLength;

      // Copy the data.
      NdisMoveMemory(
         lpBuffer,
         &VirtualAddress[ CurrentOffset ],
         AmountToMove
         );

      // Update destination pointer
      lpBuffer += AmountToMove;

      // Update counters
      *lpNumberOfBytesRead +=AmountToMove;
      nNumberOfBytesToRead -=AmountToMove;
      CurrentLength = 0;
   }
}

VOID
UTIL_WriteOnPacket(
   PNDIS_PACKET Packet,
   PUCHAR lpBuffer,
   ULONG nNumberOfBytesToWrite,
   ULONG nOffset,                // Byte Offset, Starting With MAC Header
   PULONG lpNumberOfBytesWrite
   )
{
   PNDIS_BUFFER    CurrentBuffer;
   UINT            nBufferCount, TotalPacketLength;
   PUCHAR          VirtualAddress;
   UINT            CurrentLength, CurrentOffset;
   UINT            AmountToMove;

   *lpNumberOfBytesWrite = 0;
   if (!nNumberOfBytesToWrite)
      return;

   //
   // Query Packet
   //
   NdisQueryPacket(
      (PNDIS_PACKET )Packet,
      (PUINT )NULL,           // Physical Buffer Count
      (PUINT )&nBufferCount,  // Buffer Count
      &CurrentBuffer,         // First Buffer
      &TotalPacketLength      // TotalPacketLength
      );

   //
   // Query The First Buffer
   //
   NdisQueryBuffer(
      CurrentBuffer,
      &VirtualAddress,
      &CurrentLength
      );

   CurrentOffset = 0;

   while( nOffset || nNumberOfBytesToWrite )
   {
      while( !CurrentLength )
      {
         NdisGetNextBuffer(
            CurrentBuffer,
            &CurrentBuffer
            );

         // If we've reached the end of the packet.  We return with what
         // we've done so far (which must be shorter than requested).
         if (!CurrentBuffer)
            return;

         NdisQueryBuffer(
            CurrentBuffer,
            &VirtualAddress,
            &CurrentLength
            );

         CurrentOffset = 0;
      }

      if( nOffset )
      {
         // Compute how much data to move from this fragment
         if( CurrentLength > nOffset )
            CurrentOffset = nOffset;
         else
            CurrentOffset = CurrentLength;

         nOffset -= CurrentOffset;
         CurrentLength -= CurrentOffset;
      }

      if( nOffset )
      {
         CurrentLength = 0;
         continue;
      }

      if( !CurrentLength )
      {
         continue;
      }

      // Compute how much data to move from this fragment
      if (CurrentLength > nNumberOfBytesToWrite)
         AmountToMove = nNumberOfBytesToWrite;
      else
         AmountToMove = CurrentLength;

      // Copy the data.
      NdisMoveMemory(
         &VirtualAddress[ CurrentOffset ],
         lpBuffer,
         AmountToMove
         );

      // Update destination pointer
      lpBuffer += AmountToMove;

      // Update counters
      *lpNumberOfBytesWrite +=AmountToMove;
      nNumberOfBytesToWrite -=AmountToMove;
      CurrentLength = 0;
   }
}

//取系统启动到现在所经过的时间,分别以秒和毫秒为单位
#ifdef	_WIN32_WINNT
ULONG GetSystemTime()
{
	LARGE_INTEGER lnTime;
	KeQuerySystemTime(&lnTime);

	return (ULONG)(lnTime.QuadPart/10000000);
}
ULONG GetMSTime()
{
	LARGE_INTEGER lnTime;
	KeQuerySystemTime(&lnTime);

	return (ULONG)(lnTime.QuadPart/10000);
}
#else
#define	GetSystemTime() (Get_Last_Updated_System_Time()/1000)
#define	GetMSTime() Get_Last_Updated_System_Time()
#endif

//计算包校验值
unsigned short checksum(unsigned short* addr,int len)
{
	register long sum = 0;

	while(len > 1){
			sum += *addr++;
			len -= 2;
			}
	if(len > 0) sum += *addr;
	while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);

	return (USHORT)~sum;
}

unsigned short udpcksum (SIp *pip,SUdp *pudp)
{
	register long sum = 0;
	SPsh psh_h;
	USHORT *addr=(USHORT*)&psh_h;
	int len=sizeof(psh_h);

	psh_h.ip_dst=pip->ip_dst;
	psh_h.ip_src=pip->ip_src;
	psh_h.zero=0;
	psh_h.ip_p=17;
	psh_h.usLen=pudp->len;
	while(len > 1){
			sum += *addr++;
			len -= 2;
			}

	addr=(USHORT*)pudp;
	len=UTIL_htons(pudp->len);
	while(len > 1){
			sum += *addr++;
			len -= 2;
			}
	if(len > 0) sum += (unsigned char)*addr;

	while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);
	return (USHORT)~sum;
}

//解密包
#define	MAX_RAND1		36
#define	MAX_RAND4		16

int DecryptVarLenPacket(const UCHAR *szInPacket, UINT nInLen, UCHAR *szOutPacket, UINT nOutBufLen)
{
	UCHAR nRand1,nRand2,nRand3,nRand4,nCheckNum1,nCheckNum2;
	ULONG n,nPos,nSum,nAdd,nTemp;
	UINT nDataLen;
	const UCHAR *pPacket=szInPacket;

	if(nInLen<=7) return 0;	// || nInLen>=100000

	nRand1=szInPacket[0];
	if(nRand1>MAX_RAND1) return 0;

    nCheckNum2=szInPacket[nInLen-1];
    pPacket+=nInLen-5;
    nDataLen=*(ULONG*)pPacket;
    nCheckNum1=szInPacket[nInLen-6];

    if(nDataLen<=0) return 0;
	if(nDataLen>nOutBufLen) return 0;

	nPos=1+nRand1+nDataLen;
	nRand2=szInPacket[nPos];

	nPos++;
	nRand3=szInPacket[nPos];

	nPos++;
	nRand4=szInPacket[nPos];
	if(nRand4>MAX_RAND4) return 0;

	nPos+=nRand4+1;
	n=nSum=0;
	while(n<=nPos-1)
	{
		nSum+=szInPacket[n];
		n+=7;
	}
	nSum+=nRand1+nRand2+nRand3+nRand4;
	if(nSum%256 != nCheckNum1) return 0;

	nPos+=2;
	n=nSum=0;
	while(n<=nPos)
	{
		nSum+=szInPacket[n];
		n+=9;
	}
	nSum+=nCheckNum1+nDataLen;
	if(nSum%256 != nCheckNum2) return 0;

    memcpy(szOutPacket,szInPacket+1+nRand1,nDataLen);
	nPos=0;
	while(nPos<nDataLen)
	{
		nAdd=nRand1+(nPos/2)*nRand2;
		n=(nAdd-szOutPacket[nPos]+256-1)/256;
		nTemp=szOutPacket[nPos]+n*256-nAdd;
		szOutPacket[nPos]=(UCHAR)nTemp;

		nAdd=nRand4+(nPos/2)*nRand3;
		n=(nAdd-szOutPacket[nPos+1]+256-1)/256;
		nTemp=szOutPacket[nPos+1]+n*256-nAdd;
		szOutPacket[nPos+1]=(UCHAR)nTemp;

		nPos+=2;
	}

	return nDataLen;
}

#pragma pack(1)
//用来辅助打印IP的结构
typedef union
{
	struct
	{
		UCHAR a;
		UCHAR b;
		UCHAR c;
		UCHAR d;
	}sIp;
	ULONG uIp;
}UAddr;
#pragma pack()

//调试函数:打印IP
void PrintIp(ULONG uIp)
{
	static char szIp[16];
	UAddr addr;
	addr.uIp=uIp;

	DbgPrint("%d.%d.%d.%d",addr.sIp.a,addr.sIp.b,addr.sIp.c,addr.sIp.d);
}

//调试函数:打印MAC,szMsg为提示信息
void PrintMac(const char *szMsg,UCHAR mac[])
{
	DbgPrint("%s=%02X-%02X-%02X-%02X-%02X-%02X",szMsg,
		mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
}

//从具有count个整数的32位整数数组arrayu32中搜索整数uip,pPos返回数组中位置
//1-成功,0-失败
int ArrayFindU32(ULONG arrayu32[],ULONG uip,USHORT count,int *pPos)
{
	int begin,end;

	if(count==0) return 0;

	begin=0;
	end=count-1;
	*pPos=(begin+end)/2;

	while(end>begin)
	{
		if(uip>arrayu32[*pPos])
		{
			begin=(*pPos)+1;
			*pPos=(begin+end)/2;
		}
		else if(uip<arrayu32[*pPos])
		{
			end=(*pPos)-1;
			*pPos=(begin+end)/2;
		}
		else
		{
			return 1;
		}
	}

	return (uip==arrayu32[*pPos]);
}

//从具有*pCount个整数的32位整数数组*parrayu32中增加整数uip,pPos返回数组中位置
//nMaxCount为数组最大个数
//1-成功,0-失败
int ArrayAddU32(ULONG (*parrayu32)[],ULONG uip,USHORT *pCount,int *pPos,int nMaxCount)
{
	int n;

	if((*pCount)==0)
	{
		*pPos=0;
		goto add;
	}

	if(ArrayFindU32(*parrayu32,uip,*pCount,pPos)) return 0;

	if((*pCount)>=nMaxCount) return 0;

	if(uip>(*parrayu32)[*pPos]) (*pPos)++;

	for(n=(*pCount)-1;n>=(*pPos);n--)
	{
		(*parrayu32)[n+1]=(*parrayu32)[n];
	}
add:
	(*parrayu32)[*pPos]=uip;
	(*pCount)++;

	return 1;
}

#define SYSNAME "System"

#ifdef	_WIN32_WINNT
ULONG g_uMajVer=0;
ULONG g_uMinVer=0;
ULONG g_uPNameOff=0;

//取进程名在PEPROCESS结构中的偏移位置
void GetProcessNameOffset()
{
    PEPROCESS curproc=PsGetCurrentProcess();
    int i;

    // Scan for 12KB, hopping the KPEB never grows that big!
    for( i = 0; i < 3*PAGE_SIZE; i++ )
	{
        if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) ))
		{
			g_uPNameOff=i;
			break;
        }
    }
}

//取进程名
char* GetProcessName()
{
	if(g_uMajVer!=5) return NULL;

	switch(g_uMinVer)
	{
	case 0:
		return (char*)PsGetCurrentProcess() + 0x1FC;	//Win2K
	case 1:
		return (char*)PsGetCurrentProcess() + 0x174;	//WinXP
	case 2:
		return (char*)PsGetCurrentProcess() + 0x154;	//Win2003
	default:
		if(g_uPNameOff) return (char*)PsGetCurrentProcess() + g_uPNameOff;
		break;
	}

	return NULL;
}
#else
char* GetProcessName()
{
	PVOID       CurProc;
	PVOID       ring3proc;
	char        *name;
	static char		ProcessName[MAX_PNAME_LEN];

	// Get the ring0 process pointer.
	CurProc = VWIN32_GetCurrentProcessHandle();

	// Now, map the ring3 PCB 
	ring3proc = (PVOID) SelectorMapFlat(
		Get_Sys_VM_Handle(), 
		(DWORD)(*(PDWORD)((char *) CurProc + 0x38)) | 0x7,
		0
		);

	if( ring3proc == (PVOID) -1 )
	{
		strcpy( ProcessName, SYSNAME);
	}
	else
	{
		name = ((char *)ring3proc) + 0xF2;
		strncpy(ProcessName,name,8);
		ProcessName[8] = 0;

/*		if( name[0] >= 'A' && name[0] <= 'z' )
		{
			strcpy( ProcessName, name );
			ProcessName[8] = 0;
		}
		else
		{
			strcpy( ProcessName, SYSNAME);
		}*/
	}

	return ProcessName;
}
#endif

#define	IsBroadcastExMac(mac) (memcmp(mac,g_brdctmac,6)==0 || mac[0]==1 || memcmp(mac,g_dnatmac,6)==0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -