有偿求助: winsock lsp tcp 代理部分;详情见描述

2018-05-30 19:16:52 +08:00
 undefinedList

使用 lsp->socks5 来做游戏代理,主要是自用的 步骤如下: 1:拦截 wspSocket,创建相同参数的 socket ① 2:拦截 asyncSelect 和 eventSelect。wspIoctl 并记录参数 3:connect 时用①来代替原来的 socket,如果被修改过阻塞类型那么将类型修改为阻塞;和 socks5 代理协商并发送需要代理的数据;重新设置 async,event,wspIoctl 三种事件 结果:LOL 登陆是成功的,但开始游戏后聊天室连接不上(这个没啥,还凑合);倒计时结束开始加载对战界面的时候会提示连接服务器失败 求助:我该如何做

connect 部分代码如下:

#include "stdafx.h"

// an ip address is local address ; such as 127.0.0.1 169 192.168
bool isLocalAddr(const struct sockaddr *lpTo) {
	
}

//检查进程是否走代理
bool isProxy() {
	
}

bool SetSocketNonblock(SOCK_INFO *s, u_long nonblock)
{
	WSATHREADID id;
	id.ThreadHandle = GetCurrentThread();
	id.Reserved = NULL;
	INT err;
	DWORD pvout, pvlen = sizeof(DWORD);
	return s->Provider->NextProcTable.lpWSPIoctl(s->ProviderSocket, FIONBIO, &nonblock, sizeof(u_long), &pvout,	sizeof(DWORD), &pvlen, NULL, NULL, &id, &err) == 0;
}

int changeBlocking(SOCK_INFO *s, bool isReset = false) {
	int err = 0, ret = 0, nonBlock;

	if (isReset) {
		if (s->blockingType == BLOCKING_EVENT) {
			ret = s->Provider->NextProcTable.lpWSPEventSelect(s->ProviderSocket, s->eventSelectInfo.hEventObject, s->eventSelectInfo.lNetworkEvents, &err);
		}
		else if(s->blockingType == BLOCKING_ASYNC){
			ret = s->Provider->NextProcTable.lpWSPAsyncSelect(s->ProviderSocket, s->asyncSelectInfo.hWnd, s->asyncSelectInfo.wMsg, s->asyncSelectInfo.lEvent,  &err);
		}
		if (ret == SOCKET_ERROR) {
			dbgprint("Error: reset socket %d failed: %d",s->ProviderSocket,err);
			goto cleanup;
		}
	}
	else {
		nonBlock = 0;
		if (s->blockingType == BLOCKING_EVENT) {
			ret = s->Provider->NextProcTable.lpWSPEventSelect(s->ProviderSocket, 0, NULL, &err);
		}
		else if (s->blockingType == BLOCKING_ASYNC) {
			ret = s->Provider->NextProcTable.lpWSPAsyncSelect(s->ProviderSocket, s->asyncSelectInfo.hWnd, 0, 0, &err);
		}
		if (ret == SOCKET_ERROR) {
			dbgprint("Error: clean socket %d event failed: %d", s->ProviderSocket, err);
			goto cleanup;
		}
		SetSocketNonblock(s, FALSE);
	}

cleanup:

	return ret;
}

