// FireWallDll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "windows.h"
#include "winsock2.h"
#include <stdio.h>
#include <ws2spi.h>
#include <tchar.h>
#include <string.h>
#include <sporder.h>
#include "Head.h"
#pragma comment(lib,"ws2_32.lib")
LPWSAPROTOCOL_INFOW protoinfo;
unsigned long protoinfosize;
int totalprotos;
WSPPROC_TABLE nextproctable;
GUID TCPguid={0x4d1e91fd,0x116a,0x44aa,{0x8f,0xd4,0x1d,0x2c,0xf2,0x7b,0xd9,0xa9}};
GUID TCPchainguid={0x4d1e91fd,0x116a,0x44aa,{0x8f,0xd4,0x1d,0x2c,0xf2,0x7b,0xd9,0xa9}};
//擷取一個端口清單條目,放在Item中
BOOL GetPortListItem(int i,PORTLISTITEM *Item)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
if(i<PortListSize)
{
*Item = PortList[i];
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
LeaveCriticalSection(&RWSCriticalSection);
return FALSE;
}
//添加一個端口條目
BOOL AddPortListItem(PORTLISTITEM Item)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
PortList[PortListSize] = Item;
PortListSize++;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
//删除一個端口條目
BOOL DeletePortListItem(int i)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
if(i<PortListSize)
{
for(int j=PortListSize-1; j>i ;j--)
{
PortList[j-1] = PortList[j];
}
PortListSize--;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
LeaveCriticalSection(&RWSCriticalSection);
return FALSE;
}
//
//擷取一個IP條目
BOOL GetIpListItem(int i,IPLISTITEM *Item)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
if(i < IpListSize)
{
*Item = IpList[i];
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return FALSE;
}
//添加一個IP條目
BOOL AddIpListItem(IPLISTITEM Item)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
IpList[IpListSize] = Item;
IpListSize++;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
//删除一個IP條目
BOOL DeleteIpListItem(int i)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
if(i<IpListSize)
{
for(int j = IpListSize-1;j>i;j--)
{
IpList[j-1] = IpList[j];
}
IpListSize--;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return FALSE;
}
//擷取一個應用程式條目
BOOL GetPathListItem(int i,PATHLISTITEM *Item)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
if(i<PathListSize)
{
*Item = PathList[i];
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return FALSE;
}
//添加一個應用程式條目
BOOL AddPathListItem(PATHLISTITEM Item)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
PathList[PathListSize] = Item;
PathListSize++;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
//删除一個應用程式條目
BOOL DeletePathListItem(int i)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
if(i<PathListSize)
{
for(int j=PathListSize-1;j>i;j--)
{
PathList[j-1] = PathList[j];
}
PathListSize--;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return FALSE;
}
/
//檢查端口
BOOL CheckPort(USHORT Port)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
//依次對比表中的各項
for(int i=0;i<PortListSize;i++)
{
if(Port == PortList[i].Port)
{
BOOL Buff = PortList[i].Pass;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return Buff;
}
}
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
///
//檢查應用程式
//
BOOL CheckAppPath(WCHAR * Path)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
//依次對比表中的各項
for(int i = 0;i<PathListSize;i++)
{
if(wcscmp(PathList[i].Path,Path)==0)
{
BOOL Buff = PathList[i].Pass;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return Buff;
}
}
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
WCHAR Buff[512] = {0};
wcscat(Buff,Path);
wcscat(Buff,L"正要産生網絡連接配接,是否阻止,單擊“是”按鈕進行阻止并加入黑名單,單擊“否”按鈕解除阻止并加入白名單。");
switch(MessageBox(NULL,(char *)Buff,"FireWall",MB_YESNOCANCEL))
{
case IDYES:
{
PATHLISTITEM ItemBuff;
wcscpy(ItemBuff.Path,Path);
ItemBuff.Pass = FALSE;
AddPathListItem(ItemBuff);
}
break;
case IDNO:
{
PATHLISTITEM ItemBuff;
wcscpy(ItemBuff.Path,Path);
ItemBuff.Pass = TRUE;
AddPathListItem(ItemBuff);
}
break;
default:
break;
}
return TRUE;
}
/
//檢查目的IP
/
BOOL CheckIp(IN_ADDR Ip)
{
//進入臨界區
EnterCriticalSection(&RWSCriticalSection);
//依次對比表中各項
for(int i=0;i<IpListSize;i++)
{
if(memcmp(&IpList[i].Ip,&Ip,sizeof(IN_ADDR))==0)
{
BOOL Buff = IpList[i].Pass;
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return Buff;
}
}
//離開臨界區
LeaveCriticalSection(&RWSCriticalSection);
return TRUE;
}
//WSPBind函數,供上一個服務提供者調用
int WINAPI FWWSPBind(
SOCKET s,
const struct sockaddr* name,
int namelen,
LPINT lpErrno)
{
SOCKADDR_IN SrcSockAddr;
memcpy(&SrcSockAddr,name,sizeof(SrcSockAddr));
//檢查要綁定的Port的合法性
if(CheckPort(SrcSockAddr.sin_port)==FALSE)
{
*lpErrno = WSAECONNABORTED;
return SOCKET_ERROR;
}
return nextproctable.lpWSPBind(s,name,namelen,lpErrno);
}
///
//WSPListen函數,供上一個服務提供者調用
///
int WINAPI FWWSPListen(
SOCKET s,
int backlog,
LPINT lpErrno)
{
SOCKADDR_IN SrcSockAddr;
int SrcSockAddrLen = sizeof(SrcSockAddr);
//擷取與該SOCKET綁定的socketaddr
if(getsockname(s,(sockaddr*)&SrcSockAddr,&SrcSockAddrLen)==0)
{
//檢查要監聽的端口的合法性
if(CheckPort(SrcSockAddr.sin_port)==FALSE)
{
*lpErrno = WSAECONNABORTED;
return SOCKET_ERROR;
}
}
return nextproctable.lpWSPListen(s,backlog,lpErrno);
}
int WINAPI FWWSPConnect(
SOCKET s,
const struct sockaddr* name,
int namelen,
LPWSABUF lpCallerData,
LPWSABUF lpCalleeData,
LPQOS lpSQOS,
LPQOS lpGQOS,
LPINT lpErrno)
{
SOCKADDR_IN DestSockAddr;
memcpy(&DestSockAddr,name,namelen);
//檢查目的IP
if(CheckIp(DestSockAddr.sin_addr)==FALSE)
{
*lpErrno = WSAECONNABORTED;
return SOCKET_ERROR;
}
//存放傳回值
int RST = 0;
RST = nextproctable.lpWSPConnect(s,name,namelen,lpCallerData,lpCalleeData,lpSQOS,lpGQOS,lpErrno);
SOCKADDR_IN SrcSockAddr;
int SrcSockAddrLen = sizeof(SrcSockAddr);
if(RST == 0)
{
if(getsockname(s,(sockaddr*)&SrcSockAddr,&SrcSockAddrLen)==0)
{
if(CheckPort(SrcSockAddr.sin_port)==FALSE)
{
*lpErrno = WSAECONNABORTED;
return SOCKET_ERROR;
}
}
}
return RST;
}
/******** 獲得服務提供者資訊 **********/
BOOL GetProviders()
{
int errorcode;
//這幾個都是全局變量
protoinfo = NULL;
protoinfosize = 0;
totalprotos = 0;
//列舉服務提供者,其實是為了擷取LSP的數量
if(WSCEnumProtocols(NULL,protoinfo,&protoinfosize,&errorcode) == SOCKET_ERROR)
{
if(errorcode != WSAENOBUFS)
return FALSE;
}
//按LSP數量配置設定記憶體空間
if((protoinfo = (LPWSAPROTOCOL_INFOW)GlobalAlloc(GPTR,protoinfosize)) == NULL)
{
return FALSE;
}
//獲得所有LSP資訊,儲存在protoinfo
if((totalprotos = WSCEnumProtocols(NULL,protoinfo,&protoinfosize,&errorcode)) == SOCKET_ERROR)
{
return FALSE;
}
return TRUE;
}
void FreeProviders()
{
GlobalFree(protoinfo);
}
void ChangeFromUnicode(unsigned short *UFilterPath,char *FilterPath)
{
int i=0;
while(UFilterPath[i]!=0)
{
FilterPath[i]=UFilterPath[i];
i++;
}
FilterPath[i]=0;
}
int WSPAPI WSPRecvFrom (
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
struct sockaddr FAR * lpFrom,
LPINT lpFromlen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
struct sockaddr_in sin;
sin=*(const struct sockaddr_in *)lpFrom;
if(sin.sin_port==htons(8888))
{
OutputDebugString(_T("WSPSendTo Tencent Filtered"));
// return 0;
return nextproctable.lpWSPRecvFrom(s,lpBuffers,dwBufferCount,
lpNumberOfBytesRecvd,lpFlags,lpFrom,lpFromlen,
lpOverlapped,lpCompletionRoutine,lpThreadId,lpErrno);
//return nextproctable.lpWSPSendTo(s,lpbuffer,dwbuffercount,
// lpnumberofbytessent,dwflags,lpto,itolen,
// lpoverlapped,lpcompletionroutine,lpthreadid,lperrno);
}
else
{
//return 0;
return nextproctable.lpWSPRecvFrom(s,lpBuffers,dwBufferCount,
lpNumberOfBytesRecvd,lpFlags,lpFrom,lpFromlen,
lpOverlapped,lpCompletionRoutine,lpThreadId,lpErrno);
}
}
int WSPAPI WSPStartup(
WORD wversionrequested,
LPWSPDATA lpwspdata,
LPWSAPROTOCOL_INFOW lpprotoinfo,
WSPUPCALLTABLE upcalltable,
LPWSPPROC_TABLE lpproctable)
{
int i;
int errorcode;
int filterpathlen;
DWORD layerid = 0;
DWORD nextlayerid = 0;
unsigned short *NextDllPathUnicode;
TCHAR *NextDllPath;
HINSTANCE hfilter;
LPWSPSTARTUP wspstartupfunc = NULL;
if(lpprotoinfo->ProtocolChain.ChainLen <= 1)
{
return FALSE;
}
//擷取LSP資訊
GetProviders();
/**************找到自己的LSP的入口ID********************/
for(i=0;i<totalprotos;i++)
{
if(memcmp(&protoinfo[i].ProviderId,&TCPguid,sizeof(GUID))==0)
{
layerid = protoinfo[i].dwCatalogEntryId;
break;
}
}
if(i>=totalprotos)
{
return FALSE;
}
/***************找到自己的服務鍊,并在服務鍊中找到下一個LSP的入口ID**************/
for(i=0;i<totalprotos;i++)
{
if(memcmp(&protoinfo[i].ProviderId,&TCPchainguid,sizeof(GUID))==0)
{
protoinfo = protoinfo+i;
break;
}
}
if(i>=totalprotos)
{
return FALSE;
}
//在服務鍊中找到自己的LSP的下一個LSP
for(i=0;i<lpprotoinfo->ProtocolChain.ChainLen;i++)
{
if(lpprotoinfo->ProtocolChain.ChainEntries[i] == layerid)
{
nextlayerid = lpprotoinfo->ProtocolChain.ChainEntries[i+1];
break;
}
}
if(i>=lpprotoinfo->ProtocolChain.ChainLen)
{
return FALSE;
}
FreeProviders();
GetProviders();
//根據入口ID找到LSP并擷取其DLL的路徑并安裝
filterpathlen = MAX_PATH;
NextDllPathUnicode = (unsigned short*)GlobalAlloc(GPTR,filterpathlen);
for(i=0;i<totalprotos;i++)
{
if(nextlayerid == protoinfo[i].dwCatalogEntryId)
{
//查找其DLL路徑
if(WSCGetProviderPath(&protoinfo[i].ProviderId,NextDllPathUnicode,&filterpathlen,&errorcode)==SOCKET_ERROR)
{
return WSAEPROVIDERFAILEDINIT;
}
break;
}
}
ChangeFromUnicode(NextDllPathUnicode,NextDllPath);
if(!ExpandEnvironmentStrings(NextDllPath,NextDllPath,MAX_PATH))
{
return WSAEPROVIDERFAILEDINIT;
}
//加載下一個LSP的DLL
if((hfilter = LoadLibrary(NextDllPath))==NULL)
{
return WSAEPROVIDERFAILEDINIT;
}
//擷取下一個LSP的WSPStartup函數位址并調用
//擷取函數位址
if((wspstartupfunc=(LPWSPSTARTUP)GetProcAddress(hfilter,"WSPStartup"))==NULL)
{
return WSAEPROVIDERFAILEDINIT;
}
//調用下一個LSP的WSPStartup函數
if((errorcode=wspstartupfunc(wversionrequested,lpwspdata,lpprotoinfo,upcalltable,lpproctable))!=ERROR_SUCCESS)
{
return errorcode;
}
//儲存下一個LSP的各個WSP函數位址
nextproctable = *lpproctable;
//向上導出的函數表位址更改
lpproctable->lpWSPRecvFrom = WSPRecvFrom;
lpproctable->lpWSPConnect = FWWSPConnect;
lpproctable->lpWSPBind = FWWSPBind;
lpproctable->lpWSPListen = FWWSPListen;
FreeProviders();
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}