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

如何按指定格式输出进程内存数据并解决大内存读取限制

问题解答

首先先贴出你的代码方便参考:

void update_memblock(MEMBLOCK *mb) { 
    static unsigned char tempbuf[128 * 1024]; 
    SIZE_T bytes_left; 
    SIZE_T total_read; 
    SIZE_T bytes_to_read; 
    SIZE_T bytes_read; 

    bytes_left = mb->size; 
    total_read = 0; 

    while (bytes_left) { 
        bytes_to_read = (bytes_left > sizeof(tempbuf)) ? sizeof(tempbuf) : bytes_left; 
        ReadProcessMemory(mb->hProc, mb->addr + total_read, tempbuf, bytes_to_read, &bytes_read); 

        if (bytes_read != bytes_to_read) break; 

        memcpy(mb->buffer + total_read, tempbuf, bytes_read); 
        bytes_left -= bytes_read; 
        total_read += bytes_read; 
    } 

    mb->size = total_read; 
}

一、实现内存数据的格式化输出(类似图片中的内存查看器格式)

你需要写一个专门的格式化函数,把字节数据转换成「地址+十六进制+ASCII」的标准内存dump格式。这里给你一个示例实现:

#include <stdio.h>
#include <ctype.h>
#include <stdint.h>

void print_memory_dump(const unsigned char *data, SIZE_T size, uintptr_t base_addr) {
    // 遍历每一行(每行16字节)
    for (SIZE_T i = 0; i < size; i += 16) {
        // 打印当前行的起始地址(8位十六进制)
        printf("%08X  ", base_addr + i);

        // 打印十六进制部分:16个字节,每8个字节加一个空格分隔
        for (SIZE_T j = 0; j < 16; j++) {
            if (i + j < size) {
                printf("%02X ", data[i + j]);
            } else {
                printf("   "); // 不足16字节时补空格对齐
            }
            if (j == 7) {
                printf(" "); // 8字节后加分隔空格
            }
        }

        // 打印ASCII部分:可见字符直接输出,不可见字符用.代替
        printf(" ");
        for (SIZE_T j = 0; j < 16; j++) {
            if (i + j < size) {
                unsigned char c = data[i + j];
                printf("%c", isprint((unsigned char)c) ? c : '.');
            } else {
                printf(" ");
            }
        }
        printf("\n");
    }
}

使用方法很简单:在你读取完tempbuf的bytes_read字节后,调用这个函数即可:

// 比如在memcpy之后添加
print_memory_dump(tempbuf, bytes_read, mb->addr + total_read);

二、突破tempbuf大小限制读取更多数据

你的代码其实已经具备循环读取大内存的逻辑了——每次用tempbuf读取一部分,然后复制到mb->buffer,直到所有数据读完。出现「只能读取tempbuf大小数据」的问题,大概率是这两个原因之一:

1. 确保mb->buffer有足够的存储空间

在调用update_memblock之前,你必须确保mb->buffer已经预先分配了至少mb->size大小的内存(比如用malloc(mb->size))。如果mb->buffer太小,后续的memcpy会导致缓冲区溢出,数据无法正确存储。

2. 优化读取逻辑(可选:用动态缓冲区代替静态数组)

如果想减少循环次数,或者需要更大的单次读取缓冲区,可以把静态的tempbuf改成动态分配的:

void update_memblock(MEMBLOCK *mb) { 
    SIZE_T bytes_left; 
    SIZE_T total_read; 
    SIZE_T bytes_to_read; 
    SIZE_T bytes_read; 
    // 动态分配缓冲区,这里设为1MB,你可以根据需求调整
    SIZE_T tempbuf_size = 1024 * 1024; 
    unsigned char *tempbuf = malloc(tempbuf_size);

    if (!tempbuf) {
        // 内存分配失败,返回已读取的字节数
        mb->size = 0;
        return;
    }

    bytes_left = mb->size; 
    total_read = 0; 

    while (bytes_left) { 
        bytes_to_read = (bytes_left > tempbuf_size) ? tempbuf_size : bytes_left; 
        // 先检查ReadProcessMemory的返回值,更健壮
        if (!ReadProcessMemory(mb->hProc, mb->addr + total_read, tempbuf, bytes_to_read, &bytes_read)) {
            break; // 读取失败,退出循环
        }
        if (bytes_read == 0) {
            break; // 未读取到任何数据
        }

        memcpy(mb->buffer + total_read, tempbuf, bytes_read); 
        bytes_left -= bytes_read; 
        total_read += bytes_read; 
    } 

    mb->size = total_read; 
    free(tempbuf); // 释放动态分配的内存
}

另外,原代码中只检查bytes_read != bytes_to_read就退出,其实不够严谨——有时候ReadProcessMemory会成功但返回的字节数小于请求值(比如读取到进程内存的边界),这种情况可以继续尝试读取剩余数据,而不是直接退出。你可以把原有的if (bytes_read != bytes_to_read) break;改成:

if (bytes_read == 0) break; // 只有当没读到数据时才退出

这样就能尽可能读取所有可访问的内存数据了。


内容的提问来源于stack exchange,提问作者Total Anime Immersion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:58:37