多线程应用程序中注入的 mprotect 调用的切换标志

Toggling flags for injected mprotect calls in multi-threaded applications

我正在开发一个项目,其中动态库 (.so) 在运行时注入到某个目标程序中(动态检测)。该库使用 mmap/munmap 处理自己的内存。出于安全原因,要求库中的某些映射区域 可通过库中公开的 API 进行写入。

我们所做的是切换内存区域的写标志使用mprotectPROT_WRITE在prologue/epilogue库函数,例如:

void foo(void) {
  mprotect(addr, PAGE_SIZE, PROT_READ | PROT_WRITE);
  ...
  ...
  mprotect(addr, PAGE_SIZE, PROT_READ);
}

这适用于单线程应用程序。对于多线程应用程序,如果上下文切换(到同一进程中的不同任务)发生 after,则同一进程中的其他任务可能能够写入映射的库区域PROT_WRITE 已设置(因此内存是可写的)并且 它被清除之前。

所以,问题是:是否可以在 foo returns 之前禁用进程中的其他任务?如果没有,您建议如何解决这个问题?

您的安全模型无效。如果您的库代码可以 mprotect 这些区域可写,那么程序的任何其他部分也可以。你无法内省地阻止这种情况。这种安全属性只能通过某种外部监督来实现,直接由内核或通过跟踪过程(例如使用传统的 ptrace 或 seccomp 跟踪)。

如果您实际上不需要 安全性 属性,而只是想通过已经信任的代码可靠地捕获写入,您 可以通过跟踪所有线程,用 pthread_kill 向它们发出信号,并让信号处理程序阻塞直到信号线程允许它们继续,从而实现类似的目的。