LinuxSir.cn,穿越时空的Linuxsir!

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

帮我看看这段代码,受不了了

[复制链接]
发表于 2004-11-30 22:59:55 | 显示全部楼层 |阅读模式
这是从OpenQ上摘出来的加密的代码
在109行调用了41行的encrypt_every_8_byte函数,这个函数的第65行    crypted+=8把crypted移动了8,可是函数调用结束后,crypted又返回了原值。到底是怎么回事阿。

  1. #include <iostream.h>
  2. #include <stdlib.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <netdb.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <sys/types.h>

  10. typedef unsigned char  int8;
  11. typedef unsigned short int16;
  12. typedef unsigned int   int32;

  13. void qq_encipher (
  14.     unsigned long *const        v,
  15.     const unsigned long *const  k,
  16.     unsigned long *const        w)
  17. {
  18.   register unsigned long
  19.     y     = ntohl(v[0]),
  20.     z     = ntohl(v[1]),
  21.                 a     = ntohl(k[0]),
  22.     b     = ntohl(k[1]),
  23.     c     = ntohl(k[2]),
  24.     d     = ntohl(k[3]),
  25.     n     = 0x10,
  26.     sum   = 0,
  27.     delta = 0x9E3779B9; /*  0x9E3779B9 - 0x100000000 = -0x61C88647 */

  28.   while (n-- > 0) {
  29.     sum += delta;
  30.     y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
  31.     z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
  32.   }// while

  33.   w[0] = htonl(y); w[1] = htonl(z);
  34. }// qq_enciper


  35. void encrypt_every_8_byte(
  36.         int                 *pos_in_byte,
  37.         int                 *is_header,
  38.         unsigned char         *plain_pre_8,
  39.         unsigned char        *plain,
  40.         unsigned char        *crypted_pre_8,
  41.         unsigned char        *crypted,
  42.         unsigned char   *key,
  43.         int                *count)
  44. {
  45.     for(*pos_in_byte=0; *pos_in_byte<8; (*pos_in_byte)++) {
  46.       if(*is_header) { plain[*pos_in_byte] ^= plain_pre_8[*pos_in_byte]; }
  47.       else { plain[*pos_in_byte] ^= crypted_pre_8[*pos_in_byte]; }
  48.     } // prepare plain text
  49.     qq_encipher( (unsigned long *) plain,
  50.                               (unsigned long *) key,
  51.                               (unsigned long *) crypted);   // encrypt it
  52.    
  53.     for(*pos_in_byte=0; *pos_in_byte<8; (*pos_in_byte)++) {
  54.       crypted[*pos_in_byte] ^= plain_pre_8[*pos_in_byte];
  55.     }
  56.     memcpy(plain_pre_8, plain, 8);     // prepare next
  57.    
  58.     crypted_pre_8   =   crypted;       // store position of previous 8 byte
  59.     crypted         +=  8;             // prepare next output
  60.     *count           +=  8;             // outstrlen increase by 8
  61.     *pos_in_byte     =   0;             // back to start
  62.     *is_header       =   0;             // and exit header
  63.     printf("crypted=%x\n",crypted);
  64.                   
  65. }// encrypt_every_8_byte

  66. int rand_0(void) {    // it can be the real random seed function
  67.         return 0xdead; }  // override with number, convenient for debug

  68. void qq_encrypt (  
  69.     unsigned char*  instr,
  70.     int             instrlen,
  71.     unsigned char*  key,
  72.     unsigned char*  outstr,
  73.     int            outstrlen_prt)
  74. {
  75.   unsigned char
  76.     plain[8],         // plain text buffer
  77.     plain_pre_8[8],   // plain text buffer, previous 8 bytes
  78.     * crypted,        // crypted text
  79.     * crypted_pre_8,  // crypted test, previous 8 bytes
  80.     * inp;            // current position in instr
  81.   int
  82.     pos_in_byte = 1,  // loop in the byte
  83.     is_header=1,      // header is one byte
  84.     count=0,          // number of bytes being crypted
  85.     padding = 0;      // number of padding stuff
  86.   
  87.   pos_in_byte = (instrlen + 0x0a) % 8; // header padding decided by instrlen
  88.   if (pos_in_byte) {
  89.     pos_in_byte = 8 - pos_in_byte;
  90.   }
  91.   plain[0] = (rand_0() & 0xf8) | pos_in_byte;
  92.   
  93.   memset(plain+1, rand_0()&0xff, pos_in_byte++);
  94.   memset(plain_pre_8, 0x00, sizeof(plain_pre_8));

  95.   crypted = crypted_pre_8 = outstr;
  96.   
  97.   padding = 1; // pad some stuff in header
  98.   while (padding <= 2) { // at most two byte
  99.     if(pos_in_byte < 8) { plain[pos_in_byte++] = rand_0() & 0xff; padding ++; }
  100.     if(pos_in_byte == 8){ encrypt_every_8_byte(&pos_in_byte,&is_header,plain_pre_8,plain,crypted_pre_8,crypted,key,&count);
  101.     printf("crypted=%x\n",crypted);
  102.     }
  103.   }
  104.   
  105.   inp = instr;
  106.   while (instrlen > 0) {
  107.     if (pos_in_byte < 8) { plain[pos_in_byte++] = *(inp++); instrlen --; }
  108.     if (pos_in_byte == 8){ encrypt_every_8_byte(&pos_in_byte,&is_header,plain_pre_8,plain,crypted_pre_8,crypted,key,&count); }
  109.   }

  110.   padding = 1; // pad some stuff in tailer
  111.   while (padding <= 7) { // at most sever byte
  112.     if (pos_in_byte < 8) { plain[pos_in_byte++] = 0x00; padding ++; }
  113.     if (pos_in_byte == 8){ encrypt_every_8_byte(&pos_in_byte,&is_header,plain_pre_8,plain,crypted_pre_8,crypted,key,&count); }
  114.   }
  115.   
  116.   outstrlen_prt = count;
  117. }// qq_encrypt


  118. main()
  119. {
  120.     int8 *key,key_1[]={0xe0,0xcc,0x55,0x76,0xfe,0x4d,0xc6,0x92,0x16,0x17,0xc6,0x97,0x14,0x91,0x1e,0xa7,0x1e};
  121.     key=key_1;
  122.     int8 *outstr=new int8[69];
  123.     int outstrlen_ptr;
  124.     qq_encrypt((int8 *)"",0, key, outstr, outstrlen_ptr);
  125.     printf("this_is_raw_data\n");
  126.     for(int k=0;outstr[k]!='\0';k++)
  127.         printf("%x",outstr[k]);
  128.     printf("\n");
  129. }


