Js也能写外挂?5行代码改掉《植物大战僵尸》的阳光值!
??从前端到内存操作:用 Node.js 写《植物大战僵尸》修改器?谁说前端只能玩页面交互?
??本文将带你用Node.js+memoryjs操作经典游戏《植物大战僵尸》的内存,修改阳光值、让植物种植无冷却。
??不需要 C++,不需要驱动,只要你会 JS,就能一行一行“控制游戏”,轻松写出专属游戏辅助脚本。
??? 为什么选择 Node.js + memoryjs?作者作为一名切图仔,不会C++,不会Lua,只会一点易语言。但使用易语言编写脚本时,总感觉蹩脚得很。那么Nodejs能不能写脚本呢? 经过我多方打听,终于找到memoryjs这个库,提供了对 Windows 下进程、模块、内存读写的封装:
npm install memoryjs
推荐使用最新封装编译版本:
npm install memoryprocess
搭配 Electron,你甚至可以给它做个 UI。
?? 项目目标我们以《植物大战僵尸》为例,实现:
实时修改阳光值一键开启/关闭无冷却Electron实现UI??? 基础准备:打开游戏进程首先我们要“定位游戏进程”并获取它的内存句柄(Handle):
constmemoryJs =require('memoryjs')
constGameExeName ='PlantsVsZombies.exe'
functiongetGameProcessHandler(){
constprocess = memoryJs.openProcess(GameExeName)
if(!process)thrownewError('请先打开游戏')
returnprocess
}
调用openProcess会返回目标进程的 ID、句柄等信息,后续所有内存读写都依赖它。
?? 结构分析:找到目标地址游戏的数据(比如阳光值)并不是固定地址,而是通过「模块基地址 + 偏移链」来定位的:
/**
* 获取模块基地址
*/
functiongetModuleBaseAddr(process, moduleName = GameExeName){
constmodules = memoryJs.getModules(process.th32ProcessID)
constmod = modules.find((m) =m.szModule.toLowerCase() === moduleName)
returnmod?.modBaseAddr
}
/**
* 计算偏移后的地址
*/
functionresolveAddr(process, baseAddr, offsets){
letaddr = memoryJs.readMemory(process.handle, baseAddr,'dword')
for(leti =0; i offsets.length -1; i++) {
addr = memoryJs.readMemory(process.handle, addr + offsets[i],'dword')
}
returnaddr + offsets[offsets.length -1]
}
?? 示例一:设置阳光值通过配置管理偏移结构:
/**
* 关卡阳光的基地址为:[[[Game.exe + 0x2a9f38] + 0x768] + 0x5560]
*/
constGameConfig = {
set_sunshine: {
baseOffset:0x2a9f38,// 例如 Game.exe + 0x2a9f38
offsets: [0x768,0x5560],//两次偏移,分别是 0x768,0x5560
type:'dword'
}
}
/**
* 设置阳光值
*/
functionGame_SetSunshine(value){
// 先获取进程句柄
constprocess = getGameProcessHandler()
// 获取进程模块基地址
constbase = getModuleBaseAddr(process)
// 获取阳光的地址
constaddr = resolveAddr(
process,
base + GameConfig.set_sunshine.baseOffset,
GameConfig.set_sunshine.offsets
)
// 向这个内存地址写入新的阳光值
memoryJs.writeMemory(process.handle, addr, value,'dword')
// 关闭进程句柄
memoryJs.closeHandle(process.handle)
}
?? 运行Game_SetSunshine(9999)就能瞬间让你财大气粗!
?? 示例二:开启无冷却相较于修改阳光值,无冷却功能需要我们覆盖游戏某段指令(即修改源代码),通过写入汇编字节实现功能开启:
functionGame_SetCoolDown(open){
constprocess = getGameProcessHandler()
constaddr = getModuleBaseAddr(process) +0x87296// 冷却相关地址
// addr 便是存储判断冷却的相关代码。
// 原代码是 0x7E 0x14 -- 修改为 0x7F 0x14
// 其实就是将判断冷却时间的代码中的 `Jle` 改为了 `Jg`: `小于等于` - `大于`
constnewBytes = open ? Buffer.from([0x7f,0x14]) : Buffer.from([0x7e,0x14])
memoryJs.writeBuffer(process.handle, addr, newBytes)
memoryJs.closeHandle(process.handle)
}
?? 示例三:读取阳光值你甚至可以把这个值实时展示到 UI(比如 Electron 界面)中:
functionGame_GetSunshine(){
constprocess = getGameProcessHandler()
constbase = getModuleBaseAddr(process)
constaddr = resolveAddr(
process,
base + GameConfig.set_sunshine.baseOffset,
GameConfig.set_sunshine.offsets
)
constvalue = memoryJs.readMemory(process.handle, addr,'dword')
memoryJs.closeHandle(process.handle)
returnvalue
}
?? 最佳实践:配合Electron提供操作UI界面https://electron-vite.github.io/https://github.com/JoShMiQueL/memoryprocesshttps://github.com/Rob--/memoryjs?? 注意事项「必须以管理员权限运行 Node 脚本」,否则无法访问游戏内存确保你找到的偏移是当前版本可用的(可配合 Cheat Engine 分析)这是纯学习研究项目,请勿用于非法用途?? 后续拓展方向,欢迎关注使用Nodejs调用大漠插件:??图文识别使用Nodejs调用易键鼠的双头盒子dll: ??虚拟输入大型网游实战???? 总结通过Node.js + memoryjs,即使是纯前端背景的开发者也可以轻松进入「内存脚本开发的世界」。利用现代 JS 工具链,我们可以封装一个安全、可维护的辅助工具。
如果你也想使用Nodejs来编写游戏修改器或者游戏脚本,欢迎一起讨论!
附录修改器Demo仓库:https://github.com/chinjiaqing/pvz-tools游戏下载地址:https://www.32r.com/soft/110449.html如何运行demo克隆仓库gitclonehttps://github.com/chinjiaqing/pvz-tools.git
安装依赖,推荐使用yarnyarn install
运行yarn dev
打包exeyarn build:win
AI编程资讯AI Coding专区指南:https://aicoding.juejin.cn/aicoding
点击"阅读原文"了解详情~
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线