LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1108|回复: 7

QQ挂机程序的简单实现.(含部分C代码)

[复制链接]
发表于 2005-8-8 21:00:15 | 显示全部楼层 |阅读模式
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <signal.h>

  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>

  10. #include <stdarg.h>

  11. #include <errno.h>

  12. #include <fcntl.h>


  13. /*我的QQ协议C实现*/
  14. #include "protocol.h"





  15. /* 你的QQ号码.*/
  16. static uint32_t id = 0;
  17. /* 你的QQ密码*/
  18. static char pass[36];
  19. /*在线状态.在protocol.h中定义*/
  20. static int online_status = QQ_ONLINE_NORMAL;
  21. /*QQ客户端实例*/
  22. static struct qq_client * qc = NULL;
  23. /*是否在后台运行*/
  24. static int is_daemon = 0;
  25. /*后台模式日志*/
  26. static int lfd = -1;



  27. /*QQ 服务器.*/
  28. const char *tencent_servers[]  = {
  29.         "219.133.40.173",
  30.         "61.144.238.146",
  31.         "61.144.238.145",
  32.         "202.104.129.251",
  33.         "202.104.129.254",
  34.         "61.141.194.203",
  35.         "61.141.194.203",
  36.         "202.104.129.252",
  37.         "202.104.129.253",
  38.         "202.104.129.253",
  39.         "202.96.170.64",
  40.         "64.144.238.155",
  41.         "202.104.129.254",
  42.         "219.133.40.15",
  43.         "218.17.209.23",
  44.         "218.18.95.153",
  45.         "202.104.129.251",
  46.         "61.144.238.145",
  47.         "202.104.129.253",
  48.         "61.141.194.203",
  49.         "202.104.129.254",
  50.         "218.18.95.165",
  51.         "61.144.238.146",
  52.         "219.133.40.91",
  53.         "211.248.99.252",
  54.         "218.17.217.66",
  55.         "61.144.238.156",
  56.         "219.133.4.89",
  57.         "219.133.40.115",
  58.         "219.133.40.90",
  59.         "219.133.40.113",
  60.         "219.133.40.114",
  61.         "210.22.12.126",
  62.         "61.141.194.223",
  63.         "61.172.249.135",
  64.         "202.104.128.233",
  65.         "202.96.170.164",
  66.         "218.17.217.103",
  67.         "218.66.59.233",
  68.         "61.141.194.207",
  69.         "202.96.170.163",
  70.         "202.96.170.166",
  71.         "202.96.140.18",
  72.         "202.96.140.119",
  73.         "202.96.140.8",
  74.         "202.96.140.12"
  75. };



  76. /*帮助函数*/
  77. void usage(void);
  78. void usage(void)
  79. {

  80.         fprintf(stderr,"\nqqalive usage:\n");
  81.         fprintf(stderr,"qqalive -i <QQ> -p <Password> [-d] [-n|-o|-a|-h] \n");
  82.         fprintf(stderr,"   -i   your QQ number\n");
  83.         fprintf(stderr,"   -p   your QQ password\n");
  84.         fprintf(stderr,"   -n   login in normail mode\n");
  85.         fprintf(stderr,"   -o   login in offline mode\n");
  86.         fprintf(stderr,"   -a   login in away mode\n");
  87.         fprintf(stderr,"   -h   login in invisible mode\n");
  88.         fprintf(stderr,"   -d   daemon background mode\n");
  89.         return;
  90. }


  91. /*推出hook*/
  92. void keepalive_exit(int signo);
  93. void keepalive_exit(int signo)
  94. {

  95.         printf("signal %d recvied exiting ...\n",signo);

  96.         /*登出QQ*/
  97.         qq_logout(qc);
  98.         /*释放资源*/
  99.         qq_release_client(qc);
  100.         qc = NULL;
  101.         exit(0);
  102. }




  103. int main(int argc,char**argv)
  104. {

  105.         char *ip = NULL;
  106.         int  n = 0;
  107.         int  e = 0;
  108.         int i = 0;

  109.         int fd = -1;
  110.         char ch = 0;
  111.         extern char* optarg;
  112.         pid_t pid = 0;
  113.         char tmp[512];
  114.         int port = 6660;


  115.         /*重新生成随机种子*/
  116.         srand(time(0));

  117.         bzero(pass,sizeof(pass));

  118.         while( (ch=getopt(argc,argv,"i:p:dnoah")) != -1 ){

  119.                 switch(ch){
  120.                         case 'i':
  121.                                 id =  atol(optarg);
  122.                                 break;
  123.                         case 'p':
  124.                                 snprintf(pass,16,optarg);
  125.                                 break;
  126.                         case 'd':
  127.                                 is_daemon = 1;
  128.                                 break;
  129.                         case 'n':
  130.                                 online_status = QQ_ONLINE_NORMAL;
  131.                                 break;
  132.                         case 'o':
  133.                                 online_status = QQ_ONLINE_OFFLINE;
  134.                         case 'a':
  135.                                 online_status = QQ_ONLINE_AWAY;
  136.                         case 'h':
  137.                                 online_status = QQ_ONLINE_INVISIBLE;
  138.                                 break;
  139.                         default:
  140.                                 fprintf(stderr,"unrecognized option.\n");
  141.                                 break;
  142.                 }
  143.         }



  144.         if(id==0||pass[0]==0){
  145.                 fprintf(stderr,"option -i and -p must be given.\n");
  146.                 usage();
  147.                 return -EFAULT;
  148.         }


  149.         signal(SIGINT,keepalive_exit);
  150.         signal(SIGTERM,keepalive_exit);
  151.         signal(SIGCHLD,SIG_IGN);


  152.         bzero(tmp,sizeof(tmp));

  153.         if(getenv ("HOME")){
  154.                 sprintf(tmp,"%s/oicq",getenv("HOME"));
  155.         }
  156.         else
  157.         {
  158.                 sprintf(tmp,"oicq");
  159.         }



  160.         if(access(tmp,W_OK)){
  161.                 e = mkdir(tmp,0755);

  162.                 if(e){
  163.                         fprintf(stderr,"failed to create directory %s\n",tmp);
  164.                         return -EFAULT;
  165.                 }
  166.         }


  167.         printf("directory is "%s"\n",tmp);



  168.         if(getenv("HOME")){
  169.                 sprintf(tmp,"%s/oicq/%d",getenv("HOME"),id);
  170.         }
  171.         else
  172.         {
  173.                 sprintf(tmp,"oicq/%d",id);
  174.         }




  175.         if(is_daemon==1){
  176.                 pid = fork();

  177.                 if(pid<0){
  178.                         fprintf(stderr,"failed fork.\n");
  179.                         exit(-1);
  180.                 }

  181.                 if(pid>0){
  182.                         exit(0);
  183.                 }

  184.                 pid = fork();
  185.                 if(pid<0){
  186.                         fprintf(stderr,"failed fork.\n");
  187.                         exit(-1);
  188.                 }

  189.                 if(pid>0){
  190.                         exit(0);
  191.                 }

  192.                 lfd = open(tmp,O_RDONLY|O_WRONLY|O_CREAT,0666);

  193.                 if(lfd<0){
  194.                         fprintf(stderr,"failed to open file - "%s"\n",tmp);
  195.                         return -EFAULT;
  196.                 }

  197.                 printf("log file is - "%s"\n",tmp);
  198.                 close(0);
  199.                 close(1);
  200.                 close(2);

  201.                 dup(lfd);
  202.                 dup(lfd);
  203.                 dup(lfd);


  204.         }


  205.    
  206.         //创建一个新的客户端实例
  207.         qc = qq_create_client();

  208.         if(qc==NULL){
  209.                 fprintf(stderr,"qq_create_client failed.\n");
  210.                 return -EFAULT;
  211.         }


  212.         /*开始挂机*/
  213.         while(1){

  214.                 n = sizeof(tencent_servers)/sizeof(char*);

  215.                 /*随机选择一个服务器*/
  216.                 ip = tencent_servers[rand()%n];

  217.                 printf("select tencent server ip %s\n",ip);

  218.                 //字符形式的号码
  219.                 sprintf(tmp,"%d",id);

  220.                 /*随机选择一个本地UDP倾听端口*/
  221.                 port = 1234+rand()%(65535-1234);


  222.                 //
  223.                 //  -EINVAL  密码错误
  224.                 //  -EFAULT  其他错误
  225.                 //   0  成功
  226.                 e = qq_login(   qc, /*qc*/
  227.                                 tmp,pass,
  228.                                 QQ_LOGIN_MODE_NORMAL,
  229.                                 "0.0.0.0", /*本地地址..一般填0.0.0.0*/
  230.                                 port,      /*本地服务端口.*/
  231.                                 ip,8000);  /*服务器地址和端口*/

  232.                 if(e==0){

  233.                         //成功啦.
  234.                         while(1){
  235.                                 int tcount = 0;
  236.                                 int alive_error = 0;

  237.                                 sleep(5);

  238.                                 qc->online_status = online_status;

  239.                                 qq_change_status(qc);

  240.                                 sleep(5);

  241.                                 e = qq_keep_alive(qc);

  242.                                 if(e){
  243.                                         alive_error++;
  244.                                 }


  245.                                 tcount++;

  246.                                 if( alive_error>4 || tcount>100 ){
  247.                                         qq_change_status(qc);
  248.                                         tcount = 0;
  249.                                         qq_logout(qc);
  250.                                         break;
  251.                                 }
  252.                         }
  253.                 }
  254.                 else
  255.                 {
  256.                         fprintf(stderr,"login failed . retry ...\n");
  257.                         sleep(1);
  258.                 }

  259.         }

  260.         return 0;
  261. }
