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

2 阅读3分钟

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

ScreenShot_2026-03-30_100609_991.png

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 → 最终地址

代码实现

ScreenShot_2026-03-30_094346_830.png

ScreenShot_2026-03-30_094550_574.png

ScreenShot_2026-03-30_094605_310.png

完整代码

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 的基址:

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. 沿指针链查找阳光地址

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

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

向计算出的地址写入 9999

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

运行后控制台输出:

当前阳光: 9999

进阶:锁定阳光

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

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

核心参数说明:

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

总结

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

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

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