QQ数据包解密

news2025/2/23 7:16:57

Windows版qq数据包格式:
在这里插入图片描述

android版qq数据包格式:

在这里插入图片描述

密钥:16个0

算法:tea_crypt算法

pc版qq 0825数据包解密源码:

#include "qq.h"
#include "qqcrypt.h"
#include <WinSock2.h>
#include "../public.h"
#include "../ProtocolParser.h"
#include "../ResultFile.h"
#include "../fileOper.h"
#include <windows.h>


int QQ::isQQ(const char * data, int len, DATALISTHEADER hdr) {
	if (hdr.sock.protocol == 0x11 )
	{
		if ( hdr.sock.dstport == 8000)
		{
			int firstsize = hdr.sizelist->size;
			if (hdr.datalist->data[0] == 0x02 && hdr.datalist->data[firstsize-1] == 0x03 )
			{
				return TRUE;
			}
		}
	}
	return FALSE;
}




int QQ::processQQ(LPDATABLOCKLIST list, LPPACKSIZELIST sizelist, DATALISTHEADER hdr) {
	int ret = 0;

	char lpbuf [0x1000];
	int offset = 0;
	while (list && sizelist)
	{
		int len = DataBlockList::getNextPacket(list, offset, sizelist, (char*)lpbuf);
		if (len > 0)
		{
			QQHEADER * qqhdr = (QQHEADER*)(lpbuf + 1);
			if (qqhdr->cmd == 0x2508)
			{
				int pad = sizeof(QQHEADER) ;
				if (memcmp(lpbuf + 1 + pad, "\x03\x00\x00\x00", 4) == 0)//010101
				{
					pad += 15;
				}else if (memcmp(lpbuf + 1 + pad,"\x00\x00\x00",3) == 0)
				{
					pad += 15;
				}
				char * offset = lpbuf + 1 + pad;
				int size = len - 1 - pad - 1 ;

				unsigned char *key = (unsigned char*)offset;

				int decodelen = size + 1024;
				unsigned char *decodebuf = new unsigned char[size + 1024];

				int ret = qq_decrypt((unsigned char*)offset + 16, size - 16, key, decodebuf, &decodelen);
				if (ret > 0)
				{
					Public::WriteDataFile("qq.dat", (const char*)decodebuf, decodelen);
				}

				delete decodebuf;

				char szqq[16];
				sprintf(szqq, "%u", ntohl(qqhdr->qq));
				ResultFile::writeRecord(hdr, "qq", "on", szqq);
			}
// 			else if (qqhdr->cmd == 0x3608)
// 			{
// 				char szqq[16];
// 				sprintf(szqq, "%u", ntohl(qqhdr->qq));
// 				ResultFile::writeRecord(hdr, "qq", "on", szqq);
// 			}
		}
		else {

// 			string fn = ProtocolParser::formatfn(hdr, "qq_error");
// 			ret = ProtocolParser::writeBlocks(list, fn);
 			break;
		}
	}
	
	return 0;
}


/*
POST /qbrowser HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0) QQBrowser/9.0
Host: update.browser.qq.com
Content-Length: 345
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: uin_cookie=2210853762; euin_cookie=53DFE9A7024225C8649F40745723E578AC136F6862ECF843

{
"COS": "10.0.17763",
"CSoftID": 22,
"CVer": "1.6.6699.999",
"Cmd": 1,
"ExeVer": "1.0.1118.400",
"GUID": "9308ec3d7b7602d10f39e90f88399236",
"InstallTimeStamp": 1557478990,
"QID": 16785570,
"QQVer": "9.1.3.25332",
"SupplyID": 0,
"TriggerMode": 1,
"UIN": 0,
"bPatch": 0,
"osDigit": 64
}
HTTP/1.1 200
Date: Sun, 11 Aug 2019 03:14:20 GMT
Content-Length: 450
Connection: keep-alive

{ "CSoftID": 22, "CommandLine": "", "Desp": "\u0031\u002e\u0030\u002e\u0031\u0031\u0036\u0030\u002e\u0034\u0030", "DownloadUrl": "http://dl_dir.qq.com/invc/tt/minibrowser11.zip", "ErrCode": 0, "File": "minibrowser11.zip", "Flags": 1, "Hash": "b1309eb4312bd83d154a4b2b1b66547b", "InstallType": 0, "NewVer": "1.0.1160.400", "PatchFile": "QBDeltaUpdate.exe", "PatchHash": "b1309eb4312bd83d154a4b2b1b66547b", "Sign": "", "Size": 36003449, "VerType": "" }
*/

Android版qq解密代码:


#include "mobileQQ.h"
#include "winsock2.h"
#include "qqcrypt.h"
#include "../public.h"
#include "../ProtocolParser.h"
#include "../ResultFile.h"
#include "../fileOper.h"
#include "../SearchData.h"


