在国内玩国外的游戏或者电信与网通移动这些网络通信,大家应该都遇到一种情况,就是网速好卡是吧,我们今天就是来解决这类问题的。
这是因为两端网络不同,传输距离过远,路由过滤等因素。
为了游戏或者不同网络环境有更好的体验,现在国内出现了大量的网络加速工具。
现在的程序,特别是现在的网络游戏,有各种保护,如TP TS HS CD GPK BE NP等等保护,用以前的老方法如LSP和API HOOK已经不行了,他们的原理都是会给游戏加载一个DLL,因为游戏会检测DLL,会误认为是辅助类东西,就会报非法或者禁止加载,所以老的办法兼容性已经过时了。
根据个人经验,目前最好的办法是用TDI及WFP驱动来拦截网络数据,然后R3层通过SOCKS5来与代理服务器交互数据,这样是底层拦截,不注入不对目标进程任何操作,兼容所有WIN系统,支持任何联网进程或者游戏。
最终的效果,可以实现单窗口单IP,每个进程不同IP,象模拟器都可以不同IP,局部SOCKS5,全局SOCKS5等功能的。还可以不关进程换IP,只代理指定端口或者IP数据等功能。这些功能都可以在R3层完成,这样的模式可以滥生出很多其它功能,如做防火墙,IP重定向等程序。
下载地址:https://download.csdn.net/download/qq1289671197/11860069
WFP部分见以下代码:
FWPS_STREAM_CALLOUT_IO_PACKET* streamPacket;
FWPS_STREAM_DATA* streamData;
PTCPCTX pTcpCtx;
FWPS_PACKET_INJECTION_STATE packetState;
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN isSend;
KIRQL irql;
UNREFERENCED_PARAMETER(classifyContext);
UNREFERENCED_PARAMETER(filter);
streamPacket = (FWPS_STREAM_CALLOUT_IO_PACKET*) packet;
streamData = streamPacket->streamData;
pTcpCtx = *(PTCPCTX*)(UINT64*) &flowContext;
if ((classifyOut->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
KdPrint((DPREFIX"callouts_streamCallout [%I64u] no FWPS_RIGHT_ACTION_WRITE\n", pTcpCtx->id));
return status;
}
if (!devctrl_isProxyAttached() ||
pTcpCtx->abortConnection ||
devctrl_isShutdown())
{
KdPrint((DPREFIX"callouts_streamCallout [%I64u] drop connection\n", pTcpCtx->id));
streamPacket->streamAction = FWPS_STREAM_ACTION_DROP_CONNECTION;
classifyOut->actionType = FWP_ACTION_NONE;
return status;
}
R3部分部分检测代理函数:
SOCKET MySocket = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in sock;
sock.sin_family = AF_INET;
sock.sin_port = htons(s5port);
sock.sin_addr.s_addr = inet_addr(s5ip);
if (sock.sin_addr.S_un.S_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(s5ip);
if (lphost != NULL)
{
sock.sin_addr.S_un.S_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
}
else
{
closesocket(MySocket);
return FALSE;
}
}
if (connect(MySocket, (struct sockaddr *)&sock, sizeof(sock)))
{
//OutputDebugStringA("Failed to connect proxy.\n");
closesocket(MySocket);
return FALSE;
}
int nLen = 0;
char szBuffer[1024 + 1] = { "" };
szBuffer[0] = 5;
szBuffer[1] = 2;
szBuffer[2] = 0;
szBuffer[3] = 2;
nLen = 4;
send(MySocket, szBuffer, nLen, 0);
nLen = 2;
recv(MySocket, szBuffer, nLen, 0);
char *lpszUserName = user;
char *lpszPassword = pass;
if (szBuffer[0] == 5) //need auth
{
if (szBuffer[1] == 2)
{
szBuffer[0] = 1;
nLen = strlen(lpszUserName);
szBuffer[1] = nLen;
strncpy(szBuffer + 2, lpszUserName, strlen(lpszUserName));
nLen += 2;
szBuffer[nLen] = strlen(lpszPassword);
strcpy(szBuffer + nLen + 1, lpszPassword);
nLen = nLen + 1 + strlen(lpszPassword);
send(MySocket, szBuffer, nLen, 0);
nLen = 2;
recv(MySocket, szBuffer, nLen, 0);
if (szBuffer[1] != 0)
{
//OutputDebugStringA("user failed!\n");
closesocket(MySocket);
return FALSE;
}
}
}