tars源码分析之17

tea可不是茶,而是腾讯采用的一个加密算法,细节不用掌握,知道功能就行:

#include "util/tc_tea.h"
#include <arpa/inet.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>

namespace tars
{

vector<char> TC_Tea::encrypt(const char *key, const char *sIn, size_t iLength)
{
    size_t outlen = 16 + 2*iLength;

    vector<char> v;

    v.resize(outlen);

    oi_symmetry_encrypt(sIn, iLength, key, &v[0], &outlen);

    v.resize(outlen);

    return v;
}

vector<char> TC_Tea::decrypt(const char *key, const char *sIn, size_t iLength)
{
    size_t outlen = 2*iLength;

    vector<char> v;

    v.resize(outlen);

    if (!oi_symmetry_decrypt(sIn, iLength, key, &v[0], &outlen))
    {
        throw TC_Tea_Exception("[TC_Tea::decrypt] decrypt error.");
    }

    v.resize(outlen);

    return v;
}

vector<char> TC_Tea::encrypt2(const char *key, const char *sIn, size_t iLength)
{
    size_t outlen = oi_symmetry_encrypt2_len(iLength);

    vector<char> v;

    v.resize(outlen);

    oi_symmetry_encrypt2(sIn, iLength, key, &v[0], &outlen);

    v.resize(outlen);

    return v;
}

vector<char> TC_Tea::decrypt2(const char *key, const char *sIn, size_t iLength)
{
    size_t outlen = 2*iLength;

    vector<char> v;

    v.resize(outlen);

    if (!oi_symmetry_decrypt2(sIn, iLength, key, &v[0], &outlen))
    {
        throw TC_Tea_Exception("[TC_Tea::decrypt] decrypt error.");
    }

    v.resize(outlen);

    return v;
}

//
const uint32_t DELTA = 0x9e3779b9;

#define SALT_LEN 2

#define ZERO_LEN 7

#define ROUNDS 16

#define LOG_ROUNDS 4

void TC_Tea::TeaEncryptECB(const char *pInBuf, const char *pKey, char *pOutBuf)
{
	uint32_t y, z;
	uint32_t sum;
	uint32_t k[4];
	int i;

	/*plain-text is TCP/IP-endian;*/

	/*GetBlockBigEndian(in, y, z);*/
	y = ntohl(*((uint32_t*)pInBuf));
	z = ntohl(*((uint32_t*)(pInBuf+4)));
	/*TCP/IP network byte order (which is big-endian).*/

	for ( i = 0; i<4; i++)
	{
		/*now key is TCP/IP-endian;*/
		k[i] = ntohl(*((uint32_t*)(pKey+i*4)));
	}

	sum = 0;
	for (i=0; i<ROUNDS; i++)
	{
		sum += DELTA;
		y += (z << 4) + (k[0] ^ z) + (sum ^ (z >> 5)) + k[1];
		z += (y << 4) + (k[2] ^ y) + (sum ^ (y >> 5)) + k[3];
	}

	*((uint32_t*)pOutBuf) = htonl(y);
	*((uint32_t*)(pOutBuf+4)) = htonl(z);

	/*now encrypted buf is TCP/IP-endian;*/
}

void TC_Tea::TeaDecryptECB(const char *pInBuf, const char *pKey, char *pOutBuf)
{
	uint32_t y, z, sum;
	uint32_t k[4];
	int i;

	/*now encrypted buf is TCP/IP-endian;*/
	/*TCP/IP network byte order (which is big-endian).*/
	y = ntohl(*((uint32_t*)pInBuf));
	z = ntohl(*((uint32_t*)(pInBuf+4)));

	for ( i=0; i<4; i++)
	{
		/*key is TCP/IP-endian;*/
		k[i] = ntohl(*((uint32_t*)(pKey+i*4)));
	}

	sum = DELTA << LOG_ROUNDS;
	for (i=0; i<ROUNDS; i++)
	{
		z -= (y << 4) + (k[2] ^ y) + (sum ^ (y >> 5)) + k[3];
		y -= (z << 4) + (k[0] ^ z) + (sum ^ (z >> 5)) + k[1];
		sum -= DELTA;
	}

	*((uint32_t*)pOutBuf) = htonl(y);
	*((uint32_t*)(pOutBuf+4)) = htonl(z);

	/*now plain-text is TCP/IP-endian;*/
}

//
///

/*
	ÊäÈë:pInBufΪÐè¼ÓÃܵÄÃ÷ÎIJ¿·Ö(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_encrypt(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], zero_iv[8], *iv_buf;
	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_i = 1; /*src_iÖ¸Ïòsrc_bufÏÂÒ»¸öλÖÃ*/

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

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