int parseHeartbeat(const char * data, int len) {
	const char * pos = SearchData::getstring("Heartbeat.Alive", lstrlenA("Heartbeat.Alive"), data, len);
	if (pos)
	{
		pos = pos - lstrlenA("Heartbeat.Alive") - 2;
		int len = ntohl(*(short*)pos);
		pos += len;

		len = ntohs(*(short*)pos);
		pos += len;

		len = ntohs(*(short*)pos);
		string imei = string(pos + 2, len - 2);
		pos += len;

		len = ntohs(*(short*)pos);
		pos += len;

		len = ntohs(*(short*)(pos -2));
		if (*pos == '|')
		{
			string imsi = string(pos, len - 2);
			imsi = imsi.substr(1);
			int dot = imsi.find("|");
			if (dot > 0)
			{
				imsi = imsi.substr(0, dot);
			}
		}		
	}

	return 0;
}

int MobileQQ::parsePacket(const char * data, int &len,int dport,int sport,DATALISTHEADER hdr) {

	const char * qqdata = data;

	LPMOBILEQQ_PACK_HDR qqhdr = (LPMOBILEQQ_PACK_HDR)qqdata;
	int offset = ntohl(qqhdr->offset);
	if (offset >= 0x80 || offset < 0)
	{
		offset = 4;
	}

	qqdata = qqdata + sizeof(MOBILEQQ_PACK_HDR) + offset;

	string qqno = "";
	char qqnolen = *qqdata - sizeof(int);
	if (qqnolen >= 5 && qqnolen <= 10)
	{
		qqdata++;
		qqno = string(qqdata, qqnolen);
	}
	else {
		printf("error qq no len\r\n");
		return -1;
	}

	qqdata += qqnolen;

	if (qqhdr->cryption == 2)
	{
		ResultFile::writeRecord(hdr, "mqq", "on", qqno);

		unsigned char key[16] = { 0 };

		int cryptlen = len - (qqdata - data);
		unsigned char *decodebuf = new unsigned char[cryptlen + 4096];
		int decodelen = cryptlen + 4096;
		int ret = qq_decrypt((unsigned char*)qqdata, cryptlen, key, decodebuf, &decodelen);
		if (/*ret && */decodelen > 0)
		{
			*(decodebuf + decodelen) = 0;
			printf("succeed decrypted size:%u,encrypted size:%u\r\n", decodelen, cryptlen);
			Public::WriteDataFile("mobileqq.dat", (const char*)decodebuf, decodelen);

			//ResultFile::writeRecord(hdr, "mqq", "on", qqno);
		}
		else {
			printf("error:decrypted size:%u,encrypted size:%u\r\n", decodelen, cryptlen);
			//printf("decrypt mobile qq fix crypt packet error\r\n");
		}

		delete decodebuf;
	}
	else if(qqhdr->cryption == 0){
		printf("no cryption mobile qq packet\r\n");
	}
	else if (qqhdr->cryption == 1)
	{

	}
	else {
		printf("error qq packet cryption\r\n");
		return -1;
	}

	return 0;
}


int MobileQQ::isMobileQQPack(DATALISTHEADER hdr) {
	int dport = hdr.sock.dstport;
	char * data = hdr.datalist->data;
	int len = hdr.sizelist->size;

	if (hdr.sock.protocol == 6 &&(dport == 8080 || dport == 443 || dport == 80 || dport == 14000))
	{
		int packlen = ntohl(*(int*)data);
		if (len == packlen )
		{
			char crypt = *(data + 8);
			if (crypt == 1 || crypt == 2 || crypt == 0)
			{
				int ver = *(int*)(data + sizeof(int));
				//3 = 2010 11 = 2016
				if (ver == 0x0a000000 || ver == 0x0b000000 || ver == 0x09000000)
				{
					return TRUE;
				}
			}
		}
	}

	return FALSE;
}







tea_crypt算法解密源码:

/**
* The QQ2003C protocol plugin
*
* for gaim
*
* Copyright (C) 2004 Puzzlebird
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*
* OICQ encryption algorithm
* Convert from ASM code provided by PerlOICQ
*
* Puzzlebird, Nov-Dec 2002
*/

/*****************************************************************************/
/*Notes: (OICQ uses 0x10 iterations, and modified something...)

IN : 64  bits of data in v[0] - v[1].
OUT: 64  bits of data in w[0] - w[1].
KEY: 128 bits of key  in k[0] - k[3].

delta is chosen to be the real part of
the golden ratio: Sqrt(5/4) - 1/2 ~ 0.618034 multiplied by 2^32.

0x61C88647 is what we can track on the ASM codes.!!
*/

//#ifndef _WIN32
//#include <arpa/inet.h>
//#else
//#include "win32dep.h"
//#endif
#ifndef _QQ_QQ_CRYPT_C_
#define _QQ_QQ_CRYPT_C_

