Skip to content

Commit 726db94

Browse files
committed
zsign POC
1 parent 8a3aaef commit 726db94

37 files changed

+9749
-14
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ packages/
33
.DS_Store
44
LiveContainer.xcodeproj
55
project.xcworkspace
6-
xcuserdata
6+
xcuserdata
7+
Resources/Frameworks/OpenSSL.framework

LiveContainerSwiftUI/LCAppBanner.swift

+8-1
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,12 @@ struct LCAppBanner : View {
239239
Text("lc.appBanner.waitForJitMsg".loc)
240240
}
241241

242-
.alert("lc.common.error".loc, isPresented: $errorShow) {
242+
.alert("lc.common.error".loc, isPresented: $errorShow){
243243
Button("lc.common.ok".loc, action: {
244244
})
245+
Button("lc.common.copy".loc, action: {
246+
copyError()
247+
})
245248
} message: {
246249
Text(errorInfo)
247250
}
@@ -386,6 +389,10 @@ struct LCAppBanner : View {
386389

387390
return ans
388391
}
392+
393+
func copyError() {
394+
UIPasteboard.general.string = errorInfo
395+
}
389396

390397
}
391398

LiveContainerSwiftUI/LCAppListView.swift

+16-2
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,14 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
194194

195195
}
196196
.navigationViewStyle(StackNavigationViewStyle())
197-
.alert(isPresented: $errorShow){
198-
Alert(title: Text("lc.common.error".loc), message: Text(errorInfo))
197+
.alert("lc.common.error".loc, isPresented: $errorShow){
198+
Button("lc.common.ok".loc, action: {
199+
})
200+
Button("lc.common.copy".loc, action: {
201+
copyError()
202+
})
203+
} message: {
204+
Text(errorInfo)
199205
}
200206
.fileImporter(isPresented: $choosingIPA, allowedContentTypes: [.ipa]) { result in
201207
Task { await startInstallApp(result) }
@@ -400,11 +406,13 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
400406
if sameBundleIdApp.count > 0 && !sharedModel.isHiddenAppUnlocked {
401407
do {
402408
if !(try await LCUtils.authenticateUser()) {
409+
self.installprogressVisible = false
403410
return
404411
}
405412
} catch {
406413
errorInfo = error.localizedDescription
407414
errorShow = true
415+
self.installprogressVisible = false
408416
return
409417
}
410418
}
@@ -451,6 +459,7 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
451459
}
452460
var signError : String? = nil
453461
await withCheckedContinuation({ c in
462+
finalNewApp.signer = Signer(rawValue: LCUtils.appGroupUserDefault.integer(forKey: "LCDefaultSigner"))!
454463
finalNewApp.patchExecAndSignIfNeed(completionHandler: { error in
455464
signError = error
456465
c.resume()
@@ -473,6 +482,7 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
473482
finalNewApp.doSymlinkInbox = appToReplace.appInfo.doSymlinkInbox
474483
finalNewApp.setDataUUID(appToReplace.appInfo.getDataUUIDNoAssign())
475484
finalNewApp.setTweakFolder(appToReplace.appInfo.tweakFolder())
485+
finalNewApp.signer = appToReplace.appInfo.signer
476486
}
477487
DispatchQueue.main.async {
478488
if let appToReplace {
@@ -602,4 +612,8 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
602612
isNavigationActive = false
603613
navigateTo = nil
604614
}
615+
616+
func copyError() {
617+
UIPasteboard.general.string = errorInfo
618+
}
605619
}

LiveContainerSwiftUI/LCAppModel.swift

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class LCAppModel: ObservableObject, Hashable {
2222
@Published var uiTweakFolder : String?
2323
@Published var uiDoSymlinkInbox : Bool
2424
@Published var uiBypassAssertBarrierOnQueue : Bool
25+
@Published var uiSigner : Signer
2526

2627
var jitAlert : YesNoHelper? = nil
2728

@@ -43,6 +44,7 @@ class LCAppModel: ObservableObject, Hashable {
4344
self.uiTweakFolder = appInfo.tweakFolder()
4445
self.uiDoSymlinkInbox = appInfo.doSymlinkInbox
4546
self.uiBypassAssertBarrierOnQueue = appInfo.bypassAssertBarrierOnQueue
47+
self.uiSigner = appInfo.signer
4648
}
4749

4850
static func == (lhs: LCAppModel, rhs: LCAppModel) -> Bool {

LiveContainerSwiftUI/LCAppSettingsView.swift

+16
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ struct LCAppSettingsView : View{
178178
}
179179
}
180180

181+
Picker(selection: $model.uiSigner) {
182+
Text("ZSign").tag(Signer.ZSign)
183+
Text("AltSigner").tag(Signer.AltSigner)
184+
185+
} label: {
186+
Text("Signer")
187+
}
188+
.onChange(of: model.uiSigner, perform: { newValue in
189+
Task { await setSigner(newValue) }
190+
})
181191

182192
Section {
183193
Toggle(isOn: $model.uiDoSymlinkInbox) {
@@ -399,6 +409,12 @@ struct LCAppSettingsView : View{
399409

400410
}
401411

412+
func setSigner(_ signer: Signer) async {
413+
appInfo.signer = signer
414+
model.uiSigner = signer
415+
416+
}
417+
402418
func setSimlinkInbox(_ simlinkInbox : Bool) async {
403419
appInfo.doSymlinkInbox = simlinkInbox
404420
model.uiDoSymlinkInbox = simlinkInbox

LiveContainerSwiftUI/LCSettingsView.swift

+15
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct LCSettingsView: View {
2626
@State private var isAltStorePatched = false
2727

2828
@State var isJitLessEnabled = false
29+
@State var defaultSigner = Signer.ZSign
2930

3031
@State var isAltCertIgnored = false
3132
@State var frameShortIcon = false
@@ -43,6 +44,8 @@ struct LCSettingsView: View {
4344

4445
init(apps: Binding<[LCAppModel]>, hiddenApps: Binding<[LCAppModel]>, appDataFolderNames: Binding<[String]>) {
4546
_isJitLessEnabled = State(initialValue: LCUtils.certificatePassword() != nil)
47+
_defaultSigner = State(initialValue: Signer(rawValue: LCUtils.appGroupUserDefault.integer(forKey: "LCDefaultSigner"))!)
48+
4649
_isAltCertIgnored = State(initialValue: UserDefaults.standard.bool(forKey: "LCIgnoreALTCertificate"))
4750
_frameShortIcon = State(initialValue: UserDefaults.standard.bool(forKey: "LCFrameShortcutIcons"))
4851
_silentSwitchApp = State(initialValue: UserDefaults.standard.bool(forKey: "LCSwitchAppWithoutAsking"))
@@ -95,6 +98,15 @@ struct LCSettingsView: View {
9598
}
9699
}
97100
}
101+
102+
Picker(selection: $defaultSigner) {
103+
Text("ZSign").tag(Signer.ZSign)
104+
Text("AltSigner").tag(Signer.AltSigner)
105+
106+
} label: {
107+
Text("Default Signer")
108+
}
109+
98110

99111
} header: {
100112
Text("lc.settings.jitLess".loc)
@@ -339,6 +351,9 @@ struct LCSettingsView: View {
339351
.onChange(of: sideJITServerAddress) { newValue in
340352
saveAppGroupItem(key: "LCSideJITServerAddress", val: newValue)
341353
}
354+
.onChange(of: defaultSigner) { newValue in
355+
saveAppGroupItem(key: "LCDefaultSigner", val: newValue.rawValue)
356+
}
342357
}
343358
.navigationViewStyle(StackNavigationViewStyle())
344359

LiveContainerSwiftUI/Localizable.xcstrings

+2-2
Original file line numberDiff line numberDiff line change
@@ -660,13 +660,13 @@
660660
"en" : {
661661
"stringUnit" : {
662662
"state" : "translated",
663-
"value" : "Bundle Identifier"
663+
"value" : "Bundle Folder"
664664
}
665665
},
666666
"zh_CN" : {
667667
"stringUnit" : {
668668
"state" : "translated",
669-
"value" : "包名"
669+
"value" : "包文件名"
670670
}
671671
}
672672
}

LiveContainerUI/LCAppInfo.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#import <Foundation/Foundation.h>
22
#import <UIKit/UIKit.h>
3+
#import "LCUtils.h"
34

45
@interface LCAppInfo : NSObject {
56
NSMutableDictionary* _info;
@@ -13,6 +14,7 @@
1314
@property bool doSymlinkInbox;
1415
@property bool bypassAssertBarrierOnQueue;
1516
@property UIColor* cachedColor;
17+
@property Signer signer;
1618

1719
- (void)setBundlePath:(NSString*)newBundlePath;
1820
- (NSMutableDictionary*)info;
@@ -30,5 +32,5 @@
3032
- (instancetype)initWithBundlePath:(NSString*)bundlePath;
3133
- (NSDictionary *)generateWebClipConfig;
3234
- (void)save;
33-
- (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo))completetionHandler progressHandler:(void(^)(NSProgress* errorInfo))progressHandler forceSign:(BOOL)forceSign;
35+
- (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo))completetionHandler progressHandler:(void(^)(NSProgress* progress))progressHandler forceSign:(BOOL)forceSign;
3436
@end

LiveContainerUI/LCAppInfo.m

+33-5
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ - (void)preprocessBundleBeforeSiging:(NSURL *)bundleURL completion:(dispatch_blo
181181
}
182182

183183
// return "SignNeeded" if sign is needed, other wise return an error
184-
- (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo))completetionHandler progressHandler:(void(^)(NSProgress* errorInfo))progressHandler forceSign:(BOOL)forceSign {
184+
- (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo))completetionHandler progressHandler:(void(^)(NSProgress* progress))progressHandler forceSign:(BOOL)forceSign {
185185
NSString *appPath = self.bundlePath;
186186
NSString *infoPath = [NSString stringWithFormat:@"%@/Info.plist", appPath];
187187
NSMutableDictionary *info = _info;
@@ -243,9 +243,8 @@ - (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo
243243
info[@"CFBundleIdentifier"] = info[@"LCBundleIdentifier"];
244244
[info removeObjectForKey:@"LCBundleExecutable"];
245245
[info removeObjectForKey:@"LCBundleIdentifier"];
246-
247-
__block NSProgress *progress = [LCUtils signAppBundle:appPathURL
248-
completionHandler:^(BOOL success, NSError *_Nullable error) {
246+
247+
void (^signCompletionHandler)(BOOL success, NSError *error) = ^(BOOL success, NSError *_Nullable error) {
249248
dispatch_async(dispatch_get_main_queue(), ^{
250249
if (!error) {
251250
info[@"LCJITLessSignID"] = @(signID);
@@ -267,7 +266,25 @@ - (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo
267266
}
268267

269268
});
270-
}];
269+
};
270+
271+
__block NSProgress *progress;
272+
273+
switch ([self signer]) {
274+
case ZSign:
275+
NSLog(@"[LC] using ZSign");
276+
progress = [LCUtils signAppBundleWithZSign:appPathURL execName:info[@"CFBundleExecutable"] completionHandler:signCompletionHandler];
277+
break;
278+
case AltSigner:
279+
NSLog(@"[LC] using AltSigner");
280+
progress = [LCUtils signAppBundle:appPathURL completionHandler:signCompletionHandler];
281+
break;
282+
283+
default:
284+
completetionHandler(@"Signer Not Found");
285+
break;
286+
}
287+
271288
if (progress) {
272289
progressHandler(progress);
273290
}
@@ -345,6 +362,17 @@ - (void)setBypassAssertBarrierOnQueue:(bool)enabled {
345362

346363
}
347364

365+
- (Signer)signer {
366+
return (Signer) [((NSNumber*) _info[@"signer"]) intValue];
367+
368+
}
369+
- (void)setSigner:(Signer)newSigner {
370+
_info[@"signer"] = [NSNumber numberWithInt:(int) newSigner];
371+
NSLog(@"[LC] new signer = %d", (int) newSigner);
372+
[self save];
373+
374+
}
375+
348376
- (UIColor*)cachedColor {
349377
if(_info[@"cachedColor"] != nil) {
350378
NSData *colorData = _info[@"cachedColor"];

LiveContainerUI/LCUtils.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ typedef NS_ENUM(NSInteger, Store){
77
AltStore
88
};
99

10+
typedef NS_ENUM(NSInteger, Signer){
11+
ZSign = 0,
12+
AltSigner = 1
13+
};
14+
1015
NSString *LCParseMachO(const char *path, LCParseMachOCallback callback);
1116
void LCPatchAddRPath(const char *path, struct mach_header_64 *header);
1217
void LCPatchExecSlice(const char *path, struct mach_header_64 *header);
@@ -37,7 +42,7 @@ void LCPatchAltStore(const char *path, struct mach_header_64 *header);
3742

3843
+ (void)removeCodeSignatureFromBundleURL:(NSURL *)appURL;
3944
+ (NSProgress *)signAppBundle:(NSURL *)path completionHandler:(void (^)(BOOL success, NSError *error))completionHandler;
40-
45+
+ (NSProgress *)signAppBundleWithZSign:(NSURL *)path execName:(NSString*)execName completionHandler:(void (^)(BOOL success, NSError *error))completionHandler;
4146
+ (BOOL)isAppGroupAltStoreLike;
4247
+ (Store)store;
4348
+ (NSString *)appGroupID;

LiveContainerUI/LCUtils.m

+32
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#import "AltStoreCore/ALTSigner.h"
66
#import "LCUtils.h"
77
#import "LCVersionInfo.h"
8+
#import "../zsign/zsigner.h"
89

910
@implementation LCUtils
1011

@@ -134,6 +135,16 @@ + (void)loadStoreFrameworksWithError:(NSError **)error {
134135
loaded = YES;
135136
}
136137

138+
+ (void)loadStoreFrameworksWithError2:(NSError **)error {
139+
// too lazy to use dispatch_once
140+
static BOOL loaded = NO;
141+
if (loaded) return;
142+
143+
dlopen("@executable_path/Frameworks/ZSign.dylib", RTLD_GLOBAL);
144+
145+
loaded = YES;
146+
}
147+
137148
+ (NSString *)storeBundleID {
138149
// Assuming this format never changes...
139150
// group.BUNDLEID.YOURTEAMID
@@ -233,6 +244,27 @@ + (NSProgress *)signAppBundle:(NSURL *)path completionHandler:(void (^)(BOOL suc
233244
return [signer signAppAtURL:path provisioningProfiles:@[(id)profile] completionHandler:completionHandler];
234245
}
235246

247+
+ (NSProgress *)signAppBundleWithZSign:(NSURL *)path execName:(NSString*)execName completionHandler:(void (^)(BOOL success, NSError *error))completionHandler {
248+
NSError *error;
249+
250+
// use zsign as our signer~
251+
NSURL *profilePath = [NSBundle.mainBundle URLForResource:@"embedded" withExtension:@"mobileprovision"];
252+
NSData *profileData = [NSData dataWithContentsOfURL:profilePath];
253+
// Load libraries from Documents, yeah
254+
[self loadStoreFrameworksWithError2:&error];
255+
256+
if (error) {
257+
completionHandler(NO, error);
258+
return nil;
259+
}
260+
261+
NSLog(@"[LC] starting signing...");
262+
263+
NSProgress* ans = [NSClassFromString(@"ZSigner") signWithAppPath:[path path] execName:execName prov:profileData key: self.certificateData pass:self.certificatePassword completionHandler:completionHandler];
264+
265+
return ans;
266+
}
267+
236268
#pragma mark Setup
237269

238270
+ (NSString *)appGroupID {

Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ $(APPLICATION_NAME)_FRAMEWORKS = UIKit
1919

2020
include $(THEOS_MAKE_PATH)/application.mk
2121

22-
SUBPROJECTS += LiveContainerUI TweakLoader TestJITLess LiveContainerSwiftUI AltStoreTweak
22+
SUBPROJECTS += ZSign LiveContainerUI TweakLoader TestJITLess LiveContainerSwiftUI AltStoreTweak
2323
include $(THEOS_MAKE_PATH)/aggregate.mk
2424

2525
# Make the executable name longer so we have space to overwrite it with the guest app's name
@@ -29,3 +29,6 @@ before-package::
2929
@cp $(THEOS_STAGING_DIR)/Applications/LiveContainer.app/LiveContainer $(THEOS_STAGING_DIR)/Applications/LiveContainer.app/JITLessSetup
3030
@ldid -Sentitlements_setup.xml $(THEOS_STAGING_DIR)/Applications/LiveContainer.app/JITLessSetup
3131
@mv $(THEOS_STAGING_DIR)/Applications/LiveContainer.app/LiveContainer $(THEOS_STAGING_DIR)/Applications/LiveContainer.app/LiveContainer_PleaseDoNotShortenTheExecutableNameBecauseItIsUsedToReserveSpaceForOverwritingThankYou
32+
33+
before-all::
34+
@sh ./download_openssl.sh

download_openssl.sh

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/bash
2+
if [ -d "$THEOS/lib/OpenSSL.framework" ]; then
3+
echo "OpenSSL.framework already exists in $THEOS/lib"
4+
else
5+
echo "OpenSSL.framework not found. Downloading..."
6+
7+
curl -L "https://github.com/HAHALOSAH/OpenSSL-Swift/releases/download/3.1.5004/OpenSSL.xcframework.zip" -o "OpenSSL.xcframework.zip"
8+
9+
unzip -q "OpenSSL.xcframework.zip" -d .
10+
11+
mkdir -p "$THEOS/lib"
12+
mv "OpenSSL.xcframework/ios-arm64/OpenSSL.framework" "$THEOS/lib"
13+
14+
rm -f "OpenSSL.xcframework.zip"
15+
rm -rf "OpenSSL.xcframework"
16+
17+
echo "OpenSSL.framework has been installed to $THEOS/lib"
18+
fi
19+
20+
if [ ! -d "./Resources/Frameworks/OpenSSL.framework" ]; then
21+
rsync -av --exclude 'Headers' "$THEOS/lib/OpenSSL.framework" "./Resources/Frameworks"
22+
fi

0 commit comments

Comments
 (0)