复制代码
发表于 2004-12-1 08:47:20 | 显示全部楼层
注意这句:

  1. crypted = crypted_pre_8 = outstr;
复制代码

outstr不是encrypt_every_8_byte函数中定义的变量,是在main函数中定义的。encrypt_every_8_byte函数退出对它的值没有影响,下次调用时,会继续接着上一次进行。
发表于 2004-12-1 08:56:33 | 显示全部楼层
crypted += 8 中的 crypted 是 encrypt_every_8_byte() 中的局域变量,改变它的值只在 encrypt_every_8_byte() 中有效

如果你想在 encrypt_every_8_byte() 中改变 qq_encrypt() 中 crypted 的值,encrypt_every_8_byte() 的参数定义要改成
unsigned char **crypted,
qq_encrypt() 中调用 encrypt_every_8_byte() 时参数要写成
&crypted,
encrypt_every_8_byte() 中赋值要写成
(*crypted) += 8;
发表于 2004-12-1 09:35:42 | 显示全部楼层
最初由 kj501 发表
注意这句:

  1. crypted = crypted_pre_8 = outstr;
复制代码

outstr不是encrypt_every_8_byte函数中定义的变量,是在main函数中定义的。encrypt_every_8_byte函数退出对它的值没有影响,下次调用时,会继续接着上一次进行。

不好意思,没有看清楚代码。感谢doubleelec兄及时纠正。
 楼主| 发表于 2004-12-1 10:17:20 | 显示全部楼层
谢谢阿,原来这就是传说中的指向指针的指针?我在学的时候不太理解这个东东怎么用,原来时这样用的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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