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 = 2016if (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 longy = 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 longy = 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 charplain[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*/intpos_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 chardecrypted[8], m[8],*crypt_buff,*crypt_buff_pre_8,*outp;intcount,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 chardecrypted[8], m[8],*crypt_buff,*crypt_buff_pre_8,*outp;intcount,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;}elsereturn 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