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

能否用C++访问运行中程序的变量及其值?含跨进程访问场景

让我分别解答这两个问题:

问题1:是否可以访问运行中的C++程序内部的变量及其对应的值?

当然可以,而且有好几种实用方式,完全看你的使用场景:

  • 同一进程内直接访问:如果是你自己编写的程序,运行时想要查看变量值,最简单的就是直接通过变量名访问——只要变量在当前作用域内,或者你持有它的指针/引用且变量还未被销毁。比如全局变量可以在任何函数里直接读取,局部变量如果需要在其他函数监控,保存它的地址就行:
    int global_a = 0;
    
    void monitor_global() {
        std::cout << "当前global_a的值:" << global_a << std::endl;
    }
    
    int main() {
        int local_b = 10;
        int* b_ptr = &local_b;
        // 后续代码里通过指针就能读取local_b的值
        std::cout << "当前local_b的值:" << *b_ptr << std::endl;
        monitor_global();
        return 0;
    }
    
  • 使用调试工具:如果程序已经在运行,你可以用调试器(比如GDB、Visual Studio调试器、LLDB)附加到进程,打断点或者直接查看内存地址对应的变量值,这种方式特别适合调试时排查问题。
  • 添加日志/监控逻辑:在程序里嵌入日志代码,定期输出变量值到控制台或文件,适合长时间运行的程序做状态监控。

问题2:是否能够使用C++语言访问另一个正在运行的程序所使用的变量?

可以实现,但比同进程访问复杂很多——因为每个进程都有独立的虚拟地址空间,变量名在其他进程中是完全无效的。核心思路是借助操作系统提供的进程内存访问API,读取目标进程特定内存地址的值,具体步骤如下:

关键操作步骤

  • 获取目标进程的PID:首先得找到你要访问的程序的进程ID(PID)。Windows上可以用CreateToolhelp32Snapshot枚举进程,Linux上可以通过/proc文件系统查找进程信息。
  • 获取目标进程的访问权限:打开目标进程并申请内存读取权限(Windows用OpenProcess,Linux用ptrace或process_vm_readv),通常需要管理员/root权限才能完成这一步。
  • 确定变量在目标进程中的虚拟地址:这是最麻烦的环节:
    • 如果目标程序是你自己编写的,编译时保留符号表(别用-s参数剥离符号),可以通过调试符号工具(Windows的dbghelp库、Linux的elfutils)查找变量的地址;
    • 如果是第三方程序且没有符号,就需要逆向工程(比如内存扫描、特征码定位)来找到变量的内存位置。
    • 注意:很多系统开启了ASLR(地址空间布局随机化),目标进程每次启动时变量的虚拟地址都会变化,所以需要动态获取地址,不能硬编码。
  • 读取目标进程的内存:用系统API读取对应地址的内存值(Windows用ReadProcessMemory,Linux用process_vm_readv)。

简单示例(Windows平台)

#include <windows.h>
#include <tlhelp32.h>
#include <iostream>

// 根据进程名获取PID
DWORD GetProcessIdByName(const wchar_t* processName) {
    PROCESSENTRY32 pe32{};
    pe32.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return 0;

    if (Process32First(hSnapshot, &pe32)) {
        do {
            if (!_wcsicmp(pe32.szExeFile, processName)) {
                CloseHandle(hSnapshot);
                return pe32.th32ProcessID;
            }
        } while (Process32Next(hSnapshot, &pe32));
    }
    CloseHandle(hSnapshot);
    return 0;
}

int main() {
    // 替换为你的目标程序名(比如Target.exe)
    DWORD pid = GetProcessIdByName(L"Target.exe");
    if (pid == 0) {
        std::cout << "找不到目标进程" << std::endl;
        return 1;
    }

    // 打开进程并申请内存读取权限
    HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, pid);
    if (hProcess == NULL) {
        std::cout << "无法打开进程,错误码:" << GetLastError() << std::endl;
        return 1;
    }

    // 注意:这里的地址需要替换为目标变量的实际虚拟地址
    int target_value{};
    SIZE_T bytes_read{};
    BOOL success = ReadProcessMemory(
        hProcess,
        (LPCVOID)0x0000000123456789, // 示例地址,需替换
        &target_value,
        sizeof(target_value),
        &bytes_read
    );

    if (success && bytes_read == sizeof(target_value)) {
        std::cout << "读取到目标变量的值:" << target_value << std::endl;
    } else {
        std::cout << "读取失败,错误码:" << GetLastError() << std::endl;
    }

    CloseHandle(hProcess);
    return 0;
}

补充说明

  • 如果是你自己控制两个程序,更可靠的方式是使用共享内存(比如Windows的CreateFileMapping、Linux的shmget),让两个进程直接访问同一块共享内存区域的变量,这样就不用手动找地址和跨进程读内存了。
  • 跨进程访问受系统安全机制限制,比如Windows的UAC、Linux的ptrace权限,没有足够权限会操作失败。

内容的提问来源于stack exchange,提问作者noah.ehrnstrom

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:22:43