c程序的内存访问监视器

Flo*_*ram 10 c memory heap-memory

我试图追踪堆分配内存的内存访问.

例如,如果我有以下代码:

void set_value(int* buffer, size_t pos, int value) {
    buffer[pos] = value;
}
int main(void) {    
    int* buffer = malloc(BUFF_SIZE * sizeof(int));
    set_value(buffer, 2, 10);
    set_value(buffer, 3, 12);

    free(buffer);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我主要感兴趣的是访问内存的函数和已修改内容的地址.

我曾尝试使用多个内存工具,如ptrace,strace,ASan,Dmalloc,但我没有达到结果.

另一个想法是使用mprotect修改内存更改内存保护并为页面错误编写处理程序.我将内存设置为只读,当发生写入时,处理程序修改页面保护并让函数将内容写入内存,但之后我无法再次读取页面,以便进一步访问.

你有关于如何监控每次写入堆内存的提示吗?

Har*_*ald 2

如果您愿意监视每个内存访问,我建议您查看 PIN [1] 和/或 DynInst [2] 等软件包。两者都是动态二进制检测包,允许您修改应用程序二进制文件以注入所需的代码。在这种情况下,这两个工具都允许您检测每条指令并了解它们引用的地址(如果它们是加载/存储)。然后,如果您只对 malloc(或 realloc 或 calloc)分配的内存感兴趣,您还可以检测这些例程来捕获它们的入口参数和出口值,以确定感兴趣的内存区域。这两种工具都提供类似的功能。我想说它们的主要区别在于 PIN 专门针对 Intel 处理器,而 DynInst 是一个开源项目,支持不同的处理器架构(Intel、IBM-Power、ARM)。

由于在这种对每条指令进行检测的特定场景中,检测可能成本很高,并且您可以负担采样内存引用的费用,因此我建议您探索最近的 Intel 处理器中的 PEBS 基础设施 [3](AMD 处理器有类似的名为 IBS 的东西)。PEBS 可以通过 Linux 操作系统中可用的 perf 工具使用 [4](我不知道它是否在其他操作系统上可用)

[1] PIN https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool

[2] DynInst http://www.dyninst.org

[3] 英特尔手册第 18.4.4 节基于精确事件的采样 (PEBS) http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-软件开发人员-vol-3b-part-2-manual.pdf

[4] Linux perf 采样内存地址https://lwn.net/Articles/531766/