LOSTARK调试的建议(该部分不需要可以不看)

这个游戏,在有的系统或则电脑上,当我们用DBG 附加并且下断断下的时候,会出现鼠标键盘卡顿的情况。

(不是轻微的卡顿,是完全没有办法控制)

即使用了驱动工具,也是一样的。

这种情况,一般是由于鼠标键盘钩子导致的,我们可以用PCH,XT等工具查看钩子并且进行还原处理,但是工具也不是百分百可以处理好的。

不过还有另外一种更简单一些的办法,那就是尝试砍掉他相应的检测线程。

这种线程可以实时检测到我们,而不是间歇性的

那么有2个特点必须满足

一是单独放到一个线程的可能大

二是执行优先级比较高和执行频率要比较快

根据这样的特点,我们到游戏中看一下线程

Lua人物瞬移_瞬移

我们按照优先级排列一下

Lua人物瞬移_瞬移_02

由于上面2点原因,这里面我们优先实时优先级的线程,如果不行再考虑高优先级的线程

这里面有3个实时线程

我们砍掉其中一个发现断下不在卡顿了

Lua人物瞬移_瞬移_03

那么我们的目的就达到了,是不是很简单

当然调试能达到效果即可,不用像软件那么严谨。

朝向

朝向我们要找一下,毕竟,你瞬移不是乱瞬移,要往固定方向(例如寻路过程中的身前)

游戏逆向中,人物朝向属性一般都在人物坐标附近,就好像蓝量一般都会在血量附近一个道理!

但是这个游戏偏移有那么一丢丢大,我们在之前找到的坐标附近观察了半天没看出来。

于是选择CE扫描,

通过不断转换人物朝向,CE搜索变化的值,

找到一个0----FFFF的值。 修改可以改变人物朝向,

发现在我们之前找的坐标下面,不过偏移大一点,

表达式:

朝向 = *(DWORD*)(*(QWORD*)(对象2 + 0x90) + 0x4B4);

4B4的偏移 我们没有看到也算正常。

改变朝向,根据坐标方位分析得出结论:

X正朝向为0 和FFFF(朝向必有一个朝向是最大值和最小值重叠的)

Y正朝向为 3FFF

X负朝向 7FFE

Y负朝向 BFFD

注意:我们这里面为了锻炼 x 和 y 的理解 画出来的坐标系 不是标准坐标系

而是 纵轴X 横轴 Y

Lua人物瞬移_瞬移_04

这样朝向就分析清楚了

Lua人物瞬移_瞬移_05

瞬移

直接修改人物坐标就可以达到瞬移的效果,但是只能短距离瞬移,如果长距离瞬移,会被服务器修正回来。

事实上,如果不做发包动作的话,短距离瞬移也只是本地的效果,服务器是接收不到的

简单的瞬移代码如下:

void Call_瞬移(FLOAT X, FLOAT Y, FLOAT Z)
{
	extern QWORD 角色基地址2;
	QWORD Temp = *(QWORD*)角色基地址2;
	Temp = *(QWORD*)(Temp + 0x440);
	QWORD 对象2 = *(QWORD*)(Temp + 0x18);

	*(FLOAT*)(*(QWORD*)(对象2 + 0x90) + 0x7C) = X;
	*(FLOAT*)(*(QWORD*)(对象2 + 0x90) + 0x80) = Y;
	*(FLOAT*)(*(QWORD*)(对象2 + 0x90) + 0x84) = Z;
}
void CTestDialog::OnBnClickedButton19()
{
	UpdateData(TRUE);
	Call_瞬移(m_edit3, m_edit4, m_edit5);
}

开始加速 和 瞬移 ,凌波微步

为了能让短距离瞬移变得有意义,短距离瞬移之后我们再走路,其他玩家会看到我们是瞬移成功的,

但是长距离瞬移确不行,说明服务器对我们的坐标是有验证的,这个容忍度我们上面说了220左右

不超过这个范围就不会被修正。

那么我们完全可以短距离瞬移,之后走路,让服务器承认我们的位置,然后再继续下次的瞬移,2次短距离瞬移的间隔如果很小,那么和长距离瞬移的结果几乎是一样的。

(如果我们连续短距离瞬移,中间不走路来让服务器确认我们的坐标有效性和直接长距离瞬移是没有区别的,还是会被修正回来的)

所以,我们要做一个短距离瞬移 + 寻路的功能,出来的效果看上去像凌波微步

但是还存在一个问题,就是,当我们瞬移的时候,不能去到地图无效点,否则还是会被修正

也就是说,我们选择的瞬移点位也必须是合理的

那么,怎么才能合理呢?

我们利用寻路,因为在寻路的时候,他会自动把人物转向到要寻路的方向,我们按照寻路的方向,小距离瞬移即可,即使到了地图边缘,那么下一次调用寻路,又会帮我们修正方向了

本着这个思路,我们需要做的事就是计算出来,我们面朝方向的一小段距离的坐标点,瞬移到这个坐标点。

这个距离我们用200,200在这个游戏不大,只有2小步那么长

那么计算方法如下:

第一象限

下图有一个错误,看看是否能够发现?(X增和Y增写反了,我们说了 这个坐标系纵轴是X)

Lua人物瞬移_数据挖掘_06

if (A.朝向 > 0 && A.朝向 < 0x3FFF)
	{
		X增 = (FLOAT)(200 * sin((0x3FFF - A.朝向) * 2 * 3.14159 / 0xFFFF));
		Y增 = (FLOAT)(200 * cos((0x3FFF - A.朝向) * 2 * 3.14159 / 0xFFFF));
		Call_瞬移(A.X + X增, A.Y + Y增, A.Z);
	}