	memset(zero_iv, 0, 8);
	iv_buf = zero_iv; /*make 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++) /*CBC XOR*/
				src_buf[j]^=iv_buf[j];
			/*pOutBuffer¡¢pInBuffer¾ùΪ8byte, pKeyΪ16byte*/
			TeaEncryptECB(src_buf, pKey, pOutBuf);
			src_i=0;
			iv_buf=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 (i=0;i<8;i++) /*CBC XOR*/
				src_buf[i]^=iv_buf[i];
			/*pOutBuffer¡¢pInBuffer¾ùΪ8byte, pKeyΪ16byte*/
			TeaEncryptECB(src_buf, pKey, pOutBuf);
			src_i=0;
			iv_buf=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++) /*CBC XOR*/
				src_buf[j]^=iv_buf[j];
			/*pOutBuffer¡¢pInBuffer¾ùΪ8byte, pKeyΪ16byte*/
			TeaEncryptECB(src_buf, pKey, pOutBuf);
			src_i=0;
			iv_buf=pOutBuf;
			*pOutBufLen+=8;
			pOutBuf+=8;
		}
	}
}

/*
	ÊäÈë:pInBufΪÃÜÎĸñʽ,nInBufLenΪpInBufµÄ³¤¶ÈÊÇ8byteµÄ±¶Êý;
	Êä³ö:pOutBufΪÃ÷ÎÄ(Body),pOutBufLenΪpOutBufµÄ³¤¶È;
	·µ»ØÖµ:Èç¹û¸ñʽÕýÈ··µ»ØTRUE;
*/
/*TEA½âÃÜËã·¨,CBCģʽ*/
/*ÃÜÎĸñʽ:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
bool TC_Tea::oi_symmetry_decrypt(const char* pInBuf, size_t nInBufLen, const char* pKey, char* pOutBuf, size_t *pOutBufLen)
{
	size_t nPadLen, nPlainLen;
	char dest_buf[8];
	const char *iv_buf;
	size_t dest_i, i, j;

	if ((nInBufLen%8) || (nInBufLen<16)) return false;

	TeaDecryptECB(pInBuf, pKey, dest_buf);

	nPadLen = dest_buf[0] & 0x7/*Ö»Òª×îµÍÈýλ*/;

	/*ÃÜÎĸñʽ:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
	i = nInBufLen-1/*PadLen(1byte)*/-nPadLen-SALT_LEN-ZERO_LEN; /*Ã÷Îij¤¶È*/
	if (*pOutBufLen<i) return false;
	*pOutBufLen = i;
	//here it should never success
	//if (*pOutBufLen < 0) return false;

	iv_buf = pInBuf; /*init iv*/
	nInBufLen -= 8;
	pInBuf += 8;

	dest_i=1; /*dest_iÖ¸Ïòdest_bufÏÂÒ»¸öλÖÃ*/

	/*°ÑPaddingÂ˵ô*/
	dest_i+=nPadLen;

	/*dest_i must <=8*/

	/*°ÑSaltÂ˵ô*/
	for (i=1; i<=SALT_LEN;)
	{
		if (dest_i<8)
		{
			dest_i++;
			i++;
		}

		if (dest_i==8)
		{
			/*dest_i==8*/
			TeaDecryptECB(pInBuf, pKey, dest_buf);
			for (j=0; j<8; j++)
				dest_buf[j]^=iv_buf[j];

			iv_buf = pInBuf;
			nInBufLen -= 8;
			pInBuf += 8;

			dest_i=0; /*dest_iÖ¸Ïòdest_bufÏÂÒ»¸öλÖÃ*/
		}
	}

	/*»¹Ô­Ã÷ÎÄ*/

	nPlainLen=*pOutBufLen;
	while (nPlainLen)
	{
		if (dest_i<8)
		{
			*(pOutBuf++)=dest_buf[dest_i++];
			nPlainLen--;
		}
		else if (dest_i==8)
		{
			/*dest_i==8*/
			TeaDecryptECB(pInBuf, pKey, dest_buf);
			for (i=0; i<8; i++)
				dest_buf[i]^=iv_buf[i];

			iv_buf = pInBuf;
			nInBufLen -= 8;
			pInBuf += 8;

			dest_i=0; /*dest_iÖ¸Ïòdest_bufÏÂÒ»¸öλÖÃ*/
		}
	}

	/*УÑéZero*/
	for (i=1;i<=ZERO_LEN;)
	{
		if (dest_i<8)
		{
			if(dest_buf[dest_i++]) return false;
			i++;
		}
		else if (dest_i==8)
		{
			/*dest_i==8*/
			TeaDecryptECB(pInBuf, pKey, dest_buf);
			for (j=0; j<8; j++)
				dest_buf[j]^=iv_buf[j];

			iv_buf = pInBuf;
			nInBufLen -= 8;
			pInBuf += 8;

			dest_i=0; /*dest_iÖ¸Ïòdest_bufÏÂÒ»¸öλÖÃ*/
		}
	}

	return true;
}

