某游戏通信内容抓包,丑陋的编码,被我破了

2 篇文章 0 订阅
1 篇文章 0 订阅

2004年底破掉的东西:

<pre>

 

"dANNNNNNNNNfNNx[NSE>NNN[NNNN_EbU>l^VRAKXNhVTmN@mTNNN" "BANNNNNNNNNZN>_^N_A>/Ad/NJANGNTwVpANGN>/NJANtTfAdDNmtTfAdDNm"
 
"dNNNNNNNNNNzNTwNNASjrWnI[cprgNNNNNNNNNNNNNNNGNNN" "dNNNNNNNNNNzNTw>NESjrWnIQzjrgNNNNNNNNNNNNNNNGNNN" "dNNNNNNNNNNzNTwTNuSjrWnIDfzrgNNNNNNNNNNNNNNNGNNN" "dNNNNNNNNNNzNTwS>NSjrWnIifjrgNNNNNNNNNNNNNNNGNNN" "dNNNNNNNNNNzNTwV>ASjrWnIXI]cOANNNNNNNNNNNNNNGNNN"
"dNNNNNNNNNNzNTwU>ESjrWnI;zrcOANNNNNNNNNNNNNNGNNN" "dNNNNNNNNNNzNTwJ>uSjrWnI<fzrgNNNNNNNNNNNNNNNGNNN" "dNNNNNNNNNNzNTwlTNSjrWnIWoprgNNNNNNNNNNNNNNNGNNN" "dNNNNNNNNNNzNTwwTASjrWnItMbrgNNNNNNNNNNNNNNNGNNN" "dNNNNNNNNNNzNTwdTESjrWnIXIsdIANNNNNNNNNNNNNNGNNN"
</pre>

 

网络游戏 外挂 前年 解密 通信协议 编码

2004/12/6 23:26:02
这是我2003年6月写的东西,我想现在 游戏 《千年》已经作了很大的改动所以决定将此文件抛出,有兴趣的可以过来研究一下:
请大家在转载的时候指名出处,是对我分析工作的尊重,谢谢!
 
    下面程序的程序是对千年的通信协议进行分析,因为客户端与服务器之间的通讯是经过编码的,所以需要把编码的内容解码,解码后的内容将会包含真实的信息,该程序就是将通信协议解码。
附件中是C语言实现!
 
头文件:
//开始分析千年协议的时候,我以为是BASE64编码的,很快我就发现不是,后来我找到了编码规则!
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
 
//GH  GameHack
namespace GH {
 
  namespace PRIVATE {
    const static unsigned short base = 0x3B;
    const static int tab_len = 64;
 
    static char dtab[tab_len];
 
    const static BYTE etab[] = { //编码表
      0x4e, 0x3E, 0x54, 0x53, 0x56, 0x55, 0x4A, 0x6C,
        0x77, 0x64, 0x63, 0x42, 0x4D, 0x46, 0x6A, 0x6E,
        0x41, 0x4B, 0x62, 0x3F, 0x71, 0x78, 0x76, 0x79,
        0x65, 0x47, 0x7A, 0x66, 0x4C, 0x50, 0x3D, 0x5F,
        0x45, 0x52, 0x40, 0x5A, 0x5C, 0x61, 0x6D, 0x5D,
        0x43, 0x68, 0x67, 0x6F, 0x57, 0x44, 0x3B, 0x51,
        0x75, 0x58, 0x5B, 0x3C, 0x74, 0x6B, 0x70, 0x72,
        0x5E, 0x60, 0x69, 0x49, 0x48, 0x4F, 0x59, 0x73
    };
   
    void inittab();
  };
 
  size_t encode(const BYTE *src, char *dst, size_t len);
  size_t decode(const char* src, BYTE *dst, size_t len);
 
  void dumphex(const BYTE* str,size_t len);
  inline void init()
  {
    PRIVATE::inittab();
  }
}
 
//实现文件
namespace GH {
 
  void PRIVATE::inittab() {
    //初始化转化表
    int i;
    for(i=0; i<tab_len; i++)
      dtab[etab[i]-base]=i;
  }
 
