Seraph 内存搜索

2019-11-07 12:52:48刘景俊
一般情况下,为了应付游戏的动态内存地址,我们用基址的方式来读取内存,不过前提是可以知道基址。有的游戏,基址是很难分析到的,而且很多游戏加了隐藏和变换,搞的分析起来特别复杂。这个时候,借助Seraph,我们可以用另一种方式——搜索内存。

虽然找不出基址,但是我们可以很轻松的找到一些我们想要的数据的直接地址。比如我们在一次游戏的运行里,可以用CE找到血的地址是&H900010, 血最大值的地址是&H900014,MP地址&H900020,最大MP&H900024。

虽然下一次游戏运行时,这些地址都会变,但是我们知道,这些地址互相间的相对地址偏移是不变的。也就是说最大血地址=血地址+4,MP地址=血地址+&H10
这样我们就可以搜索了。举个例子,我们知道我们的血/最大血/MP/最大MP分别是8000/8000/12000/12000。那么在脚本里,告诉Seraph的内存搜索引擎,我们要搜索一个地址,它的值是8000,这个地址+4的值也是8000,这个地址+&H10和+&H14的值是12000。这样的地址,一般在游戏里只有一个。
怎么搜索呢?

ClearSearchMemoryTable()
AddSearchMemoryItem(&H900010, 2, 8000)
AddSearchMemoryItem(&H900014, 2, 8000)
AddSearchMemoryItem(&H900020, 2, 12000)
AddSearchMemoryItem(&H900024, 2, 12000)
if SearchMemory(&H000000, Address) then
Print("找到地址:"&Address)
end if


注意,以上代码里,我们调用AddSearchMemoryItem函数来设置一些我们要搜索的条件。
第一个参数是每个值的地址。不用担心这个地址在下一次游戏运行时不正确,Seraph搜索只关心所有添加的搜索项之间的“相对地址”。
第二个参数是指定类型,2代表四字节整型。我们同样可以添加双字节,浮点数,以及字符串等不同类型。详见帮助手册。
第三个参数就是这个搜索项的值。你必须填入这个数据的当前值,如果填错了,就搜不到了。(关于怎么在脚本里指定当前的用于搜索的值,我们之后讲)
注意,第一行的ClearSearchMemoryTable()是用于清除上一次添加的搜索项。重新开始一次搜索前我们都要调一上这个函数。
添加完了这4个搜索项以后,我们用SearchMemory开始搜索。第一个参数表示搜索的开始值,我们一般都可以用&H000000。第二个参数值用于返回搜索到的结果。
搜到的结果就是第一个搜索项的地址,也就是当前血的地址。我们可以保存这个地址,用ReadMemory随时去读数据。

那么,整体的流程应该是:
1. 在参数设置里,我们添加一些参数,用于填入搜索的数据。告诉用户在脚本开始前,先设置这些数据。比如,填入自己的血,MP,并在红蓝满的时候开始脚本。
2. 在脚本一开始,用GetConfigNumber等函数取出设置的值,用以上代码搜索内存,把得到的数据保存下来