#include <string.h>
#include "qqcrypt.h"
#include <winsock2.h>
#include <stdlib.h>

void qq_encipher(
	unsigned long *const        v,
	const unsigned long *const  k,
	unsigned long *const        w);

void qq_decipher(
	unsigned long *const        v,
	const unsigned long *const  k,
	unsigned long *const        w);

void qq_encrypt(
	unsigned char*  instr,
	int             instrlen,
	unsigned char*  key,
	unsigned char*  outstr,
	int*            outstrlen_prt);

int qq_decrypt(
	unsigned char*  instr,
	int             instrlen,
	unsigned char*  key,
	unsigned char*  outstr,
	int*            outstrlen_ptr);

/*****************************************************************************/
void qq_encipher(
	unsigned long *const        v,
	const unsigned long *const  k,
	unsigned long *const        w)
{
	register unsigned long
		y = ntohl(v[0]),
		z = ntohl(v[1]),
		a = ntohl(k[0]),
		b = ntohl(k[1]),
		c = ntohl(k[2]),
		d = ntohl(k[3]),
		n = 0x10,
		sum = 0,
		delta = 0x9E3779B9; /*  0x9E3779B9 - 0x100000000 = -0x61C88647 */

	while (n-- > 0) {
		sum += delta;
		y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
		z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
	}

	w[0] = htonl(y); w[1] = htonl(z);
}

/*****************************************************************************/
void qq_decipher(
	unsigned long *const        v,
	const unsigned long *const  k,
	unsigned long *const        w)
{
	register unsigned long
		y = ntohl(v[0]),
		z = ntohl(v[1]),
		a = ntohl(k[0]),
		b = ntohl(k[1]),
		c = ntohl(k[2]),
		d = ntohl(k[3]),
		n = 0x10,
		sum = 0xE3779B90,
		/* why this ? must be related with n value*/
		delta = 0x9E3779B9;

	/* sum = delta<<5, in general sum = delta * n */
	while (n-- > 0) {
		z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
		y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
		sum -= delta;
	}

	w[0] = htonl(y); w[1] = htonl(z);
}

/********************************************************************
* encrypt part
*******************************************************************/

