论坛: 编程破解 标题: QQ本地消息破解代码 复制本贴地址    
作者: babyfrog [babyfrog]    论坛用户   登录
/*
* qq decrypt functions, Tencent never modify it since 2001
* original code from pure(青衣~ shadow in silence)'s post at
* Crack@bbs.tsinghua.edu.cn
* Copyright (c) 2001 Shellcode@sina.com.cn
* edited by doublelee@etang.com
*/

#include "qqcrypt.h"

unsigned int swapu32(unsigned int n)
{
// In fact htonl() returns it!
        return(((n & 0xff000000) >> 24) | ((n & 0x000000ff) << 24) |
                ((n & 0x00ff0000) >> 8) | ((n & 0x0000ff00) << 8));
}

unsigned short swapu16(unsigned short n)
{
// In fact swab() returns it!
        return(((n & 0x00ff) << 8) | ((n & 0xff00) >> 8));
}


// added by doublelee
void decrypt_tea_16(unsigned long *in, unsigned long *key, unsigned long *out)
{
// Their is some difference between it and the original TEA routine
// code by David Wheeler and Roger Needham, which can be found on
// http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html

        unsigned long code[4];
        register unsigned long n=16, sum, y, z, delta = 0x9E3779B9;

        sum = delta << 4;
        y = swapu32(in[0]);
        z = swapu32(in[1]);

        code[0] = swapu32(key[0]); code[1] = swapu32(key[1]);
        code[2] = swapu32(key[2]); code[3] = swapu32(key[3]);

        while(n-->0)
        {
                z -= ((y>>5)+code[3])^((y<<4)+code[2])^(sum+y);
                y -= ((z>>5)+code[1])^((z<<4)+code[0])^(sum+z);
                sum -= delta;
        }
        out[0] = swapu32(y);
        out[1] = swapu32(z);
}



void decrypt_qword(unsigned long *in, unsigned long *key, unsigned long *out)
{

        decrypt_tea_16(in, key, out);
// following are pure's code, it is exactly a 16-round TEA
/*
        unsigned long code[4];
        register unsigned long i=16, j=0xe3779B90, m, n;

        m = swapu32(in[0]);
        n = swapu32(in[1]);

        code[0] = swapu32(key[0]); code[1] = swapu32(key[1]);
        code[2] = swapu32(key[2]); code[3] = swapu32(key[3]);

        while(i-- >0)
        {
                n -= ((m>>5)+code[3])^((m<<4)+code[2])^(j+m);
                m -= ((n>>5)+code[1])^((n<<4)+code[0])^(j+n);
                j += 0x61C88647;
        }
        out[0] = swapu32(m);
        out[1] = swapu32(n);
*/
}

int decrypt_msg(unsigned char *in, int inlen, unsigned long *key,
    unsigned char *out, unsigned long *outlen)
{
        unsigned char q[8], mkey[8], *q1, *q2, *outp;
        register int count, i, j, p;

        if (inlen%8 || inlen<16) return 0;
        /* get basic information of the packet */
        decrypt_qword((unsigned long *)in, key, (unsigned long *)q);
        j = q[0]&0x7;
        count = inlen - j - 10;
    //  if (*outlen < count || count < 0) return 0; //?????*outlen
        if (count < 0) return 0;
        *outlen = count;

        memset(mkey, 0, 8);
        q2 = mkey;
        i = 8; p = 1;
        q1 = in+8;
        j ++;
        while (p <= 2) {    //0x004576af
                if (j < 8) { //0x00457648
                        j ++;
                        p ++;
                } else if (j == 8) {
                        q2 = in;
                        for (j = 0; j < 8; j ++ ) {
                                if (i + j >= inlen) return 0;
                                q[j] ^= q1[j];
                        }
                        decrypt_qword((unsigned long *)q, key, (unsigned long *)q);
                        i += 8;
                        q1 += 8;
                        j = 0;
                }
        }
        outp = out;
        while(count !=0) {
                if (j < 8) {
                        outp[0] = q2[j] ^ q[j];
                        outp ++;
                        count --;
                        j ++;
                } else if (j == 8) {
                        q2 = q1-8;
                        for (j = 0; j < 8; j ++ ) {
                                if (i + j >= inlen) return 0;
                                q[j] ^= q1[j];
                        }
                        decrypt_qword((unsigned long *)q, key, (unsigned long *)q);
                        i += 8;
                        q1 += 8;
                        j = 0;
                }
        }
        for (p = 1; p < 8; p ++) {
                if (j < 8) {
                        if (q2[j]^q[j])
                                return 0;
                        j ++;
                } else if (j == 8 ) {
                        q2 = q1;
                        for (j = 0; j < 8; j ++ ) {
                                if (i + j >= inlen) return 0;
                                q[j] ^= q1[j];
                        }
                        decrypt_qword((unsigned long *)q, key, (unsigned long *)q);
                        i += 8;
                        q1 += 8;
                        j = 0;
                }
        }
        return 1;
}

