概述
要用C语言实现QQ回复,需要以下步骤:
1.手撕QQ协议
鉴于QQ的历史悠久,协议一定经历了N次的更新换代。说不定在你分析的时候协议就更新换代了,这个方案需要精通网络知识,加密知识。能手撕QQ协议的必然是大佬。这就跟写外挂一样,自动打怪的那种,还不需要开客户端的那种,我也只能意淫一下。
2.酷q
显然,我们不需要手撕QQ协议,其实大佬已经帮我们写好了。没错就是COOLQ。
coolq已经完成了协议分析的功能,我们只有给coolq写插件就可以实现自动回复的功能了。
代码如下:
main.c
//======================// main.c//======================#include #include "win32timer.h" // UserTimerSet(uDelay,UserFun)int cnt = 0;void myISR_Called_Per_1000ms(void);int main(void){ /* 每1000ms调用一次myISR_Called_Per_1000ms */ UserTimerSet ( 1000, myISR_Called_Per_1000ms ) ; while (cnt<10); return 0; }void myISR_Called_Per_1000ms(void){ printf("The Program has run %dsn",cnt++);}
3.自然回复
既然分析QQ协议怎么麻烦,我们干脆不分析了,直接抓QQ程序好了。
使用C语言操作QQ程序,就跟一个人使用QQ差不多,这样不久实现了QQ消息的自动回复了吗?
至于如何使用C语言模拟操作想必对于题主来说不在话下。
程序如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
unsigned short checksum(unsigned short *buffer, int size)
{
unsigned long cksum=0;
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if (size)
{
cksum += *(unsigned char *)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (unsigned short)(~cksum);
}
void CalculateCheckSum(
void *iphdr,
struct udphdr *udphdr,
char *payload,
int payloadlen)
{
struct iphdr *v4hdr=NULL;
unsigned long zero=0;
char buf[1000],
*ptr=NULL;
int chksumlen=0,
i;
ptr = buf;
v4hdr = (struct iphdr *)iphdr;
// Include the source and destination IP addresses
memcpy(ptr, &v4hdr->saddr, sizeof(v4hdr->saddr));
ptr += sizeof(v4hdr->saddr);
chksumlen += sizeof(v4hdr->saddr);
memcpy(ptr, &v4hdr->daddr, sizeof(v4hdr->daddr));
ptr += sizeof(v4hdr->daddr);
chksumlen += sizeof(v4hdr->daddr);
// Include the 8 bit zero field
memcpy(ptr, &zero, 1);
ptr++;
chksumlen += 1;
// Protocol
memcpy(ptr, &v4hdr->protocol, sizeof(v4hdr->protocol));
ptr += sizeof(v4hdr->protocol);
chksumlen += sizeof(v4hdr->protocol);
// UDP length
memcpy(ptr, &udphdr->len, sizeof(udphdr->len));
ptr += sizeof(udphdr->len);
chksumlen += sizeof(udphdr->len);
// UDP source port
memcpy(ptr, &udphdr->source, sizeof(udphdr->source));
ptr += sizeof(udphdr->source);
chksumlen += sizeof(udphdr->source);
// UDP destination port
memcpy(ptr, &udphdr->dest, sizeof(udphdr->dest));
ptr += sizeof(udphdr->dest);
chksumlen += sizeof(udphdr->dest);
// UDP length again
memcpy(ptr, &udphdr->len, sizeof(udphdr->len));
ptr += sizeof(udphdr->len);
chksumlen += sizeof(udphdr->len);
// 16-bit UDP checksum, zero
memcpy(ptr, &zero, sizeof(unsigned short));
ptr += sizeof(unsigned short);
chksumlen += sizeof(unsigned short);
// payload
memcpy(ptr, payload, payloadlen);
ptr += payloadlen;
chksumlen += payloadlen;
// pad to next 16-bit boundary
for(i=0 ; i < payloadlen%2 ; i++, ptr++)
{
printf("pad one byten");
*ptr = 0;
ptr++;
chksumlen++;
}
// Compute the checksum and put it in the UDP header
udphdr->check = checksum((unsigned short *)buf, chksumlen);
return;
}
void main()
{
int sock;
unsigned int buffer_size = sizeof(struct iphdr) + sizeof(struct udphdr);
char DNS_Data[] = "x71x79x81x80x00x01"
"x00x02x00x04x00x04x03x77x77x77x03x61x62x63x03x63"
"x6fx6dx00x00x01x00x01xc0x0cx00x05x00x01x00x00x02"
"xe8x00x02xc0x10xc0x10x00x01x00x01x00x00x02xe9x00"
"x04x0axb5x84xfaxc0x10x00x02x00x01x00x00xdaxebx00"
"x0dx06x73x65x6ex73x30x31x03x64x69x67xc0x14xc0x10"
"x00x02x00x01x00x00xdaxebx00x09x06x73x65x6ex73x30"
"x32xc0x4exc0x10x00x02x00x01x00x00xdaxebx00x09x06"
"x6fx72x6ex73x30x31xc0x4exc0x10x00x02x00x01x00x00"
"xdaxebx00x09x06x6fx72x6ex73x30x32xc0x4exc0x75x00"
"x01x00x01x00x00x7ax36x00x04x0axbbxbdx2cxc0x8ax00"
"x01x00x01x00x00x1bx96x00x04x0axbbxbex2cxc0x47x00"
"x01x00x01x00x00x92xb1x00x04x0axb5x86x10xc0x60x00"
"x01x00x01x00x00x92xb1x00x04x0axb5x87xc7";
buffer_size += sizeof(DNS_Data);
unsigned char buffer[buffer_size];
memset (buffer, 0, buffer_size);
struct iphdr *ip = (struct iphdr *)buffer;
struct udphdr *udp = (struct udphdr *)(buffer + sizeof(struct iphdr));
if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP)) == -1) {
perror("socket()");
exit(EXIT_FAILURE);
}
int o = 1;
if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&o,sizeof(o)) == -1) {
perror("setsockopt()");
exit(EXIT_FAILURE);
}
ip->version = 4;
ip->ihl = 5;
ip->id = htonl(random());
ip->saddr = inet_addr("1.0.0.1");
ip->daddr = inet_addr("10.0.0.63");
ip->ttl = 255;
ip->protocol = IPPROTO_UDP;
ip->tot_len = buffer_size;
ip->check = 0;
udp->source = htons(53);
udp->dest = htons(1234);
udp->len = htons(buffer_size - sizeof(struct iphdr));
udp->check = 0;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = udp->source;
addr.sin_addr.s_addr = ip->saddr;
memcpy(buffer+sizeof(struct iphdr) + sizeof(struct udphdr),DNS_Data,sizeof(DNS_Data));
CalculateCheckSum(ip,udp,DNS_Data,sizeof(DNS_Data));
if ((sendto(sock, buffer, buffer_size, 0, (struct sockaddr*)&addr,
sizeof(struct sockaddr_in))) == -1) {
perror("send()");
exit(1);
}
else
printf("OKn");
}
这大概就是用C语言回复QQ信息的三大步骤
最后
以上就是英勇画笔为你收集整理的学用C语言来实现QQ回复的全部内容,希望文章能够帮你解决学用C语言来实现QQ回复所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复