2026-06-19 17:51:51 -07:00
#ifdef WITH_GUI
#include "ExploitPanel.hpp"
#include <wx/wx.h>
2026-07-06 04:05:57 -07:00
#include <wx/mstream.h>
#include <wx/image.h>
#include <wx/bitmap.h>
#include <wx/statline.h>
2026-06-19 17:51:51 -07:00
2026-06-26 20:55:55 -07:00
#include <thread>
2026-06-28 23:34:59 -07:00
#ifdef __cplusplus
2026-06-26 20:55:55 -07:00
#include <atomic>
2026-06-28 23:34:59 -07:00
using std :: atomic_int ;
using std :: atomic_bool ;
#else
#include <stdatomic.h>
#endif
#include <memory>
2026-06-26 20:55:55 -07:00
2026-06-19 17:51:51 -07:00
#include "AppFrame.hpp"
2026-06-26 17:23:09 -07:00
#include "../m8/run.h"
2026-06-28 22:32:34 -07:00
#include "../utils.h"
2026-07-06 04:05:57 -07:00
#include "../gen/images/logo.h"
2026-06-26 20:55:55 -07:00
2026-06-19 17:51:51 -07:00
ExploitPanel :: ExploitPanel ( MainFrame * frame , wxWindow * parent )
: DevicePanel ( frame , parent )
{
2026-07-06 04:05:57 -07:00
auto * root = new wxBoxSizer ( wxHORIZONTAL );
auto * left = new wxBoxSizer ( wxVERTICAL );
wxMemoryInputStream stream ( images_logo_png , images_logo_png_len );
wxImage img ( stream , wxBITMAP_TYPE_PNG );
wxBitmap bmp ( img );
auto * logo = new wxStaticBitmap ( this , wxID_ANY , bmp );
auto * logoText = new wxStaticText ( this , wxID_ANY , "Jailbreak" );
auto * right = new wxBoxSizer ( wxVERTICAL );
2026-06-29 22:31:51 -07:00
m_statusText = new wxStaticText ( this , wxID_ANY , stage_to_string ( STAGE_RESET ));
2026-06-19 17:51:51 -07:00
2026-06-26 20:55:55 -07:00
m_progressBar = new wxGauge ( this , wxID_ANY , 100 );
m_progressBar -> SetValue ( 0 );
2026-06-19 17:51:51 -07:00
m_backButton = new wxButton ( this , wxID_ANY , "Back" );
m_backButton -> Disable ();
2026-06-26 20:55:55 -07:00
m_backButton -> Bind ( wxEVT_BUTTON , [ this , frame ]( wxCommandEvent & ) {
2026-06-29 22:31:51 -07:00
m_statusText -> SetLabel ( stage_to_string ( STAGE_RESET ));
2026-06-26 20:55:55 -07:00
m_progressBar -> SetValue ( 0 );
m_backButton -> Disable ();
2026-06-19 17:51:51 -07:00
frame -> ShowMain ();
});
2026-07-06 04:05:57 -07:00
left -> Add ( new wxStaticText ( this , wxID_ANY , "Installing jailbreak, this will take a moment. If the device asks for a passcode please enter it. Do not disconnect the device until finished." ,
wxDefaultPosition ,
wxDefaultSize ,
wxST_WRAP
), 0 , wxALL , 10 );
left -> Add ( m_statusText , 0 , wxALL , 10 );
left -> Add ( m_progressBar , 0 , wxALL | wxEXPAND , 20 );
2026-06-19 17:51:51 -07:00
2026-07-06 04:05:57 -07:00
right -> Add ( logo , 0 , wxALIGN_CENTER_HORIZONTAL | wxTOP | wxLEFT | wxRIGHT , 10 );
right -> Add ( logoText , 0 , wxALIGN_CENTER_HORIZONTAL | wxTOP , 5 );
right -> AddStretchSpacer ();
right -> Add ( m_backButton , 0 , wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM , 10 );
2026-06-28 22:32:34 -07:00
2026-07-06 04:05:57 -07:00
root -> Add ( left , 1 , wxEXPAND );
root -> Add ( new wxStaticLine ( this , wxID_ANY , wxDefaultPosition , wxDefaultSize , wxLI_VERTICAL ), 0 , wxEXPAND | wxTOP | wxBOTTOM , 10 );
root -> Add ( right , 0 , wxEXPAND );
2026-06-19 17:51:51 -07:00
SetSizer ( root );
}
void ExploitPanel :: SetDeviceState ( const DeviceState & state )
{
DevicePanel :: SetDeviceState ( state );
2026-06-26 20:55:55 -07:00
if ( ! IsShown ())
2026-06-19 17:51:51 -07:00
return ;
}
void ExploitPanel :: StartExploit ()
{
m_backButton -> Disable ();
std :: thread ([ this ]()
{
2026-06-26 20:55:55 -07:00
const auto deviceState = GetDeviceState ();
2026-06-29 22:31:51 -07:00
if ( ! deviceState . connected || deviceState . mode != DeviceMode :: DFU ) {
wxTheApp -> CallAfter ([ this ]() { m_backButton -> Enable (); });
2026-06-19 17:51:51 -07:00
return ;
2026-06-29 22:31:51 -07:00
}
2026-06-26 20:55:55 -07:00
2026-06-28 22:32:34 -07:00
auto state = std :: make_shared < shared_t > ();
atomic_init ( & state -> stage , STAGE_RESET );
atomic_init ( & state -> stop , false );
atomic_init ( & state -> result , 0 );
2026-06-26 20:55:55 -07:00
2026-06-29 22:31:51 -07:00
auto isFinished = std :: make_shared < std :: atomic < bool >> ( false );
std :: thread worker ([ state , isFinished ]()
2026-06-28 22:32:34 -07:00
{
exploit ( state . get ());
2026-06-29 22:31:51 -07:00
isFinished -> store ( true );
2026-06-26 20:55:55 -07:00
});
2026-06-29 22:31:51 -07:00
for (;;)
2026-06-26 20:55:55 -07:00
{
2026-06-28 22:32:34 -07:00
int stage = atomic_load ( & state -> stage );
2026-06-26 20:55:55 -07:00
int progress = stage_to_progress ( stage );
2026-06-29 22:31:51 -07:00
bool finished = isFinished -> load ();
2026-06-26 20:55:55 -07:00
2026-06-29 22:31:51 -07:00
wxTheApp -> CallAfter ([ this , stage , progress , finished ]()
2026-06-28 22:32:34 -07:00
{
2026-06-26 20:55:55 -07:00
m_statusText -> SetLabel ( stage_to_string ( stage ));
m_progressBar -> SetValue ( progress );
2026-06-29 22:31:51 -07:00
if ( finished || stage == STAGE_DONE ) {
m_backButton -> Enable ();
}
2026-06-26 20:55:55 -07:00
});
2026-06-29 22:31:51 -07:00
if ( stage == STAGE_DONE || finished ) {
atomic_store ( & state -> stop , true );
2026-06-26 20:55:55 -07:00
break ;
2026-06-29 22:31:51 -07:00
}
2026-06-26 20:55:55 -07:00
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( 100 ));
}
2026-06-28 22:32:34 -07:00
if ( worker . joinable ())
worker . join ();
2026-06-19 17:51:51 -07:00
}). detach ();
}
#endif // WITH_GUI