Code Monkey home page Code Monkey logo

insert_dylib's Introduction

insert_dylib

Command line utility for inserting a dylib load command into a Mach-O binary.

Does the following (to each arch if the binary is fat):

  • Adds a LC_LOAD_DYLIB load command to the end of the load commands
  • Increments the mach header's ncmds and adjusts its sizeofcmds
  • (Removes code signature if present)

Usage

Usage: insert_dylib dylib_path binary_path [new_binary_path]
Option flags: --inplace --weak --overwrite --strip-codesig --no-strip-codesig --all-yes

insert_dylib inserts a load command to load the dylib_path in binary_path.

Unless --inplace option is specified, insert_dylib will produce a new binary at new_binary_path.
If neither --inplace nor new_binary_path is specified, the output binary will be located at the same location as the input binary with _patched prepended to the name.

If the --weak option is specified, insert_dylib will insert a LC_LOAD_WEAK_DYLIB load command instead of LC_LOAD_DYLIB.

Example

$ cat > test.c
int main(void) {
	printf("Testing\n");
	return 0;
}
^D
$ clang test.c -o test &> /dev/null
$ insert_dylib /usr/lib/libfoo.dylib test
The provided dylib path doesn't exist. Continue anyway? [y/n] y
Added LC_LOAD_DYLIB to test_patched
$ ./test
Testing
$ ./test_patched
dyld: Library not loaded: /usr/lib/libfoo.dylib
  Referenced from: /Users/Tyilo/./test_patched
  Reason: image not found
Trace/BPT trap: 5

otool diff between original and patched binary

$ diff -u <(otool -hl test) <(otool -hl test_patched)
--- /dev/fd/63	2014-07-30 04:08:40.000000000 +0200
+++ /dev/fd/62	2014-07-30 04:08:40.000000000 +0200
@@ -1,7 +1,7 @@
-test:
+test_patched:
 Mach header
       magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
- 0xfeedfacf 16777223          3  0x80          2    16       1296 0x00200085
+ 0xfeedfacf 16777223          3  0x80          2    17       1344 0x00200085
 Load command 0
       cmd LC_SEGMENT_64
   cmdsize 72
@@ -231,3 +231,10 @@
   cmdsize 16
   dataoff 8296
  datasize 64
+Load command 16
+          cmd LC_LOAD_DYLIB
+      cmdsize 48
+         name /usr/lib/libfoo.dylib (offset 24)
+   time stamp 0 Thu Jan  1 01:00:00 1970
+      current version 0.0.0
+compatibility version 0.0.0

--weak option

$ insert_dylib --weak /usr/lib/libfoo.dylib test test_patched2
The provided dylib path doesn't exist. Continue anyway? [y/n] y
Added LC_LOAD_WEAK_DYLIB to test_patched2
$ ./test_patched2
Testing

Removing code signature

To remove the code signature it is enough to delete the LC_CODE_SIGNATURE load command and fixup the mach header's ncmds and sizeofcmds, assuming it is the last load command.

However if you just do this codesign_allocate (used by codesign and ldid) will fail with the error:

.../codesign_allocate: file not in an order that can be processed (link edit information does not fill the __LINKEDIT segment):

To fix this insert_dylib assumes that the code signature that LC_CODE_SIGNATURE is in the end of the __LINKEDIT segment and the that the segment is in the end of the architectures slice.

It then truncate that slice to remove the code signature part of the __LINKEDIT segment. It also updates the LC_SEGMENT (or LC_SEGMENT64) load command for the __LINKEDIT segment from the new file size. If the binary is fat we also update the size and we might also move the slice and so the offset should also be updated.

After removing the code signature from the __LINKEDIT segment, the last thing in that segment is typically the string table. As the code signature seems to be aligned by 0x10, and so after removing the code signature, nothing points to the padding at the end of the segment, which codesign_allocate doesn't like either. To fix this we just increase the size of the string table in the LC_SYMTAB command so it also includes the padding.

Todo

  • Improved checking for free space to insert the new load command
  • Allow removal of LC_CODE_SIGNATURE if it isn't the last load command
  • Remove __RESTRICT,__restrict if not enough space (suggesion by dirkg)

insert_dylib's People

Contributors

stanley1108 avatar tyilo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

insert_dylib's Issues

Trying to load .dylib into iOS binary - crash at exec

I insert the dylib correctly (I guess), my otool -L binary show me this:

@executable_path/final.dylib (compatibility version 0.0.0, current version 0.0.0)

Watching my iPad syslog on Xcode after side loading the modified app, I get the following message:

Aug 15 04:44:53 arthurpad ReportCrash[5619] : Dyld Error Message:

Dyld Message: Library not loaded: @executable_path/final.dylib

Referenced from: /var/containers/Bundle/Application/ABC2F509-0738-44C6-BF1E-E082ED13A460/NvwaStone.app/NvwaStone

Reason: unsafe use of @executable_path in /var/containers/Bundle/Application/ABC2F509-0738-44C6-BF1E-E082ED13A460/NvwaStone.app/NvwaStone with restricted binary

