tars源码漫谈第18篇------tc_tea.h/tc_tea.cpp(TEA加解密)

      tc_tea中实现的是TEA加解密算法, 业界用TEA还是相对较少的, 但查了一下资料, 发现这个TEA算法历史悠久, 且在工程上是安全的。

      TEA的实现和使用都比AES要简单, 腾讯开源tars用到了这个算法, 看来腾讯有可能很喜欢这个算法, 并广泛使用。

      看一下oi_symmetry_encrypt2,  oi是什么意思? 是oicq的意思, 腾讯qq的来源。

      源码其实不用细看, 无非就是变换而已, 加密,解密。 正所谓过程可能复杂, 但逻辑很简单。

      还是看一下部分源码, 头大, 赶紧闪人:

/*pKey为16byte*/
/*
	输入:pInBuf为需加密的明文部分(Body),nInBufLen为pInBuf长度;
	输出:pOutBuf为密文格式,pOutBufLen为pOutBuf的长度是8byte的倍数;
*/
/*TEA加密算法,CBC模式*/
/*密文格式:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
void TC_Tea::oi_symmetry_encrypt2(const char* pInBuf, size_t nInBufLen, const char* pKey, char* pOutBuf, size_t *pOutBufLen)
{
	size_t nPadSaltBodyZeroLen/*PadLen(1byte)+Salt+Body+Zero的长度*/;
	size_t nPadlen;
	char src_buf[8], iv_plain[8], *iv_crypt;
	size_t src_i, i, j;

	/*根据Body长度计算PadLen,最小必需长度必需为8byte的整数倍*/
	nPadSaltBodyZeroLen = nInBufLen/*Body长度*/+1+SALT_LEN+ZERO_LEN/*PadLen(1byte)+Salt(2byte)+Zero(7byte)*/;
	if((nPadlen=nPadSaltBodyZeroLen%8)) /*len=nSaltBodyZeroLen%8*/
	{
		/*模8余0需补0,余1补7,余2补6,...,余7补1*/
		nPadlen=8-nPadlen;
	}

	/*srand( (unsigned)time( NULL ) ); 初始化随机数*/
	/*加密第一块数据(8byte),取前面10byte*/
//	src_buf[0] = ((char)rand()) & 0x0f8/*最低三位存PadLen,清零*/ | (char)nPadlen;
	src_buf[0] = (((char)rand()) & 0x0f8) | (char)nPadlen;
	src_i = 1; /*src_i指向src_buf下一个位置*/

	while(nPadlen--)
		src_buf[src_i++]=(char)rand(); /*Padding*/

	/*come here, src_i must <= 8*/

	for ( i=0; i<8; i++)
		iv_plain[i] = 0;
	iv_crypt = iv_plain; /*make zero iv*/

	*pOutBufLen = 0; /*init OutBufLen*/

	for (i=1;i<=SALT_LEN;) /*Salt(2byte)*/
	{
		if (src_i<8)
		{
			src_buf[src_i++]=(char)rand();
			i++; /*i inc in here*/
		}

		if (src_i==8)
		{
			/*src_i==8*/

			for (j=0;j<8;j++) /*加密前异或前8个byte的密文(iv_crypt指向的)*/
				src_buf[j]^=iv_crypt[j];

			/*pOutBuffer、pInBuffer均为8byte, pKey为16byte*/
			/*加密*/
			TeaEncryptECB(src_buf, pKey, pOutBuf);

			for (j=0;j<8;j++) /*加密后异或前8个byte的明文(iv_plain指向的)*/
				pOutBuf[j]^=iv_plain[j];

			/*保存当前的iv_plain*/
			for (j=0;j<8;j++)
				iv_plain[j]=src_buf[j];

			/*更新iv_crypt*/
			src_i=0;
			iv_crypt=pOutBuf;
			*pOutBufLen+=8;
			pOutBuf+=8;
		}
	}

	/*src_i指向src_buf下一个位置*/

	while(nInBufLen)
	{
		if (src_i<8)
		{
			src_buf[src_i++]=*(pInBuf++);
			nInBufLen--;
		}

		if (src_i==8)
		{
			/*src_i==8*/

			for (j=0;j<8;j++) /*加密前异或前8个byte的密文(iv_crypt指向的)*/
				src_buf[j]^=iv_crypt[j];
			/*pOutBuffer、pInBuffer均为8byte, pKey为16byte*/
			TeaEncryptECB(src_buf, pKey, pOutBuf);

			for (j=0;j<8;j++) /*加密后异或前8个byte的明文(iv_plain指向的)*/
				pOutBuf[j]^=iv_plain[j];

			/*保存当前的iv_plain*/
			for (j=0;j<8;j++)
				iv_plain[j]=src_buf[j];

			src_i=0;
			iv_crypt=pOutBuf;
			*pOutBufLen+=8;
			pOutBuf+=8;
		}
	}

	/*src_i指向src_buf下一个位置*/

	for (i=1;i<=ZERO_LEN;)
	{
		if (src_i<8)
		{
			src_buf[src_i++]=0;
			i++; /*i inc in here*/
		}

		if (src_i==8)
		{
			/*src_i==8*/

			for (j=0;j<8;j++) /*加密前异或前8个byte的密文(iv_crypt指向的)*/
				src_buf[j]^=iv_crypt[j];
			/*pOutBuffer、pInBuffer均为8byte, pKey为16byte*/
			TeaEncryptECB(src_buf, pKey, pOutBuf);

			for (j=0;j<8;j++) /*加密后异或前8个byte的明文(iv_plain指向的)*/
				pOutBuf[j]^=iv_plain[j];

			/*保存当前的iv_plain*/
			for (j=0;j<8;j++)
				iv_plain[j]=src_buf[j];

			src_i=0;
			iv_crypt=pOutBuf;
			*pOutBufLen+=8;
			pOutBuf+=8;
		}
	}
}

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
-原理实现 在上一篇文章中我们,提到了如何获取到sessionkey,如果对此感兴趣的朋友可以自行到[调试逆向]某Qsessionkey查找完整版查看 首先,就是HOOK掉关键传入sessionkey的地方,也就是Common.dll中的Common.oi_symmetry_encrypt2简单的分析一下参数,就可以看到参数中有sessionkey的指针了。 可以说获得了sessionkey基本所有Q的操作我们都可以实现了 简单的分析一下发送的QQ包下面是已经通过sessionkey解的udp数据包 (1) 00000010000000120801120C08 C8A3C3C906 10E30798010008E50F1001220B58 E2D0F3B40D (2) 00000010000000120801120C08 C8A3C3C906 10E30798010008E50F1001220B58 85F99F9103 (3) 00000010000000120801120C08 E2D0F3B40D 10E30798010008E50F1001220B58 C8A3C3C906 (1)和(2)是相同QQ号发送得点赞请求,那么唯一发生变化得就是对方QQ (2)和(3)不同QQ号发送,上面得5字节也发送了变化,那么有理由相信这就是我的QQ号 发送包分析完了,那就得求得密算法了,QQ转16进制,应该是4字节,而到这里就变成了5字节,那这里一定是密了,到这里我上网查了一些,没自己分析,就不多bb了,等下下载码自己看看得了(python中有句话叫不要重复造轮子,确实不想造) 至此感觉,QQ协议不过如此嘛,简简单单,东拼西凑QQ点赞器就成了?当然并没有 确实刚做好能点赞,但是当我重新登录得时候,奇怪得事情还是发生了(bug),点赞并没有成功,于是我猜想了一下原因: 原本QQ协议一些参数需要重新获取 码本身存在问题 已经被tx察觉 发生ip发生了变化 按照这个调bug思路我走了下去,确实问题发生在了ip上 这不就简简单单,内存中搜索一下不就ok了吗?(你看我这臭毛病,总是喜欢自问自答),但是想在QQ中搜到自己想要的数据几乎不可能,于是还是从函数(win32.api)入手吧! 如果想要发送udp的包,那么一定逃不过下面的api ws2_32.dll.sendto ws2_32.dll.WSASendTo 事实上我们的想法确实是有效的,F2下断在参数中我们就找到了指向ip的指针,使用抓包工具,看看ip,确实是这个ip,至此我们要的所有条件就完成了。 下节我们讲如何获取最新的clientkey(也就是快速登录) 基本内容 老版本clientkey如何获取的 简单的抓包即可实现 新版本会遇到什么问题 本地发包验证 解决思路 拦截http请求,断点调试

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值