qq的工作原理(明白易懂详细)

一、 口令加密 
每个oicq帐号的口令都保存在本地的一个文件中。登录oicq时,先将输入的口令与本地的 
文件进行比较。如果口令与文件中保存的不符,将提示"输入的密码与上次成功登录的密码 
不一致,是否到服务器验证?"。 
OICQ 99c的口令文件为matrix.cnt。OICQ 99b的口令文件为matric.ewh。 
口令加密算法的函数原型为: 
void CalcPassword(char *password ,int len ,char *outbuffer) 
参数: 
password为输入的明码口令 
len: password长度 
outbuffer:固定16个字节长度的加密后的口令。 
说明:该函数用调试工具查到入口地址为15f:456718。在口令加密和用户之间通讯时都要 
用到这个函数。已知能够计算的最长口令为20个字节,见下文用户之间加密通信。 
Oicq99b的口令文件就是将口令进行一次CalcPassword计算后保存在每个oicq帐号目录中的 
matrix.ewh,该文件正好为16个字节。因此有这个文件就可以使用暴力进行口令破解了。 

  Oicq99c的口令文件就复杂多了,第一次将明码的口令用CalcPassword进行计算,然后 
将结果再作为口令进行计算,迭代计算很多次。计算次数用4个字节的双字表示。将4个字 
节的次数和计算后的口令保存在每个oicq帐号的matrix.cnt文件中,这个文件正好为20个 
字节长度。因为迭代计算了很多次,使口令计算时间极大地延长了,使用暴力破解oicq99 
c的口令几乎不太可能。 
二、 聊天历史的查看 
  与每个人聊天的历史都存在自已的oicq号目录下,文件名为对方的oicq号.msh(99b)或 
.msj(99c)文件中。 
  核心解密函数的原型为: 
BOOL Decode(char *src ,int srclen ,char *decodekey, char   outbuffer,int * p 
outlen) 
  参数: 
src:存放加密数据的缓冲区。 
Srclen:src字节数。 
Decodekey:固定16个字节的密钥。 
Outbuffer:输出明文缓冲区的地址。 
Poutlen:解密后的长度存放地址。 
说明:该函数入口地址:15f:456D33。这个函数以密钥进行解密。如果成功返回TRUE,否 
则返回FALSE。 
  显而易见,解密的关键是如何得到16个字节的密钥decodekey。 
  查看聊天历史的密钥生成不需要口令。算法为: 
  1、 用当前使用的oicq号为口令,调用口令计算函数CalcPassword,得出一个临时密 
钥keycode1。 
  2、 用keycode1为密钥,进行解密。数据为文件matrix2.ewh(99b为matrix.ewh) 从0 
起第17个字节,长度为32个字节,解出16个字节的密钥为keycode2。 
  3、 用keycode2为密钥,可以解开跟任何人聊天的历史。 
  例如要查看oicq号为123456的聊天历史记录,算法为: 
  BYTE keycode1<16>; 
  BYTE filebuffer<32>; 
  //读文件matrix2.ewh,从0起第17个字长,长度为32的内容读出保存在filebuffer。 

