游戏安全实验室 首页 外挂分析 查看内容

【外挂分析】游戏安全之扫拍外挂

发布于:2017-9-8 14:18   |    171429次阅读 作者: 管理员    |   来自: 外部投稿

天下武功,唯快不破,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;

}

...

...

...

这里只展示部分技术研究测试代码,以防止对游戏造成伤害。

有兴趣的同学可以自行研究。



来源:外部投稿

*转载请注明来自游戏安全实验室(GSLAB.QQ.COM)

分享到:
踩0 赞8

收藏

上一篇:【外挂分析】触动精灵初步分析报告

下一篇:【外挂分析】游戏无敌功能外挂分析

相关阅读
最新评论
引用 寂寞小骷髅 2017-9-12 21:07
唯快不破,的确是这样,鸟老师讲的真好,玩转收发包就是666
引用 月魂 2017-9-12 13:11
6666
引用 小小虾 2017-9-8 16:56
老师棒棒哒
引用 cc 2017-9-8 15:52
引用 cc 2017-9-8 15:52
引用 任鸟飞 2017-9-8 14:47

查看全部评论(6)

B Color Image Link Quote Code Smilies

发表评论

top 问题反馈

返回顶部