mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-15 20:10:30 +00:00
Compare commits
12 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1256c52803 | ||
|
|
3422fc4725 | ||
|
|
734361bb9d | ||
|
|
cd5e609387 | ||
|
|
e4665d74b5 | ||
|
|
300ebff50b | ||
|
|
775fba15f3 | ||
|
|
871f1461d9 | ||
|
|
4bdfc92aa7 | ||
|
|
4b3c8d6e88 | ||
| c03abcaa44 | |||
|
|
d4306e724b |
7 changed files with 73 additions and 76 deletions
35
README.md
35
README.md
|
|
@ -7,24 +7,17 @@
|
|||
<p><i>An on-device debugger/JIT enabler for iOS versions 17.4+ powered by <a href="https://github.com/jkcoxson/idevice">idevice</a>.</i></p>
|
||||
</div>
|
||||
|
||||
<h6 align="center">
|
||||
<a href="https://discord.gg/ZnNcrRT3M8">
|
||||
<img src="https://img.shields.io/badge/Discord-join%20us-7289DA?logo=discord&logoColor=white&style=for-the-badge&labelColor=23272A" />
|
||||
</a>
|
||||
<a href="https://github.com/StikDebug/StikDebug/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/StikDebug/StikDebug?label=License&color=5865F2&style=for-the-badge&labelColor=23272A" />
|
||||
</a>
|
||||
<a href="https://github.com/StikDebug/StikDebug/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/StikDebug/StikDebug?label=Stars&color=FEE75C&style=for-the-badge&labelColor=23272A" />
|
||||
</a>
|
||||
<a href="https://github.com/StikDebug/StikDebug/releases">
|
||||
<img src="https://img.shields.io/github/v/release/StikDebug/StikDebug?label=Latest&color=00BFFF&style=for-the-badge&labelColor=23272A" />
|
||||
</a>
|
||||
<br />
|
||||
</h6>
|
||||
<h3 align="center">
|
||||
<a href="https://discord.gg/ZnNcrRT3M8"><img src="https://img.shields.io/badge/Discord-join%20us-7289DA?logo=discord&logoColor=white&style=for-the-badge&labelColor=23272A" /></a>
|
||||
<a href="https://github.com/StikDebug/StikDebug/blob/main/LICENSE"><img src="https://img.shields.io/github/license/StikDebug/StikDebug?label=License&color=5865F2&style=for-the-badge&labelColor=23272A" /></a>
|
||||
<a href="https://github.com/StikDebug/StikDebug"><img src="https://img.shields.io/github/stars/StikDebug/StikDebug?label=Stars&color=FEE75C&style=for-the-badge&labelColor=23272A" /></a>
|
||||
<a href="https://github.com/StikDebug/StikDebug/releases"><img src="https://img.shields.io/github/v/release/StikDebug/StikDebug?label=Latest&color=00BFFF&style=for-the-badge&labelColor=23272A" /></a>
|
||||
<a href="https://deepwiki.com/StikDebug/StikDebug"><img src="https://img.shields.io/badge/Ask-DeepWiki-grey?style=for-the-badge&labelColor=23272A&color=007ec6" /></a>
|
||||
<br />
|
||||
</h3>
|
||||
|
||||
## Features
|
||||
- **JIT:** Enable Just In Time compilation for sideloaded apps that have the `get-task-allow` entitlement.
|
||||
- **JIT:** Enable Just-In-Time compilation for sideloaded apps that have the `get-task-allow` entitlement.
|
||||
- **App Launching:** Launch every app installed on your device.
|
||||
- **Console:** Live app and system logs.
|
||||
- **Scripts:** Manage automation scripts (mainly used for iOS 26 JIT).
|
||||
|
|
@ -40,7 +33,7 @@
|
|||
<h3 align="center">
|
||||
<a href="https://altdirect.app/?url=https://stikdebug.xyz/index.json" target="_blank"><img src="https://altdirect.app/assets/png/AltSource_Blue.png" alt="Add AltSource" width="200"></a>
|
||||
|
||||
<a href="https://github.com/StikDebug/StikDebug/releases/download/3.1.9/StikDebug-3.1.9.ipa" target="_blank"><img src="https://altdirect.app/assets/png/Download_Blue.png" alt="Download .ipa" width="200"></a>
|
||||
<a href="https://github.com/StikDebug/StikDebug/releases/latest/download/StikDebug-3.1.15.ipa" target="_blank"><img src="https://altdirect.app/assets/png/Download_Blue.png" alt="Download .ipa" width="200"></a>
|
||||
</h3>
|
||||
|
||||
## Compatibility
|
||||
|
|
@ -69,12 +62,12 @@ StikDebug enables **JIT** for sideloaded apps on iOS 17.4+ without needing a com
|
|||
- Launch LocalDevVPN and enable the VPN.
|
||||
|
||||
4. **Enable JIT for an app**
|
||||
- Launch StikDebug and tapp the `Enable JIT` button.
|
||||
- Launch StikDebug and tap the `Enable JIT` button.
|
||||
- Select your sideloaded app from the list in StikDebug.
|
||||
|
||||
**Troubleshooting**
|
||||
- "Connection dropped" or loopback errors → Check iOS version compatibility / beta warnings.
|
||||
- Heartbeat errors → Ensure that the VPN is on and that you are connecected to Wi-Fi. It may be a pairing file issue.
|
||||
- Heartbeat errors → Ensure that the VPN is on and that you are connected to Wi-Fi. It may be a pairing file issue.
|
||||
- Pairing file issues → Replace file with device unlocked & trusted.
|
||||
- Still stuck? Join the [Discord](https://discord.gg/ZnNcrRT3M8) with logs/screenshots.
|
||||
|
||||
|
|
@ -147,13 +140,11 @@ To propose a new feature, open a feature request issue and provide:
|
|||
|
||||
### Code Contributions (Best Practices)
|
||||
- Follow normal Swift and SwiftUI style.
|
||||
- Write clear and easy to understand code.
|
||||
- Write clear and easy-to-understand code.
|
||||
- Keep your changes consistent with how the project is already set up.
|
||||
- Make sure everything builds and works without errors.
|
||||
|
||||
We appreciate your time and effort in helping improve this project.
|
||||
|
||||
## Code Help
|
||||
[](https://deepwiki.com/StikDebug/stikdebug)
|
||||
## License
|
||||
StikDebug is licensed under **AGPL-3.0**. See [`LICENSE`](LICENSE) for details.
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@
|
|||
"$(PROJECT_DIR)/StikDebug/idevice",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 15.1;
|
||||
MARKETING_VERSION = 3.1.12;
|
||||
MARKETING_VERSION = 3.1.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.stik.stikdebug;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
@ -544,7 +544,7 @@
|
|||
"$(PROJECT_DIR)/StikDebug/idevice",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 15.1;
|
||||
MARKETING_VERSION = 3.1.12;
|
||||
MARKETING_VERSION = 3.1.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.stik.stikdebug;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ private enum IdeviceBridge {
|
|||
}
|
||||
|
||||
let code = Int(ffiError.pointee.code)
|
||||
let message = string(from: ffiError.pointee.message) ?? fallback
|
||||
let detail = string(from: ffiError.pointee.message) ?? fallback
|
||||
let message = detail == fallback ? fallback : "\(fallback): \(detail)"
|
||||
idevice_error_free(ffiError)
|
||||
return makeError(domain: domain, code: code, message: message)
|
||||
}
|
||||
|
|
@ -264,45 +265,50 @@ private enum IdeviceBridge {
|
|||
extension JITEnableContext {
|
||||
func isDeveloperDiskImageMounted() throws -> Bool {
|
||||
try IdeviceBridge.withTunnelHandles(for: self) { adapter, handshake in
|
||||
var installed: UnsafeMutablePointer<InstalledCryptexC>?
|
||||
let ffiError = cryptexd_installed_ddi(adapter, handshake, &installed)
|
||||
let queryError = ffiError.map {
|
||||
IdeviceBridge.consumeFFIError($0, fallback: "Failed to query installed DDI cryptex")
|
||||
}
|
||||
defer { cryptexd_free_installed_cryptex(installed) }
|
||||
if installed != nil {
|
||||
return true
|
||||
var cryptexQuerySucceeded = false
|
||||
var cryptexQueryError: NSError?
|
||||
if DeveloperDiskImageService.usesCryptexDDI {
|
||||
var installed: UnsafeMutablePointer<InstalledCryptexC>?
|
||||
defer { cryptexd_free_installed_cryptex(installed) }
|
||||
if let ffiError = cryptexd_installed_ddi(adapter, handshake, &installed) {
|
||||
cryptexQueryError = IdeviceBridge.consumeFFIError(ffiError, fallback: "Failed to query installed DDI cryptex")
|
||||
} else {
|
||||
cryptexQuerySucceeded = true
|
||||
if installed != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let legacyMounted = (try? IdeviceBridge.withConnectedClient(
|
||||
fallback: "Failed to connect to image mounter",
|
||||
missingClientMessage: "Image mounter client was not created",
|
||||
connect: { image_mounter_connect_rsd(adapter, handshake, $0) },
|
||||
cleanup: { image_mounter_free($0) }
|
||||
) { client in
|
||||
var devices: UnsafeMutablePointer<plist_t?>?
|
||||
var deviceCount = 0
|
||||
if let error = image_mounter_copy_devices(client, &devices, &deviceCount) {
|
||||
throw IdeviceBridge.consumeFFIError(error, fallback: "Failed to fetch mounted devices")
|
||||
}
|
||||
if let devices {
|
||||
for index in 0..<deviceCount {
|
||||
plist_free(devices[index])
|
||||
do {
|
||||
return try IdeviceBridge.withConnectedClient(
|
||||
fallback: "Failed to connect to image mounter",
|
||||
missingClientMessage: "Image mounter client was not created",
|
||||
connect: { image_mounter_connect_rsd(adapter, handshake, $0) },
|
||||
cleanup: { image_mounter_free($0) }
|
||||
) { client in
|
||||
var devices: UnsafeMutablePointer<plist_t?>?
|
||||
var deviceCount = 0
|
||||
if let error = image_mounter_copy_devices(client, &devices, &deviceCount) {
|
||||
throw IdeviceBridge.consumeFFIError(error, fallback: "Failed to fetch mounted devices")
|
||||
}
|
||||
idevice_data_free(
|
||||
UnsafeMutableRawPointer(devices).assumingMemoryBound(to: UInt8.self),
|
||||
UInt(deviceCount * MemoryLayout<plist_t?>.stride)
|
||||
)
|
||||
if let devices {
|
||||
for index in 0..<deviceCount {
|
||||
plist_free(devices[index])
|
||||
}
|
||||
idevice_data_free(
|
||||
UnsafeMutableRawPointer(devices).assumingMemoryBound(to: UInt8.self),
|
||||
UInt(deviceCount * MemoryLayout<plist_t?>.stride)
|
||||
)
|
||||
}
|
||||
return deviceCount > 0
|
||||
}
|
||||
return deviceCount > 0
|
||||
}) ?? false
|
||||
if legacyMounted {
|
||||
return true
|
||||
} catch {
|
||||
if cryptexQuerySucceeded {
|
||||
return false
|
||||
}
|
||||
throw cryptexQueryError ?? (error as NSError)
|
||||
}
|
||||
if let queryError {
|
||||
throw queryError
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,8 @@ final class JITEnableContext {
|
|||
guard let ffiError else {
|
||||
return makeError(fallback)
|
||||
}
|
||||
let message = nsString(from: ffiError.pointee.message, fallback: fallback)
|
||||
let detail = nsString(from: ffiError.pointee.message, fallback: fallback)
|
||||
let message = detail == fallback ? fallback : "\(fallback): \(detail)"
|
||||
let error = makeError(message, code: Int(ffiError.pointee.code))
|
||||
idevice_error_free(ffiError)
|
||||
return error
|
||||
|
|
@ -457,22 +458,19 @@ final class JITEnableContext {
|
|||
private func withConnectedRemoteServer<T>(
|
||||
_ body: (OpaquePointer) throws -> T
|
||||
) throws -> T {
|
||||
try ensureTunnel()
|
||||
guard let adapter, let handshake else {
|
||||
throw makeError("Tunnel is not connected")
|
||||
}
|
||||
try withFreshDebugTunnel(hostname: "StikDebugRemoteServer") { adapter, handshake in
|
||||
var remoteServer: OpaquePointer?
|
||||
if let ffiError = remote_server_connect_rsd(adapter, handshake, &remoteServer) {
|
||||
throw error(from: ffiError, fallback: "Failed to connect remote server")
|
||||
}
|
||||
|
||||
var remoteServer: OpaquePointer?
|
||||
if let ffiError = remote_server_connect_rsd(adapter, handshake, &remoteServer) {
|
||||
throw error(from: ffiError, fallback: "Failed to connect remote server")
|
||||
}
|
||||
guard let remoteServer else {
|
||||
throw makeError("Remote server handle was not created")
|
||||
}
|
||||
|
||||
guard let remoteServer else {
|
||||
throw makeError("Remote server handle was not created")
|
||||
defer { remote_server_free(remoteServer) }
|
||||
return try body(remoteServer)
|
||||
}
|
||||
|
||||
defer { remote_server_free(remoteServer) }
|
||||
return try body(remoteServer)
|
||||
}
|
||||
|
||||
private func withProcessControl<T>(
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ func checkMountStatus() -> MountCheckResult {
|
|||
do {
|
||||
return try JITEnableContext.shared.isDeveloperDiskImageMounted() ? .mounted : .notMounted
|
||||
} catch {
|
||||
LogManager.shared.addErrorLog("Failed to check DDI mount status: \(error.localizedDescription)")
|
||||
return .unreachable
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ extension ScriptStore {
|
|||
"Amethyst",
|
||||
"MeloNX",
|
||||
"XeniOS",
|
||||
"MeloCafe",
|
||||
"MeloCafé",
|
||||
"Manic EMU",
|
||||
"DukeX",
|
||||
"TachyonU",
|
||||
|
|
@ -23,7 +23,8 @@ extension ScriptStore {
|
|||
"HyperHLE",
|
||||
"Applesauce",
|
||||
"RPCS3",
|
||||
"AetherPS4"
|
||||
"AetherPS4",
|
||||
"Husk"
|
||||
],
|
||||
resource: ScriptResource(resourceName: "universal", fileName: "universal.js")
|
||||
),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import SwiftUI
|
|||
import UIKit
|
||||
|
||||
private enum SettingsLinks {
|
||||
static let githubStars = URL(string: "https://github.com/StikDebug/StikDebug/stargazers")!
|
||||
static let githubStars = URL(string: "https://github.com/StikDebug/StikDebug")!
|
||||
static let pairingFileGuide = URL(string: "https://github.com/StikDebug/StikDebug-Guide/blob/main/pairing_file.md")!
|
||||
static let localDevVPN = URL(string: "https://apps.apple.com/us/app/localdevvpn/id6755608044")!
|
||||
static let discord = URL(string: "https://discord.gg/qahjXNTDwS")!
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue