PCQQ official算法逆向

news/2024/10/31 3:31:15/

在分析pcqq协议时,0836包里有一个official算法,经多次测试发现,如果这个算法没有或者错误,会导致账号被冻结或屏蔽。为了解决这个问题,我们要逆向这个算法
1.用od调试找到这个算法的汇编代码为

mov eax, [ebp+0Ch]
mov eax, [eax]
add eax, 08h
push eax
mov edx, [ebp+08h]
mov edx, [edx]
add edx, 08h
mov ecx, [ebp+10h]
mov ecx, [ecx]
add ecx, 08h
call 00000024Chmov esp, ebp
pop ebp
retn 000Chsub esp, 14h
mov eax, [edx]
push ebx
mov [esp+14h], ecx
mov ebx, 00000010h
mov ecx, [esp+1Ch]
push ebp
push esi
mov esi, [edx+04h]
mov edx, [ecx+04h]
mov [esp+0Ch], edx
mov edx, [ecx]
mov ebp, [esp+0Ch]
mov [esp+10h], edx
mov edx, [ecx+0Ch]
mov ecx, [ecx+08h]
push edi
bswap esi
bswap eax
mov edi, 9E3779B9h
mov [esp+1Ch], edx
mov [esp+18h], ecx
mov edx, esi
mov ecx, esi
shr edx, 05h
shl ecx, 04h
add edx, ebp
add ecx, [esp+14h]
xor edx, ecx
lea ecx, [esi+edi]
xor edx, ecx
add eax, edx
mov edx, eax
mov ecx, eax
shl edx, 04h
add edx, [esp+18h]
shr ecx, 05h
add ecx, [esp+1Ch]
xor edx, ecx
lea ecx, [eax+edi]
xor edx, ecx
lea edi, [edi-61C88647h]
add esi, edx
dec ebx
jne 00000041h
mov ebp, [esp+20h]
bswap esi
pop edi
bswap eax
mov [ebp+04h], esi
mov [ebp+00h], eax
mov eax, ebp
pop esi
pop ebp
pop ebx
add esp, 14h
retn 0004h

2.汇编找到了,但是怎么在代码里面调用呢?第一种办法:vs可以直接在_asm{}块中嵌套汇编代码。但是我的call 00000024h这一段不知道为什么会报错,所以只能用第二种办法了,就是直接翻译成c源码。
3.这时默默地打开了从看雪论坛买来的加密与解密第四版一书,看了两章,然后直接开干。代码如下

// test.cpp : 定义控制台应用程序的入口点。#include "stdafx.h"typedef unsigned char BYTE;BYTE* Long2Bytes(unsigned long n);
unsigned long Bytes2Long(BYTE *bytes);
BYTE* ReverseBytes(BYTE* data, int size);
void Official(BYTE *data, BYTE *key, BYTE *result);
BYTE* SubBytes(BYTE *bytes, int start, int count);
void PrintBytes(BYTE *bytes, int size);int _tmain(int argc, _TCHAR* argv[])
{BYTE *data = new BYTE[8]{1, 2, 3, 4, 5, 6, 7, 8};//要加密的数据BYTE *key = new BYTE[16]{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};//加密keyBYTE *result = new BYTE[8]{0};//加密结果Official(data, key, result);PrintBytes(result,8);delete[] data;delete[] key;delete[] result;getchar();return 0;
}
void PrintBytes(BYTE *bytes, int size){for (int i = 0; i < size; i++){printf("%d ",bytes[i]);}
}
void Official(BYTE *data, BYTE *key, BYTE *result){unsigned long eax = Bytes2Long(SubBytes(data,0,4));unsigned long esi = Bytes2Long(SubBytes(data, 4, 4));unsigned long var4 = Bytes2Long(ReverseBytes(SubBytes(key, 0, 4), 4));unsigned long ebp = Bytes2Long(ReverseBytes(SubBytes(key, 4, 4), 4));unsigned long var3 = Bytes2Long(ReverseBytes(SubBytes(key, 8, 4), 4));unsigned long var2 = Bytes2Long(ReverseBytes(SubBytes(key, 12, 4), 4));//printf("%lu %lu %lu %lu %lu %lu\n", eax,esi,var4, ebp, var3, var2);unsigned long edi = 0x9E3779B9;unsigned long edx = 0;unsigned long ecx = 0;for (int i = 0; i < 16; i++){edx = esi;ecx = esi;edx = edx >> 5;ecx = ecx << 4;edx += ebp;ecx += var4;edx = edx ^ ecx;ecx = esi + edi;edx = edx ^ ecx;eax += edx;edx = eax;ecx = eax;edx = edx << 4;edx = edx + var3;ecx = ecx >> 5;ecx += var2;edx = edx ^ ecx;ecx = eax + edi;edx = edx ^ ecx;edi -= 0x61C88647;esi += edx;}memcpy(result,Long2Bytes(eax), 4);memcpy(result+4, Long2Bytes(esi), 4);
}
BYTE* Long2Bytes(unsigned long n){BYTE *temp = new BYTE[4];temp[0] = n / 16777216;temp[1] = (n - temp[0] * 16777216)/65536;temp[2] = (n - temp[0] * 16777216 - temp[1] * 65536) / 256;temp[3] = (n - temp[0] * 16777216 - temp[1] * 65536-temp[2]*256);return temp;
}
unsigned long Bytes2Long(BYTE *bytes){unsigned long a =bytes[0] * 16777216;unsigned long  b = bytes[1] * 65536;unsigned long  c = bytes[2] * 256;unsigned long  d = bytes[3];unsigned long  n = a + b + c + d;return n;
}
//因为数据在内存中是从低到高存放的,所以要反取字节
BYTE* ReverseBytes(BYTE* bytes, int size){BYTE *temp = new BYTE[size];for (int i = 0; i < size; i++){temp[i] = bytes[size - i - 1];}return temp;
}
BYTE* SubBytes(BYTE* bytes, int start, int count){BYTE *temp = new BYTE[count];for (int i = 0; i < count; i++){temp[i] = bytes[start + i];}return temp;
}