第二象限 ,其他象限也是一样的,但是要注意,X增和Y增 不同象限可能是加也可能是减

if (A.朝向 > 0xFFFF * 3 / 4 && A.朝向 < 0xFFFF)
	{
		X增 = (FLOAT)(200 * sin((A.朝向 - 0xFFFF * 3 / 4) * 2 * 3.14159 / 0xFFFF));
		Y增 = (FLOAT)(200 * cos((A.朝向 - 0xFFFF * 3 / 4) * 2 * 3.14159 / 0xFFFF));
		Call_瞬移(A.X + X增, A.Y - Y增, A.Z);
	}

第三象限

if (A.朝向 > 0xFFFF / 2 && A.朝向 < 0xFFFF * 3 / 4)
	{
		X增 = (FLOAT)(200 * sin((0xFFFF * 3 / 4 - A.朝向) * 2 * 3.14159 / 0xFFFF));
		Y增 = (FLOAT)(200 * cos((0xFFFF * 3 / 4 - A.朝向) * 2 * 3.14159 / 0xFFFF));
		Call_瞬移(A.X - X增, A.Y - Y增, A.Z);
	}

第四象限

if (A.朝向 > 0x3FFF && A.朝向 < 0xFFFF / 2)
	{
		X增 = (FLOAT)(200 * sin((A.朝向 - 0x3FFF) * 2 * 3.14159 / 0xFFFF));
		Y增 = (FLOAT)(200 * cos((A.朝向 - 0x3FFF) * 2 * 3.14159 / 0xFFFF));
		Call_瞬移(A.X - X增, A.Y + Y增, A.Z);
	}

上面的计算封装成子程序

void  Call_向前瞬移200()
{
	人物属性 A;
	A.初始化();
	FLOAT X增;
	FLOAT Y增;
 
	if (A.朝向 > 0 && A.朝向 < 0x3FFF)
	{       //Q2217777779
		X增 = (FLOAT)(200 * sin((0x3FFF - A.朝向) * 2 * 3.14159 / 0xFFFF));
		Y增 = (FLOAT)(200 * cos((0x3FFF - A.朝向) * 2 * 3.14159 / 0xFFFF));
		Call_瞬移(A.X + X增, A.Y + Y增, A.Z);
	}
	if (A.朝向 > 0xFFFF * 3 / 4 && A.朝向 < 0xFFFF)
	{
		X增 = (FLOAT)(200 * sin((A.朝向 - 0xFFFF * 3 / 4) * 2 * 3.14159 / 0xFFFF));
		Y增 = (FLOAT)(200 * cos((A.朝向 - 0xFFFF * 3 / 4) * 2 * 3.14159 / 0xFFFF));
		Call_瞬移(A.X + X增, A.Y - Y增, A.Z);
	}
	if (A.朝向 > 0xFFFF / 2 && A.朝向 < 0xFFFF * 3 / 4)
	{
		X增 = (FLOAT)(200 * sin((0xFFFF * 3 / 4 - A.朝向) * 2 * 3.14159 / 0xFFFF));
		Y增 = (FLOAT)(200 * cos((0xFFFF * 3 / 4 - A.朝向) * 2 * 3.14159 / 0xFFFF));
		Call_瞬移(A.X - X增, A.Y - Y增, A.Z);
	}
	if (A.朝向 > 0x3FFF && A.朝向 < 0xFFFF / 2)
	{
		X增 = (FLOAT)(200 * sin((A.朝向 - 0x3FFF) * 2 * 3.14159 / 0xFFFF));
		Y增 = (FLOAT)(200 * cos((A.朝向 - 0x3FFF) * 2 * 3.14159 / 0xFFFF));
		Call_瞬移(A.X - X增, A.Y + Y增, A.Z);
	}

}

然后在我们的代码中调用即可

void Call_凌波微步(FLOAT X, FLOAT Y, FLOAT Z)
{

	人物属性 A;
	A.初始化();
	int i = 0;

	FLOAT 距离 = sqrt((A.X - X)*(A.X - X) + (A.Y - Y)*(A.Y - Y) + (A.Z - Z)*(A.Z - Z));
	while (距离>50)
	{
		i++;
		if (i > 100) break;
	

		Call_向前瞬移200();
        Sleep(80);
                //公众号 任鸟飞逆向 2217777779
		Call_寻路(X, Y, Z);
		Sleep(120);
		A.初始化();
		距离 = sqrt((A.X - X)*(A.X - X) + (A.Y - Y)*(A.Y - Y) + (A.Z - Z)*(A.Z - Z));
	}
}

在我们自己的屏幕上 是一步步瞬移过去的,但是在别的玩家屏幕看到的效果

我们是窗墙 ,飞檐走壁的

分享个视频方便更好理解:

百度盘: 百度网盘 请输入提取码 提取码: zs8n

修复漏洞的建议 和方法

加速和瞬移 有点像开车, 服务器就像摄像头。

虽然可以监督和检查,

但是确不能完全的实时检测,否则会严重的影响游戏体验度和流畅度。

那么有什么办法,可以在服务器眼里并不是特别大的情况

又起到检测最好效果呢?

我这里的建议是:

1.检测无需实时, 抽样调查,减少服务器压力, 而且每人又会不知什么情况下被检测,

既起到了检测作用, 用起到了检测的隐藏作用。

2.做单点检测 不可能完美, 做区间测速,

排除一切 传送等因素的情况下, 不定时 做区间测速,这可以从根本上解决加速的问题,并且不需要实时检测。

3.玩家举报

4.相关原理,过程代码的检测