You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中向其他程序的指针地址写入数据?

嘿,正在折腾Undertale无敌作弊器的朋友,这个练习对理解Windows进程内存机制太合适了!结合你提到的需求,我帮你把代码补全并梳理清楚核心要点,让你不仅能跑通程序,还能明白背后的内存操作逻辑。

完整实现代码

先给你能直接用的完整代码,记得替换成你用Cheat Engine找到的真实内存地址:

#include <stdio.h>
#include <Windows.h>

int main(void) {
    // 可调整的最大生命值,Undertale默认Frisk满生命值是20
    const double MAX_HEALTH = 20.0;
    // 替换成你通过Cheat Engine找到的生命值内存地址
    const uintptr_t HEALTH_ADDRESS = 0x00000000; // 这里改真实地址!

    // 第一步:找到Undertale的游戏窗口
    HWND undertaleWindow = FindWindowA(NULL, "Undertale");
    if (!undertaleWindow) {
        printf("找不到Undertale窗口!请先启动游戏~ \n");
        return 1;
    }

    // 第二步:获取游戏进程ID
    DWORD processId;
    GetWindowThreadProcessId(undertaleWindow, &processId);
    if (processId == 0) {
        printf("获取进程ID失败,错误码:%d\n", GetLastError());
        return 1;
    }

    // 第三步:打开游戏进程,申请内存写入权限
    HANDLE processHandle = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, processId);
    if (!processHandle) {
        printf("打开进程失败,错误码:%d\n", GetLastError());
        return 1;
    }

    printf("已成功连接到Undertale,开始锁定生命值为%.1f...\n按Ctrl+C即可退出程序\n", MAX_HEALTH);

    // 第四步:循环持续写入最大生命值,实现无敌
    while (1) {
        BOOL writeSuccess = WriteProcessMemory(
            processHandle,
            (LPVOID)HEALTH_ADDRESS,
            &MAX_HEALTH,
            sizeof(MAX_HEALTH),
            NULL
        );

        if (!writeSuccess) {
            printf("写入内存失败,错误码:%d\n", GetLastError());
            break;
        }

        Sleep(100); // 每100毫秒写一次,避免占用过多CPU
    }

    // 收尾:关闭进程句柄
    CloseHandle(processHandle);
    return 0;
}
关键知识点解析(针对你关注的内存机制)
  • 进程内存隔离:Windows下每个进程的内存是独立的,所以必须通过OpenProcess获取目标进程的句柄,才能跨进程读写内存。
  • 权限控制:OpenProcess必须指定PROCESS_VM_WRITE(写入权限)和PROCESS_VM_OPERATION(内存操作权限),不然系统会拒绝你的写入请求。
  • 动态地址处理:如果你用Cheat Engine找到的是动态地址(游戏重启后地址会变),那不能直接写死地址,得用基地址+偏移的方式:
    // 举个例子,假设基地址来自Undertale.exe模块,偏移是0x1234
    uintptr_t baseModule = (uintptr_t)GetModuleHandleA("Undertale.exe");
    uintptr_t healthAddress = baseModule + 0x1234;
    
    这样每次游戏重启,GetModuleHandleA会自动拿到最新的模块基地址,加上固定偏移就能找到正确的生命值内存位置。
  • 循环写入的必要性:游戏会在运行中随时更新生命值(比如受伤害、回血),所以必须循环覆盖这个地址的值,才能保证角色一直处于无敌状态。
注意事项
  • 编译时要确保用的是和游戏同架构的编译器(比如游戏是32位,你就用32位编译器编译程序),不然内存地址会不匹配。
  • 如果运行时提示权限不足,右键以管理员身份运行你的作弊程序。

内容的提问来源于stack exchange,提问作者Nim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:28:41