Skip to content

Commit

Permalink
beta 1.2.6
Browse files Browse the repository at this point in the history
1: fixed the forkfix syscall bug that caused some devices to fail to bootstrap/install packages

2: automatically fix broken roothidepatch files caused by old versions of Bootstrap

3: fixed an issue that could cause the Bootstrap app to crash during bootstrapping
  • Loading branch information
roothider committed Sep 6, 2024
1 parent 56cbfdb commit 624ee75
Show file tree
Hide file tree
Showing 17 changed files with 149 additions and 32 deletions.
4 changes: 2 additions & 2 deletions Bootstrap.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.5;
MARKETING_VERSION = 1.2.6;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.roothide.Bootstrap;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -609,7 +609,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.5;
MARKETING_VERSION = 1.2.6;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.roothide.Bootstrap;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
Binary file not shown.
26 changes: 25 additions & 1 deletion Bootstrap/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ BOOL checkServer()
return ret;
}


#define PROC_PIDPATHINFO_MAXSIZE (1024)
int proc_pidpath(pid_t pid, void *buffer, uint32_t buffersize);
NSString* getLaunchdPath()
{
char pathbuf[PROC_PIDPATHINFO_MAXSIZE] = {0};
ASSERT(proc_pidpath(1, pathbuf, sizeof(pathbuf)) > 0);
return @(pathbuf);
}

void initFromSwiftUI()
{
BOOL IconCacheRebuilding=NO;
Expand Down Expand Up @@ -410,11 +420,25 @@ void bootstrapAction()
[AppDelegate showMesage:Localized(@"Your device does not seem to have developer mode enabled.\n\nPlease enable developer mode and reboot your device.") title:Localized(@"Error")];
return;
}

NSString* launchdpath = getLaunchdPath();
if(![launchdpath isEqualToString:@"/sbin/launchd"] && ![launchdpath hasPrefix:@"/var/containers/Bundle/Application/.jbroot-"])
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:Localized(@"Error") message:Localized(@"Please reboot device first.") preferredStyle:UIAlertControllerStyleAlert];

[alert addAction:[UIAlertAction actionWithTitle:Localized(@"Cancel") style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:Localized(@"Reboot Device") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
ASSERT(spawnRoot(NSBundle.mainBundle.executablePath, @[@"reboot"], nil, nil)==0);
}]];

[AppDelegate showAlert:alert];
return;
}

UIImpactFeedbackGenerator* generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleSoft];
[generator impactOccurred];

