feat: wxWidgets gui
No files matched your search
@@ -1,5 +1,3 @@
|
||||
build/
|
||||
.DS_Store
|
||||
src/exploit/payloads/
|
||||
src/exploit/userland/
|
||||
src/exploit/logo.h
|
||||
src/gen/
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"cmake.loadCompileCommands": true,
|
||||
"cmake.configureOnOpen": true,
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build",
|
||||
"cmake.copyCompileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||
}
|
||||
@@ -1,62 +1,359 @@
|
||||
# Project
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(palera1n VERSION 3.0)
|
||||
|
||||
include(FetchContent)
|
||||
include(ExternalProject)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra -DWX_PRECOMP")
|
||||
|
||||
# Option for GUI (wxWidgets)
|
||||
option(WITH_GUI "Build with wxWidgets GUI" OFF)
|
||||
option(WITH_STATIC "Build with static wxWidgets" OFF)
|
||||
option(WITH_STATIC "Build with static wxWidgets / deps" OFF)
|
||||
|
||||
# Architectures
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13")
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Deps
|
||||
set(DEPS_PREFIX ${CMAKE_BINARY_DIR}/deps)
|
||||
|
||||
# =========================
|
||||
# wxWidgets
|
||||
# =========================
|
||||
if(WITH_GUI)
|
||||
if(WITH_STATIC)
|
||||
set(wxBUILD_SHARED OFF)
|
||||
FetchContent_Declare(
|
||||
wxWidgets
|
||||
GIT_REPOSITORY https://github.com/wxWidgets/wxWidgets.git
|
||||
GIT_SHALLOW ON
|
||||
)
|
||||
FetchContent_MakeAvailable(wxWidgets)
|
||||
set(WX_LIBRARIES wxWidgets::core wxWidgets::base wxWidgets::net)
|
||||
else()
|
||||
find_package(wxWidgets REQUIRED COMPONENTS core base net)
|
||||
include(${wxWidgets_USE_FILE})
|
||||
set(WX_LIBRARIES ${wxWidgets_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_STATIC)
|
||||
set(wxBUILD_SHARED OFF CACHE BOOL "" FORCE)
|
||||
|
||||
FetchContent_Declare(
|
||||
wxWidgets
|
||||
GIT_REPOSITORY https://github.com/wxWidgets/wxWidgets.git
|
||||
GIT_SHALLOW ON
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(wxWidgets)
|
||||
|
||||
set(WX_LIBRARIES wxcore wxbase wxnet)
|
||||
|
||||
else()
|
||||
find_package(wxWidgets REQUIRED COMPONENTS core base net)
|
||||
include(${wxWidgets_USE_FILE})
|
||||
set(WX_LIBRARIES ${wxWidgets_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Files
|
||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "src/*.cpp" "src/*.c" "src/*.h" "src/*.hpp")
|
||||
# =========================
|
||||
# JSON
|
||||
# =========================
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
nlohmann_json
|
||||
GIT_REPOSITORY https://github.com/nlohmann/json.git
|
||||
GIT_TAG v3.11.3
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(nlohmann_json)
|
||||
|
||||
# =========================
|
||||
# SOURCES
|
||||
# =========================
|
||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
|
||||
"src/*.cpp"
|
||||
"src/*.c"
|
||||
"src/*.h"
|
||||
"src/*.hpp"
|
||||
)
|
||||
|
||||
# =========================
|
||||
# TARGET
|
||||
# =========================
|
||||
if(APPLE AND WITH_GUI)
|
||||
set(APP_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/palera1n.icns)
|
||||
|
||||
add_executable(palera1n MACOSX_BUNDLE ${SOURCES})
|
||||
set_target_properties(palera1n PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/Info.plist)
|
||||
elseif(APPLE)
|
||||
add_executable(palera1n ${SOURCES})
|
||||
|
||||
target_sources(palera1n PRIVATE ${APP_ICON})
|
||||
|
||||
set_source_files_properties(${APP_ICON} PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION "Resources"
|
||||
)
|
||||
|
||||
set_target_properties(palera1n PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/Info.plist
|
||||
MACOSX_BUNDLE_ICON_FILE palera1n.icns
|
||||
)
|
||||
else()
|
||||
add_executable(palera1n WIN32 ${SOURCES} resources/main.exe.manifest)
|
||||
add_executable(palera1n ${SOURCES})
|
||||
endif()
|
||||
|
||||
include_directories(${DEPS_PREFIX}/include)
|
||||
link_directories(${DEPS_PREFIX}/lib)
|
||||
|
||||
# =========================
|
||||
# APPLE FRAMEWORKS
|
||||
# =========================
|
||||
if(APPLE)
|
||||
find_library(IOKIT IOKit)
|
||||
find_library(COREFOUNDATION CoreFoundation)
|
||||
target_link_libraries(palera1n PRIVATE ${IOKIT} ${COREFOUNDATION})
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${IOKIT}
|
||||
${COREFOUNDATION}
|
||||
)
|
||||
endif()
|
||||
|
||||
# =========================
|
||||
# wxWidgets
|
||||
# =========================
|
||||
if(WITH_GUI)
|
||||
if(WITH_STATIC)
|
||||
target_link_libraries(palera1n PRIVATE wxcore wxnet)
|
||||
else()
|
||||
target_link_libraries(palera1n PRIVATE ${wxWidgets_LIBRARIES})
|
||||
target_link_libraries(palera1n PRIVATE ${WX_LIBRARIES})
|
||||
target_compile_definitions(palera1n PRIVATE WITH_GUI)
|
||||
endif()
|
||||
target_compile_definitions(palera1n PRIVATE WITH_GUI)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE nlohmann_json::nlohmann_json)
|
||||
|
||||
# =========================
|
||||
# libimobiledevice
|
||||
# =========================
|
||||
if(WITH_GUI)
|
||||
if(WITH_STATIC)
|
||||
include(ExternalProject)
|
||||
|
||||
find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config REQUIRED)
|
||||
|
||||
set(PKG_ENV
|
||||
env
|
||||
PKG_CONFIG=${PKG_CONFIG_EXECUTABLE}
|
||||
PKG_CONFIG_PATH=${DEPS_PREFIX}/lib/pkgconfig:${DEPS_PREFIX}/share/pkgconfig
|
||||
PKG_CONFIG_LIBDIR=${DEPS_PREFIX}/lib/pkgconfig:${DEPS_PREFIX}/share/pkgconfig
|
||||
|
||||
CPPFLAGS=-I${DEPS_PREFIX}/include
|
||||
LDFLAGS=-L${DEPS_PREFIX}/lib
|
||||
|
||||
C_INCLUDE_PATH=${DEPS_PREFIX}/include
|
||||
CPLUS_INCLUDE_PATH=${DEPS_PREFIX}/include
|
||||
|
||||
libcurl_CFLAGS=-I/Applications/Xcode-26.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/usr/include
|
||||
libcurl_LIBS=-lcurl
|
||||
|
||||
mbedtls_INCLUDES=${DEPS_PREFIX}/include
|
||||
mbedtls_LIBDIR=${DEPS_PREFIX}/lib
|
||||
mbedtls_LIBS=-lmbedtls\ -lmbedx509\ -lmbedcrypto
|
||||
)
|
||||
|
||||
# =========================
|
||||
# mbedTLS
|
||||
# =========================
|
||||
ExternalProject_Add(mbedtls_ep
|
||||
GIT_REPOSITORY https://github.com/Mbed-TLS/mbedtls.git
|
||||
GIT_TAG mbedtls-3.5.2
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
PATCH_COMMAND patch -p1 < ${CMAKE_SOURCE_DIR}/patches/0001-Allow-empty-x509-cert-issuer.patch
|
||||
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_PREFIX}
|
||||
-DENABLE_TESTING=OFF
|
||||
-DENABLE_PROGRAMS=OFF
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
|
||||
INSTALL_DIR ${DEPS_PREFIX}
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libplist
|
||||
# =========================
|
||||
ExternalProject_Add(libplist_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libplist.git
|
||||
GIT_TAG 2117b8fdb6b4096455bd2041a63e59a028120136
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
--enable-static
|
||||
--disable-shared
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libimobiledevice-glue
|
||||
# =========================
|
||||
ExternalProject_Add(limd_glue_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libimobiledevice-glue.git
|
||||
GIT_TAG 362f7848ac89b74d9dd113b38b51ecb601f76094
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
--enable-static
|
||||
--disable-shared
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libusbmuxd
|
||||
# =========================
|
||||
ExternalProject_Add(libusbmuxd_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libusbmuxd.git
|
||||
GIT_TAG a7f0543fb1ecb20ac7121c0fd77297200e0e43fc
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
--enable-static
|
||||
--disable-shared
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep limd_glue_ep
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libtatsu
|
||||
# =========================
|
||||
ExternalProject_Add(libtatsu_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libtatsu.git
|
||||
GIT_SHALLOW 1
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
--enable-static
|
||||
--disable-shared
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libimobiledevice
|
||||
# =========================
|
||||
ExternalProject_Add(libimobiledevice_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libimobiledevice.git
|
||||
GIT_TAG ed0d66d0341562731bb19928dfe48155509fa7a7
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
--with-mbedtls
|
||||
--enable-static
|
||||
--disable-shared
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS mbedtls_ep libplist_ep libusbmuxd_ep limd_glue_ep libtatsu_ep
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libirecovery
|
||||
# =========================
|
||||
ExternalProject_Add(libirecovery_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libirecovery.git
|
||||
GIT_TAG 7ce02c347b7c26e59498e6af31c9da51018d0fa1
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
--enable-static
|
||||
--disable-shared
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep libusbmuxd_ep limd_glue_ep libtatsu_ep
|
||||
)
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0")
|
||||
|
||||
target_include_directories(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/include
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
find_library(IOKIT IOKit)
|
||||
find_library(COREFOUNDATION CoreFoundation)
|
||||
find_library(SECURITY Security)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${IOKIT}
|
||||
${COREFOUNDATION}
|
||||
${SECURITY}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/lib/libimobiledevice-1.0.a
|
||||
${DEPS_PREFIX}/lib/libirecovery-1.0.a
|
||||
${DEPS_PREFIX}/lib/libusbmuxd-2.0.a
|
||||
${DEPS_PREFIX}/lib/libplist-2.0.a
|
||||
${DEPS_PREFIX}/lib/libimobiledevice-glue-1.0.a
|
||||
${DEPS_PREFIX}/lib/libtatsu.a
|
||||
)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/lib/libmbedtls.a
|
||||
${DEPS_PREFIX}/lib/libmbedx509.a
|
||||
${DEPS_PREFIX}/lib/libmbedcrypto.a
|
||||
)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
curl
|
||||
)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_check_modules(IMD REQUIRED libimobiledevice-1.0)
|
||||
pkg_check_modules(IRECOVERY REQUIRED libirecovery-1.0)
|
||||
pkg_check_modules(PLIST REQUIRED libplist-2.0)
|
||||
pkg_check_modules(USBMUXD REQUIRED libusbmuxd-2.0)
|
||||
|
||||
target_include_directories(palera1n PRIVATE
|
||||
${IMD_INCLUDE_DIRS}
|
||||
${IRECOVERY_INCLUDE_DIRS}
|
||||
${PLIST_INCLUDE_DIRS}
|
||||
${USBMUXD_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${IMD_LIBRARIES}
|
||||
${IRECOVERY_LIBRARIES}
|
||||
${PLIST_LIBRARIES}
|
||||
${USBMUXD_LIBRARIES}
|
||||
)
|
||||
|
||||
target_compile_options(palera1n PRIVATE
|
||||
${IMD_CFLAGS_OTHER}
|
||||
${IRECOVERY_INCLUDE_DIRS}
|
||||
${PLIST_CFLAGS_OTHER}
|
||||
${USBMUXD_CFLAGS_OTHER}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -5,19 +5,21 @@ WITH_STATIC ?= 0
|
||||
BUILD_TYPE ?= Debug
|
||||
|
||||
payloads:
|
||||
@mkdir -p src/exploit/payloads
|
||||
@for file in payloads/*; do \
|
||||
@for file in images/*; do \
|
||||
name=$$(basename "$$file"); \
|
||||
name=$${name%.*}; \
|
||||
echo " XXD $$file"; \
|
||||
xxd -i $$file > src/exploit/$$file.h; \
|
||||
xxd -i -n "$$name" "$$file" > "src/gen/images/$$name.h"; \
|
||||
done
|
||||
xxd -i resources/logo.png > src/exploit/logo.h
|
||||
|
||||
xxd -i -n "DFUHelperDeviceInfo" resources/DFUHelperDeviceInfo.json > src/gen/DFUHelperDeviceInfo.h
|
||||
|
||||
palera1n: payloads
|
||||
@cmake -S . -B build \
|
||||
-DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \
|
||||
-DWITH_GUI=$(WITH_GUI) \
|
||||
-DWITH_STATIC=$(WITH_STATIC) && \
|
||||
cmake --build build -- -j$(sysctl -n hw.ncpu)
|
||||
cmake --build build -- -j4
|
||||
|
||||
palera1n_xcode: payloads
|
||||
@cmake -S . -B build \
|
||||
|
||||
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,33 @@
|
||||
From a2d012f3ba459f6debe636b576ad9aeab7b3c2aa Mon Sep 17 00:00:00 2001
|
||||
From: Nick Chan <[email protected]>
|
||||
Date: Sat, 27 May 2023 23:50:23 +0800
|
||||
Subject: [PATCH] Allow empty x509 cert issuer
|
||||
|
||||
---
|
||||
library/x509_crt.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/library/x509_crt.c b/library/x509_crt.c
|
||||
index cf62532f2..ef25b3d77 100644
|
||||
--- a/library/x509_crt.c
|
||||
+++ b/library/x509_crt.c
|
||||
@@ -1061,13 +1061,13 @@ static int x509_crt_parse_der_core(mbedtls_x509_crt *crt,
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
- mbedtls_x509_crt_free(crt);
|
||||
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
|
||||
+ /*mbedtls_x509_crt_free(crt);
|
||||
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);*/
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_get_name(&p, p + len, &crt->issuer)) != 0) {
|
||||
- mbedtls_x509_crt_free(crt);
|
||||
- return ret;
|
||||
+ /*mbedtls_x509_crt_free(crt);
|
||||
+ return ret;*/
|
||||
}
|
||||
|
||||
crt->issuer_raw.len = p - crt->issuer_raw.p;
|
||||
--
|
||||
2.39.1
|
||||
@@ -0,0 +1,452 @@
|
||||
{
|
||||
"devicemap":{
|
||||
"iPhone6,1":"iphonese",
|
||||
"iPhone6,2":"iphonese",
|
||||
"iPhone7,1":"iphone6s",
|
||||
"iPhone7,2":"iphone6s",
|
||||
"iPhone8,1":"iphone6s",
|
||||
"iPhone8,2":"iphone6s",
|
||||
"iPhone8,4":"iphonese",
|
||||
"iPhone9,1":"iphone7",
|
||||
"iPhone9,2":"iphone7",
|
||||
"iPhone9,3":"iphone7",
|
||||
"iPhone9,4":"iphone7",
|
||||
"iPhone10,1":"iphone8",
|
||||
"iPhone10,2":"iphone8",
|
||||
"iPhone10,4":"iphone8",
|
||||
"iPhone10,5":"iphone8",
|
||||
"iPhone10,3":"iphonex",
|
||||
"iPhone10,6":"iphonex",
|
||||
|
||||
"iPhone11,2":"iphonex",
|
||||
"iPhone11,4":"iphonex",
|
||||
"iPhone11,6":"iphonex",
|
||||
"iPhone11,8":"iphonex",
|
||||
"iPhone12,1":"iphonex",
|
||||
"iPhone12,3":"iphonex",
|
||||
"iPhone12,5":"iphonex",
|
||||
"iPhone12,8":"iphone8",
|
||||
|
||||
"iPad4,1":"ipad",
|
||||
"iPad4,2":"ipad",
|
||||
"iPad4,3":"ipad",
|
||||
"iPad5,3":"ipad",
|
||||
"iPad5,4":"ipad",
|
||||
"iPad6,3":"ipad",
|
||||
"iPad6,4":"ipad",
|
||||
"iPad6,7":"ipad",
|
||||
"iPad6,8":"ipad",
|
||||
"iPad6,11":"ipad",
|
||||
"iPad6,12":"ipad",
|
||||
"iPad7,1":"ipad",
|
||||
"iPad7,2":"ipad",
|
||||
"iPad7,3":"ipad",
|
||||
"iPad7,4":"ipad",
|
||||
"iPad7,5":"ipad",
|
||||
"iPad7,6":"ipad",
|
||||
"iPad7,11":"ipad",
|
||||
"iPad7,12":"ipad",
|
||||
|
||||
"iPad8,1":"ipad",
|
||||
"iPad8,2":"ipad",
|
||||
"iPad8,3":"ipad",
|
||||
"iPad8,4":"ipad",
|
||||
"iPad8,5":"ipad",
|
||||
"iPad8,6":"ipad",
|
||||
"iPad8,7":"ipad",
|
||||
"iPad8,8":"ipad",
|
||||
"iPad8,9":"ipad",
|
||||
"iPad8,10":"ipad",
|
||||
"iPad8,11":"ipad",
|
||||
"iPad8,12":"ipad",
|
||||
"iPad11,3":"ipad",
|
||||
"iPad11,4":"ipad",
|
||||
"iPad11,6":"ipad",
|
||||
"iPad11,7":"ipad",
|
||||
|
||||
"iPad4,4":"ipadmini",
|
||||
"iPad4,5":"ipadmini",
|
||||
"iPad4,6":"ipadmini",
|
||||
"iPad4,7":"ipadmini",
|
||||
"iPad4,8":"ipadmini",
|
||||
"iPad4,9":"ipadmini",
|
||||
"iPad5,1":"ipadmini",
|
||||
"iPad5,2":"ipadmini",
|
||||
"iPod7,1":"ipodtouch",
|
||||
"iPod9,1":"ipodtouch7",
|
||||
"AppleTV5,3":"appletv4",
|
||||
"AppleTV6,2":"appletv4k"
|
||||
},
|
||||
"devicelayout":{
|
||||
"ipodtouch7":{
|
||||
"image_name":"ipodtouch",
|
||||
"image_width":116,
|
||||
"image_height":240,
|
||||
"image_offset_x":100,
|
||||
"buttons":{
|
||||
"top":{
|
||||
"name":"– Top button",
|
||||
"x":192,
|
||||
"y":-4
|
||||
},
|
||||
"vol_down":{
|
||||
"name":"Volume down –",
|
||||
"x":8,
|
||||
"y":62
|
||||
}
|
||||
},
|
||||
"sequence":"ipodtouch7"
|
||||
},
|
||||
"ipodtouch":{
|
||||
"image_name":"ipodtouch",
|
||||
"image_width":116,
|
||||
"image_height":240,
|
||||
"image_offset_x":100,
|
||||
"buttons":{
|
||||
"top":{
|
||||
"name":"– Top button",
|
||||
"x":196,
|
||||
"y":-4
|
||||
},
|
||||
"home":{
|
||||
"name":"Home button –",
|
||||
"x":50,
|
||||
"y":210
|
||||
}
|
||||
},
|
||||
"sequence":"iphone-old"
|
||||
},
|
||||
"iphonese":{
|
||||
"image_name":"iphonese",
|
||||
"image_width":119,
|
||||
"image_height":240,
|
||||
"image_offset_x":100,
|
||||
"buttons":{
|
||||
"top":{
|
||||
"name":"– Top button",
|
||||
"x":200,
|
||||
"y":-4
|
||||
},
|
||||
"home":{
|
||||
"name":"Home button –",
|
||||
"x":56,
|
||||
"y":210
|
||||
}
|
||||
},
|
||||
"sequence":"iphone-old"
|
||||
},
|
||||
"iphone6s":{
|
||||
"image_name":"iphone6s",
|
||||
"image_width":123,
|
||||
"image_height":240,
|
||||
"image_offset_x":100,
|
||||
"buttons":{
|
||||
"side":{
|
||||
"name":"– Side button",
|
||||
"x":224,
|
||||
"y":58
|
||||
},
|
||||
"home":{
|
||||
"name":"Home button –",
|
||||
"x":60,
|
||||
"y":210
|
||||
}
|
||||
},
|
||||
"sequence":"iphone6"
|
||||
},
|
||||
"iphone7":{
|
||||
"image_name":"iphone7",
|
||||
"image_width":123,
|
||||
"image_height":240,
|
||||
"image_offset_x":100,
|
||||
"buttons":{
|
||||
"side":{
|
||||
"name":"– Side button",
|
||||
"x":224,
|
||||
"y":58
|
||||
},
|
||||
"vol_down":{
|
||||
"name":"Volume down –",
|
||||
"x":14,
|
||||
"y":78
|
||||
}
|
||||
},
|
||||
"sequence":"iphone7"
|
||||
},
|
||||
"iphone8":{
|
||||
"image_name":"iphone8",
|
||||
"image_width":120,
|
||||
"image_height":240,
|
||||
"image_offset_x":100,
|
||||
"buttons":{
|
||||
"side":{
|
||||
"name":"– Side button",
|
||||
"x":220,
|
||||
"y":58
|
||||
},
|
||||
"vol_down":{
|
||||
"name":"Volume down –",
|
||||
"x":10,
|
||||
"y":78
|
||||
}
|
||||
},
|
||||
"sequence":"iphone8"
|
||||
},
|
||||
"iphonex":{
|
||||
"image_name":"iphonex",
|
||||
"image_width":121,
|
||||
"image_height":240,
|
||||
"image_offset_x":100,
|
||||
"buttons":{
|
||||
"side":{
|
||||
"name":"– Side button",
|
||||
"x":220,
|
||||
"y":68
|
||||
},
|
||||
"vol_down":{
|
||||
"name":"Volume down –",
|
||||
"x":10,
|
||||
"y":75
|
||||
}
|
||||
},
|
||||
"sequence":"iphone8"
|
||||
},
|
||||
"ipad":{
|
||||
"image_name":"ipad",
|
||||
"image_width":170,
|
||||
"image_height":240,
|
||||
"buttons":{
|
||||
"top":{
|
||||
"name":"Top button",
|
||||
"x":149,
|
||||
"y":5
|
||||
},
|
||||
"home":{
|
||||
"name":"Home button",
|
||||
"x":89,
|
||||
"y":225
|
||||
}
|
||||
},
|
||||
"sequence":"iphone-old"
|
||||
},
|
||||
"ipadmini":{
|
||||
"image_name":"ipadmini",
|
||||
"image_width":163,
|
||||
"image_height":240,
|
||||
"buttons":{
|
||||
"top":{
|
||||
"name":"Top button",
|
||||
"x":140,
|
||||
"y":4
|
||||
},
|
||||
"home":{
|
||||
"name":"Home button",
|
||||
"x":86,
|
||||
"y":224
|
||||
}
|
||||
},
|
||||
"sequence":"iphone-old"
|
||||
},
|
||||
"appletv4":{
|
||||
"image_name":"siriremote",
|
||||
"image_width":79,
|
||||
"image_height":240,
|
||||
"image_offset_x":120,
|
||||
"buttons":{
|
||||
"menu":{
|
||||
"name":"Menu –",
|
||||
"x":84,
|
||||
"y":84
|
||||
},
|
||||
"playpause":{
|
||||
"name":"Play/Pause –",
|
||||
"x":52,
|
||||
"y":146
|
||||
}
|
||||
},
|
||||
"sequence":"appletv4"
|
||||
},
|
||||
"appletv4k":{
|
||||
"image_name":"atv_std_brd",
|
||||
"image_width":300,
|
||||
"image_height":240,
|
||||
"image_offset_x":0,
|
||||
"buttons":{
|
||||
"dfu":{
|
||||
"name":"-- DFU button",
|
||||
"x":120,
|
||||
"y":48
|
||||
}
|
||||
},
|
||||
"sequence":"atv_standard_breakout"
|
||||
}
|
||||
},
|
||||
"sequences":{
|
||||
"ipodtouch7":[
|
||||
{
|
||||
"buttons":[
|
||||
|
||||
],
|
||||
"description":"Click Start",
|
||||
"duration":0
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"top",
|
||||
"vol_down"
|
||||
],
|
||||
"description":"Press and hold the Top and Volume down buttons together",
|
||||
"duration":4,
|
||||
"action":"reboot"
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"vol_down"
|
||||
],
|
||||
"description":"Release the Top button BUT KEEP HOLDING the Volume down button",
|
||||
"duration":10
|
||||
}
|
||||
],
|
||||
"iphone-old":[
|
||||
{
|
||||
"buttons":[
|
||||
|
||||
],
|
||||
"description":"Click Start",
|
||||
"duration":0
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"top",
|
||||
"home"
|
||||
],
|
||||
"description":"Press and hold the Top\n and Home buttons\n together",
|
||||
"duration":4,
|
||||
"action":"reboot"
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"home"
|
||||
],
|
||||
"description":"Release the Top button\n BUT KEEP HOLDING the\n Home button",
|
||||
"duration":10
|
||||
}
|
||||
],
|
||||
"iphone6":[
|
||||
{
|
||||
"buttons":[
|
||||
|
||||
],
|
||||
"description":"Click Start",
|
||||
"duration":0
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"side",
|
||||
"home"
|
||||
],
|
||||
"description":"Press and hold the Side\n and Home buttons\n together",
|
||||
"duration":4,
|
||||
"action":"reboot"
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"home"
|
||||
],
|
||||
"description":"Release the Side button\n BUT KEEP HOLDING the\n Home button",
|
||||
"duration":10
|
||||
}
|
||||
],
|
||||
"iphone7":[
|
||||
{
|
||||
"buttons":[
|
||||
|
||||
],
|
||||
"description":"Click Start",
|
||||
"duration":0
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"side",
|
||||
"vol_down"
|
||||
],
|
||||
"description":"Press and hold the Side\n and Volume down\n buttons together",
|
||||
"duration":4,
|
||||
"action":"reboot"
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"vol_down"
|
||||
],
|
||||
"description":"Release the Side button\n BUT KEEP HOLDING the\n Volume down button",
|
||||
"duration":10
|
||||
}
|
||||
],
|
||||
"iphone8":[
|
||||
{
|
||||
"buttons":[
|
||||
|
||||
],
|
||||
"description":"Click Start",
|
||||
"duration":0
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"side",
|
||||
"vol_down"
|
||||
],
|
||||
"description":"Press and hold the Side\n and Volume down\n buttons together",
|
||||
"duration":4,
|
||||
"action":"reboot"
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"vol_down"
|
||||
],
|
||||
"description":"Release the Side button\n BUT KEEP HOLDING the\n Volume down button",
|
||||
"duration":10
|
||||
}
|
||||
],
|
||||
"appletv4":[
|
||||
{
|
||||
"buttons":[
|
||||
|
||||
],
|
||||
"description":"Get Ready",
|
||||
"duration":3
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"menu",
|
||||
"playpause"
|
||||
],
|
||||
"description":"Press and hold Menu\n and Play/Pause together\n ",
|
||||
"duration":7
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
|
||||
],
|
||||
"description":"Release the buttons",
|
||||
"duration":2
|
||||
}
|
||||
],
|
||||
"atv_standard_breakout":[
|
||||
{
|
||||
"buttons":[
|
||||
|
||||
],
|
||||
"description":"Get Ready",
|
||||
"duration":3
|
||||
},
|
||||
{
|
||||
"buttons":[
|
||||
"dfu"
|
||||
],
|
||||
"description":"Press and hold the DFU\n button",
|
||||
"duration":10,
|
||||
"action":"reboot"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>palera.in.palera1n</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>palera1n</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>palera1n.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>palera1n</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>palera1n</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>(c) 2026 palera1n</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>platform-application</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.no-container</key>
|
||||
<true/>
|
||||
<key>com.apple.security.iokit-user-client-class</key>
|
||||
<array>
|
||||
<string>IOUserClient</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Before Width: | Height: | Size: 6.0 KiB |
@@ -0,0 +1,186 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include "event.hpp"
|
||||
|
||||
#include "wx/AppFrame.hpp"
|
||||
#include "state.hpp"
|
||||
#include "sequence.hpp"
|
||||
#include "utils/log.h"
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <thread>
|
||||
|
||||
#include <libimobiledevice/libimobiledevice.h>
|
||||
#include <libimobiledevice/lockdown.h>
|
||||
#include <libirecovery.h>
|
||||
|
||||
static inline DeviceState make_fresh_state()
|
||||
{
|
||||
return DeviceState{};
|
||||
}
|
||||
|
||||
void normal_device_event_cb(
|
||||
const idevice_event_t* event,
|
||||
void* user_data)
|
||||
{
|
||||
#ifdef WITH_GUI
|
||||
auto* frame = static_cast<MainFrame*>(user_data);
|
||||
if (!frame || !event)
|
||||
return;
|
||||
#endif
|
||||
|
||||
DeviceState state = make_fresh_state();
|
||||
|
||||
if (event->event == IDEVICE_DEVICE_REMOVE)
|
||||
{
|
||||
#ifdef WITH_GUI
|
||||
send_device_state(frame, state);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->event != IDEVICE_DEVICE_ADD)
|
||||
return;
|
||||
|
||||
idevice_t device = nullptr;
|
||||
if (idevice_new(&device, event->udid) != IDEVICE_E_SUCCESS)
|
||||
return;
|
||||
|
||||
state.connected = true;
|
||||
state.mode = DeviceMode::Normal;
|
||||
state.udid = event->udid ? event->udid : "";
|
||||
|
||||
lockdownd_client_t client = nullptr;
|
||||
|
||||
if (lockdownd_client_new_with_handshake(device, &client, "palera1n") == LOCKDOWN_E_SUCCESS)
|
||||
{
|
||||
plist_t product = nullptr;
|
||||
plist_t version = nullptr;
|
||||
plist_t ecid = nullptr;
|
||||
|
||||
char *p = nullptr, *v = nullptr;
|
||||
uint64_t ecid_val = 0;
|
||||
|
||||
lockdownd_get_value(client, nullptr, "ProductType", &product);
|
||||
lockdownd_get_value(client, nullptr, "ProductVersion", &version);
|
||||
lockdownd_get_value(client, nullptr, "UniqueChipID", &ecid);
|
||||
|
||||
if (product) plist_get_string_val(product, &p);
|
||||
if (version) plist_get_string_val(version, &v);
|
||||
if (ecid) plist_get_uint_val(ecid, &ecid_val);
|
||||
|
||||
state.productType = p ? p : "";
|
||||
state.productVersion = v ? v : "";
|
||||
state.ecid = ecid_val;
|
||||
|
||||
free(p);
|
||||
free(v);
|
||||
|
||||
if (product) plist_free(product);
|
||||
if (version) plist_free(version);
|
||||
if (ecid) plist_free(ecid);
|
||||
|
||||
lockdownd_client_free(client);
|
||||
}
|
||||
|
||||
idevice_free(device);
|
||||
|
||||
state.isSupported = SequenceIsSupported(state.productType);
|
||||
|
||||
#ifdef WITH_GUI
|
||||
send_device_state(frame, state);
|
||||
#endif
|
||||
}
|
||||
|
||||
void recovery_device_event_cb(
|
||||
const irecv_device_event_t* event,
|
||||
void* user_data)
|
||||
{
|
||||
#ifdef WITH_GUI
|
||||
auto* frame = static_cast<MainFrame*>(user_data);
|
||||
if (!frame || !event)
|
||||
return;
|
||||
#endif
|
||||
|
||||
DeviceState state = make_fresh_state();
|
||||
|
||||
if (event->type == IRECV_DEVICE_REMOVE)
|
||||
{
|
||||
#ifdef WITH_GUI
|
||||
send_device_state(frame, state);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->type != IRECV_DEVICE_ADD)
|
||||
return;
|
||||
|
||||
state.connected = true;
|
||||
|
||||
if (event->mode == IRECV_K_DFU_MODE)
|
||||
{
|
||||
state.mode = DeviceMode::DFU;
|
||||
#ifdef WITH_GUI
|
||||
send_device_state(frame, state);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event->mode == IRECV_K_RECOVERY_MODE_1 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_2 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_3 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_4))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
state.mode = DeviceMode::Recovery;
|
||||
|
||||
uint64_t ecid_val = 0;
|
||||
if (event->device_info && event->device_info->ecid)
|
||||
ecid_val = event->device_info->ecid;
|
||||
state.ecid = ecid_val;
|
||||
|
||||
irecv_client_t client = nullptr;
|
||||
|
||||
int attempts = 0;
|
||||
const int max_attempts = 10;
|
||||
|
||||
while (attempts < max_attempts)
|
||||
{
|
||||
if (irecv_open_with_ecid(&client, state.ecid) == IRECV_E_SUCCESS)
|
||||
break;
|
||||
|
||||
attempts++;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
LOG("Opened client after %d attempts", attempts);
|
||||
|
||||
irecv_device_t device = nullptr;
|
||||
if (irecv_devices_get_device_by_client(client, &device) == IRECV_E_SUCCESS && device)
|
||||
{
|
||||
LOG("device product type: %s", device->product_type);
|
||||
LOG("device display name: %s", device->display_name);
|
||||
|
||||
state.productType = device->product_type ? device->product_type : "";
|
||||
state.displayName = device->display_name ? device->display_name : "";
|
||||
}
|
||||
|
||||
irecv_close(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("Failed to open irecv client after retries");
|
||||
}
|
||||
|
||||
state.isSupported = SequenceIsSupported(state.productType);
|
||||
|
||||
#ifdef WITH_GUI
|
||||
send_device_state(frame, state);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#ifndef EVENT_H
|
||||
#define EVENT_H
|
||||
|
||||
#include "state.hpp"
|
||||
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include <libimobiledevice/libimobiledevice.h>
|
||||
#include <libimobiledevice/lockdown.h>
|
||||
#include <libirecovery.h>
|
||||
|
||||
class MainFrame;
|
||||
|
||||
void normal_device_event_cb(const idevice_event_t* event, void* user_data);
|
||||
void recovery_device_event_cb(const irecv_device_event_t* event, void* user_data);
|
||||
|
||||
#endif // EVENT_H
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -5,12 +5,6 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/usb/IOUSBLib.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_GUI
|
||||
# include <wx/wx.h>
|
||||
#endif
|
||||
@@ -21,9 +15,16 @@
|
||||
|
||||
void print_credits() {
|
||||
printf(
|
||||
":: ========================== ::\n"
|
||||
":: palera1n: " PALERAIN_VERSION "\n"
|
||||
":: ========================== ::\n\n"
|
||||
"#\n"
|
||||
"# palera1n: " PALERAIN_VERSION "\n"
|
||||
"#\n"
|
||||
"# ======== Made by =======\n"
|
||||
"# Made by: asdfugil, kok3shidoll, claration, mineek, staturnz\n"
|
||||
"# ======== Thanks to =======\n"
|
||||
"# Thanks to: llsc12, Nebula, Lrdsnow, nikias (libimobiledevice),\n"
|
||||
"# checkra1n team (Siguza, axi0mx, littlelailo et al.),\n"
|
||||
"# Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)\n"
|
||||
"# ==========================\n\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "gen/DFUHelperDeviceInfo.h"
|
||||
#include "sequence.hpp"
|
||||
|
||||
DfuSequence ParseSequence(const std::string& deviceKey)
|
||||
{
|
||||
DfuSequence seq;
|
||||
|
||||
static nlohmann::json j = nlohmann::json::parse(
|
||||
DFUHelperDeviceInfo,
|
||||
DFUHelperDeviceInfo + DFUHelperDeviceInfo_len
|
||||
);
|
||||
|
||||
auto itMap = j["devicemap"].find(deviceKey);
|
||||
if (itMap == j["devicemap"].end())
|
||||
return seq;
|
||||
|
||||
const std::string deviceType = itMap.value();
|
||||
|
||||
auto itLayout = j["devicelayout"].find(deviceType);
|
||||
if (itLayout == j["devicelayout"].end())
|
||||
return seq;
|
||||
|
||||
const auto& layout = itLayout.value();
|
||||
|
||||
seq.imageName = layout.value("image_name", "");
|
||||
seq.imageWidth = layout.value("image_width", 0);
|
||||
seq.imageHeight = layout.value("image_height", 0);
|
||||
seq.imageOffsetX = layout.value("image_offset_x", 0);
|
||||
|
||||
if (layout.contains("buttons"))
|
||||
{
|
||||
for (auto it = layout["buttons"].begin();
|
||||
it != layout["buttons"].end();
|
||||
++it)
|
||||
{
|
||||
DfuButton btn;
|
||||
|
||||
btn.id = it.key();
|
||||
|
||||
const auto& b = it.value();
|
||||
|
||||
btn.name = b.value("name", "");
|
||||
btn.x = b.value("x", 0);
|
||||
btn.y = b.value("y", 0);
|
||||
|
||||
seq.buttons.push_back(std::move(btn));
|
||||
}
|
||||
}
|
||||
|
||||
const std::string sequenceKey =
|
||||
layout.value("sequence", "");
|
||||
|
||||
auto itSeq = j["sequences"].find(sequenceKey);
|
||||
if (itSeq == j["sequences"].end())
|
||||
return seq;
|
||||
|
||||
for (const auto& s : itSeq.value())
|
||||
{
|
||||
DfuStep step;
|
||||
|
||||
step.description = s.value("description", "");
|
||||
step.duration = s.value("duration", 0);
|
||||
step.action = s.value("action", "");
|
||||
|
||||
if (s.contains("buttons"))
|
||||
{
|
||||
for (const auto& b : s["buttons"])
|
||||
step.activeButtons.push_back(
|
||||
b.get<std::string>()
|
||||
);
|
||||
}
|
||||
|
||||
seq.steps.push_back(std::move(step));
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
bool SequenceIsSupported(const std::string& deviceKey)
|
||||
{
|
||||
DfuSequence seq = ParseSequence(deviceKey);
|
||||
return !seq.steps.empty();
|
||||
}
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#ifndef SEQUENCE_H
|
||||
#define SEQUENCE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
struct DfuButton
|
||||
{
|
||||
std::string id;
|
||||
std::string name;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
};
|
||||
|
||||
struct DfuStep
|
||||
{
|
||||
std::string description;
|
||||
int duration = 0;
|
||||
std::vector<std::string> activeButtons;
|
||||
std::string action;
|
||||
};
|
||||
|
||||
struct DfuSequence
|
||||
{
|
||||
std::string imageName;
|
||||
int imageWidth = 0;
|
||||
int imageHeight = 0;
|
||||
int imageOffsetX = 0;
|
||||
|
||||
std::vector<DfuButton> buttons;
|
||||
std::vector<DfuStep> steps;
|
||||
};
|
||||
|
||||
DfuSequence ParseSequence(const std::string& deviceKey);
|
||||
bool SequenceIsSupported(const std::string& deviceKey);
|
||||
|
||||
#endif // SEQUENCE_H
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef STATE_H
|
||||
#define STATE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
enum class DeviceMode
|
||||
{
|
||||
None,
|
||||
Normal,
|
||||
Recovery,
|
||||
DFU
|
||||
};
|
||||
|
||||
struct DeviceState
|
||||
{
|
||||
bool connected = false;
|
||||
bool isSupported = false;
|
||||
DeviceMode mode = DeviceMode::None;
|
||||
std::string productVersion;
|
||||
std::string productType;
|
||||
std::string displayName;
|
||||
std::string udid;
|
||||
uint64_t ecid;
|
||||
};
|
||||
|
||||
#endif // STATE_H
|
||||
@@ -1,209 +0,0 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include "app.hpp"
|
||||
#include <wx/wx.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/statline.h>
|
||||
#include <string>
|
||||
#include "../utils/constants.h"
|
||||
#include "../utils/paleinfo.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../exploit/logo.h"
|
||||
|
||||
class MainFrame;
|
||||
|
||||
class MainPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
explicit MainPanel(MainFrame* frame, wxWindow* parent);
|
||||
};
|
||||
|
||||
class SettingsPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
explicit SettingsPanel(MainFrame* frame, wxWindow* parent);
|
||||
};
|
||||
|
||||
class MainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MainFrame()
|
||||
: wxFrame(
|
||||
nullptr,
|
||||
wxID_ANY,
|
||||
"palera1n – Version beta " + wxString(PALERAIN_VERSION),
|
||||
wxDefaultPosition,
|
||||
wxSize(480, 360),
|
||||
wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER))
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_main = new MainPanel(this, this);
|
||||
m_settings = new SettingsPanel(this, this);
|
||||
|
||||
root->Add(m_main, 1, wxEXPAND);
|
||||
root->Add(m_settings, 1, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
|
||||
ShowMain();
|
||||
}
|
||||
|
||||
void ShowMain()
|
||||
{
|
||||
m_main->Show();
|
||||
m_settings->Hide();
|
||||
Layout();
|
||||
}
|
||||
|
||||
void ShowSettings()
|
||||
{
|
||||
m_main->Hide();
|
||||
m_settings->Show();
|
||||
Layout();
|
||||
}
|
||||
|
||||
private:
|
||||
MainPanel* m_main;
|
||||
SettingsPanel* m_settings;
|
||||
};
|
||||
|
||||
MainPanel::MainPanel(MainFrame* frame, wxWindow* parent)
|
||||
: wxPanel(parent)
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxInitAllImageHandlers();
|
||||
|
||||
wxMemoryInputStream stream(resources_logo_png, resources_logo_png_len);
|
||||
wxImage img(stream, wxBITMAP_TYPE_PNG);
|
||||
wxBitmap bmp(img);
|
||||
auto* logo = new wxStaticBitmap(this, wxID_ANY, bmp);
|
||||
|
||||
auto* titletext = new wxStaticText(this, wxID_ANY, "Welcome to palera1n!");
|
||||
wxFont titlefont = titletext->GetFont();
|
||||
titlefont.SetWeight(wxFONTWEIGHT_BOLD);
|
||||
titletext->SetFont(titlefont);
|
||||
|
||||
auto* left = new wxBoxSizer(wxVERTICAL);
|
||||
left->Add(titletext, 0, wxTOP | wxLEFT, 10);
|
||||
|
||||
auto* row = new wxBoxSizer(wxHORIZONTAL);
|
||||
row->Add(left, 0, wxALIGN_TOP);
|
||||
row->AddStretchSpacer();
|
||||
row->Add(logo, 0, wxTOP | wxRIGHT, 10);
|
||||
root->Add(row, 0, wxEXPAND);
|
||||
|
||||
root->Add(new wxStaticLine(this), 0, wxEXPAND | wxALL, 10);
|
||||
|
||||
auto* credtext = new wxStaticText(this, wxID_ANY, "Made by: asdfugil, kok3shidoll, claration, mineek, staturnz\n\nThanks to: itsnebulalol, llsc12, lrdsnow, nikias (libimobiledevice), Checkra1n\n(Siguza, axi0mx, littlelailo et al.), Procursus (Hayden Seay, Cameron Katri,\nKeto et al.)\n\nWith 💖 from C (claration)");
|
||||
root->Add(credtext, 0, wxLEFT | wxRIGHT, 10);
|
||||
|
||||
root->Add(new wxStaticLine(this), 0, wxEXPAND | wxALL, 10);
|
||||
|
||||
auto* notetext = new wxStaticText(this, wxID_ANY, "NOTE: Please ensure you have a backup of your device before applying the\njailbreak. While data loss is unlikely, we won't be responsible if something goes\nwrong. Use at your own risk.");
|
||||
wxFont notefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
notefont.SetPointSize(12);
|
||||
notefont.SetStyle(wxFONTSTYLE_ITALIC);
|
||||
notetext->SetFont(notefont);
|
||||
root->Add(notetext, 0, wxLEFT | wxRIGHT, 10);
|
||||
|
||||
root->AddStretchSpacer();
|
||||
|
||||
auto* btn = new wxButton(this, wxID_ANY, "Options");
|
||||
auto* sbtn = new wxButton(this, wxID_ANY, "Start");
|
||||
sbtn->Disable();
|
||||
btn->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
|
||||
{
|
||||
frame->ShowSettings();
|
||||
});
|
||||
auto* bottomRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
bottomRow->AddStretchSpacer();
|
||||
bottomRow->Add(btn, 0, wxALL, 10);
|
||||
bottomRow->Add(sbtn, 0, wxALL, 10);
|
||||
root->Add(bottomRow, 0, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
}
|
||||
|
||||
SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent)
|
||||
: wxPanel(parent)
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
root->Add(new wxStaticText(this, wxID_ANY,
|
||||
"You may set the following options. If you don't know what they mean you'll\n"
|
||||
"probably have no reason to set them."), 0, wxALL, 10);
|
||||
|
||||
auto* option_safemode = new wxCheckBox(this, wxID_ANY, "Safe Mode");
|
||||
auto* option_verbose = new wxCheckBox(this, wxID_ANY, "Verbose Boot");
|
||||
auto* option_revert = new wxCheckBox(this, wxID_ANY, "Restore System");
|
||||
auto* option_dark_blockchain = new wxCheckBox(this, wxID_ANY, "Dark Blockchain");
|
||||
|
||||
option_safemode->SetValue(palerain_flags & palerain_option_safemode);
|
||||
option_verbose->SetValue(palerain_flags & palerain_option_verbose_boot);
|
||||
option_revert->SetValue(palerain_flags & palerain_option_force_revert);
|
||||
option_dark_blockchain->SetValue(true);
|
||||
|
||||
option_safemode->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
|
||||
{
|
||||
if (e.IsChecked())
|
||||
palerain_flags |= palerain_option_safemode;
|
||||
else
|
||||
palerain_flags &= ~palerain_option_safemode;
|
||||
});
|
||||
option_verbose->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
|
||||
{
|
||||
if (e.IsChecked())
|
||||
palerain_flags |= palerain_option_verbose_boot;
|
||||
else
|
||||
palerain_flags &= ~palerain_option_verbose_boot;
|
||||
});
|
||||
option_revert->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
|
||||
{
|
||||
if (e.IsChecked())
|
||||
palerain_flags |= palerain_option_force_revert;
|
||||
else
|
||||
palerain_flags &= ~palerain_option_force_revert;
|
||||
});
|
||||
|
||||
root->Add(option_safemode, 0, wxLEFT | wxRIGHT, 10);
|
||||
root->Add(option_verbose, 0, wxLEFT | wxRIGHT | wxTOP, 10);
|
||||
|
||||
root->Add(new wxStaticText(this, wxID_ANY, "Boot Arguments:"), 0, wxALL, 10);
|
||||
auto* bootArgs = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize);
|
||||
root->Add(bootArgs, 0, wxLEFT | wxRIGHT | wxEXPAND, 30);
|
||||
|
||||
root->Add(option_revert, 0, wxLEFT | wxRIGHT | wxTOP, 10);
|
||||
root->Add(option_dark_blockchain, 0, wxLEFT | wxRIGHT | wxTOP, 10);
|
||||
|
||||
root->AddStretchSpacer();
|
||||
|
||||
auto* back = new wxButton(this, wxID_ANY, "Back");
|
||||
|
||||
back->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
|
||||
{
|
||||
frame->ShowMain();
|
||||
});
|
||||
|
||||
auto* bottomRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
bottomRow->AddStretchSpacer();
|
||||
bottomRow->Add(back, 0, wxALL, 10);
|
||||
|
||||
root->Add(bottomRow, 0, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
}
|
||||
|
||||
bool PalerainApp::OnInit()
|
||||
{
|
||||
auto* frame = new MainFrame();
|
||||
frame->Show(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
wxIMPLEMENT_APP_NO_MAIN(PalerainApp);
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifdef WITH_GUI
|
||||
#pragma once
|
||||
#include <wx/wx.h>
|
||||
|
||||
class PalerainApp : public wxApp {
|
||||
public:
|
||||
bool OnInit() override;
|
||||
};
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
|
||||
#define PALERAIN_VERSION "2.4.0"
|
||||
#define PALERAIN_VERSION "3.0.0"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include "AppFrame.hpp"
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include "../utils/constants.h"
|
||||
#include "../event.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <libimobiledevice/libimobiledevice.h>
|
||||
#include <libimobiledevice/lockdown.h>
|
||||
#include <libirecovery.h>
|
||||
|
||||
wxDEFINE_EVENT(EVT_DEVICE_STATE_UPDATE, wxCommandEvent);
|
||||
|
||||
void send_device_state(MainFrame* frame, const DeviceState& state)
|
||||
{
|
||||
wxTheApp->CallAfter([frame, state]() {
|
||||
auto* evt = new wxCommandEvent(EVT_DEVICE_STATE_UPDATE);
|
||||
evt->SetClientData(new DeviceState(state));
|
||||
wxPostEvent(frame, *evt);
|
||||
});
|
||||
}
|
||||
|
||||
MainFrame::MainFrame()
|
||||
: wxFrame(nullptr,
|
||||
wxID_ANY,
|
||||
"palera1n – Version beta " + wxString(PALERAIN_VERSION),
|
||||
wxDefaultPosition,
|
||||
wxSize(480, 360),
|
||||
wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER))
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_main = new MainPanel(this, this);
|
||||
m_settings = new SettingsPanel(this, this);
|
||||
m_recovery = new RecoveryPanel(this, this);
|
||||
m_dfu = new DfuPanel(this, this);
|
||||
m_exploit = new ExploitPanel(this, this);
|
||||
|
||||
root->Add(m_main, 1, wxEXPAND);
|
||||
root->Add(m_settings, 1, wxEXPAND);
|
||||
root->Add(m_recovery, 1, wxEXPAND);
|
||||
root->Add(m_dfu, 1, wxEXPAND);
|
||||
root->Add(m_exploit, 1, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
|
||||
Bind(EVT_DEVICE_STATE_UPDATE, [this](wxCommandEvent& e)
|
||||
{
|
||||
auto* state = static_cast<DeviceState*>(e.GetClientData());
|
||||
|
||||
if (!state)
|
||||
return;
|
||||
|
||||
UpdateDeviceState(*state);
|
||||
|
||||
delete state;
|
||||
});
|
||||
|
||||
ShowMain();
|
||||
|
||||
std::thread([this]()
|
||||
{
|
||||
idevice_event_subscribe(normal_device_event_cb, this);
|
||||
|
||||
while (true)
|
||||
sleep(1);
|
||||
}).detach();
|
||||
|
||||
std::thread([this]()
|
||||
{
|
||||
static irecv_device_event_context_t ctx = nullptr;
|
||||
|
||||
irecv_device_event_subscribe(
|
||||
&ctx,
|
||||
recovery_device_event_cb,
|
||||
this
|
||||
);
|
||||
|
||||
while (true)
|
||||
sleep(1);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
void MainFrame::ShowMain()
|
||||
{
|
||||
m_main->Show();
|
||||
m_settings->Hide();
|
||||
m_recovery->Hide();
|
||||
m_dfu->Hide();
|
||||
m_exploit->Hide();
|
||||
Layout();
|
||||
}
|
||||
|
||||
void MainFrame::ShowSettings()
|
||||
{
|
||||
m_main->Hide();
|
||||
m_settings->Show();
|
||||
m_recovery->Hide();
|
||||
m_dfu->Hide();
|
||||
m_exploit->Hide();
|
||||
Layout();
|
||||
}
|
||||
|
||||
void MainFrame::ShowRecovery()
|
||||
{
|
||||
m_main->Hide();
|
||||
m_settings->Hide();
|
||||
m_recovery->Show();
|
||||
m_dfu->Hide();
|
||||
m_exploit->Hide();
|
||||
Layout();
|
||||
}
|
||||
|
||||
void MainFrame::ShowDfu()
|
||||
{
|
||||
m_main->Hide();
|
||||
m_settings->Hide();
|
||||
m_recovery->Hide();
|
||||
m_dfu->Show();
|
||||
m_dfu->LoadDevice(m_state.productType);
|
||||
m_exploit->Hide();
|
||||
Layout();
|
||||
}
|
||||
|
||||
void MainFrame::ShowExploit()
|
||||
{
|
||||
m_main->Hide();
|
||||
m_settings->Hide();
|
||||
m_recovery->Hide();
|
||||
m_dfu->Hide();
|
||||
m_exploit->Show();
|
||||
m_exploit->StartExploit();
|
||||
Layout();
|
||||
}
|
||||
|
||||
void MainFrame::UpdateDeviceState(const DeviceState& state)
|
||||
{
|
||||
m_state = state;
|
||||
|
||||
if (m_main)
|
||||
m_main->SetDeviceState(m_state);
|
||||
|
||||
if (m_recovery)
|
||||
m_recovery->SetDeviceState(m_state);
|
||||
|
||||
if (m_dfu)
|
||||
m_dfu->SetDeviceState(m_state);
|
||||
|
||||
if (m_exploit)
|
||||
m_exploit->SetDeviceState(m_state);
|
||||
}
|
||||
|
||||
bool PalerainApp::OnInit()
|
||||
{
|
||||
auto* frame = new MainFrame();
|
||||
frame->Show(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
wxIMPLEMENT_APP_NO_MAIN(PalerainApp);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef APPFRAME_H
|
||||
#define APPFRAME_H
|
||||
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include "../state.hpp"
|
||||
|
||||
#include "MainPanel.hpp"
|
||||
#include "SettingsPanel.hpp"
|
||||
#include "RecoveryPanel.hpp"
|
||||
#include "DfuPanel.hpp"
|
||||
#include "ExploitPanel.hpp"
|
||||
|
||||
void send_device_state(MainFrame* frame, const DeviceState& state);
|
||||
|
||||
class MainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MainFrame();
|
||||
|
||||
void ShowMain();
|
||||
void ShowSettings();
|
||||
void ShowRecovery();
|
||||
void ShowDfu();
|
||||
void ShowExploit();
|
||||
|
||||
const DeviceState& GetDeviceState() const { return m_state; }
|
||||
void UpdateDeviceState(const DeviceState& state);
|
||||
|
||||
MainPanel* GetMainPanel() const { return m_main; }
|
||||
SettingsPanel* GetSettingsPanel() const { return m_settings; }
|
||||
RecoveryPanel* GetRecoveryPanel() const { return m_recovery; }
|
||||
DfuPanel* GetDfuPanel() const { return m_dfu; }
|
||||
ExploitPanel* GetExploitPanel() const { return m_exploit; }
|
||||
private:
|
||||
MainPanel* m_main = nullptr;
|
||||
SettingsPanel* m_settings = nullptr;
|
||||
RecoveryPanel* m_recovery = nullptr;
|
||||
DfuPanel* m_dfu = nullptr;
|
||||
ExploitPanel* m_exploit = nullptr;
|
||||
|
||||
DeviceState m_state;
|
||||
};
|
||||
|
||||
class PalerainApp : public wxApp {
|
||||
public:
|
||||
bool OnInit() override;
|
||||
};
|
||||
|
||||
#endif // WITH_GUI
|
||||
|
||||
#endif // APPFRAME_H
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef DEVICEPANEL_H
|
||||
#define DEVICEPANEL_H
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include "../state.hpp"
|
||||
|
||||
class MainFrame;
|
||||
class DevicePanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
DevicePanel(MainFrame* frame, wxWindow* parent)
|
||||
: wxPanel(parent),
|
||||
m_frame(frame)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void SetDeviceState(const DeviceState& state)
|
||||
{
|
||||
m_deviceState = state;
|
||||
}
|
||||
|
||||
protected:
|
||||
MainFrame* GetMainFrame() const
|
||||
{
|
||||
return m_frame;
|
||||
}
|
||||
|
||||
const DeviceState& GetDeviceState() const
|
||||
{
|
||||
return m_deviceState;
|
||||
}
|
||||
|
||||
private:
|
||||
MainFrame* m_frame;
|
||||
DeviceState m_deviceState;
|
||||
};
|
||||
|
||||
#endif // DEVICEPANEL_H
|
||||
@@ -0,0 +1,427 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include "DfuPanel.hpp"
|
||||
|
||||
#include "AppFrame.hpp"
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
#include "../sequence.hpp"
|
||||
#include "../utils/log.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/bitmap.h>
|
||||
|
||||
#include "../gen/images/atv_std_brd.h"
|
||||
#include "../gen/images/ipad.h"
|
||||
#include "../gen/images/ipadmini.h"
|
||||
#include "../gen/images/iphone6s.h"
|
||||
#include "../gen/images/iphone7.h"
|
||||
#include "../gen/images/iphone8.h"
|
||||
#include "../gen/images/iphonese.h"
|
||||
#include "../gen/images/iphonex.h"
|
||||
#include "../gen/images/ipodtouch.h"
|
||||
#include "../gen/images/siriremote.h"
|
||||
|
||||
#include <libirecovery.h>
|
||||
|
||||
static const wxColour kActive =
|
||||
wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
|
||||
|
||||
static const wxColour kInactive =
|
||||
wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
|
||||
|
||||
DfuPanel::DfuPanel(MainFrame* frame, wxWindow* parent)
|
||||
: DevicePanel(frame, parent)
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_headerText = new wxStaticText(this, wxID_ANY, "Time to put the device into DFU mode. Locate the buttons as marked below\non your device and check the instructions on the right.");
|
||||
root->Add(m_headerText, 0, wxALL, 10);
|
||||
|
||||
auto* contentRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_devicePanel = new wxPanel(this);
|
||||
m_devicePanel->SetMinSize(wxSize(310, 260));
|
||||
|
||||
m_deviceImage = new wxStaticBitmap(
|
||||
m_devicePanel,
|
||||
wxID_ANY,
|
||||
wxBitmap()
|
||||
);
|
||||
|
||||
contentRow->Add(m_devicePanel, 1, wxTOP, 10);
|
||||
m_stepsSizer = new wxBoxSizer(wxVERTICAL);
|
||||
contentRow->Add(m_stepsSizer, 2, wxEXPAND | wxALL, 0);
|
||||
|
||||
root->Add(contentRow, 1, wxEXPAND);
|
||||
|
||||
m_backButton = new wxButton(this, wxID_ANY, "Back");
|
||||
m_startButton = new wxButton(this, wxID_ANY, "Start");
|
||||
|
||||
m_backButton->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
|
||||
{
|
||||
frame->ShowMain();
|
||||
});
|
||||
|
||||
m_startButton->Bind(wxEVT_BUTTON, [this](wxCommandEvent&)
|
||||
{
|
||||
m_isEnteringDfu = true;
|
||||
m_backButton->Disable();
|
||||
m_startButton->Disable();
|
||||
|
||||
StartSequence(m_sequence);
|
||||
});
|
||||
|
||||
m_timer.Bind(wxEVT_TIMER, [this](wxTimerEvent&)
|
||||
{
|
||||
RunStep();
|
||||
});
|
||||
|
||||
m_stagnentTimer.Bind(wxEVT_TIMER, [this](wxTimerEvent&)
|
||||
{
|
||||
m_backButton->Enable();
|
||||
m_startButton->Enable();
|
||||
GetMainFrame()->ShowExploit();
|
||||
});
|
||||
|
||||
auto* bottomRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
bottomRow->AddStretchSpacer();
|
||||
bottomRow->Add(m_backButton, 0, wxALL, 10);
|
||||
bottomRow->Add(m_startButton, 0, wxALL, 10);
|
||||
|
||||
root->Add(bottomRow, 0, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
}
|
||||
|
||||
void DfuPanel::SetDeviceState(const DeviceState& state)
|
||||
{
|
||||
DevicePanel::SetDeviceState(state);
|
||||
|
||||
if (!(this->IsShown()))
|
||||
return;
|
||||
|
||||
if (m_isEnteringDfu && state.mode == DeviceMode::DFU)
|
||||
{
|
||||
m_isEnteringDfu = false;
|
||||
m_headerText->SetLabel("Device entered DFU mode successfully.\n");
|
||||
|
||||
if (!m_stagnentTimer.IsRunning())
|
||||
m_stagnentTimer.StartOnce(3000);
|
||||
}
|
||||
|
||||
if (m_isEnteringDfu && state.mode == DeviceMode::Normal)
|
||||
{
|
||||
m_isEnteringDfu = false;
|
||||
m_backButton->Enable();
|
||||
m_startButton->Enable();
|
||||
GetMainFrame()->ShowRecovery();
|
||||
GetMainFrame()->GetRecoveryPanel()->SetStatusText("Hmm... It seems like the device didn't enter DFU mode.");
|
||||
}
|
||||
|
||||
if (m_isEnteringDfu && state.mode == DeviceMode::Recovery)
|
||||
{
|
||||
m_isEnteringDfu = false;
|
||||
m_backButton->Enable();
|
||||
m_startButton->Enable();
|
||||
GetMainFrame()->ShowMain();
|
||||
}
|
||||
}
|
||||
|
||||
void DfuPanel::LoadDevice(const std::string& productType)
|
||||
{
|
||||
m_sequence = ParseSequence(productType);
|
||||
m_index = 0;
|
||||
|
||||
m_deviceImage->SetBitmap(wxBitmap());
|
||||
|
||||
for (auto* lbl : m_stepLabels)
|
||||
lbl->Destroy();
|
||||
|
||||
m_stepLabels.clear();
|
||||
m_stepsSizer->Clear(false);
|
||||
|
||||
for (auto* lbl : m_buttonLabels)
|
||||
lbl->Destroy();
|
||||
|
||||
m_buttonLabels.clear();
|
||||
|
||||
const unsigned char* imageData = nullptr;
|
||||
size_t imageSize = 0;
|
||||
|
||||
if (m_sequence.imageName == "ipadmini")
|
||||
{
|
||||
imageData = ipadmini;
|
||||
imageSize = ipadmini_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "ipad")
|
||||
{
|
||||
imageData = ipad;
|
||||
imageSize = ipad_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "iphonese")
|
||||
{
|
||||
imageData = iphonese;
|
||||
imageSize = iphonese_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "iphone6s")
|
||||
{
|
||||
imageData = iphone6s;
|
||||
imageSize = iphone6s_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "iphone7")
|
||||
{
|
||||
imageData = iphone7;
|
||||
imageSize = iphone7_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "iphone8")
|
||||
{
|
||||
imageData = iphone8;
|
||||
imageSize = iphone8_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "iphonex")
|
||||
{
|
||||
imageData = iphonex;
|
||||
imageSize = iphonex_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "ipodtouch")
|
||||
{
|
||||
imageData = ipodtouch;
|
||||
imageSize = ipodtouch_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "siriremote")
|
||||
{
|
||||
imageData = siriremote;
|
||||
imageSize = siriremote_len;
|
||||
}
|
||||
else if (m_sequence.imageName == "atv_std_brd")
|
||||
{
|
||||
imageData = atv_std_brd;
|
||||
imageSize = atv_std_brd_len;
|
||||
}
|
||||
|
||||
if (imageData)
|
||||
{
|
||||
wxMemoryInputStream stream(imageData, imageSize);
|
||||
|
||||
wxImage img(stream, wxBITMAP_TYPE_PNG);
|
||||
|
||||
if (img.IsOk())
|
||||
{
|
||||
img = img.Scale(
|
||||
m_sequence.imageWidth,
|
||||
m_sequence.imageHeight,
|
||||
wxIMAGE_QUALITY_HIGH
|
||||
);
|
||||
|
||||
m_deviceImage->SetBitmap(wxBitmap(img));
|
||||
m_deviceImage->SetPosition(wxPoint(m_sequence.imageOffsetX, 0));
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& button : m_sequence.buttons)
|
||||
{
|
||||
auto* lbl = new wxStaticText(
|
||||
m_devicePanel,
|
||||
wxID_ANY,
|
||||
button.name
|
||||
);
|
||||
|
||||
lbl->SetPosition(wxPoint(button.x, button.y));
|
||||
|
||||
m_buttonLabels.push_back(lbl);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_sequence.steps.size(); i++)
|
||||
{
|
||||
const auto& step = m_sequence.steps[i];
|
||||
|
||||
wxString label = wxString::Format(
|
||||
"%zu. %s (%d)",
|
||||
i + 1,
|
||||
step.description,
|
||||
step.duration
|
||||
);
|
||||
|
||||
auto* lbl = new wxStaticText(
|
||||
this,
|
||||
wxID_ANY,
|
||||
label
|
||||
);
|
||||
|
||||
lbl->SetForegroundColour(i == 0 ? kActive : kInactive);
|
||||
|
||||
m_stepsSizer->Add(lbl, 0, wxBOTTOM, 5);
|
||||
m_stepLabels.push_back(lbl);
|
||||
}
|
||||
|
||||
m_devicePanel->Layout();
|
||||
m_stepsSizer->Layout();
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void DfuPanel::StartSequence(const DfuSequence& seq)
|
||||
{
|
||||
m_sequence = seq;
|
||||
m_index = 0;
|
||||
m_stepRemaining = -1;
|
||||
m_actionExecutedIndex = -1;
|
||||
|
||||
RunStep();
|
||||
m_timer.StartOnce(1000);
|
||||
}
|
||||
|
||||
void DfuPanel::RunStep()
|
||||
{
|
||||
if (m_sequence.steps.empty())
|
||||
return;
|
||||
|
||||
if (m_index >= m_sequence.steps.size())
|
||||
{
|
||||
for (auto* lbl : m_stepLabels)
|
||||
lbl->SetForegroundColour(kInactive);
|
||||
|
||||
Layout();
|
||||
Refresh();
|
||||
|
||||
m_timer.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& step = m_sequence.steps[m_index];
|
||||
|
||||
if (m_stepRemaining < 0)
|
||||
m_stepRemaining = step.duration;
|
||||
|
||||
if (m_stepRemaining > 0)
|
||||
--m_stepRemaining;
|
||||
|
||||
bool finished = (m_stepRemaining == 0);
|
||||
size_t completedIndex = m_index;
|
||||
|
||||
if (finished)
|
||||
{
|
||||
++m_index;
|
||||
m_stepRemaining = -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_stepLabels.size(); i++)
|
||||
{
|
||||
auto* lbl = m_stepLabels[i];
|
||||
|
||||
if (i == m_index)
|
||||
{
|
||||
lbl->SetForegroundColour(kActive);
|
||||
|
||||
lbl->SetLabel(wxString::Format(
|
||||
"%zu. %s (%d)",
|
||||
i + 1,
|
||||
m_sequence.steps[i].description,
|
||||
m_stepRemaining < 0 ? m_sequence.steps[i].duration : m_stepRemaining
|
||||
));
|
||||
}
|
||||
else if (finished && i == completedIndex)
|
||||
{
|
||||
lbl->SetForegroundColour(kInactive);
|
||||
|
||||
lbl->SetLabel(wxString::Format(
|
||||
"%zu. %s (0)",
|
||||
i + 1,
|
||||
m_sequence.steps[i].description
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
lbl->SetForegroundColour(kInactive);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* lbl : m_buttonLabels)
|
||||
lbl->SetForegroundColour(kInactive);
|
||||
|
||||
const auto& activeStep =
|
||||
(m_index < m_sequence.steps.size())
|
||||
? m_sequence.steps[m_index]
|
||||
: m_sequence.steps.back();
|
||||
|
||||
for (const auto& buttonId : activeStep.activeButtons)
|
||||
{
|
||||
for (const auto& btn : m_sequence.buttons)
|
||||
{
|
||||
if (btn.id == buttonId)
|
||||
{
|
||||
for (auto* lbl : m_buttonLabels)
|
||||
{
|
||||
if (lbl->GetLabel() == btn.name)
|
||||
lbl->SetForegroundColour(kActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_index < m_sequence.steps.size())
|
||||
{
|
||||
const auto& activeStep = m_sequence.steps[m_index];
|
||||
|
||||
if (!activeStep.action.empty() && m_actionExecutedIndex != m_index)
|
||||
{
|
||||
m_actionExecutedIndex = m_index;
|
||||
|
||||
if (activeStep.action == "reboot")
|
||||
{
|
||||
Reboot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Layout();
|
||||
Refresh();
|
||||
Update();
|
||||
|
||||
m_timer.StartOnce(1000);
|
||||
}
|
||||
|
||||
void DfuPanel::Reboot()
|
||||
{
|
||||
std::thread([this]()
|
||||
{
|
||||
const auto state = GetDeviceState();
|
||||
|
||||
if (!state.connected || state.mode != DeviceMode::Recovery)
|
||||
return;
|
||||
|
||||
irecv_client_t client = nullptr;
|
||||
|
||||
int attempts = 0;
|
||||
const int max_attempts = 8;
|
||||
|
||||
while (attempts < max_attempts)
|
||||
{
|
||||
if (irecv_open_with_ecid(&client, state.ecid) == IRECV_E_SUCCESS)
|
||||
break;
|
||||
|
||||
attempts++;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
}
|
||||
|
||||
if (!client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
irecv_setenv(client, "auto-boot", "true");
|
||||
irecv_saveenv(client);
|
||||
irecv_reboot(client);
|
||||
|
||||
irecv_close(client);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef DFUPANEL_H
|
||||
#define DFUPANEL_H
|
||||
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
#include "../sequence.hpp"
|
||||
|
||||
class DfuPanel;
|
||||
class DfuPanel : public DevicePanel
|
||||
{
|
||||
public:
|
||||
explicit DfuPanel(MainFrame* frame, wxWindow* parent);
|
||||
void SetDeviceState(const DeviceState& state) override;
|
||||
void LoadDevice(const std::string& productType);
|
||||
void StartSequence(const DfuSequence& seq);
|
||||
void RunStep();
|
||||
void Reboot();
|
||||
private:
|
||||
wxStaticText* m_headerText = nullptr;
|
||||
wxButton* m_backButton = nullptr;
|
||||
wxButton* m_startButton = nullptr;
|
||||
|
||||
wxBoxSizer* m_stepsSizer = nullptr;
|
||||
|
||||
std::vector<wxStaticText*> m_stepLabels;
|
||||
|
||||
DfuSequence m_sequence;
|
||||
size_t m_index = 0;
|
||||
int m_stepRemaining = 0;
|
||||
|
||||
wxTimer m_timer;
|
||||
wxTimer m_stagnentTimer;
|
||||
bool m_isEnteringDfu = false;
|
||||
|
||||
wxPanel* m_devicePanel = nullptr;
|
||||
wxStaticBitmap* m_deviceImage = nullptr;
|
||||
std::vector<wxStaticText*> m_buttonLabels;
|
||||
size_t m_actionExecutedIndex = std::numeric_limits<size_t>::max();
|
||||
};
|
||||
|
||||
|
||||
#endif // WITH_GUI
|
||||
|
||||
#endif // DFUPANEL_H
|
||||
@@ -0,0 +1,72 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include "ExploitPanel.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include "AppFrame.hpp"
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
#include "../utils/log.h"
|
||||
|
||||
ExploitPanel::ExploitPanel(MainFrame* frame, wxWindow* parent)
|
||||
: DevicePanel(frame, parent)
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
auto* text = new wxStaticText(this, wxID_ANY,
|
||||
"Installing jailbreak, this will take a moment. If the device asks for a passcode\nplease enter it. Do not disconnect the device until finished.");
|
||||
|
||||
m_statusText = new wxStaticText(this, wxID_ANY, "");
|
||||
|
||||
root->Add(text, 0, wxALL, 10);
|
||||
root->Add(m_statusText, 0, wxALL, 10);
|
||||
|
||||
m_backButton = new wxButton(this, wxID_ANY, "Back");
|
||||
m_backButton->Disable();
|
||||
m_backButton->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
|
||||
{
|
||||
frame->ShowMain();
|
||||
});
|
||||
|
||||
auto* bottomRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
bottomRow->AddStretchSpacer();
|
||||
bottomRow->Add(m_backButton, 0, wxALL, 10);
|
||||
|
||||
root->AddStretchSpacer();
|
||||
root->Add(bottomRow, 0, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
}
|
||||
|
||||
void ExploitPanel::SetDeviceState(const DeviceState& state)
|
||||
{
|
||||
DevicePanel::SetDeviceState(state);
|
||||
|
||||
if (!(this->IsShown()))
|
||||
return;
|
||||
|
||||
if (state.mode == DeviceMode::Normal)
|
||||
{
|
||||
m_statusText->SetLabel("Done.");
|
||||
m_backButton->Enable();
|
||||
}
|
||||
}
|
||||
|
||||
void ExploitPanel::StartExploit()
|
||||
{
|
||||
m_statusText->SetLabel("Exploiting device...");
|
||||
m_backButton->Disable();
|
||||
|
||||
std::thread([this]()
|
||||
{
|
||||
const auto state = GetDeviceState();
|
||||
if (!state.connected || state.mode != DeviceMode::DFU)
|
||||
return;
|
||||
|
||||
LOG("Starting exploit on worker thread...");
|
||||
}).detach();
|
||||
}
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef EXPLOITPANEL_HPP
|
||||
#define EXPLOITPANEL_HPP
|
||||
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
|
||||
class ExploitPanel;
|
||||
class ExploitPanel : public DevicePanel
|
||||
{
|
||||
public:
|
||||
explicit ExploitPanel(MainFrame* frame, wxWindow* parent);
|
||||
void SetDeviceState(const DeviceState& state) override;
|
||||
void StartExploit();
|
||||
private:
|
||||
wxButton* m_backButton = nullptr;
|
||||
wxStaticText* m_statusText = nullptr;
|
||||
};
|
||||
|
||||
#endif // WITH_GUI
|
||||
|
||||
#endif // EXPLOITPANEL_HPP
|
||||
@@ -0,0 +1,164 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include "MainPanel.hpp"
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/statline.h>
|
||||
|
||||
#include "AppFrame.hpp"
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
|
||||
#include "../gen/images/logo.h"
|
||||
|
||||
const char* deviceTextString = "Connect your iPhone, iPod touch, iPad, or AppleTV to begin.";
|
||||
|
||||
MainPanel::MainPanel(MainFrame* frame, wxWindow* parent)
|
||||
: DevicePanel(frame, parent)
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxInitAllImageHandlers();
|
||||
|
||||
wxMemoryInputStream stream(logo, logo_len);
|
||||
wxImage img(stream, wxBITMAP_TYPE_PNG);
|
||||
wxBitmap bmp(img);
|
||||
|
||||
auto* logo = new wxStaticBitmap(this, wxID_ANY, bmp);
|
||||
|
||||
auto* titletext = new wxStaticText(this, wxID_ANY, "Welcome to palera1n!");
|
||||
wxFont titlefont = titletext->GetFont();
|
||||
titlefont.SetWeight(wxFONTWEIGHT_BOLD);
|
||||
titletext->SetFont(titlefont);
|
||||
|
||||
m_deviceText = new wxStaticText(
|
||||
this,
|
||||
wxID_ANY,
|
||||
deviceTextString
|
||||
);
|
||||
|
||||
auto* left = new wxBoxSizer(wxVERTICAL);
|
||||
left->Add(titletext, 0, wxTOP | wxLEFT, 10);
|
||||
left->Add(m_deviceText, 0, wxTOP | wxLEFT, 10);
|
||||
|
||||
auto* row = new wxBoxSizer(wxHORIZONTAL);
|
||||
row->Add(left, 0, wxALIGN_TOP);
|
||||
row->AddStretchSpacer();
|
||||
row->Add(logo, 0, wxTOP | wxRIGHT, 10);
|
||||
|
||||
root->Add(row, 0, wxEXPAND);
|
||||
|
||||
root->Add(new wxStaticLine(this), 0, wxEXPAND | wxALL, 10);
|
||||
|
||||
auto* credtext = new wxStaticText(this, wxID_ANY,
|
||||
"Made by: asdfugil, kok3shidoll, claration, mineek, staturnz\n\n"
|
||||
"Thanks to: itsnebulalol, llsc12, lrdsnow, nikias (libimobiledevice), Checkra1n\n"
|
||||
"(Siguza, axi0mx, littlelailo et al.), Procursus (Hayden Seay, Cameron Katri,\n"
|
||||
"Keto et al.)\n\n"
|
||||
"With 💖 from C (claration)");
|
||||
|
||||
root->Add(credtext, 0, wxLEFT | wxRIGHT, 10);
|
||||
|
||||
root->Add(new wxStaticLine(this), 0, wxEXPAND | wxALL, 10);
|
||||
|
||||
auto* notetext = new wxStaticText(this, wxID_ANY,
|
||||
"NOTE: Please ensure you have a backup of your device before applying the\n"
|
||||
"jailbreak. While data loss is unlikely, we won't be responsible if something goes\n"
|
||||
"wrong. Use at your own risk.");
|
||||
|
||||
wxFont notefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
notefont.SetPointSize(12);
|
||||
notefont.SetStyle(wxFONTSTYLE_ITALIC);
|
||||
notetext->SetFont(notefont);
|
||||
|
||||
root->Add(notetext, 0, wxLEFT | wxRIGHT, 10);
|
||||
|
||||
root->AddStretchSpacer();
|
||||
|
||||
auto* btn = new wxButton(this, wxID_ANY, "Options");
|
||||
m_startButton = new wxButton(this, wxID_ANY, "Start");
|
||||
m_startButton->Disable();
|
||||
|
||||
btn->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
|
||||
{
|
||||
frame->ShowSettings();
|
||||
});
|
||||
|
||||
m_startButton->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
|
||||
{
|
||||
if (frame->GetDeviceState().mode == DeviceMode::Normal)
|
||||
{
|
||||
frame->ShowRecovery();
|
||||
}
|
||||
else if (frame->GetDeviceState().mode == DeviceMode::Recovery)
|
||||
{
|
||||
frame->ShowDfu();
|
||||
}
|
||||
});
|
||||
|
||||
auto* bottomRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
bottomRow->AddStretchSpacer();
|
||||
bottomRow->Add(btn, 0, wxALL, 10);
|
||||
bottomRow->Add(m_startButton, 0, wxALL, 10);
|
||||
|
||||
root->Add(bottomRow, 0, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
}
|
||||
|
||||
void MainPanel::SetDeviceState(const DeviceState& state)
|
||||
{
|
||||
DevicePanel::SetDeviceState(state);
|
||||
|
||||
if (m_deviceText)
|
||||
{
|
||||
if (!state.connected)
|
||||
{
|
||||
m_deviceText->SetLabel(deviceTextString);
|
||||
m_startButton->Enable(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string versionString =
|
||||
state.productVersion.empty() ? "Unknown" : state.productVersion;
|
||||
const std::string productString =
|
||||
state.productType.empty() ? "Unknown" : state.productType;
|
||||
const std::string ecidString = state.ecid != 0 ? ("ECID: " + std::to_string(state.ecid)) : "ECID: Unknown";
|
||||
|
||||
switch (state.mode)
|
||||
{
|
||||
case DeviceMode::Normal:
|
||||
if (state.isSupported) {
|
||||
m_deviceText->SetLabel("Connected " + productString + " (iOS " + versionString + ") in normal mode.\n" + ecidString);
|
||||
m_startButton->Enable();
|
||||
} else {
|
||||
m_deviceText->SetLabel("Sorry, " + productString + " (iOS " + versionString + ") is not supported.\n" + ecidString);
|
||||
m_startButton->Enable(false);
|
||||
}
|
||||
break;
|
||||
case DeviceMode::Recovery:
|
||||
if (state.isSupported) {
|
||||
m_deviceText->SetLabel("Connected " + productString + " in recovery mode.\n" + ecidString);
|
||||
m_startButton->Enable();
|
||||
} else {
|
||||
m_deviceText->SetLabel("Sorry, " + productString + " is not supported.\n" + ecidString);
|
||||
m_startButton->Enable(false);
|
||||
}
|
||||
break;
|
||||
case DeviceMode::DFU:
|
||||
m_deviceText->SetLabel("Sorry, DFU mode is not supported.");
|
||||
m_startButton->Enable(false);
|
||||
break;
|
||||
case DeviceMode::None:
|
||||
m_deviceText->SetLabel(deviceTextString);
|
||||
m_startButton->Enable(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef MAINPANEL_H
|
||||
#define MAINPANEL_H
|
||||
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
|
||||
class MainPanel;
|
||||
class MainPanel : public DevicePanel
|
||||
{
|
||||
public:
|
||||
explicit MainPanel(MainFrame* frame, wxWindow* parent);
|
||||
void SetDeviceState(const DeviceState& state) override;
|
||||
private:
|
||||
wxStaticText* m_deviceText = nullptr;
|
||||
wxButton* m_startButton = nullptr;
|
||||
};
|
||||
|
||||
#endif // WITH_GUI
|
||||
|
||||
#endif // MAINPANEL_H
|
||||
@@ -0,0 +1,130 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include "RecoveryPanel.hpp"
|
||||
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include "AppFrame.hpp"
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
|
||||
#include <libimobiledevice/libimobiledevice.h>
|
||||
#include <libimobiledevice/lockdown.h>
|
||||
#include <libirecovery.h>
|
||||
|
||||
RecoveryPanel::RecoveryPanel(MainFrame* frame, wxWindow* parent)
|
||||
: DevicePanel(frame, parent)
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
root->Add(new wxStaticText(this, wxID_ANY,
|
||||
"The device needs to be put into DFU mode to apply the jailbreak. This is a\n"
|
||||
"manual process and we will guide you through it.\n\n"
|
||||
"In order to prevent filesystem corruption through hard reset, the device will\n"
|
||||
"be put into recovery mode first. Click next when you are ready."), 0, wxALL, 10);
|
||||
|
||||
m_statusText = new wxStaticText(this, wxID_ANY, "");
|
||||
root->Add(m_statusText, 0, wxALL, 10);
|
||||
|
||||
m_backButton = new wxButton(this, wxID_ANY, "Back");
|
||||
m_nextButton = new wxButton(this, wxID_ANY, "Next");
|
||||
|
||||
m_backButton->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
|
||||
{
|
||||
frame->ShowMain();
|
||||
});
|
||||
|
||||
m_nextButton->Bind(wxEVT_BUTTON, [this](wxCommandEvent&)
|
||||
{
|
||||
m_statusText->SetLabel("Entering recovery mode...");
|
||||
m_backButton->Disable();
|
||||
m_nextButton->Disable();
|
||||
EnterRecoveryMode();
|
||||
});
|
||||
|
||||
m_timer.Bind(wxEVT_TIMER, [this](wxTimerEvent&)
|
||||
{
|
||||
m_backButton->Enable();
|
||||
m_nextButton->Enable();
|
||||
m_isEnteringRecovery = false;
|
||||
|
||||
GetMainFrame()->ShowDfu();
|
||||
m_statusText->SetLabel("");
|
||||
});
|
||||
|
||||
auto* bottomRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
bottomRow->AddStretchSpacer();
|
||||
bottomRow->Add(m_backButton, 0, wxALL, 10);
|
||||
bottomRow->Add(m_nextButton, 0, wxALL, 10);
|
||||
|
||||
root->AddStretchSpacer();
|
||||
root->Add(bottomRow, 0, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
}
|
||||
|
||||
void RecoveryPanel::SetDeviceState(const DeviceState& state)
|
||||
{
|
||||
DevicePanel::SetDeviceState(state);
|
||||
|
||||
if (!(this->IsShown()))
|
||||
return;
|
||||
|
||||
if (m_isEnteringRecovery && state.mode == DeviceMode::Recovery)
|
||||
{
|
||||
m_statusText->SetLabel("Device is now in recovery mode.");
|
||||
m_timer.StartOnce(3000);
|
||||
}
|
||||
|
||||
if (m_isEnteringRecovery && state.mode == DeviceMode::Normal)
|
||||
{
|
||||
m_isEnteringRecovery = false;
|
||||
m_statusText->SetLabel("Hmm... It seems like the device didn't enter recovery mode. Please try again.");
|
||||
m_backButton->Enable();
|
||||
m_nextButton->Enable();
|
||||
}
|
||||
|
||||
if (!m_isEnteringRecovery && state.mode == DeviceMode::None)
|
||||
{
|
||||
m_backButton->Enable();
|
||||
m_nextButton->Enable();
|
||||
GetMainFrame()->ShowMain();
|
||||
}
|
||||
}
|
||||
|
||||
void RecoveryPanel::EnterRecoveryMode()
|
||||
{
|
||||
const auto& state = GetDeviceState();
|
||||
|
||||
if (!state.connected)
|
||||
return;
|
||||
|
||||
idevice_t device = nullptr;
|
||||
lockdownd_client_t client = nullptr;
|
||||
|
||||
if (idevice_new(&device, state.udid.c_str()) != IDEVICE_E_SUCCESS)
|
||||
return;
|
||||
|
||||
if (lockdownd_client_new_with_handshake(
|
||||
device,
|
||||
&client,
|
||||
"palera1n") != LOCKDOWN_E_SUCCESS)
|
||||
{
|
||||
idevice_free(device);
|
||||
return;
|
||||
}
|
||||
|
||||
m_isEnteringRecovery = true;
|
||||
|
||||
lockdownd_enter_recovery(client);
|
||||
|
||||
lockdownd_client_free(client);
|
||||
idevice_free(device);
|
||||
}
|
||||
|
||||
void RecoveryPanel::SetStatusText(const wxString& text)
|
||||
{
|
||||
m_statusText->SetLabel(text);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef RECOVERYPANEL_H
|
||||
#define RECOVERYPANEL_H
|
||||
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include "DevicePanel.hpp"
|
||||
|
||||
class RecoveryPanel;
|
||||
class RecoveryPanel : public DevicePanel
|
||||
{
|
||||
public:
|
||||
explicit RecoveryPanel(MainFrame* frame, wxWindow* parent);
|
||||
void SetDeviceState(const DeviceState& state) override;
|
||||
void SetStatusText(const wxString& text);
|
||||
void EnterRecoveryMode();
|
||||
private:
|
||||
wxButton* m_backButton = nullptr;
|
||||
wxButton* m_nextButton = nullptr;
|
||||
wxStaticText* m_statusText = nullptr;
|
||||
wxTimer m_timer;
|
||||
bool m_isEnteringRecovery = false;
|
||||
};
|
||||
|
||||
|
||||
#endif // WITH_GUI
|
||||
|
||||
#endif // RECOVERYPANEL_H
|
||||
@@ -0,0 +1,84 @@
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include "SettingsPanel.hpp"
|
||||
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include "AppFrame.hpp"
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../utils/constants.h"
|
||||
#include "../utils/paleinfo.h"
|
||||
|
||||
SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent)
|
||||
: DevicePanel(frame, parent)
|
||||
{
|
||||
auto* root = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
root->Add(new wxStaticText(this, wxID_ANY,
|
||||
"You may set the following options. If you don't know what they mean you'll\n"
|
||||
"probably have no reason to set them."), 0, wxALL, 10);
|
||||
|
||||
auto* option_safemode = new wxCheckBox(this, wxID_ANY, "Safe Mode");
|
||||
auto* option_verbose = new wxCheckBox(this, wxID_ANY, "Verbose Boot");
|
||||
auto* option_revert = new wxCheckBox(this, wxID_ANY, "Restore System");
|
||||
auto* option_dark_blockchain = new wxCheckBox(this, wxID_ANY, "Dark Blockchain");
|
||||
|
||||
option_safemode->SetValue(palerain_flags & palerain_option_safemode);
|
||||
option_verbose->SetValue(palerain_flags & palerain_option_verbose_boot);
|
||||
option_revert->SetValue(palerain_flags & palerain_option_force_revert);
|
||||
option_dark_blockchain->SetValue(true);
|
||||
|
||||
option_safemode->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
|
||||
{
|
||||
if (e.IsChecked())
|
||||
palerain_flags |= palerain_option_safemode;
|
||||
else
|
||||
palerain_flags &= ~palerain_option_safemode;
|
||||
});
|
||||
|
||||
option_verbose->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
|
||||
{
|
||||
if (e.IsChecked())
|
||||
palerain_flags |= palerain_option_verbose_boot;
|
||||
else
|
||||
palerain_flags &= ~palerain_option_verbose_boot;
|
||||
});
|
||||
|
||||
option_revert->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
|
||||
{
|
||||
if (e.IsChecked())
|
||||
palerain_flags |= palerain_option_force_revert;
|
||||
else
|
||||
palerain_flags &= ~palerain_option_force_revert;
|
||||
});
|
||||
|
||||
root->Add(option_safemode, 0, wxLEFT | wxRIGHT, 10);
|
||||
root->Add(option_verbose, 0, wxLEFT | wxRIGHT | wxTOP, 10);
|
||||
|
||||
root->Add(new wxStaticText(this, wxID_ANY, "Boot Arguments:"), 0, wxALL, 10);
|
||||
|
||||
auto* bootArgs = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize);
|
||||
root->Add(bootArgs, 0, wxLEFT | wxRIGHT | wxEXPAND, 30);
|
||||
|
||||
root->Add(option_revert, 0, wxLEFT | wxRIGHT | wxTOP, 10);
|
||||
root->Add(option_dark_blockchain, 0, wxLEFT | wxRIGHT | wxTOP, 10);
|
||||
|
||||
root->AddStretchSpacer();
|
||||
|
||||
auto* back = new wxButton(this, wxID_ANY, "Back");
|
||||
|
||||
back->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
|
||||
{
|
||||
frame->ShowMain();
|
||||
});
|
||||
|
||||
auto* bottomRow = new wxBoxSizer(wxHORIZONTAL);
|
||||
bottomRow->AddStretchSpacer();
|
||||
bottomRow->Add(back, 0, wxALL, 10);
|
||||
|
||||
root->Add(bottomRow, 0, wxEXPAND);
|
||||
|
||||
SetSizer(root);
|
||||
}
|
||||
|
||||
#endif // WITH_GUI
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef SETTINGSPANEL_H
|
||||
#define SETTINGSPANEL_H
|
||||
|
||||
#ifdef WITH_GUI
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include "DevicePanel.hpp"
|
||||
|
||||
class SettingsPanel;
|
||||
class SettingsPanel : public DevicePanel
|
||||
{
|
||||
public:
|
||||
explicit SettingsPanel(MainFrame* frame, wxWindow* parent);
|
||||
};
|
||||
|
||||
#endif // WITH_GUI
|
||||
|
||||
#endif // SETTINGSPANEL_H
|
||||