Skip to content

Commit

Permalink
v6 Beta 5
Browse files Browse the repository at this point in the history
  • Loading branch information
Lrdsnow committed Sep 19, 2024
1 parent 719c7bc commit a063542
Show file tree
Hide file tree
Showing 21 changed files with 696 additions and 197 deletions.
12 changes: 9 additions & 3 deletions PureKFD/Main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
// Created by Lrdsnow on 6/26/24.
//

// PureKFD is NOT yet ready for use

import UIKit
import SwiftUI
import CoreGraphics

@main
struct purekfdApp: App {
@StateObject private var appData = AppData()
@StateObject private var repoHandler = RepoHandler()
@State private var font: Font? = nil
@AppStorage("accentColor") private var accentColor: Color = Color(hex: "#D4A7FC")!

init() {
setenv("USBMUXD_SOCKET_ADDRESS", "127.0.0.1:60215", 1)
Expand All @@ -31,6 +32,8 @@ struct purekfdApp: App {
ContentView()
.environmentObject(appData)
.environmentObject(repoHandler)
.accentColor(accentColor)
.preferredColorScheme(.dark)
}
}
}
Expand All @@ -40,19 +43,23 @@ struct ContentView: View {
@EnvironmentObject var repoHandler: RepoHandler
@State private var installing = false
@State private var selectedTab = 0
@AppStorage("accentColor") private var accentColor: Color = Color(hex: "#D4A7FC")!

var body: some View {
ZStack(alignment: .bottom) {
TabView(selection: $selectedTab) {
FeaturedView()
.tabItem({Label("Featured", systemImage: "star.fill")})
.tag(0)
.accentColor(accentColor)
BrowseView()
.tabItem({Label("Browse", systemImage: "square.grid.2x2")})
.tag(1)
.accentColor(accentColor)
InstalledView(installing: $installing)
.tabItem({Label("Installed", systemImage: "square.and.arrow.down")})
.tag(2)
.accentColor(accentColor)
}
}.onChange(of: selectedTab) { newValue in
if installing {
Expand Down Expand Up @@ -80,4 +87,3 @@ struct ContentView: View {
})
}
}

25 changes: 25 additions & 0 deletions Shared/SparseRestore/get_libraries_sim.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash
set -e

cd lib

extract_deb() {
wget -nc $1 -O tmp.deb
ar -x tmp.deb
rm tmp.deb
tar --zstd -xvf data.tar.zst
mv usr/lib/*.a ..
}

wget -nc https://github.com/SideStore/EMPackage/raw/main/RustXcframework.xcframework/ios-arm64/libem_proxy-ios.a
wget -nc https://github.com/SideStore/MinimuxerPackage/raw/main/RustXcframework.xcframework/ios-arm64/libminimuxer-ios.a

mkdir tmp && cd tmp

extract_deb https://apt.procurs.us/pool/main/iphoneos-arm64/1700/libimobiledevice/libimobiledevice-dev_1.3.0+git20220702.2eec1b9-1_iphoneos-arm.deb
extract_deb https://apt.procurs.us/pool/main/iphoneos-arm64/1700/libimobiledevice-glue/libimobiledevice-glue-dev_1.0.0+git20220522.d2ff796_iphoneos-arm.deb
extract_deb https://apt.procurs.us/pool/main/iphoneos-arm64/1700/libplist/libplist-dev_2.2.0+git20230130.4b50a5a_iphoneos-arm.deb
extract_deb https://apt.procurs.us/pool/main/iphoneos-arm64/1700/libusbmuxd/libusbmuxd-dev_2.0.2+git20220504.36ffb7a_iphoneos-arm.deb
extract_deb https://apt.procurs.us/pool/main/iphoneos-arm64/1700/openssl/libssl-dev_3.2.1_iphoneos-arm.deb

cd .. && rm -r tmp
2 changes: 1 addition & 1 deletion Shared/build_sparsebox.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ cd SparseBox
echo """
ARCHS := $ARCHS
PACKAGE_FORMAT := ipa
TARGET := $TARGET_PLATFORM
TARGET := iphone:clang:latest:16.0
include $THEOS/makefiles/common.mk
Expand Down
8 changes: 6 additions & 2 deletions purebox.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
65916F502C955960005C8462 /* minimuxer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65916F4F2C955960005C8462 /* minimuxer.swift */; };
65916F522C955967005C8462 /* minimuxer-helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65916F512C955967005C8462 /* minimuxer-helpers.swift */; };
65916F542C95596E005C8462 /* SwiftBridgeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65916F532C95596E005C8462 /* SwiftBridgeCore.swift */; };
6595F3402C9BDC7800F00BD6 /* DirectWrite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6595F33F2C9BDC7600F00BD6 /* DirectWrite.swift */; };
65ABD2D22C93D77F00DD01E8 /* TweakPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ABD2D12C93D77C00DD01E8 /* TweakPath.swift */; };
65ABD2D32C93D77F00DD01E8 /* TweakPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65ABD2D12C93D77C00DD01E8 /* TweakPath.swift */; };
65B18D4C2C418B38002C6276 /* SwiftKFD in Frameworks */ = {isa = PBXBuildFile; productRef = 65B18D4B2C418B38002C6276 /* SwiftKFD */; };
Expand Down Expand Up @@ -174,6 +175,7 @@
65916F4F2C955960005C8462 /* minimuxer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = minimuxer.swift; path = SparseBox/include/minimuxer.swift; sourceTree = "<group>"; };
65916F512C955967005C8462 /* minimuxer-helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "minimuxer-helpers.swift"; path = "SparseBox/include/minimuxer-helpers.swift"; sourceTree = "<group>"; };
65916F532C95596E005C8462 /* SwiftBridgeCore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SwiftBridgeCore.swift; path = SparseBox/include/SwiftBridgeCore.swift; sourceTree = "<group>"; };
6595F33F2C9BDC7600F00BD6 /* DirectWrite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectWrite.swift; sourceTree = "<group>"; };
65ABD2D12C93D77C00DD01E8 /* TweakPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TweakPath.swift; sourceTree = "<group>"; };
65B18D4D2C418B4A002C6276 /* KFD.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KFD.swift; sourceTree = "<group>"; };
65C073832C2E571B0038E045 /* ImageHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageHandling.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -448,6 +450,7 @@
65DA9E1A2C330BEE007D9AAA /* Exploit */ = {
isa = PBXGroup;
children = (
6595F33F2C9BDC7600F00BD6 /* DirectWrite.swift */,
650607A82C9474BC00E1848C /* VirtualEnviorment.swift */,
650607A62C9474B900E1848C /* MDC.swift */,
650607A42C9474AF00E1848C /* SparseRestore.swift */,
Expand Down Expand Up @@ -642,6 +645,7 @@
656C14C72C2D3DF00017F279 /* RepoHandler.swift in Sources */,
656C14DA2C2DC1680017F279 /* Package.swift in Sources */,
65916F2A2C9530EB005C8462 /* ByteBuffer-int.swift in Sources */,
6595F3402C9BDC7800F00BD6 /* DirectWrite.swift in Sources */,
65916F2B2C9530EB005C8462 /* ByteBuffer-conversions.swift in Sources */,
65916F2C2C9530EB005C8462 /* ByteBuffer-foundation.swift in Sources */,
65916F2D2C9530EB005C8462 /* IntegerTypes.swift in Sources */,
Expand Down Expand Up @@ -900,7 +904,7 @@
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = $BUILD_DIR/Libraries;
MARKETING_VERSION = 1.0;
MARKETING_VERSION = "6.0 Beta 5";
PRODUCT_BUNDLE_IDENTIFIER = uwu.lrdsnow.purekfdiOS;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down Expand Up @@ -937,7 +941,7 @@
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = $BUILD_DIR/Libraries;
MARKETING_VERSION = 1.0;
MARKETING_VERSION = "6.0 Beta 5";
PRODUCT_BUNDLE_IDENTIFIER = uwu.lrdsnow.purekfdiOS;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
Binary file not shown.
18 changes: 18 additions & 0 deletions purekfd/Backend/Exploit/DirectWrite.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Rootless.swift
// purebox
//
// Created by Lrdsnow on 9/18/24.
//

import Foundation

class DirectWrite: NSObject {

@objc public static func overwriteFile(_ from: URL, to: URL) {
let fm = FileManager.default
try? fm.createDirectory(at: to.deletingLastPathComponent(), withIntermediateDirectories: true)
try? fm.copyItem(at: from, to: to)
}

}
66 changes: 52 additions & 14 deletions purekfd/Backend/Exploit/SparseRestore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func checkWiFiConnection(completion: @escaping (Bool) -> Void) {
class SparseRestore: NSObject {

@objc public static func startExploit(_ json: [String:String]) -> String? {
exploitLog = ""
var result: String? = nil
let semaphore = DispatchSemaphore(value: 0)

Expand All @@ -49,6 +50,8 @@ class SparseRestore: NSObject {
return
}

let forcefulMode = json["Forceful Mode"] == "true"

let backupPath = URL.documents.appendingPathComponent("backup")
let fm = FileManager.default

Expand Down Expand Up @@ -92,8 +95,11 @@ class SparseRestore: NSObject {
for _info in DeviceManager().getInstalledApps(udid, use_network: true) {
sparseRestoreAppInfo.append(SparseRestoreAppInfo(bundleID: _info.bundleID, path: _info.path, container: _info.container))
}
if sparseRestoreAppInfo.isEmpty {
if ((try? String(contentsOf: backupPath.appendingPathComponent("minimuxer.log"), encoding: .utf8)) ?? "").contains("Failed to create heartbeat") {
if sparseRestoreAppInfo.isEmpty,
forcefulMode {
let minimuxer_logs = ((try? String(contentsOf: backupPath.appendingPathComponent("minimuxer.log"), encoding: .utf8)) ?? "").lowercased()
if minimuxer_logs.contains("failed to create heartbeat"),
!minimuxer_logs.contains("success!") {
result = "Failed to connect to device"
semaphore.signal()
return
Expand Down Expand Up @@ -140,15 +146,16 @@ class SparseRestore: NSObject {
}
}

@objc public static func endExploit() -> String? {
let result = restore()
@objc public static func endExploit(_ json: [String:String]) -> String? {
let result = restore(json)
try? exploitLog.write(to: URL.documents.appendingPathComponent("exploitlog.txt"), atomically: true, encoding: String.Encoding.utf8)
return result
}

public static func restore() -> String? {
public static func restore(_ json: [String:String]) -> String? {
let tempBackupDir = URL.documents.appendingPathComponent("temp")
let backupPath = URL.documents.appendingPathComponent("backup")
let forcefulMode = json["Forceful Mode"] == "true"
let fm = FileManager.default
if fm.fileExists(atPath: tempBackupDir.path) {

Expand Down Expand Up @@ -213,7 +220,10 @@ class SparseRestore: NSObject {
backupInfo = existingInfo
}
if backupInfo.isEmpty {
throw "Backup doesnt exist?"
return "No files to write?"
}
if !forcefulMode, backupInfo.contains(where: { $0.contains("/containers/Bundle/") }) {
return "A tweak is enabled that attempts to write to a container, please enable the required setting to use it and only continue if you know what you are doing (if you do not know what the required setting is then you should not use the tweak)"
}
for file in backupInfo.indices {
let filePath = backupInfo[file]
Expand All @@ -225,9 +235,22 @@ class SparseRestore: NSObject {
if #available(iOS 17.0, *) {
basePath = to.path.hasPrefix("/var/mobile/") ? "var/mobile" : "var"
}
let containerFile = to.path.contains("/containers/")
let containerFile = to.path.contains("/containers/Bundle/")
if containerFile {
let testURL = URL.documents.appendingPathComponent("container.txt")
if let numStr = try? String(contentsOf: testURL),
let num = Int(numStr) {
if num > file {
continue
}
}
if !(file == backupInfo.count-1) {
try? "\(file+1)".write(to: testURL, atomically: true, encoding: .utf8)
}
}
let folderPath = to.deletingLastPathComponent().path.replacingOccurrences(of: "//private/var", with: "/var").replacingOccurrences(of: "/private/var", with: "/var")
let targetPath = to.path.replacingOccurrences(of: "//private/var", with: "/var").replacingOccurrences(of: "/private/var", with: "/var")

backupFiles += [
ConcreteFile(path: "Library/Preferences/temp\(containerFile ? "" : String(Int(file)))", domain: "RootDomain", contents: fileContents, inode: containerFile ? 0 : UInt64(file)),
Directory(path: "", domain: "SysContainerDomain-../../../../../../../../\(basePath)/backup\(folderPath)", owner: containerFile ? 33 : 501, group: containerFile ? 33 : 501),
Expand All @@ -240,11 +263,14 @@ class SparseRestore: NSObject {
} catch {}
}

backupFiles += [
ConcreteFile(path: "", domain: "SysContainerDomain-../../../../../../../../crash_on_purpose", contents: Data())
]
let varMobile = backupInfo.contains(where: { $0.contains("/var/mobile/") })

if !varMobile {
backupFiles += [
ConcreteFile(path: "", domain: "SysContainerDomain-../../../../../../../../crash_on_purpose", contents: Data())
]
}

try? fm.removeItem(at: tempBackupDir)
let mbdb = Backup(files: backupFiles)
try mbdb.writeTo(directory: folder)

Expand All @@ -260,15 +286,27 @@ class SparseRestore: NSObject {

try? FileManager.default.removeItem(at: backupPath)
try? exploitLog.write(to: URL.documents.appendingPathComponent("exploitlog.txt"), atomically: true, encoding: String.Encoding.utf8)
guard exploitLog.contains("crash_on_purpose") else { return "An unknown error has occured on restore, check exploitLog for more details" }
if exploitLog.lowercased().contains("find my") {
return "Find my phone appears to be enabled, please disable it and retry"
}
if result == 2 {
return "An error has occured, please restart the app and try again"
}
if !exploitLog.contains("crash_on_purpose"),
!(result == -18) {
return "An unknown error has occured on restore, check exploitLog for more details"
}

print("Restore succeeded")

sparseRestoreLogPipe.fileHandleForReading.readabilityHandler = nil

return nil
if varMobile {
return "Restore successful, but a tweak has written to /var/mobile so setup bypass has been disabled, in setup please select 'continue with partial setup', failure to do so WILL RESULT IN BOOTLOOP"
} else {
return nil
}
} catch {
try? FileManager.default.removeItem(at: tempBackupDir)
try? FileManager.default.removeItem(at: backupPath)
return "Failed to restore: \(error.localizedDescription)"
}
Expand Down
40 changes: 23 additions & 17 deletions purekfd/Backend/ExploitHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,7 @@ struct Exploit {
var exploitLog = ""

class ExploitHandler {

#if targetEnvironment(simulator) && false
public static var exploits: [Exploit] = [
Exploit(
name: "Virtual Enviorment",
compat: "*",
cpu_compat: "*",
description: "Virtual Enviorment",
stability_rating: 10,
handler: VirtualEnviorment.self,
varOnly: true
)
]
#elseif !os(macOS)
#if !os(macOS)
public static var exploits: [Exploit] = [
// Exploit/KFD.swift
Exploit(
Expand Down Expand Up @@ -126,12 +113,31 @@ class ExploitHandler {
description: "SparseRestore",
stability_rating: 10,
settings: [
"Forceful Mode":"Bool",
"PairingFile":"FilePicker"
],
handler: SparseRestore.self,
varOnly: true,
start_exploit: true,
end_exploit: true
),
//
Exploit(
name: "Direct Write",
compat: "*",
cpu_compat: "*",
description: "Direct Writes",
stability_rating: 10,
handler: DirectWrite.self
),
// DEBUG MODE
Exploit(
name: "Virtual Enviorment",
compat: "*",
cpu_compat: "*",
description: "Virtual Enviorment",
stability_rating: 10,
handler: VirtualEnviorment.self
)
]
#else
Expand Down Expand Up @@ -326,16 +332,16 @@ class ExploitHandler {
}
}

public static func endExploit(_ exploitIndex: Int) -> String? {
public static func endExploit(_ exploitIndex: Int, json: [String: String] = [:]) -> String? {
let exploit = exploits[exploitIndex]

if exploit.end_exploit {
let selector = NSSelectorFromString("endExploit")
if exploit.handler.responds(to: selector) {
let methodIMP: IMP = exploit.handler.method(for: selector)!
typealias EndExploitFunc = @convention(c) (AnyObject, Selector) -> String?
typealias EndExploitFunc = @convention(c) (AnyObject, Selector, [String: String]) -> String?
let function = unsafeBitCast(methodIMP, to: EndExploitFunc.self)
return function(exploit.handler, selector)
return function(exploit.handler, selector, json)
} else {
print("Exploit handler does not implement endExploit()")
}
Expand Down
Loading

0 comments on commit a063542

Please sign in to comment.