red_angelxID:Red_angelX
50968次访问,排名1965好友2人,关注者7
Red_angelX的文章
原创 53 篇
翻译 0 篇
转载 3 篇
评论 26 篇
Red_angelX的公告
新Blog:http://www.cnblogs.com/Red_angelX/ CSDN BLOG停用
最近评论
lrongk:怎么没有原码
lqqldj:第一次看此类破解文章,大开眼界,谢谢.
afterruins:能把代码发下麽!学习学习!谢谢啊!
li_zhao_long@126.com
zhangwujian85:怎么下不了啊
pks3000:0Day 是啥?
文章分类
收藏
    相册
    推荐网站
    CodeProject
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 QQ的TEA填充算法C#实现 By Red_angelX收藏

    新一篇: C#编写贪吃蛇游戏 RedSnake | 旧一篇: SafeDel 文件安全删除器alpha

    注:本人只是从LUMA QQ的 Source Code里面把相应Java语言翻译成C#,纯技术研究,并没有对TC产品做任何逆向分析,不承担任何法律责任!转载请保持本文完整性

    网上有c/c++,vb,delphi,java,perl各种版本的tea填充算法,唯独没有C#的,这让我这种狂热喜爱C#的人如何承受,于是,花3天时间看了各种代码经历无数失败的挫折终于用C#完成了该填充算法,废话不多说,直接给代码

     /*********************************************************

    FILE :      QQCrypt.cs

    9.22更正:一处笔误造成解密失败的BUG

                        优化部分代码

    **********************************************************/

     

    using System;

    namespace RedQ
    {
        
    /// <summary>
        
    /// QQ Msg En/DeCrypt Class
        
    /// Writen By Red_angelX On 2006.9.13
        
    /// </summary>

        public class QQCrypt
        
    {    
            
    //QQ TEA-16 Encrypt/Decrypt Class 
            
    // 
            
    // 
            
    //And also LumaQQ//s source code 
            
    //  CopyRight:No CopyRight^_^ 
            
    //  Author : Red_angelX     
            
    //  NetWork is Free,Tencent is ****!
            
    // 
            
    //Class Begin 
            
    //AD:Find Job!!,If you Want Give me a Job,Content Me!!

            
    //Copied & translated from LumaQQ//s source code          `From LumaQQ///s source code: 
            private byte[] Plain;                                   //指向当前的明文块 
            private byte[] prePlain ;                               //指向前面一个明文块 
            private byte[] Out;                                     //输出的密文或者明文 
            private long Crypt, preCrypt;                           //当前加密的密文位置和上一次加密的密文块位置,他们相差8 
            private long Pos;                                       //当前处理的加密解密块的位置 
            private long padding;                                   //填充数 
            private byte[] Key = new byte[16];                      //密钥 
            private bool Header;                                    //用于加密时,表示当前是否是第一个8字节块,因为加密算法 
                                                                    
    //是反馈的,但是最开始的8个字节没有反馈可用,所有需要标 
                                                                    
    //明这种情况 
            private long contextStart;                              //这个表示当前解密开始的位置,之所以要这么一个变量是为了 
                                                                    
    //避免当解密到最后时后面已经没有数据,这时候就会出错,这 
                                                                    
    //个变量就是用来判断这种情况免得出错 
            public QQCrypt()
            
    {
                
    //
                
    // TODO: 在此处添加构造函数逻辑
                
    //
            }

            

            
    //Push 数据
            byte[] CopyMemory(byte[] arr,int arr_index,long input)  //lenth = 4
            {
                
    if(arr_index+4 > arr.Length)
                
    {
                    
    // 不能执行
                    return arr;
                }


                arr[arr_index
    +3]=(byte)((input & 0xff000000>> 24);
                arr[arr_index
    +2]=(byte)((input & 0x00ff0000>> 16);
                arr[arr_index
    +1]=(byte)((input & 0x0000ff00>> 8);
                arr[arr_index]
    =(byte)(input & 0x000000ff);

                arr[arr_index] 
    &= 0xff;
                arr[arr_index
    +1&= 0xff;
                arr[arr_index
    +2&= 0xff;
                arr[arr_index
    +3&= 0xff;

                
    return arr;
            }


            
    long CopyMemory(long Out,byte[] arr,int arr_index)
            
    {
                
    if(arr_index+4 > arr.Length)
                
    {
                    
    return Out;
                    
    //不能执行
                }


                
    long x1 = arr[arr_index+3<< 24;
                
    long x2 = arr[arr_index+2<< 16;
                
    long x3 = arr[arr_index+1<< 8;
                
    long x4 = arr[arr_index];

                
    long o = x1 | x2 | x3 | x4;
                o 
    &= 0xffffffff;
                
    return o;
            }


            
    long getUnsignedInt(byte[] arrayIn, int offset,int len /*Default is 4*/
            
    {

                
    long ret = 0;
                
    int end = 0;
                
    if (len > 8)
                    end 
    = offset + 8;
                
    else
                    end 
    = offset + len;
                
    for (int i = offset; i < end; i++
                
    {
                    ret 
    <<= 8;
                    ret 
    |= arrayIn[i] & 0xff;
                }

                
    return (ret & 0xffffffff| (ret >> 32);
            }


            
    long Rand()
            
    {
                Random rd 
    = new Random();
                
    long ret;
                ret 
    = rd.Next() + (rd.Next() % 1024);
                
    return ret;
            }


            
    private byte[] Decipher(byte[] arrayIn,byte[] arrayKey,long offset)
            
    {
                
    //long Y,z,a,b,c,d;
                long sum,delta;
                
    //Y=z=a=b=c=d=0;
                byte[] tmpArray = new byte[24];
                
    byte[] tmpOut = new byte[8];
                
    if(arrayIn.Length < 8)
                
    {
                    
    // Error:return
                    return tmpOut;
                }

                
    if(arrayKey.Length < 16)
                
    {
                    
    // Error:return
                    return tmpOut;
                }

                sum 
    = 0xE3779B90
                sum 
    = sum & 0xFFFFFFFF
                delta 
    = 0x9E3779B9
                delta 
    = delta & 0xFFFFFFFF
                
    /*tmpArray[3] = arrayIn[offset]; 
                tmpArray[2] = arrayIn[offset + 1]; 
                tmpArray[1] = arrayIn[offset + 2]; 
                tmpArray[0] = arrayIn[offset + 3]; 
                tmpArray[7] = arrayIn[offset + 4]; 
                tmpArray[6] = arrayIn[offset + 5]; 
                tmpArray[5] = arrayIn[offset + 6]; 
                tmpArray[4] = arrayIn[offset + 7]; 
                tmpArray[11] = arrayKey[0]; 
                tmpArray[10] = arrayKey[1]; 
                tmpArray[9] = arrayKey[2]; 
                tmpArray[8] = arrayKey[3]; 
                tmpArray[15] = arrayKey[4]; 
                tmpArray[14] = arrayKey[5]; 
                tmpArray[13] = arrayKey[6]; 
                tmpArray[12] = arrayKey[7]; 
                tmpArray[19] = arrayKey[8]; 
                tmpArray[18] = arrayKey[9]; 
                tmpArray[17] = arrayKey[10]; 
                tmpArray[16] = arrayKey[11]; 
                tmpArray[23] = arrayKey[12]; 
                tmpArray[22] = arrayKey[13]; 
                tmpArray[21] = arrayKey[14]; 
                tmpArray[20] = arrayKey[15]; 
                Y=CopyMemory(Y,tmpArray,0);    
                z=CopyMemory(z,tmpArray,4);
                a=CopyMemory(a,tmpArray,8);
                b=CopyMemory(b,tmpArray,12);
                c=CopyMemory(c,tmpArray,16);
                d=CopyMemory(d,tmpArray,20);
    */

                
    long Y = getUnsignedInt(arrayIn, (int)offset, 4);
                
    long z = getUnsignedInt(arrayIn, (int)offset + 44);
                
    long a = getUnsignedInt(arrayKey, 04);
                
    long b = getUnsignedInt(arrayKey, 44);
                
    long c = getUnsignedInt(arrayKey, 84);
                
    long d = getUnsignedInt(arrayKey, 124);
                
    for(int i=1;i<=16;i++)
                
    {
                    z 
    -= ((Y<<4)+c) ^ (Y+sum) ^ ((Y>>5)+d);
                    z 
    &= 0xFFFFFFFF;
                    Y 
    -= ((z<<4)+a) ^ (z+sum) ^ ((z>>5)+b);
                    Y 
    &= 0xFFFFFFFF;
                    sum 
    -= delta;
                    sum 
    &= 0xFFFFFFFF
                }


                tmpArray 
    = CopyMemory(tmpArray,0,Y);
                tmpArray 
    = CopyMemory(tmpArray,4,z);
                tmpOut[
    0= tmpArray[3]; 
                tmpOut[
    1= tmpArray[2]; 
                tmpOut[
    2= tmpArray[1]; 
                tmpOut[
    3= tmpArray[0]; 
                tmpOut[
    4= tmpArray[7]; 
                tmpOut[
    5= tmpArray[6]; 
                tmpOut[
    6= tmpArray[5]; 
                tmpOut[
    7= tmpArray[4]; 

                
    return tmpOut;    
            }


            
    private byte[] Decipher(byte[] arrayIn,byte[] arrayKey)
            
    {
                
    return Decipher(arrayIn,arrayKey,0);
            }


            
    private byte[] Encipher(byte[] arrayIn,byte[] arrayKey,long offset)
            
    {
                
    byte[] tmpOut = new byte[8];
                
    byte[] tmpArray = new byte[24];
                
    //long Y,z,a,b,c,d;
                
    //Y=z=a=b=c=d=0;
                long sum,delta;
                
    if(arrayIn.Length < 8)
                
    {
                    
    // Error:
                    return tmpOut;
                }

                
    if(arrayKey.Length < 16)
                
    {
                    
    // Error:
                    return tmpOut;
                }

                sum 
    = 0;
                delta 
    = 0x9E3779B9;
                delta 
    &= 0xFFFFFFFF;

                
    /*tmpArray[3] = arrayIn[offset]; 
                tmpArray[2] = arrayIn[offset + 1]; 
                tmpArray[1] = arrayIn[offset + 2]; 
                tmpArray[0] = arrayIn[offset + 3]; 
                tmpArray[7] = arrayIn[offset + 4]; 
                tmpArray[6] = arrayIn[offset + 5]; 
                tmpArray[5] = arrayIn[offset + 6]; 
                tmpArray[4] = arrayIn[offset + 7]; 
                tmpArray[11] = arrayKey[0]; 
                tmpArray[10] = arrayKey[1]; 
                tmpArray[9] = arrayKey[2]; 
                tmpArray[8] = arrayKey[3]; 
                tmpArray[15] = arrayKey[4]; 
                tmpArray[14] = arrayKey[5]; 
                tmpArray[13] = arrayKey[6]; 
                tmpArray[12] = arrayKey[7]; 
                tmpArray[19] = arrayKey[8];
                tmpArray[18] = arrayKey[9]; 
                tmpArray[17] = arrayKey[10]; 
                tmpArray[16] = arrayKey[11]; 
                tmpArray[23] = arrayKey[12]; 
                tmpArray[22] = arrayKey[13]; 
                tmpArray[21] = arrayKey[14]; 
                tmpArray[20] = arrayKey[15]; 

                Y=CopyMemory(Y,tmpArray,0);
                z=CopyMemory(z,tmpArray,4);
                a=CopyMemory(a,tmpArray,8);
                b=CopyMemory(b,tmpArray,12);
                c=CopyMemory(c,tmpArray,16);
                d=CopyMemory(d,tmpArray,20);
    */


                
    long Y = getUnsignedInt(arrayIn, (int)offset, 4);
                
    long z = getUnsignedInt(arrayIn, (int)offset + 44);
                
    long a = getUnsignedInt(arrayKey, 04);
                
    long b = getUnsignedInt(arrayKey, 44);
                
    long c = getUnsignedInt(arrayKey, 84);
                
    long d = getUnsignedInt(arrayKey, 124);

                
    for(int i=1;i<=16;i++)
                
    {
                    sum 
    += delta;
                    sum 
    &= 0xFFFFFFFF;
                    Y 
    += ((z<<4)+a) ^ (z+sum) ^ ((z>>5)+b);
                    Y 
    &= 0xFFFFFFFF;
                    z 
    += ((Y<<4)+c) ^ (Y+sum) ^ ((Y>>5)+d);
                    z 
    &= 0xFFFFFFFF;
                }


                tmpArray 
    = CopyMemory(tmpArray,0,Y);
                tmpArray 
    = CopyMemory(tmpArray,4,z);

                tmpOut[
    0= tmpArray[3]; 
                tmpOut[
    1= tmpArray[2]; 
                tmpOut[
    2= tmpArray[1];
                tmpOut[
    3= tmpArray[0]; 
                tmpOut[
    4=</