首先,根据网友们的软文,可以知道qq的协议主要是基于tea加密算法的变种,tea算法网上代码很多,随便找一份贴在这里,以方便od调试的时候,知道重点关注那些东西。这是c代码,tea算法是每8个字节为一组进行加密的,腾讯的xxtea基础还是这个算法。
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}
//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
1,首先登陆协议因为有双进程守护,暂时先搁置。
2,分析聊天协议的时候,刚开始想着从发送消息入手进行分析,用od附加了qq之后,在send()上下断,之后再栈回溯寻找加密相关的函数进行分析,试了几次发现这个方法太折腾了,想到了可以收到消息之后,看他解密的过程,既然是消息,肯定是需药在收到之后进行解密的,那就在收消息的时候下断点,这块有个坑,收消息的时候,如果收到的消息是udp的,那么在recv()上下断点是可以断下来的,但是如果是udp的,这时候在recvfrom()上下断点是不行的,得在WSARecvFrom()上下断,但是测试的时候,大部分的消息其实都是tcp的,可能是因为测试的原因吧,毕竟tx聊天好像用udp协议多一些。
3,收到消息之后一步步跟是很费功夫的,收到消息之后,从收消息的socket函数出来,走几步之后可以看到有memcpy这个函数,会对收到的数据进行拷贝,这时候在目的地址上下内存访问断点,这时候跟踪会发现几次对拷贝到的数据的操作,是取出前面几个字节去进行数据匹配,tcp携带的数据的前几个字节是没有加密的,在将所有的未加密的数据取出来之后,剩下的密文。
4,接下来会继续调用memcpy再将剩下的密文进行拷贝到新的内存空间中去,这时候就是利用秘钥(堆栈中),对数据进行tx_xxtea解密的操作。这时候通过栈回溯可以知道加密解密函数的函数名。
5,打开熟悉的ida,寻找到这个解密的函数,分析一波伪代码。
这只是基本操作,秘钥的来源才是重点关注的东西。