您现在的位置:好股网 >> 股票资讯 >> 股票知识
股票资讯分类导航
股票入门 股票知识 炒股经验 股市实战
精品股票资讯
更多>>
本文好评率100%

通达信登录原理及登录BUG

出处:本站整理时间:2010-11-15 08:58:00人气:
Tags:

免责声明

仅供学习交流之用,请在下载后24小时内删除!不得用于公共场所及商业盈利行为和无限散布,本人将不对所提供的软件或资源负任何民事或刑事法律责任。用户下载需承担一切因您的行为而直接或间接导致的民事或刑事法律责任。对您下载文件后造成的任何问题本人不负任何民事或刑事法律责任!


声明:仅供学习交流之用,如果利用本原理获得非法收入或触犯法律,本人概不对你做的任何后果负责,请慎重!
注:之前声明过通达信终结版,今天也不会提供任何程序,仅提供原理及部分代码,仅供交流学习之用.

先简单说明下通达信的登录过程:

简写:客户机 (C) 验证服务器 (Sy) 行情服务器 (Sh)
C=====1===>Sy
Sy====2====>C
(BUG1)这里有个致命BUG,通达信报文是进行了时间加密,但如果发送报文固定后,返回报文默认提示非法,但懂汇编的朋友,这里跳过非法提示这里就可以正常登录了。
说到这里好多人会问,BUG在哪儿?
不要着急^_^ 慢慢来。
如果多人同时用一个帐号登录,通达信sy后台有判断,会进行封号处理,同时会互相踢人!
如果把这个返回的报文放到自己网站(免费的均可),自己写程序再从这个网站获取该报文修改通达信返回报文,这样就可以一号多用,同时不会被通达信发觉(sh没有验证帐号机制)。
C====3====>Sh
Sh===4====>C
C+Sy返回的验证=====5===>Sh (初始化报文)
Sy返回的验证解释:就是Sy====2====>C返回报文通达信进行逆向计算报文获得的一个16进制值,如果这个值和SY值一致这里就能成功初始化。
Sh===6====>C(如果对Sh返回给C,否Sh则断开SOCKET,此报文中含有时间字段~)
....//中间几个报文未进行验证就不一一写了。
C+Sy返回的验证=====11===>Sh (初始化通知报文)
Sh===12====>C(如果对Sh返回给C,否则Sh断开SOCKET)

如果开启深圳10档,登录后还有个深圳10档行情的验证报文,如果报文非法就看不到行情数据。
(每天更换一次,并有规律变化,因为目前验证机制还是这样,我这里就不提供源码了)
(BUG2)也就是说这3个验证的值,正版号通过通达信程序获得,写到文件存放到网站上,特别版版程序获取这个验证字段,分别写入报文里,就可以成功合法登录。
即可以实现一号多用。


08年终结版封后,其实这个BUG到现在一直存在着!
通达信中间是进行了几次升级:
针对(BUG2)升级1:通达信修改了验证值的算法,之前算法每10分钟规律变一次,现改成随机变化。
(这样特别版就很简单,只用知道月初的第一个验证值进行计算就可以得到实时验证数字,就可以直接登录)
附:当时用月初验证值计算当时验证值的算法,现在已经无效!
int x;//C+Sy返回的验证=====5===>Sh (初始化报文月初验证值)
int y;//C+Sy返回的验证=====11===>Sh(通知报文月初验证值)
int m;//今天0时到现在变化次数。
GetLocalTime(<);
m=lt.wHour*6+lt.wMinute/10;
for(int t=0;t<(lt.wDay-1);t++)//计算出今天0时的验证值
{
if(x+3>120)x=x-95;
else x=x+3;

if(y+4>120)y=y-89;
else y=y+4;
}
for(int n=0;n<m;n++)//计算出现在的验证值
{
if(x+5>120)x=x-95;
else x=x+5;

if(y+11>119)y=y-89;
else y=y+11;
}
针对(BUG2)升级2:通达信进行IP链接次数限制,达到一定次数就会封IP。
(如果没有正版号可以自己写程序伪装程序给通达信发报文来获取这个验证值。由于封IP,
这样就限制了固定IP用户,但对ADSL这种做法其实无效的,封了IP,断开一次ADSL即可实现继续
扫描该值,自然可以正常登录)
附:扫描验证值的程序,现在已经基本无效!
static DWORD WINAPI ConnectTest(LPVOID lp)//线程获取服务器IP延时
{
int time1=0;
int time2=0;
int time11=0;
int time22=0;
int times=0;
char *Ip=((INFO*)lp)->Ip;
BYTE sendtest[]={0x0C,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x15,0x00};
char recvBuf[500]={0};

SYSTEMTIME st;

WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1,1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {return 0;}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ){
WSACleanup();
return 0;
}

SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr(Ip);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(7709);
connect(sockSrv,(SOCKADDR *)&addrSrv,sizeof(SOCKADDR));
if(10060 != WSAGetLastError())
{
GetLocalTime(&st);
time1=st.wMilliseconds;
time11=st.wSecond;
send(sockSrv,(const char *)sendtest,12,0);
recv(sockSrv,(char *)recvBuf,500,0);
GetLocalTime(&st);
time2=st.wMilliseconds;
time22=st.wSecond;
times=time2-time1+(time22-time11)*1000;

}
closesocket(sockSrv);
((INFO*)lp)->Time=times;
return 0;
}
void ConnectTDX(char *ip_pp)//扫描TDX服务器获取验证值
{
BYTE tcsend1[]={发送报文1,我这里省略,正版就能获取着几个报文}
BYTE tcsend2[]={发送报文2,我这里省略}
BYTE tcsend3[]={发送报文3,我这里省略}
char recvBuf[500]={0};
if(1 != tdxsock2)
{

WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1,1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {return;}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ){
WSACleanup();
return;
}

SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr(ip_pp);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(7709);
connect(sockSrv,(SOCKADDR *)&addrSrv,sizeof(SOCKADDR));

send(sockSrv,(const char *)tcsend1,42,0);
Sleep(10);

memset(recvBuf,0,500);
recv(sockSrv,recvBuf,70,0);
//if(10060 == WSAGetLastError())
if(recvBuf[0] == 0)
{
tdxsock2=0;
}

if(10060 != WSAGetLastError() && recvBuf[0] != 0)
{
if(0 == tdxsock1)
{
tcsend2[12]=(unsigned char)i;
i++;
}
send(sockSrv,(const char *)tcsend2,13,0);
Sleep(10);
memset(recvBuf,0,500);
recv(sockSrv,(char *)recvBuf,205,0);

//if(10060 == WSAGetLastError())
if(recvBuf[0] == 0)
{
tdxsock1=0;
}

if(10060 != WSAGetLastError() && recvBuf[0] != 0)
{
tdxsock1=1;
tcsend3[29]=(unsigned char)j;
j=j+1;
send(sockSrv,(const char *)tcsend3,42,0);
Sleep(10);

memset(recvBuf,0,500);
recv(sockSrv,(char *)recvBuf,195,0);

if(10060 != WSAGetLastError() && recvBuf[0] != 0)
tdxsock2=1;
}

}
closesocket(sockSrv);
}
}
struct INFO //存储IP地址及该IP延时时间。
{
int Time=0;
char Ip[17];
} ;
int tdxsock1=0;//初始化验证值是否有效标志
int tdxsock2=0;//提取通知验证值是否有效标志

