星痕共鸣的一些数据分析
抓包分析报告 本文针对星恒共鸣交易中心的网络数据包进行了抓取和分析。数据包包含多个交易物品信息,通过解析发现:1) 数据包头部包含包大小等信息;2) 主体数据由多个0x12开头的物品信息段组成;3) 每个物品段包含ID、数量和最低价格三个关键字段。研究提出基于Varint编码的解析算法,通过逐字节处理实现数据提取。实验结果表明,该方法能有效解析交易物品的ID(如0x96a13e)、数量(如0xa9
·
抓包实验
抓包目标为星恒共鸣交易中心内容
char peer0_2[] = { /* Packet 10 */
0x00, 0x00, 0x00, 0x94,
0x00, 0x06, 0x00, 0x00, 0x39, 0x91,
0x00, 0x00,
0x00, 0x8a, 0x00, 0x03,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x10, 0x46,
0x00, 0x00, 0x00, 0x00,
0x0a, 0x76,
0x12, 0x0b, 0x08, 0x96, 0xa1, 0x3e, 0x10, 0xa9, 0x06, 0x18,
0xe4, 0xaf, 0x01, 0x12, 0x0a, 0x08, 0x97, 0xa1,
0x3e, 0x10, 0xe0, 0x04, 0x18, 0x98, 0x75, 0x12,
0x0a, 0x08, 0x98, 0xa1, 0x3e, 0x10, 0xc7, 0x06,
0x18, 0x98, 0x75, 0x12, 0x04, 0x08, 0xf7, 0xa1,
0x3e, 0x12, 0x0b, 0x08, 0xf8, 0xa1, 0x3e, 0x10,
0xec, 0x03, 0x18, 0x80, 0xe1, 0x01, 0x12, 0x04,
0x08, 0xf9, 0xa1, 0x3e, 0x12, 0x0a, 0x08, 0xfa,
0xa1, 0x3e, 0x10, 0x01, 0x18, 0x8c, 0xf6, 0x01,
0x12, 0x0a, 0x08, 0xfb, 0xa1, 0x3e, 0x10, 0x03,
0x18, 0xf8, 0xd2, 0x01, 0x12, 0x04, 0x08, 0xfc,
0xa1, 0x3e, 0x12, 0x0b, 0x08, 0xfd, 0xa1, 0x3e,
0x10, 0x8e, 0x01, 0x18, 0x88, 0xef, 0x01, 0x12,
0x0b, 0x08, 0xfe, 0xa1, 0x3e, 0x10, 0xeb, 0x04,
0x18, 0xfc, 0xd9, 0x01 };
包分析粗略结果
| 字节位 | 备注 |
|---|---|
| 1-4 | 包大小 |
| 5-10 | 疑似上一数据包包末数据位+关系 |
| 11-30 | 意义不明 |
| 之后 | 数据片段 |
数据片段分析结果
0x12, 0x0b, 0x08, 0x96, 0xa1, 0x3e, 0x10, 0xa9, 0x06, 0x18, 0xe4, 0xaf, 0x01,
0x12, 0x0a, 0x08, 0x97, 0xa1, 0x3e, 0x10, 0xe0, 0x04, 0x18, 0x98, 0x75,
0x12, 0x0a, 0x08, 0x98, 0xa1, 0x3e, 0x10, 0xc7, 0x06, 0x18, 0x98, 0x75,
0x12, 0x04, 0x08, 0xf7, 0xa1, 0x3e,
0x12, 0x0b, 0x08, 0xf8, 0xa1, 0x3e, 0x10, 0xec, 0x03, 0x18, 0x80, 0xe1, 0x01,
0x12, 0x04, 0x08, 0xf9, 0xa1, 0x3e,
0x12, 0x0a, 0x08, 0xfa, 0xa1, 0x3e, 0x10, 0x01, 0x18, 0x8c, 0xf6, 0x01,
0x12, 0x0a, 0x08, 0xfb, 0xa1, 0x3e, 0x10, 0x03, 0x18, 0xf8, 0xd2, 0x01,
0x12, 0x04, 0x08, 0xfc, 0xa1, 0x3e,
0x12, 0x0b, 0x08, 0xfd, 0xa1, 0x3e, 0x10, 0x8e, 0x01, 0x18, 0x88, 0xef, 0x01,
0x12, 0x0b, 0x08, 0xfe, 0xa1, 0x3e, 0x10, 0xeb, 0x04, 0x18, 0xfc, 0xd9, 0x01
将数据格式化后可以看出大致规律
0x12:数据起始位置(这里后面接本段数据长度+道具ID)
0x10:标志道具数量
0x18:标志当前道具的最低价格
解析结果
0x12, 0x0b, 0x08, 0x96, 0xa1, 0x3e, 0x10, 0xa9, 0x06, 0x18, 0xe4, 0xaf, 0x01,
拆解为(注意事项:标志位长度不固定,必须通过遍历进行解析)
道具ID:0x0b, 0x08, 0x96, 0xa1, 0x3e
道具数量:0xa9, 0x06
最低价格:0xe4, 0xaf, 0x01
解析算法
int parse_varint(const char* data, int count) {//返回解析后的数值
int value = 0;
int shift = 0;
for (int i = 0; i < count; i++) {
char byte = data[i];
value |= ((byte & 0x7F) << shift);
shift += 7;
}
return value;
}
解析示例
char t[]={0x0b, 0x08, 0x96, 0xa1, 0x3e};
int num=parse_varint(t,5);
printf("道具ID:%d",num)
完整测试代码
#include<iostream>
#include<vector>
char peer0_2[] = { /* Packet 9 */
0x00, 0x00, 0x00, 0x93, 0x00, 0x06, 0x00, 0x01,
0xd6, 0x71, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x84,
0x00, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x12, 0x0b,
0x08, 0x96, 0xa1, 0x3e, 0x10, 0x94, 0x06, 0x18,
0x88, 0xa4, 0x01, 0x12, 0x0a, 0x08, 0x97, 0xa1,
0x3e, 0x10, 0x8e, 0x05, 0x18, 0x98, 0x75, 0x12,
0x0a, 0x08, 0x98, 0xa1, 0x3e, 0x10, 0xf6, 0x06,
0x18, 0x98, 0x75, 0x12, 0x04, 0x08, 0xf7, 0xa1,
0x3e, 0x12, 0x0b, 0x08, 0xf8, 0xa1, 0x3e, 0x10,
0xe1, 0x03, 0x18, 0xf0, 0xc4, 0x01, 0x12, 0x04,
0x08, 0xf9, 0xa1, 0x3e, 0x12, 0x0a, 0x08, 0xfa,
0xa1, 0x3e, 0x10, 0x06, 0x18, 0x8c, 0xf6, 0x01,
0x12, 0x0a, 0x08, 0xfb, 0xa1, 0x3e, 0x10, 0x06,
0x18, 0x88, 0xef, 0x01, 0x12, 0x04, 0x08, 0xfc,
0xa1, 0x3e, 0x12, 0x0a, 0x08, 0xfd, 0xa1, 0x3e,
0x10, 0x03, 0x18, 0x88, 0xef, 0x01, 0x12, 0x0b,
0x08, 0xfe, 0xa1, 0x3e, 0x10, 0xb2, 0x03, 0x18,
0x88, 0xef, 0x01 };
int parse_varint(const char* data, int count) {
int value = 0;
int shift = 0;
for (int i = 0; i < count; i++) {
char byte = data[i];
value |= ((byte & 0x7F) << shift);
shift += 7;
}
return value;
}
class infs_1
{
public:
int itemid;
int count;
int min_money;
int load(const char*t1)
{
if (t1[1] == 0x04)
{
this->itemid = parse_varint(t1 + 3, 3);
this->count = 0;
this->min_money = 0;
return 6;
}
else
{
this->itemid = parse_varint(t1 + 3, 3);
int s1 = 0;
for (int i = 7; i < t1[1] + 2; i++)
{
if (t1[i] == 0x18)
{
this->count = parse_varint(t1 + 7, i - 7);
s1 = i + 1;
}
}
this->min_money = parse_varint(t1 + s1, t1[1] + 2 - s1);
return (int)(t1[1] + 2);
}
return true;
}
infs_1()
{
}
};
class page {
public:
std::vector<infs_1*> vec;
int length;
int ID;
int XL;
int D_length;
int sjq;
int unknow1;
int unknow2;
char start_bs[2];
int load_sp(const char*t1, int pos1)
{
int pos = pos1;
while (true)
{
if (pos >= this->length - 1)
return 0;
//printf("%x %d %d\n", t1[pos],pos,this->length);
if (t1[pos] != 0x12)
return 0;
infs_1 *t = new infs_1();
pos += t->load(t1 + pos);
vec.push_back(t);
}
return 0;
}
int load(const char *t1)
{
int pos = 0;
int *tmp_val = NULL;
{
tmp_val = &(this->length);
*tmp_val = 0;
for (int i = 0; i < 4; i++)
{
*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
}
pos += 4;
}
{
tmp_val = &(this->ID);
*tmp_val = 0;
for (int i = 0; i < 4; i++)
{
*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
}
pos += 4;
}
{
tmp_val = &(this->XL);
*tmp_val = 0;
for (int i = 0; i < 4; i++)
{
*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
}
pos += 4;
}
{
tmp_val = &(this->D_length);
*tmp_val = 0;
for (int i = 0; i < 4; i++)
{
*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
}
pos += 4;
}
{
tmp_val = &(this->sjq);
*tmp_val = 0;
for (int i = 0; i < 4; i++)
{
*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
}
pos += 4;
}
{
tmp_val = &(this->unknow1);
*tmp_val = 0;
for (int i = 0; i < 4; i++)
{
*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
}
pos += 4;
}
{
tmp_val = &(this->unknow2);
*tmp_val = 0;
for (int i = 0; i < 4; i++)
{
*tmp_val = (*tmp_val << 4) | (t1[pos + i] & 0xFF);
}
pos += 4;
}
{
for (int i = 0; i < 2; i++)
{
this->start_bs[i] = t1[pos + i];
}
pos += 2;
}
load_sp(t1, pos);
return 0;
}
};
void main()
{
page t;
int pos = t.load(peer0_2);
//printf("%d\n", t.vec.size());
//printf("%d\n%d\n%d\n%d\n%d\n%d\n%d\n", t.length, t.ID, t.D_length, t.sjq, t.unknow1, t.unknow2);
for (int i = 0; i < t.vec.size(); i++)
{
infs_1 *t1 = t.vec.at(i);
printf("ID:%10d 数量:%6d 最低价:%6d \n", t1->itemid, t1->count, t1->min_money);
}
getchar();
}
输出
包关系分析
下图为客户端包和服务器包分析
客户端包1-4字节暂时意义不明,5-10字节会与服务器包成一定关系,抓包显示客户端包后9-10字节在每次发起tcp连接后会自增(用C++重发包,服务器会拒绝你的连接),猜测算法可能是在登录时确定了一个数字,每次自增来防止作弊(可以尝试断网获取最后一次包末数字,再重连检查数字变化规律)
更多推荐
所有评论(0)