    size_t  encode(const BYTE *src, char *dst, size_t len)
    {
      size_t i,j,k;
      BYTE tmp[4];
      int in,jn,kn;
 
      k = 0;
      for(i=0; i<len; i++){
        j = i%3;
        tmp[j] =  src[i];
        if (j==2) {
 
          /*
          * 形成第一个字节
          */
 
          in = (int) *tmp;
          in = in & 0X0FF;
          jn = in;
 
          /*
          * 保留in 最后两位,并左移4位 000000XX => 00XX0000
          */
          in = in & 3;
          in = in << 4;
 
          /*
          * 形成第一个字节00XXXXXX(FF变为3F)
          */
          jn = jn >> 2;
          dst[k++] = PRIVATE::etab[jn];
 

          /*
          * 形成第二个字节
          */
          jn = (int) *(tmp+1);
          jn = jn & 0X0FF;
          kn = jn;
 
          /*
          * kn右移四位,YYYYYYYY => 0000YYYY
          *      并与in进行或运算,形成了第二个字节
          *      00XXYYYY
          */
          kn = kn >> 4;
          kn = kn | in;
          dst[k++] = PRIVATE::etab[kn];
 
          /*
          * jn保留了四位字节,左移两位 0000YYYY => 00YYYY00
          */
 

          jn = jn & 0X0F;
          jn = jn << 2;
 
          /*
          * 形成第三个字节
          */
 
          in = (int)*(tmp+2);
          in = 0X0FF;
          kn = in;
 
          /*
          * kn右移六位000000ZZ,与jn或运算,得到00YYYYZZ
          *      第三个字节
          */
 
          kn = kn >> 6;
          kn = kn | jn;
          dst[k++] = PRIVATE::etab[kn];
 
          /*
          * 形成第四个字节,in保留底六位
          */
          in = 0X3F;
          dst[k++] = PRIVATE::etab[in];
 
          memset(tmp,0,4);
        }
      }
      return k;
 
    }
 
    size_t decode(const char* src, BYTE *dst, size_t len)
    {
      size_t i,j,k;
      char ch;
      BYTE tmp[4];
 
      k = 0;
      for(i=0; i<len; i++)
      {
        j=i%4;
        tmp[j] = PRIVATE::dtab[ src[i]-PRIVATE::base ];
        if( j==3 )
        {
          ch = tmp[0] << 2; /* 00XXXXXX => XXXXXXXX00 */
          ch += tmp[1] >> 4;/* 00XXYYYY => 00000000XX */
          dst[k++] = ch;
 
          ch = tmp[1] << 4; /* 00XXYYYY => YYYY0000 */
          ch += tmp[2] >> 2; /* 00YYYYZZ => 0000YYYY */
          dst[k++] = ch;
 
          ch = tmp[2]<< 6;   /* 00YYYYZZ => ZZ000000 */
          ch += tmp[3];     /* 00ZZZZZZ */
          dst[k++]=ch;
        }
      }
      return k;
    }
 
    void dumphex(const BYTE* str,size_t len)
    {
      size_t i,l;
      const size_t linelen = 16;
 
      size_t line = len/linelen;
 
      for (l=0;l<line+1;l++)
      {
        for(i=0;i<linelen;i++)
        {
          if(l*linelen+i<len)
            printf("%02X ",str[l*linelen+i]);
          else
            printf("   ");
        }
        printf("/n");
 
      }
 
      for(i=0;i<len;i++)
      {
        if(iscntrl(str[i]))
          printf(".");
        else
          printf("%c",str[i]);
      }
      printf("/n");
 
    }
 
}
 
 
 
void showhex(const BYTE* str)
{
char tmp[1024];
size_t l;
size_t len = strlen((const char*)str);
 
printf("Source(%d chars): /n",len);
GH::dumphex(str,len);
 
l= GH::decode((const char*)str,(BYTE*)&tmp[0],len);
printf("After Decoded(%d chars):/n",l);
GH::dumphex((const BYTE*)&tmp[0],l);
printf("/n/n");
}
 
int main(int argc,char* argv[])
{
  int i;
  if(argc<2)
  {
    printf("Usage:/n/t %s string1 string2 .../n",argv[0]);
    return 1;
  }
 
  printf("初始化解码表/n");
  GH::init();
 
  for(i = 1;i<argc;i++)
  {
    printf(".");
    showhex((const BYTE*)argv[i]);
  }
 

  return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值