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

如何从运行中的程序读取并修改变量?C语言跨程序操作问询

如何读取/修改运行中程序的内部变量

核心结论

完全可以实现读取和修改操作,这两类能力都由操作系统提供的进程内存访问接口支持,只要你拥有目标进程的对应操作权限即可完成需求。

操作前提

  • 先获取目标程序的进程ID(PID),Linux下可通过ps命令获取,Windows下可通过任务管理器获取
  • 提前定位到目标变量a在目标进程虚拟地址空间中的准确地址,可通过gdb、x64dbg等调试工具预先获取

各平台实现方案

Linux平台

Linux下可通过ptrace系统调用完成进程附加、内存读写操作,示例代码如下:

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
    if (argc != 3) {
        printf("用法: %s <目标PID> <变量a的16进制地址>\n", argv[0]);
        return 1;
    }
    pid_t pid = atoi(argv[1]);
    uint64_t addr = strtoul(argv[2], NULL, 16);

    // 附加到目标进程,附加后目标进程会暂停运行
    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
        perror("attach失败");
        return 1;
    }
    waitpid(pid, NULL, 0);

    // 读取变量a的值
    long a_val = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
    printf("读取到的a当前值: %ld\n", a_val);

    // 修改a的值为100
    if (ptrace(PTRACE_POKEDATA, pid, addr, 100) == -1) {
        perror("修改失败");
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
        return 1;
    }
    printf("已将a的值修改为100\n");

    // 分离进程,恢复目标程序运行
    ptrace(PTRACE_DETACH, pid, NULL, NULL);
    return 0;
}

使用方式:用gcc编译后,以root权限运行,传入目标PID和变量地址即可完成操作。

Windows平台

Windows下可通过系统API OpenProcess、ReadProcessMemory、WriteProcessMemory完成操作,示例代码如下:

#include <windows.h>
#include <stdio.h>

int main() {
    DWORD pid = 1234; // 替换为目标程序的实际PID
    LPVOID addr = (LPVOID)0x12345678; // 替换为变量a的实际地址
    int a_val;
    SIZE_T read_bytes, write_bytes;

    // 打开目标进程,获取读写权限
    HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
    if (hProcess == NULL) {
        printf("打开进程失败,错误码: %d\n", GetLastError());
        return 1;
    }

    // 读取变量a的值
    if (ReadProcessMemory(hProcess, addr, &a_val, sizeof(a_val), &read_bytes) && read_bytes == sizeof(a_val)) {
        printf("读取到的a当前值: %d\n", a_val);
    } else {
        printf("读取内存失败\n");
        CloseHandle(hProcess);
        return 1;
    }

    // 修改a的值为100
    int new_val = 100;
    if (WriteProcessMemory(hProcess, addr, &new_val, sizeof(new_val), &write_bytes) && write_bytes == sizeof(new_val)) {
        printf("已将a的值修改为100\n");
    } else {
        printf("写入内存失败\n");
        CloseHandle(hProcess);
        return 1;
    }

    CloseHandle(hProcess);
    return 0;
}

使用方式:编译后以管理员权限运行即可。

注意事项

  • 如果目标程序开启了地址空间布局随机化(ASLR),每次运行时变量的虚拟地址都会变化,不可硬编码地址,需要动态定位变量地址
  • 跨用户操作进程需要更高的系统权限,普通权限默认只能操作同用户启动的进程
  • 栈变量的地址只有在对应栈帧未销毁时有效,本示例中a是main函数内的栈变量,程序运行全程栈帧不会销毁,地址固定可安全操作
  • 这类内存修改操作目标程序本身无感知,除非程序本身做了内存完整性校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 15:39:02