mirror of
				https://github.com/opa334/TrollStore.git
				synced 2025-11-04 07:32:36 +08:00 
			
		
		
		
	
						commit
						783ab43c3e
					
				@ -14,6 +14,6 @@ trollstorehelper_CODESIGN_FLAGS = --entitlements entitlements.plist
 | 
				
			|||||||
trollstorehelper_INSTALL_PATH = /usr/local/bin
 | 
					trollstorehelper_INSTALL_PATH = /usr/local/bin
 | 
				
			||||||
trollstorehelper_LIBRARIES = archive
 | 
					trollstorehelper_LIBRARIES = archive
 | 
				
			||||||
trollstorehelper_FRAMEWORKS = CoreTelephony
 | 
					trollstorehelper_FRAMEWORKS = CoreTelephony
 | 
				
			||||||
trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager
 | 
					trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager FrontBoardServices
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include $(THEOS_MAKE_PATH)/tool.mk
 | 
					include $(THEOS_MAKE_PATH)/tool.mk
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								RootHelper/devmode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								RootHelper/devmode.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#import <Foundation/Foundation.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BOOL checkDeveloperMode(void);
 | 
				
			||||||
 | 
					BOOL armDeveloperMode(BOOL* alreadyEnabled);
 | 
				
			||||||
							
								
								
									
										142
									
								
								RootHelper/devmode.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								RootHelper/devmode.m
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,142 @@
 | 
				
			|||||||
 | 
					@import Foundation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Types
 | 
				
			||||||
 | 
					typedef NSObject* xpc_object_t;
 | 
				
			||||||
 | 
					typedef xpc_object_t xpc_connection_t;
 | 
				
			||||||
 | 
					typedef void (^xpc_handler_t)(xpc_object_t object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Serialization
 | 
				
			||||||
 | 
					extern CFTypeRef _CFXPCCreateCFObjectFromXPCObject(xpc_object_t xpcattrs);
 | 
				
			||||||
 | 
					extern xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef attrs);
 | 
				
			||||||
 | 
					extern xpc_object_t _CFXPCCreateXPCMessageWithCFObject(CFTypeRef obj);
 | 
				
			||||||
 | 
					extern CFTypeRef _CFXPCCreateCFObjectFromXPCMessage(xpc_object_t obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Communication
 | 
				
			||||||
 | 
					extern xpc_connection_t xpc_connection_create_mach_service(const char* name, dispatch_queue_t targetq, uint64_t flags);
 | 
				
			||||||
 | 
					extern void xpc_connection_set_event_handler(xpc_connection_t connection, xpc_handler_t handler);
 | 
				
			||||||
 | 
					extern void xpc_connection_resume(xpc_connection_t connection);
 | 
				
			||||||
 | 
					extern void xpc_connection_send_message_with_reply(xpc_connection_t connection, xpc_object_t message, dispatch_queue_t replyq, xpc_handler_t handler);
 | 
				
			||||||
 | 
					extern xpc_object_t xpc_connection_send_message_with_reply_sync(xpc_connection_t connection, xpc_object_t message);
 | 
				
			||||||
 | 
					extern xpc_object_t xpc_dictionary_get_value(xpc_object_t xdict, const char *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    kAMFIActionArm = 0,     // Trigger a prompt asking the user to enable developer mode on the next reboot
 | 
				
			||||||
 | 
					                            // (regardless of current state)
 | 
				
			||||||
 | 
					    kAMFIActionDisable = 1, // Disable developer mode if it's currently enabled. Takes effect immediately.
 | 
				
			||||||
 | 
					    kAMFIActionStatus = 2,  // Returns a dict: {success: bool, status: bool, armed: bool}
 | 
				
			||||||
 | 
					} AMFIXPCAction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					xpc_connection_t startConnection(void) {
 | 
				
			||||||
 | 
						xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.amfi.xpc", NULL, 0);
 | 
				
			||||||
 | 
					    if (!connection) {
 | 
				
			||||||
 | 
					        NSLog(@"[startXPCConnection] Failed to create XPC connection to amfid");
 | 
				
			||||||
 | 
					        return nil;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    xpc_connection_resume(connection);
 | 
				
			||||||
 | 
					    return connection;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NSDictionary* sendXPCRequest(xpc_connection_t connection, AMFIXPCAction action) {
 | 
				
			||||||
 | 
					    xpc_object_t message = _CFXPCCreateXPCMessageWithCFObject((__bridge CFDictionaryRef) @{@"action": @(action)});
 | 
				
			||||||
 | 
					    xpc_object_t replyMsg = xpc_connection_send_message_with_reply_sync(connection, message);
 | 
				
			||||||
 | 
					    if (!replyMsg) {
 | 
				
			||||||
 | 
					        NSLog(@"[sendXPCRequest] got no reply from amfid");
 | 
				
			||||||
 | 
					        return nil;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xpc_object_t replyObj = xpc_dictionary_get_value(replyMsg, "cfreply");
 | 
				
			||||||
 | 
					    if (!replyObj) {
 | 
				
			||||||
 | 
					        NSLog(@"[sendXPCRequest] got reply but no cfreply");
 | 
				
			||||||
 | 
					        return nil;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NSDictionary* asCF = (__bridge NSDictionary*)_CFXPCCreateCFObjectFromXPCMessage(replyObj);
 | 
				
			||||||
 | 
					    return asCF;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BOOL getDeveloperModeState(xpc_connection_t connection) {
 | 
				
			||||||
 | 
					    NSDictionary* reply = sendXPCRequest(connection, kAMFIActionStatus);
 | 
				
			||||||
 | 
					    if (!reply) {
 | 
				
			||||||
 | 
					        NSLog(@"[getDeveloperModeState] failed to get reply");
 | 
				
			||||||
 | 
					        return NO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NSLog(@"[getDeveloperModeState] got reply %@", reply);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NSObject* success = reply[@"success"];
 | 
				
			||||||
 | 
					    if (!success || ![success isKindOfClass:[NSNumber class]] || ![(NSNumber*)success boolValue]) {
 | 
				
			||||||
 | 
					        NSLog(@"[getDeveloperModeState] request failed with error %@", reply[@"error"]);
 | 
				
			||||||
 | 
					        return NO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NSObject* status = reply[@"status"];
 | 
				
			||||||
 | 
					    if (!status || ![status isKindOfClass:[NSNumber class]]) {
 | 
				
			||||||
 | 
					        NSLog(@"[getDeveloperModeState] request succeeded but no status");
 | 
				
			||||||
 | 
					        return NO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return [(NSNumber*)status boolValue];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BOOL setDeveloperModeState(xpc_connection_t connection, BOOL enable) {
 | 
				
			||||||
 | 
					    NSDictionary* reply = sendXPCRequest(connection, enable ? kAMFIActionArm : kAMFIActionDisable);
 | 
				
			||||||
 | 
					    if (!reply) {
 | 
				
			||||||
 | 
					        NSLog(@"[setDeveloperModeState] failed to get reply");
 | 
				
			||||||
 | 
					        return NO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NSObject* success = reply[@"success"];
 | 
				
			||||||
 | 
					    if (!success || ![success isKindOfClass:[NSNumber class]] || ![(NSNumber*)success boolValue]) {
 | 
				
			||||||
 | 
					        NSLog(@"[setDeveloperModeState] request failed with error %@", reply[@"error"]);
 | 
				
			||||||
 | 
					        return NO;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return YES;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BOOL checkDeveloperMode(void) {
 | 
				
			||||||
 | 
					    // Developer mode does not exist before iOS 16
 | 
				
			||||||
 | 
					    if (@available(iOS 16, *)) {
 | 
				
			||||||
 | 
					        xpc_connection_t connection = startConnection();
 | 
				
			||||||
 | 
					        if (!connection) {
 | 
				
			||||||
 | 
					            NSLog(@"[checkDeveloperMode] failed to start connection");
 | 
				
			||||||
 | 
					            // Assume it's disabled
 | 
				
			||||||
 | 
					            return NO;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return getDeveloperModeState(connection);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return YES;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BOOL armDeveloperMode(BOOL* alreadyEnabled) {
 | 
				
			||||||
 | 
					    // Developer mode does not exist before iOS 16
 | 
				
			||||||
 | 
					    if (@available(iOS 16, *)) {
 | 
				
			||||||
 | 
					        xpc_connection_t connection = startConnection();
 | 
				
			||||||
 | 
					        if (!connection) {
 | 
				
			||||||
 | 
					            NSLog(@"[armDeveloperMode] failed to start connection");
 | 
				
			||||||
 | 
					            return NO;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        BOOL enabled = getDeveloperModeState(connection);
 | 
				
			||||||
 | 
					        if (alreadyEnabled) {
 | 
				
			||||||
 | 
					            *alreadyEnabled = enabled;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (enabled) {
 | 
				
			||||||
 | 
					            // NSLog(@"[armDeveloperMode] already enabled");
 | 
				
			||||||
 | 
					            return YES;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        BOOL success = setDeveloperModeState(connection, YES);
 | 
				
			||||||
 | 
					        if (!success) {
 | 
				
			||||||
 | 
					            NSLog(@"[armDeveloperMode] failed to arm");
 | 
				
			||||||
 | 
					            return NO;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return YES;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -44,5 +44,9 @@
 | 
				
			|||||||
		<string>Uninstall</string>
 | 
							<string>Uninstall</string>
 | 
				
			||||||
		<string>UpdatePlaceholderMetadata</string>
 | 
							<string>UpdatePlaceholderMetadata</string>
 | 
				
			||||||
	</array>
 | 
						</array>
 | 
				
			||||||
 | 
					    <key>com.apple.private.amfi.developer-mode-control</key>
 | 
				
			||||||
 | 
					    <true/>
 | 
				
			||||||
 | 
					    <key>com.apple.frontboard.shutdown</key>
 | 
				
			||||||
 | 
					    <true/>
 | 
				
			||||||
</dict>
 | 
					</dict>
 | 
				
			||||||
</plist>
 | 
					</plist>
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@
 | 
				
			|||||||
#import <sys/utsname.h>
 | 
					#import <sys/utsname.h>
 | 
				
			||||||
#import <mach-o/loader.h>
 | 
					#import <mach-o/loader.h>
 | 
				
			||||||
#import <mach-o/fat.h>
 | 
					#import <mach-o/fat.h>
 | 
				
			||||||
 | 
					#import "devmode.h"
 | 
				
			||||||
#ifndef EMBEDDED_ROOT_HELPER
 | 
					#ifndef EMBEDDED_ROOT_HELPER
 | 
				
			||||||
#import "codesign.h"
 | 
					#import "codesign.h"
 | 
				
			||||||
#import "coretrust_bug.h"
 | 
					#import "coretrust_bug.h"
 | 
				
			||||||
@ -20,6 +21,7 @@
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#import <SpringBoardServices/SpringBoardServices.h>
 | 
					#import <SpringBoardServices/SpringBoardServices.h>
 | 
				
			||||||
 | 
					#import <FrontBoardServices/FBSSystemService.h>
 | 
				
			||||||
#import <Security/Security.h>
 | 
					#import <Security/Security.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef EMBEDDED_ROOT_HELPER
 | 
					#ifdef EMBEDDED_ROOT_HELPER
 | 
				
			||||||
@ -564,6 +566,10 @@ int signApp(NSString* appPath)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// On iOS 16+, binaries with certain entitlements requires developer mode to be enabled, so we'll check
 | 
				
			||||||
 | 
						// while we're fixing entitlements
 | 
				
			||||||
 | 
						BOOL requiresDevMode = NO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	NSURL* fileURL;
 | 
						NSURL* fileURL;
 | 
				
			||||||
	NSDirectoryEnumerator *enumerator;
 | 
						NSDirectoryEnumerator *enumerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -608,6 +614,25 @@ int signApp(NSString* appPath)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			if (!entitlementsToUse) entitlementsToUse = [NSMutableDictionary new];
 | 
								if (!entitlementsToUse) entitlementsToUse = [NSMutableDictionary new];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Developer mode does not exist before iOS 16
 | 
				
			||||||
 | 
								if (@available(iOS 16, *)){
 | 
				
			||||||
 | 
									if (!requiresDevMode) {
 | 
				
			||||||
 | 
										for (NSString* restrictedEntitlementKey in @[
 | 
				
			||||||
 | 
											@"get-task-allow", 
 | 
				
			||||||
 | 
											@"task_for_pid-allow", 
 | 
				
			||||||
 | 
											@"com.apple.system-task-ports",
 | 
				
			||||||
 | 
											@"com.apple.system-task-ports.control",
 | 
				
			||||||
 | 
											@"com.apple.system-task-ports.token.control",
 | 
				
			||||||
 | 
											@"com.apple.private.cs.debugger"
 | 
				
			||||||
 | 
										]) {
 | 
				
			||||||
 | 
											NSObject *restrictedEntitlement = entitlementsToUse[restrictedEntitlementKey];
 | 
				
			||||||
 | 
											if (restrictedEntitlement && [restrictedEntitlement isKindOfClass:[NSNumber class]] && [(NSNumber *)restrictedEntitlement boolValue]) {
 | 
				
			||||||
 | 
												requiresDevMode = YES;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			NSObject *containerRequiredO = entitlementsToUse[@"com.apple.private.security.container-required"];
 | 
								NSObject *containerRequiredO = entitlementsToUse[@"com.apple.private.security.container-required"];
 | 
				
			||||||
			BOOL containerRequired = YES;
 | 
								BOOL containerRequired = YES;
 | 
				
			||||||
			if (containerRequiredO && [containerRequiredO isKindOfClass:[NSNumber class]]) {
 | 
								if (containerRequiredO && [containerRequiredO isKindOfClass:[NSNumber class]]) {
 | 
				
			||||||
@ -686,6 +711,11 @@ int signApp(NSString* appPath)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (requiresDevMode) {
 | 
				
			||||||
 | 
							// Postpone trying to enable dev mode until after the app is (successfully) installed
 | 
				
			||||||
 | 
							return 182;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -770,10 +800,19 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate,
 | 
				
			|||||||
		applyPatchesToInfoDictionary(appBundleToInstallPath);
 | 
							applyPatchesToInfoDictionary(appBundleToInstallPath);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BOOL requiresDevMode = NO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(sign)
 | 
						if(sign)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		int signRet = signApp(appBundleToInstallPath);
 | 
							int signRet = signApp(appBundleToInstallPath);
 | 
				
			||||||
		if(signRet != 0) return signRet;
 | 
							// 182: app requires developer mode; non-fatal
 | 
				
			||||||
 | 
							if(signRet != 0) {
 | 
				
			||||||
 | 
								if (signRet == 182) {
 | 
				
			||||||
 | 
									requiresDevMode = YES;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return signRet;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil];
 | 
						MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil];
 | 
				
			||||||
@ -919,6 +958,23 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate,
 | 
				
			|||||||
		[[NSFileManager defaultManager] removeItemAtURL:appContainer.url error:nil];
 | 
							[[NSFileManager defaultManager] removeItemAtURL:appContainer.url error:nil];
 | 
				
			||||||
		return 181;
 | 
							return 181;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Handle developer mode after installing and registering the app, to ensure that we
 | 
				
			||||||
 | 
						// don't arm developer mode but then fail to install the app
 | 
				
			||||||
 | 
						if (requiresDevMode) {
 | 
				
			||||||
 | 
							BOOL alreadyEnabled = NO;
 | 
				
			||||||
 | 
							if (armDeveloperMode(&alreadyEnabled)) {
 | 
				
			||||||
 | 
								if (!alreadyEnabled) {
 | 
				
			||||||
 | 
									NSLog(@"[installApp] app requires developer mode and we have successfully armed it");
 | 
				
			||||||
 | 
									// non-fatal
 | 
				
			||||||
 | 
									return 182;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								NSLog(@"[installApp] failed to arm developer mode");
 | 
				
			||||||
 | 
								// fatal
 | 
				
			||||||
 | 
								return 183;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1470,6 +1526,22 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
 | 
				
			|||||||
				setTSURLSchemeState(newState, nil);
 | 
									setTSURLSchemeState(newState, nil);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							else if([cmd isEqualToString:@"check-dev-mode"])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// switch the result, so 0 is enabled, and 1 is disabled/error
 | 
				
			||||||
 | 
								ret = !checkDeveloperMode();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if([cmd isEqualToString:@"arm-dev-mode"])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// assumes that checkDeveloperMode() has already been called
 | 
				
			||||||
 | 
								ret = !armDeveloperMode(NULL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if([cmd isEqualToString:@"reboot"])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								[[FBSSystemService sharedService] reboot];
 | 
				
			||||||
 | 
								// Give the system some time to reboot
 | 
				
			||||||
 | 
								sleep(1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		NSLog(@"trollstorehelper returning %d", ret);
 | 
							NSLog(@"trollstorehelper returning %d", ret);
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,7 @@ ifeq ($(EMBEDDED_ROOT_HELPER),1)
 | 
				
			|||||||
TrollStorePersistenceHelper_CFLAGS += -DEMBEDDED_ROOT_HELPER=1
 | 
					TrollStorePersistenceHelper_CFLAGS += -DEMBEDDED_ROOT_HELPER=1
 | 
				
			||||||
TrollStorePersistenceHelper_FILES += $(wildcard ../RootHelper/*.m)
 | 
					TrollStorePersistenceHelper_FILES += $(wildcard ../RootHelper/*.m)
 | 
				
			||||||
TrollStorePersistenceHelper_LIBRARIES += archive
 | 
					TrollStorePersistenceHelper_LIBRARIES += archive
 | 
				
			||||||
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS += SpringBoardServices BackBoardServices
 | 
					TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS += SpringBoardServices BackBoardServices FrontBoardServices
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include $(THEOS_MAKE_PATH)/application.mk
 | 
					include $(THEOS_MAKE_PATH)/application.mk
 | 
				
			||||||
@ -80,6 +80,12 @@ extern NSUserDefaults* trollStoreUserDefaults();
 | 
				
			|||||||
        case 181:
 | 
					        case 181:
 | 
				
			||||||
        errorDescription = @"Failed to add app to icon cache.";
 | 
					        errorDescription = @"Failed to add app to icon cache.";
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					        case 182:
 | 
				
			||||||
 | 
					        errorDescription = @"The app was installed successfully, but requires developer mode to be enabled to run. After rebooting, select \"Turn On\" to enable developer mode.";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        case 183:
 | 
				
			||||||
 | 
					        errorDescription = @"Failed to enable developer mode.";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NSError* error = [NSError errorWithDomain:TrollStoreErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
 | 
					    NSError* error = [NSError errorWithDomain:TrollStoreErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
 | 
				
			||||||
 | 
				
			|||||||
@ -32,42 +32,58 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				[TSPresentationDelegate stopActivityWithCompletion:^
 | 
									[TSPresentationDelegate stopActivityWithCompletion:^
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					if(ret != 0)
 | 
										if (ret == 0) {
 | 
				
			||||||
					{
 | 
											// success
 | 
				
			||||||
 | 
											if(completionBlock) completionBlock(YES, nil);
 | 
				
			||||||
 | 
										} else if (ret == 171) {
 | 
				
			||||||
 | 
											// recoverable error
 | 
				
			||||||
						UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
 | 
											UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
 | 
				
			||||||
						UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
 | 
											UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							if(ret == 171)
 | 
												if(completionBlock) completionBlock(NO, error);
 | 
				
			||||||
							{
 | 
					 | 
				
			||||||
								if(completionBlock) completionBlock(NO, error);
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}];
 | 
											}];
 | 
				
			||||||
						[errorAlert addAction:closeAction];
 | 
											[errorAlert addAction:closeAction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						if(ret == 171)
 | 
											UIAlertAction* forceInstallAction = [UIAlertAction actionWithTitle:@"Force Installation" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							UIAlertAction* forceInstallAction = [UIAlertAction actionWithTitle:@"Force Installation" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
 | 
												[self handleAppInstallFromFile:pathToIPA forceInstall:YES completion:completionBlock];
 | 
				
			||||||
							{
 | 
											}];
 | 
				
			||||||
								[self handleAppInstallFromFile:pathToIPA forceInstall:YES completion:completionBlock];
 | 
											[errorAlert addAction:forceInstallAction];
 | 
				
			||||||
							}];
 | 
					 | 
				
			||||||
							[errorAlert addAction:forceInstallAction];
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						else
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
							UIAlertAction* copyLogAction = [UIAlertAction actionWithTitle:@"Copy Debug Log" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
 | 
					 | 
				
			||||||
							{
 | 
					 | 
				
			||||||
								UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
 | 
					 | 
				
			||||||
								pasteboard.string = log;
 | 
					 | 
				
			||||||
							}];
 | 
					 | 
				
			||||||
							[errorAlert addAction:copyLogAction];
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
						[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
 | 
											[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
 | 
				
			||||||
					}
 | 
										} else if (ret == 182) {
 | 
				
			||||||
 | 
											// non-fatal informative message
 | 
				
			||||||
 | 
											UIAlertController* rebootNotification = [UIAlertController alertControllerWithTitle:@"Reboot Required" message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
 | 
				
			||||||
 | 
											UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												if(completionBlock) completionBlock(YES, nil);
 | 
				
			||||||
 | 
											}];
 | 
				
			||||||
 | 
											[rebootNotification addAction:closeAction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if(ret != 171)
 | 
											UIAlertAction* rebootAction = [UIAlertAction actionWithTitle:@"Reboot Now" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
 | 
				
			||||||
					{
 | 
											{
 | 
				
			||||||
						if(completionBlock) completionBlock((BOOL)error, error);
 | 
												if(completionBlock) completionBlock(YES, nil);
 | 
				
			||||||
 | 
												spawnRoot(rootHelperPath(), @[@"reboot"], nil, nil);
 | 
				
			||||||
 | 
											}];
 | 
				
			||||||
 | 
											[rebootNotification addAction:rebootAction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											[TSPresentationDelegate presentViewController:rebootNotification animated:YES completion:nil];
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											// unrecoverable error
 | 
				
			||||||
 | 
											UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
 | 
				
			||||||
 | 
											UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
 | 
				
			||||||
 | 
											[errorAlert addAction:closeAction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											UIAlertAction* copyLogAction = [UIAlertAction actionWithTitle:@"Copy Debug Log" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
 | 
				
			||||||
 | 
												pasteboard.string = log;
 | 
				
			||||||
 | 
											}];
 | 
				
			||||||
 | 
											[errorAlert addAction:copyLogAction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											if(completionBlock) completionBlock(NO, error);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}];
 | 
									}];
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
				
			|||||||
@ -5,5 +5,6 @@
 | 
				
			|||||||
    PSSpecifier* _installPersistenceHelperSpecifier;
 | 
					    PSSpecifier* _installPersistenceHelperSpecifier;
 | 
				
			||||||
    NSString* _newerVersion;
 | 
					    NSString* _newerVersion;
 | 
				
			||||||
    NSString* _newerLdidVersion;
 | 
					    NSString* _newerLdidVersion;
 | 
				
			||||||
 | 
					    BOOL _devModeEnabled;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@end
 | 
					@end
 | 
				
			||||||
@ -55,6 +55,16 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	//}
 | 
						//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (@available(iOS 16, *))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_devModeEnabled = spawnRoot(rootHelperPath(), @[@"check-dev-mode"], nil, nil) == 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_devModeEnabled = YES;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						[self reloadSpecifiers];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (NSMutableArray*)specifiers
 | 
					- (NSMutableArray*)specifiers
 | 
				
			||||||
@ -82,6 +92,26 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
 | 
				
			|||||||
			[_specifiers addObject:updateTrollStoreSpecifier];
 | 
								[_specifiers addObject:updateTrollStoreSpecifier];
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!_devModeEnabled)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								PSSpecifier* enableDevModeGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
 | 
				
			||||||
 | 
								enableDevModeGroupSpecifier.name = @"Developer Mode";
 | 
				
			||||||
 | 
								[enableDevModeGroupSpecifier setProperty:@"Some apps require developer mode enabled to launch. This requires a reboot to take effect." forKey:@"footerText"];
 | 
				
			||||||
 | 
								[_specifiers addObject:enableDevModeGroupSpecifier];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								PSSpecifier* enableDevModeSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Enable Developer Mode"
 | 
				
			||||||
 | 
															target:self
 | 
				
			||||||
 | 
															set:nil
 | 
				
			||||||
 | 
															get:nil
 | 
				
			||||||
 | 
															detail:nil
 | 
				
			||||||
 | 
															cell:PSButtonCell
 | 
				
			||||||
 | 
															edit:nil];
 | 
				
			||||||
 | 
								enableDevModeSpecifier.identifier = @"enableDevMode";
 | 
				
			||||||
 | 
								[enableDevModeSpecifier setProperty:@YES forKey:@"enabled"];
 | 
				
			||||||
 | 
								enableDevModeSpecifier.buttonAction = @selector(enableDevModePressed);
 | 
				
			||||||
 | 
								[_specifiers addObject:enableDevModeSpecifier];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		PSSpecifier* utilitiesGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
 | 
							PSSpecifier* utilitiesGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
 | 
				
			||||||
		utilitiesGroupSpecifier.name = @"Utilities";
 | 
							utilitiesGroupSpecifier.name = @"Utilities";
 | 
				
			||||||
		[utilitiesGroupSpecifier setProperty:@"If an app does not immediately appear after installation, respring here and it should appear afterwards." forKey:@"footerText"];
 | 
							[utilitiesGroupSpecifier setProperty:@"If an app does not immediately appear after installation, respring here and it should appear afterwards." forKey:@"footerText"];
 | 
				
			||||||
@ -369,6 +399,37 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
 | 
				
			|||||||
	[TSInstallationController installLdid];
 | 
						[TSInstallationController installLdid];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (void)enableDevModePressed
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret = spawnRoot(rootHelperPath(), @[@"arm-dev-mode"], nil, nil);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret == 0) {
 | 
				
			||||||
 | 
							UIAlertController* rebootNotification = [UIAlertController alertControllerWithTitle:@"Reboot Required"
 | 
				
			||||||
 | 
								message:@"After rebooting, select \"Turn On\" to enable developer mode."
 | 
				
			||||||
 | 
								preferredStyle:UIAlertControllerStyleAlert
 | 
				
			||||||
 | 
							];
 | 
				
			||||||
 | 
							UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								[self reloadSpecifiers];
 | 
				
			||||||
 | 
							}];
 | 
				
			||||||
 | 
							[rebootNotification addAction:closeAction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							UIAlertAction* rebootAction = [UIAlertAction actionWithTitle:@"Reboot Now" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								spawnRoot(rootHelperPath(), @[@"reboot"], nil, nil);
 | 
				
			||||||
 | 
							}];
 | 
				
			||||||
 | 
							[rebootNotification addAction:rebootAction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TSPresentationDelegate presentViewController:rebootNotification animated:YES completion:nil];
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Error %d", ret] message:@"Failed to enable developer mode." preferredStyle:UIAlertControllerStyleAlert];
 | 
				
			||||||
 | 
							UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
 | 
				
			||||||
 | 
							[errorAlert addAction:closeAction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (void)installPersistenceHelperPressed
 | 
					- (void)installPersistenceHelperPressed
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	NSMutableArray* appCandidates = [NSMutableArray new];
 | 
						NSMutableArray* appCandidates = [NSMutableArray new];
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user