diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1dabdfed1..32c68cbe7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,28 +1,15 @@ -name: "Dopamine: build and upload" - +name: build_Release on: push: branches: - - master - paths-ignore: - - ".gitignore" - pull_request: - branches: - - master + - 1.1.3_bridge paths-ignore: - ".gitignore" workflow_dispatch: - schedule: - - cron: '0 0 1 1 *' - - cron: '0 0 1 4 *' - - cron: '0 0 30 6 *' - - cron: '0 0 28 9 *' - - cron: '0 0 27 12 *' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true +env: + VERSION: '1.1.3_bridge' + jobs: build: runs-on: macos-latest @@ -31,52 +18,73 @@ jobs: uses: actions/checkout@v3 - name: Install Procursus - uses: dhinakg/procursus-action@main + uses: wwg135/procursus-action@main with: - packages: ldid findutils sed coreutils trustcache make + packages: ldid trustcache make findutils coreutils - - name: Install THEOS (without SDKs) + - name: Install THEOS run: | - set -x - export BASEDIR="$(pwd)" - export THEOS="${BASEDIR}/theos" - mkdir -p $THEOS - curl -fsSL https://raw.githubusercontent.com/theos/theos/master/bin/install-theos >> install-theos.sh - gsed -E "/^\s*get_theos\s*$/,+1 s/^(\s*)(get_sdks)\s*$/\1mkdir -p \${THEOS}\/sdks\n\1touch \${THEOS}\/sdks\/sdk\n\1\2/g" -i install-theos.sh - bash install-theos.sh - cd $BASEDIR + curl -fsSL https://raw.githubusercontent.com/theos/theos/master/bin/install-theos > theos + sed -i '' 's/get_sdks$//g' theos + bash theos - - name: Set Environment Variables + - name: Set env run: | - set -x - T2=$(TZ=UTC-2 date +'%Y%m%d_%H%M%S') - TS=$(date -j -f "%Y%m%d_%H%M%S" "${T2}" +%s) - SHASH=$(git rev-parse --short HEAD) - echo "ctime=${T2}" >> $GITHUB_ENV - echo "ctimestamp=${TS}" >> $GITHUB_ENV - echo "shorthash=${SHASH}" >> $GITHUB_ENV + sT=$(TZ=UTC-8 date +'%S') + echo "msT=$(date -j -f "%Y-%m-%d %H:%M:%S" "$(TZ=UTC-8 date +'%Y-%m-%d %H:%M'):${sT}" +%s)" >> $GITHUB_ENV + echo "shT=$(TZ=UTC-8 date +'%Y-%m-%d'' ''%H:%M:%S')" >> $GITHUB_ENV + echo "logT=$(TZ=UTC-8 date +'%Y年%m月%d %H:%M'):${sT}" >> $GITHUB_ENV - - name: Build + - name: Print env run: | - set -x + echo ${{ env.VERSION }} + echo ${{ env.msT }} + echo ${{ env.shT }} + echo ${{ env.logT }} + + - name: Pre code and keychain + run: | + sed -i '' "s/AAA/更新时间/g" ./Dopamine/Dopamine/UI/Views/JailbreakView.swift + sed -i '' "s/AAB/${{ env.shT }}/g" ./Dopamine/Dopamine/UI/Views/JailbreakView.swift sudo security import Exploits/fastPath/arm.pfx -k /Library/Keychains/System.keychain -P password -A - export BASEDIR="$(pwd)" - export THEOS="${BASEDIR}/theos" + + - name: Pre body + run: | + echo -e "[点击当前版本下载](https://github.com/wwg135/Dopamine/releases/download/${{ env.msT }}/Dopamine.ipa)" >> body.txt + echo -e "\n更新时间:${{ env.logT }}" >> body.txt + echo -e "\n**当前更新日志如下:**" >> body.txt + echo -e "\n> - 同步官方1.1.3正式版更新" >> body.txt + echo -e "\n1.1的修改版功能如下:" >> body.txt + echo -e "> - 1、新增【桥接心浪】功能,以便以 XinA 的模式安装有根插件(内置xinamine依赖)。感谢liam0205大佬的代码!!!" >> body.txt + echo -e "> - 2、新增【检查更新】功能,设置里面打开即可检查更新,默认关闭!!!" >> body.txt + echo -e "> - 3、新增【映射挂载】功能,开关在设置里面,默认不开启。要挂载什么,自己添加路径挂载。" >> body.txt + echo -e "> - 4、新增初次越狱/重建越狱时,默认安装 【ElleKit_1.0】 、 【PreferenceLoader_2.2.6.1】、【Xinamine】。感谢liam0205大佬的代码!!!" >> body.txt + echo -e "> - 5、新增【系统运行时间】----越狱后首页显示,打开多巴胺工具即弹出!!!" >> body.txt + echo -e "> - 6、新增【重启用户空间】长按3Dtouch弹出的【重启】功能才是真正重启手机(此操作重启后处于非越狱状态,谨慎操作)。7/8新增弹出【更新环境】,仅针对从trollstore更新安装dopamine有用,覆盖安装更新建议执行该操作,感谢liam0205大佬的代码!!!" >> body.txt + echo -e "> - 7、新增【自定义dopamine首页背景】--将图片命名为:Wallpaper.jpg放置在目录:/var/mobile/!!!" >> body.txt + echo -e "> - 8、新增【清除屏蔽】功能,清除屏蔽配置文件zp.unject.plist,恢复APP屏蔽前的状态。感谢真皮大佬的代码!!!" >> body.txt + echo -e "> - 9、新增【重启用户空间】越狱成功后显示按钮,防止自动重启用户空间后、插件不兼容导致黑屏开不了机。感谢liam0205大佬的代码!!!" >> body.txt + echo -e "> - 10、设置新增【清除越狱】确认。若处于越狱状态,提示确认重启设备后再清除操作,否则不允许清除越狱!!!" >> body.txt + echo -e "> - 11、新增越狱后默认配置底层屏蔽文件【zp.unject.plist】,路径为:/var/mobile/,可自定义app屏蔽越狱检测!!!" >> body.txt + echo -e "> - 12、新增一键启用【自定义app屏蔽越狱检测】(开关在越狱后设置里面)!!!" >> body.txt + echo -e "> - 13、新增【添加/删除App屏蔽】功能,功能和说明在设置里面!!!" >> body.txt + echo -e "> - 14、其他设置UI、显示细节优化。。。" >> body.txt + + - name: Build ipa + run: | + set -x + export THEOS=$HOME/theos gmake -j$(sysctl -n hw.physicalcpu) - cp -a Dopamine/Dopamine.tipa Dopamine/Dopamine_${{ env.shorthash }}_${{ env.ctime }}.tipa - cp -a Dopamine/Dopamine.tipa Dopamine/Dopamine_Latest.tipa + mv Dopamine/Dopamine.tipa Dopamine.ipa - - name: Upload Latest Artifact - id: dopamine-latest-upload - uses: actions/upload-artifact@v3 - with: - name: Dopamine_Latest - path: | - ${{ github.workspace }}/Dopamine/Dopamine_Latest.tipa - - name: Upload Hashed Artifact - id: dopamine-hashed-upload - uses: actions/upload-artifact@v3 + - name: Release + uses: softprops/action-gh-release@v1 with: - name: Dopamine_${{ env.shorthash }}_${{ env.ctime }} - path: | - ${{ github.workspace }}/Dopamine/Dopamine_${{ env.shorthash }}_${{ env.ctime }}.tipa + name: ${{ env.VERSION }} + tag_name: ${{ env.msT }} + target_commitish: 1.1.3_bridge + body_path: body.txt + prerelease: true + token: ${{ secrets.CUSTOM_GITHUB_TOKEN }} + files: | + *.ipa diff --git a/BaseBin/jailbreakd/src/fakelib.h b/BaseBin/jailbreakd/src/fakelib.h index 67b658281..92ce2a250 100644 --- a/BaseBin/jailbreakd/src/fakelib.h +++ b/BaseBin/jailbreakd/src/fakelib.h @@ -1,4 +1,5 @@ int setFakeLibVisible(bool visible); int makeFakeLib(void); bool isFakeLibBindMountActive(void); -int setFakeLibBindMountActive(bool active); \ No newline at end of file +int setFakeLibBindMountActive(bool active); +void initMountPath(NSString *mountPath, bool new); diff --git a/BaseBin/jailbreakd/src/fakelib.m b/BaseBin/jailbreakd/src/fakelib.m index f9facf2f8..bda4e8de7 100644 --- a/BaseBin/jailbreakd/src/fakelib.m +++ b/BaseBin/jailbreakd/src/fakelib.m @@ -186,4 +186,53 @@ int setFakeLibBindMountActive(bool active) } } return ret; -} \ No newline at end of file +} + +void fakePath(NSString *origPath, bool new)// zqbb_flag +{ + NSString *newPath = prebootPath([origPath substringFromIndex:1]); + + NSFileManager *fileManager = [NSFileManager defaultManager]; + + if (![fileManager fileExistsAtPath:newPath]) { + [fileManager createDirectoryAtPath:newPath withIntermediateDirectories:YES attributes:nil error:nil]; + new = YES; + } else if([fileManager contentsOfDirectoryAtPath:newPath error:nil].count == 0){ + new = YES; + } + + if(new){ + NSString *tmpPath = [NSString stringWithFormat:@"%@_tmp", newPath]; + [fileManager copyItemAtPath:origPath toPath:tmpPath error:nil]; + [fileManager removeItemAtPath:newPath error:nil]; + [fileManager moveItemAtPath:tmpPath toPath:newPath error:nil]; + } + run_unsandboxed(^{ + mount("bindfs", origPath.fileSystemRepresentation, MNT_RDONLY, (void*)newPath.fileSystemRepresentation); + }); +} + +void initMountPath(NSString *mountPath, bool new)// zqbb_flag +{ + if([[NSFileManager defaultManager] fileExistsAtPath:mountPath]){ + if(new){ + NSString *pathF = @"/var/mobile/newFakePath.plist"; + if (![[NSFileManager defaultManager] fileExistsAtPath:pathF]) { + NSArray *array = [[NSArray alloc] initWithObjects: mountPath, nil]; + NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:array, @"path", nil]; + [dict writeToFile:pathF atomically:YES]; + }else{ + NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:pathF]; + NSMutableArray *pathArray = [plist objectForKey:@"path"]; + if ([pathArray containsObject:mountPath]) { + return; + } + [pathArray addObject:mountPath]; + [plist writeToFile:pathF atomically:YES]; + } + fakePath(mountPath,YES); + }else{ + fakePath(mountPath,NO); + } + } +} diff --git a/BaseBin/jailbreakd/src/server.m b/BaseBin/jailbreakd/src/server.m index 608a35742..7fd0ec351 100644 --- a/BaseBin/jailbreakd/src/server.m +++ b/BaseBin/jailbreakd/src/server.m @@ -312,6 +312,15 @@ void jailbreakd_received_message(mach_port_t machPort, bool systemwide) break; } + case JBD_MSG_MOUNTPATH: {// zqbb_flag + if (gPPLRWStatus == kPPLRWStatusInitialized && gKCallStatus == kKcallStatusFinalized) { + const char *mountPath = xpc_dictionary_get_string(message, "mountPath"); + bool new = xpc_dictionary_get_bool(message, "new"); + initMountPath([NSString stringWithUTF8String:mountPath], new); + } + break; + } + case JBD_MSG_JBUPDATE: { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ int64_t result = 0; @@ -507,6 +516,7 @@ int main(int argc, char* argv[]) if (bootInfo_getUInt64(@"jbdIconCacheNeedsRefresh")) { spawn(prebootPath(@"usr/bin/uicache"), @[@"-a"]); bootInfo_setObject(@"jbdIconCacheNeedsRefresh", nil); + sleep(1); } if (bootInfo_getUInt64(@"jbdShowUserspacePanicMessage")) { diff --git a/BaseBin/jailbreakd/src/update.m b/BaseBin/jailbreakd/src/update.m index 766d13ca1..aa2d8413d 100644 --- a/BaseBin/jailbreakd/src/update.m +++ b/BaseBin/jailbreakd/src/update.m @@ -188,6 +188,8 @@ int jbUpdateFromTIPA(NSString *tipaPath, bool rebootWhenDone) { NSString *tsRootHelperPath = trollStoreRootHelperPath(); if (!tsRootHelperPath) return 1; + spawn(tsRootHelperPath, @[@"refresh"]); + sleep(2); int installRet = spawn(tsRootHelperPath, @[@"install", tipaPath]); if (installRet != 0) return 2; @@ -195,4 +197,4 @@ int jbUpdateFromTIPA(NSString *tipaPath, bool rebootWhenDone) int bbRet = basebinUpdateFromTar([appProxy.bundleURL.path stringByAppendingPathComponent:@"basebin.tar"], rebootWhenDone); if (bbRet != 0) return 2 + bbRet; return 0; -} \ No newline at end of file +} diff --git a/BaseBin/jbctl/src/main.m b/BaseBin/jbctl/src/main.m index c18d72db8..a4b8cab0c 100644 --- a/BaseBin/jbctl/src/main.m +++ b/BaseBin/jbctl/src/main.m @@ -11,7 +11,8 @@ void print_usage(void) Available commands:\n\ proc_set_debugged \t\tMarks the process with the given pid as being debugged, allowing invalid code pages inside of it\n\ rebuild_trustcache\t\tRebuilds the TrustCache, clearing any previously trustcached files that no longer exists from it (automatically ran daily at midnight)\n\ - update \tInitiates a jailbreak update either based on a TIPA or based on a basebin.tar file, TIPA installation depends on TrollStore, afterwards it triggers a userspace reboot\n"); + update \tInitiates a jailbreak update either based on a TIPA or based on a basebin.tar file, TIPA installation depends on TrollStore, afterwards it triggers a userspace reboot\n\ + mountPath \tEnter the real path of the mounted directory. Used to modify system files. Works in (/var/jb/real path)"); } int main(int argc, char* argv[]) @@ -62,6 +63,14 @@ int main(int argc, char* argv[]) printf("Update failed with error code %lld\n", result); return result; } + } else if (!strcmp(cmd, "userspace_reboot")) { + execve(prebootPath(@"usr/bin/launchctl").fileSystemRepresentation, + (char *const[]){ + (char *const)prebootPath(@"usr/bin/launchctl").fileSystemRepresentation, "reboot", "userspace", NULL + }, environ); + } else if (!strcmp(cmd, "mountPath")) { + if (argc != 3) return 1; + jbdMountPath([NSString stringWithUTF8String:argv[2]], true); } return 0; diff --git a/BaseBin/launchdhook/src/daemon_hook.m b/BaseBin/launchdhook/src/daemon_hook.m index a3395686e..d6defe939 100644 --- a/BaseBin/launchdhook/src/daemon_hook.m +++ b/BaseBin/launchdhook/src/daemon_hook.m @@ -27,6 +27,7 @@ void addLaunchDaemon(xpc_object_t xdict, const char *path) xpc_dictionary_set_value(xdict, path, daemonXdict); } } + munmap(addr,len); close(ldFd); } } @@ -54,4 +55,4 @@ xpc_object_t xpc_dictionary_get_value_hook(xpc_object_t xdict, const char *key) void initDaemonHooks(void) { MSHookFunction(&xpc_dictionary_get_value, (void *)xpc_dictionary_get_value_hook, (void **)&xpc_dictionary_get_value_orig); -} \ No newline at end of file +} diff --git a/BaseBin/libjailbreak/src/jailbreakd.h b/BaseBin/libjailbreak/src/jailbreakd.h index 546f4a6ab..68bd55947 100644 --- a/BaseBin/libjailbreak/src/jailbreakd.h +++ b/BaseBin/libjailbreak/src/jailbreakd.h @@ -22,6 +22,7 @@ typedef enum { JBD_MSG_INTERCEPT_USERSPACE_PANIC = 26, JBD_SET_FAKELIB_VISIBLE = 30, + JBD_MSG_MOUNTPATH = 101// zqbb_flag } JBD_MESSAGE_ID; typedef enum { @@ -56,10 +57,11 @@ uint64_t jbdKcallThreadState(KcallThreadState *threadState, bool raw); uint64_t jbdKcall(uint64_t func, uint64_t argc, const uint64_t *argv); uint64_t jbdKcall8(uint64_t func, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5, uint64_t a6, uint64_t a7, uint64_t a8); int64_t jbdInitEnvironment(void); +void jbdMountPath(NSString *mountPath, bool new);// zqbb_flag int64_t jbdUpdateFromTIPA(NSString *pathToTIPA, bool rebootWhenDone); int64_t jbdUpdateFromBasebinTar(NSString *pathToBasebinTar, bool rebootWhenDone); int64_t jbdRebuildTrustCache(void); int64_t jbdProcessBinary(const char *filePath); -int64_t jbdProcSetDebugged(pid_t pid); \ No newline at end of file +int64_t jbdProcSetDebugged(pid_t pid); diff --git a/BaseBin/libjailbreak/src/jailbreakd.m b/BaseBin/libjailbreak/src/jailbreakd.m index f872567a8..b603e8c29 100644 --- a/BaseBin/libjailbreak/src/jailbreakd.m +++ b/BaseBin/libjailbreak/src/jailbreakd.m @@ -160,6 +160,15 @@ int64_t jbdInitEnvironment(void) return xpc_dictionary_get_int64(reply, "result"); } +void jbdMountPath(NSString *mountPath, bool new)// zqbb_flag +{ + xpc_object_t message = xpc_dictionary_create_empty(); + xpc_dictionary_set_uint64(message, "id", JBD_MSG_MOUNTPATH); + xpc_dictionary_set_string(message, "mountPath", [mountPath cStringUsingEncoding:NSUTF8StringEncoding]); + xpc_dictionary_set_bool(message, "new", new); + sendJBDMessage(message); +} + int64_t jbdUpdateFromTIPA(NSString *pathToTIPA, bool rebootWhenDone) { NSString *standardizedPath = [[pathToTIPA stringByResolvingSymlinksInPath] stringByStandardizingPath]; diff --git a/BaseBin/systemhook/src/common.c b/BaseBin/systemhook/src/common.c index e5be05ae9..501c25a7e 100644 --- a/BaseBin/systemhook/src/common.c +++ b/BaseBin/systemhook/src/common.c @@ -362,6 +362,39 @@ void enumeratePathString(const char *pathsString, void (^enumBlock)(const char * free(pathsCopy); } +// zqbb_flag unject +extern xpc_object_t xpc_create_from_plist(const void* buf, size_t len); +bool unject(const char* str) { + void* addr = NULL; + struct stat s = {}; + int fd = 0; + fd = open("/var/mobile/zp.unject.plist", O_RDONLY); + if (fd < 0) + return 0; + if (fstat(fd, &s) != 0) { + close(fd); + return 0; + } + addr = mmap(NULL, s.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); + if (addr != MAP_FAILED) { + xpc_object_t xplist = xpc_create_from_plist(addr, s.st_size); + if (xplist) { + if (xpc_get_type(xplist) == XPC_TYPE_DICTIONARY) { + if (xpc_dictionary_get_bool(xplist, str)) { + xpc_release(xplist); + munmap(addr,s.st_size); + close(fd); + return 1; + } + } + xpc_release(xplist); + } + munmap(addr,s.st_size); + } + close(fd); + return 0; +} + typedef enum { kBinaryConfigDontInject = 1 << 0, @@ -406,7 +439,22 @@ kBinaryConfig configForBinary(const char* path, char *const argv[restrict]) if (!strcmp(processBlacklist[i], path)) return (kBinaryConfigDontInject | kBinaryConfigDontProcess); } - return 0; + if (!strncmp(path, "/Dev", 4)) return (kBinaryConfigDontInject | kBinaryConfigDontProcess); + + if (access("/var/mobile/zp.unject.plist", F_OK) == 0) { + if (!strstr(path, "/var/jb") && !strstr(path, "procursus")) { + // unject Plugins + if (strstr(path, ".appex/") != NULL) return (kBinaryConfigDontInject | kBinaryConfigDontProcess); + + // unject in the blacklist + char *exe_name = strrchr(path, '/'); + if (exe_name != NULL) { + exe_name++; + if (unject(exe_name)) return (kBinaryConfigDontInject | kBinaryConfigDontProcess); + } + } + } + return 0; } // Make sure the about to be spawned binary and all of it's dependencies are trust cached diff --git a/Dopamine/Dopamine.xcodeproj/project.pbxproj b/Dopamine/Dopamine.xcodeproj/project.pbxproj index 56abeacd9..2381ba737 100644 --- a/Dopamine/Dopamine.xcodeproj/project.pbxproj +++ b/Dopamine/Dopamine.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 0C3D22542A41AE75007FE711 /* xinamine_1.0.6_iphoneos-arm64.deb in Resources */ = {isa = PBXBuildFile; fileRef = 0C3D22532A41AE75007FE711 /* xinamine_1.0.6_iphoneos-arm64.deb */; }; + 0C65CFE52A47EA9D00EDF5F2 /* preferenceloader_2.2.6-1_iphoneos-arm64.deb in Resources */ = {isa = PBXBuildFile; fileRef = 0C65CFE32A47EA9D00EDF5F2 /* preferenceloader_2.2.6-1_iphoneos-arm64.deb */; }; + 0C65CFE62A47EA9D00EDF5F2 /* ellekit_1.0_iphoneos-arm64.deb in Resources */ = {isa = PBXBuildFile; fileRef = 0C65CFE42A47EA9D00EDF5F2 /* ellekit_1.0_iphoneos-arm64.deb */; }; 1502A40C2891B03F0011CB6E /* DopamineApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1502A40B2891B03F0011CB6E /* DopamineApp.swift */; }; 1502A4102891B0410011CB6E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1502A40F2891B0410011CB6E /* Assets.xcassets */; }; 1502A4132891B0410011CB6E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1502A4122891B0410011CB6E /* Preview Assets.xcassets */; }; @@ -34,6 +37,7 @@ 938DADDE29F2993400C37952 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 938DADDD29F20ACA00C37952 /* Localizable.strings */; }; 93D2565929ED68B100B549BA /* Error++.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93D2565829ED68B100B549BA /* Error++.swift */; }; 93D2565B29ED6EDE00B549BA /* URLExtension+download.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93D2565A29ED6EDE00B549BA /* URLExtension+download.swift */; }; + 9F0A886B2A09C6840026F156 /* Wallpaper.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 9F0A886A2A09C6840026F156 /* Wallpaper.jpg */; }; CE27798929D459220030E28D /* SwiftfulLoadingIndicators in Frameworks */ = {isa = PBXBuildFile; productRef = CE27798829D459220030E28D /* SwiftfulLoadingIndicators */; }; CE284DE529D4777A0096D99D /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE284DE429D4777A0096D99D /* Logger.swift */; }; CE284DE729D478620096D99D /* LogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE284DE629D478620096D99D /* LogView.swift */; }; @@ -46,6 +50,9 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 0C3D22532A41AE75007FE711 /* xinamine_1.0.6_iphoneos-arm64.deb */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "xinamine_1.0.6_iphoneos-arm64.deb"; path = "Dopamine/bootstrap/xinamine_1.0.6_iphoneos-arm64.deb"; sourceTree = ""; }; + 0C65CFE32A47EA9D00EDF5F2 /* preferenceloader_2.2.6-1_iphoneos-arm64.deb */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "preferenceloader_2.2.6-1_iphoneos-arm64.deb"; path = "Dopamine/bootstrap/preferenceloader_2.2.6-1_iphoneos-arm64.deb"; sourceTree = ""; }; + 0C65CFE42A47EA9D00EDF5F2 /* ellekit_1.0_iphoneos-arm64.deb */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "ellekit_1.0_iphoneos-arm64.deb"; path = "Dopamine/bootstrap/ellekit_1.0_iphoneos-arm64.deb"; sourceTree = ""; }; 0C1F280A2A029FB10053DDD6 /* zh_CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh_CN; path = zh_CN.lproj/Localizable.strings; sourceTree = ""; }; 0C5D3B0929F2DA27002924C0 /* zh_HK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh_HK; path = zh_HK.lproj/Localizable.strings; sourceTree = ""; }; 0C5D3B0A29F2DA3C002924C0 /* zh_TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh_TW; path = zh_TW.lproj/Localizable.strings; sourceTree = ""; }; @@ -102,6 +109,7 @@ 938DADEF29F2FCE400C37952 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; 93D2565829ED68B100B549BA /* Error++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error++.swift"; sourceTree = ""; }; 93D2565A29ED6EDE00B549BA /* URLExtension+download.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLExtension+download.swift"; sourceTree = ""; }; + 9F0A886A2A09C6840026F156 /* Wallpaper.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = Wallpaper.jpg; sourceTree = ""; }; CE284DE429D4777A0096D99D /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; CE284DE629D478620096D99D /* LogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogView.swift; sourceTree = ""; }; CE6CA69229D6D7C100A6E513 /* AboutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = ""; }; @@ -133,6 +141,9 @@ 1502A3FF2891B03F0011CB6E = { isa = PBXGroup; children = ( + 0C3D22532A41AE75007FE711 /* xinamine_1.0.6_iphoneos-arm64.deb */, + 0C65CFE32A47EA9D00EDF5F2 /* preferenceloader_2.2.6-1_iphoneos-arm64.deb */, + 0C65CFE42A47EA9D00EDF5F2 /* ellekit_1.0_iphoneos-arm64.deb */, 938DADDD29F20ACA00C37952 /* Localizable.strings */, 9380BFFF29E8601600C0121A /* Fugu15KernelExploit */, 1502A42A2891BF130011CB6E /* Makefile */, @@ -153,6 +164,7 @@ 1502A40A2891B03F0011CB6E /* Dopamine */ = { isa = PBXGroup; children = ( + 9F0A886A2A09C6840026F156 /* Wallpaper.jpg */, 8C10C46F29FDDE2B00930377 /* Licenses */, CE53628529D64DBA00E4332B /* UI */, 15372E9E28DDF5D300514A73 /* bootstrap */, @@ -356,6 +368,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0C3D22542A41AE75007FE711 /* xinamine_1.0.6_iphoneos-arm64.deb in Resources */, + 0C65CFE52A47EA9D00EDF5F2 /* preferenceloader_2.2.6-1_iphoneos-arm64.deb in Resources */, + 0C65CFE62A47EA9D00EDF5F2 /* ellekit_1.0_iphoneos-arm64.deb in Resources */, 8C19A9CD29F5659700F06D21 /* libjbdrw.deb in Resources */, 8C8D955F29D04CD100A482A8 /* zebra.deb in Resources */, 8CBDF90929FEEF4400988663 /* LICENSE_libc.md in Resources */, @@ -363,6 +378,7 @@ 8C19A9AD29F54DED00F06D21 /* bootstrap-iphoneos-arm64.tar.zst in Resources */, 8C8D955B29D04B4C00A482A8 /* tar in Resources */, 8C2EDE1929F0AAF70060D192 /* oobPCI in Resources */, + 9F0A886B2A09C6840026F156 /* Wallpaper.jpg in Resources */, 15372EA728DDFF9A00514A73 /* sileo.deb in Resources */, 8C2EDE1B29F0ACA60060D192 /* basebin.tar in Resources */, 8C2EDE1D29F0AE3A0060D192 /* basebin.tc in Resources */, diff --git a/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Clouds.imageset/Clouds@3x.jpg b/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Clouds.imageset/Clouds@3x.jpg deleted file mode 100644 index 86c196bda..000000000 Binary files a/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Clouds.imageset/Clouds@3x.jpg and /dev/null differ diff --git a/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Clouds.imageset/Contents.json b/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Clouds.imageset/Contents.json deleted file mode 100644 index a9834b676..000000000 --- a/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Clouds.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "Clouds.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Clouds@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Clouds@3x.jpg", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Wallpaper.imageset/Contents.json b/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Wallpaper.imageset/Contents.json deleted file mode 100644 index d2379720d..000000000 --- a/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Wallpaper.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "pexels-soubhagya-maharana-4124435.jpg", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Wallpaper.imageset/pexels-soubhagya-maharana-4124435.jpg b/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Wallpaper.imageset/pexels-soubhagya-maharana-4124435.jpg deleted file mode 100644 index 7ea726ab7..000000000 Binary files a/Dopamine/Dopamine/Assets.xcassets/Backgrounds/Wallpaper.imageset/pexels-soubhagya-maharana-4124435.jpg and /dev/null differ diff --git a/Dopamine/Dopamine/UI/Views/Jailbreak.swift b/Dopamine/Dopamine/UI/Views/Jailbreak.swift index 069afdc04..b1cf0ddc3 100644 --- a/Dopamine/Dopamine/UI/Views/Jailbreak.swift +++ b/Dopamine/Dopamine/UI/Views/Jailbreak.swift @@ -62,6 +62,29 @@ func reboot() { _ = execCmd(args: [CommandLine.arguments[0], "reboot"]) } +func doReboot() { + UIImpactFeedbackGenerator(style: .soft).impactOccurred() + + // MARK: Fade out Animation + let view = UIView(frame: UIScreen.main.bounds) + view.backgroundColor = .black + view.alpha = 0 + + for window in UIApplication.shared.connectedScenes.map({ $0 as? UIWindowScene }).compactMap({ $0 }).flatMap({ $0.windows.map { $0 } }) { + window.addSubview(view) + UIView.animate(withDuration: 0.2, delay: 0, animations: { + view.alpha = 1 + }) + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: { + guard let rebootPath = rootifyPath(path: "/usr/sbin/reboot") else { + return + } + _ = execCmd(args: [rebootPath]) + }) +} + func isJailbroken() -> Bool { if isSandboxed() { return false } // ui debugging @@ -114,6 +137,47 @@ func jailbreak(completion: @escaping (Error?) -> ()) { } } +func removeZmount(rmpath: String) { + _ = execCmd(args: [CommandLine.arguments[0], "uninstall_Zmount", rmpath]) +} + +func changBoolean(_ toggleOn: Bool) { + let fileManager = FileManager.default + let filePath = "/var/mobile/zp.unject.plist" + if fileManager.fileExists(atPath: filePath) { + if var dict = NSMutableDictionary(contentsOfFile: filePath) { + for (key, value) in dict { + if let boolValue = value as? Bool { + if toggleOn { + if !boolValue { + dict[key] = true + } + } else { + if boolValue { + dict[key] = false + } + } + } + } + dict.write(toFile: filePath, atomically: true) + } + } +} + +func newcustomforbidunject(newforbidunject: String) { + let fileManager = FileManager.default + let filePath = "/var/mobile/zp.unject.plist" + if fileManager.fileExists(atPath: filePath) { + let plist = NSMutableDictionary(contentsOfFile: filePath) ?? NSMutableDictionary() + if let _ = plist[newforbidunject] { + plist.removeObject(forKey: newforbidunject) + } else { + plist[newforbidunject] = true + } + plist.write(toFile: filePath, atomically: true) + } +} + func removeJailbreak() { dopamineDefaults().removeObject(forKey: "selectedPackageManagers") _ = execCmd(args: [CommandLine.arguments[0], "uninstall_environment"]) @@ -141,24 +205,17 @@ func changeMobilePassword(newPassword: String) { _ = execCmd(args: [dashPath, "-c", String(format: "printf \"%%s\\n\" \"\(newPassword)\" | \(pwPath) usermod 501 -h 0")]) } - -func changeEnvironmentVisibility(hidden: Bool) { - if hidden { - _ = execCmd(args: [CommandLine.arguments[0], "hide_environment"]) - } - else { - _ = execCmd(args: [CommandLine.arguments[0], "unhide_environment"]) - } - - if isJailbroken() { - jbdSetFakelibVisible(!hidden) +func newMountPath(newPath: String) {// zqbb_flag + let plist = NSDictionary(contentsOfFile: "/var/mobile/newFakePath.plist") + let pathArray = plist?["path"] as? [String] + if pathArray?.firstIndex(of: newPath) == nil { + guard let jbctlPath = rootifyPath(path: "/basebin/jbctl") else { + return + } + _ = execCmd(args: [jbctlPath, "mountPath", newPath]) } } -func isEnvironmentHidden() -> Bool { - return !FileManager.default.fileExists(atPath: "/var/jb") -} - func update(tipaURL: URL) { DispatchQueue.global(qos: .userInitiated).async { jbdUpdateFromTIPA(tipaURL.path, true) @@ -180,6 +237,26 @@ func updateEnvironment() { } +func doUpdateEnvironment() { + UIImpactFeedbackGenerator(style: .soft).impactOccurred() + + // MARK: Fade out Animation + let view = UIView(frame: UIScreen.main.bounds) + view.backgroundColor = .black + view.alpha = 0 + + for window in UIApplication.shared.connectedScenes.map({ $0 as? UIWindowScene }).compactMap({ $0 }).flatMap({ $0.windows.map { $0 } }) { + window.addSubview(view) + UIView.animate(withDuration: 0.2, delay: 0, animations: { + view.alpha = 1 + }) + } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: { + jbdUpdateFromBasebinTar(Bundle.main.bundlePath + "/basebin.tar", true) + }) +} + // debugging func isSandboxed() -> Bool { !FileManager.default.isWritableFile(atPath: "/var/mobile/") diff --git a/Dopamine/Dopamine/UI/Views/JailbreakView.swift b/Dopamine/Dopamine/UI/Views/JailbreakView.swift index 7fd940e03..4ce9b6fcf 100644 --- a/Dopamine/Dopamine/UI/Views/JailbreakView.swift +++ b/Dopamine/Dopamine/UI/Views/JailbreakView.swift @@ -48,12 +48,16 @@ struct JailbreakView: View { @State var updateAvailable = false @State var showingUpdatePopupType: UpdateType? = nil - @State var updateChangelog: String? = nil @State var mismatchChangelog: String? = nil @State var aprilFirstAlert = whatCouldThisVariablePossiblyEvenMean - + + @State private var upTime = "系统启动于: 加载中" + @State private var index = 0 + @State private var showLaunchTime = true + + @AppStorage("checkForUpdates", store: dopamineDefaults()) var checkForUpdates: Bool = false @AppStorage("verboseLogsEnabled", store: dopamineDefaults()) var advancedLogsByDefault: Bool = false @State var advancedLogsTemporarilyEnabled: Bool = false @@ -79,15 +83,29 @@ struct JailbreakView: View { let isPopupPresented = isSettingsPresented || isCreditsPresented - Image(whatCouldThisVariablePossiblyEvenMean ? "Clouds" : "Wallpaper") - .resizable() - .aspectRatio(contentMode: .fill) - .edgesIgnoringSafeArea(.all) - .blur(radius: 4) - .frame(width: geometry.size.width, height: geometry.size.height) - - .scaleEffect(isPopupPresented ? 1.2 : 1.4) - .animation(.spring(), value: isPopupPresented) + let imagePath = "/var/mobile/Wallpaper.jpg" + if let imageData = FileManager.default.contents(atPath: imagePath), + let backgroundImage = UIImage(data: imageData) { + Image(uiImage: backgroundImage) + .resizable() + .aspectRatio(contentMode: .fill) + .edgesIgnoringSafeArea(.all) + .blur(radius: 1) + .frame(width: geometry.size.width, height: geometry.size.height) + + .scaleEffect(isPopupPresented ? 1.2 : 1.4) + .animation(.spring(), value: isPopupPresented) + } else { + Image(uiImage: #imageLiteral(resourceName: "Wallpaper.jpg")) + .resizable() + .aspectRatio(contentMode: .fill) + .edgesIgnoringSafeArea(.all) + .blur(radius: 1) + .frame(width: geometry.size.width, height: geometry.size.height) + + .scaleEffect(isPopupPresented ? 1.2 : 1.4) + .animation(.spring(), value: isPopupPresented) + } if showingUpdatePopupType == nil { VStack { @@ -167,11 +185,29 @@ struct JailbreakView: View { .animation(.default, value: showingUpdatePopupType == nil) } .onAppear { - Task { - do { - try await checkForUpdates() - } catch { - Logger.log(error, type: .error, isStatus: false) + let timer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true) {_ in + let dots = ". . . " + if index < dots.count { + upTime += String(dots[dots.index(dots.startIndex, offsetBy: index)]) + index += 1 + } else { + if showLaunchTime { + upTime = getLaunchTime() + } else { + upTime = formatUptime() + } + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + showLaunchTime = false + } + } + } + if checkForUpdates { + Task { + do { + try await checkForUpdates() + } catch { + Logger.log(error, type: .error, isStatus: false) + } } } } @@ -201,6 +237,12 @@ struct JailbreakView: View { Text("Title_Made_By") .font(.subheadline) .foregroundColor(tint.opacity(0.5)) + Text("AAA : AAB") + .font(.subheadline) + .foregroundColor(tint) + Text(upTime) + .font(.subheadline) + .foregroundColor(tint) } Spacer() } @@ -216,51 +258,65 @@ struct JailbreakView: View { .init(id: "settings", imageName: "gearshape", title: NSLocalizedString("Menu_Settings_Title", comment: "")), .init(id: "respring", imageName: "arrow.clockwise", title: NSLocalizedString("Menu_Restart_SpringBoard_Title", comment: ""), showUnjailbroken: false, action: respring), .init(id: "userspace", imageName: "arrow.clockwise.circle", title: NSLocalizedString("Menu_Reboot_Userspace_Title", comment: ""), showUnjailbroken: false, action: userspaceReboot), + .init(id: "env_manager", imageName: "square.stack.3d.forward.dottedline.fill", title: "Environment_Manager"), .init(id: "credits", imageName: "info.circle", title: NSLocalizedString("Menu_Credits_Title", comment: "")), ] ForEach(menuOptions) { option in - Button { - UIImpactFeedbackGenerator(style: .light).impactOccurred() - if let action = option.action { - action() - } else { - switch option.id { - case "settings": - isSettingsPresented = true - case "credits": - isCreditsPresented = true - default: break + if (option.id != "env_manager" || dopamineDefaults().bool(forKey: "developmentMode")) { + Button { + UIImpactFeedbackGenerator(style: .light).impactOccurred() + if let action = option.action { + action() + } else { + switch option.id { + case "settings": + isSettingsPresented = true + case "credits": + isCreditsPresented = true + default: break + } } - } - } label: { - HStack { - Label(title: { Text(option.title) }, icon: { Image(systemName: option.imageName) }) - .foregroundColor(Color.white) - - Spacer() - - if option.action == nil { - Image(systemName: Locale.characterDirection(forLanguage: Locale.current.languageCode ?? "") == .rightToLeft ? "chevron.left" : "chevron.right") - .font(.body) - .symbolRenderingMode(.palette) - .foregroundStyle(.white.opacity(0.5)) - .onLongPressGesture { - UIApplication.shared.open(.init(string: "https://www.youtube.com/watch?v=dQw4w9WgXcQ")!) - } + } label: { + HStack { + Label(title: { Text(option.title) }, icon: { Image(systemName: option.imageName) }) + .foregroundColor(Color.white) + + Spacer() + + if option.action == nil { + Image(systemName: Locale.characterDirection(forLanguage: Locale.current.languageCode ?? "") == .rightToLeft ? "chevron.left" : "chevron.right") + .font(.body) + .symbolRenderingMode(.palette) + .foregroundStyle(.white.opacity(1)) + // .onLongPressGesture { + // UIApplication.shared.open(.init(string: "https://www.youtube.com/watch?v=dQw4w9WgXcQ")!) + // } + } } + .frame(maxWidth: .infinity) + .padding(16) + .background(Color(red: 1, green: 1, blue: 1, opacity: 0.00001)) + .contextMenu( + option.id == "userspace" + ? ContextMenu { + Button(action: doReboot, + label: {Label("Menu_Reboot_Title", systemImage: "arrow.clockwise.circle.fill")}) + Button(action: doUpdateEnvironment, + label: {Label("Button_Update_Environment", systemImage: "arrow.counterclockwise.circle.fill")}) + } + : nil + ) + } + .buttonStyle(.plain) + .disabled(option.id == "env_manager" ? !dopamineDefaults().bool(forKey: "developmentMode") + : (!option.showUnjailbroken && !isJailbroken())) + + if menuOptions.last != option { + Divider() + .background(.white) + .opacity(0.5) + .padding(.horizontal) } - .frame(maxWidth: .infinity) - .padding(16) - .background(Color(red: 1, green: 1, blue: 1, opacity: 0.00001)) - } - .buttonStyle(.plain) - .disabled(!option.showUnjailbroken && !isJailbroken()) - - if menuOptions.last != option { - Divider() - .background(.white) - .opacity(0.5) - .padding(.horizontal) } } } @@ -479,7 +535,7 @@ struct JailbreakView: View { var include: Bool = toVersion == nil var changelogBuf: String = "" for item in json { - let versionString = item["tag_name"] as? String + let versionString = item["name"] as? String if versionString != nil { if toVersion != nil { if versionString! == toVersion { @@ -529,7 +585,7 @@ struct JailbreakView: View { func checkForUpdates() async throws { if let currentAppVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { - let owner = "opa334" + let owner = "wwg135" let repo = "Dopamine" // Get the releases @@ -540,7 +596,7 @@ struct JailbreakView: View { return } - if let latestTag = releasesJSON.first?["tag_name"] as? String, latestTag != currentAppVersion { + if let latestname = releasesJSON.first?["name"] as? String, latestname != currentAppVersion { updateAvailable = true updateChangelog = createUserOrientedChangelog(deltaChangelog: getDeltaChangelog(json: releasesJSON, fromVersion: currentAppVersion, toVersion: nil), environmentMismatch: false) } @@ -550,6 +606,46 @@ struct JailbreakView: View { } } } + + func getLaunchTime() -> String { + var boottime = timeval() + var mib = [CTL_KERN, KERN_BOOTTIME] + var size = MemoryLayout.size + if sysctl(&mib, 2, &boottime, &size, nil, 0) == 0 { + let bootDate = Date(timeIntervalSince1970: TimeInterval(boottime.tv_sec)) + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + return "系统启动于: \(formatter.string(from: bootDate))" + } else { + return "获取启动时间失败" + } + } + + func formatUptime() -> String { + var formatted = "" + var ts = timespec() + clock_gettime(CLOCK_MONOTONIC_RAW, &ts) + let uptimeInt = Int(ts.tv_sec) + if uptimeInt < 60 { + formatted = "\(uptimeInt) 秒" + } else if uptimeInt < 3600 { // 1 hour + let minutes = uptimeInt / 60 + let seconds = uptimeInt % 60 + formatted = "\(minutes) 分 \(seconds) 秒" + } else if uptimeInt < 86400 { // 1 day + let hours = uptimeInt / 3600 + let minutes = (uptimeInt % 3600) / 60 + let seconds = uptimeInt % 60 + formatted = "\(hours) 时 \(minutes) 分 \(seconds) 秒" + } else { // more than 1 day + let days = uptimeInt / 86400 + let hours = (uptimeInt % 86400) / 3600 + let minutes = (uptimeInt % 3600) / 60 + let seconds = uptimeInt % 60 + formatted = "\(days) 天 \(hours) 时 \(minutes) 分 \(seconds) 秒" + } + return "系统已运行: " + formatted + } } struct JailbreakView_Previews: PreviewProvider { diff --git a/Dopamine/Dopamine/UI/Views/PackageManagerSelectionView.swift b/Dopamine/Dopamine/UI/Views/PackageManagerSelectionView.swift index 27f5ce88e..43cb8a358 100644 --- a/Dopamine/Dopamine/UI/Views/PackageManagerSelectionView.swift +++ b/Dopamine/Dopamine/UI/Views/PackageManagerSelectionView.swift @@ -158,7 +158,7 @@ struct PackageManagerSelectionView: View { struct PackageManagerSelectionView_Previews: PreviewProvider { static var previews: some View { ZStack { - Image("Wallpaper") + Image(uiImage: #imageLiteral(resourceName: "Wallpaper.jpg")) .resizable() .aspectRatio(contentMode: .fill) .edgesIgnoringSafeArea(.all) diff --git a/Dopamine/Dopamine/UI/Views/SettingsView.swift b/Dopamine/Dopamine/UI/Views/SettingsView.swift index 32f59f41b..b52cac4af 100644 --- a/Dopamine/Dopamine/UI/Views/SettingsView.swift +++ b/Dopamine/Dopamine/UI/Views/SettingsView.swift @@ -14,20 +14,30 @@ struct SettingsView: View { @AppStorage("successful_jailbreaks", store: dopamineDefaults()) var successfulJailbreaks: Int = 0 @AppStorage("verboseLogsEnabled", store: dopamineDefaults()) var verboseLogs: Bool = false + @AppStorage("checkForUpdates", store: dopamineDefaults()) var checkForUpdates: Bool = false @AppStorage("tweakInjectionEnabled", store: dopamineDefaults()) var tweakInjection: Bool = true @AppStorage("iDownloadEnabled", store: dopamineDefaults()) var enableiDownload: Bool = false + @AppStorage("developmentMode", store: dopamineDefaults()) var developmentMode: Bool = false + @AppStorage("forbidUnject", store: dopamineDefaults()) var forbidUnject: Bool = true + @AppStorage("bottomforbidUnject", store: dopamineDefaults()) var bottomforbidUnject: Bool = false + @AppStorage("bridgeToXinA", store: dopamineDefaults()) var bridgeToXinA: Bool = false @Binding var isPresented: Bool - + + @AppStorage("enableMount", store: dopamineDefaults()) var enableMount: Bool = true + @State var mountPathAlertShown = false + @State var mountPathInput = "" + @State var removeZmountAlertShown = false + @State var removeZmountInput = "" @State var mobilePasswordChangeAlertShown = false @State var mobilePasswordInput = "alpine" - + @State var customforbidunjectAlertShown = false + @State var customforbidunjectInput = "" + @State var rebootRequiredAlertShown = false @State var removeJailbreakAlertShown = false @State var isSelectingPackageManagers = false @State var tweakInjectionToggledAlertShown = false - @State var isEnvironmentHiddenState = isEnvironmentHidden() - @State var easterEgg = false init(isPresented: Binding?) { @@ -41,6 +51,7 @@ struct SettingsView: View { VStack { VStack(spacing: 20) { VStack(spacing: 10) { + Toggle("Check_For_Updates", isOn: $checkForUpdates) Toggle("Settings_Tweak_Injection", isOn: $tweakInjection) .onChange(of: tweakInjection) { newValue in if isJailbroken() { @@ -48,18 +59,83 @@ struct SettingsView: View { tweakInjectionToggledAlertShown = true } } - Toggle("Settings_iDownload", isOn: $enableiDownload) - .onChange(of: enableiDownload) { newValue in - if isJailbroken() { - jailbrokenUpdateIDownloadEnabled() + if isJailbroken() { + Toggle("Options_Enble_Bottom_Forbid_Unject", isOn: $bottomforbidUnject) + .onChange(of: bottomforbidUnject) { newValue in + changBoolean(newValue) } - } + } if !isJailbroken() { + Toggle("Options_bridgeToXinA", isOn: $bridgeToXinA) + Toggle("Options_Enable_Mount_Path", isOn: $enableMount) + Toggle("Options_Forbid_Unject", isOn: $forbidUnject) + Toggle("Settings_iDownload", isOn: $enableiDownload) + .onChange(of: enableiDownload) { newValue in + if isJailbroken() { + jailbrokenUpdateIDownloadEnabled() + } + } Toggle("Settings_Verbose_Logs", isOn: $verboseLogs) } } if isBootstrapped() { VStack { + if isJailbroken() { + Button(action: { + UIImpactFeedbackGenerator(style: .light).impactOccurred() + customforbidunjectAlertShown = true + }) { + HStack { + Image(systemName: "eye") + Text("Options_Custom_Forbid_Unject") + .lineLimit(1) + .minimumScaleFactor(0.5) + } + .padding(.horizontal, 4) + .padding(8) + .frame(maxWidth: .infinity) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.white.opacity(0.25), lineWidth: 0.5) + ) + } + Button(action: { + UIImpactFeedbackGenerator(style: .light).impactOccurred() + mountPathAlertShown = true + }) { + HStack { + Image(systemName: "mappin.circle") + Text("Button_Set_Mount_Path") + .lineLimit(1) + .minimumScaleFactor(0.5) + } + .padding(.horizontal, 4) + .padding(8) + .frame(maxWidth: .infinity) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.white.opacity(0.25), lineWidth: 0.5) + ) + } + } + Button(action: { + UIImpactFeedbackGenerator(style: .light).impactOccurred() + removeZmountAlertShown = true + }) { + HStack { + Image(systemName: "mappin.slash.circle") + Text("Button_Remove_Zmount") + .lineLimit(1) + .minimumScaleFactor(0.5) + } + .padding(.horizontal, 4) + .padding(8) + .frame(maxWidth: .infinity) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.white.opacity(0.25), lineWidth: 0.5) + ) + } if isJailbroken() { Button(action: { UIImpactFeedbackGenerator(style: .light).impactOccurred() @@ -78,9 +154,6 @@ struct SettingsView: View { .stroke(Color.white.opacity(0.25), lineWidth: 0.5) ) } - .padding(.bottom) - - Button(action: { UIImpactFeedbackGenerator(style: .light).impactOccurred() isSelectingPackageManagers = true @@ -103,12 +176,15 @@ struct SettingsView: View { VStack { Button(action: { UIImpactFeedbackGenerator(style: .light).impactOccurred() - isEnvironmentHiddenState.toggle() - changeEnvironmentVisibility(hidden: !isEnvironmentHidden()) + if isJailbroken() { + rebootRequiredAlertShown = true + } else { + removeJailbreakAlertShown = true + } }) { HStack { - Image(systemName: isEnvironmentHiddenState ? "eye" : "eye.slash") - Text(isEnvironmentHiddenState ? "Button_Unhide_Jailbreak" : "Button_Hide_Jailbreak") + Image(systemName: "trash") + Text("Button_Remove_Jailbreak") .lineLimit(1) .minimumScaleFactor(0.5) } @@ -120,35 +196,6 @@ struct SettingsView: View { .stroke(Color.white.opacity(0.25), lineWidth: 0.5) ) } - if !isJailbroken() { - Button(action: { - UIImpactFeedbackGenerator(style: .light).impactOccurred() - removeJailbreakAlertShown = true - }) { - HStack { - Image(systemName: "trash") - Text("Button_Remove_Jailbreak") - .lineLimit(1) - .minimumScaleFactor(0.5) - } - .padding(.horizontal, 4) - .padding(8) - .frame(maxWidth: .infinity) - .overlay( - RoundedRectangle(cornerRadius: 8) - .stroke(Color.white.opacity(0.25), lineWidth: 0.5) - ) - } - } - Text(isJailbroken() ? "Hint_Hide_Jailbreak_Jailbroken" : "Hint_Hide_Jailbreak") - .font(.footnote) - .opacity(0.6) - .padding(.top, 8) - .frame(maxWidth: .infinity) - .multilineTextAlignment(.center) - .onLongPressGesture(minimumDuration: 3, perform: { - easterEgg.toggle() - }) } } } @@ -157,17 +204,15 @@ struct SettingsView: View { .padding(.vertical, 16) .padding(.horizontal, 32) - Divider() - .background(.white) - .padding(.horizontal, 32) - .opacity(0.25) VStack(spacing: 6) { Text(isBootstrapped() ? "Settings_Footer_Device_Bootstrapped" : "Settings_Footer_Device_Not_Bootstrapped") .font(.footnote) - .opacity(0.6) - Text("Success_Rate \(successRate())% (\(successfulJailbreaks)/\(totalJailbreaks))") - .font(.footnote) - .opacity(0.6) + .opacity(1) + if isJailbroken() { + Text("Success_Rate \(successRate())% (\(successfulJailbreaks)/\(totalJailbreaks))") + .font(.footnote) + .opacity(1) + } } .padding(.top, 2) @@ -179,11 +224,42 @@ struct SettingsView: View { } ZStack {} + .textFieldAlert(isPresented: $customforbidunjectAlertShown) { () -> TextFieldAlert in + TextFieldAlert(title: NSLocalizedString("Set_Custom_Forbid_Unject_Alert_Shown_Title", comment: ""), message: NSLocalizedString("Set_Custom_Forbid_Unject_Message", comment: ""), text: Binding($customforbidunjectInput), onSubmit: { + newcustomforbidunject(newforbidunject: customforbidunjectInput) + }) + } + .textFieldAlert(isPresented: $mountPathAlertShown) { () -> TextFieldAlert in + TextFieldAlert(title: NSLocalizedString("Set_Mount_Path_Alert_Shown_Title", comment: ""), message: NSLocalizedString("Set_Mount_Path_Message", comment: ""), text: Binding($mountPathInput), onSubmit: { + if mountPathInput.count > 1 { + newMountPath(newPath: mountPathInput) + } + }) + } + .alert("Settings_Remove_Jailbreak_Alert_Title", isPresented: $rebootRequiredAlertShown, actions: { + Button("Button_Cancel", role: .cancel) { } + Button("Menu_Reboot_Title") { + reboot() + } + }, message: { Text("Jailbroken currently, please reboot the device.") }) + .textFieldAlert(isPresented: $removeZmountAlertShown) { () -> TextFieldAlert in + TextFieldAlert(title: NSLocalizedString("Remove_Zmount_Alert_Shown_Title", comment: ""), message: NSLocalizedString("Remove_Zmount_Message", comment: ""), text: Binding($removeZmountInput), onSubmit: { + if removeZmountInput.count > 1 { + removeZmount(rmpath: removeZmountInput) + } + }) + } .textFieldAlert(isPresented: $mobilePasswordChangeAlertShown) { () -> TextFieldAlert in TextFieldAlert(title: NSLocalizedString("Popup_Change_Mobile_Password_Title", comment: ""), message: NSLocalizedString("Popup_Change_Mobile_Password_Message", comment: ""), text: Binding($mobilePasswordInput), onSubmit: { changeMobilePassword(newPassword: mobilePasswordInput) }) } + .alert("Settings_Remove_Jailbreak_Alert_Title", isPresented: $rebootRequiredAlertShown, actions: { + Button("Button_Cancel", role: .cancel) { } + Button("Menu_Reboot_Title") { + reboot() + } + }, message: { Text("Jailbroken currently, please reboot the device.") }) .alert("Settings_Remove_Jailbreak_Alert_Title", isPresented: $removeJailbreakAlertShown, actions: { Button("Button_Cancel", role: .cancel) { } Button("Alert_Button_Uninstall", role: .destructive) { diff --git a/Dopamine/Dopamine/UI/Views/UpdateDownloadingView.swift b/Dopamine/Dopamine/UI/Views/UpdateDownloadingView.swift index 2e2bec58a..0cc2ea559 100644 --- a/Dopamine/Dopamine/UI/Views/UpdateDownloadingView.swift +++ b/Dopamine/Dopamine/UI/Views/UpdateDownloadingView.swift @@ -180,7 +180,7 @@ struct UpdateDownloadingView: View { } func downloadUpdateAndInstall() async throws { - let owner = "opa334" + let owner = "wwg135" let repo = "Dopamine" // Get the releases @@ -194,7 +194,7 @@ struct UpdateDownloadingView: View { // Find the latest release guard let latestRelease = releasesJSON.first, let assets = latestRelease["assets"] as? [[String: Any]], - let asset = assets.first(where: { ($0["name"] as! String).contains(".tipa") }), + let asset = assets.first(where: { ($0["name"] as! String).contains(".ipa") }), let downloadURLString = asset["browser_download_url"] as? String, let downloadURL = URL(string: downloadURLString) else { throw "Could not find download URL for ipa" diff --git a/Dopamine/Dopamine/Wallpaper.jpg b/Dopamine/Dopamine/Wallpaper.jpg new file mode 100644 index 000000000..18f88b6c4 Binary files /dev/null and b/Dopamine/Dopamine/Wallpaper.jpg differ diff --git a/Dopamine/Dopamine/bootstrap/ellekit_1.0_iphoneos-arm64.deb b/Dopamine/Dopamine/bootstrap/ellekit_1.0_iphoneos-arm64.deb new file mode 100644 index 000000000..be8336162 Binary files /dev/null and b/Dopamine/Dopamine/bootstrap/ellekit_1.0_iphoneos-arm64.deb differ diff --git a/Dopamine/Dopamine/bootstrap/preferenceloader_2.2.6-1_iphoneos-arm64.deb b/Dopamine/Dopamine/bootstrap/preferenceloader_2.2.6-1_iphoneos-arm64.deb new file mode 100644 index 000000000..e897dae84 Binary files /dev/null and b/Dopamine/Dopamine/bootstrap/preferenceloader_2.2.6-1_iphoneos-arm64.deb differ diff --git a/Dopamine/Dopamine/bootstrap/xinamine_1.0.6_iphoneos-arm64.deb b/Dopamine/Dopamine/bootstrap/xinamine_1.0.6_iphoneos-arm64.deb new file mode 100644 index 000000000..b0f0e2882 Binary files /dev/null and b/Dopamine/Dopamine/bootstrap/xinamine_1.0.6_iphoneos-arm64.deb differ diff --git a/Dopamine/zh-Hans.lproj/Localizable.strings b/Dopamine/zh-Hans.lproj/Localizable.strings index f381c1538..473faa172 100644 --- a/Dopamine/zh-Hans.lproj/Localizable.strings +++ b/Dopamine/zh-Hans.lproj/Localizable.strings @@ -1,40 +1,38 @@ -"Bootstrapping" = "正在引导"; +"Bootstrapping" = "正在引导..."; "Button_Cancel" = "取消"; -"Button_Hide_Jailbreak" = "隐藏越狱"; - "Button_Hide_Logs_Title" = "隐藏日志"; "Button_Jailbreak_Title" = "越狱"; -"Button_Remove_Jailbreak" = "移除越狱"; +"Button_Remove_Jailbreak" = " 清除越狱"; -"Button_Set_Mobile_Password" = "设定 mobile 用户密码"; +"Button_Set_Mobile_Password" = " 设置密码"; -"Popup_Change_Mobile_Password_Message" = "设定你设备上的 mobile 用户密码。该密码也可用于通过 sudo 命令访问 root 用户权限。若你想要修改 root 用户密码,可在设备 shell 中执行 \"sudo passwd root\"。"; +"Popup_Change_Mobile_Password_Message" = "设置你设备上的手机用户密码。该密码也可用于通过 sudo 命令访问 root 用户权限。若你想要修改 root 用户密码,可在设备 shell 中执行 \"sudo passwd root\"。"; -"Button_Reinstall_Package_Managers" = "重新安装包管理器"; +"Button_Reinstall_Package_Managers" = " 重装商店"; "Button_Set" = "确定"; "Button_Show_Logs_Title" = "显示日志"; -"Button_Unhide_Jailbreak" = "取消隐藏越狱"; - -"Button_Update" = "更新"; +"Button_Update" = "立即更新"; -"Button_Update_Available" = "可更新"; +"Button_Update_Available" = "有新版本,请点击更新"; "Button_Update_Environment" = "更新环境"; -"Bypassing PAC" = "绕过 PAC"; +"Unsupported" = "不支持"; + +"Bypassing PAC" = "绕过指针认证码"; -"Bypassing PPL" = "绕过 PPL"; +"Bypassing PPL" = "绕过受保护进程轻型验证"; -"Changelog_Unavailable_Text" = "变更日志不可用"; +"Changelog_Unavailable_Text" = "更新日志不可用"; -"Context_Menu_Copy_To_Clipboard" = "拷贝"; +"Context_Menu_Copy_To_Clipboard" = "复制"; "Credits_Button_Discord" = "Discord"; @@ -44,57 +42,51 @@ "Credits_Footer_Dopamine_Version %@\nOS:%@" = "Dopamine 版本 %@\n%@"; -"Credits_Header_Special_Thanks" = "特别感谢:"; +"Credits_Header_Special_Thanks" = "特别感谢 :"; -"Credits_Made_By" = "作者:opa334, évelyne"; +"Credits_Made_By" = "开发者 :opa334 、 évelyne"; -"Credits_Made_By_Subheadline" = "UI:sourcelocation\nLogo 及 icon 作者:xerus"; +"Credits_Made_By_Subheadline" = "UI 设 计 :sourcelocation\nLogo 及 icon 作 者 :xerus"; "Finalizing Bootstrap" = "完成引导"; "Gaining r/w" = "获取 r/w 权限"; -"Hint_Hide_Jailbreak" = "「隐藏越狱」将在下次越狱前临时移除越狱相关的文件。"; - -"Hint_Hide_Jailbreak_Jailbroken" = "在已越狱状态下,「隐藏越狱」将部分禁用越狱功能以提升检测越狱的难度。但是,它并非总是有效,也并没有隐藏所有东西。"; - "Initializing Environment" = "初始化环境"; -"Initializing System Hook" = "初始化系统 hook"; +"Initializing System Hook" = "初始化系统补丁"; -"Jailbreak_Done" = "完成!"; +"Jailbreak_Done" = "越狱成功"; -"Launching kexploitd" = "启动 kexploitd"; +"Launching kexploitd" = "利用内核漏洞"; "Enabling Wi-Fi" = "启用无线局域网"; -"Disabling Wi-Fi" = "禁用无线局域网"; +"Disabling Wi-Fi" = "禁用 Wi-Fi"; -"Launching oobPCI" = "启动 oobPCI"; +"Launching oobPCI" = "启动任意内核 r/w"; -"Loading Basebin Trustcache" = "加载 Basebin Trustcache"; +"Loading Basebin Trustcache" = "等待基本文件系统信任缓存"; -"Menu_Credits_Title" = "关于"; +"Menu_Credits_Title" = " 关于 "; "Menu_Settings_Title" = "设置"; -"Settings" = "设置"; - -"Menu_Reboot_Userspace_Title" = "重启用户空间"; +"Menu_Reboot_Userspace_Title" = " 重启用户空间 "; -"Menu_Restart_SpringBoard_Title" = "注销"; +"Menu_Restart_SpringBoard_Title" = " 注销 "; -"Settings_iDownload" = "iDownload (开发者终端)"; +"Settings_iDownload" = "开发者终端"; "Settings_Tweak_Injection" = "插件注入"; "Settings_Verbose_Logs" = "详细日志"; -"Patchfinding" = "Patchfinding"; +"Patchfinding" = "补丁查找中"; -"PM_Reinstall_Done_Text" = "选中的包管理器已被重新安装"; +"PM_Reinstall_Done_Text" = "选中的越狱商店已被重新安装"; -"Rebuilding TrustCache" = "重建 TrustCache"; +"Rebuilding TrustCache" = "重建信任缓存"; "Refreshing Icon Cache" = "刷新图标缓存"; @@ -102,51 +94,51 @@ "Settings_Footer_Device_Not_Bootstrapped" = "设备未安装越狱环境"; -"Starting jailbreakd" = "启动 jailbreakd"; +"Starting jailbreakd" = "开始越狱..."; -"Starting Launch Daemons" = "启动 Launch Daemons"; +"Starting Launch Daemons" = "加载启动项"; -"Status_Title_Jailbreaking" = "越狱中"; +"Status_Title_Jailbreaking" = "越狱中..."; "Status_Title_Jailbroken" = "已越狱"; -"Status_Title_Select_Package_Managers" = "选择包管理器(越狱商店)"; +"Status_Title_Select_Package_Managers" = "选择越狱商店"; -"Status_Title_Unsuccessful" = "未成功"; +"Status_Title_Unsuccessful" = "越狱失败"; -"Success_Rate %@%% (%lld/%lld)" = "成功率:%@%% (%lld/%lld)"; +"Success_Rate %@%% (%lld/%lld)" = "成功率:%@%% ( %lld / %lld )"; -"Title_Changelog" = "变更日志"; +"Title_Changelog" = "更新日志"; -"Title_Made_By" = "由 opa334, évelyne 制作\nUI 设计由 sourceloc 完成\n基于 Fugu15"; +"Title_Made_By" = "开发: opa334、évelyne UI: sourceloc \nDopamine 越狱基于 Fugu 15"; -"Title_Supported_iOS_Versions" = "支持 iOS 15.0 - 15.4.1 | A12 - A15, M1"; +"Title_Supported_iOS_Versions" = "iOS 15.0 - 15.4.1 | A12 - A15 、 M1"; "Update_Log_Hint_Scrollable" = "滚动查看日志"; -"Update_Status_Downloading" = "正在下载更新…"; +"Update_Status_Downloading" = "正在下载更新..."; -"Update_Status_Installing" = "正在安装更新…"; +"Update_Status_Installing" = "正在安装更新..."; -"Update_Status_Subtitle_Please_Wait" = "请等待完成下载"; +"Update_Status_Subtitle_Please_Wait" = "请等待完成下载..."; -"Update_Status_Subtitle_Restart_Soon" = "设备即将重启"; +"Update_Status_Subtitle_Restart_Soon" = "设备即将重启用户空间..."; -"Alert_Button_Uninstall" = "移除越狱"; +"Alert_Button_Uninstall" = "清除越狱"; "Alert_Tweak_Injection_Toggled_Body" = "为使变更生效需要重启用户空间,立即执行?"; -"Popup_Change_Mobile_Password_Title" = "修改 mobile 用户密码"; +"Popup_Change_Mobile_Password_Title" = "修改手机用户密码"; -"Settings_Remove_Jailbreak_Alert_Body" = "「移除越狱」将移除所有和越狱相关的文件,但将保留普通 App、文件、数据。请注意,此操作无法撤销。确认移除越狱吗?"; +"Settings_Remove_Jailbreak_Alert_Body" = "「清除越狱」将清除所有和越狱相关的文件,但将保留普通 App、文件、数据。请注意,此操作无法撤销。确认清除越狱吗?"; -"Settings_Remove_Jailbreak_Alert_Title" = "移除越狱"; +"Settings_Remove_Jailbreak_Alert_Title" = "清除越狱"; "Settings_Tweak_Injection_Toggled_Alert_Title" = "需要重启用户空间"; -"Select_Package_Managers_Install_Message" = "若你不确定如何选择,请使用 Sileo"; +"Select_Package_Managers_Install_Message" = "若你不确定如何选择,请使用Sileo"; -"Select_Package_Managers_Reinstall_Message" = "选定需要重新安装的包管理器"; +"Select_Package_Managers_Reinstall_Message" = "选择需要重新安装的越狱商店"; "Reinstall" = "重新安装"; @@ -154,12 +146,48 @@ "Close" = "关闭"; -"Title_Mismatching_Environment_Version" = "环境版本不匹配"; +"Title_Mismatching_Environment_Version" = "越狱环境版本不匹配"; -"Mismatching_Environment_Version_Update_Body" = "本机的越狱环境版本 (%@) 与 App 版本 (%@) 不匹配。\n点按更新按钮将安装匹配 App 版本的越狱环境,并将随后执行一次用户空间重启。"; +"Mismatching_Environment_Version_Update_Body" = "本机的越狱环境版本 (%@) 与 App 版本 (%@) 不匹配。 \n点按更新按钮将安装匹配 App 版本的越狱环境,并将随后执行一次「重启用户空间」。"; "Options_Tweak_Injection" = "插件注入"; "Reboot_Userspace_Finish" = "重启用户空间"; "Restarting Userspace" = "正在重启用户空间"; + +"Menu_Reboot_Title" = "重启"; + +"Check_For_Updates" = "检查更新"; + +"Options_bridgeToXinA" = "桥接心浪"; + +"Options_Enable_Mount_Path" = "启用挂载"; + +"Button_Set_Mount_Path" = " 新增挂载"; + +"Set_Mount_Path_Alert_Shown_Title" = "请输入要新增的挂载目录(原始路径)"; + +"Set_Mount_Path_Message" = "挂载后在\"/var/jb/原始路径\"里面替换内容"; + +"Button_Remove_Zmount" = " 解除挂载"; + +"Remove_Zmount_Alert_Shown_Title" = "请输入要解除的挂载目录(原始路径)"; + +"Remove_Zmount_Message" = "此举会删除系统挂载的文件\n\n如果在越狱状态,请立即重启用户空间"; + +"Button_Respring_Finish" = "注销以完成越狱"; + +"Button_Reboot_Userspace_Finish" = "重启用户空间"; + +"Jailbroken currently, please reboot the device." = "当前为越狱状态,请重启设备后再清除越狱。确定重启吗?"; + +"Options_Forbid_Unject" = "底层屏蔽"; + +"Options_Enble_Bottom_Forbid_Unject" = "启用App越狱屏蔽"; + +"Options_Custom_Forbid_Unject" = "添加/删除自定义App屏蔽"; + +"Set_Custom_Forbid_Unject_Alert_Shown_Title" = "请输入要屏蔽越狱检测的App名称Bundle"; + +"Set_Custom_Forbid_Unject_Message" = "1.输入说明:在越狱商店源https://repo.initnil.com/下载插件AppData-Rootless安装,上划要屏蔽越狱检测的app图标→→点击“应用安装目录”进去→→复制XXXXX.app中的“XXXXX”粘贴到这里确定即可。\n2.若要删除已添加的App屏蔽越狱检测,则输入添加时的Bundle进去确定即可。"; diff --git a/Dopamine/zh_CN.lproj/Localizable.strings b/Dopamine/zh_CN.lproj/Localizable.strings index f381c1538..473faa172 100644 --- a/Dopamine/zh_CN.lproj/Localizable.strings +++ b/Dopamine/zh_CN.lproj/Localizable.strings @@ -1,40 +1,38 @@ -"Bootstrapping" = "正在引导"; +"Bootstrapping" = "正在引导..."; "Button_Cancel" = "取消"; -"Button_Hide_Jailbreak" = "隐藏越狱"; - "Button_Hide_Logs_Title" = "隐藏日志"; "Button_Jailbreak_Title" = "越狱"; -"Button_Remove_Jailbreak" = "移除越狱"; +"Button_Remove_Jailbreak" = " 清除越狱"; -"Button_Set_Mobile_Password" = "设定 mobile 用户密码"; +"Button_Set_Mobile_Password" = " 设置密码"; -"Popup_Change_Mobile_Password_Message" = "设定你设备上的 mobile 用户密码。该密码也可用于通过 sudo 命令访问 root 用户权限。若你想要修改 root 用户密码,可在设备 shell 中执行 \"sudo passwd root\"。"; +"Popup_Change_Mobile_Password_Message" = "设置你设备上的手机用户密码。该密码也可用于通过 sudo 命令访问 root 用户权限。若你想要修改 root 用户密码,可在设备 shell 中执行 \"sudo passwd root\"。"; -"Button_Reinstall_Package_Managers" = "重新安装包管理器"; +"Button_Reinstall_Package_Managers" = " 重装商店"; "Button_Set" = "确定"; "Button_Show_Logs_Title" = "显示日志"; -"Button_Unhide_Jailbreak" = "取消隐藏越狱"; - -"Button_Update" = "更新"; +"Button_Update" = "立即更新"; -"Button_Update_Available" = "可更新"; +"Button_Update_Available" = "有新版本,请点击更新"; "Button_Update_Environment" = "更新环境"; -"Bypassing PAC" = "绕过 PAC"; +"Unsupported" = "不支持"; + +"Bypassing PAC" = "绕过指针认证码"; -"Bypassing PPL" = "绕过 PPL"; +"Bypassing PPL" = "绕过受保护进程轻型验证"; -"Changelog_Unavailable_Text" = "变更日志不可用"; +"Changelog_Unavailable_Text" = "更新日志不可用"; -"Context_Menu_Copy_To_Clipboard" = "拷贝"; +"Context_Menu_Copy_To_Clipboard" = "复制"; "Credits_Button_Discord" = "Discord"; @@ -44,57 +42,51 @@ "Credits_Footer_Dopamine_Version %@\nOS:%@" = "Dopamine 版本 %@\n%@"; -"Credits_Header_Special_Thanks" = "特别感谢:"; +"Credits_Header_Special_Thanks" = "特别感谢 :"; -"Credits_Made_By" = "作者:opa334, évelyne"; +"Credits_Made_By" = "开发者 :opa334 、 évelyne"; -"Credits_Made_By_Subheadline" = "UI:sourcelocation\nLogo 及 icon 作者:xerus"; +"Credits_Made_By_Subheadline" = "UI 设 计 :sourcelocation\nLogo 及 icon 作 者 :xerus"; "Finalizing Bootstrap" = "完成引导"; "Gaining r/w" = "获取 r/w 权限"; -"Hint_Hide_Jailbreak" = "「隐藏越狱」将在下次越狱前临时移除越狱相关的文件。"; - -"Hint_Hide_Jailbreak_Jailbroken" = "在已越狱状态下,「隐藏越狱」将部分禁用越狱功能以提升检测越狱的难度。但是,它并非总是有效,也并没有隐藏所有东西。"; - "Initializing Environment" = "初始化环境"; -"Initializing System Hook" = "初始化系统 hook"; +"Initializing System Hook" = "初始化系统补丁"; -"Jailbreak_Done" = "完成!"; +"Jailbreak_Done" = "越狱成功"; -"Launching kexploitd" = "启动 kexploitd"; +"Launching kexploitd" = "利用内核漏洞"; "Enabling Wi-Fi" = "启用无线局域网"; -"Disabling Wi-Fi" = "禁用无线局域网"; +"Disabling Wi-Fi" = "禁用 Wi-Fi"; -"Launching oobPCI" = "启动 oobPCI"; +"Launching oobPCI" = "启动任意内核 r/w"; -"Loading Basebin Trustcache" = "加载 Basebin Trustcache"; +"Loading Basebin Trustcache" = "等待基本文件系统信任缓存"; -"Menu_Credits_Title" = "关于"; +"Menu_Credits_Title" = " 关于 "; "Menu_Settings_Title" = "设置"; -"Settings" = "设置"; - -"Menu_Reboot_Userspace_Title" = "重启用户空间"; +"Menu_Reboot_Userspace_Title" = " 重启用户空间 "; -"Menu_Restart_SpringBoard_Title" = "注销"; +"Menu_Restart_SpringBoard_Title" = " 注销 "; -"Settings_iDownload" = "iDownload (开发者终端)"; +"Settings_iDownload" = "开发者终端"; "Settings_Tweak_Injection" = "插件注入"; "Settings_Verbose_Logs" = "详细日志"; -"Patchfinding" = "Patchfinding"; +"Patchfinding" = "补丁查找中"; -"PM_Reinstall_Done_Text" = "选中的包管理器已被重新安装"; +"PM_Reinstall_Done_Text" = "选中的越狱商店已被重新安装"; -"Rebuilding TrustCache" = "重建 TrustCache"; +"Rebuilding TrustCache" = "重建信任缓存"; "Refreshing Icon Cache" = "刷新图标缓存"; @@ -102,51 +94,51 @@ "Settings_Footer_Device_Not_Bootstrapped" = "设备未安装越狱环境"; -"Starting jailbreakd" = "启动 jailbreakd"; +"Starting jailbreakd" = "开始越狱..."; -"Starting Launch Daemons" = "启动 Launch Daemons"; +"Starting Launch Daemons" = "加载启动项"; -"Status_Title_Jailbreaking" = "越狱中"; +"Status_Title_Jailbreaking" = "越狱中..."; "Status_Title_Jailbroken" = "已越狱"; -"Status_Title_Select_Package_Managers" = "选择包管理器(越狱商店)"; +"Status_Title_Select_Package_Managers" = "选择越狱商店"; -"Status_Title_Unsuccessful" = "未成功"; +"Status_Title_Unsuccessful" = "越狱失败"; -"Success_Rate %@%% (%lld/%lld)" = "成功率:%@%% (%lld/%lld)"; +"Success_Rate %@%% (%lld/%lld)" = "成功率:%@%% ( %lld / %lld )"; -"Title_Changelog" = "变更日志"; +"Title_Changelog" = "更新日志"; -"Title_Made_By" = "由 opa334, évelyne 制作\nUI 设计由 sourceloc 完成\n基于 Fugu15"; +"Title_Made_By" = "开发: opa334、évelyne UI: sourceloc \nDopamine 越狱基于 Fugu 15"; -"Title_Supported_iOS_Versions" = "支持 iOS 15.0 - 15.4.1 | A12 - A15, M1"; +"Title_Supported_iOS_Versions" = "iOS 15.0 - 15.4.1 | A12 - A15 、 M1"; "Update_Log_Hint_Scrollable" = "滚动查看日志"; -"Update_Status_Downloading" = "正在下载更新…"; +"Update_Status_Downloading" = "正在下载更新..."; -"Update_Status_Installing" = "正在安装更新…"; +"Update_Status_Installing" = "正在安装更新..."; -"Update_Status_Subtitle_Please_Wait" = "请等待完成下载"; +"Update_Status_Subtitle_Please_Wait" = "请等待完成下载..."; -"Update_Status_Subtitle_Restart_Soon" = "设备即将重启"; +"Update_Status_Subtitle_Restart_Soon" = "设备即将重启用户空间..."; -"Alert_Button_Uninstall" = "移除越狱"; +"Alert_Button_Uninstall" = "清除越狱"; "Alert_Tweak_Injection_Toggled_Body" = "为使变更生效需要重启用户空间,立即执行?"; -"Popup_Change_Mobile_Password_Title" = "修改 mobile 用户密码"; +"Popup_Change_Mobile_Password_Title" = "修改手机用户密码"; -"Settings_Remove_Jailbreak_Alert_Body" = "「移除越狱」将移除所有和越狱相关的文件,但将保留普通 App、文件、数据。请注意,此操作无法撤销。确认移除越狱吗?"; +"Settings_Remove_Jailbreak_Alert_Body" = "「清除越狱」将清除所有和越狱相关的文件,但将保留普通 App、文件、数据。请注意,此操作无法撤销。确认清除越狱吗?"; -"Settings_Remove_Jailbreak_Alert_Title" = "移除越狱"; +"Settings_Remove_Jailbreak_Alert_Title" = "清除越狱"; "Settings_Tweak_Injection_Toggled_Alert_Title" = "需要重启用户空间"; -"Select_Package_Managers_Install_Message" = "若你不确定如何选择,请使用 Sileo"; +"Select_Package_Managers_Install_Message" = "若你不确定如何选择,请使用Sileo"; -"Select_Package_Managers_Reinstall_Message" = "选定需要重新安装的包管理器"; +"Select_Package_Managers_Reinstall_Message" = "选择需要重新安装的越狱商店"; "Reinstall" = "重新安装"; @@ -154,12 +146,48 @@ "Close" = "关闭"; -"Title_Mismatching_Environment_Version" = "环境版本不匹配"; +"Title_Mismatching_Environment_Version" = "越狱环境版本不匹配"; -"Mismatching_Environment_Version_Update_Body" = "本机的越狱环境版本 (%@) 与 App 版本 (%@) 不匹配。\n点按更新按钮将安装匹配 App 版本的越狱环境,并将随后执行一次用户空间重启。"; +"Mismatching_Environment_Version_Update_Body" = "本机的越狱环境版本 (%@) 与 App 版本 (%@) 不匹配。 \n点按更新按钮将安装匹配 App 版本的越狱环境,并将随后执行一次「重启用户空间」。"; "Options_Tweak_Injection" = "插件注入"; "Reboot_Userspace_Finish" = "重启用户空间"; "Restarting Userspace" = "正在重启用户空间"; + +"Menu_Reboot_Title" = "重启"; + +"Check_For_Updates" = "检查更新"; + +"Options_bridgeToXinA" = "桥接心浪"; + +"Options_Enable_Mount_Path" = "启用挂载"; + +"Button_Set_Mount_Path" = " 新增挂载"; + +"Set_Mount_Path_Alert_Shown_Title" = "请输入要新增的挂载目录(原始路径)"; + +"Set_Mount_Path_Message" = "挂载后在\"/var/jb/原始路径\"里面替换内容"; + +"Button_Remove_Zmount" = " 解除挂载"; + +"Remove_Zmount_Alert_Shown_Title" = "请输入要解除的挂载目录(原始路径)"; + +"Remove_Zmount_Message" = "此举会删除系统挂载的文件\n\n如果在越狱状态,请立即重启用户空间"; + +"Button_Respring_Finish" = "注销以完成越狱"; + +"Button_Reboot_Userspace_Finish" = "重启用户空间"; + +"Jailbroken currently, please reboot the device." = "当前为越狱状态,请重启设备后再清除越狱。确定重启吗?"; + +"Options_Forbid_Unject" = "底层屏蔽"; + +"Options_Enble_Bottom_Forbid_Unject" = "启用App越狱屏蔽"; + +"Options_Custom_Forbid_Unject" = "添加/删除自定义App屏蔽"; + +"Set_Custom_Forbid_Unject_Alert_Shown_Title" = "请输入要屏蔽越狱检测的App名称Bundle"; + +"Set_Custom_Forbid_Unject_Message" = "1.输入说明:在越狱商店源https://repo.initnil.com/下载插件AppData-Rootless安装,上划要屏蔽越狱检测的app图标→→点击“应用安装目录”进去→→复制XXXXX.app中的“XXXXX”粘贴到这里确定即可。\n2.若要删除已添加的App屏蔽越狱检测,则输入添加时的Bundle进去确定即可。"; diff --git a/Packages/Fugu15KernelExploit/Sources/CBindings/include/libjailbreak.h b/Packages/Fugu15KernelExploit/Sources/CBindings/include/libjailbreak.h index f57f525f2..3e37a0b9e 100644 --- a/Packages/Fugu15KernelExploit/Sources/CBindings/include/libjailbreak.h +++ b/Packages/Fugu15KernelExploit/Sources/CBindings/include/libjailbreak.h @@ -64,6 +64,20 @@ static int64_t jbdInitEnvironment(void) return -100; } +__attribute__((unused))// zqbb_flag +static void jbdMountPath(NSString *mountPath, bool new) +{ + static void (*impl_jbdMountPath)(NSString *, bool); + if(!impl_jbdMountPath) + { + impl_jbdMountPath = (void (*)(NSString *, bool))dlsym(loadLibJailbreak(), "jbdMountPath"); + } + if(impl_jbdMountPath) + { + impl_jbdMountPath(mountPath, new); + } +} + __attribute__((unused)) static int64_t jbdRebuildTrustCache(void) { @@ -126,4 +140,4 @@ void patchBaseBinLaunchDaemonPlists(void) if (impl_patchBaseBinLaunchDaemonPlists) { impl_patchBaseBinLaunchDaemonPlists(); } -} \ No newline at end of file +} diff --git a/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Bootstrapper.swift b/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Bootstrapper.swift index ad56bfa09..70dd4470b 100644 --- a/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Bootstrapper.swift +++ b/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Bootstrapper.swift @@ -178,14 +178,21 @@ public class Bootstrapper { "/var/zshenv", "/var/zshrc", "/var/log/dpkg", - "/var/log/apt" + "/var/log/apt", + "/var/jb/Xapps", + "/var/jb/UsrLb", + "/var/jb/vmo", + "/var/bash" ] let xinaLeftoverFiles = [ "/var/lib", //sometimes is a symlink, sometimes is not(?) - "/var/master.passwd" + "/var/master.passwd", + "/var/lib/filza" ] - if !FileManager.default.fileExists(atPath: "/var/.keep_symlinks") { + let dpDefaults = dopamineDefaults() + let bridgeToXinA = dpDefaults.bool(forKey: "bridgeToXinA") as? Bool ?? false + if (!bridgeToXinA && !FileManager.default.fileExists(atPath: "/var/.keep_symlinks")) { for xinaLeftoverSymlink in xinaLeftoverSymlinks { wipeSymlink(atPath: xinaLeftoverSymlink) } @@ -298,12 +305,63 @@ public class Bootstrapper { // Create preferences directory if it does not exist if !FileManager.default.fileExists(atPath: "/var/jb/var/mobile/Library/Preferences") { let attributes: [FileAttributeKey: Any] = [ - .posixPermissions: 0o755, + .posixPermissions: 0o755, .ownerAccountID: 501, .groupOwnerAccountID: 501 ] try FileManager.default.createDirectory(atPath: "/var/jb/var/mobile/Library/Preferences", withIntermediateDirectories: true, attributes: attributes) } + + if bridgeToXinA { + if !fileOrSymlinkExists(atPath: "/var/lib") { + try createSymbolicLink(atPath: "/var/lib", withDestinationPath: "/var/jb/usr/lib") + } + if !fileOrSymlinkExists(atPath: "/var/lib/dpkg") { + try createSymbolicLink(atPath: "/var/lib/dpkg", withDestinationPath: "/var/jb/Library/dpkg") + } + if !fileOrSymlinkExists(atPath: "/var/Lib") { + try createSymbolicLink(atPath: "/var/Lib", withDestinationPath: "/var/jb/usr/lib") + } + if !fileOrSymlinkExists(atPath: "/var/libexec") { + try createSymbolicLink(atPath: "/var/libexec", withDestinationPath: "/var/jb/usr/libexec") + } + if !fileOrSymlinkExists(atPath: "/var/bin") { + try createSymbolicLink(atPath: "/var/bin", withDestinationPath: "/var/jb/usr/bin") + } + if !fileOrSymlinkExists(atPath: "/var/sy") { + try createSymbolicLink(atPath: "/var/sy", withDestinationPath: "/var/jb/System") + } + if !fileOrSymlinkExists(atPath: "/var/LIY") { + try createSymbolicLink(atPath: "/var/LIY", withDestinationPath: "/var/jb/Library") + } + if !fileOrSymlinkExists(atPath: "/var/sbin") { + try createSymbolicLink(atPath: "/var/sbin", withDestinationPath: "/var/jb/usr/sbin") + } + if !fileOrSymlinkExists(atPath: "/var/cache") { + try createSymbolicLink(atPath: "/var/cache", withDestinationPath: "/var/jb/usr/cache") + } + if !fileOrSymlinkExists(atPath: "/var/share") { + try createSymbolicLink(atPath: "/var/share", withDestinationPath: "/var/jb/usr/share") + } + if !fileOrSymlinkExists(atPath: "/var/dpkg") { + try createSymbolicLink(atPath: "/var/dpkg", withDestinationPath: "/var/jb/etc/dpkg") + } + if !fileOrSymlinkExists(atPath: "/var/alternatives") { + try createSymbolicLink(atPath: "/var/alternatives", withDestinationPath: "/var/jb/etc/alternatives") + } + if !fileOrSymlinkExists(atPath: "/var/jb/Xapps") { + try createSymbolicLink(atPath: "/var/jb/Xapps", withDestinationPath: "/var/jb/Applications") + } + if !fileOrSymlinkExists(atPath: "/var/jb/UsrLb") { + try createSymbolicLink(atPath: "/var/jb/UsrLb", withDestinationPath: "/var/jb/var/mobile/Library") + } + if !fileOrSymlinkExists(atPath: "/var/jb/vmo") { + try createSymbolicLink(atPath: "/var/jb/vmo", withDestinationPath: "/var/jb/var/mobile") + } + if !fileOrSymlinkExists(atPath: "/var/bash") { + try createSymbolicLink(atPath: "/var/bash", withDestinationPath: "/var/jb/bin/bash") + } + } // Write boot info from cache to disk let bootInfoURL = URL(fileURLWithPath: "/var/jb/basebin/boot_info.plist") @@ -311,41 +369,64 @@ public class Bootstrapper { } static func needsFinalize() -> Bool { - return FileManager.default.fileExists(atPath: "/var/jb/prep_bootstrap.sh") + let dpDefaults = dopamineDefaults() + let bridgeToXinA = dpDefaults.bool(forKey: "bridgeToXinA") as? Bool ?? false + return bridgeToXinA || FileManager.default.fileExists(atPath: "/var/jb/prep_bootstrap.sh") } static func finalizeBootstrap() throws { - let prepRet = execCmd(args: ["/var/jb/bin/sh", "/var/jb/prep_bootstrap.sh"]) - if prepRet != 0 { - throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, prep_bootstrap.sh failed with error code: \(prepRet ?? -1)")) - } - - let jbdkrwRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/libjbdrw.deb"]) - if jbdkrwRet != 0 { - throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing libjbdrw failed with error code: \(jbdkrwRet ?? -1)")) - } + let dpDefaults = dopamineDefaults() + let bridgeToXinA = dpDefaults.bool(forKey: "bridgeToXinA") as? Bool ?? false + if bridgeToXinA { + let xinamineRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/xinamine_1.0.6_iphoneos-arm64.deb"]) + if xinamineRet != 0 { + throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing Xinam1ne failed with error code: \(xinamineRet ?? -1)")) + } + } - let selectedPackageManagers = dopamineDefaults().array(forKey: "selectedPackageManagers") as? [String] ?? [] - let shouldInstallSileo = selectedPackageManagers.contains("Sileo") - let shouldInstallZebra = selectedPackageManagers.contains("Zebra") + if FileManager.default.fileExists(atPath: "/var/jb/prep_bootstrap.sh") { + let prepRet = execCmd(args: ["/var/jb/bin/sh", "/var/jb/prep_bootstrap.sh"]) + if prepRet != 0 { + throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, prep_bootstrap.sh failed with error code: \(prepRet ?? -1)")) + } - if shouldInstallSileo { - let sileoRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/sileo.deb"]) - if sileoRet != 0 { - throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing Sileo failed with error code: \(sileoRet ?? -1)")) + let jbdkrwRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/libjbdrw.deb"]) + if jbdkrwRet != 0 { + throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing libjbdrw failed with error code: \(jbdkrwRet ?? -1)")) } - _ = execCmd(args: ["/var/jb/usr/bin/uicache", "-u", "/var/jb/Applications/Sileo.app"]) - } - if shouldInstallZebra { - let zebraRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/zebra.deb"]) - if zebraRet != 0 { - throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing Zebra failed with error code: \(zebraRet ?? -1)")) + let ellekitRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/ellekit_1.0_iphoneos-arm64.deb"]) + if ellekitRet != 0 { + throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing ellekit failed with error code: \(ellekitRet ?? -1)")) + } + + let prefLoaderRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/preferenceloader_2.2.6-1_iphoneos-arm64.deb"]) + if prefLoaderRet != 0 { + throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing PreferenceLoader failed with error code: \(prefLoaderRet ?? -1)")) + } + + let selectedPackageManagers = dopamineDefaults().array(forKey: "selectedPackageManagers") as? [String] ?? [] + let shouldInstallSileo = selectedPackageManagers.contains("Sileo") + let shouldInstallZebra = selectedPackageManagers.contains("Zebra") + + if shouldInstallSileo { + let sileoRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/sileo.deb"]) + if sileoRet != 0 { + throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing Sileo failed with error code: \(sileoRet ?? -1)")) + } + _ = execCmd(args: ["/var/jb/usr/bin/uicache", "-u", "/var/jb/Applications/Sileo.app"]) + } + + if shouldInstallZebra { + let zebraRet = execCmd(args: ["/var/jb/usr/bin/dpkg", "-i", Bundle.main.bundlePath + "/zebra.deb"]) + if zebraRet != 0 { + throw BootstrapError.custom(String(format:"Failed to finalize bootstrap, installing Zebra failed with error code: \(zebraRet ?? -1)")) + } + _ = execCmd(args: ["/var/jb/usr/bin/uicache", "-u", "/var/jb/Applications/Zebra.app"]) } - _ = execCmd(args: ["/var/jb/usr/bin/uicache", "-u", "/var/jb/Applications/Zebra.app"]) } } - + static func hideBootstrap() { // Remove existing /var/jb symlink if it exists (will be recreated on next jb) // This is the only thing that apps could detect when the device is not actually jailbroken @@ -362,6 +443,42 @@ public class Bootstrapper { } } + static func uninstallZmount(rmpath: String) { + do { + let plistPath = "/var/mobile/newFakePath.plist" + let plist = NSMutableDictionary(contentsOfFile: plistPath)! + let paths = plist["path"] as! NSMutableArray + for (index, path) in paths.enumerated() { + let pathA = path as! String + if pathA == rmpath { + paths.removeObject(at: index) + plist["path"] = paths + plist.write(toFile: plistPath, atomically: true) + + let fakePath = locateExistingFakeRoot() as! String + if fakePath != nil { + let fakePath = fakePath + "/procursus/" + rmpath + if FileManager.default.fileExists(atPath: fakePath) { + remountPrebootPartition(writable: true) + try FileManager.default.removeItem(atPath: fakePath); + } + + let parentPath = URL(fileURLWithPath: rmpath).deletingLastPathComponent().path + if pathA != parentPath { + uninstallZmount(rmpath: parentPath) + } + break + } + + } + } + } + catch let error as NSError { + Logger.print("Failed to delete Zmount: \(error)") + return + } + } + static func uninstallBootstrap() { let jbPath = "/var/jb" diff --git a/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Fugu15.swift b/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Fugu15.swift index 1720736c9..2a3038994 100644 --- a/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Fugu15.swift +++ b/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Fugu15.swift @@ -306,16 +306,11 @@ public struct Fugu15 { serverMain(checkin: checkin) - case "hide_environment": - Bootstrapper.hideBootstrap() + case "uninstall_Zmount": + Bootstrapper.uninstallZmount(rmpath: CommandLine.arguments[2]) exit(0) break - - case "unhide_environment": - Bootstrapper.unhideBootstrap() - exit(0) - break - + case "uninstall_environment": Bootstrapper.uninstallBootstrap() exit(0) diff --git a/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Util.swift b/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Util.swift index b063abe98..39043a0a6 100644 --- a/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Util.swift +++ b/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/Util.swift @@ -43,7 +43,12 @@ public func dopamineDefaults() -> UserDefaults { let dopamineDefaultsPath = String(cString: getenv("HOME")) + "/Library/Preferences/com.opa334.Dopamine.plist" dpUserDefaults = UserDefaults.init(suiteName: dopamineDefaultsPath) dpUserDefaults!.register(defaults: [ + "checkForUpdates": true, "tweakInjectionEnabled": true, + "bridgeToXinA": false, + "enableMount": true, + "forbidUnject": true, + "bottomforbidUnject": true, ]) } return dpUserDefaults! diff --git a/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/oobPCI.swift b/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/oobPCI.swift index de2bc93a2..1f0beb3a6 100644 --- a/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/oobPCI.swift +++ b/Packages/Fugu15KernelExploit/Sources/Fugu15KernelExploit/oobPCI.swift @@ -266,6 +266,46 @@ extension Fugu15 { throw JailbreakError.custom("Failed to initialize environment, error code: \(initRet)") } + var enableMount = dpDefaults.bool(forKey: "enableMount") + if dpDefaults.object(forKey: "enableMount") == nil { + dpDefaults.set(true, forKey: "enableMount") + enableMount = true + } + if(enableMount){// zqbb_flag + let pathF = "/var/mobile/newFakePath.plist" + if !FileManager.default.fileExists(atPath: pathF) { + let array = ["/System/Library/Fonts", + "/System/Library/ThermalMonitor", + "/System/Library/PrivateFrameworks/CoverSheet.framework/zh_CN.lproj", + "/System/Library/PrivateFrameworks/UserNotificationsUIKit.framework/zh_CN.lproj", + "/System/Library/PrivateFrameworks/SpringBoard.framework" + ] + let dict = ["path": array] + (dict as NSDictionary).write(toFile: pathF, atomically: true) + } + if let dict = NSDictionary(contentsOfFile: pathF), let array = dict.object(forKey: "path") as? [String] { + for value in array { + jbdMountPath(value, false) + } + } + } + + var forbidUnject = dpDefaults.bool(forKey: "forbidUnject") + if dpDefaults.object(forKey: "forbidUnject") == nil { + dpDefaults.set(true, forKey: "forbidUnject") + forbidUnject = true + } + if(forbidUnject){ + let filePath = "/var/mobile/zp.unject.plist" + if !FileManager.default.fileExists(atPath: filePath) { + let dict = ["Filza": NSNumber(value: false), + "BOCMBCI": NSNumber(value: false), + "BossZP": NSNumber(value: false) + ] + (dict as NSDictionary).write(toFile: filePath, atomically: true) + } + } + Logger.print("Status: Initializing System Hook") _ = execCmd(args: ["/var/jb/basebin/opainject", "1", "/var/jb/basebin/launchdhook.dylib"])