Linux 在给定受保护内存时,如何使系统调用调用我的SIGSEGV处理程序?
我正在开发一个内存跟踪库,在这个库中,我们使用Linux 在给定受保护内存时,如何使系统调用调用我的SIGSEGV处理程序?,linux,memory,system-calls,segmentation-fault,Linux,Memory,System Calls,Segmentation Fault,我正在开发一个内存跟踪库,在这个库中,我们使用mprotect删除对程序大部分内存的访问,并使用SIGSEGV处理程序在程序接触单个页面时恢复对它们的访问。这在大多数情况下都很有效 我的问题是,当程序调用一个系统调用(比如说read),而我的库中的内存被标记为no access时,系统调用只返回-1并将errno设置为EFAULT。这会以奇怪的方式改变正在测试的程序的行为。我希望能够在系统调用真正进入内核之前,恢复对它的访问 我目前的方法是为每个涉及内存的系统调用创建一个包装器。每个包装器在将其
mprotect
删除对程序大部分内存的访问,并使用SIGSEGV处理程序在程序接触单个页面时恢复对它们的访问。这在大多数情况下都很有效
我的问题是,当程序调用一个系统调用(比如说read
),而我的库中的内存被标记为no access时,系统调用只返回-1并将errno
设置为EFAULT
。这会以奇怪的方式改变正在测试的程序的行为。我希望能够在系统调用真正进入内核之前,恢复对它的访问
我目前的方法是为每个涉及内存的系统调用创建一个包装器。每个包装器在将其传递给真正的系统调用之前,都会接触到提供给它的所有内存。这似乎适用于直接从程序发出的调用,但不适用于libc发出的调用(例如,fread
将在不使用我的包装器的情况下直接调用read
)。有没有更好的办法?如何实现这种行为?您可以使用来实现这一点。它允许您监视流程,并在发生某些事件时得到通知。出于您的目的,请查看PTRACE_SYSCALL
,它允许您在进入和退出SYSCALL时停止进程
但是,您必须更改一些内存跟踪基础结构,因为ptrace
的运行方式是父进程监视子进程,而就子进程而言,它不知道监视的事件何时发生。话虽如此,您应该能够按照以下思路做一些事情:
- 设置ptrace父级和子级,监视(至少)
ptrace\u系统调用
- 子进程执行系统调用;并通知家长
- 父级保存请求的系统调用信息;并使用
和PTRACE_GETREGS
来更改子状态,从而代替调用系统调用;子进程调用“内存取消保护”例程李>PTRACE_SETREGS
- 孩子不保护自己的记忆;然后引发
或类似事件,告知控制父级内存工作已完成SIGUSR1
- 父级捕获
,使用SIGUSR
恢复先前保存的系统调用信息并恢复子级PTRACE\u SETREGS
- 子系统恢复并执行原始系统调用