if(find_jbroot()) //make sure jbroot() function available
if(find_jbroot(YES)) //make sure jbroot() function available
{
if([NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/.installed_dopamine")]) {
[AppDelegate showMesage:Localized(@"roothide dopamine has been installed on this device, now install this bootstrap may break it!") title:Localized(@"Error")];
Expand Down
2 changes: 1 addition & 1 deletion Bootstrap/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct MainView: View {
@State var currentBlobs: [Color] = []
@State var currentHighlights: [Color] = []

@AppStorage("colorScheme", store: UserDefaults.app()) var colorScheme = 0
@AppStorage("colorScheme", store: UserDefaults.app()) var colorScheme = 1

@State private var showOptions = false
@State private var showCredits = false
Expand Down
Binary file modified Bootstrap/basebin/bootstrap.dylib
Binary file not shown.
Binary file modified Bootstrap/basebin/bootstrapd
Binary file not shown.
Binary file modified Bootstrap/basebin/devtest
Binary file not shown.
Binary file modified Bootstrap/basebin/preload
Binary file not shown.
Binary file modified Bootstrap/basebin/preload.dylib
Binary file not shown.
Binary file modified Bootstrap/basebin/rebuildapp
Binary file not shown.
Binary file modified Bootstrap/basebin/uicache
Binary file not shown.
99 changes: 92 additions & 7 deletions Bootstrap/bootstrap.m
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ int InstallBootstrap(NSString* jbroot_path)

ASSERT(mkdir(jbroot_path.fileSystemRepresentation, 0755) == 0);
ASSERT(chown(jbroot_path.fileSystemRepresentation, 0, 0) == 0);

find_jbroot(YES); //refresh

//jbroot() and jbrand() available now

NSString* bootstrapZstFile = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:
[NSString stringWithFormat:@"strapfiles/bootstrap-%d.tar.zst", getCFMajorVersion()]];
Expand Down Expand Up @@ -252,13 +256,13 @@ int InstallBootstrap(NSString* jbroot_path)

int ReRandomizeBootstrap()
{
//jbroot() unavailable

NSFileManager* fm = NSFileManager.defaultManager;

uint64_t prev_jbrand = jbrand();
uint64_t new_jbrand = jbrand_new();

//jbroot() and jbrand() unavailable now

NSFileManager* fm = NSFileManager.defaultManager;

ASSERT( [fm moveItemAtPath:[NSString stringWithFormat:@"/var/containers/Bundle/Application/.jbroot-%016llX", prev_jbrand]
toPath:[NSString stringWithFormat:@"/var/containers/Bundle/Application/.jbroot-%016llX", new_jbrand] error:nil] );

Expand Down Expand Up @@ -292,8 +296,10 @@ int ReRandomizeBootstrap()
ASSERT([fm createSymbolicLinkAtPath:[jbroot_secondary stringByAppendingPathComponent:@".jbroot"]
withDestinationPath:jbroot_path error:nil]);

//jbroot() available now
find_jbroot(YES); //refresh

//jbroot() and jbrand() available now

STRAPLOG("Status: Building Base Binaries");
ASSERT(rebuildBasebin() == 0);

Expand Down Expand Up @@ -332,6 +338,84 @@ void fixMobileDirectories()
}
}

#include <mach-o/loader.h>
NSString* getMachoInstallName(NSString* path)
{
int fd = open(path.fileSystemRepresentation, O_RDONLY);
if(fd < 0) return nil;

NSString* installname = nil;

do {
if(lseek(fd, 0, SEEK_SET) != 0) break;

struct mach_header_64 header={0};
if(read(fd, &header, sizeof(header)) != sizeof(header))break;

//there is no universal macho on Bootstrap
if(header.magic!=MH_MAGIC_64 || header.cputype!= CPU_TYPE_ARM64) break;

struct load_command* lc = malloc(header.sizeofcmds);
if(!lc) break;

if(read(fd, lc, header.sizeofcmds) != header.sizeofcmds)break;

for (uint32_t i = 0; i < header.ncmds; i++) {
if (lc->cmd == LC_ID_DYLIB)
{
struct dylib_command* id_dylib = (struct dylib_command*)lc;
const char* name = (char*)((uint64_t)id_dylib + id_dylib->dylib.name.offset);
installname = @(name);
}
lc = (struct load_command *) ((char *)lc + lc->cmdsize);
}

} while(0);

close(fd);

return installname;
}

void fixBadPatchFiles()
{
NSString* dirpath = jbroot(@"/");
for(NSString* path in [[NSFileManager defaultManager] enumeratorAtPath:dirpath]) {

if(![path.pathExtension isEqualToString:@"roothidepatch"]) {
continue;
}

NSString* fullpath = [dirpath stringByAppendingPathComponent:path];

struct stat symst;
if(lstat(fullpath.fileSystemRepresentation, &symst) !=0)
{
SYSLOG("scanBadPatchFiles: lstat: %@: %s", fullpath, strerror(errno));
continue;
}

if(S_ISLNK(symst.st_mode))
{
SYSLOG("scanBadPatchFiles: symlink: %@", fullpath);
continue;
}

STRAPLOG("fixBadPatchFiles: %@", path);

NSString* installname = getMachoInstallName(fullpath);

if([installname.stringByDeletingLastPathComponent isEqualToString:@"@loader_path/.jbroot/usr/lib/DynamicPatches"])
{
ASSERT(unlink(fullpath.fileSystemRepresentation) == 0);

NSString* sympath = jbroot([@"/usr/lib/DynamicPatches" stringByAppendingPathComponent:installname.lastPathComponent]);
ASSERT(symlink(sympath.fileSystemRepresentation, fullpath.fileSystemRepresentation) == 0);
}
}
}


int bootstrap()
{
ASSERT(getuid()==0);
Expand All @@ -346,7 +430,7 @@ int bootstrap()
ASSERT([fm removeItemAtPath:@"/var/jb" error:nil]);
}

NSString* jbroot_path = find_jbroot();
NSString* jbroot_path = find_jbroot(YES);

if(!jbroot_path) {
STRAPLOG("device is not strapped...");
Expand Down Expand Up @@ -385,6 +469,7 @@ int bootstrap()
ASSERT(ReRandomizeBootstrap() == 0);

fixMobileDirectories();
fixBadPatchFiles();
}

ASSERT(disableRootHideBlacklist()==0);
Expand Down Expand Up @@ -467,7 +552,7 @@ int unbootstrap()

bool isBootstrapInstalled()
{
if(!find_jbroot())
if(!find_jbroot(YES))
return NO;

if(![NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/.bootstrapped")]
Expand Down
2 changes: 1 addition & 1 deletion Bootstrap/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ uint64_t jbrand();

uint64_t jbrand_new();

NSString* find_jbroot();
NSString* find_jbroot(BOOL force);

NSString* jbroot(NSString *path);

Expand Down
42 changes: 25 additions & 17 deletions Bootstrap/utils.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,37 +60,45 @@ uint64_t resolve_jbrand_value(const char* name)
}


NSString* find_jbroot()
NSString* find_jbroot(BOOL force)
{
//jbroot path may change when re-randomize it
NSString * jbroot = nil;
NSArray *subItems = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/var/containers/Bundle/Application/" error:nil];
for (NSString *subItem in subItems) {
if (is_jbroot_name(subItem.UTF8String))
{
NSString* path = [@"/var/containers/Bundle/Application/" stringByAppendingPathComponent:subItem];

// if([NSFileManager.defaultManager fileExistsAtPath:
// [path stringByAppendingPathComponent:@".installed_dopamine"]])
// continue;
static NSString* cached_jbroot = nil;
if(!force && cached_jbroot) {
return cached_jbroot;
}
@synchronized(@"find_jbroot_lock")
{
//jbroot path may change when re-randomize it
NSString * jbroot = nil;
NSArray *subItems = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/var/containers/Bundle/Application/" error:nil];
for (NSString *subItem in subItems) {
if (is_jbroot_name(subItem.UTF8String))
{
NSString* path = [@"/var/containers/Bundle/Application/" stringByAppendingPathComponent:subItem];

jbroot = path;
break;
// if([NSFileManager.defaultManager fileExistsAtPath:
// [path stringByAppendingPathComponent:@".installed_dopamine"]])
// continue;

jbroot = path;
break;
}
}
cached_jbroot = jbroot;
}
return jbroot;
return cached_jbroot;
}

NSString *jbroot(NSString *path)
{
NSString* jbroot = find_jbroot();
NSString* jbroot = find_jbroot(NO);
ASSERT(jbroot != NULL); //to avoid [nil stringByAppendingString:
return [jbroot stringByAppendingPathComponent:path];
}

uint64_t jbrand()
{
NSString* jbroot = find_jbroot();
NSString* jbroot = find_jbroot(NO);
ASSERT(jbroot != NULL);
return resolve_jbrand_value([jbroot lastPathComponent].UTF8String);
}
Expand Down
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ INSTALL_TARGET_PROCESSES = Bootstrap

THEOS_PACKAGE_SCHEME = roothide

THEOS_DEVICE_IP = iphone13pm.local

#disable theos auto sign for all mach-o
TARGET_CODESIGN = echo "don't sign"

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ By design, roothide does not inject tweaks into any applications by default. To

**A roothide Bootstrap FAQ** is available [here](https://github.com/dleovl/Bootstrap/blob/faq/README.md).

**For installing Bootstrap**, refer to the guides at (https://onejailbreak.com/blog/bootstrap-roothide/)[https://onejailbreak.com/blog/bootstrap-roothide/]

## Develop tweaks

Both rootful and rootless tweaks aren't out-of-the-box compatible with roothide, so you'll need to develop them specifically to support it. You can refer to the developer documentation [here](https://github.com/roothide/Developer).
Expand Down

0 comments on commit 624ee75

Please sign in to comment.