Skip to content

Commit

Permalink
adapt JitStreamer EB 0.2.0, hide lc from dyld api, fix zsign not sign…
Browse files Browse the repository at this point in the history
…ing FAT binaries
  • Loading branch information
hugeBlack committed Feb 7, 2025
1 parent 43a0771 commit 9146b83
Show file tree
Hide file tree
Showing 15 changed files with 176 additions and 85 deletions.
2 changes: 1 addition & 1 deletion LiveContainerSwiftUI/LCAppListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
return
}

if !installUrl.startAccessingSecurityScopedResource() {
if !FileManager.default.isReadableFile(atPath: installUrl.path) && !installUrl.startAccessingSecurityScopedResource() {
errorInfo = "lc.appList.ipaAccessError".loc
errorShow = true
return
Expand Down
4 changes: 2 additions & 2 deletions LiveContainerSwiftUI/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -3216,7 +3216,7 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Install another LiveContainer"
"value" : "Install Another LiveContainer"
}
},
"zh_CN" : {
Expand Down Expand Up @@ -3267,7 +3267,7 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reinstall another LiveContainer"
"value" : "Reinstall Another LiveContainer"
}
},
"zh_CN" : {
Expand Down
64 changes: 40 additions & 24 deletions LiveContainerSwiftUI/Shared.swift
Original file line number Diff line number Diff line change
Expand Up @@ -793,15 +793,44 @@ extension LCUtils {
onServerMessage?("Please make sure the VPN is connected if the server is not in your local network.")

do {

onServerMessage?("Contacting JitStreamer-EB server at \(JITStresmerEBAddress)...")

let session = URLSession.shared
let decoder = JSONDecoder()

let mountStatusUrlStr = "\(JITStresmerEBAddress)/mount"
guard let mountStatusUrl = URL(string: mountStatusUrlStr) else { return false }
let mountRequest = URLRequest(url: mountStatusUrl)

// check mount status
onServerMessage?("Checking mount status...")
let (mountData, mountResponse) = try await session.asyncRequest(request: mountRequest)
guard let mountData else {
onServerMessage?("Failed to mount status from server!")
return false
}
let mountResponseObj = try decoder.decode(JITStreamerEBMountResponse.self, from: mountData)
guard mountResponseObj.ok else {
onServerMessage?(mountResponseObj.error ?? "Mounting failed with unknown error.")
return false
}
if mountResponseObj.mounting {
onServerMessage?("Your device is currently mounting the developer disk image. Leave your device on and connected. Once this finishes, you can run JitStreamer again.")
onServerMessage?("Check \(JITStresmerEBAddress)/mount_status for mounting status.")
return false
}

// send launch_app request
let launchJITUrlStr = "\(JITStresmerEBAddress)/launch_app/\(Bundle.main.bundleIdentifier ?? "")"
guard let launchJITUrl = URL(string: launchJITUrlStr) else { return false }
let session = URLSession.shared


onServerMessage?("Contacting JitStreamer-EB server at \(JITStresmerEBAddress)...")
onServerMessage?("Sending launch request...")
let request1 = URLRequest(url: launchJITUrl)
let (data, response) = try await session.asyncRequest(request: request1)

let decoder = JSONDecoder()

guard let data else {
onServerMessage?("Failed to retrieve data from server!")
return false
Expand All @@ -813,11 +842,7 @@ extension LCUtils {
return false
}

if launchAppResponse.mounting {
onServerMessage?("Your device is currently mounting the developer disk image. Leave your device on and connected. Once this finishes, you can run JitStreamer again.")
} else {
onServerMessage?("Your app will launch soon! You are position \(launchAppResponse.position ?? -1) in the queue.")
}
onServerMessage?("Your app will launch soon! You are position \(launchAppResponse.position ?? -1) in the queue.")

// start polling status
let statusUrlStr = "\(JITStresmerEBAddress)/status"
Expand All @@ -841,23 +866,10 @@ extension LCUtils {
}
if statusResponse.done {
onServerMessage?("Server done.")
if launchAppResponse.mounting {
onServerMessage?("Run the app again to enable JIT.")
}

return true
}
if statusResponse.in_progress {
if launchAppResponse.mounting {
onServerMessage?("JIT enabling in progress. (Attempt \(i + 1)/\(maxTries))")
} else {
onServerMessage?("Mounting in progress. (Attempt \(i + 1)/\(maxTries))")
}

} else {
onServerMessage?("Your app will launch soon! You are position \(launchAppResponse.position ?? -1) in the queue. (Attempt \(i + 1)/\(maxTries))")
}

onServerMessage?("Your app will launch soon! You are position \(launchAppResponse.position ?? -1) in the queue. (Attempt \(i + 1)/\(maxTries))")
}


Expand All @@ -876,15 +888,19 @@ extension LCUtils {
struct JITStreamerEBLaunchAppResponse : Codable {
let ok: Bool
let launching: Bool
let mounting: Bool
let position: Int?
let error: String?
}

struct JITStreamerEBStatusResponse : Codable {
let ok: Bool
let done: Bool
let in_progress: Bool
let position: Int?
let error: String?
}

struct JITStreamerEBMountResponse : Codable {
let ok: Bool
let mounting: Bool
let error: String?
}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export CONFIG_COMMIT = $(shell git log --oneline | sed '2,10000000d' | cut -b 1-
# Build the app
APPLICATION_NAME = LiveContainer

$(APPLICATION_NAME)_FILES = dyld_bypass_validation.m main.m utils.m LCSharedUtils.m NSUserDefaults.m SecItem.m fishhook/fishhook.c
$(APPLICATION_NAME)_FILES = dyld_bypass_validation.m main.m utils.m LCSharedUtils.m Tweaks/NSUserDefaults.m Tweaks/SecItem.m Tweaks/NSBundle+FixCydiaSubstrate.m Tweaks/Dyld.m fishhook/fishhook.c
$(APPLICATION_NAME)_CODESIGN_FLAGS = -Sentitlements.xml
$(APPLICATION_NAME)_CFLAGS = -fobjc-arc
$(APPLICATION_NAME)_LDFLAGS = -e _LiveContainerMain -rpath @loader_path/Frameworks
Expand Down
4 changes: 2 additions & 2 deletions Resources/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.2.55</string>
<string>3.2.56</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
Expand All @@ -61,7 +61,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>3.2.55</string>
<string>3.2.56</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>LSApplicationQueriesSchemes</key>
Expand Down
2 changes: 1 addition & 1 deletion TweakLoader/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ include $(THEOS)/makefiles/common.mk

LIBRARY_NAME = TweakLoader

TweakLoader_FILES = TweakLoader.m NSBundle+FixCydiaSubstrate.m NSFileManager+GuestHooks.m UIKit+GuestHooks.m utils.m DocumentPicker.m FBSSerialQueue.m ../Localization.m
TweakLoader_FILES = TweakLoader.m NSFileManager+GuestHooks.m UIKit+GuestHooks.m utils.m DocumentPicker.m FBSSerialQueue.m ../Localization.m
TweakLoader_CFLAGS = -objc-arc
TweakLoader_INSTALL_PATH = /Applications/LiveContainer.app/Frameworks
TweakLoader_PRIVATE_FRAMEWORKS = CoreServices FrontBoard RunningBoardServices
Expand Down
29 changes: 0 additions & 29 deletions TweakLoader/NSBundle+FixCydiaSubstrate.m

This file was deleted.

77 changes: 77 additions & 0 deletions Tweaks/Dyld.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// Dyld.m
// LiveContainer
//
// Created by s s on 2025/2/7.
//
#include <dlfcn.h>
#include <execinfo.h>
#include <signal.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <mach-o/dyld.h>
#include <mach-o/dyld_images.h>
#include <objc/runtime.h>
#include <mach-o/ldsyms.h>
#import "../fishhook/fishhook.h"

uint32_t appMainImageIndex = 0;
void* appExecutableHandle = 0;

void* (*orig_dlsym)(void * __handle, const char * __symbol);
uint32_t (*orig_dyld_image_count)(void);
const struct mach_header* (*orig_dyld_get_image_header)(uint32_t image_index);
intptr_t (*orig_dyld_get_image_vmaddr_slide)(uint32_t image_index);
const char* (*orig_dyld_get_image_name)(uint32_t image_index);

static inline int translateImageIndex(int origin) {
if(origin == 1) {
return appMainImageIndex;
}
if(origin >= appMainImageIndex) {
return origin + 1;
}
return origin;
}


void* hook_dlsym(void * __handle, const char * __symbol) {
if(__handle == (void*)RTLD_MAIN_ONLY) {
if(strcmp(__symbol, MH_EXECUTE_SYM) == 0) {
return (void*)orig_dyld_get_image_header(appMainImageIndex);
}
__handle = appExecutableHandle;
}

__attribute__((musttail)) return orig_dlsym(__handle, __symbol);
}

uint32_t hook_dyld_image_count(void) {
return orig_dyld_image_count() - 1;
}

const struct mach_header* hook_dyld_get_image_header(uint32_t image_index) {
__attribute__((musttail)) return orig_dyld_get_image_header(translateImageIndex(image_index));
}

intptr_t hook_dyld_get_image_vmaddr_slide(uint32_t image_index) {
__attribute__((musttail)) return orig_dyld_get_image_vmaddr_slide(translateImageIndex(image_index));
}

const char* hook_dyld_get_image_name(uint32_t image_index) {
__attribute__((musttail)) return orig_dyld_get_image_name(translateImageIndex(image_index));
}



void DyldHooksInit(void) {
// hook dlsym to solve RTLD_MAIN_ONLY, hook other functions to hide LiveContainer itself
rebind_symbols((struct rebinding[5]){
{"dlsym", (void *)hook_dlsym, (void **)&orig_dlsym},
{"_dyld_image_count", (void *)hook_dyld_image_count, (void **)&orig_dyld_image_count},
{"_dyld_get_image_header", (void *)hook_dyld_get_image_header, (void **)&orig_dyld_get_image_header},
{"_dyld_get_image_vmaddr_slide", (void *)hook_dyld_get_image_vmaddr_slide, (void **)&orig_dyld_get_image_vmaddr_slide},
{"_dyld_get_image_name", (void *)hook_dyld_get_image_name, (void **)&orig_dyld_get_image_name},
},5);
}
22 changes: 22 additions & 0 deletions Tweaks/NSBundle+FixCydiaSubstrate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#import <Foundation/Foundation.h>
#import "Tweaks.h"
#import <objc/runtime.h>

@implementation NSString(LiveContainer)
- (NSString *)lc_realpath {
// stringByResolvingSymlinksInPath does not fully resolve symlink, and some apps will cradh without /private prefix
char result[PATH_MAX];
realpath(self.fileSystemRepresentation, result);
return [NSString stringWithUTF8String:result];
}
@end
@implementation NSBundle(LiveContainer)
// Built-in initWith* will strip out the /private prefix, which could crash certain apps
// This initializer replicates +[NSBundle mainBundle] to solve this issue (FIXME: may not work)
- (instancetype)initWithPathForMainBundle:(NSString *)path {
self = [self init];
CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:path.lc_realpath];
object_setIvar(self, class_getInstanceVariable(self.class, "_cfBundle"), CFBridgingRelease(CFBundleCreate(NULL, url)));
return self;
}
@end
File renamed without changes.
2 changes: 1 addition & 1 deletion SecItem.m → Tweaks/SecItem.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#import <Security/Security.h>
#import "utils.h"
#import <CommonCrypto/CommonDigest.h>
#import "fishhook/fishhook.h"
#import "../fishhook/fishhook.h"

extern void* (*msHookFunction)(void *symbol, void *hook, void **old);
OSStatus (*orig_SecItemAdd)(CFDictionaryRef attributes, CFTypeRef *result);
Expand Down
21 changes: 21 additions & 0 deletions Tweaks/Tweaks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Tweaks.h
// LiveContainer
//
// Created by s s on 2025/2/7.
//

void swizzle(Class class, SEL originalAction, SEL swizzledAction);


void NUDGuestHooksInit(void);
void SecItemGuestHooksInit(void);
void DyldHooksInit(void);

@interface NSBundle(LiveContainer)
- (instancetype)initWithPathForMainBundle:(NSString *)path;
@end


extern uint32_t appMainImageIndex;
extern void* appExecutableHandle;
4 changes: 2 additions & 2 deletions ZSign/macho.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,6 @@ bool is_64bit_macho(const char *filepath) {
fread(&magic, sizeof(uint32_t), 1, file);
fclose(file);

// 64-bit Mach-O magic number is 0xfeedfacf
return magic == 0xfeedfacf;
// check 64-bit Mach-O magic number
return magic == MH_MAGIC_64 || magic == FAT_CIGAM;
}
2 changes: 1 addition & 1 deletion control
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: com.kdt.livecontainer
Name: livecontainer
Version: 3.2.55
Version: 3.2.56
Architecture: iphoneos-arm
Description: Run iOS app without actually installing it!
Maintainer: khanhduytran0
Expand Down
Loading

0 comments on commit 9146b83

Please sign in to comment.