📄 drivertool.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 + -