有人知道 OICQ的数据包格式吗?欢迎一起探讨

greensleeve 2001-03-07 10:47:00
...全文
214 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
早先oicq的包格式:



下面是 Oicq server 通知Oicq 好友上线和下线的消息结构:

struct TOicqUp

{

char Tag1; // 0x02 // 显然是 Oicq 的协议编号 or 版本,固定

char Tag2; // 0x01 // 显然是 Oicq 的协议编号 or 版本,固定

char Tag3; // 0x00

char Tag4; // 0x00

char Tag5; // 0x81

char Tag6; // 这两个字节相当于 unix 上的进程 ID,

char Tag7; // 随便赋值就可。

char cOicqNub[]; // 通知上线的Oicq 号码。 exp:123456

char cFF; // 0x1f 在所有的Oicq 信息结构中,分割符都是 0x1f

char cIP; // 该号码所在的 IP 地址

char cFF; //

char cE[]; // "8685" ,这一位相对固定,随便添一个四位数字

char cFF;

char cDD[]; // exp: "10",0x1f,"107" 基本固定

char cEnd; // 0x03 ,所有的 oicq 信息都已 0x03 为标记结束。

};

//--------------------------------------------------------

struct TOicqDown

{

char Tag1; // 0x02 // 显然是 Oicq 的协议编号 or 版本,固定

char Tag2; // 0x01 // 显然是 Oicq 的协议编号 or 版本,固定

char Tag3; // 0x00

char Tag4; // 0x00

char Tag5; // 0x81

char Tag6; // 这两个字节相当于 unix 上的进程 ID,

char Tag7; // 随便赋值就可。

char cOicqNub[]; // 通知上线的Oicq 号码。 exp:123456

char cFF; // 0x1f 在所有的Oicq 信息结构中,分割符都是 0x1f

char cIP; // 该号码所在的 IP 地址 // 随便填

char cFF; //

char cE[]; // "8685" ,这一位相对固定,随便添一个四位数字

char cFF;

char cDD[]; // exp: "20",0x1f,"107" 基本固定

char cEnd; // 0x03 ,所有的 oicq 信息都已 0x03 为标记结束。

};

在Oicq中最常用的消息传送时,Oicq 采用了如下策略: 当二者能直接(点到点)

通讯时,消息就直接的发送到对方,否则重试 N 次后通过Oicq 服务器转发。接受方

在收到消息后返回一个回应信息,发送方就是通过这个信息来确认消息是否已经收到。

消息的结构是:

(注意:本文中所有的 Oicq 协议结构是通过分析得来,不能保证其正确性)

struct TOicqPtoP

{

char Tag1; // 0x02 // 显然是 Oicq 的协议编号 or 版本,固定

char Tag2; // 0x01 // 显然是 Oicq 的协议编号 or 版本,固定

char Tag3; // 0x07

char Tag4; // 0x00

char Tag5; // 0x78

char Tag6; // 这两个字节相当于 unix 上的进程 ID,

char Tag7; // 随便赋值就可。

char cOicqNub[]; // 发送方的Oicq 号码。 exp:123456

char cFF; // 0x1f 在所有的Oicq 信息结构中,分割符都是 0x1f

char cR; // '0' 固定

char cFF; //

char cE[]; // "75" ,这一位相对固定,可能是操作方式。

char cFF;

char cDateTime[]; // exp: "2000-4-10",0x1f,"12:00:12",0x1f

char OutMsg[]; // 发送的消息内容。

char cEnd; // 0x03 ,所有的 oicq 信息都已 0x03 为标记结束。

};

新oicq的包格式:

三、 与服务器通信的加密

与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字节加密后的口令一同发给服务器验证。如果能

用sniffer侦听到别人与服务器的通信,就能进行口令破解。当然也可以通过服务

器进行在线的口令破解,只是速度很慢,没有实用价值。

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号为123

456。

l 消息的解密。

先合成一个20字节的口令。前4个字节为从高到低的二进制对方的oicq号。后16个

字节为服务器发来的ServerKey。ServerKey的来源见第三节。

如对方的oicq号为123456,20字节的口令为



00 01 E2 40 + 16字节的ServerKey。

用口令算法对这20字节的口令进行计算,得16个字节的密钥,就可以解开对方发

来的消息。

五、 发给其它用户消息的加密

在登录后,服务器会通知好友的IP地址和端口,以及一个16个字节的密钥。就是

当前的OICQ号加对方16个字节ServerKey通过CalcPass的计算结果。

向对方发送消息时,只要用这16个字节进行加密即可。
greensleeve 2001-03-08
  • 打赏
  • 举报
回复
没人知道 吗?

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