谁知道oicq在windows下的原理?

谁知道oicq在windows下的原理?

不行咱们自己可以搞一个,可惜我不知道腾讯的技术,搞不出来。有谁知道吗?咱们一块搞?!      
没多么好搞吧!!!      
兄弟啊,你真的以为什么事情都很简单吗?tencent公司没有公布他们的协议,难道你还自己去破不成?      
   本人一时冲动对oicq99坐了一些反汇编,本想彻底弄清oicq的协议,
编一个oicq for linux.但后来发现一个人坐实在是不行,一方面太花时间,
另一方面精力不够.今天看见有人在问oicq的协议,我就把我知道的说了吧,
有什么地方搞错还请多多指教.


    oicq99客户段发送的报文格式:

struct oicq_client_packet{
        char        ver;                        //我起的名字
        char        unknowA[2];
        char         cmd[2];                //我起的名字
        char         id[2];                        //我起的名字
        char        uin[4];                //oicq的号码
        char  hash[16];                //用于加密
        char  data[0];
};


    现在基本弄清oicq99客户段对发送的报文中的数据(oicq_client_packet->data)是如何加密了,
以下是我编的加解密程序:


oicqlib_code(char *hash,char *data,int len,char **ret);                //用于加密
oicqlib_decode(char *hash,char *data,int len);                        //用于解密

void
oicqlib_decodeA(char *hash,char *source,char *dest){
        unsigned int sourceL,sourceH;
        unsigned int VAR;
        int i;
        unsigned int array[4];
        unsigned int t,A,B;

        sourceL=htonl(*((unsigned int*)&source[0]));
        sourceH=htonl(*((unsigned int*)&source[4]));

        for(i=0; i<4; i++)
                array=htonl( *(((int*)&hash[i*4])) );

        VAR=0;
        for(i=0x10; i; i--)
                VAR-=0x61C88647L;

        for(i=0x10; i; i--){
                A=(sourceL>>5)+array[3];
                B=(sourceL<<4)+array[2];
                A^=B;
                B=VAR+sourceL;
                A^=B;
                sourceH-=A;

                A=(sourceH>>5)+array[1];
                B=(sourceH<<4)+array[0];
                A^=B;
                B=VAR+sourceH;
                A^=B;
                sourceL-=A;

                VAR+=0x61C88647L;
        }

        *((unsigned int*)&dest[0])=ntohl(sourceL);
        *((unsigned int*)&dest[4])=ntohl(sourceH);
}
//data为加密后的数据,hash用于解密,最后把原数据返回到data
int
oicqlib_decode(char *hash,char *data,int len){
        char *buf_start,*buf,*source,*prev;
        int buf_len=len;
        char tmp[8],empty[8];
        int i;

        buf_start=buf=malloc(buf_len);
        memset(tmp,0,sizeof(tmp));
        memset(empty,0,sizeof(empty));
        prev=&empty[0];
        source=data;
        while(len){
                for(i=0; i<8; i++)
                        buf=source^tmp;

                oicqlib_decodeA(hash,buf,buf);
                memcpy(tmp,buf,8);

                for(i=0; i<8; i++)
                        *buf++^=*prev++;

                prev=source;
                source+=8;
                len-=8;
        }
        i=(buf_start[0] & 0x7)+1+2;
        buf_len-=i;
//        buf_len-=8;

        memcpy(data,&buf_start,buf_len);
        free(buf_start);

        return buf_len;
}






void
oicqlib_codeA(char *hash,char *source,char *dest)
{
        unsigned int sourceL,sourceH;
        unsigned int VAR;
        int i;
        unsigned int array[4];
        unsigned int t,A,B;

        sourceL=htonl(*((unsigned int*)&source[0]));
        sourceH=htonl(*((unsigned int*)&source[4]));

        for(i=0; i<4; i++)
                array=htonl( *(((int*)&hash[i*4])) );

        VAR=0;
        for(i=0x10; i; i--){
                VAR-=0x61C88647L;

                A=(sourceH>>5)+array[1];
                B=(sourceH<<4)+array[0];
                A^=B;
                B=VAR+sourceH;
                A^=B;
                sourceL+=A;

                A=(sourceL>>5)+array[3];
                B=(sourceL<<4)+array[2];
                A^=B;
                B=VAR+sourceL;
                A^=B;
                sourceH+=A;
        }

        *((unsigned int*)&dest[0])=ntohl(sourceL);
        *((unsigned int*)&dest[4])=ntohl(sourceH);        
}