void qq_encrypt(
	unsigned char*  instr,
	int             instrlen,
	unsigned char*  key,
	unsigned char*  outstr,
	int*            outstrlen_prt)
{
	unsigned char
		plain[8],         /* plain text buffer*/
		plain_pre_8[8],   /* plain text buffer, previous 8 bytes*/
		*crypted,        /* crypted text*/
		*crypted_pre_8,  /* crypted test, previous 8 bytes*/
		*inp;            /* current position in instr*/
	int
		pos_in_byte = 1,  /* loop in the byte */
		is_header = 1,      /* header is one byte*/
		count = 0,          /* number of bytes being crypted*/
		padding = 0;      /* number of padding stuff*/

						  //  int rand(void);
						  //  void encrypt_every_8_byte (void);    
						  //  int rand(void) {    /* it can be the real random seed function*/
						  //    return 0xdead; }  /* override with number, convenient for debug*/

						  /*** we encrypt every eight byte ***/
						  //  void encrypt_every_8_byte (void) {
						  //    for(pos_in_byte=0; pos_in_byte<8; pos_in_byte++) {
						  //      if(is_header) { plain[pos_in_byte] ^= plain_pre_8[pos_in_byte]; }
						  //      else { plain[pos_in_byte] ^= crypted_pre_8[pos_in_byte]; }
						  //    } /* prepare plain text*/
						  //    qq_encipher( (unsigned long *) plain,
						  //       		       (unsigned long *) key, 
						  //         		     (unsigned long *) crypted);   /* encrypt it*/
						  //    
						  //    for(pos_in_byte=0; pos_in_byte<8; pos_in_byte++) {
						  //      crypted[pos_in_byte] ^= plain_pre_8[pos_in_byte]; 
						  //    } 
						  //    memcpy(plain_pre_8, plain, 8);     /* prepare next*/
						  //    
						  //    crypted_pre_8   =   crypted;       /* store position of previous 8 byte*/
						  //    crypted         +=  8;             /* prepare next output*/
						  //    count           +=  8;             /* outstrlen increase by 8*/
						  //    pos_in_byte     =   0;             /* back to start*/
						  //    is_header       =   0;             /* and exit header*/
						  //  }/* encrypt_every_8_byte*/

	pos_in_byte = (instrlen + 0x0a) % 8; /* header padding decided by instrlen*/
	if (pos_in_byte) {
		pos_in_byte = 8 - pos_in_byte;
	}
	plain[0] = (rand() & 0xf8) | pos_in_byte;

	memset(plain + 1, rand() & 0xff, pos_in_byte++);
	memset(plain_pre_8, 0x00, sizeof(plain_pre_8));

	crypted = crypted_pre_8 = outstr;

	padding = 1; /* pad some stuff in header*/
	while (padding <= 2) { /* at most two byte */
		if (pos_in_byte < 8) { plain[pos_in_byte++] = rand() & 0xff; padding++; }
		if (pos_in_byte == 8) {
			//encrypt_every_8_byte(); } 
			//void encrypt_every_8_byte (void) 
			{
				for (pos_in_byte = 0; pos_in_byte<8; pos_in_byte++) {
					if (is_header) { plain[pos_in_byte] ^= plain_pre_8[pos_in_byte]; }
					else { plain[pos_in_byte] ^= crypted_pre_8[pos_in_byte]; }
				} /* prepare plain text*/
				qq_encipher((unsigned long *)plain,
					(unsigned long *)key,
					(unsigned long *)crypted);   /* encrypt it*/

				for (pos_in_byte = 0; pos_in_byte<8; pos_in_byte++) {
					crypted[pos_in_byte] ^= plain_pre_8[pos_in_byte];
				}
				memcpy(plain_pre_8, plain, 8);     /* prepare next*/

				crypted_pre_8 = crypted;       /* store position of previous 8 byte*/
				crypted += 8;             /* prepare next output*/
				count += 8;             /* outstrlen increase by 8*/
				pos_in_byte = 0;             /* back to start*/
				is_header = 0;             /* and exit header*/
			}/* encrypt_every_8_byte*/
		}
	}

	inp = instr;
	while (instrlen > 0) {
		if (pos_in_byte < 8) { plain[pos_in_byte++] = *(inp++); instrlen--; }
		if (pos_in_byte == 8) {
			//encrypt_every_8_byte(); }
			//void encrypt_every_8_byte (void)
			{
				for (pos_in_byte = 0; pos_in_byte<8; pos_in_byte++) {
					if (is_header) { plain[pos_in_byte] ^= plain_pre_8[pos_in_byte]; }
					else { plain[pos_in_byte] ^= crypted_pre_8[pos_in_byte]; }
				} /* prepare plain text*/
				qq_encipher((unsigned long *)plain,
					(unsigned long *)key,
					(unsigned long *)crypted);   /* encrypt it*/

				for (pos_in_byte = 0; pos_in_byte<8; pos_in_byte++) {
					crypted[pos_in_byte] ^= plain_pre_8[pos_in_byte];
				}
				memcpy(plain_pre_8, plain, 8);     /* prepare next*/

				crypted_pre_8 = crypted;       /* store position of previous 8 byte*/
				crypted += 8;             /* prepare next output*/
				count += 8;             /* outstrlen increase by 8*/
				pos_in_byte = 0;             /* back to start*/
				is_header = 0;             /* and exit header*/
			}/* encrypt_every_8_byte*/
		}
	}

	padding = 1; /* pad some stuff in tailer*/
	while (padding <= 7) { /* at most sever byte*/
		if (pos_in_byte < 8) { plain[pos_in_byte++] = 0x00; padding++; }
		if (pos_in_byte == 8) {
			// encrypt_every_8_byte(); 
			//void encrypt_every_8_byte (void)
			{
				for (pos_in_byte = 0; pos_in_byte<8; pos_in_byte++) {
					if (is_header) { plain[pos_in_byte] ^= plain_pre_8[pos_in_byte]; }
					else { plain[pos_in_byte] ^= crypted_pre_8[pos_in_byte]; }
				} /* prepare plain text*/
				qq_encipher((unsigned long *)plain,
					(unsigned long *)key,
					(unsigned long *)crypted);   /* encrypt it*/

				for (pos_in_byte = 0; pos_in_byte<8; pos_in_byte++) {
					crypted[pos_in_byte] ^= plain_pre_8[pos_in_byte];
				}
				memcpy(plain_pre_8, plain, 8);     /* prepare next*/

				crypted_pre_8 = crypted;       /* store position of previous 8 byte*/
				crypted += 8;             /* prepare next output*/
				count += 8;             /* outstrlen increase by 8*/
				pos_in_byte = 0;             /* back to start*/
				is_header = 0;             /* and exit header*/
			}/* encrypt_every_8_byte*/
		}
	}

	*outstrlen_prt = count;
}/* qq_encrypt*/


 /********************************************************************
 * [decrypt part]
 * return 0 if failed, otherwise return 1
 ********************************************************************/

