Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

27 changes: 27 additions & 0 deletions .github/workflows/makefile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Makefile CI

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: configure
run: ./configure

- name: Install dependencies
run: make

- name: Run check
run: make check

- name: Run distcheck
run: make distcheck
37 changes: 27 additions & 10 deletions ChoicyPrefs/CHPAdditionalExecutablesListController.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ - (id)_editButtonBarItem
return addButton;
}

//for high version of ios16, ios17+
- (id)editBarButtonItem
{
return [self _editButtonBarItem];
}

- (id)previewStringForSpecifier:(PSSpecifier *)specifier
{
return [CHPListController previewStringForSpecifier:specifier];
Expand Down Expand Up @@ -63,7 +69,7 @@ - (void)addButtonPressed
UIAlertController *executableAlert = [UIAlertController alertControllerWithTitle:localize(@"SELECT_EXECUTABLE") message:localize(@"SELECT_EXECUTABLE_MESSAGE") preferredStyle:UIAlertControllerStyleAlert];

[executableAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = localize(@"PATH");
textField.placeholder = [NSString stringWithFormat:@"%@ (%@)",localize(@"PATH"),localize(@"Path based on jbroot")];
if (@available(iOS 13, *)) {
textField.textColor = [UIColor labelColor];
}
Expand Down Expand Up @@ -100,25 +106,26 @@ - (void)addExecutableAtPath:(NSString *)executablePath
{
if ([_additionalExecutables containsObject:executablePath]) return;

if (![[NSFileManager defaultManager] fileExistsAtPath:executablePath]) {
if (![[NSFileManager defaultManager] fileExistsAtPath:jbroot(executablePath)]) {
[self showErrorMessage:localize(@"ERROR_FILE_NOT_FOUND")];
return;
}

if (!isFileAtPathMacho(executablePath)) {
if (!isFileAtPathMacho(jbroot(executablePath))) {
[self showErrorMessage:localize(@"ERROR_FILE_NO_EXECUTABLE")];
return;
}

if (![[CHPTweakList sharedInstance] oneOrMoreTweaksInjectIntoExecutableAtPath:executablePath]) {
[self showErrorMessage:localize(@"ERROR_NO_TWEAKS_INJECT")];
return;
}
// maybe we just want to disable tweak for the process
// if (![[CHPTweakList sharedInstance] oneOrMoreTweaksInjectIntoExecutableAtPath:executablePath]) {
// [self showErrorMessage:localize(@"ERROR_NO_TWEAKS_INJECT")];
// return;
// }

[_additionalExecutables addObject:executablePath];
[self saveAdditionalExecutables];

PSSpecifier *specifierToInsert = [CHPListController createSpecifierForExecutable:executablePath named:executablePath];
PSSpecifier *specifierToInsert = [CHPListController createSpecifierForExecutable:jbroot(executablePath) named:executablePath];
[self insertSpecifier:specifierToInsert atEndOfGroup:0 animated:YES];
}

Expand All @@ -129,10 +136,20 @@ - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleFo

- (BOOL)performDeletionActionForSpecifier:(PSSpecifier *)specifier
{
//Due to Choicy's prefs logic, it is difficult to determine how to delete its configuration through a path (it may be in daemonSettings or appSettings)
UIAlertController *alert = [UIAlertController alertControllerWithTitle:localize(@"WARNING_ALERT_TITLE") message:
@"You need to manually remove it from appSettings/daemonSettings/additionalExecutables in jbroot:/var/mobile/Library/Preferences/com.opa334.choicyprefs.plist and execute 'killall -9 cfprefsd'" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:localize(@"CANCEL") style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];
[self reloadSpecifiers];
return NO;


BOOL orig = [super performDeletionActionForSpecifier:specifier];

NSString *executablePath = [specifier propertyForKey:@"executablePath"];
[_additionalExecutables removeObject:executablePath];
[_additionalExecutables removeObject:rootfs(executablePath)];
[self saveAdditionalExecutables];

return orig;
Expand All @@ -151,7 +168,7 @@ - (NSMutableArray *)specifiers
[_specifiers addObject:groupSpecifier];

[_additionalExecutables enumerateObjectsUsingBlock:^(NSString *executablePath, NSUInteger idx, BOOL *stop) {
[_specifiers addObject:[CHPListController createSpecifierForExecutable:executablePath named:executablePath]];
[_specifiers addObject:[CHPListController createSpecifierForExecutable:jbroot(executablePath) named:executablePath]];
}];
}

Expand Down
5 changes: 4 additions & 1 deletion ChoicyPrefs/CHPDaemonList.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#import "CHPTweakList.h"
#import "../Shared.h"
#import "../HBLogWeak.h"
#import <libroot.h>
#import <roothide.h>

#import <dirent.h>

Expand Down Expand Up @@ -80,6 +80,9 @@ - (void)updateDaemonListIfNeeded
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/var/jb/Library/LaunchDaemons"]) {
[daemonPlists addObjectsFromArray:[[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:@"/var/jb/Library/LaunchDaemons"] includingPropertiesForKeys:nil options:0 error:nil]];
}
if (![jbroot(@"/") isEqualToString:@"/"] && [[NSFileManager defaultManager] fileExistsAtPath:jbroot(@"/Library/LaunchDaemons")]) {
[daemonPlists addObjectsFromArray:[[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:jbroot(@"/Library/LaunchDaemons")] includingPropertiesForKeys:nil options:0 error:nil]];
}

for (NSURL *daemonPlistURL in [daemonPlists reverseObjectEnumerator]) {
if (![daemonPlistURL.pathExtension isEqualToString:@"plist"]) {
Expand Down
2 changes: 1 addition & 1 deletion ChoicyPrefs/CHPDaemonListController.m
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ - (NSMutableArray *)specifiers
[_specifiers addObject:daemonToggleSpecifier];

PSSpecifier *daemonsGroup = [PSSpecifier emptyGroupSpecifier];
[daemonsGroup setProperty:localize(@"DAEMON_LIST_BOTTOM_NOTICE") forKey:@"footerText"];
// [daemonsGroup setProperty:localize(@"DAEMON_LIST_BOTTOM_NOTICE") forKey:@"footerText"];
[_specifiers addObject:daemonsGroup];

NSArray<CHPDaemonInfo*> *daemonList = [CHPDaemonList sharedInstance].daemonList;
Expand Down
8 changes: 4 additions & 4 deletions ChoicyPrefs/CHPPackageInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#import "CHPPackageInfo.h"
#import "CHPTweakList.h"
#import <libroot.h>
#import <roothide.h>

NSDictionary *g_packageNamesByIdentifier;
NSArray *g_packageInfos;
Expand All @@ -37,7 +37,7 @@ + (void)loadPackageNames
{
NSMutableDictionary *packageNamesByIdentifierM = [NSMutableDictionary new];

NSString *status = [NSString stringWithContentsOfFile:JBROOT_PATH_NSSTRING(@"/var/lib/dpkg/status") encoding:NSUTF8StringEncoding error:nil];
NSString *status = [NSString stringWithContentsOfFile:jbroot(@"/var/lib/dpkg/status") encoding:NSUTF8StringEncoding error:nil];
NSArray *statusSections = [status componentsSeparatedByString:@"\n\n"];
[statusSections enumerateObjectsUsingBlock:^(NSString *packageInfoStr, NSUInteger idx, BOOL *stop) {
if ([packageInfoStr hasPrefix:@"Package: "]) {
Expand Down Expand Up @@ -66,7 +66,7 @@ + (void)loadAvailablePackages
//Load all packages that have a dylib into g_packageInfos
NSMutableArray *packageInfos = [NSMutableArray new];

NSString *dirPath = JBROOT_PATH_NSSTRING(@"/var/lib/dpkg/info");
NSString *dirPath = jbroot(@"/var/lib/dpkg/info");
NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:dirPath];

NSString *filename;
Expand Down Expand Up @@ -115,7 +115,7 @@ - (instancetype)initWithPackageIdentifier:(NSString *)packageID

- (void)loadTweakDylibs
{
NSString *dpkgInfoPath = [NSString stringWithFormat:JBROOT_PATH_NSSTRING(@"/var/lib/dpkg/info/%@.list"), _identifier];
NSString *dpkgInfoPath = [NSString stringWithFormat:jbroot(@"/var/lib/dpkg/info/%@.list"), _identifier];
NSString *dpkgInfo = [NSString stringWithContentsOfFile:dpkgInfoPath encoding:NSUTF8StringEncoding error:nil];

NSMutableArray *tweakDylibsM = [NSMutableArray new];
Expand Down
10 changes: 7 additions & 3 deletions ChoicyPrefs/CHPRootListController.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#import <mach-o/dyld.h>
#import "CHPPreferences.h"
#import "../ChoicyPrefsMigrator.h"
#import <libroot.h>
#import <roothide.h>

NSArray *dylibsBeforeChoicy;

Expand Down Expand Up @@ -276,15 +276,19 @@ void determineLoadingOrder()

if (choicyIndex == NSNotFound) return;

if(access(jbroot("/usr/lib/libellekit.dylib"), F_OK)==0) {
return; //ellekit's TweakLoader always load Choicy first
}

if (choicyIndex != 0) {
dylibsBeforeChoicy = [dylibsInOrder subarrayWithRange:NSMakeRange(0,choicyIndex)];
}

if (dylibsBeforeChoicy && isSubstrate) {
NSDictionary *targetLoaderAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:JBROOT_PATH_NSSTRING(@"/usr/lib/substrate/SubstrateLoader.dylib") error:nil];
NSDictionary *targetLoaderAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:jbroot(@"/usr/lib/substrate/SubstrateLoader.dylib") error:nil];

if ([[targetLoaderAttributes objectForKey:NSFileType] isEqualToString:NSFileTypeSymbolicLink]) {
NSString *destination = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:JBROOT_PATH_NSSTRING(@"/usr/lib/substrate/SubstrateLoader.dylib") error:nil];
NSString *destination = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:jbroot(@"/usr/lib/substrate/SubstrateLoader.dylib") error:nil];
if ([destination hasPrefix:@"/usr/lib/ChoicyLoader.dylib"]) {
// If ChoicyLoader is installed on Substrate, Choicy always loads first
dylibsBeforeChoicy = nil;
Expand Down
51 changes: 48 additions & 3 deletions ChoicyPrefs/CHPTweakList.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#import "CHPMachoParser.h"
#import "../Shared.h"
#import "../HBLogWeak.h"
#import <libroot.h>
#import <roothide.h>

@implementation CHPTweakList

Expand All @@ -42,7 +42,7 @@ + (instancetype)sharedInstance
+ (NSArray *)possibleInjectionLibrariesPaths
{
// /Library and /usr always gets converted to rootless paths on xina, so this workaround is neccessary
return @[[@"/" stringByAppendingString:@"Library/MobileSubstrate/DynamicLibraries"], [@"/" stringByAppendingString:@"usr/lib/TweakInject"], @"/var/jb/Library/MobileSubstrate/DynamicLibraries", @"/var/jb/usr/lib/TweakInject"];
return @[jbroot(@"/Library/MobileSubstrate/DynamicLibraries"), jbroot(@"/usr/lib/TweakInject"), @"/var/jb/Library/MobileSubstrate/DynamicLibraries", @"/var/jb/usr/lib/TweakInject"];
}

+ (NSString *)injectionLibrariesPath
Expand All @@ -61,7 +61,8 @@ + (BOOL)isTweakLibraryPath:(NSString *)path
if (![path.pathExtension isEqualToString:@"dylib"]) return NO;

for (NSString *possibleInjectionLibrariesPath in [self possibleInjectionLibrariesPaths]) {
if ([path hasPrefix:possibleInjectionLibrariesPath]) return YES;
//if ([path hasPrefix:possibleInjectionLibrariesPath]) return YES;
if([possibleInjectionLibrariesPath hasSuffix:[path stringByDeletingLastPathComponent]]) return YES;
}

return NO;
Expand Down Expand Up @@ -101,6 +102,7 @@ - (void)updateTweakList
self.tweakList = [tweakListM copy];
}

/*
- (NSArray *)tweakListForExecutableAtPath:(NSString *)executablePath
{
HBLogDebugWeak(@"tweakListForExecutableAtPath:%@", executablePath);
Expand All @@ -119,6 +121,22 @@ - (NSArray *)tweakListForExecutableAtPath:(NSString *)executablePath
}
}

if([executablePath isEqualToString:@"/System/Library/CoreServices/SpringBoard.app/SpringBoard"]) {
__block BOOL isUITweak = NO;

[tweakInfo.filterBundles enumerateObjectsUsingBlock:^(NSString *bundleID, NSUInteger idx, BOOL *stop) {
if ([bundleID hasPrefix:@"com.apple.UIKit"] || [bundleID hasPrefix:@"com.apple.TextInput"] || [bundleID hasPrefix:@"com.apple.TextEntry"]) {
isUITweak = YES;
*stop = YES;
}
}];

if(isUITweak) {
[tweakListForExecutable addObject:tweakInfo];
return;
}
}

if (executableName) {
if ([tweakInfo.filterExecutables containsObject:executableName]) {
[tweakListForExecutable addObject:tweakInfo];
Expand All @@ -138,6 +156,33 @@ - (NSArray *)tweakListForExecutableAtPath:(NSString *)executablePath

return tweakListForExecutable;
}
//*/

- (NSArray *)tweakListForExecutableAtPath:(NSString *)executablePath
{
HBLogDebugWeak(@"tweakListForExecutableAtPath:%@", executablePath);
if (!executablePath) return nil;

NSString *executableName = executablePath.lastPathComponent;

NSMutableArray *tweakListForExecutable = [NSMutableArray new];
[self.tweakList enumerateObjectsUsingBlock:^(CHPTweakInfo *tweakInfo, NSUInteger idx, BOOL *stop) {

if (executableName) {
if ([tweakInfo.filterExecutables containsObject:executableName]) {
[tweakListForExecutable addObject:tweakInfo];
return;
}
}

if (tweakInfo.filterBundles) {
[tweakListForExecutable addObject:tweakInfo];
return;
}
}];

return tweakListForExecutable;
}

- (BOOL)oneOrMoreTweaksInjectIntoExecutableAtPath:(NSString *)executablePath
{
Expand Down
19 changes: 14 additions & 5 deletions ChoicySB/SpringBoard.x
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#import "SpringBoard.h"
#import "ChoicyOverrideManager.h"
#import <UIKit/UIKit.h>
#import <libroot.h>
#import <roothide.h>
#import "ChoicySB.h"

NSBundle *CHBundle;
Expand Down Expand Up @@ -58,9 +58,18 @@ BOOL choicy_shouldShow3DTouchOptionForDisableTweakInjectionState(BOOL disableTwe
toggleOneTimeApplicationID = nil;
if (toggleOnce) {
NSMutableDictionary *environmentM = [executionContext.environment mutableCopy];
BOOL newValue = !choicy_shouldDisableTweakInjectionForApplication(bundleIdentifier);
[environmentM setObject:@(newValue) forKey:@"_MSSafeMode"];
[environmentM setObject:@(newValue) forKey:@"_SafeMode"];
if(choicy_shouldDisableTweakInjectionForApplication(bundleIdentifier)) {
//tweak disabled in preferences, so we want to enable them for this time launch
[environmentM setObject:@(1) forKey:@"_CHOICY_LOAD_TWEAKS_ONCE"];
[environmentM removeObjectForKey:@"_MSSafeMode"];
[environmentM removeObjectForKey:@"_SafeMode"];
}
else {
//tweak not disabled in preferences, so we want to disable them for this time launch
[environmentM setObject:@(1) forKey:@"_MSSafeMode"];
[environmentM setObject:@(1) forKey:@"_SafeMode"];
[environmentM removeObjectForKey:@"_CHOICY_LOAD_TWEAKS_ONCE"];
}
executionContext.environment = [environmentM copy];
}

Expand Down Expand Up @@ -242,7 +251,7 @@ void choicy_initSpringBoard(void)
{
%init();

CHBundle = [NSBundle bundleWithPath:JBROOT_PATH_NSSTRING(@"/Library/Application Support/Choicy.bundle")];
CHBundle = [NSBundle bundleWithPath:jbroot(@"/Library/Application Support/Choicy.bundle")];
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, respring, CFSTR("com.opa334.choicy/respring"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);

if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_13_0) {
Expand Down
2 changes: 1 addition & 1 deletion ChoicySB/Tweak.x
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ BOOL choicy_shouldDisableTweakInjectionForApplication(NSString *applicationID)

NSDictionary *choicy_applyEnvironmentChanges(NSDictionary *originalEnvironment, NSString *bundleIdentifier)
{
if (originalEnvironment[@"_MSSafeMode"] || originalEnvironment[@"_SafeMode"]) {
if (originalEnvironment[@"_MSSafeMode"] || originalEnvironment[@"_SafeMode"] || originalEnvironment[@"_CHOICY_LOAD_TWEAKS_ONCE"]) {
// If this is set, it was set by the SpringBoard hook and that should act as an override
// To support the haptic touch app option
return originalEnvironment;
Expand Down
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
ifeq ($(THEOS_PACKAGE_SCHEME),rootless)
TARGET = iphone:clang:16.5:15.0
else ifeq ($(THEOS_PACKAGE_SCHEME),roothide)
export TARGET = iphone:clang:16.2:15.0
else
TARGET = iphone:clang:13.7:8.0
endif
Expand All @@ -8,10 +10,12 @@ include $(THEOS)/makefiles/common.mk

TWEAK_NAME = Choicy

Choicy_FILES = Tweak.x Shared.m ChoicyPrefsMigrator.m
Choicy_FILES = Tweak.x Shared.m ChoicyPrefsMigrator.m fishhook.c
Choicy_CFLAGS = -fobjc-arc -DTHEOS_LEAN_AND_MEAN # <- this makes theos not link against anything by default (we do not want to link UIKit cause we inject system wide)
Choicy_FRAMEWORKS = Foundation
Choicy_EXTRA_FRAMEWORKS = CydiaSubstrate
# Choicy_EXTRA_FRAMEWORKS = CydiaSubstrate
Choicy_LOGOS_DEFAULT_GENERATOR = internal


include $(THEOS_MAKE_PATH)/tweak.mk
SUBPROJECTS += ChoicyPrefs
Expand Down
4 changes: 2 additions & 2 deletions Shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#import <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#import <HBLog.h>
#import <libroot.h>
#import <roothide.h>

extern NSBundle *CHBundle;
extern NSString *localize(NSString *key);
Expand All @@ -31,7 +31,7 @@ extern NSDictionary *processPreferencesForDaemon(NSDictionary *preferences, NSSt
extern BOOL parseNumberBool(id number, BOOL default_);
extern NSInteger parseNumberInteger(id number, NSInteger default_);

#define kChoicyPrefsPlistPath JBROOT_PATH_NSSTRING(@"/var/mobile/Library/Preferences/com.opa334.choicyprefs.plist")
#define kChoicyPrefsPlistPath jbroot(@"/var/mobile/Library/Preferences/com.opa334.choicyprefs.plist")
#define kChoicyDylibName @" Choicy"

#define kChoicyPrefsKeyGlobalDeniedTweaks @"globalDeniedTweaks"
Expand Down
Loading