📄 qqproto.c
字号:
#include "sk.h"
#include "qqproto.h"
#include "friendlist.h"
#include "stdio.h"
//TODO add seq check.
unsigned long id;
char passwd[PASSWD_MAX];
unsigned char my_key[KEY_LEN+1];
char b = 0;
unsigned char tpasswd[KEY_LEN];//passwd transformed.
short seq;
unsigned char unknown_data1[]={0xAF,0x41,0x37,0x4B,0x30,0xFB,0x39,0xAC,0x7B,0x24,0xC7,0x6E,0xF3,0x9D,0x61,0x22};
unsigned char rand_data[]={0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad,0xad};
int state = 0;
extern unsigned long local_ip;
extern unsigned char server_ip[16];
int send_logout()
{
unsigned char buffer[512];
unsigned char buf[100];//TODO calc the correct size.
int buflen;
short* pSeq;
unsigned long *pId;
state = ST_LOGOUT;
sub_49EDCF(passwd,strlen((const char*)passwd),my_key,buf,&buflen);
buffer[0] = 2;
buffer[1] = 5;
buffer[2] = 3;
buffer[3] = 0;
buffer[4] = MTYPE_LOGOUT;
pSeq = (short*)&buffer[5];
*pSeq = htons(seq++);
pId = (unsigned long*)&buffer[7];
*pId = htonl(id);
memcpy(&buffer[0xB],buf,buflen);
buffer[0xC + buflen - 1 ] = 3;
return send2server(buffer,0xC + buflen);
}
int send_user_head_pic()
{
unsigned char buffer[512];
unsigned char t[] = "10";// it is default pic number,so can be changed.
unsigned char buf[100];//TODO calc the correct size.
int buflen;
short* pSeq;
unsigned long *pId;
sub_49EDCF(t,strlen((const char*)t),my_key,buf,&buflen);
buffer[0] = 2;
buffer[1] = 5;
buffer[2] = 3;
buffer[3] = 0;
buffer[4] = MTYPE_USER_HEAD_PIC;
pSeq = (short*)&buffer[5];
*pSeq = htons(seq++);
pId = (unsigned long*)&buffer[7];
*pId = htonl(id);
memcpy(&buffer[0xB],buf,buflen);
buffer[0xC + buflen - 1 ] = 3;
return send2server(buffer,0xC + buflen);
}
int send_login()
{
unsigned char buffer[512];
int len;
unsigned char buf1[0x35];//TODO calc the correct size.
int buf1len;
unsigned long* pIP;
unsigned short* pPort;
unsigned long* t;
unsigned short * pSeq;
unsigned long *pId;
sub_49EDCF(NULL,0,tpasswd,buf1,&buf1len);
buf1[0x10] = 0;
pIP = (unsigned long*)&buf1[0x11];
*pIP = local_ip;
pPort = (unsigned short*)&buf1[0x15];
*pPort = htons(DEFAULT_PORT);
t = (unsigned long*)&buf1[0x17];
*t = 5;
t = (unsigned long*)&buf1[0x1B];
*t = 1;
t = (unsigned long*)&buf1[0x1F];
*t = 1;
memcpy(&buf1[0x23],unknown_data1,sizeof(unknown_data1));
buf1[0x33] = 2;
buf1[0x34] = 0xA;
sub_49EDCF(buf1,sizeof(buf1),rand_data,&buffer[0x1B],&len);
buffer[0] = 2;
buffer[1] = 5;
buffer[2] = 3;
buffer[3] = 0;
buffer[4] = MTYPE_LOGIN;
pSeq = (unsigned short*)&buffer[5];
*pSeq = htons(seq++);
pId = (unsigned long*)&buffer[7];
*pId = htonl(id);
memcpy(&buffer[0xB],rand_data,sizeof(rand_data));
buffer[0x5B] = 3;
len += 0x1C;
return send2server(buffer,len);
}
int recv_ack_login(unsigned char* buffer,int len)
{
unsigned char tmp[100];
int l = len - 8;
if( sub_49EFA0(&buffer[0x7],len-8,tpasswd,tmp,&l) == 0)
{
l = len - 8;
sub_49EFA0(&buffer[0x7],len - 8,rand_data,tmp,&l);
bzero(server_ip,sizeof(server_ip));
strncpy(server_ip,inet_ntoa(*((long*)&tmp[5])),sizeof(server_ip));
printf("The server address change to %s\n",server_ip);
send_login();
}
else
{
memcpy(my_key,&tmp[1],KEY_LEN);
my_key[KEY_LEN] = 0;
printf("\nKey String is: %s\n",my_key);
if( state != ST_LOGIN ) printf("DAMN: it is not login phrase when receive login reply packet!\n");
state = ST_RUNNING;
}
return 1;
}
int send_message_through_server(int dstid,const char* message)
{
unsigned char buffer[512];
unsigned char tmp[1024],tmp1[1024],tmpmes[1024];//TODO
unsigned long *pLT;
unsigned short *pST;
int l = 0,l2 = 0;
*((int*)tmp) = htonl(dstid);
memcpy(&tmp[4],my_key,sizeof(my_key));
sub_4A8309(tmp1,tmp,4+sizeof(my_key));
tmp[0] = 5;
tmp[1] = 3;
pLT = (unsigned long*)&tmp[2];
*pLT = htonl(id);
pLT = (unsigned long*)&tmp[6];
*pLT = htonl(dstid);
memcpy(&tmp[0xA],tmp1,0x10);
pST = (unsigned short*)&tmp[0x1A];
*pST = htons(0xB);
pST = (unsigned short*)&tmp[0x1C];
*pST = htons(seq);
pLT = (unsigned long*)&tmp[0x1E];
*pLT = htonl(time(NULL));
pST = (unsigned short*)&tmp[0x22];
*pST = htons(0x8d);
pLT = (unsigned long*)&tmp[0x24];
*pLT = htonl(0);
pLT = (unsigned long*)&tmp1[0];
*pLT = htonl(id);
pLT = (unsigned long*)&tmp1[4];
*pLT = htonl(dstid);
sub_49FE4A(tmp,0x28,&tmp1[8],&l);
memset(tmpmes,0,sizeof(tmpmes));
tmpmes[4] = 1;
memcpy(&tmpmes[5],message,strlen((const char*)message));
sub_49FE4A(tmpmes,5+strlen((const char*)message),&tmp1[8+l],&l2);
sub_49EDCF(tmp1,l+l2+8,my_key,&buffer[0xB],&l);
buffer[0] = 2;
buffer[1] = 5;
buffer[2] = 3;
buffer[3] = 0;
buffer[4] = MTYPE_SEND_MESSAGE_THROUGH_SERVER;
pST = (unsigned short*)&buffer[5];
*pST = htons(seq++);
pLT = (unsigned long*)&buffer[7];
*pLT = htonl(id);
buffer[0xC + l - 1 ] = 3;
return send2server(buffer,l + 0xC);
}
int send_request_friends_list()
{
unsigned char buffer[512];
unsigned char t = 0;
unsigned char buf[200];////TODO calc the correct size.
int buflen;
short* pSeq;
unsigned long *pId;
sub_49EDCF(&t,sizeof(t),my_key,buf,&buflen);
buffer[0] = 2;
buffer[1] = 5;
buffer[2] = 3;
buffer[3] = 0;
buffer[4] = MTYPE_FRIENDS;
pSeq = (short*)&buffer[5];
*pSeq = htons(seq++);
pId = (unsigned long*)&buffer[7];
*pId = htonl(id);
memcpy(&buffer[0xB],buf,buflen);
buffer[0xC + buflen - 1 ] = 3;
return send2server(buffer,0xC + buflen);
}
int recv_ack_logout(unsigned char* buffer,int len)
{
return 1;
}
int recv_ack_user_head_pic(unsigned char* buffer,int len)
{
return 1;
}
int recv_ack_user_send_message_through_server(unsigned char* buffer,int len)
{
return 1;
}
int recv_ack_friends_list(unsigned char* buffer,int len)
{
unsigned char tmp[0x1f*200];//TODO must support very large friends list.
int l = len - 8,i = 0;
sub_49EFA0(&buffer[0x7],len-8,my_key,tmp,&l);
l--;
while(l > 0)
{
add_friend_online(ntohl(*((long*)&tmp[1+i*0x1f])),
*((long*)&tmp[1+i*0x1f+4]),
ntohs(*((short*)&tmp[1+i*0x1f+8])),
&tmp[1 + i*0x1f + 0xe]);
i++;
l -= 0x1f;
}
}
int recv_ack_keep_alive(unsigned char* buffer,int len)
{
state = ST_RUNNING;
return 1;
}
int send_keep_alive()
{
char idstr[0x10];/*TODO */
unsigned char buffer[512];
int len;
unsigned char buf[0x30];
unsigned short* pSeq;
unsigned long * pId;
int buflen;
snprintf(idstr,0x10,"%d",id);
sub_49EDCF(idstr,strlen(idstr),my_key,buf,&buflen);
buffer[0] = 2;
buffer[1] = 5;
buffer[2] = 3;
buffer[3] = 0;
buffer[4] = MTYPE_KEEP_ALIVE;
pSeq = (unsigned short*)&buffer[5];
*pSeq = htons(seq++);
pId = (unsigned long*)&buffer[7];
*pId = htonl(id);
memcpy(&buffer[0xB],buf,buflen);
buffer[0xC + buflen - 1 ] = 3;
state = ST_KEEPALIVE;
return send2server(buffer,0xC + buflen);
}
int recv_message_through_server(unsigned long* pid,char* message,int mlen,unsigned char* buffer,int len)
{
unsigned char tmp[1024],tmp1[1024],tmp2[1024];
unsigned int l,i;
memset(tmp,0,sizeof(tmp));
l = len - 8;
i = 0;
if(sub_49EFA0(&buffer[0x7],len-8,my_key,tmp,&l) == 0) return 0;
snprintf(message,mlen,"%s",&tmp[0x4C]);
*pid = ntohl(*((unsigned long*)&tmp[0]));
return ack_message_through_server(tmp,l);
}
int ack_message_through_server(unsigned char* buffer,int len)
{
unsigned char tmp1[1024],tmp2[1024];
unsigned short * pSeq;
unsigned long *pId;
int l = len;
sub_49EDCF(buffer,0xC,my_key,tmp1,&l);
memcpy(&tmp2[0xB],tmp1,l);
tmp2[0] = 2;
tmp2[1] = 5;
tmp2[2] = 3;
tmp2[3] = 0;
tmp2[4] = MTYPE_RECV_MESSAGE_THROUGH_SERVER;
pSeq = (unsigned short*)&tmp2[5];
*pSeq = htons(seq++);
pId = (unsigned long*)&tmp2[7];
*pId = htonl(id);
tmp2[0xB + l] = 3;
return send2server(tmp2,0xC + l);
}
int send_message_2p(unsigned long dstid,unsigned char* message)
{
unsigned char tmp[0x400],tmp1[0x14],tmp2[0x400];
unsigned char buffer[0x200];
int l,i;
unsigned long t;
*((long*)&tmp1[0]) = htonl(dstid);
memcpy(&tmp1[4],my_key,sizeof(my_key));
sub_4A8309(tmp,tmp1,0x14);
*((unsigned short*)&tmp[0x10]) = htons(0xb);
*((unsigned short*)&tmp[0x12]) = htons(seq++);
*((unsigned long*)&tmp[0x14]) = htonl(time(0));
*((unsigned short*)&tmp[0x18]) = htons(0);//pic num
*((unsigned long*)&tmp[0x1A]) = htonl(0);
*((unsigned long*)&tmp[0x1E]) = htonl(0xdead);//rand
tmp[0x22] = 1;
strncpy((char*)&tmp[0x23],message,sizeof(tmp)-0x23);
l = 5 + strlen(message) + 0x1e + 0x12;
sub_49EDCF(tmp,5+strlen(message)+0x1e,friends_list_query_key(dstid),tmp2,&l);
memcpy(&buffer[0xC],tmp2,l);
tmp[0x20] = 0;
tmp[0x21] = 5;
tmp[0x22] = 3;
tmp[0x23] = 0xad;
t = 0xadadadad; //rand();just memset(buf,0xad,4);
*((unsigned long*)&tmp[0x24]) = ~htonl(id) ^ t;
*((unsigned long*)&tmp[0x28]) = ~htonl(dstid) ^ t;
*((unsigned long*)&tmp[0x2C])= t;
memcpy(buffer,&tmp[0x20],0xc);
for(i = 0; i < 3 ;i++)
l = send2p(dstid,buffer,l + 0xC);
return l;
}
int recv_ack_send_message_2p(unsigned char* buffer,int len)
{
return 1;
}
int recv_message_from_peer(unsigned long* pid,char* message ,int mlen,unsigned char* buffer,int len)
{
int t,l,t2,t3,myID;
unsigned char tmp[100],tmp1[100];
if(len < 0x2A) return 0;
if(buffer[0] != 0) return 0;
memset(&t,buffer[3],4);
t3 = ntohl(*((int*)&buffer[8])) ^ t;
myID = ~t3;
t2 = ~( ntohl(*((int*)&buffer[4])) ^ t);
*((int*)tmp) = *pid = htonl(t2);
memcpy(&tmp[4],my_key,sizeof(my_key));
sub_4A8309(tmp1,tmp,4 + sizeof(my_key));
l = len - 0xC;
sub_49EFA0(&buffer[0xC],len-0xC,tmp1,tmp,&l);
tmp[l] = 0;
strncpy(message,&tmp[0x23],mlen);
return ack_message_from_peer(*pid,buffer,len);
}
int ack_message_from_peer(unsigned long id,unsigned char* buffer,int len)
{
send2p(id,buffer,len);
}
int qqproto_init(unsigned long aid,unsigned char* apasswd)
{
if( state == ST_RUNNING) ;//pls logout first
seq = rand();
id = aid;
memcpy(passwd,apasswd,PASSWD_MAX);
sub_4A8309(tpasswd,passwd,strlen((const char*)passwd));
state = ST_LOGIN;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -