1

I've hooked the system call to typedef int (*orig_open_f_type)(const char *__file, int __oflag, ...); and thus, whenever a file gets opened, my code gets the event before it is passed on to the system. I created a dynamic library that overrides the open call and inject this library using DYLD_INSERT_LIBRARIES - working on a Mac machine and using XCode. It is a standard step that enables me to hook calls.

Now, I have bash script in which I have some files that I want to open. I have tried xdg-open , cat, exec - but they are not triggering the system call to open the file.

How should I invoke this open call in my bash script?

Please note that I have tested my open call hook, by opening files in C code.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
prabodhprakash
  • 3,825
  • 24
  • 48
  • Seems related: http://stackoverflow.com/questions/10196395/os-system-calls-from-bash-script – Mateusz Piotrowski Dec 21 '16 at 20:21
  • 1
    It removes all the content from the original file. I've tried that also. – prabodhprakash Dec 21 '16 at 20:22
  • How did you hook the system call in your C code? `LD_PRELOAD` or another mechanism? You have to make sure that the commands you run are also hooked to use your mechanism, both Bash itself and any executables it uses. How much of a problem that represents depends on your hooking mechanism. – Jonathan Leffler Dec 21 '16 at 20:32
  • I suspect you're running foul of SIP (System Integrity Protection) which is designed to stop people doing things like that with system-provided executables. Consider copying `/bin/cat` to `/usr/local/bin/cat` and then try hooking (running) the local copy. You might get away with it there. Or downgrade to a Mac OS X release prior to El Capitan. (No, on second thoughts, don't try that.) – Jonathan Leffler Dec 21 '16 at 20:39
  • You can follow links from [Can Mac OS X El Capitan run software compiled for Yosemite that expects libraries in `/usr/gnu/lib`?](http://stackoverflow.com/questions/33074492/) to find out more about SIP. – Jonathan Leffler Dec 21 '16 at 20:43
  • I read about SIP. let me try that. However, this may not be a solution because, I need to ship this further into different machines. – prabodhprakash Dec 21 '16 at 20:43
  • The 'workaround' is purely for demonstration purposes. Basically, if I'm right, SIP is Apple's way of saying "don't go messing with our software". – Jonathan Leffler Dec 21 '16 at 20:47
  • But, hooking system calls are pretty normal thing to do and all that I now want is to see - all system commands that were run by a bash command. Is that something that anyone would want to restrict? – prabodhprakash Dec 21 '16 at 20:48
  • 1
    Following links to [System Integrity Protection](https://derflounder.wordpress.com/2015/10/01/system-integrity-protection-adding-another-layer-to-apples-security-model/), it says explicitly: _SIP’s protections are not limited to protecting the system from filesystem changes. There are also system calls which are now restricted in their functionality. • … • dyld environment variables are ignored • …_ – Jonathan Leffler Dec 21 '16 at 20:53

3 Answers3

3

I believe you're running foul of Apple's SIP (System Integrity Protection) which is designed to stop people doing things like that with system-provided executables. SIP was added to Mac OS X El Capitan (10.11) and continues in macOS Sierra (10.12).

To demonstrate whether this is the problem, consider copying /bin/cat to /usr/local/bin/cat and then try hooking (running) the local copy. You might get away with it there. This 'workaround' is purely for demonstration purposes. Basically, if I'm right, SIP is Apple's way of saying "don't go messing with our software".

You can follow links from Can Mac OS X El Capitan run software compiled for Yosemite that expects libraries in /usr/gnu/lib? to find out more about SIP. Following links via What is the "rootless" feature in El Capitan, really? on Ask Different to a blog article on System Integrity Protection, it says explicitly:

Runtime protection

SIP’s protections are not limited to protecting the system from filesystem changes. There are also system calls which are now restricted in their functionality.

  • task_for_pid() / processor_set_tasks() fail with EPERM
  • Mach special ports are reset on exec(2)
  • dyld environment variables are ignored
  • DTrace probes unavailable

However, SIP does not block inspection by the developer of their own applications while they’re being developed. Xcode’s tools will continue to allow apps to be inspected and debugged during the development process.

For more details on this, I recommend taking a look at Apple’s developer documentation for SIP.

Emphasis added

Basically, this means that you won't be able to hook calls to the open() system call for Apple-supplied software installed in the system directories. You will need to rethink what you are trying to do.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
2

Running any normal command -- like cat -- that processes a file will cause the file to be opened. You can also open a file (and immediately close it) using the shell syntax:

: < /path/to/file

If your system call hook isn't getting called, something must be wrong with your hook -- there's no way these commands are working without opening the file. Alas, you haven't explained how you implemented your hook, so we have no way of debugging that.

0

The file command opens the file to look at its contents.

$ file /path/to/file

I have suggested this because it eventually leads to having the system call open which can be confirmed using strace.

$ strace file /path/to/file 2>&1 | grep open

I thought one of the good things about using file is that it opens the file in read only mode. In comparison to other ideas, unlike cat, it will not have to run through the entire file, just part of it, so the time complexity using file may be constant. Unlike vim, which someone has suggested, file will return when finished and not block like a text editor would.

diametralpitch
  • 675
  • 3
  • 5
  • 1
    I think you've missed the point of what the question is asking about. – Jonathan Leffler Dec 21 '16 at 20:30
  • It does not invoke system's `open` call. – prabodhprakash Dec 21 '16 at 20:31
  • @prabodhprakash: the `file` command does use the `open()` system call to look at some files — not all files, but it will read some data from most regular files to identify the type. – Jonathan Leffler Dec 21 '16 at 20:33
  • So do `cat`, `head`, `wc`, `vim`, etc. etc. etc. – Keith Thompson Dec 21 '16 at 20:39
  • No idea; none of the down-votes is mine. But it would have been a good idea to remove it immediately, at least for long enough to cogitate over whether to undelete it or edit it before undeleting it. Actually, I suspect the reason is precisely that you didn't respond quick enough. SO can be harsh. – Jonathan Leffler Dec 21 '16 at 20:45
  • My interpretation was that the OP was looking for a shell command that leads to having the system call open. The idea of using 'file' came to mind because it returns immediately without blocking like the other commands do. I'm open to all feedback on this though. I can only improve if people are brutally honest with me. – diametralpitch Dec 21 '16 at 20:51
  • I think you should edit some of your commentary into the answer itself. – Mad Physicist Dec 22 '16 at 02:21