发布于:2017-9-8 14:18 | 196804次阅读 作者: 管理员 | 来自: 外部投稿
天下武功,唯快不破,1-2ms的延时都会决定成败,所以更多的外挂高手,在写扫拍挂,抢怪挂和躲避技能挂等极度追求速度的外挂时,往往都是从收包函数入手的。 为什么呢?快!客户端是先收到封包,然后对封包解密,再将信息分配写入内存,最后通过写屏等函数显示到我们面前的。 由此可见,收包最快,内存次之,模拟最慢。
以扫拍为例 处理的思路很简单,开两条线程 一条线程不断的发送刷新拍卖行封包(不懂怎么发送封包?不懂怎么分析封包?以后会有专题讲解),注意频率,一般情况下服务器都会有验证,高频率发包会被踢下线。10ms刷新一次 ,还是30ms刷新一次 要自己测试服务器的设定,应该是低于40ms,一会就会掉线。细心的同学应该会想到,那这个刷新延时40ms没有办法去掉吗?这是个不短的时间啊,只有一个办法,开多个账号同时扫拍,概率学告诉我们,如果10个账号同时扫拍,那么每个刷新封包的间隔就变成了4ms左右。
另外一条线程,HOOK收包函数,对收到的封包进行解密,判断到是我们需要的封包信息时发送购买封包。 hook recv 我们不需要HOOK函数本身,hook函数调用结束的位置即可,返回的eax是真实接收的包长,buffer里是接收到的封包。 封包解密,我们需要找到游戏的解密CALL,方法很简单,在加密封包上下访问断,游戏想解密加密封包,就一定会访问加密封包,在断下的位置一一分析即可,当然不排除多次的memmove,那样我们就要到新的内存上继续下访问断。 值得提的是,如果解密CALL没有被严重VM那么还是把功能偷出来自己解密更效率也更妥当。 判断封包就很简单了,通过包头字节可以判断出来封包的信息,封包里会有商行物品的所有信息,满足我们要求的物品,毫不犹豫,买!当然解密之后的封包也有可能不是一个包,可能存在粘包,我们还需要根据包头的buffersize 进行拆包等等简单的操作。 做了以上的所有操作,在网络足够优秀的前提下,扫拍,抢怪,躲避技能是多么简单的一件事,例如天涯明月刀抢怪,LOL躲避技能,都是一样的思路。
***************************************刷新商行信息线程
void Refresh() { byte p[]={0x10, 0x00, 0xF7, 0x03, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x01, 0x01,\ 0x03, 0x30, 0x20, 0x30, 0x00}; //刷新商行封包 HMODULE 窗口句柄=GetModuleHandleA("3DRole.dll"); DWORD Base=(DWORD)窗口句柄+0x837318; DWORD CallAddr=(DWORD)窗口句柄+0x25E9C2; char * P=(char *)p;
__asm //调用明文发包CALL 进行发包 { pushad push 0x10 push P mov ecx,Base mov eax,CallAddr call eax popad } DbgPrint_Mine("发送刷新封包"); } void 刷新线程() { AAA=0; while (AAA==0) { Refresh(); Sleep(45);//控制在 40以上 否则会掉线 } }
********************************************HOOK recv
void Hook() //HOOK收包 { DWORD dwHookAddr = (DWORD)Handle+0x263A4C; DWORD dwTargetAddr = (DWORD)HookCall; EnableDebugPrivilege(TRUE);//提升EXE权限 DWORD h窗口句柄=*(DWORD*)((DWORD)Handle+0x88E9B4); DbgPrint_Mine("窗口句柄:%x",h窗口句柄); DWORD pid=NULL; DWORD WriteSize=NULL; GetWindowThreadProcessId((HWND)h窗口句柄,&pid);//获得进程ID g_进程ID=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);//打开进程 DbgPrint_Mine("进程ID:%x",g_进程ID); byte Temp=0xE9; WriteProcessMemory(g_进程ID,(LPDWORD)(dwHookAddr + 0x00),&Temp,1,&WriteSize); DWORD Temp1=dwTargetAddr - dwHookAddr - 5; WriteProcessMemory(g_进程ID,(LPDWORD)(dwHookAddr + 0x01),&Temp1,4,&WriteSize); byte Temp2=0x90; WriteProcessMemory(g_进程ID,(LPDWORD)(dwHookAddr + 0x05),&Temp2,1,&WriteSize); }
************************************************信息判断
__declspec(naked) void HookCall()//裸函数 HOOK明文包子程序 { __asm { push eax mov eax,[ebp-0x8] mov g_包地址,eax mov eax,[ebp-0x24] add g_包地址,eax add g_包地址,0xC mov eax,[ebp-0x4] mov g_包长,eax pop eax pushad } do { w标志位1=*(WORD*)(g_包地址+0x2); w标志位2=*(WORD*)(g_包地址+0x8); if (w标志位1==0x03F7&&w标志位2==0x01EA) { w标志位3=*(WORD*)(g_包地址+0xC); if (w标志位3==0x2030) { //DbgPrint_Mine("包 最低价格是系统!!!"); i=0; do { b标志位4=*(BYTE*)(g_包地址+0xE+i); i=i+1; } while (b标志位4!=0x20);
ID=atoi((char*)(g_包地址+0xE)); 金币=atoi((char*)(g_包地址+0xE+i+0x7)); if (金币<5000&&金币>0) { DbgPrint_Mine("包 i:%d ID:%d 金币:%d ",i,ID,金币); WORD 包长A=0x17; BYTE 包长B=0xA; if (i==3) { 包长A=0x18; 包长B=0xB; } if (i==4) { 包长A=0x19; 包长B=0xC; } ... ... ... 这里只展示部分技术研究测试代码,以防止对游戏造成伤害。 有兴趣的同学可以自行研究。 来源:外部投稿 |
最新评论
查看全部评论(6)
发表评论