给网站加个地图的代码,wordpress 扁平化,seo常用分析的专业工具,百度账号管理免责声明#xff1a;内容仅供学习参考#xff0c;请合法利用知识#xff0c;禁止进行违法犯罪活动#xff01;
如果看不懂、不知道现在做的什么#xff0c;那就跟着做完看效果
内容参考于#xff1a;易道云信息技术研究院VIP课
上一个内容#xff1a;33.游戏登录数据…免责声明内容仅供学习参考请合法利用知识禁止进行违法犯罪活动
如果看不懂、不知道现在做的什么那就跟着做完看效果
内容参考于易道云信息技术研究院VIP课
上一个内容33.游戏登录数据包分析利用
码云地址master 分支https://gitee.com/dye_your_fingers/titan
码云版本号6c3534735ead7eccb03aa3ba5762ac35c7821586
代码下载地址在 titan 目录下文件名为titan-登录数据包的监视与模拟.zip 链接https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg 提取码q9n5 --来自百度网盘超级会员V4的分享 HOOK引擎文件名为黑兔sdk升级版.zip 链接https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw 提取码78h8 --来自百度网盘超级会员V4的分享 以 33.游戏登录数据包分析利用 它的代码为基础进行修改 上一个内容里做了大量基础工作没有完成这次会利用上一个内容里数据包的分析结果完成登录监视与模拟
新加头文件 监控账号效果图模拟登录效果图没法看需要看代码注释以写好在 GameWinSock.cpp文件里的Onlogin函数里 监控登录的账号密码 监控登录失败 现在的配置现在已经把登录相关的搞好了可以监控、可以修改账号密码使用代码登录所以登录相关的数据包就不不需要在显示到列表里了如下图配置显示的值为否 新加NetClass.h文件
#pragma once
/*数据包还原结构体要注意内存对齐如果数据不满4字节它字段会补齐比如结构体里有一个char变量它是1字节在内存里它可能会为了内存对齐让它变成4字节所以这要注意
*/
// 登录数据
typedef struct DATA_LOGIN {int op 0x0300;char buff[0x10]{};int lenId 0x10;/*这个是登录的账号它可能会变成0x20或更长现在默认让它0x10读的时候以长度为准就好了*/char Id[0x10]{};int lenPass 0x10;/*这个是登录的密码它可能会变成0x20或更长现在默认让它0x10读的时候以长度为准就好了*/char Pass[0x10]{};int lenCode 0x10;char Code[0x10]{};int eop 0x01;
}*PDATALOGIN;NetClient.cpp文件的修改实现 login函数、loginfailed函数引入 extern_all.h头文件
#include pch.h
#include NetClient.h
#include extern_all.hbool NetClient::login(const char* Id, const char* Pass)
{const int bufflen sizeof(DATA_LOGIN) 1;char buff[bufflen];DATA_LOGIN data;// 有些操作系统这样写会报错因为内存不对齐现在Windows下没事//PDATALOGIN _data (PDATALOGIN)(buff 1);// 这样写就能解决内存对齐问题PDATALOGIN _data data;int len strlen(Id);memcpy(_data-Id, Id, len);len strlen(Pass);memcpy(_data-Pass, Pass, len);memcpy(buff1, _data, sizeof(DATA_LOGIN));buff[0] I_LOGIN;WinSock-OnSend(buff, sizeof(buff));return true;
}void NetClient::loginfailed(int code)
{CString txt;if (code 51001) {txt L登陆失败,易道云通行证不存在!;}else if (code 51002) {txt L登录失败,密码错误!;}else txt L未定义错误!;#ifdef Anlyanly-SendData(TTYPE::I_LOG, 0, txt.GetBuffer(), txt.GetLength()*2);
#endif
}
NetClient.h文件的修改logfailed函数的名字改成了loginfailed引入 NetClass头文件
#pragma once
#include NetClass.h
class NetClient // 监视客户端每一个操作
{
public:/*模拟登陆的方法Id是账号Pass是密码它要基于发送的方法实现因为我们没有连接socket的操作*/bool login(const char* Id, const char*Pass);
public:// 登陆失败参数是错误码void loginfailed(int code);
};
GameProc.cpp文件的修改
#include pch.h
#include GameProc.h
#include extern_all.h// typedef bool(GameWinSock::* U)(char*, unsigned);bool _OnRecv(HOOKREFS2) {unsigned* _esp (unsigned*)_ESP;_EAX WinSock-RecvPoint;WinSock-OnRecving((char*)_esp[1], _esp[2]);return true;
}bool _OnConnect(HOOKREFS2) {/*根据虚函数表做HOOK的操作截取 ecx 获取 winsock 的值(指针)*/unsigned* vtable (unsigned*)_EDX;//WinSock (GameWinSock *)_ECX;/*联合体的特点是共用一个内存由于 GameWinSock::OnConnect 的 OnConnect函数是 GameWinSock类的成员函数直接 vtable[0x34 / 4] (unsigned)GameWinSock::OnConnect; 这样写语法不通过所以使用联合体让语法通过*/union {unsigned value;bool(GameWinSock::* _proc)(char*, unsigned);} vproc;DWORD oldPro, backProc;VirtualProtect(vtable, 0x100, PAGE_EXECUTE_READWRITE, oldPro);/*vproc._proc GameWinSock::OnConnect; 这一句是把我们自己写的调用connect函数的地址的出来*/ vproc._proc GameWinSock::OnConnect; /*InitClassProc函数里做的是给指针赋值的操作InitClassProc(GameWinSock::_OnConnect, vtable[0x34/4]);这一句的意思是把GameWinSock类里的_OnConnect变量的值赋值成vtable[0x34/4]这个 vtable[0x34/4] 是虚表里的函数vtable[0x34/4]是游戏中调用connect函数的函数地址经过之前的分析调用connect是先调用了虚表中的一个函数然后从这个函数中调用了connect函数*/InitClassProc(GameWinSock::_OnConnect, vtable[0x34/4]);vtable[0x34 / 4] vproc.value;vproc._proc GameWinSock::OnSend;InitClassProc(GameWinSock::_OnSend, vtable[0x3C / 4]);vtable[0x3C / 4] vproc.value;VirtualProtect(vtable, 0x100, oldPro, backProc);return true;
}GameProc::GameProc()
{hooker new htd::hook::htdHook2();Init();InitInterface();
}void GameProc::LoadBase()
{LoadLibraryA(fxnet2.dll);
}void GameProc::Init()
{
#ifdef anlyanly new CAnly();
#endif/*这里的 WinSock 是0没有创建对象但是还是能调用Init函数这是因为Init函数里面没有用到this没用到就不会报错*/WinSock-Init(); Client new NetClient();
}void GameProc::InitInterface()
{LoadBase();// MessageBoxA(0, 1, 1, MB_OK);// 只会HOOK一次一次性的HOOKhooker-SetHook((LPVOID)0x10617046, 0x1, _OnConnect, 0, true);/*第一个参数是HOOK的位置第二个参数是HOOK的位置的汇编代码的长度用于保证执行的汇编代码完整第三个参数是HOOK之后当游戏执行到第一个参数的位置的时候跳转的位置*/hooker-SetHook((LPVOID)0x10618480, 0x1, _OnRecv);/*在这里绑定游戏处理数据包函数0x10618480函数然后0x10618480函数在上面一行代码已经进行了HOOK所以在调用_OnRecv函数指针时它就会进入我们HOOK*/InitClassProc(GameWinSock::_OnRecv, 0x10618480);
}
extern_all.cpp文件的修改新加 Client变量
/*此文件是用来存放全局变量、全局函数通用函数
*/
#include pch.h
#include extern_all.h
GameWinSock* WinSock nullptr;
GameProc* PGameProc nullptr;
NetClient* Client nullptr;
#ifdef Anly
CAnly* anly nullptr;
#endifvoid InitClassProc(LPVOID proc_addr, unsigned value)
{unsigned* writer (unsigned*)proc_addr;writer[0] value;
}extern_all.h文件的修改新加 Client变量、NetClient.h头文件
/*此文件是用来存放全局变量、全局函数通用函数
*/
#pragma once
#include GameWinSock.h
#include GameProc.h
#include CAnly.h
#include NetClient.hextern GameWinSock* WinSock;
extern GameProc* PGameProc;
extern NetClient* Client;
extern void InitClassProc(LPVOID proc_addr, unsigned value);#ifdef Anly
extern CAnly* anly;
#endifGameWinSock.h文件的修改新加 I_LOGIN宏、S_LOGINFAIL宏、S_LOGINOK宏
#pragma once#define I_LOGIN 0x2 // 登录#define S_LOGINFAIL 0x3 // 登录失败的返回数据包的头
#define S_LOGINOK 0x4 // 登录成功的返回数据包的头class GameWinSock
{typedef bool(GameWinSock::* PROC)(char*, unsigned);
public:unsigned* vatble;// 虚函数表unsigned un[17];unsigned RecvPoint; // 游戏recv之后调用处理一个数据包函数时的eax这里偏移是0x48
public:static PROC _OnConnect;static PROC _OnSend;static PROC _OnRecv;bool OnConnect(char* ip, unsigned port);bool OnSend(char* buff, unsigned len);bool OnRecving(char* buff, unsigned len);bool OnRecv(char* buff, unsigned len);void Init();
};
GameWinSock.cpp文件的修改修改了 OnConnect函数、OnSend函数、OnRecving函数、Init函数新加 Onlogin函数、Onloginfailed函数
#include pch.h
#include GameWinSock.h
#include extern_all.h
#include NetClass.htypedef bool(* DealProc)(char*, unsigned);DealProc SendDealProc[0x100];
DealProc RecvDealProc[0x100];GameWinSock::PROC GameWinSock::_OnConnect{};
GameWinSock::PROC GameWinSock::_OnSend{};
GameWinSock::PROC GameWinSock::_OnRecv{};bool DeafaultDeal(char*, unsigned) { return true; }// 登录数据包的处理
bool Onlogin(char * buff, unsigned len) { /* 修改账号密码len sizeof(DATA_LOGIN) 1;buff new char[len];DATA_LOGIN data;PDATALOGIN _data data;buff[0] 0x2;CStringA _id ;// 补充账号CStringA _pass ;// 补充密码memcpy(_data-Id, _id.GetBuffer(), _id.GetLength());memcpy(_data-Pass, _pass.GetBuffer(), _pass.GetLength());memcpy(buff 1, _data, len - 1);*//* 监控登录数据PDATALOGIN _data (PDATALOGIN)buff;CStringA _id _data-Id;_data (PDATALOGIN)(buff _data-lenId - 0x10);CStringA _pass _data-Pass;CStringA _tmp;// 请求登录 账号[% s]密码[% s] 这个内容别人在逆向的时候就会看到// 所以这种东西需要自己搞个编码来代替它_tmp.Format(请求登录 账号[%s]密码[%s], _id, _pass);
#ifdef Anlyanly-SendData(TTYPE::I_DIS, 1, _tmp.GetBuffer(), _tmp.GetAllocLength());
#endif*//*返回false游戏无法发送数据包原因看调用此此函数的位置 OnSend 函数if (SendDealProc[buff[0]]((buff 1), len - 1))*/return true;
}bool Onloginfailed(char*buff, unsigned len) { int* code (int*)buff[1];Client-loginfailed(code[0]);return true;
}// 这个函数拦截了游戏的连接
bool GameWinSock::OnConnect(char* ip, unsigned port)
{
#ifdef Anly// 长度24的原因它是宽字节要一个文字要2个字节一共是10个文字加上结尾的0是11个// 所以 11 乘以2然后再加2 anly-SendData(TTYPE::I_LOG, 0, L服务器正在连接。。。, 24);
#endif// this是ecxHOOK的点已经有ecx了WinSock this;bool b (this-*_OnConnect)(ip, port);// 下方注释的代码时为了防止多次注入导致虚函数地址不恢复问题导致死循环通过一次性HOOK也能解决/*unsigned* vtable (unsigned*)this;vtable (unsigned*)vtable[0];union {unsigned value;bool(GameWinSock::* _proc)(char*, unsigned);} vproc;vproc._proc _OnConnect;DWORD oldPro, backProc;VirtualProtect(vtable, 0x10x00, PAGE_EXECUTE_READWRITE, oldPro);vtable[0x34 / 4] vproc.value;VirtualProtect(vtable, 0x10x00, oldPro, backProc);*/return b;
}bool GameWinSock::OnSend(char* buff, unsigned len)
{/*这里就可以监控游戏发送的数据了*/#ifdef Anlyanly-SendData(TTYPE::I_SEND, buff[0], buff, len);
#endif/*数据包的头只有一字节所以它的取值范围就是0x0-0xFF*/if (SendDealProc[buff[0]]((buff), len)) {// 执行失败不让游戏发送数据包return (this-*_OnSend)(buff, len);}else {// 发送失败屏蔽消息return true;// 屏蔽消息}}bool GameWinSock::OnRecving(char* buff, unsigned len)
{// MessageBoxA(0, 11111111111111, 0, MB_OK);/*监控游戏接收的数据包*/
#ifdef Anlyanly-SendData(TTYPE::I_RECV, buff[0], buff, len);
#endifreturn RecvDealProc[buff[0]](buff, len);
}bool GameWinSock::OnRecv(char* buff, unsigned len)
{
//#ifdef Anly
// anly-SendData(1, buff, len);
//#endifreturn (this-*_OnRecv)(buff, len);
}void GameWinSock::Init()
{for (int i 0; i 0x100; i) {SendDealProc[i] DeafaultDeal;RecvDealProc[i] DeafaultDeal;}// 注册登录数据包处理函数// SendDealProc[I_LOGIN] Onlogin;// 注册数据登录失败数据包处理函数RecvDealProc[S_LOGINFAIL] Onloginfailed;RecvDealProc[S_LOGINOK] Onloginfailed;
}