int qq_decrypt(
	unsigned char*  instr,
	int             instrlen,
	unsigned char*  key,
	unsigned char*  outstr,
	int*            outstrlen_ptr)
{
	unsigned char
		decrypted[8], m[8],
		*crypt_buff,
		*crypt_buff_pre_8,
		*outp;
	int
		count,
		context_start,
		pos_in_byte,
		padding;
	//  int decrypt_every_8_byte (void);
	//  int decrypt_every_8_byte (void) {
	//    for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte ++ ) {
	//        if (context_start + pos_in_byte >= instrlen) return 1;
	//        decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
	//    }
	//    qq_decipher( (unsigned long *) decrypted, 
	//       	  	     (unsigned long *) key, 
	//        	  	   (unsigned long *) decrypted);
	//    
	//    context_start +=  8;
	//    crypt_buff    +=  8;
	//    pos_in_byte   =   0;
	//    return 1;
	//  }/* decrypt_every_8_byte*/

	/* at least 16 bytes and %8 == 0*/
	if ((instrlen % 8) || (instrlen < 16)) return 0;
	/* get information from header*/
	qq_decipher((unsigned long *)instr,
		(unsigned long *)key,
		(unsigned long *)decrypted);
	pos_in_byte = decrypted[0] & 0x7;
	count = instrlen - pos_in_byte - 10; /* this is the plaintext length*/
										 /* return if outstr buffer is not large enought or error plaintext length*/
	if (*outstrlen_ptr < count || count < 0) return 0;

	memset(m, 0, 8);
	crypt_buff_pre_8 = m;
	*outstrlen_ptr = count;   /* everything is ok! set return string length*/

	crypt_buff = instr + 8;   /* address of real data start */
	context_start = 8;        /* context is at the second 8 byte*/
	pos_in_byte++;           /* start of paddng stuffv*/

	padding = 1;              /* at least one in header*/
	while (padding <= 2) {    /* there are 2 byte padding stuff in header*/
		if (pos_in_byte < 8) {  /* bypass the padding stuff, none sense data*/
			pos_in_byte++; padding++;
		}
		if (pos_in_byte == 8) {
			crypt_buff_pre_8 = instr;
			//      if (!decrypt_every_8_byte())
			//		  return 0; 
			//	  int decrypt_every_8_byte (void);
			//	  int decrypt_every_8_byte (void)
			{
				for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
					if (context_start + pos_in_byte >= instrlen)
						return 0;
					decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
				}
				qq_decipher((unsigned long *)decrypted,
					(unsigned long *)key,
					(unsigned long *)decrypted);

				context_start += 8;
				crypt_buff += 8;
				pos_in_byte = 0;
				//		  return 0;
			}/* decrypt_every_8_byte*/
		}
	}/* while*/

	outp = outstr;
	while (count != 0) {
		if (pos_in_byte < 8) {
			*outp = crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte];
			outp++;
			count--;
			pos_in_byte++;
		}
		if (pos_in_byte == 8) {
			crypt_buff_pre_8 = crypt_buff - 8;
			//      if (! decrypt_every_8_byte()) return 0;
			//	  int decrypt_every_8_byte (void);
			//	  int decrypt_every_8_byte (void)
			{
				for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
					if (context_start + pos_in_byte >= instrlen)
						return 0;
					decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
				}
				qq_decipher((unsigned long *)decrypted,
					(unsigned long *)key,
					(unsigned long *)decrypted);

				context_start += 8;
				crypt_buff += 8;
				pos_in_byte = 0;
				//		  return 0;
			}/* decrypt_every_8_byte*/

		}
	}/* while*/

	for (padding = 1; padding < 8; padding++) {
		if (pos_in_byte < 8) {
			if (crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte]) return 0;
			pos_in_byte++;
		}
		if (pos_in_byte == 8) {
			crypt_buff_pre_8 = crypt_buff;
			//      if (! decrypt_every_8_byte()) return 0;
			//	  int decrypt_every_8_byte (void);
			//	  int decrypt_every_8_byte (void)
			{
				int haveData = 1;
				for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
					if (context_start + pos_in_byte >= instrlen)
					{
						haveData = 0;
						break;
					}
					decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
				}
				if (haveData == 1)
				{
					qq_decipher((unsigned long *)decrypted,
						(unsigned long *)key,
						(unsigned long *)decrypted);

					context_start += 8;
					crypt_buff += 8;
					pos_in_byte = 0;
				}
				//		  return 0;
			}/* decrypt_every_8_byte*/
		}
	}/* for*/
	return 1;
}/* qq_decrypt*/

 /*****************************************************************************/
 /* This is the Public Function */
 /* return 1 is succeed, otherwise return 0*/
int qq_crypt(
	unsigned char   flag,
	unsigned char*  instr,
	int             instrlen,
	unsigned char*  key,
	unsigned char*  outstr,
	int*            outstrlen_ptr)
{
	if (flag == DECRYPT)
		return qq_decrypt(instr, instrlen, key, outstr, outstrlen_ptr);
	else if (flag == ENCRYPT)
		qq_encrypt(instr, instrlen, key, outstr, outstrlen_ptr);

	return 1; /* flag must be DECRYPT or ENCRYPT*/
}/* qq_crypt*/
 /*****************************************************************************/
 /* END OF FILE*/











