feat(tui/wx): support pongo/dfu modes

This commit is contained in:
CLARATION committed 2026-07-31 21:38:43 -07:00
1 parent 7ed291dd46
commit b40e137a37
9 files changed
+84 -27

No files matched your search

+1 -1
View File
@@ -259,7 +259,7 @@ jobs:
- name: Build - name: Build
run: | run: |
make palera1n WITH_STATIC=1 WITH_GUI=1 WITH_TUI=1 WITH_CIDERRAIN=1 WITH_CIDERRAIN=1 BUILD_TYPE=Release JOBS=$(sysctl -n hw.ncpu) make palera1n WITH_STATIC=1 WITH_GUI=1 WITH_TUI=1 WITH_CIDERRAIN=1 BUILD_TYPE=Release JOBS=$(sysctl -n hw.ncpu)
strip -x build/palera1n.app/Contents/MacOS/palera1n strip -x build/palera1n.app/Contents/MacOS/palera1n
- name: Package - name: Package
+9 -1
View File
@@ -73,6 +73,7 @@ struct ManagedDevice {
bool normalPresent = false; bool normalPresent = false;
bool recoveryPresent = false; bool recoveryPresent = false;
bool dfuPresent = false; bool dfuPresent = false;
bool pongoPresent = false;
hotplug_handle_t handle{}; hotplug_handle_t handle{};
uint32_t device_id = 0; uint32_t device_id = 0;
@@ -279,6 +280,7 @@ static void handle_other_add(hotplug_handle_t handle, DeviceMode mode) {
m.recoveryPresent = (mode == DeviceMode::Recovery); m.recoveryPresent = (mode == DeviceMode::Recovery);
m.dfuPresent = (mode == DeviceMode::DFU); m.dfuPresent = (mode == DeviceMode::DFU);
m.pongoPresent = (mode == DeviceMode::Pongo);
} }
publish_state(); publish_state();
} }
@@ -304,6 +306,7 @@ static void remove_device(platform_service_t service, DeviceMode mode, uint32_t
switch (mode) { switch (mode) {
case DeviceMode::Recovery: return pair.second.recoveryPresent; case DeviceMode::Recovery: return pair.second.recoveryPresent;
case DeviceMode::DFU: return pair.second.dfuPresent; case DeviceMode::DFU: return pair.second.dfuPresent;
case DeviceMode::Pongo: return pair.second.pongoPresent;
default: return false; default: return false;
} }
}); });
@@ -319,9 +322,11 @@ static void remove_device(platform_service_t service, DeviceMode mode, uint32_t
m.recoveryPresent = false; m.recoveryPresent = false;
} else if (mode == DeviceMode::DFU) { } else if (mode == DeviceMode::DFU) {
m.dfuPresent = false; m.dfuPresent = false;
} else if (mode == DeviceMode::Pongo) {
m.pongoPresent = false;
} }
if (!m.normalPresent && !m.recoveryPresent && !m.dfuPresent) { if (!m.normalPresent && !m.recoveryPresent && !m.dfuPresent && !m.pongoPresent) {
release_handle(m.handle); release_handle(m.handle);
g_devices.erase(it); g_devices.erase(it);
} }
@@ -419,6 +424,9 @@ static void hotplug_callback(hotplug_event_t event, hotplug_handle_t handle) {
case HOTPLUG_EVENT_DFU_REMOVE: remove_device(srv, DeviceMode::DFU); break; case HOTPLUG_EVENT_DFU_REMOVE: remove_device(srv, DeviceMode::DFU); break;
case HOTPLUG_EVENT_RECOVERY_ADD: handle_other_add(handle, DeviceMode::Recovery); break; case HOTPLUG_EVENT_RECOVERY_ADD: handle_other_add(handle, DeviceMode::Recovery); break;
case HOTPLUG_EVENT_RECOVERY_REMOVE: remove_device(srv, DeviceMode::Recovery); break; case HOTPLUG_EVENT_RECOVERY_REMOVE: remove_device(srv, DeviceMode::Recovery); break;
case HOTPLUG_EVENT_PONGO_ADD: handle_other_add(handle, DeviceMode::Pongo); break;
case HOTPLUG_EVENT_PONGO_REMOVE: remove_device(srv, DeviceMode::Pongo); break;
default: break;
} }
} }
+2 -1
View File
@@ -43,7 +43,8 @@ enum class DeviceMode
None, None,
Normal, Normal,
Recovery, Recovery,
DFU DFU,
Pongo,
}; };
struct DeviceState struct DeviceState
+11 -7
View File
@@ -35,15 +35,16 @@
#include <atomic> #include <atomic>
#include <chrono> #include <chrono>
constexpr int32_t APPLE_VID = 0x05AC; constexpr int32_t APPLE_VID = 0x05AC;
constexpr int32_t PID_DFU = 0x1227; constexpr int32_t PID_DFU = 0x1227;
constexpr int32_t PID_RECOVERY_1 = 0x1280; constexpr int32_t PID_RECOVERY_1 = 0x1280;
constexpr int32_t PID_RECOVERY_2 = 0x1281; constexpr int32_t PID_RECOVERY_2 = 0x1281;
constexpr int32_t PID_RECOVERY_3 = 0x1282; constexpr int32_t PID_RECOVERY_3 = 0x1282;
constexpr int32_t PID_RECOVERY_4 = 0x1283; constexpr int32_t PID_RECOVERY_4 = 0x1283;
constexpr int32_t PID_PONGO = 0x4141;
static const std::vector<int32_t> TARGET_PIDS = { static const std::vector<int32_t> TARGET_PIDS = {
PID_DFU, PID_RECOVERY_1, PID_RECOVERY_2, PID_RECOVERY_3, PID_RECOVERY_4 PID_DFU, PID_RECOVERY_1, PID_RECOVERY_2, PID_RECOVERY_3, PID_RECOVERY_4, PID_PONGO
}; };
static hotplug_callback_t gUserCallback = nullptr; static hotplug_callback_t gUserCallback = nullptr;
@@ -56,6 +57,9 @@ static hotplug_event_t get_hotplug_event(int32_t pid, bool arrived) {
if (pid == PID_DFU) { if (pid == PID_DFU) {
return arrived ? HOTPLUG_EVENT_DFU_ADD : HOTPLUG_EVENT_DFU_REMOVE; return arrived ? HOTPLUG_EVENT_DFU_ADD : HOTPLUG_EVENT_DFU_REMOVE;
} }
if (pid == PID_PONGO) {
return arrived ? HOTPLUG_EVENT_PONGO_ADD : HOTPLUG_EVENT_PONGO_REMOVE;
}
return arrived ? HOTPLUG_EVENT_RECOVERY_ADD : HOTPLUG_EVENT_RECOVERY_REMOVE; return arrived ? HOTPLUG_EVENT_RECOVERY_ADD : HOTPLUG_EVENT_RECOVERY_REMOVE;
} }
+3 -1
View File
@@ -51,7 +51,9 @@ typedef enum {
HOTPLUG_EVENT_DFU_ADD, HOTPLUG_EVENT_DFU_ADD,
HOTPLUG_EVENT_DFU_REMOVE, HOTPLUG_EVENT_DFU_REMOVE,
HOTPLUG_EVENT_RECOVERY_ADD, HOTPLUG_EVENT_RECOVERY_ADD,
HOTPLUG_EVENT_RECOVERY_REMOVE HOTPLUG_EVENT_RECOVERY_REMOVE,
HOTPLUG_EVENT_PONGO_ADD,
HOTPLUG_EVENT_PONGO_REMOVE,
} hotplug_event_t; } hotplug_event_t;
typedef struct { typedef struct {
+1 -1
View File
@@ -119,7 +119,7 @@ void TuiExploitPanel::exploit()
std::thread([this]() std::thread([this]()
{ {
const DeviceState deviceState = GetFrame()->GetDeviceState(); const DeviceState deviceState = GetFrame()->GetDeviceState();
if (!deviceState.connected || deviceState.mode != DeviceMode::DFU) { if (!deviceState.connected || (deviceState.mode != DeviceMode::DFU && deviceState.mode != DeviceMode::Pongo)) {
m_is_exploiting = false; m_is_exploiting = false;
return; return;
} }
+31 -9
View File
@@ -53,9 +53,6 @@ static std::string get_device_title(const DeviceState& state) {
} }
const std::string product = state.displayName.empty() ? (state.productType.empty() ? "Unknown" : state.productType) : state.displayName; const std::string product = state.displayName.empty() ? (state.productType.empty() ? "Unknown" : state.productType) : state.displayName;
if (state.mode == DeviceMode::DFU) {
return "DFU Mode device";
}
return product; return product;
} }
@@ -74,7 +71,7 @@ static std::string get_device_subtitle(const DeviceState& state) {
switch (state.mode) { switch (state.mode) {
case DeviceMode::Normal: case DeviceMode::Normal:
if (state.requiresCLI) { if (state.requiresCLI) {
return "Sorry, jailbreaking is only available via CLI mode * iOS " + version + "\n" + ecid; return "Sorry, jailbreaking is only available via DFU mode * iOS " + version + "\n" + ecid;
} else if (state.isSupported) { } else if (state.isSupported) {
return "Connected in normal mode * iOS " + version + "\n" + ecid; return "Connected in normal mode * iOS " + version + "\n" + ecid;
} else { } else {
@@ -82,14 +79,24 @@ static std::string get_device_subtitle(const DeviceState& state) {
} }
case DeviceMode::Recovery: case DeviceMode::Recovery:
if (state.requiresCLI) { if (state.requiresCLI) {
return "Sorry, jailbreaking is only available via CLI mode.\n" + ecid; return "Sorry, jailbreaking is only available via DFU mode.\n" + ecid;
} else if (state.isSupported) { } else if (state.isSupported) {
return "Connected in recovery mode.\n" + ecid; return "Connected in recovery mode.\n" + ecid;
} else { } else {
return "Sorry, this recovery device is not supported.\n" + ecid; return "Sorry, this recovery device is not supported.\n" + ecid;
} }
case DeviceMode::DFU: case DeviceMode::DFU:
return "Sorry, jailbreaking in DFU is not supported.\n"; if (state.isSupported) {
return "Connected in DFU mode.\n" + ecid;
} else {
return "Sorry, this DFU device is not supported.\n" + ecid;
}
case DeviceMode::Pongo:
if (state.isSupported) {
return "Connected in PongoOS mode.\n" + ecid;
} else {
return "This PongoOS device is not supported, worth a shot though...\n" + ecid;
}
case DeviceMode::None: case DeviceMode::None:
return "Please connect a device to get started. Ensure version range is 15.0+"; return "Please connect a device to get started. Ensure version range is 15.0+";
} }
@@ -223,14 +230,23 @@ void TuiMainPanel::handle_enter(int selected, int sy, int sx) {
case 1: case 1:
GetFrame()->ShowSettings(5); GetFrame()->ShowSettings(5);
break; break;
case 2: { case 2: {
if (block_start) break; if (block_start) break;
bool can_start = (state.connected && state.isSupported && !state.requiresCLI && state.mode != DeviceMode::DFU); bool isDfuLike =
state.mode == DeviceMode::DFU ||
state.mode == DeviceMode::Pongo;
bool can_start =
state.connected &&
state.isSupported &&
(isDfuLike || !state.requiresCLI);
if (can_start) { if (can_start) {
if (state.mode == DeviceMode::Recovery) { if (state.mode == DeviceMode::Recovery) {
GetFrame()->ShowDfu(1); GetFrame()->ShowDfu(1);
} else if (isDfuLike) {
GetFrame()->ShowExploit(0);
} else { } else {
GetFrame()->ShowRecovery(1); GetFrame()->ShowRecovery(1);
} }
@@ -261,7 +277,13 @@ bool TuiMainPanel::is_button_enabled(int btn_idx) const {
switch(btn_idx) { switch(btn_idx) {
case 0: return true; case 0: return true;
case 1: return true; case 1: return true;
case 2: return (state.connected && state.isSupported && !state.requiresCLI && state.mode != DeviceMode::DFU); case 2: {
bool isDfuLike =
state.mode == DeviceMode::DFU ||
state.mode == DeviceMode::Pongo;
return state.connected && state.isSupported && (isDfuLike || !state.requiresCLI);
}
case 3: return true; case 3: return true;
} }
+1 -1
View File
@@ -110,7 +110,7 @@ void ExploitPanel::StartExploit()
std::thread([this]() std::thread([this]()
{ {
const auto deviceState = GetDeviceState(); const auto deviceState = GetDeviceState();
if (!deviceState.connected || deviceState.mode != DeviceMode::DFU) { if (!deviceState.connected || (deviceState.mode != DeviceMode::DFU && deviceState.mode != DeviceMode::Pongo)) {
wxTheApp->CallAfter([this]() { m_backButton->Enable(); }); wxTheApp->CallAfter([this]() { m_backButton->Enable(); });
return; return;
} }
+25 -5
View File
@@ -149,6 +149,9 @@ MainPanel::MainPanel(MainFrame* frame, wxWindow* parent)
frame->ShowRecovery(); frame->ShowRecovery();
else if (frame->GetDeviceState().mode == DeviceMode::Recovery) else if (frame->GetDeviceState().mode == DeviceMode::Recovery)
frame->ShowDfu(); frame->ShowDfu();
else if (frame->GetDeviceState().mode == DeviceMode::DFU ||
frame->GetDeviceState().mode == DeviceMode::Pongo)
frame->ShowExploit();
}); });
left->Add(m_deviceTitle, 0, wxLEFT | wxRIGHT | wxTOP, 10); left->Add(m_deviceTitle, 0, wxLEFT | wxRIGHT | wxTOP, 10);
@@ -246,7 +249,7 @@ void MainPanel::SetDeviceState(const DeviceState& state)
case DeviceMode::Normal: case DeviceMode::Normal:
if (state.requiresCLI) { if (state.requiresCLI) {
m_deviceTitle->SetLabel(productString); m_deviceTitle->SetLabel(productString);
m_deviceSubtitle->SetLabel("Sorry, jailbreaking is only available via CLI mode - OS " + versionString + "\n" + ecidString); m_deviceSubtitle->SetLabel("Sorry, jailbreaking is only available via DFU mode - OS " + versionString + "\n" + ecidString);
m_startButton->Enable(false); m_startButton->Enable(false);
} else if (state.isSupported) { } else if (state.isSupported) {
m_deviceTitle->SetLabel(productString); m_deviceTitle->SetLabel(productString);
@@ -261,7 +264,7 @@ void MainPanel::SetDeviceState(const DeviceState& state)
case DeviceMode::Recovery: case DeviceMode::Recovery:
if (state.requiresCLI) { if (state.requiresCLI) {
m_deviceTitle->SetLabel(productString); m_deviceTitle->SetLabel(productString);
m_deviceSubtitle->SetLabel("Sorry, jailbreaking is only available via CLI mode.\n" + ecidString); m_deviceSubtitle->SetLabel("Sorry, jailbreaking is only available via DFU mode.\n" + ecidString);
m_startButton->Enable(false); m_startButton->Enable(false);
} else if (state.isSupported) { } else if (state.isSupported) {
m_deviceTitle->SetLabel(productString); m_deviceTitle->SetLabel(productString);
@@ -274,9 +277,26 @@ void MainPanel::SetDeviceState(const DeviceState& state)
} }
break; break;
case DeviceMode::DFU: case DeviceMode::DFU:
m_deviceTitle->SetLabel("DFU Mode device"); if (state.isSupported) {
m_deviceSubtitle->SetLabel("Sorry, jailbreaking in DFU is not supported.\n"); m_deviceTitle->SetLabel(productString);
m_startButton->Enable(false); m_deviceSubtitle->SetLabel("Connected in DFU mode.\n" + ecidString);
m_startButton->Enable();
} else {
m_deviceTitle->SetLabel(productString);
m_deviceSubtitle->SetLabel("Sorry, this DFU device is not supported.\n" + ecidString);
m_startButton->Enable(false);
}
break;
case DeviceMode::Pongo:
if (state.isSupported) {
m_deviceTitle->SetLabel(productString);
m_deviceSubtitle->SetLabel("Connected in PongoOS mode.\n" + ecidString);
m_startButton->Enable();
} else {
m_deviceTitle->SetLabel(productString);
m_deviceSubtitle->SetLabel("This PongoOS device is not supported, worth a shot though...\n" + ecidString);
m_startButton->Enable(true);
}
break; break;
case DeviceMode::None: case DeviceMode::None:
m_deviceTitle->SetLabel(deviceTextString); m_deviceTitle->SetLabel(deviceTextString);