int simple_decrypt(unsigned char *in, unsigned long *key)
{
//  code following comes from qq.asm and pure's code
//  do a quick decryption for QQ key checking, for efficiency of
//  bruteforce cracking
//  assume *in has a length of 16, we try to decrypt it with the key 'key'

unsigned char out[20];
unsigned char q[8], mkey[8], *q1, *q2, *outp;
register int count, i, j, p;
int inlen = 16;

/* get basic information of the packet */
decrypt_tea_16((unsigned long *)in, key, (unsigned long *)q);
j = q[0]&0x7;
count = inlen - j - 10;
if (count) return 0;
//tremendous possibility(7/8) it will return here, so make it quicker when cracking than decrypt_msg().

memset(mkey, 0, 8);
q2 = mkey;
i = 8; p = 1;
q1 = in+8;
j ++;
while (p <= 2)
{
  if (j < 8)
  {
  j ++;
  p ++;
  }
  else if (j == 8)
  {
  q2 = in;
  for (j = 0; j < 8; j ++ )
  {
    if (i + j >= inlen) return 0;
    q[j] ^= q1[j];
  }
  decrypt_tea_16((unsigned long *)q, key, (unsigned long *) q);
  i += 8;
  q1 += 8;
  j = 0;
  }
}
outp = out;
while(count !=0)
{
  if (j < 8)
  {
  outp[0] = q2[j] ^ q[j];
  outp ++;
  count --;
  j ++;
  }
  else if (j == 8)
  {
  q2 = q1-8;
  for (j = 0; j < 8; j ++ )
  {
    if (i + j >= inlen) return 0;
    q[j] ^= q1[j];
  }
  decrypt_tea_16((unsigned long *)q, key, (unsigned long *) q);
  i += 8;
  q1 += 8;
  j = 0;
  }
}
for (p = 1; p < 8; p ++)
{
  if (j < 8)
  {
  if (q2[j]^q[j]) return 0;
  j ++;
  }
  else if (j == 8 )
  {
  q2 = q1;
  for (j = 0; j < 8; j ++ )
  {
    if (i + j >= inlen) return 0;
    q[j] ^= q1[j];
  }
  decrypt_tea_16((unsigned long *)q, key, (unsigned long *) q);
  i += 8;
  q1 += 8;
  j = 0;
  }
}
return 1;
}

// encryption code omitted. we just never use it!

地主 发表时间: 05-01-02 09:20

回复: xubin [xubin]   论坛用户   登录
太多记不住

B1层 发表时间: 05-01-02 20:04

回复: saskatoon [saskatoon]   论坛用户   登录
干什么用?

B2层 发表时间: 05-01-02 22:24

回复: cailiao2 [cailiao2]   论坛用户   登录
好像程序还没结束!

B3层 发表时间: 05-02-19 20:09

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号