Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Linux中的截获文件打开事件_Android_Linux_Unix_Posix_Inotify - Fatal编程技术网

Android Linux中的截获文件打开事件

Android Linux中的截获文件打开事件,android,linux,unix,posix,inotify,Android,Linux,Unix,Posix,Inotify,假设我们有一个进程可能dlopen()某个第三方库。此库可以对用户只有写入权限的某些文件执行open(“仅写入日志文件”,O\u WRONLY)。如果此库试图打开文件,我们需要能够收到通知,因此稍后我们可能会dup()返回描述符并重定向输出。 很少有限制使拦截更困难: LD\u预加载被禁止-无法钩住open() inotify(7)没有帮助,因为用户对“只写日志文件”没有读取权限,并且该文件归管理员所有 我们无法访问图书馆资源,因此无法对其进行修改 “只写日志文件”在库中是硬编码的,因此我们无

假设我们有一个进程可能
dlopen()
某个第三方库。此库可以对用户只有写入权限的某些文件执行
open(“仅写入日志文件”,O\u WRONLY)
。如果此库试图打开文件,我们需要能够收到通知,因此稍后我们可能会
dup()
返回描述符并重定向输出。 很少有限制使拦截更困难:

  • LD\u预加载被禁止-无法钩住
    open()
  • inotify(7)
    没有帮助,因为用户对
    “只写日志文件”
    没有读取权限,并且该文件归管理员所有
  • 我们无法访问图书馆资源,因此无法对其进行修改
  • “只写日志文件”
    在库中是硬编码的,因此我们无法传递其他名称来执行重定向
我想知道Linux是否有一种在这种情况下提供帮助的有效方法。 特别是考虑到进程经常会
打开()
杂项文件这一事实

另外,为了避免混淆和更好地理解,它是一个带有加载JVM的常规Android应用程序。如果应用程序挂起(即所谓的ANR)-系统将向其发送
SIGQUIT
。信号通过专用线程接收,该线程
open()
s
/data/anr/traces.txt
并向其写入JVM状态。这些数据对于调试非常有用。但由于安全原因,应用程序无法直接读取该文件(所有应用程序都会写入该文件,所以可能存在一些敏感问题)。无论如何,我相信截取我的流程将写入的内容是绝对公平的


注意:在最坏的情况下,可以找到JVM库映像(
libart.so
),并手动为
open()
修补跳转槽。但是听起来不太好。

如果这只是将写入(和读取)重定向到单个文件,您可以在装载命名空间中运行应用程序,并为该特定文件提供合适的绑定装载。以这种方式设置可能需要一个小的SUID二进制文件


一个更通用的解决方案很快就可以使用联合文件系统,而且要正确使用它是相当困难的。即使是内核中的union文件系统,
overlayfs
,也无法提供完整的POSIX语义。

您需要LD_PRELOAD来钩住应用程序。要钩住第三方库,只需在库之前加载钩子(或者将其放在可执行文件中)


假设库从libc调用
open
,而不是直接调用相应的系统调用,并且它是以正常方式链接的,那么代码中的某个地方就有一个名为
open
的函数。让它从libc调用
open
RTLD\u NEXT
或其他任何东西)。第三方库(当然还有所有其他库)会将其
open
符号解析为您的函数

听起来你的处境很麻烦。下面简单提到的大多数解决方案都保证会干扰SELinux,所以不要相信我的话

使用
strace
调试自己的进程以拦截
open
是普通Linux上常见的解决方案之一。我不确定它是否能在安卓系统中工作;在某些新版本中启动的不可调试应用程序(如果尚未被禁止的话)可能会被禁止使用

seccomp bpf是另一种可能性。可能在较旧的安卓版本上不可用,但由于安卓O seccomp将成为安卓安全装备的保证部分。在仅警告模式下拦截
open
,并在发生有趣的事情时(通过调试或信号)将控制权交还给自己

如果按需打开
/data/anr/traces.txt
,您应该能够通过使用inotify或通过轮询查看
/proc/self/fd/
的内容来观察到这一点。您可以通过设置打开线程的io精细度来减少竞争的影响

所有这些都只是部分解决方案,您可能仍然需要解码实际发生的
open
syscall(strace源代码可能有助于strace/seccomp解决方案,readlink for
/proc/self/fd/
)并据此采取行动(dup2,正如您已经提到的)

“只写日志文件”在库中硬编码


是否可以修改库/可执行文件数据段的内存?Afaik
mprotect
PROTECT\u EXEC
尤其受到严格限制,但至少允许使用mmap(以支持JIT编译器等)。也许可以编造一些东西来在适当的位置编辑字符串常量(只要这样做是可能的和允许的,我自己对此不确定)。

我觉得对
LD\u PRELOAD
的反对是非技术性的。它在原则上可能有效,但如果站点策略不允许使用它,这并不重要。哦,我对我的问题描述得很糟糕,因为我错过了这样的场景。我不能使用动态链接器的
LD_PRELOAD
和任何技巧,因为没有机会在应该监视的库之前加载任何自定义代码。请参阅编辑后的问题。“没有机会加载任何应监视的库之前的自定义代码”您的意思不太清楚。“假设我们有一个可能会打开()某个第三方库的进程”。如果你能控制这个过程,你就被设置好了。如果不是,那么用一种奇怪的方式来描述这种情况。整个程序是第三方的。与其他操作系统相比,Linux使这一点相对困难。微软的分层驱动架构使它相对容易。许多Windows驱动程序手册都包含强制加密文件系统的驱动程序示例。我从未见过Linux中分层的好例子。在当前的设计下,这可能是不可能的。这可能是重复的:。在40161522问题中,他不能使用
LD_PRELOAD
,因为这对他来说不可靠。@jww很好的建议,但
L