拦截Linux上的文件操作

时间:2016-10-20 18:06:27

标签: c linux ld-preload

我正在开发一个用于渲染视觉效果和动画的云平台。我们接受各种格式的场景描述渲染它们,并将图像输出返回给用户。处理后端是Linux。有时我们会收到在Windows上生成的场景描述,因此我们得到的路径看起来像'C:\ path \ to \ file.mb'。我编写了一个Linux共享库来拦截各种文件系统调用,并改变Linux可以理解的路径'/ C / path / to / file'。我使用LD_PRELOAD机制在“真实”函数之前插入我的函数,它工作得很好......除非它没有。

例如这个命令:

  

LD_PRELOAD = / home / robert / path_fix.so渲染-s 1 -e 1 C:\ path \ to \ test_scene_03_vray.ma

找不到test_scene_03_vray.ma。这也行不通:

  

LD_PRELOAD = / home / robert / path_fix.so echo test> C:\路径\到\ test.txt的

我一直在使用ltrace来确定哪些函数是通过引用路径名调用的,但这些示例并未显示在我的跟踪中:

  

ltrace -f -C -S -o ltrace.out渲染C:\ path \到\ test_scene_03_vray.ma

是否有一个除ltrace之外的工具可以让我看到调用了哪些函数调用?

以下是我已经覆盖的内容列表:

  • 的fopen
  • freopen函数
  • 执行opendir
  • 穿心莲
  • 了openat
  • STAT
  • LSTAT
  • fstatat
  • __ lxstat
  • __ xstat
  • MKDIR
  • mkdirat
  • 的unlink
  • unlinkat
  • 访问
  • faccessat
  • 重命名
  • renameat
  • renameat2
  • CHMOD
  • fchmodat
  • CHOWN
  • lchown
  • fchownat
  • 链接
  • linkat
  • name_to_handle_at
  • 的readlink
  • readlinkat
  • 符号链接
  • symlinkat
  • 命令rmdir
  • CHDIR

我在这里缺少更多功能吗?我试图实现所有需要的东西

  

const char * filepath

作为论据。

附带问题:这似乎已经是一个已经解决的问题...是否有一个库或其他方法将Windows路径转换为unix友好路径?请记住,渲染应用程序是第三方专有二进制文件,因此我无法修改它们。

感谢您的任何建议!

2 个答案:

答案 0 :(得分:1)

Yes, there are other functions, such as the 64-bit functions open64(). There are also functions such as __open().

On a 64-bit Centos 7 server, for just open I get:

nm -D /lib64/libc.so.6  | grep open
0000000000033d70 T catopen
00000000003c0b80 B _dl_open_hook
000000000006b140 T fdopen
00000000000ba4c0 W fdopendir
00000000000755d0 T fmemopen
000000000006ba00 T fopen
000000000006ba00 W fopen64
000000000006bb60 T fopencookie
0000000000073700 T freopen
0000000000074b60 T freopen64
00000000000eb7a0 T fts_open
0000000000022220 T iconv_open
000000000006b140 T _IO_fdopen
0000000000077230 T _IO_file_fopen
0000000000077180 T _IO_file_open
000000000006ba00 T _IO_fopen
000000000006d1d0 T _IO_popen
000000000006cee0 T _IO_proc_open
0000000000131580 T __libc_dlopen_mode
00000000000e82a0 W open
00000000000e82a0 W __open
00000000000ed0f0 T __open_2
00000000000e82a0 W open64
00000000000e82a0 W __open64
00000000000ed110 T __open64_2
00000000000e8330 W openat
00000000000e8410 T __openat_2
00000000000e8330 W openat64
00000000000e8410 W __openat64_2
00000000000f7860 T open_by_handle_at
00000000000340b0 T __open_catalog
00000000000b9f70 W opendir
00000000000f12b0 T openlog
0000000000073ea0 T open_memstream
00000000000731c0 T open_wmemstream
000000000006d1d0 T popen
0000000000130630 W posix_openpt
00000000000e6ec0 T posix_spawn_file_actions_addopen

For example, on Linux this C code is quite likely to work just fine:

int fd = __open( path, O_RDONLY );

You're also not going to catch statically-linked processes, or those that issue a system call such as open directly.

答案 1 :(得分:0)

你可以在技术上使用kprobes拦截调用,但如果文件的数量太多或动态生成,我建议创建符号链接。它更安全,更简单。