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

C语言读取外部进程内存时,首次查询后修改目标变量再查无匹配结果的问题

C语言读取外部进程内存时,首次查询后修改目标变量再查无匹配结果的问题

我仔细看了你的代码和问题描述,核心问题其实出在内存区域的过滤条件上,另外还有几个小bug也会影响结果,下面给你一步步分析和解决:

1. 最关键的问题:内存保护属性判断错误

你现在的代码只扫描了PAGE_READONLY(只读)的内存区域,但我们要找的变量不管是在栈上还是堆上,对应的内存保护属性都是PAGE_READWRITE(可读写)的!这就导致第一次扫描时,你根本没扫到真正的变量地址,链表中存的全是其他只读区域里碰巧和目标值相等的“巧合值”——这些值当然不会跟着目标进程的变量变化,所以后续查询自然匹配不上。

修复这个问题很简单,把内存区域的判断条件改一下:

// 原代码
if (mbi.State == MEM_COMMIT && (mbi.Protect & PAGE_READONLY))

// 修改为:同时包含只读和可读写区域
if (mbi.State == MEM_COMMIT && (mbi.Protect & (PAGE_READONLY | PAGE_READWRITE)))

2. ask_current_value函数的潜在崩溃bug

你在处理输入换行符时,直接解引用了memchr的返回值,但如果用户输入的内容没有换行(比如输入长度刚好填满buffer,或者直接按了Ctrl+Z),memchr会返回NULL,这时候解引用就会导致程序崩溃。

修复这个bug:

int ask_current_value(){
    char buffer[128];
    printf("Current value: ");
    fgets(buffer, sizeof(buffer), stdin);
    
    // 先检查是否找到换行符,再修改
    char* newline_pos = memchr(buffer, '\n', sizeof(buffer));
    if (newline_pos != NULL) {
        *newline_pos = '\0';
    }
    
    return atoi(buffer);
}

3. 其他需要确认的细节

  • 链表实现正确性:你提到linked_list.c的第一个元素是垃圾数据,循环从i=1开始没问题,但要确保linked_list_len、fetch_linked_list_element、delete_element_at_index这些函数的索引逻辑是正确的,比如linked_list_len返回的长度是否包含头节点,避免漏扫或者越界访问。
  • 目标进程变量的稳定性:如果你的测试程序把变量放在栈上,要注意栈帧的生命周期——比如如果变量是某个函数的局部变量,函数返回后栈帧会被销毁,变量地址就失效了。建议把目标变量改成全局变量或者堆上分配的变量,确保地址在程序运行期间固定:
    // 目标测试程序示例
    #include <stdio.h>
    #include <stdlib.h>
    
    int global_target = 0; // 全局变量,地址固定
    // 或者堆分配:int* heap_target = malloc(sizeof(int)); *heap_target = 0;
    
    int main() {
        int input;
        while (1) {
            printf("Set target value: ");
            scanf("%d", &input);
            global_target = input;
            printf("New value: %d\n", global_target);
        }
        free(heap_target); // 堆分配的话最后记得释放
        return 0;
    }
    
  • 变量类型匹配:确保扫描程序和目标程序的变量类型一致——你用int来存储值,目标程序的变量也要是int,避免因为类型大小(比如long是4/8字节)不匹配导致扫描错误。

修复后的测试流程

  1. 编译并运行目标测试程序,记下它的PID;
  2. 编译你的扫描程序(记得链接linked_list.c);
  3. 输入PID,然后输入目标变量的初始值,第一次扫描会得到所有包含该值的地址(包括真正的变量地址);
  4. 修改目标程序的变量值,回到扫描程序输入新值,此时程序会过滤掉不匹配的地址,最后剩下的就是目标变量的真实地址,后续修改目标值时这个地址的内容会跟着变化。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:23:10