C语言中内存读写的自定义处理

C语言中内存读写的自定义处理,c,gcc,memory,malloc,C,Gcc,Memory,Malloc,我正在编写自己的malloc,并使用LD_PRELOAD技巧来使用它。我需要能够对堆的每次内存访问执行自定义功能,包括读写(性能不是问题,功能是目标) 例如,对于某些代码,如 intx=A[5]; 我希望能够捕获从(A+5)读取的数据,而不是从该内存位置读取,返回我自己的自定义值以存储在x中 到目前为止,我的想法是: mprotectaway,处理生成的SIGSEGV并在处理程序中执行我需要的操作。据我所知,我可以访问void*si_addr中的错误地址,但我不确定如何区分读和写-即使我做到了

我正在编写自己的
malloc
,并使用
LD_PRELOAD
技巧来使用它。我需要能够对堆的每次内存访问执行自定义功能,包括读写(性能不是问题,功能是目标)

例如,对于某些代码,如

intx=A[5];
我希望能够捕获从
(A+5)
读取的数据,而不是从该内存位置读取,返回我自己的自定义值以存储在
x

到目前为止,我的想法是:

  • mprotect
    away,处理生成的SIGSEGV并在处理程序中执行我需要的操作。据我所知,我可以访问
    void*si_addr
    中的错误地址,但我不确定如何区分读和写-即使我做到了,我也不确定如何处理写,因为我不知道要在处理程序中写入的值
  • 调整gcc以专门处理内存访问。从我所读的内容来看,理解gcc代码需要一段时间,除非它的IR/抽象程序集方便地隔离内存加载/存储,否则我不确定这有多实际

  • 感谢您的建议。

    最简单的方法是通过malloc(您可能希望拥有mmap、munmap、mprotect、sig(action、nal等)以实现全面覆盖)。您的返回地址与有效映射不对应,捕获SIGBUS+SIGSEGV,解释siginfo结构以修复您的进程。。。但这在某种程度上仅限于在堆上操作,程序可以很容易地从堆中逃脱,如果您试图捕获一个行为不正常的程序,该程序可能会损坏您的查找表

    为了更全面地覆盖,您可能想看看gvisor,它被称为容器运行时沙箱。它的技术更接近于调试器,因为它完全控制目标,捕获其故障、系统调用等。。并管理其地址空间。这可能是一个小手术来适应你的需要

    在这两种情况下,当您出现故障时,您必须安装内存并重新启动程序,或者模拟指令。如果您使用的是riscv或ARM等干净的体系结构,那么仿真也不算太糟糕,但是对于x86这样过于放纵的体系结构,您非常需要集成qemu。如果采用类似gvisor的方法,则可以安装页面并设置单步标志,然后删除单步陷阱上的页面,这样就不那么麻烦了。dtrace的前身是atrace,它使用这种方法分析缓存和tlb访问模式


    听起来是个有趣的项目;我希望一切顺利。

    如果没有内核支持和对编译器代码生成器的全面修改,我看不出这是如何在本机工作的。我估计这项任务极其困难。实现支持所需语义的虚拟机可能更容易,但如果必须从头开始,这仍然是一项艰巨的工作。如果不局限于LD_预加载,还可以像valgrind和Sun的dbx那样动态重写将要执行的代码。