//data为原数据,ret用于返回加密后的数据,hash用于加密.
int
oicqlib_code(char *hash,char *data,int len,char **ret){
        char *buf;
        int buf_len,i;
        char tmpA[8],tmpB[8];
        char *prev;
        int count,t;

        *ret=buf=malloc(len+0x15);
       
        memset(tmpA,0,sizeof(tmpA));
        memset(tmpB,0,sizeof(tmpB));
        prev=&tmpA[0];

        t=8-((len+10)%8);

        buf_len=0;
        count=0;
        buf[count++]=(oicqlib_rand() & 0xf8) | (t-1);
        for(t+=1; t; t--)
                buf[count++]=oicqlib_rand();

        if (count==8){
                for(i=0; i<8; i++)
                        tmpA=buf^prev;
                oicqlib_codeA(hash,tmpA,buf);
                for(i=0; i<8; i++)
                        buf^=tmpB;
                memcpy(tmpB,tmpA,8);
                prev=buf;
                buf_len+=8;
                buf+=8;
                count=0;
        }

        while(len){
                for(; count<8; count++){
                        buf[count]=*data++;
                        len--;
                }
                if (count==8){
                        for(i=0; i<8; i++)
                                tmpA=buf^prev;
                        oicqlib_codeA(hash,tmpA,buf);
                        for(i=0; i<8; i++)
                                buf^=tmpB;
                        memcpy(tmpB,tmpA,8);
                        prev=buf;
                        buf_len+=8;
                        buf+=8;
                        count=0;
                }
        }
        return buf_len;
}

    另外,我发现oicq好像对password用了单向加密,用了两种方法,后一种用
了oicqlib_code(0,password,16,ret),不懂.

    真希望编一个oicq for linux,该死的xx,就算不编oicq for linux,也应该编一个
oicq for java吧.有时间大家一起来弄清oicq的协议,让xx好看.



















      
我觉得大家的想法非常好,如果有志愿的朋友能组合到一起,做一些事情,我想是很好的。      
我以前也想过编oicq,但后来我觉得与其彻底另起炉灶还不如作个专为oicq设计的模拟器,那样不必知道oicq数据的加密方式,数据处理全有oicq自己完成,而模拟器就负责显示数据和想网络发送数据,虽然编程我还不太明白不过我觉得这样还是有实现的可能的。而且用这种方式实现的话,将来oicq升级也可以不用再写一次。

ps :如果哪位有兴趣开发oicq能不能大家合作,我也想顺便学学编程什么的。      
还有我一个,我有兴趣作oicq for java      
我觉得这篇文章有参考价值把地址写在这里谁有兴趣去看看吧
http://tech.163.com/tm/010705/010705_25614.html
还有一篇:
oicq在线显示原代码
发布者:flyfox 发布时间:09月13日

详细信息:
<?
if($HTTP_REFERER=="")
{
echo "非法调用<br>正确用法:&lt;script src=\"http://www.netsword.com/oicqonline.php3?uin=你的OICQ号\"&gt;&lt;/script&gt;";
exit();
}
function get_status($uin)
{
$fp = @fsockopen ("infocenter.tencent.com", 80, &$errno, &$errstr, 30);
if(!$fp)
{
return '出错';
}
else
{
fputs($fp, "GET /$uin/l/00/0/ HTTP/1.0\n\n");
$do = 'yes';
while(!feof($fp))
{
$line = fgets ($fp,128);
$do = ($do == 'yes')?'yes'eregi("^GIF89", $line))?'yes':'no';
if($do == 'yes')
{
if(ereg("Online", $line))
{
return '在线';
}
elseif(ereg("Offline", $line))
{
return '没在线';
}
}

}
fclose($fp);
}
return '未知';
}
if(isset($uin))
{
switch(get_status($uin))
{
case "在线":
$oicqimg="on.JPG";
$mstatus="在线";
break;
case "没在线":
$oicqimg="off.JPG";
$mstatus="没在线";

break;
case "未知":
$oicqimg="no.JPG";
$mstatus="未知";

break;
}
}

?>

document.write("<span style=\"cursor:hand;color:red;font-weight:bolder\" title=\"<?echo $uin.$mstatus?>\" onclick=\"window.open(\'http://netsword.net/netsword/oicq.php3\',\'_blank\',\'\');\"><img src=\"http://www.netsword.net/oicq/<?echo $oicqimg?>\"></span>");