角色删除数据包的分析
删除发送的数据:
删除发送又会收到个当前人物数据包
前面是名字,后面不知道是啥,首先猜测这后面没有用,一看是看不出这个包是个啥,后面倒是有点规律
换个号看看 发现后面没啥变化
先试一下直接06 这一串能不能
bool NetClient::delRole(wchar_t* rolename)
{
CString _name = L"zzz";
int len = _name.GetLength()+1;
len = len * 2;
len = len + 1;
char* buff = new char[len];
buff[0] = 0x06;
memcpy(buff, _name.GetBuffer(), _name.GetLength() * 2);
return winSock->MySend(buff, len);
}
没啥反应,服务器改变不理,,发了没回应,后面的也是有用的 (删除角色也做这么复杂,,
直接当做常量处理试试(因为涉及到内存对齐,只能都用int来搞下)
typedef struct DATA_DELROLE
{
int un0 = 0x875B0000;
int un1 = 0x55FE0816;
int un2 = 0x011B;
int un3 = 0x0800;
int un4 = 0x1000;
int un5 = 0x0100;
int un6 = 0x0300;
int un7 = 0x64830500;
int un8 = 0x19EDA002;
int un9 = 0x6317bd00;
int una = 0x66346b02;
int unb = 0x66348C02;
int unc = 0x19ECD402;
}*PDATA_DELROLE;
bool NetClient::delRole(wchar_t* rolename)
{
DATA_DELROLE _data;
CString _name = L"zzz";
int len = _name.GetLength()+1;
len = len * 2;
len = len + 1;
char* buff = new char[len+sizeof(_data)];
buff[0] = 0x06;
memcpy(buff+1, _name.GetBuffer(),len-1);//拷贝名字
memcpy(buff + len, &_data, sizeof(_data));//拷贝数据
return winSock->MySend(buff, len);
}
这样操作一波发现还是没啥用
比对下数据包,,
第二个包还多出一段来了,在看一个
可能和时间有关系 改下系统时间试试,还是看不出是个啥
这样模拟应该是过不去了,再看看有啥思路..
有很多变量,要确定这些变量到底对不对,我们先劫持它的删除的数据,去破坏它的变量,把他的变量破坏了他发不出去,是一种情况,如果还能发出去,就又是另一种情况了
先把删除数据的网络包屏蔽掉,服务器收不到就删不了了,那就可以拿一个号反复的删,就能看不到太多干扰元素了
//删除角色
bool OnDelRole(char*& buff, unsigned& len)
{
return false;
}
SendDealProc[I_DELROLE] = &OnDelRole;
挂上回调函数,让服务器接收不到这个删除角色的包- -
发现这个后面都是一样的,而会根据名字长度往后扩张。。。估计就是未初始化的内存
重新打开客户端,发现后面的就变了。那就可以假定这个是未初始化,值是不可控的,后面一串没变,那应该有特殊的意义
这个刚好就是 角色名字长度 ,也就是说,从这个地方开始就是有效的值了
这个很像栈的地址 比较倾向于是无效数据
前面算上06 就刚好24个字节 后面应该都是无效字节
再创个号看看
那前面的01 08都是没有用的 就是说 这个数据最长就是到这个长度的前面了
那么算上前面,刚好就是32个 也就是 0x20 比较反常的是这个头部占用了buff的内容,本来头部是单独加的
那么这个没对齐可能是因为把头部丢buff里 写代码的时候算错了 导致这里空了个出来,后面可能也是无效数据
重新定义下这个角色数据删除的结构
typedef struct DATA_DELROLE
{
char buff[0x20];
unsigned len;
unsigned un0 = 0x01;
unsigned un1 = 0x03;
unsigned un2[0x06];
}*PDATA_DELROLE;
bool NetClient::delRole(wchar_t* rolename)
{
CString _name = L"zz";
DATA_DELROLE _data;
_data.buff[0] = 0x06;
int len = _name.GetLength()+1;
len = len * 2;
_data.len = len;
memcpy(_data.buff+1, _name.GetBuffer(),len);//拷贝名字
return winSock->MySend((char*)&_data, sizeof(_data)-1);
}
不加上后面那6个没啥用的就没删掉, 加上了就删掉了,难道是和结构体大小来判定?
再把-1去掉 发现没删掉 那就是以== 作为判定删除角色
那我们就来封装下,,
bool NetClient::DelRole(wchar_t* rolename)
{
PROLEDATA _role = GetRoleByName(rolename);
if (_role == nullptr)return false;
else return DelRole(rolename,_role->name.lenth);
}
PROLEDATA NetClient::GetRoleByName(wchar_t* rolename)
{
PROLEDATA result = nullptr;
for (int i = 0; i < rolecount; i++)
{
if (StrCmpW(roles[i].name.value(), rolename) == 0)return &roles[i];
}
return result;
}
bool NetClient::DelRole(wchar_t* rolename, unsigned _len)
{
DATA_DELROLE _data;
_data.buff[0] = 0x06;
_data.len = _len;
memcpy(_data.buff+1,rolename,_len);
return winSock->MySend((char*)&_data, sizeof(_data)-1);
}
直接调用就删掉了
再弄个虚函数管理他
bool OnDelRole(char*& buff, unsigned& len)
{
PDATADELROLE p = (PDATADELROLE)buff;
return Client->OnDelRole((wchar_t*)(p->buff+1),p->len);
}
就ok了