LinuxSir.cn,穿越时空的Linuxsir!

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

我想在Win下写第三方QQ软件,打算用C语言,但我始终无法搞懂 协议的 TEA交织填充算法。

[复制链接]
发表于 2005-8-2 11:16:15 | 显示全部楼层 |阅读模式
谁能在C里面写一个加密的过程放上来
我参考了OpenQ的代码改写了Lcc能编译的源文件
但编译后运行发生非法操作??不解不解
又参考了OpenQ的代码和LumaQQ的代码编写了汇编语言的代码
编译后没非法操作但也无法正确编码解码

我不太懂C,望大哥们指教一下,下面是LCC的源程序
#include <windows.h>
#include <string.h>
#include <winsock2.h>

        unsigned char decrypted[8], m[8], *crypt_buff, *crypt_buff_pre_8, *outp;
        int count, context_start, pos_in_byte, padding, _instrlen;
        unsigned char *_key;
        unsigned char testdata = (0xAF,0x2B,0x30,0x0C,0x58,0xD8,0x99,0xD7,0x6E,0xEE,0x0F,0x02,0xB3,0xA6,0x0F,0xF9,0x7E,0x82,0x57,0xDF,0xBD,0xF3,0xF5,0xB9,0x0B,0xA8,0x75,0x45,0xE2,0x48,0xF1,0xB8,0xA0,0x99,0x4B,0xF2,0xF0,0x04,0x22,0x38,0x44,0x2D,0x98,0x8C,0x46,0x42,0x6C,0x19,0x25,0xE4,0x8C,0x42,0xA8,0xE0,0xEB,0xF0,0xD8,0x32,0xFA,0xC2,0x16,0x9E,0x2A,0x95,0x62,0xC9,0xE1,0xAF,0xD4,0x40,0x6D,0xA4,0xFF,0x6A,0xA6,0xC9,0xE6,0xAE,0x35,0x16);
        unsigned char testkey = (01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01);
        unsigned char testout[80];
        int        testoutbytes;

/*****************************************************************************/
void qq_encipher(unsigned long *const v, const unsigned long *const k, unsigned long *const w)
{
        register unsigned long y = ntohl(v[0]), z = ntohl(v[1]), a = ntohl(k[0]), b = ntohl(k[1]), c = ntohl(k[2]), d = ntohl(k[3]), n = 0x10, sum = 0, delta = 0x9E3779B9;        /*  0x9E3779B9 - 0x100000000 = -0x61C88647 */

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

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

/*****************************************************************************/
void qq_decipher(unsigned long *const v, const unsigned long *const k, unsigned long *const w)
{
        register unsigned long y = ntohl(v[0]), z = ntohl(v[1]), a = ntohl(k[0]), b = ntohl(k[1]), c = ntohl(k[2]), d = ntohl(k[3]), n = 0x10, sum = 0xE3779B90,        // why this ? must be related with n value
            delta = 0x9E3779B9;

        /* sum = delta<<5, in general sum = delta * n */
        while (n-- > 0) {
                z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
                y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
                sum -= delta;
        }

        w[0] = htonl(y);
        w[1] = htonl(z);
}                                // qq_decipher

/********************************************************************
* [decrypt part]
* return 0 if failed, otherwise return 1
********************************************************************/
        int decrypt_every_8_byte(void) {
                for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
                        if (context_start + pos_in_byte >= _instrlen)
                                return 1;
                        decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
                }
                qq_decipher((unsigned long *) decrypted, (unsigned long *) _key, (unsigned long *) decrypted);

                context_start += 8;
                crypt_buff += 8;
                pos_in_byte = 0;
                return 1;
        }                        // decrypt_every_8_byte

int qq_decrypt(unsigned char *instr, int instrlen, unsigned char *key, unsigned char *outstr, int *outstrlen_ptr)
{
    _instrlen = instrlen;
        _key = key;
        // at least 16 bytes and %8 == 0
        if ((instrlen % 8) || (instrlen < 16))
                return 0;
        // get information from header
        qq_decipher((unsigned long *) instr, (unsigned long *) key, (unsigned long *) decrypted);
        pos_in_byte = decrypted[0] & 0x7;
        count = instrlen - pos_in_byte - 10;        // this is the plaintext length
        // return if outstr buffer is not large enought or error plaintext length
        if (*outstrlen_ptr < count || count < 0)
                return 0;

        memset(m, 0, 8);
        crypt_buff_pre_8 = m;
        *outstrlen_ptr = count;        // everything is ok! set return string length

        crypt_buff = instr + 8;        // address of real data start
        context_start = 8;        // context is at the second 8 byte
        pos_in_byte++;                // start of paddng stuff

        padding = 1;                // at least one in header
        while (padding <= 2) {        // there are 2 byte padding stuff in header
                if (pos_in_byte < 8) {        // bypass the padding stuff, none sense data
                        pos_in_byte++;
                        padding++;
                }
                if (pos_in_byte == 8) {
                        crypt_buff_pre_8 = instr;
                        if (!decrypt_every_8_byte())
                                return 0;
                }
        }                        // while

        outp = outstr;
        while (count != 0) {
                if (pos_in_byte < 8) {
                        *outp = crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte];
                        outp++;
                        count--;
                        pos_in_byte++;
                }
                if (pos_in_byte == 8) {
                        crypt_buff_pre_8 = crypt_buff - 8;
                        if (!decrypt_every_8_byte())
                                return 0;
                }
        }                        // while

        for (padding = 1; padding < 8; padding++) {
                if (pos_in_byte < 8) {
                        if (crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte])
                                return 0;
                        pos_in_byte++;
                }
                if (pos_in_byte == 8) {
                        crypt_buff_pre_8 = crypt_buff;
                        if (!decrypt_every_8_byte())
                                return 0;
                }
        }                        // for
        return 1;
}                                // qq_decrypt

int main()
{
        int        dwre;

        dwre=qq_decrypt((unsigned char *)testdata,80,(unsigned char *)testkey,(unsigned char *)testout,(int *)testoutbytes);
        return 0;
}


附件里是Masm32的源程序

各位大哥帮帮忙,帮我改改程序,或提供一个可以在VC、LCC、Masm环境下正常工作的编码解码程序啊,谢谢谢谢谢谢~!!!!!!!!!!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 发表于 2005-8-3 11:52:15 | 显示全部楼层
我修改了OpenQ的源代码使其终于可以正常加密解密,有需要者与我联系
QQ27770163

Encrypt.lib
Decrypt.lib
回复 支持 反对

使用道具 举报

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

本版积分规则

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