Dyld Version: 390.7

Aug 15 04:44:53 arthurpad SpringBoard[197] : Application '(null)' exited for an unknown reason.

What am I doing wrong? Any tips? ๐Ÿ˜ฐ

1

2

Image not found

Last login: Sun Mar 29 17:18:26 on ttys000
MaTianlai@matianlaideiMac ~ % /Users/MaTianlai/Downloads/myapp.app/Contents/MacOS/myapp ; exit;
dyld: Library not loaded: libHelloLib.dylib
  Referenced from: /Users/MaTianlai/Downloads/myapp.app/Contents/MacOS/myapp
  Reason: image not found
zsh: abort      /Users/MaTianlai/Downloads/myapp.app/Contents/MacOS/myapp

Why don't it work? Is it the signature problem?

Doesn't work on iOS 11.3.1 ?

iPhone:~ root# /usr/bin/hellotest
Hello, World!
iPhone:~ root# cp /usr/bin/hellotest ./
iPhone:~ root# ldid -e hellotest > hello.xml
iPhone:~ root# 
iPhone:~ root# insert_dylib /usr/lib/hellodylib.dylib hellotest --inplace
LC_CODE_SIGNATURE load command found. Remove it? [y/n] y
Added LC_LOAD_DYLIB to hellotest
iPhone:~ root# 
iPhone:~ root# ldid -Shello.xml hellotest 
iPhone:~ root# ./hellotest          
-sh: ./hellotest: cannot execute binary file: Operation not permitted
iPhone:~ root# cp hellotest /usr/bin/hellotest2
iPhone:~ root# /usr/bin/hellotest2
dyld: Library not loaded: /usr/lib/hellodylib.dylib
  Referenced from: /usr/bin/hellotest2
  Reason: no suitable image found.  Did find:
	/usr/lib/hellodylib.dylib: code signing blocked mmap() of '/usr/lib/hellodylib.dylib'
	/usr/lib/hellodylib.dylib: code signing blocked mmap() of '/usr/lib/hellodylib.dylib'
Abort trap: 6

The exact same steps work great on iOS 10, but failed on iOS 11.3.1 with error code signing blocked mmap().
I also tried ldid -S /usr/lib/hellodylib.dylib but still the same error.

Does that mean insert_dylib will never work os iOS 11+ due to codesigning issue ?

Library not loaded

I use the code, and insert libtt_i386.dylib into a App(Mindjet MindManager), which is installed already.
Then run it from the launchpad. It return the following errors:
" Library not loaded: libtt_i386.dylib
Referenced from: /Applications/Mindjet MindManager.app/Contents/MacOS/Mindjet MindManager
Reason: image not found"

I know what the error means --- cannot find libtt_i386.dylib in its search path.
I try the run it from the path of libtt_i386.dylib in terminal, the libtt_i386.dylib will be loaded successfully, I do it as following:
cd path/to/libtt_i386.dylib
lldb /Application/Mindjet MindManager.app

I wanna know if there is a way to fix this problem.

thank you very much.

Arm64

This tool does not work for Arm64 architecture (Apple M1), please fix it

Supporting ARM64

Yes, I found the other arm64 issue #10..., but this isn't the same thing. The other repository claims, that ARM64 would actually still work, but I did not came to the same conclusion.

Issue

./test_patched
zsh: killed     ./test_patched

Reproduce

$ cat > test.c
int main(void) {
	printf("Testing\n");
	return 0;
}
^D
$ clang test.c -o test &> /dev/null
$ insert_dylib /usr/lib/libfoo.dylib test
The provided dylib path doesn't exist. Continue anyway? [y/n] y
Added LC_LOAD_DYLIB to test_patched
$ ./test
Testing
$ ./test_patched
zsh: killed     ./test_patched

Interesting
I've opened the Terminal with Rosetta enabled, so that it is X86_64 and redone the steps... and it works!

$ ./test_patched 
dyld[72520]: Library not loaded: /usr/lib/libfoo.dylib
  Referenced from: <9513973B-B8E3-3A8D-93FE-A40EEF7CDD2B> /Users/lennard/Desktop/insert_dylib/insert_dylib/test_patched
  Reason: tried: '/usr/lib/libfoo.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/lib/libfoo.dylib' (no such file), '/usr/lib/libfoo.dylib' (no such file, not in dyld cache), '/usr/local/lib/libfoo.dylib' (no such file)
zsh: abort      ./test_patched

Conclusion
ARM64 seems to be broken. It would be ๐Ÿ”ฅ, if we could fix this amazing tool for ARM64. Especially, since Apple doesn't even build Intel anymore but this tool being used till this day. However I will probably not be able to do it myself ๐Ÿฅฒ

__LINKEDIT segment is not at the end of the file

When I use insert_dylib to inject a binary file, it tell me a warning:
Warning: __LINKEDIT segment is not at the end of the file, so codesign will not work on the patched binary.
how can i do to solve it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.