int qq_decrypt2(
	unsigned char*  instr,
	int             instrlen,
	unsigned char*  key,
	unsigned char*  outstr,
	int*            outstrlen_ptr)
{
	unsigned char
		decrypted[8], m[8],
		*crypt_buff,
		*crypt_buff_pre_8,
		*outp;
	int
		count,
		context_start,
		pos_in_byte,
		padding;
	//  int decrypt_every_8_byte (void);
	//  int decrypt_every_8_byte (void) {
	//    for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte ++ ) {
	//        if (context_start + pos_in_byte >= instrlen) return 1;
	//        decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
	//    }
	//    qq_decipher( (unsigned long *) decrypted, 
	//       	  	     (unsigned long *) key, 
	//        	  	   (unsigned long *) decrypted);
	//    
	//    context_start +=  8;
	//    crypt_buff    +=  8;
	//    pos_in_byte   =   0;
	//    return 1;
	//  }/* decrypt_every_8_byte*/

	/* at least 16 bytes and %8 == 0*/
	if ((instrlen % 8) || (instrlen < 16)) return 0;
	/* get information from header*/
	qq_decipher((unsigned long *)instr,
		(unsigned long *)key,
		(unsigned long *)decrypted);
	pos_in_byte = decrypted[0] & 0x7;
	count = instrlen - pos_in_byte - 10; /* this is the plaintext length*/
										 /* return if outstr buffer is not large enought or error plaintext length*/
	if (*outstrlen_ptr < count || count < 0) return 0;

	//   if(count!=285 && count!=143)
	// 	  return 0;




	memset(m, 0, 8);
	crypt_buff_pre_8 = m;
	*outstrlen_ptr = count;   /* everything is ok! set return string length*/

	crypt_buff = instr + 8;   /* address of real data start */
	context_start = 8;        /* context is at the second 8 byte*/
	pos_in_byte++;           /* start of paddng stuffv*/

	padding = 1;              /* at least one in header*/
	while (padding <= 2) {    /* there are 2 byte padding stuff in header*/
		if (pos_in_byte < 8) {  /* bypass the padding stuff, none sense data*/
			pos_in_byte++; padding++;
		}
		if (pos_in_byte == 8) {
			crypt_buff_pre_8 = instr;
			//      if (!decrypt_every_8_byte())
			//		  return 0; 
			//	  int decrypt_every_8_byte (void);
			//	  int decrypt_every_8_byte (void)
			{
				for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
					if (context_start + pos_in_byte >= instrlen)
						return 0;
					decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
				}
				qq_decipher((unsigned long *)decrypted,
					(unsigned long *)key,
					(unsigned long *)decrypted);

				context_start += 8;
				crypt_buff += 8;
				pos_in_byte = 0;
				//		  return 0;
			}/* decrypt_every_8_byte*/
		}
	}/* while*/

	bool bcheck = false;
	outp = outstr;
	while (count != 0) {

		if ((outp - outstr)>4 && false == bcheck)
		{
			int aat = outstr[0] * 256 + outstr[1];
			if (*outstrlen_ptr - aat != 4)
				return 0;

			if (outstr[2] == 0 && outstr[3] == 0)
			{
				bcheck = true;
			}
			else if (outstr[2] == 1 &&
				(outstr[3] >= '0' && outstr[3] <= '9') ||
				(outstr[3] >= 'a' && outstr[3] <= 'z') ||
				(outstr[3] >= 'A' && outstr[3] <= 'Z')
				)
			{
				bcheck = true;
			}
			else
				return 0;
			// 		  if(memcmp(outstr+2,"\x00\x00",2)==0)
			// 		  {
			// 			 // return 1;
			// 		  }
			// 		  else
			// 		  {
			// 			  return 0;
			// 		  }
		}




		if (pos_in_byte < 8) {
			*outp = crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte];
			outp++;
			count--;
			pos_in_byte++;
		}
		if (pos_in_byte == 8) {
			crypt_buff_pre_8 = crypt_buff - 8;
			//      if (! decrypt_every_8_byte()) return 0;
			//	  int decrypt_every_8_byte (void);
			//	  int decrypt_every_8_byte (void)
			{
				for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
					if (context_start + pos_in_byte >= instrlen)
						return 0;
					decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
				}
				qq_decipher((unsigned long *)decrypted,
					(unsigned long *)key,
					(unsigned long *)decrypted);

				context_start += 8;
				crypt_buff += 8;
				pos_in_byte = 0;
				//		  return 0;
			}/* decrypt_every_8_byte*/

		}
	}/* while*/

	for (padding = 1; padding < 8; padding++) {
		if (pos_in_byte < 8) {
			if (crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte]) return 0;
			pos_in_byte++;
		}
		if (pos_in_byte == 8) {
			crypt_buff_pre_8 = crypt_buff;
			//      if (! decrypt_every_8_byte()) return 0;
			//	  int decrypt_every_8_byte (void);
			//	  int decrypt_every_8_byte (void)
			{
				int haveData = 1;
				for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
					if (context_start + pos_in_byte >= instrlen)
					{
						haveData = 0;
						break;
					}
					decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
				}
				if (haveData == 1)
				{
					qq_decipher((unsigned long *)decrypted,
						(unsigned long *)key,
						(unsigned long *)decrypted);

					context_start += 8;
					crypt_buff += 8;
					pos_in_byte = 0;
				}
				//		  return 0;
			}/* decrypt_every_8_byte*/
		}
	}/* for*/
	return 1;
}/* qq_decrypt*/