ReadToBuffer(filebuffer); 
//用当前的oicq号计算keycode1 
CalcPassword(’123456’, 6 , keycode1)。 
//计算keycode2 
BYTE keycode2<16>; 
int len = 16; 
Deocode(filebuffer , 32 , keycode1,keycode2,&len); 
//现在keycode2就是能看任何聊天历史的密钥了。 
//如看跟888888的聊天历史,将文件888888.msj读到缓冲区largerbuffer 
Decode(largerbuffer,largerbufferlen,keycode2,outbuffer,*outlen),成功后 
outbuffer中为解密后的聊天记录。 
三、 与服务器通信的加密 
与Decode相对应,是一个加密函数Encode。 
void Encode(char *src,int srclen,char *encodekey,char *outbuffer,int * 
poutlen) 
参数: 
src:明文缓冲区。 
Srclen: 明文缓冲区的长度。 
Encodekey:固定16个字节的加密的密钥。 
Outbuffer:输出加密缓冲区。 
Poutlen:输出长度的保存地址。 
说明:该函数入口地址:15f:456b62。将明文进行加密,密钥为encodekey。用d 
ecode函数和同样的密钥可以进行解密。 
l 登录服务器: 
发送的数据包为 
{BYTE b1;固定为0x2 
BYTE b2;固定为0x3 
BYTE b3;固定为0XA 
BYTE b4;固定为0X0 
BYTE cmd; 登录服务器为0X15。 
WORD seq; 顺序号,从高到低存放 
DWORD oicq号;以从高到低顺利存放二进制的OICQ号。 
BYTE key<16> ;随机产生的16个字节的密钥。 
BYTE buffer<64>;64字节的加密内容。 
BYTE endchar ;固定为0x3。 
最核心的是buffer<64>的内容。用口令调用CalcPassword进行一次计算,然后作 
为密钥对0长度的明文进行加密,得出16个字节的结果,再进行加密发送。例如口 
令为’abc123’,算法为 
BYTE passkey<16> 
CalcPassword(’abc123’,6’,passkey) 
BYTE keycode<16> 
int keycodelen=16; 
Encode(0,0,passkey,keycode,&keycodelen) 
BYTE sndbuffer<51>; 
memset(sndbuffer,0,51) 
memcpy(sndbuffer,keycode,16) 
//sndbuffer其余的内容为当前机器的ip等信息,与检查口令无关 
BYTE result<64> 
int sresultlen=64 
Encode(sndbuffer,51,随机产生16个字节的密钥,result,&resultlen) 
最后把16个字节的随机密钥和64字节加密后的口令一同发给服务器验证。如果能用sniffe 
r侦听到别人与服务器的通信,就能进行口令破解。当然也可以通过服务器进行在线的口令 
破解,只是速度很慢,没有实用价值。 
l 如果登录成功,服务器返回16个字节的密钥--ServerKey。 
l UPD数据包的格式为 
BYTE b1;固定为2 
BYTE b2;固定为1 
BYTE b3;固定为0 
BYTE b4;固定为0 
BYTE cmd;登录为0X15 
WORD seq;从高到低顺序,与发送的seq一致。 
BYTE msg<56>; 
BYTE endchar ;固定0x3。 
用口令经过一次CalcPassword计算,得出16个字节的密钥,对msg进行解密。从第1个字节 
开始的16个字节即为与服务器通信的密钥暂称为ServerKey。该密钥经常变化。 
在本次登录中,以后所有跟服务器的通信都用这个ServerKey为密钥进行加密和解密。 
四、 其它用户发来的加密消息的解密。 
其它用户的发来的加密消息格式为: 
BYTE b1;固定为0x0 
BYTE b2;固定为0x3 
BYTE b3;固定为0xA或0X2 
BYTE salt; OICQ号加密用 
DWORD EncodeOicqID;加密后的从高到低的oicq号。 
DWORD seq;序号 
BYTE msg<变长> 
l 对方oicq号的解密。 
将EncodeOicqID的4个字节分别与salt进行异或操作,然后取反。 
如salt = 0XA0, EncodeOicqID = 0X 5F5EBD1F。 
//分别进行异或操作 
0X 5F5EBD1F XOR 0XA0A0A0A0 = 0X FFFE1DBF 
//再取反 
NOT 0X FFFE1DBF = 0X1E240,转为10进制就是123456。因此对方的oicq号为123456。 
l 消息的解密。 
先合成一个20字节的口令。前4个字节为从高到低的二进制对方的oicq号。后16个字节为服 
务器发来的ServerKey。ServerKey的来源见第三节。 
如对方的oicq号为123456,20字节的口令为 
00 01 E2 40 + 16字节的ServerKey。 
用口令算法对这20字节的口令进行计算,得16个字节的密钥,就可以解开对方发来的消息 
 
五、 发给其它用户消息的加密 
在登录后,服务器会通知好友的IP地址和端口,以及一个16个字节的密钥。就是当前的OI 
CQ号加对方16个字节ServerKey通过CalcPass的计算结果。 
向对方发送消息时,只要用这16个字节进行加密即可。 
六、 一些结论 
oicq 99c的加密是严密的,不易进行破解。除非得到某人的口令,否则不可能进行消息假 
冒等。如果你有每秒能运算百亿次的巨型机,也许能解开对方跟服务器通信的16个字节的 
ServerKey,而且必须要快。总之oicq 99c 是安全的,仍然在使用的早期用户间明文通信 
协议不在本文考虑之内。

 

 

http://iask.sina.com.cn/b/6847486.html

转载于:https://www.cnblogs.com/yansj/archive/2011/12/09/2282756.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值