曾经在2005年,受人所托研究了一下<永恒 >游戏得登陆包加密算法..他们准备写个进去喊话得工具.结果刚好等我破解完登陆加密......他们就因为一些原因解体了......................,害我得辛苦白费了..........
今天偶尔在网上又看见了永恒这个游戏,不知道算法是否改变,就想起了2年前的东西了,又翻了出来放出来.不过2年过去了,他的加密算法应该已经改变了.没兴趣接着研究了.
2005年5月25日
加密算法描述:
一共是56个字节的包
算法为每4个字节的分组算法.把登陆字符串每4个字节分出来,然后
将00D926C2右移动4个字节,得到结果后取后最后一个字节为X
然后用取第一个字节与X XOR运算。
就可以得到第一个字节的结果。
保存结果A。用结果A+00d926c2*2然后保存结果B,用结果B*00409042 取后面8位
然后保存结果C,最后用结果C-0024FAE3保存结果准备下次运算
004C9BB8 |> /8A042E /mov al,byte ptr ds:[esi+ebp] ; 取出4个字节中的第一个
004C9BBB |. |8BDA |mov ebx,edx
004C9BBD |. |C1FB 04 |sar ebx,4 ; EBX右移4位
004C9BC0 |. |32C3 |xor al,bl
004C9BC2 |. |8806 |mov byte ptr ds:[esi],al ; 得出计算结果后放到临时变量中
004C9BC4 |. |25 FF000000 |and eax,0FF
004C9BC9 |. |8D1450 |lea edx,dword ptr ds:[eax+edx*2]
004C9BCC |. |8B47 08 |mov eax,dword ptr ds:[edi+8] ; 让EAX=0024FAE3准备下次运算
004C9BCF |. |0FAF57 04 |imul edx,dword ptr ds:[edi+4] ; 整数相声法取后8位
004C9BD3 |. |2BD0 |sub edx,eax ; 减法
------------------------------登陆包结构---------------------------
struct
{
dword logincommand; //0x80
dword count; //包序号
dword w; //0x70
Dword b1; //登陆包最后的基数1,0x00000000
Dword b2; //基数2 0xd8941200
Dword b3; //基数3 0xffffffff
Dword b4; //4 0xc0571600
Dword b5; //5 0xc4571600
char username[13]; //用户名长度最多12位
char password[13]; //密码长度最多位12位
}
--------------------------------明文包结构说明-------------------------------
这里假设用户名位;tangtangtang密码为jingjingjing
登陆包结构:长度固定56个字节。
80 00 00 00 | 00 00 00 00| t a n g | t a n g | t a n g | j i n g | j i n g | j i n g |
↑ ↑ --------------------------- ---------------------------
logincommand count user name password
70 00 00 00 | 00 00 00 00| d8 94 12 00 | ff ff ff ff | c0 57 16 00 | c4 57 16 00 |
-------------- ------------------------------------------------------------
w b1 b2 b3 b4 b5
变化中,不知道是怎么来的
---------------------------------加密算法--------------------------------
int b=0x00d926c2; //每次加密4个字节的时候初始化的key,加密下4个字节的时候重新初始化为这个
int a; //加密下一个字节需要保存的key
int buf[5]={0x80,0x00,0x00,0x00};//待加密的字符串
int jiami[5]; //加密完成
int abc;
for(int q=0;q<4;q++)
{
a=b;
a=a>>4;
a=a&0xff;
abc=buf[q]^a;
jiami[q]=abc;
a=abc+b*2;
a=a*0x00409042;
a=a-0x0024fae3;
b=a;
printf("%x",jiami[q]);
buf[q]=jiami[q];
}
///算法可以简化,我是随手写的 要注意的是,最后20个字节,分5组加密,包序号为0时加密一次,1加密2次
附带一个结果
80 00 00 00 加密后正确的是 EC DF 50 57
解密算法
解密和加密一样4字节分组算法。
算法稍微有点不一样
数据包结构还不清楚,
算法,取的服务器返回的,数据包长度然后每4个字节分别解密码
int key=0x00c926c2;
int daijiemi[1000]={0xEC,0xDF,0x50,0x57};
int shuchu[1000];
for(int i=0;i<4;i++)
{
int temp;
shuchu[count+i]=daijiemi[count+i]^((key>>4)&0xff);
key=((daijiemi[count+i]+key*2)*0x00409042)-0x0024fae3;
printf("%x ",shuchu[count+i]);
}
struct
{
dword logincommand; //前4个字节解密后0x80 代表服务器返回的是登陆信息包
}
因为但是没有继续下去,不知道后面游戏的加密方式是否不同,
写了个简单的测试程序.