iosjailbreaktheos

theos tweak is not loaded into app when 3rd party framework is linked


I'm using theos to link a 3rd framwork into my test tweak, which does nothing but a log, and it seems after linking the framework, the tweak.dylib is not loaded into app at all. If I comment out the framework in makefile, the tweak works well. Any idea? Thanks

The makefile is simple about the framework:

ARCHS = arm64

include $(THEOS)/makefiles/common.mk

ADDITIONAL_OBJCFLAGS = -fobjc-arc

TWEAK_NAME = WebServerTest
WebServerTest_FILES = Tweak.xm


WebServerTest_CFLAGS += -F./Frameworks
WebServerTest_LDFLAGS += -F./Frameworks -framework GCDWebServers

include $(THEOS_MAKE_PATH)/tweak.mk

after-install::
    install.exec "killall -9 SpringBoard"

The tweak.xm is very simple:

%ctor {
    NSLog(@"Staring up tweak...");
    %init();
}

So if I comment out above

WebServerTest_CFLAGS += -F./Frameworks

WebServerTest_LDFLAGS += -F./Frameworks -framework GCDWebServers

The tweak is working fine:

Aug 13 10:06:20 iOS-Dev SpringBoard(WebServerTest.dylib)[10378] <Notice>: Staring up tweak...

However if I start linking the framework, the WebServerTest.dylib is not loaded at all

I manually checked a test app in lldb cmd image list, it shows WebServerTest.dylib is not loaded at all

Any idea? Or how do I start to debug what's wrong? Because I'm not sure where is the possible cause.

env: iOS 12.0, unc0ver 3.1.0

otool -l WebServerTest.dylib | fgrep -A5 LC_LOAD_DYLIB

shows

--
          cmd LC_LOAD_DYLIB
      cmdsize 72
         name @rpath/GCDWebServers.framework/GCDWebServers (offset 24)
   time stamp 2 Thu Jan  1 08:00:02 1970
      current version 1.0.0
compatibility version 1.0.0
--

so it seems using the @rpath, I could understand, but can I embed the framework into the tweak.dylib, so it can be loaded automatically?


Solution

  • Wherever you're putting GCDWebServers.framework isn't where dyld is looking for it. There are a few ways to fix this.

    You could either patch GCDWebServers's LC_ID_DYLIB command to contain an absolute path - you'd probably want to see man install_name_tool for that.

    Or you could add some -rpath flag to your LDFLAGS. Specifically, if your GCDWebServers was located in /mypath/GCDWebServers.framework/GCDWebServers, you'd add:

    -rpath /mypath/
    

    Or, if you wanna have GCDWebServers.framework just next to your dylib, no matter the absolute path, you should be able to use:

    -rpath @loader_path/
    

    For more information, see man dyld and man ld.