INFO *ip1=new INFO;
INFO *ip2=new INFO;
INFO *ip3=new INFO;
INFO *ip4=new INFO;
INFO *ip5=new INFO;
INFO *ip6=new INFO;
INFO *ip7=new INFO;
INFO *ip8=new INFO;
INFO *ip9=new INFO;
INFO *ipA=new INFO;
INFO *ipB=new INFO;
INFO *ipC=new INFO;
INFO *ipD=new INFO;
//读取配置文件IP
GetPrivateProfileString("IPADDR","IP1",NULL,ip1->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IP2",NULL,ip2->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IP3",NULL,ip3->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IP4",NULL,ip4->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IP5",NULL,ip5->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IP6",NULL,ip6->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IP7",NULL,ip7->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IP8",NULL,ip8->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IP9",NULL,ip9->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IPA",NULL,ipA->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IPB",NULL,ipB->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IPC",NULL,ipC->Ip,16,".\\TdxWSrv.CFG");
GetPrivateProfileString("IPADDR","IPD",NULL,ipD->Ip,16,".\\TdxWSrv.CFG");

//线程测试IP延时
HANDLE hThread1=CreateThread(NULL,0,ConnectTest,(LPVOID)ip1,0,NULL);
HANDLE hThread2=CreateThread(NULL,0,ConnectTest,(LPVOID)ip2,0,NULL);
HANDLE hThread3=CreateThread(NULL,0,ConnectTest,(LPVOID)ip3,0,NULL);
HANDLE hThread4=CreateThread(NULL,0,ConnectTest,(LPVOID)ip4,0,NULL);
HANDLE hThread5=CreateThread(NULL,0,ConnectTest,(LPVOID)ip5,0,NULL);
HANDLE hThread6=CreateThread(NULL,0,ConnectTest,(LPVOID)ip6,0,NULL);
HANDLE hThread7=CreateThread(NULL,0,ConnectTest,(LPVOID)ip7,0,NULL);
HANDLE hThread8=CreateThread(NULL,0,ConnectTest,(LPVOID)ip8,0,NULL);
HANDLE hThread9=CreateThread(NULL,0,ConnectTest,(LPVOID)ip9,0,NULL);
HANDLE hThreadA=CreateThread(NULL,0,ConnectTest,(LPVOID)ipA,0,NULL);
HANDLE hThreadB=CreateThread(NULL,0,ConnectTest,(LPVOID)ipB,0,NULL);
HANDLE hThreadC=CreateThread(NULL,0,ConnectTest,(LPVOID)ipC,0,NULL);
HANDLE hThreadD=CreateThread(NULL,0,ConnectTest,(LPVOID)ipD,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
CloseHandle(hThread4);
CloseHandle(hThread5);
CloseHandle(hThread6);
CloseHandle(hThread7);
CloseHandle(hThread8);
CloseHandle(hThread9);
CloseHandle(hThreadA);
CloseHandle(hThreadB);
CloseHandle(hThreadC);
CloseHandle(hThreadD);
Sleep(3000);//等待测试链接速度线程返回,如果超过3秒,ip(X)->Time > 0 过滤。
for(;i<255 && j<255;)//为了避免IP被封单线程轮流扫描,同时提供速度,把IP延时高的过滤掉。
{

if(ip1->Time < 3000 && ip1->Time > 0) ConnectTDX(ip1->Ip);
if(1 ==tdxsock2) break;
if(ip2->Time < 3000 && ip2->Time > 0) ConnectTDX(ip2->Ip);
if(1 ==tdxsock2) break;
if(ip3->Time < 3000 && ip3->Time > 0) ConnectTDX(ip3->Ip);
if(1 ==tdxsock2) break;
if(ip4->Time < 3000 && ip4->Time > 0) ConnectTDX(ip4->Ip);
if(1 ==tdxsock2) break;
if(ip5->Time < 3000 && ip5->Time > 0) ConnectTDX(ip5->Ip);
if(1 ==tdxsock2) break;
if(ip6->Time < 3000 && ip6->Time > 0) ConnectTDX(ip6->Ip);
if(1 ==tdxsock2) break;
if(ip7->Time < 3000 && ip7->Time > 0) ConnectTDX(ip7->Ip);
if(1 ==tdxsock2) break;
if(ip8->Time < 3000 && ip8->Time > 0) ConnectTDX(ip8->Ip);
if(1 ==tdxsock2) break;
if(ip9->Time < 3000 && ip9->Time > 0) ConnectTDX(ip9->Ip);
if(1 ==tdxsock2) break;
if(ipA->Time < 3000 && ipA->Time > 0) ConnectTDX(ipA->Ip);
if(1 ==tdxsock2) break;
if(ipB->Time < 3000 && ipB->Time > 0) ConnectTDX(ipB->Ip);
if(1 ==tdxsock2) break;
if(ipC->Time < 3000 && ipC->Time > 0) ConnectTDX(ipC->Ip);
if(1 ==tdxsock2) break;
if(ipD->Time < 3000 && ipD->Time > 0) ConnectTDX(ipD->Ip);
if(1 ==tdxsock2) break;
}
i--;//(正确的初始化验证值)
j--;//(正确的通知验证值)
剩下的就是写入通达信对应发报里就可以正常登录。
TdxWSrv.CFG 配置文件内容:
[IPADDR]
IP1=61.135.142.90
IP2=123.129.245.200
IP3=59.175.238.41
IP4=119.147.86.166
IP5=119.147.86.162
IP6=113.105.73.82
IP7=61.152.168.227
IP8=61.152.168.232
IP9=124.127.97.197
IPA=123.129.245.202
IPB=114.255.100.100
IPC=210.51.55.212
IPD=59.175.238.40

针对(BUG2)升级3:应该就这几天升级了sy,凡是一次向sh发送非法报文,该IP就会被封。
(如果用正版号获取该验证值,并10分钟上传一次,写入通达信对应发送报文里就可以正常登录。)
 

对我有用(88)对我没用(0)