600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > rtx 加密机制_[原创]RTX(腾讯通)本地保存密码TEA变形算法及还原器

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

时间:2020-03-02 09:16:02

相关推荐

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

[调试逆向]

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

-11-11 12:35

16367

[调试逆向]

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

-11-11 12:35

16367

上月在研究RTX本地保存密码还原,发现是变形的TEA,伪代码如下:

//TEA test program written by HappyTown [-10-10]

#include

#include

#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

{

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);

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。