Compare commits

..
Author SHA1 Message Date
CLARATION c98dd080dd Merge branch 'main' into koputer 2026-08-03 09:45:25 -07:00
CLARATION ec64322177 chore: update jbinit 2026-08-03 09:43:56 -07:00
CLARATION 8d2fa31bc9 fix: do proper checks for pongo bin 2026-08-02 20:34:22 -07:00
CLARATION 27eb58e188 fix(build): wtf 2026-08-02 19:26:42 -07:00
CLARATION bba50ee092 refactor(build): move things in their own files 2026-08-02 19:00:28 -07:00
CLARATION 89bcddcb4b fix(tui): settings back button being broken xd 2026-08-01 21:21:22 -07:00
CLARATION 8f517976ba feat(wx/tui): add --force-enable-ssv to options 2026-08-01 21:10:38 -07:00
CLARATION 9c3a591db8 fix(wx): remove disconnects handling during dfu transition
when the text "device has entered dfu" appeared, theres a 3 second window where it waits until it transitions to the exploit screen, and during that moment device disconnect handling was being incorrectly handled when it shouldnt of been
2026-08-01 18:59:47 -07:00
CLARATION 02fe95fbfc fix(tui/wx): remove device check in exploit panel 2026-08-01 18:57:34 -07:00
CLARATION b760cc1d83 chore(ci): update loader 2026-08-01 05:09:13 -07:00
CLARATION a7af7a4041 chore: remove this todo 2026-08-01 04:16:07 -07:00
CLARATION 36dc0137bd fix: check if boot command (forgot) 2026-08-01 04:07:21 -07:00
CLARATION 7fe32b54c9 chore: remove useless checks 2026-08-01 03:47:54 -07:00
CLARATION c70c2506ad feat(docs): add --late-exit 2026-08-01 03:24:28 -07:00
CLARATION 7c6c52904e fix: incorrect handling of flag checks 2026-08-01 03:18:04 -07:00
CLARATION ef88661453 fix: redo issue_pongo_command, add error msg 2026-08-01 02:36:08 -07:00
CLARATION 68358829d6 fix(ci): use proper entitlements for ios 2026-08-01 01:15:52 -07:00
CLARATION 892e17741f fix(ci): ciderrain not ciderra1n 2026-08-01 00:33:26 -07:00
CLARATION 83489e54ea fix(ci): install brew make
fix(ci): use gnumake for pongo
2026-08-01 00:24:27 -07:00
CLARATION da8c45465a chore: minify dfuhelperinfo 2026-07-31 22:06:11 -07:00
CLARATION 3d0e269244 feat: add homepod/t2 devices to dfuhelperinfo 2026-07-31 21:57:13 -07:00
CLARATION b40e137a37 feat(tui/wx): support pongo/dfu modes 2026-07-31 21:38:43 -07:00
CLARATION 7ed291dd46 fix(wx): quick mode not activating dfu sequence 2026-07-31 20:56:58 -07:00
Nick Chan 2d7882051e Makefile and actions fixes
Signed-off-by: Nick Chan <[email protected]>
2026-07-30 21:47:50 +08:00
CLARATION cab5a9f9f8 chore(build): remove cider ios check 2026-07-30 02:53:11 -07:00
Nick Chan 0b2ba0e76e cmake: Fix dependencies deployment target
Signed-off-by: Nick Chan <[email protected]>
2026-07-30 17:10:48 +08:00
CLARATION 795cb3d126 chore(build): dont rebuild idevice each time 2026-07-30 00:50:15 -07:00
CLARATION 0801d52c97 feat(wx): add basic menubar for quit 2026-07-29 23:44:42 -07:00
bradleytechman 1481ecc512 feat(wx): Make the donate button actually do something (#769) 2026-07-27 23:16:19 -07:00
CLARATION 96486d6267 chore(ci): move this down 2026-07-27 16:42:17 -07:00
CLARATION 2720826c22 feat(ci): upload to cdn after release 2026-07-27 16:35:10 -07:00
CLARATION 81b47ab254 fix(wx): add newline for multiple devices 2026-07-27 16:25:24 -07:00
CLARATION 9c65425f7c chore: update credits 2026-07-27 16:16:21 -07:00
Nick Chan e9e44e6cc9 Add Missing Adapter devices
Signed-off-by: Nick Chan <[email protected]>
2026-07-27 18:17:28 +08:00
sealldev 3ba32c40db Fix DFU button guidance for iPod 9,1 (#766) 2026-07-27 16:17:34 +08:00
Nick Chan ad72f91ee8 Update libciderra1n
Signed-off-by: Nick Chan <[email protected]>
2026-07-27 16:05:11 +08:00
CLARATION 97138e24de feat(ci): auto bump palen1x 2026-07-26 19:24:41 -07:00
CLARATION 15d13529a8 fix(ci): checkout repo when downloading releases
also have something for workflow dispatches, so we dont need to upload them manually
2026-07-26 17:48:27 -07:00
CLARATION 337604c25d fix(docs): incorrect placement of a few lines 2026-07-26 17:42:12 -07:00
CLARATION eddcedcca1 feat: install script dmg support, beta & release tag support 2026-07-26 14:29:46 -07:00
38 changed files with 1086 additions and 667 deletions

No files matched your search

+18 -12
View File
@@ -20,7 +20,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
ref: a766a91bf4b691317df24d3be41e44e754a3e0d8 ref: 9faf50968854aa47de65231e2985d60f6944d627
repository: palera1n/loader repository: palera1n/loader
- name: Install dependencies (brew) - name: Install dependencies (brew)
@@ -52,7 +52,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
ref: 9cadaa63569ba318677b4ef0869ad984b3663a6c ref: 7e1f6e122c3a45fc45e939293c7e2eaa1889731f
repository: palera1n/jbinit repository: palera1n/jbinit
submodules: true submodules: true
@@ -102,9 +102,13 @@ jobs:
ref: e98323f8a09abd80fc4cbcd74dee023b91a1ec22 ref: e98323f8a09abd80fc4cbcd74dee023b91a1ec22
repository: palera1n/PongoOS repository: palera1n/PongoOS
- name: Install dependencies (brew)
run: |
brew install make
- name: Build - name: Build
run: | run: |
make gmake -j$(sysctl -n hw.ncpu)
- name: Prepare upload directory - name: Prepare upload directory
run: | run: |
@@ -176,7 +180,7 @@ jobs:
- name: Install dependencies (apt) - name: Install dependencies (apt)
run: | run: |
sudo apt update sudo apt update
sudo apt install -y build-essential cmake autoconf automake libtool pkg-config zstd sudo apt install -y build-essential cmake autoconf automake libtool pkg-config zstd jq
- name: Build - name: Build
run: | run: |
@@ -255,11 +259,11 @@ jobs:
- name: Install dependencies (brew) - name: Install dependencies (brew)
run: | run: |
brew update brew update
brew install cmake autoconf automake libtool pkg-config brew install make cmake autoconf automake libtool pkg-config
- name: Build - name: Build
run: | run: |
make palera1n WITH_STATIC=1 WITH_GUI=1 WITH_TUI=1 WITH_CIDERRAIN=1 BUILD_TYPE=Release JOBS=$(sysctl -n hw.ncpu) gmake 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
@@ -304,16 +308,17 @@ jobs:
- name: Install dependencies (brew) - name: Install dependencies (brew)
run: | run: |
brew update brew update
brew install cmake libtool gnu-sed brew install make cmake libtool gnu-sed
- name: Build - name: Build
run: | run: |
make palera1n_xcode PLATFORM=iphoneos WITH_STATIC=1 BUILD_TYPE=Release JOBS=$(sysctl -n hw.ncpu) gmake palera1n_xcode PLATFORM=iphoneos WITH_STATIC=1 WITH_CIDERRAIN=1 BUILD_TYPE=Release JOBS=$(sysctl -n hw.ncpu)
cmake --build build cmake --build build
codesign --force --sign - --entitlements resources/entitlements.xml build/Debug-iphoneos/palera1n.app/palera1n
- name: Package - name: Package
run: | run: |
cd build cd build
cpack -DCPACK_PACKAGE_FILE_NAME="palera1n-iphoneos-arm" \ cpack -DCPACK_PACKAGE_FILE_NAME="palera1n-iphoneos-arm" \
-DCPACK_PACKAGING_INSTALL_PREFIX="/usr/" -DCPACK_PACKAGING_INSTALL_PREFIX="/usr/"
cpack -DCPACK_PACKAGE_FILE_NAME="palera1n-iphoneos-arm64" \ cpack -DCPACK_PACKAGE_FILE_NAME="palera1n-iphoneos-arm64" \
@@ -432,6 +437,7 @@ jobs:
mingw-w64-x86_64-libusb mingw-w64-x86_64-libusb
mingw-w64-x86_64-rust mingw-w64-x86_64-rust
mingw-w64-x86_64-nsis mingw-w64-x86_64-nsis
mingw-w64-x86_64-jq
libtool libtool
openssl openssl
openssl-devel openssl-devel
@@ -534,12 +540,12 @@ jobs:
- name: Create Release - name: Create Release
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65
with: with:
name: v${{ steps.get_version.outputs.version }} name: ${{ steps.get_version.outputs.version }}
tag_name: v${{ steps.get_version.outputs.version }} tag_name: ${{ steps.get_version.outputs.version }}
files: | files: |
dist/* dist/*
generate_release_notes: true generate_release_notes: true
fail_on_unmatched_files: true fail_on_unmatched_files: true
draft: true draft: true
env: env:
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+58 -11
View File
@@ -1,26 +1,41 @@
name: "Upload debs" name: "Upload debs"
on: on:
workflow_dispatch:
inputs:
version:
description: "palera1n tag"
required: true
type: string
release: release:
types: [published] types: [published]
env:
TAG: ${{ github.event.inputs.version || github.event.release.tag_name }}
jobs: jobs:
upload: upload:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Download debs from release - uses: actions/checkout@v4
- name: Download debs from tag
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
gh release download "${{ github.event.release.tag_name }}" \ gh release download "${{ env.TAG }}"
--pattern "palera1n-iphoneos-arm64.deb" \
--pattern "palera1n-iphoneos-arm.deb"
if [ ! -f "palera1n-iphoneos-arm64.deb" ] || [ ! -f "palera1n-iphoneos-arm.deb" ]; then if [ ! -f "palera1n-iphoneos-arm64.deb" ] || [ ! -f "palera1n-iphoneos-arm.deb" ]; then
echo "Debs not found :/" echo "Debs not found :/"
exit 1 exit 1
fi fi
mkdir -p cdn-upload
cp *.tar.gz cdn-upload/
cp *.deb cdn-upload/
cp *.dmg cdn-upload/
- name: Upload debs to repo - name: Upload debs to repo
if: github.repository == 'palera1n/palera1n' if: github.repository == 'palera1n/palera1n'
env: env:
@@ -28,18 +43,50 @@ jobs:
API_TOKEN: ${{ secrets.BUILD_GITHUB_TOKEN }} API_TOKEN: ${{ secrets.BUILD_GITHUB_TOKEN }}
GH_REPO: palera1n/repo.palera.in GH_REPO: palera1n/repo.palera.in
run: | run: |
git clone https://$USERNAME:[email protected]/$GH_REPO.git upload git clone https://$USERNAME:[email protected]/$GH_REPO.git repo-upload
ARM64_HASH=$(sha256sum palera1n-iphoneos-arm64.deb | cut -c1-8) ARM64_HASH=$(sha256sum palera1n-iphoneos-arm64.deb | cut -c1-8)
ARM_HASH=$(sha256sum palera1n-iphoneos-arm.deb | cut -c1-8) ARM_HASH=$(sha256sum palera1n-iphoneos-arm.deb | cut -c1-8)
cp palera1n-iphoneos-arm64.deb upload/pool/iphoneos-arm64/palera1n_${{ github.event.release.tag_name }}_${ARM64_HASH}_iphoneos-arm64.deb cp palera1n-iphoneos-arm64.deb repo-upload/pool/iphoneos-arm64/palera1n_${{ env.TAG }}_${ARM64_HASH}_iphoneos-arm64.deb
cp palera1n-iphoneos-arm.deb upload/pool/iphoneos-arm/palera1n_${{ github.event.release.tag_name }}_${ARM_HASH}_iphoneos-arm.deb cp palera1n-iphoneos-arm.deb repo-upload/pool/iphoneos-arm/palera1n_${{ env.TAG }}_${ARM_HASH}_iphoneos-arm.deb
cd upload cd repo-upload
git config user.name "github-actions[bot]" git config user.name "$USERNAME"
git config user.email "[email protected]" git config user.email "[email protected]"
git add . git add .
git commit -m "Update palera1n for ${{ github.event.release.tag_name }}" || exit 0 git commit -m "Update palera1n for ${{ env.TAG }}" || exit 0
git push https://$USERNAME:[email protected]/$GH_REPO.git git push https://$USERNAME:[email protected]/$GH_REPO.git
- name: Upload artifacts to cdn
if: github.repository == 'palera1n/palera1n'
uses: wangyucode/sftp-upload-action@v3
with:
host: ${{ secrets.NICKCHAN_FTP_HOST }}
port: ${{ secrets.NICKCHAN_FTP_PORT }}
username: palera1n
password: ${{ secrets.NICKCHAN_FTP_PASS }}
forceUpload: true
dryRun: false
localDir: 'cdn-upload'
remoteDir: "/palera1n/c-rewrite/releases/${{ env.TAG }}"
- name: Bump palen1x
if: github.repository == 'palera1n/palera1n'
env:
USERNAME: GitHub-Actions
API_TOKEN: ${{ secrets.BUILD_GITHUB_TOKEN }}
GH_REPO: palera1n/palen1x
run: |
git clone https://$USERNAME:[email protected]/$GH_REPO.git tag
cd tag
git config --global user.name "$USERNAME"
git config --global user.email "[email protected]"
git commit --allow-empty -m "bump to ${{ env.TAG }}"
git push https://$USERNAME:[email protected]/$GH_REPO.git Alpine
git tag "${{ env.TAG }}"
git push https://$USERNAME:[email protected]/$GH_REPO.git "${{ env.TAG }}"
+1
View File
@@ -8,6 +8,7 @@ embedded/Pongo.bin
embedded/checkra1n-kpf-pongo embedded/checkra1n-kpf-pongo
embedded/ramdisk.dmg embedded/ramdisk.dmg
embedded/binpack.dmg embedded/binpack.dmg
embedded/DFUHelperDeviceInfo-minified.json
apple-include-* apple-include-*
libusbK/ libusbK/
+30 -327
View File
@@ -25,34 +25,10 @@ option(WITH_CIDERRAIN "Build with Ciderra1n instead of Openra1n" OFF)
# MARK: BUILD REQUIREMENTS # MARK: BUILD REQUIREMENTS
# ========================= # =========================
if(LINUX AND WITH_STATIC) include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/BuildRequirements.cmake")
if(NOT CROSS_HOST_TRIPLE MATCHES "musl" AND NOT CMAKE_C_COMPILER_TARGET MATCHES "musl" AND NOT CMAKE_C_COMPILER MATCHES "musl")
message(FATAL_ERROR "Static builds on Linux require a musl toolchain. Please specify a musl cross-compiler or set -DCROSS_HOST_TRIPLE=...-linux-musl")
endif()
endif()
if(MINGW AND NOT WITH_STATIC)
message(FATAL_ERROR "MinGW builds must be static. Please configure with -DWITH_STATIC=1")
endif()
if(MINGW AND WITH_TUI)
message(FATAL_ERROR "-DWITH_TUI=1 is not supported on MinGW builds.")
endif()
if(MINGW AND WITH_CIDERRAIN)
message(FATAL_ERROR "-DWITH_CIDERRAIN=1 is not supported on MinGW builds.")
endif()
if(IOS AND (WITH_TUI OR WITH_GUI))
message(FATAL_ERROR "-DWITH_TUI=1 or -DWITH_GUI=1 is not supported on iOS builds.")
endif()
if(IOS AND WITH_CIDERRAIN)
message(FATAL_ERROR "-DWITH_CIDERRAIN=1 is not supported on iOS builds.")
endif()
# ========================= # =========================
# SETUP # MARK: SETUP
# ========================= # =========================
if(MINGW) if(MINGW)
@@ -164,33 +140,7 @@ if(WITH_CIDERRAIN)
target_compile_definitions(palera1n PRIVATE WITH_CIDERRAIN) target_compile_definitions(palera1n PRIVATE WITH_CIDERRAIN)
endif() endif()
execute_process( include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Git.cmake")
COMMAND git rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND git rev-parse --abbrev-ref --symbolic-full-name "@{u}"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
execute_process(
COMMAND git remote get-url origin
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_URL
OUTPUT_STRIP_TRAILING_WHITESPACE
)
target_compile_definitions(palera1n PRIVATE
GIT_HASH="${GIT_HASH}"
GIT_BRANCH="${GIT_BRANCH}"
GIT_URL="${GIT_URL}"
)
# ========================= # =========================
# MARK: LINKS # MARK: LINKS
@@ -208,225 +158,24 @@ if(WIN32)
endif() endif()
# ========================= # =========================
# MARK: NON-CMAKE DEPENDENCIES # MARK: NON-CMAKE DEPENDENCIES (LOCAL)
# ========================= # =========================
# ra1ns # ra1ns
if(WITH_CIDERRAIN) if(WITH_CIDERRAIN)
message(STATUS "Building with Ciderra1n support") include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Ciderra1n.cmake")
# TODO: get rid
execute_process(
COMMAND patch --batch --forward -p1 -i ${CMAKE_SOURCE_DIR}/patches/liteusb/0001-cpp-compatible.patch
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libciderra1n/external/liteusb
RESULT_VARIABLE LITEUSB_PATCH_RESULT
)
if(IOS)
execute_process(
COMMAND xcrun --sdk iphoneos --show-sdk-path
OUTPUT_VARIABLE IOS_SDK
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E env
"CFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -I${CMAKE_SOURCE_DIR}/apple-include-iphoneos"
"CXXFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -I${CMAKE_SOURCE_DIR}/apple-include-iphoneos"
"LDFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} AR=${CMAKE_AR}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libciderra1n
RESULT_VARIABLE CIDERRA1N_BUILD_RESULT
)
else()
execute_process(
COMMAND make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libciderra1n
RESULT_VARIABLE CIDERRA1N_BUILD_RESULT
)
endif()
if(NOT CIDERRA1N_BUILD_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to build Ciderra1n.")
endif()
set(CIDERRAIN_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/1stparty/libciderra1n/build/include")
set(CIDERRAIN_LIB "${CMAKE_SOURCE_DIR}/1stparty/libciderra1n/build/lib/ciderra1n/libciderra1n.a")
target_include_directories(palera1n PRIVATE ${CIDERRAIN_INCLUDE_DIR})
target_link_libraries(palera1n PRIVATE "${CIDERRAIN_LIB}")
if(IOS)
target_include_directories(palera1n PRIVATE "${CMAKE_SOURCE_DIR}/apple-include-iphoneos")
endif()
if(LINUX)
set(LITEUSB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/1stparty/libciderra1n/external/liteusb/include")
target_compile_definitions(palera1n PRIVATE LITEUSB_PLATFORM_LINUX)
target_include_directories(palera1n PRIVATE ${LITEUSB_INCLUDE_DIR})
endif()
else() else()
message(STATUS "Building with Openra1n support") include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Openra1n.cmake")
if(IOS)
execute_process(
COMMAND xcrun --sdk iphoneos --show-sdk-path
OUTPUT_VARIABLE IOS_SDK
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E env
"CFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -I${CMAKE_SOURCE_DIR}/apple-include-iphoneos"
"CXXFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -I${CMAKE_SOURCE_DIR}/apple-include-iphoneos"
"LDFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} AR=${CMAKE_AR}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libopenra1n
RESULT_VARIABLE OPENRA1N_BUILD_RESULT
)
else()
execute_process(
COMMAND make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libopenra1n
RESULT_VARIABLE OPENRA1N_BUILD_RESULT
)
endif()
if(NOT OPENRA1N_BUILD_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to build Openra1n.")
endif()
set(OPENRA1N_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/1stparty/libopenra1n/build/include")
set(OPENRA1N_LIB "${CMAKE_SOURCE_DIR}/1stparty/libopenra1n/build/lib/openra1n/libopenra1n.a")
target_include_directories(palera1n PRIVATE ${OPENRA1N_INCLUDE_DIR})
target_link_libraries(palera1n PRIVATE "${OPENRA1N_LIB}")
if(IOS)
target_include_directories(palera1n PRIVATE "${CMAKE_SOURCE_DIR}/apple-include-iphoneos")
endif()
endif() endif()
# idevice # idevice
if(WITH_GUI OR WITH_TUI) if(WITH_GUI OR WITH_TUI)
set(IDevice_CARGO_ARGS include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Idevice.cmake")
--release
--no-default-features
--features "usbmuxd ring tcp"
)
set(IDevice_ENV)
if(CROSS_HOST_TRIPLE)
if(CROSS_HOST_TRIPLE STREQUAL "i486-linux-musl")
set(RUST_TARGET "i686-unknown-linux-musl")
elseif(CROSS_HOST_TRIPLE STREQUAL "x86_64-linux-musl")
set(RUST_TARGET "x86_64-unknown-linux-musl")
elseif(CROSS_HOST_TRIPLE STREQUAL "armel-linux-musleabi")
set(RUST_TARGET "arm-unknown-linux-musleabi")
elseif(CROSS_HOST_TRIPLE STREQUAL "aarch64-linux-musl")
set(RUST_TARGET "aarch64-unknown-linux-musl")
endif()
if(RUST_TARGET)
string(TOUPPER "${RUST_TARGET}" RUST_TARGET_ENV)
string(REPLACE "-" "_" RUST_TARGET_ENV "${RUST_TARGET_ENV}")
list(APPEND IDevice_CARGO_ARGS --target ${RUST_TARGET})
list(APPEND IDevice_ENV
"CC=${CMAKE_C_COMPILER}"
"AR=${CMAKE_AR}"
"CARGO_TARGET_${RUST_TARGET_ENV}_LINKER=${CMAKE_C_COMPILER}"
)
endif()
elseif(MINGW)
set(RUST_TARGET "x86_64-pc-windows-gnu")
list(APPEND IDevice_CARGO_ARGS --target ${RUST_TARGET})
list(APPEND IDevice_ENV
"CC=${CMAKE_C_COMPILER}"
"AR=${CMAKE_AR}"
"CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=${CMAKE_C_COMPILER}"
)
endif()
ExternalProject_Add(idevice_ep
GIT_REPOSITORY https://github.com/jkcoxson/idevice.git
GIT_TAG v0.1.65
PATCH_COMMAND
patch --forward --ignore-whitespace -p1 < "${CMAKE_SOURCE_DIR}/patches/idevice/0001-compile-usbmuxd-and-windows-fixes.patch" || true
CONFIGURE_COMMAND ""
BUILD_COMMAND
${CMAKE_COMMAND} -E env
${IDevice_ENV}
cargo build
${IDevice_CARGO_ARGS}
--manifest-path <SOURCE_DIR>/ffi/Cargo.toml
COMMAND ${CMAKE_COMMAND} -E chdir <SOURCE_DIR>/cpp
${CMAKE_COMMAND}
-B build
-DCMAKE_BUILD_TYPE=Release
-DIDEVICE_FFI_PATH=<SOURCE_DIR>/target/${RUST_TARGET}/release/${FFI_LIB_NAME}
"-DCMAKE_CXX_FLAGS=-Du_int64_t=uint64_t -Du_int32_t=uint32_t -Du_int16_t=uint16_t -Du_int8_t=uint8_t"
COMMAND ${CMAKE_COMMAND} --build <SOURCE_DIR>/cpp/build --config Release
INSTALL_COMMAND
${CMAKE_COMMAND} -E make_directory <INSTALL_DIR>/lib/idevice
COMMAND ${CMAKE_COMMAND} -E make_directory <INSTALL_DIR>/include
COMMAND ${CMAKE_COMMAND} -E copy
<SOURCE_DIR>/target/${RUST_TARGET}/release/libidevice_ffi.a
<INSTALL_DIR>/lib/idevice/libidevice_ffi.a
COMMAND ${CMAKE_COMMAND} -E copy
<SOURCE_DIR>/cpp/build/libidevice++.a
<INSTALL_DIR>/lib/idevice/libidevice++.a
COMMAND ${CMAKE_COMMAND} -E copy_directory
<SOURCE_DIR>/cpp/include
<INSTALL_DIR>/include
BUILD_IN_SOURCE 1
)
ExternalProject_Get_Property(idevice_ep install_dir)
set(IDEVICE_INCLUDE_DIR "${install_dir}/include")
set(IDEVICE_LIBRARY "${install_dir}/lib/idevice/libidevice++.a")
set(IDEVICE_FFI_LIBRARY "${install_dir}/lib/idevice/libidevice_ffi.a")
add_dependencies(palera1n idevice_ep)
target_include_directories(palera1n PRIVATE ${IDEVICE_INCLUDE_DIR})
target_link_libraries(palera1n PRIVATE "${IDEVICE_LIBRARY}" "${IDEVICE_FFI_LIBRARY}")
if(MINGW)
target_link_libraries(palera1n PRIVATE bcrypt userenv ntdll)
endif()
target_compile_definitions(palera1n PRIVATE LIBPLIST_STATIC)
endif() endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release") # =========================
if(APPLE) # MARK: NON-CMAKE DEPENDENCIES
target_link_options(palera1n PRIVATE # =========================
-Wl,-dead_strip
-Wl,-x
)
elseif(MINGW)
target_link_options(palera1n PRIVATE
-Wl,--gc-sections
-Wl,--strip-all
)
elseif(LINUX)
target_link_options(palera1n PRIVATE
-Wl,--gc-sections
-Wl,--strip-all
)
endif()
endif()
if(WITH_STATIC) if(WITH_STATIC)
find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config) find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config)
@@ -596,77 +345,31 @@ else()
endif() endif()
# ========================= # =========================
# MARK: INSTALL # MARK: STRIP FLAGS
# ========================= # =========================
if(LINUX AND NOT MINGW) if(CMAKE_BUILD_TYPE STREQUAL "Release")
install(TARGETS palera1n RUNTIME DESTINATION bin) if(APPLE)
elseif(IOS) target_link_options(palera1n PRIVATE
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/Debug-iphoneos/palera1n.app/palera1n" DESTINATION bin) -Wl,-dead_strip
elseif(APPLE AND WITH_GUI) -Wl,-x
install(TARGETS palera1n BUNDLE DESTINATION .) )
elseif(APPLE) elseif(MINGW)
install(TARGETS palera1n RUNTIME DESTINATION bin) target_link_options(palera1n PRIVATE
elseif(MINGW) -Wl,--gc-sections
install(TARGETS palera1n -Wl,--strip-all
RUNTIME DESTINATION . )
) elseif(LINUX)
target_link_options(palera1n PRIVATE
install(FILES -Wl,--gc-sections
"${CMAKE_CURRENT_BINARY_DIR}/libstdc++-6.dll" -Wl,--strip-all
"${CMAKE_CURRENT_BINARY_DIR}/libgcc_s_seh-1.dll"
"${CMAKE_CURRENT_BINARY_DIR}/libwinpthread-1.dll"
DESTINATION .
)
if(NOT WITH_CIDERRAIN)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/libusb-1.0.dll"
DESTINATION .
) )
endif() endif()
endif() endif()
if((LINUX AND NOT MINGW) OR IOS OR (APPLE AND NOT IOS AND NOT WITH_GUI)) # =========================
install(FILES "${CMAKE_SOURCE_DIR}/docs/palera1n.1" DESTINATION share/man/man1) # MARK: INSTALL
install(FILES "${CMAKE_SOURCE_DIR}/docs/p1ctl.8" DESTINATION share/man/man8) # =========================
endif()
set(CPACK_PACKAGE_NAME "palera1n") include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/BuildInstall.cmake")
set(CPACK_PACKAGE_VERSION "0")
set(CPACK_PACKAGE_FILE_NAME "palera1n")
if(MINGW)
set(CPACK_GENERATOR "NSIS64")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "palera1n")
set(CPACK_NSIS_DISPLAY_NAME "palera1n")
set(CPACK_NSIS_PACKAGE_NAME "palera1n")
set(CPACK_NSIS_BRANDING_TEXT "palera1n Setup")
set(CPACK_NSIS_MODIFY_PATH OFF)
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/resources/palera1n.ico")
set(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/resources/palera1n.ico")
set(CPACK_PACKAGE_EXECUTABLES "palera1n" "palera1n")
set(CPACK_NSIS_CREATE_ICONS_EXTRA
"CreateShortCut \\\"\\$DESKTOP\\\\palera1n.lnk\\\" \\\"\\$INSTDIR\\\\bin\\\\palera1n.exe\\\""
)
set(CPACK_NSIS_DELETE_ICONS_EXTRA
"Delete \\\"\\$DESKTOP\\\\palera1n.lnk\\\""
)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
elseif(APPLE AND WITH_GUI)
set(CPACK_GENERATOR "DragNDrop")
else()
set(CPACK_PACKAGING_INSTALL_PREFIX "/")
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
set(CPACK_GENERATOR "TGZ")
endif()
include(CPack)
+8 -2
View File
@@ -34,6 +34,7 @@ ifeq ($(PLATFORM),iphoneos)
ifneq ($(UNAME_S),Darwin) ifneq ($(UNAME_S),Darwin)
$(error iOS builds require macOS/Xcode) $(error iOS builds require macOS/Xcode)
endif endif
EXTRA_TARGETS = apple-include
TARGET_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path) TARGET_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path)
else ifeq ($(PLATFORM),macos) else ifeq ($(PLATFORM),macos)
ifneq ($(UNAME_S),Darwin) ifneq ($(UNAME_S),Darwin)
@@ -79,6 +80,8 @@ else
APPLE_INCLUDE_DEP := APPLE_INCLUDE_DEP :=
endif endif
all: palera1n
apple-include: apple-include:
mkdir -p $(CUSTOM_INCLUDE_PATH)/{bsm,objc,os/internal,sys,firehose,CoreFoundation,FSEvents,IOSurface,IOKit/kext,libkern,kern,arm,{mach/,}machine,CommonCrypto,Security,CoreSymbolication,Kernel/{kern,IOKit,libkern},rpc,rpcsvc,xpc/private,ktrace,mach-o,dispatch} mkdir -p $(CUSTOM_INCLUDE_PATH)/{bsm,objc,os/internal,sys,firehose,CoreFoundation,FSEvents,IOSurface,IOKit/kext,libkern,kern,arm,{mach/,}machine,CommonCrypto,Security,CoreSymbolication,Kernel/{kern,IOKit,libkern},rpc,rpcsvc,xpc/private,ktrace,mach-o,dispatch}
cp -af $(MACOSX_SYSROOT)/usr/include/{arpa,bsm,hfs,net,xpc,netinet,servers,timeconv.h,launch.h} $(CUSTOM_INCLUDE_PATH) cp -af $(MACOSX_SYSROOT)/usr/include/{arpa,bsm,hfs,net,xpc,netinet,servers,timeconv.h,launch.h} $(CUSTOM_INCLUDE_PATH)
@@ -114,8 +117,9 @@ apple-include:
payloads: payloads:
mkdir -p src/gen/embedded mkdir -p src/gen/embedded
xz --format=lzma -vfc6ekT 0 embedded/ramdisk.dmg > embedded/ramdisk-compressed.dmg.lzma xz --format=lzma -vfc6ekT 0 embedded/ramdisk.dmg > embedded/ramdisk-compressed.lzma
xz --format=lzma -vfc6ekT 0 embedded/checkra1n-kpf-pongo > embedded/checkra1n-kpf-pongo-compressed.lzma xz --format=lzma -vfc6ekT 0 embedded/checkra1n-kpf-pongo > embedded/checkra1n-kpf-pongo-compressed.lzma
jq -c . embedded/DFUHelperDeviceInfo.json > embedded/DFUHelperDeviceInfo-minified.json
@for file in embedded/*; do \ @for file in embedded/*; do \
name=$$(basename "$$file"); \ name=$$(basename "$$file"); \
@@ -128,7 +132,7 @@ payloads:
>> "src/gen/embedded/$$name.h"; \ >> "src/gen/embedded/$$name.h"; \
done done
palera1n: payloads palera1n: payloads $(EXTRA_TARGETS)
@cmake -S . -B build \ @cmake -S . -B build \
$(CMAKE_COMMON_ARGS) \ $(CMAKE_COMMON_ARGS) \
$(CMAKE_APPLE_ARGS) && \ $(CMAKE_APPLE_ARGS) && \
@@ -151,3 +155,5 @@ clean:
@rm -rf apple-include-* @rm -rf apple-include-*
@if [ -d 1stparty/libciderra1n ]; then $(MAKE) -C 1stparty/libciderra1n clean; fi @if [ -d 1stparty/libciderra1n ]; then $(MAKE) -C 1stparty/libciderra1n clean; fi
@$(MAKE) -C 1stparty/libopenra1n clean @$(MAKE) -C 1stparty/libopenra1n clean
.PHONY: palera1n palera1n_xcode palera1n_mingw payloads clean
+1 -1
View File
@@ -171,7 +171,7 @@ make palera1n_mingw
- [staturnz](https://github.com/staturnz) - Liteusb, Loader contributions - [staturnz](https://github.com/staturnz) - Liteusb, Loader contributions
- [libusb](https://github.com/libimobiledevice/libimobiledevice) - Library for access to usb-devices, used by libopenra1n - [libusb](https://github.com/libimobiledevice/libimobiledevice) - Library for access to usb-devices, used by libopenra1n
- [idevice](https://github.com/jkcoxson/idevice) - Library for access to usbmuxd devices - [idevice](https://github.com/jkcoxson/idevice) - Library for access to usbmuxd devices
- [plooshi](https://github.com/plooshi) - Plooshfinder, plooshinit, various legacy patches - [sarah](https://github.com/plooshi) - Plooshfinder, plooshinit, various legacy patches
- [Procursus](https://github.com/ProcursusTeam/Procursus) - Bootstrap & binpack - [Procursus](https://github.com/ProcursusTeam/Procursus) - Bootstrap & binpack
- [tealbathingsuit](https://github.com/tealbathingsuit) - Tweak injection ([ElleKit](https://github.com/tealbathingsuit/ellekit)) - [tealbathingsuit](https://github.com/tealbathingsuit) - Tweak injection ([ElleKit](https://github.com/tealbathingsuit/ellekit))
- [sbingner](https://github.com/sbingner) - Substitute - [sbingner](https://github.com/sbingner) - Substitute
+74
View File
@@ -0,0 +1,74 @@
# =========================
# MARK: INSTALL
# =========================
if(LINUX AND NOT MINGW)
install(TARGETS palera1n RUNTIME DESTINATION bin)
elseif(IOS)
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/Debug-iphoneos/palera1n.app/palera1n" DESTINATION bin)
elseif(APPLE AND WITH_GUI)
install(TARGETS palera1n BUNDLE DESTINATION .)
elseif(APPLE)
install(TARGETS palera1n RUNTIME DESTINATION bin)
elseif(MINGW)
install(TARGETS palera1n
RUNTIME DESTINATION .
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/libstdc++-6.dll"
"${CMAKE_CURRENT_BINARY_DIR}/libgcc_s_seh-1.dll"
"${CMAKE_CURRENT_BINARY_DIR}/libwinpthread-1.dll"
DESTINATION .
)
if(NOT WITH_CIDERRAIN)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/libusb-1.0.dll"
DESTINATION .
)
endif()
endif()
if((LINUX AND NOT MINGW) OR IOS OR (APPLE AND NOT IOS AND NOT WITH_GUI))
install(FILES "${CMAKE_SOURCE_DIR}/docs/palera1n.1" DESTINATION share/man/man1)
install(FILES "${CMAKE_SOURCE_DIR}/docs/p1ctl.8" DESTINATION share/man/man8)
endif()
set(CPACK_PACKAGE_NAME "palera1n")
set(CPACK_PACKAGE_VERSION "0")
set(CPACK_PACKAGE_FILE_NAME "palera1n")
if(MINGW)
set(CPACK_GENERATOR "NSIS64")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "palera1n")
set(CPACK_NSIS_DISPLAY_NAME "palera1n")
set(CPACK_NSIS_PACKAGE_NAME "palera1n")
set(CPACK_NSIS_BRANDING_TEXT "palera1n Setup")
set(CPACK_NSIS_MODIFY_PATH OFF)
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/resources/palera1n.ico")
set(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/resources/palera1n.ico")
set(CPACK_PACKAGE_EXECUTABLES "palera1n" "palera1n")
set(CPACK_NSIS_CREATE_ICONS_EXTRA
"CreateShortCut \\\"\\$DESKTOP\\\\palera1n.lnk\\\" \\\"\\$INSTDIR\\\\bin\\\\palera1n.exe\\\""
)
set(CPACK_NSIS_DELETE_ICONS_EXTRA
"Delete \\\"\\$DESKTOP\\\\palera1n.lnk\\\""
)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
elseif(APPLE AND WITH_GUI)
set(CPACK_GENERATOR "DragNDrop")
else()
set(CPACK_PACKAGING_INSTALL_PREFIX "/")
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
set(CPACK_GENERATOR "TGZ")
endif()
include(CPack)
+41
View File
@@ -0,0 +1,41 @@
# =========================
# BUILD REQUIREMENTS
# =========================
if(LINUX AND WITH_STATIC)
if(
NOT CROSS_HOST_TRIPLE MATCHES "musl"
AND NOT CMAKE_C_COMPILER_TARGET MATCHES "musl"
AND NOT CMAKE_C_COMPILER MATCHES "musl"
)
message(FATAL_ERROR
"Static builds on Linux require a musl toolchain. "
"Please specify a musl cross-compiler or set "
"-DCROSS_HOST_TRIPLE=...-linux-musl"
)
endif()
endif()
if(MINGW AND NOT WITH_STATIC)
message(FATAL_ERROR
"MinGW builds must be static. Please configure with -DWITH_STATIC=1"
)
endif()
if(MINGW AND WITH_TUI)
message(FATAL_ERROR
"-DWITH_TUI=1 is not supported on MinGW builds."
)
endif()
if(MINGW AND WITH_CIDERRAIN)
message(FATAL_ERROR
"-DWITH_CIDERRAIN=1 is not supported on MinGW builds."
)
endif()
if(IOS AND (WITH_TUI OR WITH_GUI))
message(FATAL_ERROR
"-DWITH_TUI=1 or -DWITH_GUI=1 is not supported on iOS builds."
)
endif()
+61
View File
@@ -0,0 +1,61 @@
# =========================
# MARK: NON-CMAKE DEPENDENCIES: CIDERRAIN
# =========================
message(STATUS "Building with Ciderra1n support")
# TODO: get rid
execute_process(
COMMAND patch --batch --forward -p1 -i ${CMAKE_SOURCE_DIR}/patches/liteusb/0001-cpp-compatible.patch
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libciderra1n/external/liteusb
RESULT_VARIABLE LITEUSB_PATCH_RESULT
)
if(IOS)
execute_process(
COMMAND xcrun --sdk iphoneos --show-sdk-path
OUTPUT_VARIABLE IOS_SDK
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E env
"EXTRA_CFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -I${CMAKE_SOURCE_DIR}/apple-include-iphoneos"
"CXXFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -I${CMAKE_SOURCE_DIR}/apple-include-iphoneos"
"LDFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} AR=${CMAKE_AR}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libciderra1n
RESULT_VARIABLE CIDERRA1N_BUILD_RESULT
)
elseif(APPLE)
execute_process(
COMMAND make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} EXTRA_CFLAGS=-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libciderra1n
RESULT_VARIABLE CIDERRA1N_BUILD_RESULT
)
else()
execute_process(
COMMAND make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libciderra1n
RESULT_VARIABLE CIDERRA1N_BUILD_RESULT
)
endif()
if(NOT CIDERRA1N_BUILD_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to build Ciderra1n.")
endif()
set(CIDERRAIN_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/1stparty/libciderra1n/build/include")
set(CIDERRAIN_LIB "${CMAKE_SOURCE_DIR}/1stparty/libciderra1n/build/lib/ciderra1n/libciderra1n.a")
target_include_directories(palera1n PRIVATE ${CIDERRAIN_INCLUDE_DIR})
target_link_libraries(palera1n PRIVATE "${CIDERRAIN_LIB}")
if(IOS)
target_include_directories(palera1n PRIVATE "${CMAKE_SOURCE_DIR}/apple-include-iphoneos")
endif()
if(LINUX)
set(LITEUSB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/1stparty/libciderra1n/external/liteusb/include")
target_compile_definitions(palera1n PRIVATE LITEUSB_PLATFORM_LINUX)
target_include_directories(palera1n PRIVATE ${LITEUSB_INCLUDE_DIR})
endif()
+31
View File
@@ -0,0 +1,31 @@
# =========================
# MARK: GIT INFO
# =========================
execute_process(
COMMAND git rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND git rev-parse --abbrev-ref --symbolic-full-name "@{u}"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
execute_process(
COMMAND git remote get-url origin
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_URL
OUTPUT_STRIP_TRAILING_WHITESPACE
)
target_compile_definitions(palera1n PRIVATE
GIT_HASH="${GIT_HASH}"
GIT_BRANCH="${GIT_BRANCH}"
GIT_URL="${GIT_URL}"
)
+121
View File
@@ -0,0 +1,121 @@
# =========================
# MARK: NON-CMAKE DEPENDENCIES: IDEVICE
# =========================
set(IDevice_CARGO_ARGS
--release
--no-default-features
--features "usbmuxd ring tcp"
)
set(IDevice_ENV)
if(APPLE)
if(IOS)
list(APPEND IDevice_ENV "IPHONEOS_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
else()
list(APPEND IDevice_ENV "MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
endif()
if(CROSS_HOST_TRIPLE)
if(CROSS_HOST_TRIPLE STREQUAL "i486-linux-musl")
set(RUST_TARGET "i686-unknown-linux-musl")
elseif(CROSS_HOST_TRIPLE STREQUAL "x86_64-linux-musl")
set(RUST_TARGET "x86_64-unknown-linux-musl")
elseif(CROSS_HOST_TRIPLE STREQUAL "armel-linux-musleabi")
set(RUST_TARGET "arm-unknown-linux-musleabi")
elseif(CROSS_HOST_TRIPLE STREQUAL "aarch64-linux-musl")
set(RUST_TARGET "aarch64-unknown-linux-musl")
endif()
if(RUST_TARGET)
string(TOUPPER "${RUST_TARGET}" RUST_TARGET_ENV)
string(REPLACE "-" "_" RUST_TARGET_ENV "${RUST_TARGET_ENV}")
list(APPEND IDevice_CARGO_ARGS --target ${RUST_TARGET})
list(APPEND IDevice_ENV
"CC=${CMAKE_C_COMPILER}"
"AR=${CMAKE_AR}"
"CARGO_TARGET_${RUST_TARGET_ENV}_LINKER=${CMAKE_C_COMPILER}"
)
endif()
elseif(MINGW)
set(RUST_TARGET "x86_64-pc-windows-gnu")
list(APPEND IDevice_CARGO_ARGS --target ${RUST_TARGET})
list(APPEND IDevice_ENV
"CC=${CMAKE_C_COMPILER}"
"AR=${CMAKE_AR}"
"CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=${CMAKE_C_COMPILER}"
)
endif()
# Only build idevice if libraries are missing
set(IDEVICE_INSTALL_DIR "${CMAKE_BINARY_DIR}/idevice_ep-prefix")
if(NOT (EXISTS "${IDEVICE_INSTALL_DIR}/lib/idevice/libidevice++.a"
AND EXISTS "${IDEVICE_INSTALL_DIR}/lib/idevice/libidevice_ffi.a"))
ExternalProject_Add(idevice_ep
GIT_REPOSITORY https://github.com/jkcoxson/idevice.git
GIT_TAG v0.1.65
PATCH_COMMAND
patch --forward --ignore-whitespace -p1 < "${CMAKE_SOURCE_DIR}/patches/idevice/0001-compile-usbmuxd-and-windows-fixes.patch" || true
CONFIGURE_COMMAND ""
BUILD_COMMAND
${CMAKE_COMMAND} -E env
${IDevice_ENV}
cargo build
${IDevice_CARGO_ARGS}
--manifest-path <SOURCE_DIR>/ffi/Cargo.toml
COMMAND ${CMAKE_COMMAND} -E chdir <SOURCE_DIR>/cpp
${CMAKE_COMMAND}
-B build
-DCMAKE_BUILD_TYPE=Release
-DIDEVICE_FFI_PATH=<SOURCE_DIR>/target/${RUST_TARGET}/release/${FFI_LIB_NAME}
"-DCMAKE_CXX_FLAGS=-Du_int64_t=uint64_t -Du_int32_t=uint32_t -Du_int16_t=uint16_t -Du_int8_t=uint8_t"
"-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}"
COMMAND ${CMAKE_COMMAND} --build <SOURCE_DIR>/cpp/build --config Release
INSTALL_COMMAND
${CMAKE_COMMAND} -E make_directory <INSTALL_DIR>/lib/idevice
COMMAND ${CMAKE_COMMAND} -E make_directory <INSTALL_DIR>/include
COMMAND ${CMAKE_COMMAND} -E copy
<SOURCE_DIR>/target/${RUST_TARGET}/release/libidevice_ffi.a
<INSTALL_DIR>/lib/idevice/libidevice_ffi.a
COMMAND ${CMAKE_COMMAND} -E copy
<SOURCE_DIR>/cpp/build/libidevice++.a
<INSTALL_DIR>/lib/idevice/libidevice++.a
COMMAND ${CMAKE_COMMAND} -E copy_directory
<SOURCE_DIR>/cpp/include
<INSTALL_DIR>/include
BUILD_IN_SOURCE 1
)
add_dependencies(palera1n idevice_ep)
endif()
set(IDEVICE_INCLUDE_DIR "${IDEVICE_INSTALL_DIR}/include")
set(IDEVICE_LIBRARY "${IDEVICE_INSTALL_DIR}/lib/idevice/libidevice++.a")
set(IDEVICE_FFI_LIBRARY "${IDEVICE_INSTALL_DIR}/lib/idevice/libidevice_ffi.a")
target_include_directories(palera1n PRIVATE ${IDEVICE_INCLUDE_DIR})
target_link_libraries(palera1n PRIVATE "${IDEVICE_LIBRARY}" "${IDEVICE_FFI_LIBRARY}")
if(MINGW)
target_link_libraries(palera1n PRIVATE bcrypt userenv ntdll)
endif()
target_compile_definitions(palera1n PRIVATE LIBPLIST_STATIC)
+51
View File
@@ -0,0 +1,51 @@
# =========================
# MARK: NON-CMAKE DEPENDENCIES: OPENRAIN
# =========================
message(STATUS "Building with Openra1n support")
if(IOS)
execute_process(
COMMAND xcrun --sdk iphoneos --show-sdk-path
OUTPUT_VARIABLE IOS_SDK
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E env
"CFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -I${CMAKE_SOURCE_DIR}/apple-include-iphoneos"
"CXXFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -I${CMAKE_SOURCE_DIR}/apple-include-iphoneos"
"LDFLAGS=-isysroot ${IOS_SDK} -arch arm64 -miphoneos-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} AR=${CMAKE_AR}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libopenra1n
RESULT_VARIABLE OPENRA1N_BUILD_RESULT
)
elseif(APPLE)
execute_process(
COMMAND ${CMAKE_COMMAND} -E env
"CFLAGS=-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}"
make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libopenra1n
RESULT_VARIABLE OPENRA1N_BUILD_RESULT
)
else()
execute_process(
COMMAND make CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/1stparty/libopenra1n
RESULT_VARIABLE OPENRA1N_BUILD_RESULT
)
endif()
if(NOT OPENRA1N_BUILD_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to build Openra1n.")
endif()
set(OPENRA1N_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/1stparty/libopenra1n/build/include")
set(OPENRA1N_LIB "${CMAKE_SOURCE_DIR}/1stparty/libopenra1n/build/lib/openra1n/libopenra1n.a")
target_include_directories(palera1n PRIVATE ${OPENRA1N_INCLUDE_DIR})
target_link_libraries(palera1n PRIVATE "${OPENRA1N_LIB}")
if(IOS)
target_include_directories(palera1n PRIVATE "${CMAKE_SOURCE_DIR}/apple-include-iphoneos")
endif()
+22 -8
View File
@@ -9,7 +9,7 @@
.Nd arm64 iOS/iPadOS/tvOS 15-26, bridgeOS 5-10 jailbreaking tool .Nd arm64 iOS/iPadOS/tvOS 15-26, bridgeOS 5-10 jailbreaking tool
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl hvlfcBsTVpednq .Op Fl hvlfcBsTVpPednq
.Op Fl e Ar Boot arguments .Op Fl e Ar Boot arguments
.Op Fl k Ar Pongo image .Op Fl k Ar Pongo image
.Op Fl o Ar overlay file .Op Fl o Ar overlay file
@@ -159,6 +159,12 @@ Remove the jailbreak while keeping user data. Some jailbreak files may remain
after running this command. Additionally, jailbreak apps may remain on the after running this command. Additionally, jailbreak apps may remain on the
home screen on for a while even when the files are deleted as the icon cache home screen on for a while even when the files are deleted as the icon cache
still has their icons. When used with still has their icons. When used with
.Fl f , -rootful ,
this will actually boot the device in rootless mode then delete the jailbreak
files. As a result, using the loader app to install the jailbreak environment
is not supported when this option is used together with
.Fl f , -rootful
\[char46]
.It Fl -force-enable-ssv .It Fl -force-enable-ssv
Force the jailbreak to detect Signed System Volume (SSV) as being required on Force the jailbreak to detect Signed System Volume (SSV) as being required on
@@ -174,13 +180,6 @@ option is specified as well.
(It is technically possible to setup fakefs using this option as well, but this (It is technically possible to setup fakefs using this option as well, but this
is not a supported scenario) is not a supported scenario)
.Fl f , -rootful ,
this will actually boot the device in rootless mode then delete the jailbreak
files. As a result, using the loader app to install the jailbreak environment
is not supported when this option is used together with
.Fl f , -rootful
\[char46]
.It Fl l , -rootless .It Fl l , -rootless
Proceed in rootless mode. This option is only supported on iOS/iPadOS. Proceed in rootless mode. This option is only supported on iOS/iPadOS.
@@ -219,6 +218,9 @@ Boots the device in verbose mode, allowing boot logs to be seen.
.It Fl p , -early-exit .It Fl p , -early-exit
Exit after booting into a clean PongoOS shell. Exit after booting into a clean PongoOS shell.
.It Fl P , -late-exit
Exit after uploading existing images into the PongoOS shell.
.It Fl e , -extra-bootargs Ar boot arguments .It Fl e , -extra-bootargs Ar boot arguments
Specify custom XNU kernel command line. Additionally, the Specify custom XNU kernel command line. Additionally, the
.Em wdt=-1 .Em wdt=-1
@@ -372,6 +374,11 @@ Equivalent to using the
.Fl p , -early-exit .Fl p , -early-exit
option. option.
.It Ev RA1N_LATE_EXIT
Equivalent to using the
.Fl P , -late-exit
option.
.It Ev RA1N_EXTRA_BOOTARGS .It Ev RA1N_EXTRA_BOOTARGS
Equivalent to using the Equivalent to using the
.Fl e , -extra-bootargs .Fl e , -extra-bootargs
@@ -600,6 +607,13 @@ has been removed, since it leaks memory in launchd.
has been renamed to has been renamed to
.Fl f, -rootful .Fl f, -rootful
due to its ambiguity. As it supports both fakefs and realfs on certain platforms. due to its ambiguity. As it supports both fakefs and realfs on certain platforms.
.Fl P, -pongo-full
has been renamed to
.Fl P, -late-exit
due to its ambiguity.
.Sh SEE ALSO .Sh SEE ALSO
.Xr launchd 8 .Xr launchd 8
.Xr launchd.plist 5 .Xr launchd.plist 5
+31 -2
View File
@@ -2,15 +2,19 @@
"devicemap":{ "devicemap":{
"iPhone6,1":"iphonese", "iPhone6,1":"iphonese",
"iPhone6,2":"iphonese", "iPhone6,2":"iphonese",
"iPhone7,1":"iphone6s", "iPhone7,1":"iphone6s",
"iPhone7,2":"iphone6s", "iPhone7,2":"iphone6s",
"iPhone8,1":"iphone6s", "iPhone8,1":"iphone6s",
"iPhone8,2":"iphone6s", "iPhone8,2":"iphone6s",
"iPhone8,4":"iphonese", "iPhone8,4":"iphonese",
"iPhone9,1":"iphone7", "iPhone9,1":"iphone7",
"iPhone9,2":"iphone7", "iPhone9,2":"iphone7",
"iPhone9,3":"iphone7", "iPhone9,3":"iphone7",
"iPhone9,4":"iphone7", "iPhone9,4":"iphone7",
"iPhone10,1":"iphone8", "iPhone10,1":"iphone8",
"iPhone10,2":"iphone8", "iPhone10,2":"iphone8",
"iPhone10,4":"iphone8", "iPhone10,4":"iphone8",
@@ -46,7 +50,6 @@
"iPad7,6":"ipad", "iPad7,6":"ipad",
"iPad7,11":"ipad", "iPad7,11":"ipad",
"iPad7,12":"ipad", "iPad7,12":"ipad",
"iPad8,1":"ipad", "iPad8,1":"ipad",
"iPad8,2":"ipad", "iPad8,2":"ipad",
"iPad8,3":"ipad", "iPad8,3":"ipad",
@@ -72,10 +75,33 @@
"iPad4,9":"ipadmini", "iPad4,9":"ipadmini",
"iPad5,1":"ipadmini", "iPad5,1":"ipadmini",
"iPad5,2":"ipadmini", "iPad5,2":"ipadmini",
"iPod7,1":"ipodtouch", "iPod7,1":"ipodtouch",
"iPod9,1":"ipodtouch7", "iPod9,1":"ipodtouch7",
"AppleTV5,3":"appletv4", "AppleTV5,3":"appletv4",
"AppleTV6,2":"appletv4k" "AppleTV6,2":"appletv4k",
"iMac20,1":"dfuonly",
"iMac20,2":"dfuonly",
"MacBookAir8,1":"dfuonly",
"MacBookAir8,2":"dfuonly",
"MacBookPro9,1":"dfuonly",
"MacBookPro15,1":"dfuonly",
"MacBookPro15,2":"dfuonly",
"MacBookPro15,3":"dfuonly",
"MacBookPro15,4":"dfuonly",
"MacBookPro16,1":"dfuonly",
"MacBookPro16,2":"dfuonly",
"MacBookPro16,3":"dfuonly",
"MacBookPro16,4":"dfuonly",
"iMacPro1,1":"dfuonly",
"Macmini8,1":"dfuonly",
"MacPro7,1":"dfuonly",
"iBridge2,11":"dfuonly",
"iBridge2,13":"dfuonly",
"AudioAccessory1,1":"dfuonly",
"AudioAccessory1,2":"dfuonly"
}, },
"devicelayout":{ "devicelayout":{
"ipodtouch7":{ "ipodtouch7":{
@@ -271,6 +297,9 @@
} }
}, },
"sequence":"atv_standard_breakout" "sequence":"atv_standard_breakout"
},
"dfuonly": {
"is_supported": false
} }
}, },
"sequences":{ "sequences":{
+51 -10
View File
@@ -48,6 +48,8 @@ prefix_path="${XDG_BIN_HOME:-$HOME/.local}"
bin_path="$prefix_path/bin" bin_path="$prefix_path/bin"
install_path="$bin_path/palera1n" install_path="$bin_path/palera1n"
old_install_path="/usr/local/bin/palera1n" old_install_path="/usr/local/bin/palera1n"
# DMG shit
downloaded_dmg="0"
download() { download() {
local url="$1" local url="$1"
@@ -230,15 +232,44 @@ esac
# Run # Run
# ========= # =========
download_version=$(curl -s https://api.github.com/repos/palera1n/palera1n/releases/latest | grep -o '"tag_name": "[^"]*' | sed 's/"tag_name": "//' || true) latest_tag=$(curl -fsSL https://api.github.com/repos/palera1n/palera1n/tags \
| grep -m1 -o '"name": "[^"]*' \
| sed 's/"name": "//' || true)
if [ -z "$download_version" ]; then latest_release=$(curl -fsSL https://api.github.com/repos/palera1n/palera1n/releases/latest \
error "Could not retrieve the latest release version from GitHub API." | grep -o '"tag_name": "[^"]*' \
| sed 's/"tag_name": "//' || true)
if [ -z "$latest_release" ]; then
error "Could not retrieve the latest release version from GitHub."
exit 1 exit 1
fi fi
if [ -n "$latest_tag" ] && [ "$latest_tag" != "$latest_release" ]; then
printf "Select a version to download:\n"
printf " 1) Latest Beta (%s)\n" "$latest_tag"
printf " 2) Latest Release (%s)\n" "$latest_release"
printf "Choice [1/2, default: 2]: "
read -r choice
case "$choice" in
1)
download_version="$latest_tag"
;;
""|2)
download_version="$latest_release"
;;
*)
error "Invalid selection."
exit 1
;;
esac
else
download_version="$latest_release"
fi
info "Detected environment: $os_name ($arch)" info "Detected environment: $os_name ($arch)"
info "Targeting release tag: ${download_version}" info "Targeting version: ${download_version}"
download_prefix="https://github.com/palera1n/palera1n/releases/download" download_prefix="https://github.com/palera1n/palera1n/releases/download"
mkdir -p "$bin_path" mkdir -p "$bin_path"
@@ -267,12 +298,17 @@ case "$os" in
tgz_url="${download_prefix}/${download_version}/palera1n-macos-${arch}.tar.gz" tgz_url="${download_prefix}/${download_version}/palera1n-macos-${arch}.tar.gz"
bin_url="${download_prefix}/${download_version}/palera1n-macos-${arch}" bin_url="${download_prefix}/${download_version}/palera1n-macos-${arch}"
if curl -fsLI "$dmg_url" >/dev/null 2>&1; then hdiutil detach "/Volumes/palera1n-macos-universal" >/dev/null 2>&1 || true
error "DMG releases are not supported by this CLI installer. Please download the DMG manually."
exit 1
fi
if curl -fsLI "$tgz_url" >/dev/null 2>&1; then if curl -fsLI "$dmg_url" >/dev/null 2>&1; then
info "Downloading macOS DMG..."
dmg_file="$TMPDIR/palera1n-macos-universal-$(date +%s).dmg"
download "$dmg_url" "$dmg_file"
hdiutil attach "$dmg_file" >/dev/null 2>&1
open "/Volumes/palera1n-macos-universal"
rm -f -- "$dmg_file"
downloaded_dmg="1"
elif curl -fsLI "$tgz_url" >/dev/null 2>&1; then
info "Installing from macOS tarball..." info "Installing from macOS tarball..."
curl -fsSL "$tgz_url" | tar -xz -C "$prefix_path" curl -fsSL "$tgz_url" | tar -xz -C "$prefix_path"
else else
@@ -283,6 +319,11 @@ case "$os" in
;; ;;
esac esac
if [ "$downloaded_dmg" = "1" ]; then
info "palera1n DMG downloaded. Please drag the palera1n app to your Applications folder."
exit 0
fi
add_to_path "$bin_path" add_to_path "$bin_path"
if [ -f "$install_path" ]; then if [ -f "$install_path" ]; then
@@ -294,7 +335,7 @@ if [ -f "$install_path" ]; then
info "palera1n installed successfully at ${install_path}." info "palera1n installed successfully at ${install_path}."
info "Type \`palera1n\` in your terminal to get started!" info "Type \`palera1n\` in your terminal to get started!"
exec "${SHELL:-/bin/sh}" -l exec "${SHELL:-/bin/sh}" -l
else else
error "palera1n failed to install. Please check your internet connection and try again." error "palera1n failed to install. Please check your internet connection and try again."
exit 1 exit 1
fi fi
+3
View File
@@ -369,6 +369,9 @@ static struct irecv_device irecv_devices[] = {
/* Apple Vision Pro */ /* Apple Vision Pro */
{ "RealityDevice14,1", "n301ap", 0x42, 0x8112, "Apple Vision Pro" }, { "RealityDevice14,1", "n301ap", 0x42, 0x8112, "Apple Vision Pro" },
{ "RealityDevice17,1", "n301aap", 0x42, 0x8142, "Apple Vision Pro (M5)" }, { "RealityDevice17,1", "n301aap", 0x42, 0x8142, "Apple Vision Pro (M5)" },
/* Lightning Video Adapters */
{ "iAccy1,1", "b137ap", 0x00, 0x8747, "Lightning Digital AV Adapter" },
{ "iAccy1,2", "b165ap", 0x02, 0x8747, "Lightning to VGA Adapter" },
/* Private Cloud Compute Research Environment */ /* Private Cloud Compute Research Environment */
{ "iPhone99,11", "vresearch101ap", 0x90, 0xFE01, "iPhone 99,11" }, { "iPhone99,11", "vresearch101ap", 0x90, 0xFE01, "iPhone 99,11" },
{ nullptr, nullptr, -1, -1, nullptr } { nullptr, nullptr, -1, -1, nullptr }
+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 {
+2
View File
@@ -67,6 +67,7 @@ const char* stage_to_string(int stage)
case STAGE_YOLODFU: return "Booting PongoOS..."; case STAGE_YOLODFU: return "Booting PongoOS...";
case STAGE_PONGO: return "Booting..."; case STAGE_PONGO: return "Booting...";
case STAGE_DONE: return "Done!"; case STAGE_DONE: return "Done!";
case STAGE_ERROR: return "Error!";
default: return "Waiting..."; default: return "Waiting...";
} }
} }
@@ -80,6 +81,7 @@ int stage_to_progress(int stage)
case STAGE_YOLODFU: return 60; case STAGE_YOLODFU: return 60;
case STAGE_PONGO: return 70; case STAGE_PONGO: return 70;
case STAGE_DONE: return 100; case STAGE_DONE: return 100;
case STAGE_ERROR: return 99;
default: return 0; default: return 0;
} }
} }
+26 -3
View File
@@ -39,7 +39,7 @@
#endif #endif
#if WITH_RAMDISK #if WITH_RAMDISK
# include "gen/embedded/ramdisk.h" # include "gen/embedded/ramdisk.h"
# include "gen/embedded/ramdisk-compressed.dmg.h" # include "gen/embedded/ramdisk-compressed.h"
#endif #endif
#include "gen/embedded/Pongo.h" #include "gen/embedded/Pongo.h"
#include "gen/embedded/checkra1n-kpf-pongo.h" #include "gen/embedded/checkra1n-kpf-pongo.h"
@@ -64,8 +64,8 @@ payload_t g_payload_overlay = {
#if WITH_RAMDISK #if WITH_RAMDISK
payload_t g_payload_ramdisk = { payload_t g_payload_ramdisk = {
.data = embedded_ramdisk_compressed_dmg_lzma, .data = embedded_ramdisk_compressed_lzma,
.data_len = embedded_ramdisk_compressed_dmg_lzma_len, .data_len = embedded_ramdisk_compressed_lzma_len,
.uncompressed_data_len = embedded_ramdisk_dmg_len, .uncompressed_data_len = embedded_ramdisk_dmg_len,
}; };
#else #else
@@ -88,6 +88,29 @@ payload_t g_payload_kpf = {
.uncompressed_data_len = embedded_checkra1n_kpf_pongo_len, .uncompressed_data_len = embedded_checkra1n_kpf_pongo_len,
}; };
#define PONGO_MAX_SZ (0x7fe00)
#define MACHO_MAGIC_32 (0xFEEDFACE)
#define MACHO_MAGIC_64 (0xFEEDFACF)
bool check_payload_validity(const payload_t *payload, bool isPongo)
{
if (!payload || !payload->data || payload->data_len < 4)
return false;
const uint32_t magic = *(const uint32_t *)payload->data;
const bool isMachO = (magic == MACHO_MAGIC_32 || magic == MACHO_MAGIC_64);
if (isPongo) {
if (isMachO || payload->data_len > PONGO_MAX_SZ)
return false;
} else {
if (!isMachO)
return false;
}
return true;
}
bool override_payload_from_file(const char *path, payload_t *out) bool override_payload_from_file(const char *path, payload_t *out)
{ {
FILE *f = fopen(path, "rb"); FILE *f = fopen(path, "rb");
+1
View File
@@ -52,6 +52,7 @@ extern payload_t g_payload_kpf;
extern "C" { extern "C" {
#endif #endif
bool check_payload_validity(const payload_t *payload, bool isPongo);
bool override_payload_from_file(const char *path, payload_t *out); bool override_payload_from_file(const char *path, payload_t *out);
#ifdef __cplusplus #ifdef __cplusplus
+114 -123
View File
@@ -65,7 +65,7 @@ void print_credits() {
"::\n" "::\n"
":: ======== Made by =======>\n" ":: ======== Made by =======>\n"
":: Made by: asdfugil, kok3shidoll, claration, mineek\n" ":: Made by: asdfugil, kok3shidoll, claration, mineek\n"
":: plooshi, staturnz\n" ":: sarah, staturnz\n"
":: ======== Thanks to =======>\n" ":: ======== Thanks to =======>\n"
":: Thanks to: itsnebulalol, llsc12, lrdsnow, dedbeddedbed\n" ":: Thanks to: itsnebulalol, llsc12, lrdsnow, dedbeddedbed\n"
":: kirb, ehilwyma, opa334, 0x7ff, alfiecg25, sneko, sbingner\n" ":: kirb, ehilwyma, opa334, 0x7ff, alfiecg25, sneko, sbingner\n"
@@ -103,6 +103,7 @@ void print_usage(char* argv) {
" -T, --telnetd Enable TELNET daemon on port 46 (insecure)\n" " -T, --telnetd Enable TELNET daemon on port 46 (insecure)\n"
" -V, --verbose-boot Enable verbose booting\n" " -V, --verbose-boot Enable verbose booting\n"
" -p, --early-exit Exit after uploading Pongo\n" " -p, --early-exit Exit after uploading Pongo\n"
" -P, --late-exit Exit after uploading existing images to Pongo\n"
" -e, --extra-bootargs <BOOTARGS> Set extra bootargs\n" " -e, --extra-bootargs <BOOTARGS> Set extra bootargs\n"
" -k, --override-pongo <FILE PATH> Override Pongo image\n" " -k, --override-pongo <FILE PATH> Override Pongo image\n"
" -K, --override-kpf <FILE PATH> Override kernel patchfinder\n" " -K, --override-kpf <FILE PATH> Override kernel patchfinder\n"
@@ -136,6 +137,7 @@ void print_usage(char* argv) {
" RA1N_TELNETD=1 Enable TELNET daemon on port 46 (insecure)\n" " RA1N_TELNETD=1 Enable TELNET daemon on port 46 (insecure)\n"
" RA1N_VERBOSE_BOOT=1 Enable verbose booting\n" " RA1N_VERBOSE_BOOT=1 Enable verbose booting\n"
" RA1N_EARLY_EXIT=1 Exit after uploading Pongo\n" " RA1N_EARLY_EXIT=1 Exit after uploading Pongo\n"
" RA1N_LATE_EXIT=1 Exit after uploading existing images to Pongo\n"
" RA1N_EXTRA_BOOTARGS=<FILE PATH> Set extra bootargs\n" " RA1N_EXTRA_BOOTARGS=<FILE PATH> Set extra bootargs\n"
" RA1N_OVERRIDE_PONGO=<FILE PATH> Override Pongo image\n" " RA1N_OVERRIDE_PONGO=<FILE PATH> Override Pongo image\n"
" RA1N_OVERRIDE_KPF=<FILE PATH> Override kernel patchfinder\n" " RA1N_OVERRIDE_KPF=<FILE PATH> Override kernel patchfinder\n"
@@ -171,15 +173,6 @@ void parse_arguments(int argc, char* argv[]) {
int options; int options;
int option_index = 0; int option_index = 0;
bool set_cli = false, set_gui = false, set_tui = false;
bool set_flower = false, set_force_revert = false, set_ssv = false;
bool set_rootless = false, set_rootful = false;
bool set_fakefs = false, set_partial_fakefs = false;
bool set_safemode = false, set_telnetd = false, set_verbose = false;
bool set_pongo_exit = false, set_no_colors = false, set_quick = false;
bool set_extra_bootargs = false, set_pongo = false, set_kpf = false;
bool set_overlay = false, set_ramdisk = false;
static struct option long_options[] = { static struct option long_options[] = {
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
@@ -202,6 +195,7 @@ void parse_arguments(int argc, char* argv[]) {
{"telnetd", no_argument, NULL, 'T'}, {"telnetd", no_argument, NULL, 'T'},
{"verbose-boot", no_argument, NULL, 'V'}, {"verbose-boot", no_argument, NULL, 'V'},
{"early-exit", no_argument, NULL, 'p'}, {"early-exit", no_argument, NULL, 'p'},
{"late-exit", no_argument, NULL, 'P'},
{"extra-bootargs", required_argument, NULL, 'e'}, {"extra-bootargs", required_argument, NULL, 'e'},
{"override-pongo", required_argument, NULL, 'k'}, {"override-pongo", required_argument, NULL, 'k'},
{"override-kpf", required_argument, NULL, 'K'}, {"override-kpf", required_argument, NULL, 'K'},
@@ -241,7 +235,7 @@ void parse_arguments(int argc, char* argv[]) {
// MARK: Standard // MARK: Standard
while ((options = getopt_long(argc, argv, "hvlfcBsTVpe:k:K:o:r:dnq", long_options, &option_index)) != -1) { while ((options = getopt_long(argc, argv, "hvlfcBsTVpPe:k:K:o:r:dnq", long_options, &option_index)) != -1) {
switch (options) { switch (options) {
case 'h': // --help case 'h': // --help
print_usage(argv[0]); print_usage(argv[0]);
@@ -294,11 +288,9 @@ void parse_arguments(int argc, char* argv[]) {
palerain_flags |= palerain_option_ssv; palerain_flags |= palerain_option_ssv;
break; break;
case 'l': // --rootless case 'l': // --rootless
palerain_flags &= ~palerain_option_rootful;
palerain_flags |= palerain_option_rootless; palerain_flags |= palerain_option_rootless;
break; break;
case 'f': // --rootful case 'f': // --rootful
palerain_flags &= ~palerain_option_rootless;
palerain_flags |= palerain_option_rootful; palerain_flags |= palerain_option_rootful;
break; break;
case 'c': // --setup-fakefs case 'c': // --setup-fakefs
@@ -319,6 +311,9 @@ void parse_arguments(int argc, char* argv[]) {
case 'p': // --early-exit case 'p': // --early-exit
palerain_flags |= palerain_option_pongo_exit; palerain_flags |= palerain_option_pongo_exit;
break; break;
case 'P': // --late-exit
palerain_flags |= palerain_option_pongo_full;
break;
case 'e': // --extra-bootargs case 'e': // --extra-bootargs
if (strlen(optarg) > (sizeof(boot_args) - 0x20)) { if (strlen(optarg) > (sizeof(boot_args) - 0x20)) {
LOG_ERROR("Boot arguments too long!"); LOG_ERROR("Boot arguments too long!");
@@ -338,11 +333,10 @@ void parse_arguments(int argc, char* argv[]) {
LOG_ERROR("Failed to load pongo payload, is the path correct?"); LOG_ERROR("Failed to load pongo payload, is the path correct?");
exit(1); exit(1);
} }
if (g_payload_pongo.data_len > PONGO_MAX_SZ) { if (!check_payload_validity(&g_payload_pongo, true)) {
LOG_ERROR("Pongo payload is too large! %zu bytes (max %zu)", g_payload_pongo.data_len, PONGO_MAX_SZ); LOG_ERROR("Pongo payload is invalid or too large! %zu bytes", g_payload_pongo.data_len);
exit(1); exit(1);
} }
// TODO: check if macho, otherwise exit
LOG("Overriding pongo payload with %s", optarg); LOG("Overriding pongo payload with %s", optarg);
break; break;
case 'K': // --override-kpf case 'K': // --override-kpf
@@ -350,11 +344,8 @@ void parse_arguments(int argc, char* argv[]) {
LOG_ERROR("Failed to load kpf payload, is the path correct?"); LOG_ERROR("Failed to load kpf payload, is the path correct?");
exit(1); exit(1);
} }
if (g_payload_kpf.data_len < 4 if (!check_payload_validity(&g_payload_kpf, false)) {
|| (memcmp(g_payload_kpf.data, MACHO_MAGIC_64, 4) != 0 LOG_ERROR("KPF payload is invalid! Is it a valid Mach-O binary?");
&& memcmp(g_payload_kpf.data, MACHO_MAGIC_32, 4) != 0))
{
LOG_ERROR("Invalid kpf payload, is it macho?");
exit(1); exit(1);
} }
LOG("Overriding kpf payload with %s", optarg); LOG("Overriding kpf payload with %s", optarg);
@@ -394,65 +385,66 @@ void parse_arguments(int argc, char* argv[]) {
// MARK: Environment vars // MARK: Environment vars
if (!set_cli && get_env_binary("RA1N_CLI") == 1) { if (get_env_binary("RA1N_CLI") == 1) {
palerain_flags &= ~palerain_option_tui; palerain_flags &= ~palerain_option_tui;
palerain_flags &= ~palerain_option_gui; palerain_flags &= ~palerain_option_gui;
palerain_flags |= palerain_option_cli; palerain_flags |= palerain_option_cli;
} }
#ifdef WITH_GUI #ifdef WITH_GUI
if (!set_gui && get_env_binary("RA1N_GUI") == 1) { if (get_env_binary("RA1N_GUI") == 1) {
palerain_flags &= ~palerain_option_cli; palerain_flags &= ~palerain_option_cli;
palerain_flags &= ~palerain_option_tui; palerain_flags &= ~palerain_option_tui;
palerain_flags |= palerain_option_gui; palerain_flags |= palerain_option_gui;
} }
#endif #endif
#ifdef WITH_TUI #ifdef WITH_TUI
if (!set_tui && get_env_binary("RA1N_TUI") == 1) { if (get_env_binary("RA1N_TUI") == 1) {
palerain_flags &= ~palerain_option_cli; palerain_flags &= ~palerain_option_cli;
palerain_flags &= ~palerain_option_gui; palerain_flags &= ~palerain_option_gui;
palerain_flags |= palerain_option_tui; palerain_flags |= palerain_option_tui;
} }
#endif #endif
if (!set_flower && get_env_binary("RA1N_DARK_BLOCKCHAIN") == 1) { if (get_env_binary("RA1N_DARK_BLOCKCHAIN") == 1) {
palerain_flags |= palerain_option_flower_chain; palerain_flags |= palerain_option_flower_chain;
} }
if (!set_force_revert && get_env_binary("RA1N_FORCE_REVERT") == 1) { if (get_env_binary("RA1N_FORCE_REVERT") == 1) {
palerain_flags |= palerain_option_force_revert; palerain_flags |= palerain_option_force_revert;
} }
if (!set_ssv && get_env_binary("RA1N_FORCE_ENABLE_SSV") == 1) { if (get_env_binary("RA1N_FORCE_ENABLE_SSV") == 1) {
palerain_flags |= palerain_option_ssv; palerain_flags |= palerain_option_ssv;
} }
if (!set_rootless && get_env_binary("RA1N_ROOTLESS") == 1) { if (get_env_binary("RA1N_ROOTLESS") == 1) {
palerain_flags &= ~palerain_option_rootful;
palerain_flags |= palerain_option_rootless; palerain_flags |= palerain_option_rootless;
} }
if (!set_rootful && get_env_binary("RA1N_ROOTFUL") == 1) { if (get_env_binary("RA1N_ROOTFUL") == 1) {
palerain_flags &= ~palerain_option_rootless;
palerain_flags |= palerain_option_rootful; palerain_flags |= palerain_option_rootful;
} }
if (!set_fakefs && get_env_binary("RA1N_SETUP_FAKEFS") == 1) { if (get_env_binary("RA1N_SETUP_FAKEFS") == 1) {
palerain_flags |= palerain_option_setup_rootful; palerain_flags |= palerain_option_setup_rootful;
} }
if (!set_partial_fakefs && get_env_binary("RA1N_SETUP_PARTIAL_FAKEFS") == 1) { if (get_env_binary("RA1N_SETUP_PARTIAL_FAKEFS") == 1) {
palerain_flags |= palerain_option_setup_partial_root; palerain_flags |= palerain_option_setup_partial_root;
} }
if (!set_safemode && get_env_binary("RA1N_SAFE_MODE") == 1) { if (get_env_binary("RA1N_SAFE_MODE") == 1) {
palerain_flags |= palerain_option_safemode; palerain_flags |= palerain_option_safemode;
} }
if (!set_telnetd && get_env_binary("RA1N_TELNETD") == 1) { if (get_env_binary("RA1N_TELNETD") == 1) {
palerain_flags |= palerain_option_telnetd; palerain_flags |= palerain_option_telnetd;
} }
if (!set_verbose && get_env_binary("RA1N_VERBOSE_BOOT") == 1) { if (get_env_binary("RA1N_VERBOSE_BOOT") == 1) {
palerain_flags |= palerain_option_verbose_boot; palerain_flags |= palerain_option_verbose_boot;
} }
if (!set_pongo_exit && get_env_binary("RA1N_EARLY_EXIT") == 1) { if (get_env_binary("RA1N_EARLY_EXIT") == 1) {
palerain_flags |= palerain_option_pongo_exit; palerain_flags |= palerain_option_pongo_exit;
} }
if (!set_no_colors && get_env_binary("RA1N_NO_COLORS") == 1) { if (get_env_binary("RA1N_LATE_EXIT") == 1) {
palerain_flags |= palerain_option_pongo_full;
}
if (get_env_binary("RA1N_NO_COLORS") == 1) {
palerain_flags |= palerain_option_no_colors; palerain_flags |= palerain_option_no_colors;
} }
#if defined(WITH_GUI) || defined(WITH_TUI) #if defined(WITH_GUI) || defined(WITH_TUI)
if (!set_quick && get_env_binary("RA1N_QUICK") == 1) { if (get_env_binary("RA1N_QUICK") == 1) {
palerain_flags |= palerain_option_quick; palerain_flags |= palerain_option_quick;
} }
#endif #endif
@@ -465,116 +457,115 @@ void parse_arguments(int argc, char* argv[]) {
} }
} }
if (!set_extra_bootargs) { const char *env_bootargs = getenv("RA1N_EXTRA_BOOTARGS");
const char *env_bootargs = getenv("RA1N_EXTRA_BOOTARGS"); if (env_bootargs) {
if (env_bootargs) { if (strlen(env_bootargs) > (sizeof(boot_args) - 0x20)) {
if (strlen(env_bootargs) > (sizeof(boot_args) - 0x20)) { LOG_ERROR("Boot arguments too long!");
LOG_ERROR("Boot arguments too long!"); exit(1);
exit(1);
}
snprintf(boot_args, sizeof(boot_args), "%s", env_bootargs);
} }
snprintf(boot_args, sizeof(boot_args), "%s", env_bootargs);
} }
if (!set_pongo) { const char *env_pongo = getenv("RA1N_OVERRIDE_PONGO");
const char *env_pongo = getenv("RA1N_OVERRIDE_PONGO"); if (env_pongo) {
if (env_pongo) { if (!override_payload_from_file(env_pongo, &g_payload_pongo)) {
if (!override_payload_from_file(env_pongo, &g_payload_pongo)) { LOG_ERROR("Failed to load pongo payload from env, is the path correct?");
LOG_ERROR("Failed to load pongo payload from env, is the path correct?"); exit(1);
exit(1);
}
if (g_payload_pongo.data_len > PONGO_MAX_SZ) {
LOG_ERROR("Pongo payload is too large! %zu bytes (max %zu)", g_payload_pongo.data_len, PONGO_MAX_SZ);
exit(1);
}
LOG("Overriding pongo payload with %s (from env)", env_pongo);
} }
if (!check_payload_validity(&g_payload_pongo, true)) {
LOG_ERROR("Pongo payload is invalid or too large! %zu bytes", g_payload_pongo.data_len);
exit(1);
}
LOG("Overriding pongo payload with %s (from env)", env_pongo);
} }
if (!set_kpf) { const char *env_kpf = getenv("RA1N_OVERRIDE_KPF");
const char *env_kpf = getenv("RA1N_OVERRIDE_KPF"); if (env_kpf) {
if (env_kpf) { if (!override_payload_from_file(env_kpf, &g_payload_kpf)) {
if (!override_payload_from_file(env_kpf, &g_payload_kpf)) { LOG_ERROR("Failed to load kpf payload from env, is the path correct?");
LOG_ERROR("Failed to load kpf payload from env, is the path correct?"); exit(1);
exit(1);
}
if (g_payload_kpf.data_len < 4
|| (memcmp(g_payload_kpf.data, MACHO_MAGIC_64, 4) != 0
&& memcmp(g_payload_kpf.data, MACHO_MAGIC_32, 4) != 0))
{
LOG_ERROR("Invalid kpf payload from env, is it macho?");
exit(1);
}
LOG("Overriding kpf payload with %s (from env)", env_kpf);
} }
if (!check_payload_validity(&g_payload_kpf, false)) {
LOG_ERROR("Invalid kpf payload from env, is it macho?");
exit(1);
}
LOG("Overriding kpf payload with %s (from env)", env_kpf);
} }
if (!set_overlay) { const char *env_overlay = getenv("RA1N_OVERRIDE_OVERLAY");
const char *env_overlay = getenv("RA1N_OVERRIDE_OVERLAY"); if (env_overlay) {
if (env_overlay) { if (!override_payload_from_file(env_overlay, &g_payload_overlay)) {
if (!override_payload_from_file(env_overlay, &g_payload_overlay)) { LOG_ERROR("Failed to load overlay payload from env, is the path correct?");
LOG_ERROR("Failed to load overlay payload from env, is the path correct?"); exit(1);
exit(1);
}
LOG("Overriding overlay payload with %s (from env)", env_overlay);
} }
LOG("Overriding overlay payload with %s (from env)", env_overlay);
} }
if (!set_ramdisk) { const char *env_ramdisk = getenv("RA1N_OVERRIDE_RAMDISK");
const char *env_ramdisk = getenv("RA1N_OVERRIDE_RAMDISK"); if (env_ramdisk) {
if (env_ramdisk) { if (!override_payload_from_file(env_ramdisk, &g_payload_ramdisk)) {
if (!override_payload_from_file(env_ramdisk, &g_payload_ramdisk)) { LOG_ERROR("Failed to load ramdisk payload from env, is the path correct?");
LOG_ERROR("Failed to load ramdisk payload from env, is the path correct?"); exit(1);
exit(1);
}
LOG("Overriding ramdisk payload with %s (from env)", env_ramdisk);
} }
LOG("Overriding ramdisk payload with %s (from env)", env_ramdisk);
} }
// MARK: Flag checks // MARK: Flag checks
if (!(palerain_flags & palerain_option_gui) && if ((palerain_flags & palerain_option_pongo_exit) &&
!(palerain_flags & palerain_option_tui)) (palerain_flags & palerain_option_pongo_full))
{ {
if ((palerain_flags & palerain_option_pongo_exit) && LOG_ERROR("You cannot specify both early-exit and late-exit modes.\n");
((palerain_flags & palerain_option_rootful) || print_usage(argv[0]);
(palerain_flags & palerain_option_rootless) || exit(1);
(palerain_flags & palerain_option_setup_rootful) || }
(palerain_flags & palerain_option_setup_partial_root)))
// Pongo exit modes are standalone and cannot be combined with root modes
if (palerain_flags & (palerain_option_pongo_exit | palerain_option_pongo_full))
{
if (palerain_flags & (palerain_option_rootful | palerain_option_rootless))
{ {
LOG_ERROR("[-p, --early-exit] cannot be used with [-f, --rootful], [-l, --rootless], [-c, --setup-fakefs], or [-B, --setup-partial-fakefs].\n"); LOG_ERROR("Pongo exit modes cannot be used with [-l, --rootless] or [-f, --rootful].\n");
print_usage(argv[0]); print_usage(argv[0]);
exit(1); exit(1);
} }
if (!(palerain_flags & palerain_option_pongo_exit) && goto skip_root_types;
!(palerain_flags & palerain_option_rootful) && }
!(palerain_flags & palerain_option_rootless))
{
LOG_ERROR("You must specify either [-l, --rootless] or [-f, --rootful].\n");
print_usage(argv[0]);
exit(1);
}
if ((palerain_flags & palerain_option_rootful) && // Normal root checks
(palerain_flags & palerain_option_rootless)) if (!(palerain_flags & palerain_option_gui) &&
{ !(palerain_flags & palerain_option_tui) &&
LOG_ERROR("You cannot specify both [-l, --rootless] and [-f, --rootful].\n"); !(palerain_flags & palerain_option_rootful) &&
print_usage(argv[0]); !(palerain_flags & palerain_option_rootless))
exit(1); {
} LOG_ERROR("You must specify either [-l, --rootless] or [-f, --rootful].\n");
print_usage(argv[0]);
exit(1);
}
if ((palerain_flags & palerain_option_setup_rootful) && if ((palerain_flags & palerain_option_rootful) &&
(palerain_flags & palerain_option_setup_partial_root)) (palerain_flags & palerain_option_rootless))
{ {
LOG_ERROR("You cannot specify both [-c, --setup-fakefs] and [-B, --setup-partial-fakefs].\n"); LOG_ERROR("You cannot specify both [-l, --rootless] and [-f, --rootful].\n");
print_usage(argv[0]); print_usage(argv[0]);
exit(1); exit(1);
} }
if (((palerain_flags & palerain_option_setup_rootful) || skip_root_types:
(palerain_flags & palerain_option_setup_partial_root)) &&
!(palerain_flags & palerain_option_rootful)) if ((palerain_flags & palerain_option_setup_rootful) &&
(palerain_flags & palerain_option_setup_partial_root))
{
LOG_ERROR("You cannot specify both [-c, --setup-fakefs] and [-B, --setup-partial-fakefs].\n");
print_usage(argv[0]);
exit(1);
}
if ((palerain_flags & palerain_option_setup_rootful) ||
(palerain_flags & palerain_option_setup_partial_root))
{
if (!(palerain_flags & palerain_option_rootful))
{ {
LOG_ERROR("[-c, --setup-fakefs] or [-B, --setup-partial-fakefs] require [-f, --rootful].\n"); LOG_ERROR("[-c, --setup-fakefs] or [-B, --setup-partial-fakefs] require [-f, --rootful].\n");
print_usage(argv[0]); print_usage(argv[0]);
+23 -18
View File
@@ -62,9 +62,7 @@ p1_transfer_ret_t issue_pongo_command(const p1_usb_handle_t *handle, const char
if (command != NULL) { if (command != NULL) {
size_t len = strlen(command); size_t len = strlen(command);
// unlikely to happen, unless we add support for pongoterm if (len >= CMD_LENGTH_MAX) {
// TODO: discuss on adding a pongoterm
if (len > CMD_LENGTH_MAX) {
LOG_ERROR("Pongo command too long: %s", command); LOG_ERROR("Pongo command too long: %s", command);
result.ret = 1; result.ret = 1;
return result; return result;
@@ -86,12 +84,8 @@ p1_transfer_ret_t issue_pongo_command(const p1_usb_handle_t *handle, const char
result = send_interface_control_request(handle, 0x21, 3, 0, 0, command_buf, len); result = send_interface_control_request(handle, 0x21, 3, 0, 0, command_buf, len);
if (result.ret != USB_TRANSFER_OK) goto result; if (result.ret != USB_TRANSFER_OK) goto result;
#endif #endif
// return early if the command is boot, we dont care about results
if (strncmp(command,"boot",4) == 0) goto result;
} }
// TODO: does this work correctly?
while (in_progress) { while (in_progress) {
#if WITH_CIDERRAIN #if WITH_CIDERRAIN
result = usb_ctrl_transfer(handle, 0xA1, 2, 0, 0, &in_progress, sizeof(in_progress)); result = usb_ctrl_transfer(handle, 0xA1, 2, 0, 0, &in_progress, sizeof(in_progress));
@@ -101,26 +95,35 @@ p1_transfer_ret_t issue_pongo_command(const p1_usb_handle_t *handle, const char
if (result.ret != USB_TRANSFER_OK) goto result; if (result.ret != USB_TRANSFER_OK) goto result;
#endif #endif
if (in_progress == 0) break; if (!in_progress) break;
if (outpos > 0x1000) {
if (outpos + 0x1000 >= sizeof(stdout_buf)) { memmove(stdout_buf, stdout_buf + outpos - 0x1000, 0x1000);
memmove(stdout_buf, stdout_buf + 0x1000, sizeof(stdout_buf) - 0x1000); outpos = 0x1000;
outpos -= 0x1000;
} }
outlen = 0;
#if WITH_CIDERRAIN #if WITH_CIDERRAIN
result = usb_ctrl_transfer(handle, 0xA1, 1, 0, 0, stdout_buf + outpos, 0x1000); result = usb_ctrl_transfer(handle, 0xA1, 1, 0, 0, (uint8_t *)(stdout_buf + outpos), 0x1000);
if (result.ret != kUSBResponseSuccess) goto result; if (result.ret != kUSBResponseSuccess) goto result;
outlen = result.wLenDone;
#else #else
result = send_interface_control_request(handle, 0xA1, 1, 0, 0, stdout_buf + outpos, 0x1000); result = send_interface_control_request(handle, 0xA1, 1, 0, 0, stdout_buf + outpos, 0x1000);
if (result.ret != USB_TRANSFER_OK) goto result; if (result.ret != USB_TRANSFER_OK) goto result;
outlen = result.sz;
#endif #endif
outlen = 0x1000;
outpos += outlen; outpos += outlen;
} }
result: result:
if (result.ret != 0) {
// boot command, we don't care about results, lets assume success :-)
if (command != NULL && (!strncmp("boot", command, 4))) {
result.ret = 0;
return result;
}
LOG_ERROR("PongoOS command output: %.*s", (int)outpos, stdout_buf);
}
return result; return result;
} }
@@ -199,8 +202,6 @@ p1_checkm8_err_t send_compressed_pongo(p1_usb_handle_t *handle, const uint8_t *p
return cr; return cr;
} }
// TODO: support early-exit but with all embedded artifacts already loaded
p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle) p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle)
{ {
p1_transfer_ret_t result; p1_transfer_ret_t result;
@@ -280,10 +281,14 @@ p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle)
if (result.ret != 0) goto bad; if (result.ret != 0) goto bad;
} }
if (palerain_flags & palerain_option_pongo_full)
goto good;
// TODO: why do we check results // TODO: why do we check results
result = issue_pongo_command(handle, "bootx"); result = issue_pongo_command(handle, "bootx");
if (result.ret != 0) goto bad; if (result.ret != 0) goto bad;
good:
return 0; return 0;
bad: bad:
return 255; return 255;
-5
View File
@@ -46,11 +46,6 @@ typedef transfer_ret_t p1_transfer_ret_t;
typedef checkm8_err_t p1_checkm8_err_t; typedef checkm8_err_t p1_checkm8_err_t;
#endif #endif
#define PONGO_MAX_SZ (0x7fe00)
// used for checking overridden files (KPF mainly)
#define MACHO_MAGIC_32 (const unsigned char[]){ 0xCE, 0xFA, 0xED, 0xFE }
#define MACHO_MAGIC_64 (const unsigned char[]){ 0xCF, 0xFA, 0xED, 0xFE }
p1_checkm8_err_t send_compressed_pongo(p1_usb_handle_t *handle, const uint8_t *pongo_bin, const size_t pongo_bin_length); p1_checkm8_err_t send_compressed_pongo(p1_usb_handle_t *handle, const uint8_t *pongo_bin, const size_t pongo_bin_length);
p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle); p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle);
+4 -4
View File
@@ -28,7 +28,7 @@
#if defined(WITH_GUI) || defined(WITH_TUI) #if defined(WITH_GUI) || defined(WITH_TUI)
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "gen/embedded/DFUHelperDeviceInfo.h" #include "gen/embedded/DFUHelperDeviceInfo-minified.h"
#include "sequence.hpp" #include "sequence.hpp"
DfuSequence ParseSequence(const std::string& deviceKey) DfuSequence ParseSequence(const std::string& deviceKey)
@@ -36,9 +36,9 @@ DfuSequence ParseSequence(const std::string& deviceKey)
DfuSequence seq; DfuSequence seq;
static nlohmann::json j = nlohmann::json::parse( static nlohmann::json j = nlohmann::json::parse(
embedded_DFUHelperDeviceInfo_json, embedded_DFUHelperDeviceInfo_minified_json,
embedded_DFUHelperDeviceInfo_json + embedded_DFUHelperDeviceInfo_minified_json +
embedded_DFUHelperDeviceInfo_json_len embedded_DFUHelperDeviceInfo_minified_json_len
); );
auto itMap = j["devicemap"].find(deviceKey); auto itMap = j["devicemap"].find(deviceKey);
-6
View File
@@ -118,12 +118,6 @@ void TuiExploitPanel::exploit()
std::thread([this]() std::thread([this]()
{ {
const DeviceState deviceState = GetFrame()->GetDeviceState();
if (!deviceState.connected || deviceState.mode != DeviceMode::DFU) {
m_is_exploiting = false;
return;
}
auto stage = std::make_shared<std::atomic<int>>(STAGE_RESET); auto stage = std::make_shared<std::atomic<int>>(STAGE_RESET);
auto result = std::make_shared<std::atomic<int>>(0); auto result = std::make_shared<std::atomic<int>>(0);
+32 -10
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+";
} }
@@ -136,7 +143,7 @@ void TuiMainPanel::draw(int sy, int sx, int selected) {
} }
const std::string made_by = const std::string made_by =
"Made by: asdfugil, claration, kok3shidoll, mineek, plooshi, staturnz"; "Made by: asdfugil, claration, kok3shidoll, mineek, sarah, staturnz";
const std::string thanks_to = const std::string thanks_to =
"Thanks to: itsnebulalol, llsc12, lrdsnow, dedbeddedbed, kirb, ehilwyma, " "Thanks to: itsnebulalol, llsc12, lrdsnow, dedbeddedbed, kirb, ehilwyma, "
"opa334, 0x7ff, alfiecg24, sneko, sbingner, nikias, " "opa334, 0x7ff, alfiecg24, sneko, sbingner, nikias, "
@@ -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;
} }
+26 -18
View File
@@ -69,14 +69,16 @@ void TuiSettingsPanel::draw(int sy, int sx, int selected) {
!!(palerain_flags & palerain_option_safemode), !!(palerain_flags & palerain_option_safemode),
!!(palerain_flags & palerain_option_verbose_boot), !!(palerain_flags & palerain_option_verbose_boot),
!!(palerain_flags & palerain_option_force_revert), !!(palerain_flags & palerain_option_force_revert),
!!(palerain_flags & palerain_option_flower_chain) !!(palerain_flags & palerain_option_flower_chain),
!!(palerain_flags & palerain_option_ssv)
}; };
const char *labels[] = { const char *labels[] = {
"Safe Mode", "Safe Mode",
"Verbose Boot", "Verbose Boot",
"Restore System", "Restore System",
"Dark Blockchain" "Dark Blockchain",
"Force Enable SSV Flag"
}; };
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
@@ -98,20 +100,25 @@ void TuiSettingsPanel::draw(int sy, int sx, int selected) {
if (selected == i + 1) attroff(A_REVERSE); if (selected == i + 1) attroff(A_REVERSE);
} }
mvprintw(sy + 13, content_x, "Jailbreak Type:"); mvprintw(sy + 13, content_x, "[%c] ", states[4] ? 'x' : ' ');
if (selected == 5) attron(A_REVERSE); if (selected == 5) attron(A_REVERSE);
mvprintw(sy + 14, content_x + 2, "(%c) Rootless", is_rootful ? ' ' : 'x'); printw("%s", labels[4]);
if (selected == 5) attroff(A_REVERSE); if (selected == 5) attroff(A_REVERSE);
mvprintw(sy + 15, content_x, "Jailbreak Type:");
if (selected == 6) attron(A_REVERSE); if (selected == 6) attron(A_REVERSE);
mvprintw(sy + 15, content_x + 2, "(%c) Rootful", is_rootful ? 'x' : ' '); mvprintw(sy + 16, content_x + 2, "(%c) Rootless", is_rootful ? ' ' : 'x');
if (selected == 6) attroff(A_REVERSE); if (selected == 6) attroff(A_REVERSE);
mvprintw(sy + 17, content_x, "Rootful Options:"); if (selected == 7) attron(A_REVERSE);
mvprintw(sy + 17, content_x + 2, "(%c) Rootful", is_rootful ? 'x' : ' ');
if (selected == 7) attroff(A_REVERSE);
mvprintw(sy + 19, content_x, "Rootful Options:");
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
const int item_idx = 7 + i; const int item_idx = 8 + i;
const int row = sy + 18 + i; const int row = sy + 20 + i;
const bool active = is_rootful; const bool active = is_rootful;
const bool is_selected = selected == item_idx; const bool is_selected = selected == item_idx;
const bool checked = setup_selection == i; const bool checked = setup_selection == i;
@@ -171,34 +178,35 @@ void TuiSettingsPanel::handle_enter(int selected, int sy, int sx) {
case 2: edit_boot_args(sy, sx); break; case 2: edit_boot_args(sy, sx); break;
case 3: palerain_flags ^= palerain_option_force_revert; break; case 3: palerain_flags ^= palerain_option_force_revert; break;
case 4: palerain_flags ^= palerain_option_flower_chain; break; case 4: palerain_flags ^= palerain_option_flower_chain; break;
case 5: case 5: palerain_flags ^= palerain_option_ssv; break;
case 6:
palerain_flags &= ~(palerain_option_rootless | palerain_option_rootful); palerain_flags &= ~(palerain_option_rootless | palerain_option_rootful);
palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root); palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root);
palerain_flags |= palerain_option_rootless; palerain_flags |= palerain_option_rootless;
break; break;
case 6: case 7:
palerain_flags &= ~(palerain_option_rootless | palerain_option_rootful); palerain_flags &= ~(palerain_option_rootless | palerain_option_rootful);
palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root); palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root);
palerain_flags |= palerain_option_rootful; palerain_flags |= palerain_option_rootful;
break; break;
case 7:
if (palerain_flags & palerain_option_rootful) {
palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root);
}
break;
case 8: case 8:
if (palerain_flags & palerain_option_rootful) { if (palerain_flags & palerain_option_rootful) {
palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root); palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root);
palerain_flags |= palerain_option_setup_rootful;
} }
break; break;
case 9: case 9:
if (palerain_flags & palerain_option_rootful) {
palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root);
palerain_flags |= palerain_option_setup_rootful;
}
break;
case 10:
if (palerain_flags & palerain_option_rootful) { if (palerain_flags & palerain_option_rootful) {
palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root); palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root);
palerain_flags |= palerain_option_setup_partial_root; palerain_flags |= palerain_option_setup_partial_root;
} }
break; break;
case 10: GetFrame()->ShowMain(0); break; case 11: GetFrame()->ShowMain(0); break;
} }
} }
@@ -207,7 +215,7 @@ void TuiSettingsPanel::handle_device_update(const DeviceState& state) {
} }
bool TuiSettingsPanel::is_button_enabled(int btn_idx) const { bool TuiSettingsPanel::is_button_enabled(int btn_idx) const {
if (btn_idx >= 7 && btn_idx <= 9) { if (btn_idx >= 8 && btn_idx <= 10) {
return (palerain_flags & palerain_option_rootful) != 0; return (palerain_flags & palerain_option_rootful) != 0;
} }
+1 -1
View File
@@ -42,7 +42,7 @@ public:
void handle_device_update(const DeviceState& state) override; void handle_device_update(const DeviceState& state) override;
bool is_button_enabled(int btn_idx) const override; bool is_button_enabled(int btn_idx) const override;
int get_total_items() const override { return 11; } int get_total_items() const override { return 12; }
int get_button_count() const override { return 1; } int get_button_count() const override { return 1; }
const char** get_buttons() const override; const char** get_buttons() const override;
+7
View File
@@ -71,6 +71,13 @@ MainFrame::MainFrame()
SetSizer(root); SetSizer(root);
// menu bar
#if __APPLE__
auto* menuBar = new wxMenuBar;
SetMenuBar(menuBar);
#endif
// listeners
Bind(EVT_DEVICE_STATE_UPDATE, [this](wxCommandEvent& e) Bind(EVT_DEVICE_STATE_UPDATE, [this](wxCommandEvent& e)
{ {
auto* state = static_cast<DeviceState*>(e.GetClientData()); auto* state = static_cast<DeviceState*>(e.GetClientData());
+8 -3
View File
@@ -160,6 +160,7 @@ void DfuPanel::SetDeviceState(const DeviceState& state)
m_index = m_sequence.steps.size(); m_index = m_sequence.steps.size();
m_stepRemaining = -1; m_stepRemaining = -1;
m_actionExecutedIndex = -1; m_actionExecutedIndex = -1;
m_waitingForDfuTransition = true;
const wxColour inactive = const wxColour inactive =
wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT); wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
@@ -191,8 +192,11 @@ void DfuPanel::SetDeviceState(const DeviceState& state)
GetMainFrame()->ShowMain(); GetMainFrame()->ShowMain();
} }
if (!m_isEnteringDfu && !state.connected) if (!state.connected)
{ {
if (m_isEnteringDfu || m_waitingForDfuTransition)
return;
m_isEnteringDfu = false; m_isEnteringDfu = false;
m_backButton->Enable(); m_backButton->Enable();
m_startButton->Enable(); m_startButton->Enable();
@@ -202,6 +206,8 @@ void DfuPanel::SetDeviceState(const DeviceState& state)
void DfuPanel::OnShow(wxShowEvent& event) void DfuPanel::OnShow(wxShowEvent& event)
{ {
DevicePanel::OnShow(event);
if (event.IsShown()) if (event.IsShown())
{ {
if (palerain_flags & palerain_option_quick) { if (palerain_flags & palerain_option_quick) {
@@ -212,8 +218,6 @@ void DfuPanel::OnShow(wxShowEvent& event)
StartSequence(m_sequence); StartSequence(m_sequence);
} }
} }
DevicePanel::OnShow(event);
} }
void DfuPanel::LoadDevice(const std::string& productType) void DfuPanel::LoadDevice(const std::string& productType)
@@ -362,6 +366,7 @@ void DfuPanel::StartSequence(const DfuSequence& seq)
m_index = 0; m_index = 0;
m_stepRemaining = -1; m_stepRemaining = -1;
m_actionExecutedIndex = -1; m_actionExecutedIndex = -1;
m_waitingForDfuTransition = false;
RunStep(); RunStep();
} }
+1
View File
@@ -62,6 +62,7 @@ private:
wxTimer m_timer; wxTimer m_timer;
wxTimer m_stagnentTimer; wxTimer m_stagnentTimer;
bool m_isEnteringDfu = false; bool m_isEnteringDfu = false;
bool m_waitingForDfuTransition = false;
wxPanel* m_devicePanel = nullptr; wxPanel* m_devicePanel = nullptr;
wxStaticBitmap* m_deviceImage = nullptr; wxStaticBitmap* m_deviceImage = nullptr;
-6
View File
@@ -109,12 +109,6 @@ void ExploitPanel::StartExploit()
std::thread([this]() std::thread([this]()
{ {
const auto deviceState = GetDeviceState();
if (!deviceState.connected || deviceState.mode != DeviceMode::DFU) {
wxTheApp->CallAfter([this]() { m_backButton->Enable(); });
return;
}
auto stage = std::make_shared<std::atomic<int>>(STAGE_RESET); auto stage = std::make_shared<std::atomic<int>>(STAGE_RESET);
auto result = std::make_shared<std::atomic<int>>(0); auto result = std::make_shared<std::atomic<int>>(0);
+32 -7
View File
@@ -74,7 +74,7 @@ MainPanel::MainPanel(MainFrame* frame, wxWindow* parent)
auto* credtext = new wxStaticText( auto* credtext = new wxStaticText(
this, this,
wxID_ANY, wxID_ANY,
"Made by: asdfugil, claration, kok3shidoll, mineek, plooshi, staturnz\n\n" "Made by: asdfugil, claration, kok3shidoll, mineek, sarah, staturnz\n\n"
"Thanks to: itsnebulalol, llsc12, lrdsnow, dedbeddedbed, kirb, ehilwyma, " "Thanks to: itsnebulalol, llsc12, lrdsnow, dedbeddedbed, kirb, ehilwyma, "
"opa334, 0x7ff, alfiecg24, sneko, sbingner, nikias, tihmstar, " "opa334, 0x7ff, alfiecg24, sneko, sbingner, nikias, tihmstar, "
"Checkra1n (Siguza, axi0mx, littlelailo et al.), Procursus (Hayden Seay, " "Checkra1n (Siguza, axi0mx, littlelailo et al.), Procursus (Hayden Seay, "
@@ -133,6 +133,11 @@ MainPanel::MainPanel(MainFrame* frame, wxWindow* parent)
palerain_flags &= ~palerain_option_quick; palerain_flags &= ~palerain_option_quick;
}); });
donateButton->Bind(wxEVT_BUTTON, [](wxCommandEvent&)
{
wxLaunchDefaultBrowser("https://patreon.com/palera1n");
});
optionsButton->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&) optionsButton->Bind(wxEVT_BUTTON, [frame](wxCommandEvent&)
{ {
frame->ShowSettings(); frame->ShowSettings();
@@ -144,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);
@@ -216,7 +224,7 @@ void MainPanel::SetDeviceState(const DeviceState& state)
m_deviceTitle->SetLabel("Multiple devices detected"); m_deviceTitle->SetLabel("Multiple devices detected");
m_deviceSubtitle->SetLabel( m_deviceSubtitle->SetLabel(
wxString::Format( wxString::Format(
"%u USB devices connected. Disconnect extras and keep only one device attached.\n", "%u USB devices connected. Disconnect extras and keep\nonly one device attached.",
state.connectedDeviceCount state.connectedDeviceCount
) )
); );
@@ -241,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);
@@ -256,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);
@@ -269,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();
}
break; break;
case DeviceMode::None: case DeviceMode::None:
m_deviceTitle->SetLabel(deviceTextString); m_deviceTitle->SetLabel(deviceTextString);
+181 -79
View File
@@ -30,6 +30,7 @@
#include "SettingsPanel.hpp" #include "SettingsPanel.hpp"
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/notebook.h>
#include <wx/mstream.h> #include <wx/mstream.h>
#include <wx/image.h> #include <wx/image.h>
#include <wx/bitmap.h> #include <wx/bitmap.h>
@@ -41,78 +42,100 @@
#include "../paleinfo.h" #include "../paleinfo.h"
#include "../gen/embedded/logo.h" #include "../gen/embedded/logo.h"
auto createTitle = [](wxWindow* parent, const wxString& text)
{
auto* title = new wxStaticText(parent, wxID_ANY, text);
wxFont font = title->GetFont();
font.SetPointSize(font.GetPointSize() - 1);
font.SetWeight(wxFONTWEIGHT_BOLD);
title->SetFont(font);
return title;
};
auto createDescription = [](wxWindow* parent, const wxString& text)
{
auto* description = new wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, wxST_WRAP);
wxFont font = description->GetFont();
font.SetPointSize(font.GetPointSize() - 2);
description->SetFont(font);
return description;
};
SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent) SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent)
: DevicePanel(frame, parent) : DevicePanel(frame, parent)
{ {
auto* root = new wxBoxSizer(wxHORIZONTAL); auto* root = new wxBoxSizer(wxHORIZONTAL);
auto* left = new wxBoxSizer(wxVERTICAL); auto* left = new wxBoxSizer(wxVERTICAL);
auto* right = new wxBoxSizer(wxVERTICAL);
wxMemoryInputStream stream(embedded_logo_png, embedded_logo_png_len); wxMemoryInputStream stream(embedded_logo_png, embedded_logo_png_len);
wxImage img(stream, wxBITMAP_TYPE_PNG); wxImage img(stream, wxBITMAP_TYPE_PNG);
wxBitmap bmp(img); wxBitmap bmp(img);
auto* logo = new wxStaticBitmap(this, wxID_ANY, bmp); auto* logo = new wxStaticBitmap(this, wxID_ANY, bmp);
auto* logoText = new wxStaticText(this, wxID_ANY, "Options"); auto* logoText = new wxStaticText(this, wxID_ANY, "Options");
auto* right = new wxBoxSizer(wxVERTICAL);
left->Add(new wxStaticText(this, wxID_ANY, left->Add(new wxStaticText(this, wxID_ANY,
"You may set the following options. If you don't know what they mean you'll probably have no reason to set them.", "You may set the following options. If you don't know what they mean you'll probably have no reason to set them.",
wxDefaultPosition, wxDefaultPosition,
wxDefaultSize, wxDefaultSize,
wxST_WRAP wxST_WRAP
), 0, wxALL, 10); ), 0, wxTOP | wxLEFT | wxRIGHT, 10);
auto* optionSafemode = new wxCheckBox(this, wxID_ANY, "Safe Mode"); auto* notebook = new wxNotebook(this, wxID_ANY);
auto* optionVerbose = new wxCheckBox(this, wxID_ANY, "Verbose Boot"); auto* generalPage = new wxPanel(notebook);
auto* optionRevert = new wxCheckBox(this, wxID_ANY, "Restore System"); auto* advancedPage = new wxPanel(notebook);
auto* optionDarkBlockchain = new wxCheckBox(this, wxID_ANY, "Dark Blockchain");
auto* bootArgs = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize);
auto* rootType = new wxRadioBox(
this,
wxID_ANY,
"Jailbreak Type",
wxDefaultPosition,
wxDefaultSize,
2,
(const wxString[]){
"Rootless",
"Rootful"
},
1,
wxRA_SPECIFY_COLS
);
auto* setupMode = new wxRadioBox( //
this, // Controls
wxID_ANY, //
"Rootful Options", auto* optionSafemode = new wxCheckBox(generalPage, wxID_ANY, "Safe Mode");
wxDefaultPosition, auto* optionVerbose = new wxCheckBox(generalPage, wxID_ANY, "Verbose Boot");
wxDefaultSize, auto* optionRevert = new wxCheckBox(generalPage, wxID_ANY, "Restore System");
3, auto* optionDarkBlockchain = new wxCheckBox(generalPage, wxID_ANY, "Dark Blockchain");
(const wxString[]){
"Boot",
"Create FakeFS",
"Create BindFS"
},
1,
wxRA_SPECIFY_COLS
);
auto* rootless = new wxRadioButton(generalPage, wxID_ANY, "Rootless", wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
auto* rootful = new wxRadioButton(generalPage, wxID_ANY, "Rootful");
auto* setupBoot = new wxRadioButton(generalPage, wxID_ANY, "Boot", wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
auto* setupFakeFS = new wxRadioButton(generalPage, wxID_ANY, "Create fakeFS");
auto* setupBindFS = new wxRadioButton(generalPage, wxID_ANY, "Create Partial fakeFS");
auto* bootArgs = new wxTextCtrl(advancedPage, wxID_ANY);
auto* optionForceEnableSSV = new wxCheckBox(advancedPage, wxID_ANY, "Force Enable SSV Flag");
//
// Load
//
optionSafemode->SetValue(palerain_flags & palerain_option_safemode); optionSafemode->SetValue(palerain_flags & palerain_option_safemode);
optionVerbose->SetValue(palerain_flags & palerain_option_verbose_boot); optionVerbose->SetValue(palerain_flags & palerain_option_verbose_boot);
optionRevert->SetValue(palerain_flags & palerain_option_force_revert); optionRevert->SetValue(palerain_flags & palerain_option_force_revert);
optionDarkBlockchain->SetValue(palerain_flags & palerain_option_flower_chain); optionDarkBlockchain->SetValue(palerain_flags & palerain_option_flower_chain);
bootArgs->SetValue(wxString(boot_args, wxConvUTF8)); bootArgs->SetValue(wxString(boot_args, wxConvUTF8));
if (palerain_flags & palerain_option_rootful) optionForceEnableSSV->SetValue(palerain_flags & palerain_option_ssv);
rootType->SetSelection(1);
else rootless->SetValue(!(palerain_flags & palerain_option_rootful));
rootType->SetSelection(0); rootful->SetValue(palerain_flags & palerain_option_rootful);
if (palerain_flags & palerain_option_setup_rootful) if (palerain_flags & palerain_option_setup_rootful)
setupMode->SetSelection(1); setupFakeFS->SetValue(true);
else if (palerain_flags & palerain_option_setup_partial_root) else if (palerain_flags & palerain_option_setup_partial_root)
setupMode->SetSelection(2); setupBindFS->SetValue(true);
else else
setupMode->SetSelection(0); setupBoot->SetValue(true);
setupMode->Enable(rootType->GetSelection() == 1);
bool isRootful = rootful->GetValue();
setupBoot->Enable(true);
setupFakeFS->Enable(isRootful);
setupBindFS->Enable(isRootful);
optionSafemode->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e) optionSafemode->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
{ {
@@ -121,6 +144,7 @@ SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent)
else else
palerain_flags &= ~palerain_option_safemode; palerain_flags &= ~palerain_option_safemode;
}); });
optionVerbose->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e) optionVerbose->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
{ {
if (e.IsChecked()) if (e.IsChecked())
@@ -128,6 +152,7 @@ SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent)
else else
palerain_flags &= ~palerain_option_verbose_boot; palerain_flags &= ~palerain_option_verbose_boot;
}); });
optionRevert->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e) optionRevert->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
{ {
if (e.IsChecked()) if (e.IsChecked())
@@ -135,6 +160,7 @@ SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent)
else else
palerain_flags &= ~palerain_option_force_revert; palerain_flags &= ~palerain_option_force_revert;
}); });
optionDarkBlockchain->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e) optionDarkBlockchain->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
{ {
if (e.IsChecked()) if (e.IsChecked())
@@ -142,60 +168,136 @@ SettingsPanel::SettingsPanel(MainFrame* frame, wxWindow* parent)
else else
palerain_flags &= ~palerain_option_flower_chain; palerain_flags &= ~palerain_option_flower_chain;
}); });
bootArgs->Bind(wxEVT_TEXT, [&](wxCommandEvent& e) bootArgs->Bind(wxEVT_TEXT, [&](wxCommandEvent& e)
{ {
wxString value = e.GetString(); wxString value = e.GetString();
if (value.length() > (sizeof(boot_args) - 0x20)) {
if (value.length() > (sizeof(boot_args) - 0x20))
return; return;
}
snprintf(boot_args, sizeof(boot_args), "%s", value.ToStdString().c_str()); snprintf(boot_args, sizeof(boot_args),
"%s",
value.ToStdString().c_str());
}); });
rootType->Bind(wxEVT_RADIOBOX, [setupMode](wxCommandEvent& e)
optionForceEnableSSV->Bind(wxEVT_CHECKBOX, [&](wxCommandEvent& e)
{ {
palerain_flags &= ~(palerain_option_rootless | palerain_option_rootful); if (e.IsChecked())
palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root); palerain_flags |= palerain_option_ssv;
setupMode->Enable(e.GetSelection() == 1);
setupMode->SetSelection(0);
if (e.GetSelection() == 0)
palerain_flags |= palerain_option_rootless;
else else
palerain_flags |= palerain_option_rootful; palerain_flags &= ~palerain_option_ssv;
}); });
setupMode->Bind(wxEVT_RADIOBOX, [&](wxCommandEvent& e) rootless->Bind(wxEVT_RADIOBUTTON,
[setupBoot, setupFakeFS, setupBindFS](wxCommandEvent&)
{ {
palerain_flags &= ~(palerain_option_setup_rootful | palerain_option_setup_partial_root); palerain_flags &= ~(palerain_option_rootless |
palerain_option_rootful |
palerain_option_setup_rootful |
palerain_option_setup_partial_root);
if (e.GetSelection() == 1) palerain_flags |= palerain_option_rootless;
palerain_flags |= palerain_option_setup_rootful;
else if (e.GetSelection() == 2) setupBoot->SetValue(true);
palerain_flags |= palerain_option_setup_partial_root; setupFakeFS->Enable(false);
setupBindFS->Enable(false);
}); });
auto* contentRow = new wxBoxSizer(wxHORIZONTAL); rootful->Bind(wxEVT_RADIOBUTTON,
auto* leftColumn = new wxBoxSizer(wxVERTICAL); [setupFakeFS, setupBindFS](wxCommandEvent&)
auto* rightColumn = new wxBoxSizer(wxVERTICAL); {
palerain_flags &= ~(palerain_option_rootless |
palerain_option_rootful);
leftColumn->Add(rootType, 0, wxALL | wxEXPAND, 5); palerain_flags |= palerain_option_rootful;
leftColumn->Add(setupMode, 0, wxALL | wxEXPAND, 5);
rightColumn->Add(optionSafemode, 0, wxALL, 5); setupFakeFS->Enable(true);
rightColumn->Add(optionVerbose, 0, wxALL, 5); setupBindFS->Enable(true);
rightColumn->Add(optionRevert, 0, wxALL, 5); });
rightColumn->Add(optionDarkBlockchain, 0, wxALL, 5);
rightColumn->AddStretchSpacer();
contentRow->Add(leftColumn, 1, wxEXPAND | wxRIGHT, 10); setupBoot->Bind(wxEVT_RADIOBUTTON, [](wxCommandEvent&)
contentRow->Add(rightColumn, 1, wxEXPAND | wxLEFT, 10); {
palerain_flags &= ~(palerain_option_setup_rootful |
palerain_option_setup_partial_root);
});
left->Add(contentRow, 1, wxEXPAND | wxLEFT | wxRIGHT, 10); setupFakeFS->Bind(wxEVT_RADIOBUTTON, [&](wxCommandEvent&)
left->Add(new wxStaticText(this, wxID_ANY, "Boot Arguments:"), 0, wxALL, 15); {
left->Add(bootArgs, 0, wxLEFT | wxRIGHT | wxEXPAND, 30); palerain_flags &= ~palerain_option_setup_partial_root;
left->AddStretchSpacer(); palerain_flags |= palerain_option_setup_rootful;
});
setupBindFS->Bind(wxEVT_RADIOBUTTON, [&](wxCommandEvent&)
{
palerain_flags &= ~palerain_option_setup_rootful;
palerain_flags |= palerain_option_setup_partial_root;
});
//
// General
//
auto* generalSizer = new wxBoxSizer(wxHORIZONTAL);
auto* generalLeft = new wxBoxSizer(wxVERTICAL);
auto* generalRight = new wxBoxSizer(wxVERTICAL);
generalLeft->Add(createTitle(generalPage, "Startup"), 0, wxBOTTOM, 3);
generalLeft->Add(optionSafemode, 0, wxTOP, 7);
generalLeft->Add(optionVerbose, 0, wxTOP , 7);
generalLeft->Add(optionRevert, 0, wxTOP, 7);
generalLeft->Add(optionDarkBlockchain, 0, wxTOP, 7);
generalLeft->AddStretchSpacer();
generalRight->Add(createTitle(generalPage, "Jailbreak Type"), 0, wxBOTTOM, 3);
generalRight->Add(rootless, 0, wxTOP, 7);
generalRight->Add(rootful, 0, wxTOP | wxBOTTOM, 5);
generalRight->Add(createTitle(generalPage, "Startup (Rootful)"), 0, wxTOP | wxBOTTOM, 3);
generalRight->Add(setupBoot, 0, wxTOP, 7);
generalRight->Add(setupFakeFS, 0, wxTOP, 5);
generalRight->Add(setupBindFS, 0, wxTOP, 5);
generalRight->AddStretchSpacer();
generalSizer->Add(generalLeft, 1, wxEXPAND | wxRIGHT | wxLEFT, 10);
generalSizer->Add(generalRight, 1, wxEXPAND | wxLEFT, 10);
generalPage->SetSizer(generalSizer);
//
// Advanced
//
auto* advancedOuterSizer = new wxBoxSizer(wxVERTICAL);
auto* advancedSizer = new wxBoxSizer(wxVERTICAL);
advancedSizer->Add(createTitle(advancedPage, "Boot Arguments"), 0, wxBOTTOM, 3);
advancedSizer->Add(bootArgs, 0, wxTOP | wxBOTTOM | wxEXPAND, 7);
advancedSizer->Add(createTitle(advancedPage, "Advanced"), 0, wxTOP | wxBOTTOM, 3);
advancedSizer->Add(optionForceEnableSSV, 0, wxTOP | wxBOTTOM, 7);
advancedSizer->Add(createDescription(advancedPage, "Forces the jailbreak to detect SSV as being required."), 0, wxLEFT | wxRIGHT, 20);
advancedOuterSizer->Add(advancedSizer, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 10);
advancedPage->SetSizer(advancedOuterSizer);
notebook->AddPage(generalPage, "General", true);
notebook->AddPage(advancedPage, "Advanced");
left->Add(notebook, 1, wxEXPAND | wxALL, 10);
//
// Right side
//
auto* back = new wxButton(this, wxID_ANY, "Back"); auto* back = new wxButton(this, wxID_ANY, "Back");
right->Add(logo, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP | wxLEFT | wxRIGHT, 10); right->Add(logo, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP | wxLEFT | wxRIGHT, 10);
right->Add(logoText, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, 5); right->Add(logoText, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, 5);
right->AddStretchSpacer(); right->AddStretchSpacer();