歡迎您光臨本站 註冊首頁

?檳愕?Q造一??SOCK5 PROXY(Gcc篇)之二

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  ?檳愕?Q造一??SOCK5 PROXY(Gcc篇)之二

作者: ?氏??(http://chiosoft.51.net)
E-mail: chiosoft@163.net
※???註明出?※


本文以QQ??ο?教你如何??一??SOCK5 PROXY
本章主要介?Launch_TCP()的工作原理

一、握手?程
===================
先看看Proxy的?出?果:

< TCP/IP Session - START >

RECV ==> 3 bytes: (0x5)(0x1)(0x0)
SEND ==> 2 bytes: (0x5)(0x0)

RECV ==> 10 bytes: (0x5)(0x3)(0x0)(0x1)(0x0)(0x0)(0x0)(0x0)(0x6)(0x32)
SEND ==> 10 bytes: (0x5)(0x0)(0x0)(0x1)(0x7f)(0x0)(0x0)(0x1)(0x22)(0x6b)

< TCP/IP Session - END >


如果不需要身份??的?,SOCK5 PROXY和客?舳說奈帳謅^程只有四句,
由於SOCK5?f?包括很多?熱???只?Ρ糾?興?玫降牟糠葑鞽穌f明,
?者可?⒖?fc1928.txt

以下逐句分析:
1. 第一句,客?舳恕?ROXY
  (0x5)版本?
  (0x1)代表有1 byte的?料
  (0x0)登入模式,0x0代表不用身份??,0x2代表需要usrname/password

2. 第二句,PROXY→客?舳?br>  (0x5)版本?
  (0x0)成功

3. 第三句,客?舳恕?ROXY
  (0x5)版本?
  (0x3)要求使用的?f??型,0x3代表UDP
  (0x0)保留字
  (0x1)地址?型,0x1代表IPv4,0x3代表Domain name,0x4代表IPv6
  (0x0)(0x0)(0x0)(0x0)?4??bytes代表客?舳說牡刂?br>  (0x6)(0x32)客?舳擻米?DP?鬏?的埠?

4. 第四句,PROXY→客?舳?br>  (0x5)版本?
  (0x0)成功
  (0x0)保留字
  (0x1)地址?型
  PROXY提供的UDP SOCKET地址和埠?,一定要?蝕_?o?,客?舳誦枰?B接到???地址.
  (0x7f)(0x0)(0x0)(0x1)
  (0x22)(0x6b)

●?:如果地址?型??omain name(0x3)的?,第1 byte是域名?度,之後n bytes就是地址



二、源代?
===================

void Launch_TCP( int service_port, const char *udp_proxy_ip, int udp_proxy_port, short *clt_udp_port )
{
//port is NOT network orders

struct sockaddr_in servaddr,clientaddr;
int clientlen;
int listenfd, connfd;
int n;

//定?socket, bind, listen, accept,?於?些操作的?料太多了,不?述
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(service_port);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0) {
p_error("socket error");
exit(-1);
}

if( bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ) {
p_error("bind error");
exit(-1);
}

if( listen(listenfd, 5) < 0 ) {
p_error("listen error");
exit(-1);
}

connfd = accept( listenfd, (struct sockaddr *)&clientaddr, &clientlen );
if( connfd < 0 ) {
p_error("accept error");
exit(-1);
}

printf("< TCP/IP Session - START >\n\n");

//接受第一句?求
n = recv( connfd, buf, BUFSZ, 0 );
debug_showbin( buf, n, "RECV", "\n" );

//目前我??只支持?o身份??的?求,即"05 01 00"
if( buf[0]==0x5 && buf[1]==0x1 && buf[2]==0x0) {
buf[0] = 0x5;
buf[1] = 0x0;

//返回"05 00",代表成功
send( connfd, buf, 2, 0 );
debug_showbin( buf, 2, "SEND", "\n\n" );
} else {
p_error("Session ERROR!\n");
exit(-1);
}

//接受第二句?求
n = recv( connfd, buf, BUFSZ, 0 );
debug_showbin( buf, n, "RECV", "\n" );

//只?理UDP?求(0x03)
if( buf[0]==0x5 && buf[1]==0x3 ) { //Client request a UDP Proxy

short udp_port;
long udp_ip;

//提取?K?Υ嬋?舳說?DP埠?
int seg=4;
if( buf[3] == 0x3 )
seg = buf[4]+1;
memcpy( clt_udp_port, &buf[4+seg], 2 );
*clt_udp_port = ntohs( *clt_udp_port );

buf[0] = 0x5;
buf[1] = 0x0;
buf[2] = 0x0;
buf[3] = 0x1;

//把本?CUDP SOCKET的IP和PORT返回?QQ
udp_ip = inet_addr( udp_proxy_ip );
udp_port = htons( udp_proxy_port );
memcpy( &buf[4], &udp_ip, 4 );
memcpy( &buf[8], &udp_port, 2 );

send(connfd, buf, 10, 0 );
debug_showbin( buf, 10, "SEND", "\n\n" );
} else {
p_error("Session ERROR: Client doesn't need a UDP Proxy!\n");
exit(-1);
}

//握手?程完成
close(connfd);
close(listenfd);

printf("< TCP/IP Session - END >\n\n");
}



三、?y?
===================
1.?在可以先把程序??,?行後程序????ccept()?句搪塞,直至有?求?入.

2.打?QQ,在[系????>???置]中?取使用SOCK5代理,在地址?諤釗?27.0.0.1或localhost,埠填8888,切?要把用?裘?兔艽a?誶蹇?因我??的程序只能?理?o身份??的?求(即握手的第一句??05 01 00"),如果用?裘?兔艽a?誆?榭盞腦?,QQ???l送"05 01 02"至Proxy.

3.按一下[?y?],看看成不成功,再自己研究一下握手的?熱?)


下?本章的源代? → mysock5_2.c





[火星人 ] ?檳愕?Q造一??SOCK5 PROXY(Gcc篇)之二已經有319次圍觀

http://coctec.com/docs/program/show-post-71950.html