//

/*TEA¼ÓÃÜËã·¨,CBCģʽ*/
/*ÃÜÎĸñʽ:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
size_t TC_Tea::oi_symmetry_encrypt2_len(size_t nInBufLen)
{
	size_t nPadSaltBodyZeroLen/*PadLen(1byte)+Salt+Body+ZeroµÄ³¤¶È*/;
	size_t nPadlen;

	/*¸ù¾Ý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;
	}

	return nPadSaltBodyZeroLen+nPadlen;
}

/*pKeyΪ16byte*/
/*
	ÊäÈë:pInBufΪÐè¼ÓÃܵÄÃ÷ÎIJ¿·Ö(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;
		}
	}
}

/*
	ÊäÈë:pInBufΪÃÜÎĸñʽ,nInBufLenΪpInBufµÄ³¤¶ÈÊÇ8byteµÄ±¶Êý; *pOutBufLenΪ½ÓÊÕ»º³åÇøµÄ³¤¶È
		Ìرð×¢Òâ*pOutBufLenÓ¦Ô¤ÖýÓÊÕ»º³åÇøµÄ³¤¶È!
	Êä³ö:pOutBufΪÃ÷ÎÄ(Body),pOutBufLenΪpOutBufµÄ³¤¶È,ÖÁÉÙÓ¦Ô¤ÁônInBufLen-10;
	·µ»ØÖµ:Èç¹û¸ñʽÕýÈ··µ»ØTRUE;
*/
/*TEA½âÃÜËã·¨,CBCģʽ*/
/*ÃÜÎĸñʽ:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
bool TC_Tea::oi_symmetry_decrypt2(const char* pInBuf, size_t nInBufLen, const char* pKey, char* pOutBuf, size_t *pOutBufLen)
{
	size_t nPadLen, nPlainLen;
	char dest_buf[8], zero_buf[8];
	const char *iv_pre_crypt, *iv_cur_crypt;
	size_t dest_i, i, j;
	//const char *pInBufBoundary;
	size_t nBufPos;
	nBufPos = 0;

	if ((nInBufLen%8) || (nInBufLen<16)) return false;

	TeaDecryptECB(pInBuf, pKey, dest_buf);

	nPadLen = dest_buf[0] & 0x7/*Ö»Òª×îµÍÈýλ*/;

	/*ÃÜÎĸñʽ:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
	i = nInBufLen-1/*PadLen(1byte)*/-nPadLen-SALT_LEN-ZERO_LEN; /*Ã÷Îij¤¶È*/

	if ((*pOutBufLen<i)) return false;

	*pOutBufLen = i;

	//pInBufBoundary = pInBuf + nInBufLen; /*ÊäÈ뻺³åÇøµÄ±ß½ç£¬ÏÂÃæ²»ÄÜpInBuf>=pInBufBoundary*/

	for ( i=0; i<8; i++)
		zero_buf[i] = 0;

	iv_pre_crypt = zero_buf;
	iv_cur_crypt = pInBuf; /*init iv*/

	pInBuf += 8;
	nBufPos += 8;

	dest_i=1; /*dest_iÖ¸Ïòdest_bufÏÂÒ»¸öλÖÃ*/

	/*°ÑPaddingÂ˵ô*/
	dest_i+=nPadLen;

	/*dest_i must <=8*/

	/*°ÑSaltÂ˵ô*/
	for (i=1; i<=SALT_LEN;)
	{
		if (dest_i<8)
		{
			dest_i++;
			i++;
		}
		else if (dest_i==8)
		{
			/*½â¿ªÒ»¸öеļÓÃÜ¿é*/

			/*¸Ä±äÇ°Ò»¸ö¼ÓÃÜ¿éµÄÖ¸Õë*/
			iv_pre_crypt = iv_cur_crypt;
			iv_cur_crypt = pInBuf;

			/*Òì»òÇ°Ò»¿éÃ÷ÎÄ(ÔÚdest_buf[]ÖÐ)*/
			for (j=0; j<8; j++)
			{
				if( (nBufPos + j) >= nInBufLen)
				{
					return false;
				}
					
				dest_buf[j]^=pInBuf[j];
			}

			/*dest_i==8*/
			TeaDecryptECB(dest_buf, pKey, dest_buf);

			/*ÔÚÈ¡³öµÄʱºò²ÅÒì»òÇ°Ò»¿éÃÜÎÄ(iv_pre_crypt)*/


			pInBuf += 8;
			nBufPos += 8;

			dest_i=0; /*dest_iÖ¸Ïòdest_bufÏÂÒ»¸öλÖÃ*/
		}
	}

	/*»¹Ô­Ã÷ÎÄ*/

	nPlainLen=*pOutBufLen;
	while (nPlainLen)
	{
		if (dest_i<8)
		{
			*(pOutBuf++)=dest_buf[dest_i]^iv_pre_crypt[dest_i];
			dest_i++;
			nPlainLen--;
		}
		else if (dest_i==8)
		{
			/*dest_i==8*/

			/*¸Ä±äÇ°Ò»¸ö¼ÓÃÜ¿éµÄÖ¸Õë*/
			iv_pre_crypt = iv_cur_crypt;
			iv_cur_crypt = pInBuf;

			/*½â¿ªÒ»¸öеļÓÃÜ¿é*/

			/*Òì»òÇ°Ò»¿éÃ÷ÎÄ(ÔÚdest_buf[]ÖÐ)*/
			for (j=0; j<8; j++)
			{
				if( (nBufPos + j) >= nInBufLen)
				{
					return false;
				}
					
				dest_buf[j]^=pInBuf[j];
			}

			TeaDecryptECB(dest_buf, pKey, dest_buf);

			/*ÔÚÈ¡³öµÄʱºò²ÅÒì»òÇ°Ò»¿éÃÜÎÄ(iv_pre_crypt)*/


			pInBuf += 8;
			nBufPos += 8;

			dest_i=0; /*dest_iÖ¸Ïòdest_bufÏÂÒ»¸öλÖÃ*/
		}
	}

	/*УÑéZero*/
	for (i=1;i<=ZERO_LEN;)
	{
		if (dest_i<8)
		{
			if(dest_buf[dest_i]^iv_pre_crypt[dest_i]) return false;
			dest_i++;
			i++;
		}
		else if (dest_i==8)
		{
			/*¸Ä±äÇ°Ò»¸ö¼ÓÃÜ¿éµÄÖ¸Õë*/
			iv_pre_crypt = iv_cur_crypt;
			iv_cur_crypt = pInBuf;

			/*½â¿ªÒ»¸öеļÓÃÜ¿é*/

			/*Òì»òÇ°Ò»¿éÃ÷ÎÄ(ÔÚdest_buf[]ÖÐ)*/
			for (j=0; j<8; j++)
			{
				if( (nBufPos + j) >= nInBufLen)
				{
					return false;
				}
					
				dest_buf[j]^=pInBuf[j];
			}

			TeaDecryptECB(dest_buf, pKey, dest_buf);

			/*ÔÚÈ¡³öµÄʱºò²ÅÒì»òÇ°Ò»¿éÃÜÎÄ(iv_pre_crypt)*/

			pInBuf += 8;
			nBufPos += 8;
			dest_i=0; /*dest_iÖ¸Ïòdest_bufÏÂÒ»¸öλÖÃ*/
		}
	}

	return true;
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
-原理实现 在上一篇文章中我们,提到了如何获取到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请求,断点调试
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值