4.在这里有个要注意的地方就是数字类型必须是unsigned long,否则会数据溢出,导致算法计算错误…坑


http://www.ppmy.cn/news/617544.html

相关文章

多元回归梯度下降算法实现(SGD优化)(数据集随机生成)

多元回归梯度下降算法实现&#xff08;SGD优化&#xff09;&#xff08;数据集随机生成&#xff09; 下面就是代码。其实博主做了很多实验&#xff0c;实验效果好不好&#xff0c;跟数据集的质量&#xff0c;跟学习率的选择&#xff0c;SGD 优化器batch的选择都很重要。 下面…

gitlab 配置QQ邮箱

gitlab 配置QQ邮箱 gitlab版本官方文档邮箱厂商需要修改的配置文件修改的配置内容调试控制台正确测试结果[rootxxxxxxxxxxxxxx gitlab]# gitlab-rails consoleGitLab: 11.2.3 (06cbee3) GitLab Shell: 8.1.1 postgresql: 9.6.8 gitlab版本 我安装的是ee版11.2.3&#xff0c;跟…

qq协议 0825 和 0836 udp 登录包解析

qq协议 0825 和 0836 udp 登录包解析 参考使用工具:概念解释udp报文解析0825 udp 发送包报文原始数据:解析 0825 返回包原始数据解析 0836 发送包原始数据解析 参考 0825包参考: https://www.cnblogs.com/mRRRR/p/5288931.html 虽然是2016年的, 但是里面的结构大体还是不变 参…

查询QQ会员账号信息API接口

接口地址&#xff1a; https://api.hackeus.cn/api/qqvip 请求协议&#xff1a; HTTP、HTTPS 请求方式&#xff1a; GET/POST 返回格式&#xff1a; JSON 请求示例&#xff1a; https://api.hackeus.cn/api/qqvip?api_key您的apiKey&qq598765401&skeyHackApi 请求…

ros 如何禁止qq

ros是个非常好用的路由设备&#xff0c;我用它实现了公司的带宽管理&#xff0c;有效保障了视频会议和业务应用的带宽。但是ros没有完善的应用管理功能&#xff0c;一直想用ros实现禁止qq的功能&#xff0c;网上查了查&#xff0c;内容很乱&#xff0c;于是自己动手抓包试验。我…

【matlab之QQ图】

文章目录 1.QQ图原理&#xff1a;2.效果图&#xff1a;3.代码: 1.QQ图原理&#xff1a; 数据中一串数目的每个点都是该数据的某分位点&#xff0c;把这些点的&#xff08;称为样本分位数点&#xff09;和相应的理论上的分位数配对做出散点图&#xff0c;如果该数据服从正态分布…

Shell 脚本配置发送QQ邮件

文章目录 方法一1进入QQ邮箱网页界面客服端2用root用户&#xff0c;执行脚本 方法二&#xff1a; 方法一 1进入QQ邮箱网页界面客服端 ①点击设置 》点击账户 ② 开启SMTP服务 》生成授权码 2用root用户&#xff0c;执行脚本 #!/bin/bash. /etc/init.d/functionsif [ $# -…

AndroidQQ登录

AndroidQQ登录 一、注册腾讯开放平台账号 1. 在腾讯开放平台注册账号获取开发者资格&#xff1a;http://open.qq.com/ 2. 注册完成后点击右上角的管理中心&#xff0c;点击右下角的创建应用 3. 创建应用之后就会获取到APPID和APPKEY 4. 下载SDKjar包&#xff1a;http://wi…