[GH-ISSUE #931] Global dylib loaded before tweakloader, causing execution issues #830

Closed
opened 2026-03-03 15:36:40 +03:00 by kerem · 6 comments
Owner

Originally created by @xinerqu on GitHub (Oct 25, 2025).
Original GitHub issue: https://github.com/LiveContainer/LiveContainer/issues/931

Description:
I wrote a very small dylib whose function is simply to display a button on the screen; tapping it executes livecontainer://open-web-page?url=about://blank. This is intended to make it easy to quickly return to LiveContainer in private app mode.

Problem:
I want this dylib to be globally active, but in that case, it gets loaded before the tweakloader module. Since tweakloader is responsible for loading other dylibs, this prevents my module from executing correctly. Currently, there doesn’t seem to be a way to control the load order.

Expected behavior:
• tweakloader should load first
• My global dylib should still take effect after tweakloader loads
• All other modules loaded by tweakloader should work normally

Question / Request:
Is there a recommended way to ensure a global dylib executes after tweakloader while still being globally effective?

Additional context:
• The issue arises only when the dylib is set to global
• Other non-global dylibs work as expected
• I’ve tried standard load order tricks, but none seem effective

Originally created by @xinerqu on GitHub (Oct 25, 2025). Original GitHub issue: https://github.com/LiveContainer/LiveContainer/issues/931 Description: I wrote a very small dylib whose function is simply to display a button on the screen; tapping it executes livecontainer://open-web-page?url=about://blank. This is intended to make it easy to quickly return to LiveContainer in private app mode. Problem: I want this dylib to be globally active, but in that case, it gets loaded before the tweakloader module. Since tweakloader is responsible for loading other dylibs, this prevents my module from executing correctly. Currently, there doesn’t seem to be a way to control the load order. Expected behavior: • tweakloader should load first • My global dylib should still take effect after tweakloader loads • All other modules loaded by tweakloader should work normally Question / Request: Is there a recommended way to ensure a global dylib executes after tweakloader while still being globally effective? Additional context: • The issue arises only when the dylib is set to global • Other non-global dylibs work as expected • I’ve tried standard load order tricks, but none seem effective
kerem closed this issue 2026-03-03 15:36:40 +03:00
Author
Owner

@khanhduytran0 commented on GitHub (Oct 25, 2025):

Do you have the call stack when your tweak loads before TweakLoader?

<!-- gh-comment-id:3447774972 --> @khanhduytran0 commented on GitHub (Oct 25, 2025): Do you have the call stack when your tweak loads before TweakLoader?
Author
Owner

@xinerqu commented on GitHub (Oct 26, 2025):

LCFloat.log

It seems I might have been mistaken. I’m not entirely sure, but this is the call stack when my dylib is loaded in non-global mode and executes correctly:

[LCFloat.dylib loaded]
Time: 2025-10-26 09:10:03 +0800
Dylib Path: /private/var/mobile/Containers/Data/Application/9246FFA5-F22E-4443-9AEC-CA1C19807C7E/Documents/Tweaks/测试/
Key call stack:

0 LCFloatLOG.dylib lc_init
14 TweakLoader.dylib loadTweakAtURL
15 TweakLoader.dylib TweakLoaderConstructor
30 LiveContainerShared dlopenBypassingLock
[2025-10-26 01:10:03 +0000] LCFloat window created

However, when I try to make my dylib globally active, it fails to load and reports code signing errors.
I don’t know how to obtain the call stack when the dylib fails to load. In that case, I only see the certificate/code signing error in LiveContainer.

<!-- gh-comment-id:3447925027 --> @xinerqu commented on GitHub (Oct 26, 2025): [LCFloat.log](https://github.com/user-attachments/files/23145942/LCFloat.log) It seems I might have been mistaken. I’m not entirely sure, but this is the call stack when my dylib is loaded in non-global mode and executes correctly: [LCFloat.dylib loaded] Time: 2025-10-26 09:10:03 +0800 Dylib Path: /private/var/mobile/Containers/Data/Application/9246FFA5-F22E-4443-9AEC-CA1C19807C7E/Documents/Tweaks/ʵãËØï/ Key call stack: 0 LCFloatLOG.dylib lc_init 14 TweakLoader.dylib loadTweakAtURL 15 TweakLoader.dylib TweakLoaderConstructor 30 LiveContainerShared dlopenBypassingLock [2025-10-26 01:10:03 +0000] LCFloat window created However, when I try to make my dylib globally active, it fails to load and reports code signing errors. I don’t know how to obtain the call stack when the dylib fails to load. In that case, I only see the certificate/code signing error in LiveContainer.
Author
Owner

@xinerqu commented on GitHub (Oct 26, 2025):

I also noticed a strange behavior. Normally, in global mode, my dylib reports a code signing error. However, if I place my dylib in global mode and also put the same dylib into a module folder, then let one app use that module folder, the app starts correctly without any errors.

Even more strangely, after doing this, all apps can correctly load my global dylib, even if they never used the module folder. I can even delete the module folder and fully quit LiveContainer, and the dylib still works correctly.

It only reports errors again if I remove the global module and re-add it. The issue can only be resolved by repeating the process: having the same dylib both globally and inside a module folder, letting one app use that module folder first, and then all apps can load the global dylib without errors.

<!-- gh-comment-id:3447947931 --> @xinerqu commented on GitHub (Oct 26, 2025): I also noticed a strange behavior. Normally, in global mode, my dylib reports a code signing error. However, if I place my dylib in global mode and also put the same dylib into a module folder, then let one app use that module folder, the app starts correctly without any errors. Even more strangely, after doing this, all apps can correctly load my global dylib, even if they never used the module folder. I can even delete the module folder and fully quit LiveContainer, and the dylib still works correctly. It only reports errors again if I remove the global module and re-add it. The issue can only be resolved by repeating the process: having the same dylib both globally and inside a module folder, letting one app use that module folder first, and then all apps can load the global dylib without errors.
Author
Owner

@hugeBlack commented on GitHub (Oct 26, 2025):

Work as intended. To avoid scanning the global tweak folder at every launch, global tweaks will only be scanned when app is launching if its tweak folder is set.

See github.com/LiveContainer/LiveContainer@ba8405475c/LiveContainerSwiftUI/LCAppModel.swift (L354)

If you readd the tweak through LiveContainer's UI it should be automatically signed and work afterwards.

<!-- gh-comment-id:3448001372 --> @hugeBlack commented on GitHub (Oct 26, 2025): Work as intended. To avoid scanning the global tweak folder at every launch, global tweaks will only be scanned when app is launching if its tweak folder is set. See https://github.com/LiveContainer/LiveContainer/blob/ba8405475ceab7068607415e103ec44bf89dc995/LiveContainerSwiftUI/LCAppModel.swift#L354 If you readd the tweak through LiveContainer's UI it should be automatically signed and work afterwards.
Author
Owner

@xinerqu commented on GitHub (Oct 26, 2025):

Work as intended. To avoid scanning the global tweak folder at every launch, global tweaks will only be scanned when app is launching if its tweak folder is set.

See

LiveContainer/LiveContainerSwiftUI/LCAppModel.swift

Line 354 in ba84054

guard let tweakFolder = appInfo.tweakFolder else {
If you readd the tweak through LiveContainer's UI it should be automatically signed and work afterwards.

实在不好意思,我还是不太理解,你提到,如果没有设置tweak folder,设定就是要避免每次都扫描全局tweak,所以他不扫描就导致也不签名,但是它还是会加载是吗?
另外,感谢回复,确实如你所说,在界面右上角的签名按钮点一下就解决这个问题了。

<!-- gh-comment-id:3448020912 --> @xinerqu commented on GitHub (Oct 26, 2025): > Work as intended. To avoid scanning the global tweak folder at every launch, global tweaks will only be scanned when app is launching if its tweak folder is set. > > See > > [LiveContainer/LiveContainerSwiftUI/LCAppModel.swift](https://github.com/LiveContainer/LiveContainer/blob/ba8405475ceab7068607415e103ec44bf89dc995/LiveContainerSwiftUI/LCAppModel.swift#L354) > > Line 354 in [ba84054](/LiveContainer/LiveContainer/commit/ba8405475ceab7068607415e103ec44bf89dc995) > > guard let tweakFolder = appInfo.tweakFolder else { > If you readd the tweak through LiveContainer's UI it should be automatically signed and work afterwards. 实在不好意思,我还是不太理解,你提到,如果没有设置tweak folder,设定就是要避免每次都扫描全局tweak,所以他不扫描就导致也不签名,但是它还是会加载是吗? 另外,感谢回复,确实如你所说,在界面右上角的签名按钮点一下就解决这个问题了。
Author
Owner

@hugeBlack commented on GitHub (Oct 26, 2025):

实在不好意思,我还是不太理解,你提到,如果没有设置tweak folder,设定就是要避免每次都扫描全局tweak,所以他不扫描就导致也不签名,但是它还是会加载是吗?

是的,加载部分你可以看
github.com/LiveContainer/LiveContainer@ba8405475c/TweakLoader/TweakLoader.m (L75)

<!-- gh-comment-id:3448027051 --> @hugeBlack commented on GitHub (Oct 26, 2025): > 实在不好意思,我还是不太理解,你提到,如果没有设置tweak folder,设定就是要避免每次都扫描全局tweak,所以他不扫描就导致也不签名,但是它还是会加载是吗? 是的,加载部分你可以看 https://github.com/LiveContainer/LiveContainer/blob/ba8405475ceab7068607415e103ec44bf89dc995/TweakLoader/TweakLoader.m#L75
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/LiveContainer#830
No description provided.