int qq_crypt2(
	unsigned char   flag,
	unsigned char*  instr,
	int             instrlen,
	unsigned char*  key,
	unsigned char*  outstr,
	int*            outstrlen_ptr
)
{
	if (flag == DECRYPT)
		return qq_decrypt2(instr, instrlen, key, outstr, outstrlen_ptr);
	else if (flag == ENCRYPT)
		qq_encrypt(instr, instrlen, key, outstr, outstrlen_ptr);

	return 1; /* flag must be DECRYPT or ENCRYPT*/
}/* qq_crypt*/


#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1401789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink(十四)【Flink SQL(中)查询】

前言 接着上次写剩下的查询继续学习。 Flink SQL 查询 环境准备&#xff1a; # 1. 先启动 hadoop myhadoop start # 2. 不需要启动 flink 只启动yarn-session即可 /opt/module/flink-1.17.0/bin/yarn-session.sh -d # 3. 启动 flink sql 的环境 sql-client ./sql-client.sh …

【优化技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路

针对Java对象压缩及序列化技术的探索之路 序列化和反序列化为何需要有序列化呢&#xff1f;Java实现序列化的方式二进制格式 指定语言层级二进制格式 跨语言层级JSON 格式化类JSON格式化&#xff1a;XML文件格式化 序列化的分类在速度的对比上一般有如下规律&#xff1a;Java…

IDEA连接mysql5.7,报[08001] Could not create connection to database server错误

导致的原因是&#xff1a; MySQL版本过高 解决方法&#xff1a; 在数据库后面添加&#xff1a;useSSLserverTimezonecharacterEncodingautoReconnect 即&#xff1a;jdbc:mysql://localhost:3306/test?useSSLfalse&serverTimezoneHongkong&characterEncodingutf-8&…

Django从入门到精通(二)

目录 三、视图 3.1、文件or文件夹 3.2、相对和绝对导入urls 3.3、视图参数requests 3.4、返回值 3.5、响应头 3.6、FBV和CBV FBV 四、静态资源 4.1、静态文件 4.2、媒体文件 五、模板 5.1、寻找html模板 5.2、模板处理的本质 5.3、常见模板语法 5.4、内置模板函…

一.初识Linux 1-3操作系统概述Linux初识虚拟机介绍

目录 一.初识Linux 1.操作系统概述 计算机组成 硬件&#xff1a; 软件&#xff1a; 操作系统&#xff1a; 操作系统工作流程 操作系统作用 常见的操作系统 PC端&#xff1a; 移动端&#xff1a;&#xff08;掌上操作系统&#xff09; 一.初识Linux 2.Linux初识 linu…

GSP专版软件系统(医疗器械进销存)

产品概述 软件完全符合药监局GSP认证要求&#xff0c;可订制其它平台的数据对接; 业务流程清晰&#xff0c;操作简单合理&#xff0c;软件速度非常快; 完善的序列号(UDI)管理,并与整个系统融合在一起; 财务账和业务账完美结合; 可自定义的界面、布局管理;灵活的打印样式设计; 可…

Spring 事务原理一

从本篇博客开始&#xff0c;我们将梳理Spring事务相关的知识点。在开始前&#xff0c;想先给自己定一个目标&#xff1a;通过此次梳理要完全理解事务的基本概念及Spring实现事务的基本原理。为实现这个目标我想按以下几个步骤进行&#xff1a; 讲解事务中的一些基本概念使用Sp…

大数据导论(4)---大数据应用

文章目录 1. 在互联网中的应用1.1 推荐系统1.2 长尾理论1.3 推荐方法与模型1.4 推荐系统应用 2. 在其他领域的应用2.1 企业营销2.2 智慧交通 1. 在互联网中的应用 1.1 推荐系统 1. 推荐系统产生&#xff1a;  (1) 互联网的飞速发展使我们进入了信息过载的时代&#xff0c;搜索…

4D毫米波雷达——FFT-RadNet 目标检测与可行驶区域分割 CVPR2022