复制代码
 楼主| 发表于 2005-8-8 21:04:28 | 显示全部楼层
这里贴的代码好像不能缩进..格式变的一踏胡涂
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-8-8 21:28:20 | 显示全部楼层
如果有需要..我可以提供一个编译好的liboicq.a和相关头文件给大家研究.
  
  liboicq.a 中的qq_login函数我加了延迟....希望大家理解.

  大家继续更贴把把...
  Anda.
回复 支持 反对

使用道具 举报

发表于 2005-8-8 23:36:19 | 显示全部楼层
为什么贴代码还遮遮掩掩的?
研究你的这个代码有什么特别的意义吗?
我觉得研究这个,还不如研究openq/lumaqq/eva呢,人家可是什么代码都公开的。
回复 支持 反对

使用道具 举报

发表于 2005-8-9 08:13:03 | 显示全部楼层
或许他是觉得这里的人并是不都需要这个,仅仅是讨论一下这份CODE,那么他贴个大概也就够了。
楼主把思路说一下更好一点,^_^
回复 支持 反对

使用道具 举报

发表于 2005-8-12 16:04:42 | 显示全部楼层
MM,贴点有营养的,论坛的朋友会夸奖你的。这份CODE都是展示如何call 她的func的。
回复 支持 反对

使用道具 举报

发表于 2005-8-12 16:17:51 | 显示全部楼层
装个sniffer,自己抓包研究一个。
回复 支持 反对

使用道具 举报

发表于 2005-8-14 16:19:03 | 显示全部楼层
关键部分都没有~~~~

算了,自己写个吧
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表