diff --git a/README.md b/README.md index 44ede28..9085013 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ An IPA file is a compressed version of an iOS application. You can attain IPA fi ## Usage -Download iPatch.app in [releases](https://github.com/EamonTracey/iPatch/releases), move it to your `Applications` directory, and open the app. Insert a dylib or tweak debian package. Insert an IPA file. Modify the display name to your liking (this is the name the app will have on the Home Screen). Choose whether to inject substrate. Click `Patch` and wait. +Download iPatch.app in [releases](https://github.com/EamonTracey/iPatch/releases), move it to your `Applications` directory, and open the app. Insert a dylib or tweak +debian package. Insert an IPA file. Modify the display name or bundle ID to your liking (this is the name the app will have on the Home Screen). Choose whether to inject +substrate. Click `Patch` and wait. ## Compatibility diff --git a/assets/window.png b/assets/window.png index 12700e0..1864754 100644 Binary files a/assets/window.png and b/assets/window.png differ diff --git a/iPatch.xcodeproj/project.xcworkspace/xcuserdata/alfie.xcuserdatad/UserInterfaceState.xcuserstate b/iPatch.xcodeproj/project.xcworkspace/xcuserdata/alfie.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..398d95d Binary files /dev/null and b/iPatch.xcodeproj/project.xcworkspace/xcuserdata/alfie.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/iPatch/Patch/patch.swift b/iPatch/Patch/patch.swift index 9248ab3..e0eb313 100644 --- a/iPatch/Patch/patch.swift +++ b/iPatch/Patch/patch.swift @@ -9,7 +9,7 @@ import Foundation let bundle = Bundle.main -func patch(ipa ipaURL: URL, withDebOrDylib debOrDylibURL: URL, andDisplayName displayName: String, injectSubstrate: Bool) { +func patch(ipa ipaURL: URL, withDebOrDylib debOrDylibURL: URL, andDisplayName displayName: String, andBundleID bundleID: String, injectSubstrate: Bool) { try? fileManager.removeItem(at: tmp) try? fileManager.createDirectory(at: tmp, withIntermediateDirectories: false, attributes: .none) let appURL = extractAppFromIPA(ipaURL) @@ -19,7 +19,14 @@ func patch(ipa ipaURL: URL, withDebOrDylib debOrDylibURL: URL, andDisplayName di if !patch_binary_with_dylib(binaryURL.path, dylibURL.lastPathComponent, injectSubstrate) { fatalExit("Unable to patch app binary at \(binaryURL.path). The binary may be malformed.") } - changeDisplayName(ofApp: appURL, to: displayName) + + if displayName != "" { + changeDisplayName(ofApp: appURL, to: displayName) + } + + if bundleID != "" { + changeBundleID(ofApp: appURL, to: bundleID) + } saveFile(url: appToIPA(appURL), withPotentialName: displayName, allowedFileTypes: ["ipa"]) } @@ -52,3 +59,10 @@ func changeDisplayName(ofApp appURL: URL, to displayName: String) { info.setValue(displayName, forKey: "CFBundleDisplayName") info.write(to: infoURL, atomically: true) } + +func changeBundleID(ofApp appURL: URL, to bundleID: String) { + let infoURL = appURL.appendingPathComponent("Info.plist") + let info = NSDictionary(contentsOf: infoURL)! + info.setValue(bundleID, forKey: "CFBundleIdentifier") + info.write(to: infoURL, atomically: true) +} diff --git a/iPatch/View Models/RootViewModel.swift b/iPatch/View Models/RootViewModel.swift index 86ee45d..ba7d769 100644 --- a/iPatch/View Models/RootViewModel.swift +++ b/iPatch/View Models/RootViewModel.swift @@ -13,6 +13,7 @@ class RootViewModel: ObservableObject { @Published var ipaURL: URL? = nil @Published var injectSubstrate = true @Published var displayName = "" + @Published var bundleID = "" @Published var substratePopoverPresented = false @Published var isPatching = false @@ -24,7 +25,7 @@ class RootViewModel: ObservableObject { func patch() { guard readyToPatch else { return } isPatching = true - iPatch.patch(ipa: ipaURL!, withDebOrDylib: debOrDylibURL!, andDisplayName: displayName, injectSubstrate: injectSubstrate) + iPatch.patch(ipa: ipaURL!, withDebOrDylib: debOrDylibURL!, andDisplayName: displayName, andBundleID: bundleID, injectSubstrate: injectSubstrate) isPatching = false } diff --git a/iPatch/Views/RootView.swift b/iPatch/Views/RootView.swift index bbc7bbc..1905ac1 100644 --- a/iPatch/Views/RootView.swift +++ b/iPatch/Views/RootView.swift @@ -23,10 +23,22 @@ struct RootView: View { URLText(url: vm.ipaURL) .offset(x: 40) } - HStack { - Text("Display Name") - TextField("", text: $vm.displayName) - .textFieldStyle(RoundedBorderTextFieldStyle()) + // SwiftUI only lets you have 10 'things' in a stack, so I combined these into one + // Tried using Group, but that caused some weird error + // Idk why this happens, I hate Swift(UI) :) + // Seems to work/look fine so who cares + VStack { + HStack { + Text("Custom Display Name") + TextField("", text: $vm.displayName) + .textFieldStyle(RoundedBorderTextFieldStyle()) + } + + HStack { + Text("Custom Bundle ID") + TextField("", text: $vm.bundleID) + .textFieldStyle(RoundedBorderTextFieldStyle()) + } } HStack { Toggle("Inject Substrate", isOn: $vm.injectSubstrate) @@ -43,7 +55,7 @@ struct RootView: View { Spacer() } Spacer() - Text("Eamon Tracey © 2021") + Text("Eamon Tracey © 2022") } .padding() .onDrop(of: [.fileURL], isTargeted: .none) { providers in vm.handleDrop(of: providers) }