前言 本文介绍使用4D毫米波雷达&#xff0c;实现目标检测与可行驶区域分割&#xff0c;它是来自CVPR2022的。 会讲解论文整体思路、输入数据分析、模型框架、设计理念、损失函数等&#xff0c;还有结合代码进行分析。 论文地址&#xff1a;Raw High-Definition Radar for Mu…

【差分数组】【图论】【分类讨论】【整除以2】100213按距离统计房屋对数目

作者推荐 【动态规划】【数学】【C算法】18赛车 本文涉及知识点 差分数组 图论 分类讨论 整除以2 LeetCode100213按距离统计房屋对数目 给你三个 正整数 n 、x 和 y 。 在城市中&#xff0c;存在编号从 1 到 n 的房屋&#xff0c;由 n 条街道相连。对所有 1 < i < n…

【QT+QGIS跨平台编译】之二:【zlib+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、zlib介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、zlib介绍 zlib是一套通用的解压缩开源库&#xff0c;提供了内存&#xff08;in-memory&#xff09;压缩和解压函数。zlib是一套通用的解压缩开源库&#xff0c;提供了内存&#xff08;in-memory&am…

Mysql学习笔记系列(一)

本次mysql系列不会讲解具体的查询语句&#xff0c;而是放在mysql的一些性能优化和一些特性上&#xff0c;是学习笔记&#xff0c;供大家参考补充。 慢查询 MySQL的慢查询&#xff0c;全名是慢查询日志&#xff0c;是MySQL提供的一种日志记录&#xff0c;用来记录在MySQL中响应…

Paimon教程

教程来自尚硅谷 目录 教程来自尚硅谷1. 概述1.1 简介1.2 核心特性1.3 文件布局1.3.1 LSM Trees 2. 集成Flink2.1 安装&配置2.2 Catalog 3. 进阶使用3.1 写入性能3.1.1 并行度3.1.2 Compaction3.1.3 触发Compaction的Sorted Run数3.1.4 写入初始化3.1.5 内存 3.2 读取性能3.…

Unity下实现跨平台的RTMP推流|轻量级RTSP服务|RTMP播放|RTSP播放低延迟解决方案

2018年&#xff0c;我们开始在原生RTSP|RTMP直播播放器的基础上&#xff0c;对接了Unity环境下的低延迟播放&#xff0c;毫秒级延迟&#xff0c;发布后&#xff0c;就得到了业内一致的认可。然后我们覆盖了Windows、Android、iOS、Linux的RTMP推送、轻量级RTSP服务和RTSP|RTMP播…

数学建模--PageRank算法的Python实现

文章目录 1. P a g e R a n k PageRank PageRank算法背景2. P a g e R a n k PageRank PageRank算法基础2.1. P a g e R a n k PageRank PageRank问题描述2.2.有向图模型2.3.随机游走模型 3. P a g e R a n k PageRank PageRank算法定义3.1. P a g e R a n k PageRank PageRank…

springcloud Hystrix断路器

文章目录 代码下载简介写服务测试高并发测试写消费者端测试2 服务降级先修改cloud-provider-hystrix-payment8001修改cloud-consumer-feign-hystrix-order80 目前问题方法2:测试 服务熔断实操测试 服务监控hystrixDashboard建mudlue断路器演示(服务监控hystrixDashboard) 代码下…

第6章 SpringBoot缓存管理

学习目标 了解SpringBoot的默认缓存 熟悉SpringBoot中Redis的缓存机制及实现 掌握SpringBoot整合Redis的缓存实现 缓存是分布式系统中的重要组件&#xff0c;主要解决数据库数据的高并发访问问题。在实际开发中&#xff0c;尤其是用户访问量较大的网站&#xff0c;为了提高服…

(上) C语言中的语句分类及分支语句:if语句、switch语句介绍

目录 前言 一、语句的分类 1. 空语句 2. 表达式语句 3. 函数调用语句 4. 复合语句 5. 控制语句 二、分支语句 1. if语句 (1) if的使用 (2) else的使用 (3) 分支中包含多条语句 (4) 嵌套if (5) 悬空else问题 2. switch语句 (1) if语句和switch语句的对比 (2) s…

HackTheBox - Medium - Linux - Noter

Noter Noter 是一种中型 Linux 机器&#xff0c;其特点是利用了 Python Flask 应用程序&#xff0c;该应用程序使用易受远程代码执行影响的“节点”模块。由于“MySQL”守护进程以用户“root”身份运行&#xff0c;因此可以通过利用“MySQL”的用户定义函数来利用它来获得RCE并…

Jmeter 配置元件

Jmeter 配置元件 CSV 数据集配置HTTP Cookie 管理器HTTP Header 信息头管理器增加多个用户案列 使用Jmeter发送请求的时候&#xff0c;需要配置元件&#xff0c;配置请求Header、Cookie、数据集合等。可以模拟多个在线用户登录&#xff0c;修改请求头数据。 CSV 数据集配置 C…