|
// MyQQ.cpp: 非完全版本
//////////////////////////////////////////////////////////////////////
#include "QQdef.h"
#include "QQcrypt.h"
#include "winsock2.h"
#include "md5.h"
#include "MyQQ.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
MyQQ::MyQQ()
{
s = NULL;
LoginToken = NULL;
LoginTokenLength = 0;
Status = 0; //下线
IsLogin = false;
LastID = 0;
MessageText = NULL;
FriendListHead = NULL;
FriendListTail = NULL;
send_seq = random() & 0x0000ffff;
LastOnline = time(NULL);
UDPServerNum = 0;
//服务器地址
LoginServer = (char *)malloc(16*sizeof(char));
//QQ号
UserID = 0;
//密码
Password = NULL;
//得到初始化密钥,按2004版
InitKey = (unsigned char*)malloc(QQ_KEY_LENGTH);
int i;
for(i = 0; i < 16; i++)
InitKey = rand();
SessionKey = (unsigned char*)malloc(QQ_KEY_LENGTH);
}
MyQQ::~MyQQ()
{
if(LoginServer != NULL)
free(LoginServer);
if(MyIP != NULL)
free(MyIP);
if(MessageText != NULL)
free(MessageText);
if(Password != NULL)
free(Password);
if(InitKey != NULL)
free(InitKey);
if(PwdKey != NULL)
free(PwdKey);
if(SessionKey != NULL)
free(SessionKey);
if(FriendListHead != NULL)
{
QQFriend *p = FriendListHead->next;
while(p != NULL)
{
free(FriendListHead);
FriendListHead = p;
p = p->next;
}
if(FriendListTail != NULL)
free(FriendListTail);
}
}
void MyQQ::Login(int pMode)
{
unsigned char *buf, *cursor, *raw_data, *encrypted_data;
int seq_ret;
int encrypted_len, bytes;
//登录模式:1 为正常登录,2为隐身登录 ,3登录即离开
LoginMode = pMode;
if(LoginToken == NULL)
{
//发送获取登录令牌的包
qq_get_logintoken();
}
else
{
//2004登录包
buf = (unsigned char*)malloc(MAX_PACKAGE_LENGTH); //包长65535
raw_data = (unsigned char*)malloc(QQ_LOGIN_DATA_LENGTH); //数据长
encrypted_data = (unsigned char*)malloc(QQ_LOGIN_DATA_LENGTH + 16); //加密数据长度多16
// 产生密文
// 000-015 用PwdKey加密空串
MCrypter.qq_crypt(ENCRYPT, (unsigned char*)"", 0, PwdKey, raw_data, &encrypted_len);
//016-051 36字节的固定内容
memmove(raw_data + 16, login_16_51, 36);
//052-052 登录方式
raw_data[52] = (unsigned char)LoginMode;
//053-068 16字节固定内容
memmove(raw_data + 53, login_53_68, 16);
//069 登录令牌长度
int pos = 69;
raw_data[pos++] = (unsigned char)LoginTokenLength;
//070-? 登录令牌
memmove(raw_data + pos, LoginToken, LoginTokenLength);
pos += LoginTokenLength;
//未知字节0x40
raw_data[pos++] = 0x40;
//固定字节
memmove(raw_data + pos, LOGIN_SEGMENTS, 100);
pos += 100;
//剩下的字节填零
for(; pos < QQ_LOGIN_DATA_LENGTH; pos++)
raw_data[pos] = 0x00;
//加密
MCrypter.qq_crypt(ENCRYPT, raw_data, QQ_LOGIN_DATA_LENGTH, InitKey, encrypted_data, &encrypted_len);
cursor = buf;
bytes = 0;
bytes += create_packet_head_seq(buf, &cursor, QQ_CMD_LOGIN, true, &seq_ret);
bytes += create_packet_dw(buf, &cursor, UserID);
bytes += create_packet_data(buf, &cursor, InitKey, QQ_KEY_LENGTH);
bytes += create_packet_data(buf, &cursor, encrypted_data, encrypted_len);
bytes += create_packet_b(buf, &cursor, QQ_PACKET_TAIL);
if (bytes == (cursor - buf)) //包被无误创建
{
qq_send_packet(buf, bytes, QQ_CMD_LOGIN);
}
free(buf);
free(raw_data);
free(encrypted_data);
}
}
//从包中读取一个字节
int MyQQ::read_packet_b(unsigned char * buf, unsigned char ** cursor, int buflen, unsigned char * b)
{
if(*cursor <= buf + buflen - sizeof(*b))
{
*b = **(unsigned char **) cursor;
*cursor += sizeof(*b);
return sizeof(*b);
}
else
return -1;
}
//从包中读取一个字
int MyQQ::read_packet_w(unsigned char * buf, unsigned char ** cursor, int buflen, short * w)
{
if(*cursor <= buf + buflen - sizeof(*w))
{
*w = ntohs(**(short **) cursor);
*cursor += sizeof(*w);
return sizeof(*w);
} else
return -1;
}
//处理收到的消息
void MyQQ::qq_process_recv_im(unsigned char* buf, int buf_len, short seq)
{
int len, bytes;
unsigned char *data, *cursor;
qq_recv_im_header *im_header;
len = buf_len;
data = (unsigned char *)malloc(len);
if (MCrypter.qq_crypt(DECRYPT, buf, buf_len, SessionKey, data, &len))
{
if(len < 16)
return;
else
qq_send_packet_recv_im_ack(seq, data);
cursor = data;
bytes = 0;
im_header = (qq_recv_im_header *)malloc(sizeof(qq_recv_im_header));
bytes += read_packet_dw(data, &cursor, len, &(im_header->sender_uid));
bytes += read_packet_dw(data, &cursor, len, &(im_header->receiver_uid));
bytes += read_packet_dw(data, &cursor, len, &(im_header->server_im_seq));
bytes += read_packet_data(data, &cursor, len, (unsigned char *) & (im_header->sender_ip), 4);
bytes += read_packet_w(data, &cursor, len, &(im_header->sender_port));
bytes += read_packet_w(data, &cursor, len, &(im_header->im_type));
if (bytes != 20) { // im_header的长度
return;
}
if (im_header->receiver_uid != UserID)
{
return;
}
LastID = im_header->sender_uid;
switch (im_header->im_type)
{
case QQ_RECV_IM_TO_BUDDY:
qq_process_recv_normal_im(data, &cursor, len);
break;
case QQ_RECV_IM_TO_UNKNOWN:
qq_process_recv_normal_im(data, &cursor, len);
break;
case QQ_RECV_IM_GROUP_IM:
//qq_process_recv_group_im(data, &cursor, len, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_ADD_TO_GROUP:
//qq_process_recv_group_im_been_added(data, &cursor, len, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_DEL_FROM_GROUP:
//qq_process_recv_group_im_been_removed(data, &cursor, len, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_APPLY_ADD_TO_GROUP:
//qq_process_recv_group_im_apply_join(data, &cursor, len, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_APPROVE_APPLY_ADD_TO_GROUP:
//qq_process_recv_group_im_been_approved(data, &cursor, len, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_REJCT_APPLY_ADD_TO_GROUP:
//qq_process_recv_group_im_been_rejected(data, &cursor, len, im_header->sender_uid, gc);
break;
case QQ_RECV_IM_SYS_NOTIFICATION:
//_qq_process_recv_sys_im(data, &cursor, len, gc);
break;
default:
break;
}// switch
}
}
| 利用BCB自己打造QQ炸弹 | 10-23 |
| 从内存中加载并启动一个exe(delp | 09-27 |
| 开启和关闭Windows xp 防火墙(de | 09-27 |
| 让你的程序通过XP防火墙(delphi编 | 09-27 |
| 如何让你的程序安全通过windows防 | 08-20 |
| 如何透过程序来控制 Windows (XP | 08-20 |
| 动易2005-2006算号器的源代码 | 08-11 |
| API对注册表进行操作(Delphi编程 | 07-30 |
| 一段隐藏注册表项的代码 | 07-26 |
| 了解VB编写病毒的大体方法 | 07-02 |
| 每秒4W的DDOS源码 | 06-08 |
| 从内存中加载并启动一个exe(Delp | 06-05 |