首页
社区
课程
招聘
[原创]RTX(腾讯通)本地保存密码TEA变形算法及还原器
发表于: 2012-11-11 12:35 19349

[原创]RTX(腾讯通)本地保存密码TEA变形算法及还原器

2012-11-11 12:35
19349
上月在研究RTX本地保存密码还原,发现是变形的TEA,伪代码如下:
//TEA test program written by HappyTown   [2006-10-10]
#include <stdio.h>
#include <stdlib.h>
#include "winsock2.h"

#pragma comment(lib,"WS2_32.LIB")
#include "tea.h"
//变形TEADec
void myDecrypt(unsigned char *data,unsigned char *key,unsigned char *out);
//变形TEAEnc
void myEncrypt(unsigned char *data,unsigned char *key,unsigned char *out);
//Ecnrypt
void myEncrypt(unsigned char *data,unsigned char *key,unsigned char *out)
{
        int i;
        unsigned int y=0,z=0,a,b,c,d;
        int        e = 0;
        unsigned int sum = 0x61C88647;

        //设置y和z
//        printf("%08X\n",*(DWORD*)data);
//        printf("%08X\n",*(DWORD*)(data+4));
        y =  ntohl(*(DWORD*)data);
        z =  ntohl(*(DWORD*)(data+4));
//        printf("y=%08X z=%08X\n",y,z);
        //变形key设置a,b,c,d值
        a = ntohl(*(DWORD*)(key+0));
        b = ntohl(*(DWORD*)(key+4));
        c = ntohl(*(DWORD*)(key+8));
        d = ntohl(*(DWORD*)(key+12));

//        printf("a=%08X,b=%08X,c=%08X,d=%08X\n",a,b,c,d);
//        printf("%08X %08X %08X\n",(c+(y<<4)),(d+(y>>5)),(c+(y<<4))^(d+(y>>5)));
//        printf("%08X %08X %08X\n",(delta+y),(delta+y) ^ (c+(y<<4))^(d+(y>>5)),z-((delta+y) ^ (c+(y<<4))^(d+(y>>5))));
        //Decrypt
        for(i=0; i<16; i++)
        {
                e -= sum;
                y += (e+z) ^ (a+(z<<4)) ^ (b+(z>>5));
                z += (e+y) ^ (c+(y<<4)) ^ (d+(y>>5));
        }
//        printf("y=%08X z=%08X \n",y,z);

        //output y
        *(DWORD*)out =  ntohl(y);
        //output z
        *(DWORD*)(out+4) = ntohl(z);
        return;
}
//Decrypt
void myDecrypt(unsigned char *data,unsigned char *key,unsigned char *out)
{
        int i;
        unsigned int y=0,z=0,a,b,c,d;
        int        e = 0;
        unsigned int sum = 0x61C88647;
        unsigned delta = 0xE3779B90;

        //设置y和z
//        printf("%08X\n",*(DWORD*)data);
//        printf("%08X\n",*(DWORD*)(data+4));
        y =  ntohl(*(DWORD*)data);
        z =  ntohl(*(DWORD*)(data+4));
//        printf("y=%08X\n",y);
//        printf("z=%08X\n",z);
       
//        printf("a=%08X,b=%08X,c=%08X,d=%08X\n",a,b,c,d);
        //变形key设置a,b,c,d值
        a = ntohl(*(DWORD*)(key));
        b = ntohl(*(DWORD*)(key+4));
        c = ntohl(*(DWORD*)(key+8));
        d = ntohl(*(DWORD*)(key+12));
//        printf("%08X %08X %08X\n",(c+(y<<4)),(d+(y>>5)),(c+(y<<4))^(d+(y>>5)));
//        printf("%08X %08X %08X\n",(delta+y),(delta+y) ^ (c+(y<<4))^(d+(y>>5)),z-((delta+y) ^ (c+(y<<4))^(d+(y>>5))));
        //Decrypt
        for(i=0; i<16; i++)
        {
                z -= (delta+y) ^ (c+(y<<4)) ^ (d+(y>>5));
                e = (delta+z) ^ (a+(z<<4)) ^ (b+(z>>5));
                delta += sum;
                y -= e;
        }
//        printf("y=%08X z=%08X \n",y,z);

        //output y
        *(DWORD*)out =  ntohl(y);
        //output z
        *(DWORD*)(out+4) = ntohl(z);
        return;
}
int main()
{
        int i;
        int runnum = 0;
        int keylen = 40;//暂定密文长40
        unsigned char k[16] = {0x52,0x00,0x54,0x00,0x58,0x00,0x21,0x00,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//128bits key
        //变形密钥
        unsigned char k2[16] = {0x00, 0x54, 0x00, 0x52, 0x00, 0x21, 0x00, 0x58, 0x00, 0x00,
0x00, 0x33, 0x00, 0x00, 0x00, 0x00};//128bits key
        unsigned char data[128] = {0x95, 0x8D, 0x23, 0x06, 0x74, 0xBB, 0x15, 0xDA, 0xC2, 0x6B,
0x0E, 0xFF, 0xE7, 0x0F, 0x6D, 0xE6, 0x88, 0x26, 0x91, 0x1F,
0xBE, 0x68, 0xBE, 0xF0, 0x3E, 0x24, 0x65, 0xBB, 0x53, 0xF0,
0x89, 0x8D, 0xB3, 0xBE, 0xE2, 0xAC, 0xC1, 0x81, 0xBA, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};//plaintext
        unsigned char outEn[128] = {0};        //cipher
        unsigned char temp[128] = {0};
        unsigned char testdata[]={0xD2,0x90,0x2d,0x48,0xd3,0x73,0x00,0x68};

        //以十六进制输出密钥k
        printf("Key is:");
        for (i=0; i<16; i++)
        {
                printf("%02X", k[i]);
        }
        //以十六进制输出密钥k
        printf("\ndata is:");
        for (i=0; i<8; i++)
        {
                printf("%02X", data[i]);
        }
        printf("\n数据解密为:\n");
/*
        //加密明文data,并输出密文
        TEA_Encrypt(outEn, data, k);
        printf("TEA(");
        for (i=0; i<16;i++)
        {
                printf("%02X ", data[i]);
        }
        printf(") is:");
        for (i=0; i<8; i++)
        {
                printf("%02X", outEn[i]);
        }

        printf("\n");
*/
       
        //解密上一步的密文outEn,并输出明文
        myDecrypt(data, k,outEn);//第一次解密
        for (i=0; i<8;i++)
        {
                printf("%02X ", outEn[i]);
        }//加密
        //开始加密
        printf("\n数据加密为:\n");
        myEncrypt(outEn,k,outEn);
        for (i=0; i<8;i++)
        {
                printf("%02X ", outEn[i]);
        }
        //再解密
        printf("\n数据再解密为:\n");
        myDecrypt(outEn,k,outEn);
        for (i=0; i<8;i++)
        {
                printf("%02X ", outEn[i]);
        }
        if(!(outEn[0] & 7))
                return 0;
//        runnum = (40-(outEn[0] & 7) -10);
//        printf("次数:%d %d",runnum,(outEn[0] & 7));
        printf("\n\n");
        system("pause");
        return 0;
}
RTX对本地代码用了随机数填充,多次加密,造成相同密码,密文不一致(密钥用的是“RTX!3”)。另外处理步骤过于复杂,还原密码就直接调用了RTX的Crypt.Dll,还原和加密代码如下(好像和QQ有些算法一致),加解密代码用到了上面的变形算法:
//自定义TEA解密
typedef BOOL (*oi_symmetry_decrypt2) (char *mw,int Len,char *key,char *ret,int *num);
oi_symmetry_decrypt2 mydecrypt2;

//自定义TEA加密
//data 是宽字符
//key 是宽字符
//ret 应该是宽字符,长64位
//num 指向长64位的宽字符
typedef BOOL (*oi_symmetry_encrypt2) (wchar_t *data,int Len,char *key,unsigned char *ret,int *num);
oi_symmetry_encrypt2 myencrypt2;

//查找函数地址
        mydecrypt2 = (oi_symmetry_decrypt2)::GetProcAddress(::LoadLibrary("Crypt.dll"), "oi_symmetry_decrypt2");
        myencrypt2 = (oi_symmetry_encrypt2)::GetProcAddress(::LoadLibrary("Crypt.dll"), "oi_symmetry_encrypt2");
还原密码:
void CRtxPwDlg::OnRead()
{
        // TODO: Add your control notification handler code here
        char key[]={0x52, 0x00, 0x54, 0x00, 0x58, 0x00, 0x21, 0x00, 0x33, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        char ret[1024]={0};
        char buff[1024]={0};
        char filekey[]="strPassword";
        int keylen = 0;
        int num = 1024;

        ::GetPrivateProfileStruct("Default","strPassword",buff,
                64,
                "D:\\rtx.cfg");//注意rtx.cfg在RTX的安装目录下,这里是本机未安装RTX将CFG文件COPY到D盘测试用
        if (2 * wcslen((unsigned short*)buff) >= 64 )
      keylen = 64;
    else
      keylen = 2*wcslen((unsigned short*)buff);

        CString msg;

        msg.Empty();
        //解密
        mydecrypt2(buff,keylen,key,ret,&num);

        for(int j=0;j<64;j++)
        {
                CString temp;
                if(ret[j]!=0x00)
                {
                        temp.Format("%c",ret[j]);
                        msg+=temp;                       
                }
        }
        AfxMessageBox(msg);
}
//加密密码
void CRtxPwDlg::OnWrite()
{
        // TODO: Add your control notification handler code here
        char key[]={0x52, 0x00, 0x54, 0x00, 0x58, 0x00, 0x21, 0x00, 0x33, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        char buff[64] = "123456";
        unsigned char ret[64] = {0};
        int temp = 0;

//        AfxMessageBox(msg);

        //第四个参数为-1时,取得转换需要的大小
        int nLen = MultiByteToWideChar(CP_ACP, 0,buff, -1, NULL, NULL);
        //分配空间
        wchar_t *pwText;
        pwText = new wchar_t[nLen];
        if(!pwText)
                delete[]pwText;
        //转换
        MultiByteToWideChar(CP_ACP,0,buff,-1,pwText,nLen);
       
        CString msg,ls;
        m_Show.Empty();
//        for(int k=1;k<nLen*2;k++)
        {
        myencrypt2(pwText,nLen*2-2,key,ret,&temp);
        msg.Empty();
        for(int i=0;i<64;i++)
        {
                ls.Format("%02X",ret[i]);
                m_Show += ls;
        }
//        AfxMessageBox(m_Show);
        }
        delete[]pwText;
        UpdateData(FALSE);
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 246
活跃值: (91)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
另外,有对北信源研究的朋友可以交流....(有个远程执行功能一直没搞懂...)
2012-11-11 12:49
0
雪    币: 1344
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mms
3
膜拜........这是要爪子奥,公司前一段时间还在使用这玩意.........
2012-11-11 12:55
0
雪    币: 5163
活跃值: (3402)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
厉害 
2012-11-11 16:14
0
雪    币: 15007
活跃值: (4105)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
只能膜拜
2012-11-11 19:10
0
雪    币: 211
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
很好哦,目前PJ的都是16进制修改的,有个注册机就好了
2012-11-16 11:45
0
游客
登录 | 注册 方可回帖
返回
//