How to insert a LC_LOAD_DYLIB command into a Mach-

2019-03-13 14:54发布

问题:

I'm looking to patch a piece of abandonware with some code.

The software is carbon based, so I can not use an InputManager (at least, I do not think I can). My idea was to add a dylib reference to the mach-o header, and launch a new thread when the initialization routine is called.

I have mucked around with the mach-o header using a hexeditor to add the appropriate load command (LC_ LOAD_DYLIB).

otool reports what I expect to see, so I'm fairly confident that the file is correctly formatted.

Load command 63
          cmd LC_LOAD_DYLIB
      cmdsize 60
         name @executable_path/libAltInput.dylib (offset 24)
   time stamp 1183743291 Fri Jul  6 19:34:51 2007
      current version 0.0.0
compatibility version 0.0.0

However, launching the binary gives me the following error

dyld: bad external relocation length

All I can guess this means is that I need to modify the LC_ SYMTAB or LC_ DYNSYMTAB sections...

Anyone have any ideas?

回答1:

I'm not entirely sure what you're trying to accomplish, but the easiest way to do this is probably to inject a thread into the mach task after it starts. A great source of information on doing this (as well as running code to do it) can be found here: http://rentzsch.com/mach_inject/.

Some caveats that you should be aware of:

  1. the mach task_for_pid() call necessary to get the mach port to the task is now privleged and requires authorization to call. The reason for this is pretty self-evident but if you were planning on releasing something with injected code, you should be aware of this.
  2. Your code will be running in the same process space as the original application but on a separate thread. You will, therefore, have full access to the application, however, if it is not thread-aware be very careful about using and manipulating data from outside of your injected code. Obviously all multithreaded issues will be amplified here because the original code was never aware of your additions.


回答2:

The easiest solution that doesn't involve patching the binary is to simply use the DYLD_INSERT_LIBRARIES environment variable and then run your application.

set DYLD_INSERT_LIBRARIES to /my/path/libAltInput.dylib

I'm assuming the reason the dynamic linker reported an error is because many fields in the Mach-O file format contain addresses specified as an offset from the beginning of the file so adding another load command would invalidate every address. For example, see the symoff and stroff entries in the Mac OS X ABI Mach-O File Format Reference.