1

I am working on a project that requires wrapping libc calls particularly file i/o calls like open, read, write, close etc. I have created a shared library (say, wrapper.so) and preload this wrapper.so. I could successful use this wrapper on Linux by setting the LD_PRELOAD variable. On MAC, I tried setting the DYLD_FORCE_FLAT_NAMESPACE to 1, DYLD_INSERT_LIBRARIES to /path/wrapper.so using 1) .bash_profile, 2)launchctl setenv, 3)LaunchAgent, 4)LaunchDeamon approaches but nothing work.

I tried even setting the DYLD_FORCE_FLAT_NAMESPACE, DYLD_INSERT_LIBRARIES environment variables at application level for specific applications via their Info.plist but this didn't work either.

Note: I could set some random new variable, say MYVAR, with all the above mentioned approaches. So, it is while setting the DYLD_* variables that I have problem setting. Can you please help me set the DYLD_FORCE_FLAT_NAMESPACE, DYLD_INSERT_LIBRARIES variables on MAC.

Damodar
  • 21
  • 4
  • Interesting link, thank you @KenThomases. Where (which folder) is the program being launched from? – Paul Sanders Jun 03 '18 at 05:13
  • Also ... Ken's link tells you what the problem is but not how to solve it. I hope my answer does this. – Paul Sanders Jun 03 '18 at 06:41
  • Well, it shows the general form of a solution, which is to set the environment variables after the launch of the protected binary. For example, if you're running a shell script, have the script itself set them rather than trying to make it inherit them from its parent. Or, avoid protected binaries completely if you can. An alternative approach to using environment variables at all might be [dyld interposing](https://opensource.apple.com/source/dyld/dyld-519.2.2/include/mach-o/dyld-interposing.h.auto.html). – Ken Thomases Jun 03 '18 at 13:54

1 Answers1

1

A shared library (.dylib) on OS X 'knows' where it expects to be installed to and this information is in turn embedded in any executable that links against it so that the executable knows where to find the library at runtime. Weird though it sounds, that's how it works. Apple call it the dylib's 'install name'.

You can see the install name of a dylib by using otool. For example:

$ otool -D wxwidgets.dylib
wxwidgets.dylib:
/Users/dipol/wxPython/dist-darwin/wx-2.8/wxWidgets/lib/wxwidgets.dylib

If there is only one consumer of your dylib then it's probably easiest to tell the dylib to use a relative path, rather than an absolute path, as its install name. You can do this when building the library like so:

gcc -o my_dylib.dylib -install_name @rpath/my_dylib.dylib ...

Then just put the dylib in the same directory as your executable and it should be able to find it. This also works with clang. You can also set the dylib's install name with a utility called install_name_tool, but that's a bit more difficult.

Here are some links you might find useful:

Apple's documentation

https://blogs.oracle.com/dipol/dynamic-libraries,-rpath,-and-mac-os http://log.zyxar.com/blog/2012/03/10/install-name-on-os-x/

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Sorry If I missed. How does this relates to setting the DYLD_* environment variable – Damodar Jun 02 '18 at 22:46
  • It doesn't, directly. People don't usually do that on the Mac for whatever reason and as I hope my answer shows, you shouldn't need to either if you do as I suggest. As Ken's link makes clear, that approach doesn't always work anymore. – Paul Sanders Jun 03 '18 at 05:16