Js也能写外挂?8 行代码改掉《植物大战僵尸》的阳光值!对于js来说超越调用大漠超越调用memory.js

Node.js 内存修改入门:植物大战僵尸阳光值修改实战

Node.js 内存修改 游戏安全 植物大战僵尸

目录

  1. 前言
  2. 环境准备
  3. 核心原理
  4. 代码实现
  5. 进阶:锁定阳光
  6. 总结

前言

原生node模块 ---- 获取地址

www.ylcp.online/engine/

对于 node 来说性能超越 大漠 性能超越 memoryjs

本文将以经典游戏《植物大战僵尸》为例,演示如何使用 Node.js 通过内存读写的方式修改游戏中的阳光值。整个实现过程仅使用 8 行代码,非常适合作为内存修改的入门教程。

声明 本文仅供学习和技术研究使用,请勿用于破坏游戏平衡或商业用途。游戏修改可能违反游戏服务条款,请在合法合规的前提下学习。

环境准备

  • Node.js v18 或更高版本(推荐 v24.x)
  • 游戏:植物大战僵尸 PC 版
  • 模块 :用于进程内存读写的 Node.js 原生扩展 目前自己写的c++高性能 .node 模块地址在上面 👆

核心原理

修改游戏内存的核心步骤如下:

  1. 找到目标进程 --- 通过窗口标题定位游戏进程 PID
  2. 获取模块基址 --- 找到 PlantsVsZombies.exe 的内存基地址
  3. 计算偏移链 --- 通过多级指针偏移找到阳光值的真实地址
  4. 写入数值 --- 向目标地址写入新的阳光值

阳光值偏移链: 基址 PlantsVsZombies.exe + 0x2A9EC0 → 偏移 0x768 → 偏移 0x5560 → 最终地址

代码实现

完整代码

javascript 复制代码
const engine = require('./engine.node');
const win = engine.getAllWindows().find(w => w.title.includes("植物大战僵尸"));
const baseAddr = Number(engine.findModuleByName(win.processId, "PlantsVsZombies.exe").baseAddress);
const sunAddr = engine.followPointerChain(win.processId, {
    baseAddress: (baseAddr + 0x2A9EC0).toString(16),
    offsets: [0x768, 0x5560],
}).finalAddress;
engine.writeInt32(win.processId, sunAddr, 9999);
console.log(`当前阳光: ${engine.readInt32(win.processId, sunAddr)}`);

代码拆分 👇

1. 获取进程与模块基址

首先加载原生模块,根据窗口标题找到游戏进程,并获取 PlantsVsZombies.exe 的基址:

javascript 复制代码
const engine = require('./engine.node');
const win = engine.getAllWindows().find(w => w.title.includes("植物大战僵尸"));
const baseAddr = Number(engine.findModuleByName(win.processId, "PlantsVsZombies.exe").baseAddress);
2. 沿指针链查找阳光地址

通过多级指针追踪,最终定位到阳光值所在的内存地址:

javascript 复制代码
const sunAddr = engine.followPointerChain(win.processId, {
    baseAddress: (baseAddr + 0x2A9EC0).toString(16),
    offsets: [0x768, 0x5560],
}).finalAddress;
3. 写入新的阳光值

向计算出的地址写入 9999

javascript 复制代码
engine.writeInt32(win.processId, sunAddr, 9999);
console.log(`当前阳光: ${engine.readInt32(win.processId, sunAddr)}`);

运行后控制台输出:

makefile 复制代码
当前阳光: 9999

进阶:锁定阳光

如果希望阳光值持续保持在 9999(游戏会不断减少阳光),可以使用内存冻结功能:

javascript 复制代码
// 锁定阳光(每 100ms 写入一次)
engine.freezeMemoryValue(win.processId, {
    address: sunAddr,
    valueType: "int32",
    value: [0x0F, 0x27, 0x00, 0x00],  // 9999 小端序
    intervalMs: 100,
});
console.log("阳光已锁定为 9999,按 Ctrl+C 停止");

核心参数说明:

参数 说明
address sunAddr 阳光值的内存地址
valueType "int32" 32位有符号整数
value 0x0F, 0x27, 0x00, 0x00 9999 的小端序字节表示
intervalMs 100 每 100ms 刷新一次

总结

通过本文,我们了解了使用 Node.js 进行游戏内存修改的基本流程:

步骤 API 作用
1. 找窗口 getAllWindows() 通过标题匹配获取游戏窗口
2. 找基址 findModuleByName() 获取 EXE 模块的内存基址
3. 追指针 followPointerChain() 多级指针链追踪到目标地址
4. 写内存 writeInt32() 写入指定值到目标地址
5. 锁定值 freezeMemoryValue() 定时刷新,持续保持目标值

本文仅展示了内存修改的基本原理。在实际学习中,你可以尝试修改更多的游戏属性(如金币、生命值、冷却时间等),进一步理解 Windows 进程内存管理机制。

相关推荐
名字还没想好☜4 小时前
React 用 Portal + Context 实现全局 Toast:一次调用、自动消失与队列管理
前端·javascript·react.js·react·next.js
嘟嘟07174 小时前
摘要 手把手实现路由鉴权守卫,逐行拆解 ProtectRoute、localStorage、Navigate state、useLocation、FormDat
javascript
肉肉不吃 肉4 小时前
无渲染组件和组合式函数
前端·javascript·vue.js
其美杰布-富贵-李4 小时前
01 从项目结构开始认识 Vue 3
javascript·vue.js·ecmascript
sugar__salt4 小时前
前端路由技术详解:从传统多页到 React SPA 的完整进化之路
前端·javascript·react.js·前端框架
用户84298142418105 小时前
JS代码压缩实测:可减小体积、提高执行效率!
前端·javascript·后端
Synmbrf5 小时前
ECharts 饼图鼠标悬浮后标签 title 消失的问题
前端·javascript
breeze jiang6 小时前
React useRef 实战:从 input 聚焦到 Web Worker 引用
前端·javascript·react.js
苏灿烤鱼7 小时前
GitHub #2 拆解|把工程经验装进 Agent,为什么仍会“静默失效”?
javascript·人工智能·agent
To_OC15 小时前
LC 35 搜索插入位置:二分查找谁都会,边界条件谁写谁懵
javascript·算法·leetcode