int ProxyConnect(SOCK_INFO *SocketContext, const struct sockaddr FAR * name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno) {
	if (!isProxy() || isLocalAddr(name)) {
		return  SocketContext->Provider->NextProcTable.lpWSPConnect(SocketContext->ProviderSocket, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, lpErrno);
	}
	dbgprint("Info: socket using lsp connect");
	int err = 0, ret = 0;
	DWORD byteLen = 0;
	ULONG nonBlock;
	//SetBlockingProvider(SocketContext->Provider);
	ret = changeBlocking(SocketContext, false);
	if (ret != 0) {
		dbgprint("Error: connect socket %d change type failed %d", SocketContext->ProviderSocket, ret);
		goto cleanup;
	}
	nonBlock = 0;
	sockaddr_in serveraddr;
	memset(&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.S_un.S_addr = inet_addr(proxyHost); //代理服务器地址
	serveraddr.sin_port = htons(proxyPort); // 端口号
	WSABUF DataBuf;
	char buffer[4];
	memset(buffer, 0, sizeof(buffer));
	DataBuf.len = 4;
	DataBuf.buf = buffer;
	err = 0;
	ret = SocketContext->Provider->NextProcTable.lpWSPConnect(SocketContext->ProviderSocket, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr), &DataBuf, lpCalleeData, lpSQOS, lpGQOS, &err);
	if (ret == SOCKET_ERROR)
	{
		dbgprint("Error: lpError is : %d;socket is %d", err, SocketContext->ProviderSocket);
		goto cleanup;
	}
	dbgprint("Info: connection to proxy %d,%s", SocketContext->ProviderSocket, callerFileNameFull);
	// 发送请求来协商版本和认证方法
	//VER   NMETHODS    METHODS  
	//1     1           1 to 255  
	char verstring[257];
	verstring[0] = 0x05;    //VER (1 Byte)  
	verstring[1] = 0x01;    //NMETHODS (1 Byte)  
	verstring[2] = 0x00;    //METHODS (allow 1 - 255 bytes, current 1 byte) 
	WSABUF infoBuf;
	infoBuf.len = 257;
	infoBuf.buf = verstring;
	err = 0;
	ret = SocketContext->Provider->NextProcTable.lpWSPSend(SocketContext->ProviderSocket, &infoBuf, 1, &byteLen, 0, NULL, NULL, NULL, &err);
	//rc = send(SocketContext->ProviderSocket, verstring, 257, 0);
	if (ret == SOCKET_ERROR)
	{
		dbgprint("Error: consult send version data to proxy failed: %d; sokcet is: %d", WSAGetLastError(), SocketContext->ProviderSocket);
		goto cleanup;
	}
	dbgprint("Info: socket send to server consult data success %d", SocketContext->ProviderSocket);
	/*
	* 接收代理服务器返回信息
	*/
	//rc = SocketContext->Provider->NextProcTable.lpWSPRecv(SocketContext->ProviderSocket, &infoBuf, 1, &byteLen, 0, NULL, NULL, NULL, &err);
	ret = recv(SocketContext->ProviderSocket, verstring, 257, 0);
	if (ret == SOCKET_ERROR)
	{
		dbgprint("Error: consult recv data from proxy failed :%d", WSAGetLastError());
		goto cleanup;
	}
	struct sockaddr_in sin;
	sin = *(const struct sockaddr_in *)name;
	char buf[10];
	buf[0] = 0x05; // 版本 SOCKS5
	buf[1] = 0x01; // 连接请求  
	buf[2] = 0x00; // 保留字段  
	buf[3] = 0x01; // IPV4  
	memcpy(&buf[4], &sin.sin_addr.S_un.S_addr, 4);
	memcpy(&buf[8], &sin.sin_port, 2);
	//发送  
	WSABUF infoBufData;
	infoBufData.len = sizeof(buf);
	infoBufData.buf = buf;
	byteLen = 0;
	//rc = SocketContext->Provider->NextProcTable.lpWSPSend(SocketContext->ProviderSocket, &infoBufData, 1, &byteLen, 0, NULL, NULL, NULL, &err);
	ret = send(SocketContext->ProviderSocket, buf, 10, 0);
	if (ret == SOCKET_ERROR)
	{
		dbgprint("Error: send proxy data to server failed: %d", err);
		goto cleanup;
	}
	//rc = SocketContext->Provider->NextProcTable.lpWSPRecv(SocketContext->ProviderSocket, &infoBufData, 1, &byteLen, 0, NULL, NULL, NULL, &err);
	ret = recv(SocketContext->ProviderSocket, buf, 10, 0);
	if (ret == SOCKET_ERROR)
	{
		dbgprint("Error: recv proxy server return failed :%d", WSAGetLastError());
		ret = ECONNREFUSED;
		goto cleanup;
	}
	SetSocketNonblock(SocketContext, SocketContext->Nonblock);
	ret = changeBlocking(SocketContext, true);
	if (ret != 0) {
		dbgprint("Error: connect socket %d reset type failed %d", SocketContext->ProviderSocket, ret);
		goto cleanup;
	}
	
	ret = NO_ERROR;
	dbgprint("Info: socket connected %d", SocketContext->ProviderSocket);

cleanup:

	return ret;
}
687 次点击
所在节点    C
6 条回复
undefinedList
2018-05-30 23:52:06 +08:00
自顶。。求助
db520
2018-05-31 06:48:23 +08:00
可能登录后用的是 udp,因此你的 sock5 还需要代理 udp
undefinedList
2018-05-31 09:56:41 +08:00
感谢大佬,udp 是 ok 的,从抓包看,没有产生 udp 包,@db520 大神起真早
undefinedList
2018-05-31 10:41:53 +08:00
RMB500 求助,来大佬教我
undefinedList
2018-05-31 16:37:37 +08:00
tcp 部分的解决了,原因:源 socket 1 ; lsp socket2
1 使用了 ioctl 来控制阻塞状态,2 未处理,正常情况下返回的应该是:return: SOCKET_ERROR; *lpErrno: 10035; 由于未处理,返回了:0 ; 0 ; 1 的程序就出错了

后续: 特么 lol 还是读秒后连不上,继续求助
undefinedList
2018-05-31 18:39:41 +08:00
解决了, 结帖

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/459028

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX