mirror of
https://github.com/palera1n/palera1n.git
synced 2026-10-21 09:47:01 +02:00
Compare commits
306
Commits
v2.0.0-beta.1
...
v2.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e041a3158 | ||
|
|
bb0077b832 | ||
|
|
2d795c1149 | ||
|
|
01d400af23 | ||
|
|
67805496f3 | ||
|
|
1389887b84 | ||
|
|
b62347c73e | ||
|
|
ad08952999 | ||
|
|
91ab9a804d | ||
|
|
edfd827386 | ||
|
|
0404c0f362 | ||
|
|
f795cbd777 | ||
|
|
24e0904f5e | ||
|
|
57c5d7eaa3 | ||
|
|
eb5e7060cc | ||
|
|
28a434084c | ||
|
|
7f55babab1 | ||
|
|
ab94104366 | ||
|
|
95c7d1c47a | ||
|
|
d9dfefadcb | ||
|
|
ff94a8281d | ||
|
|
9eba8965fc | ||
|
|
bb46df31e6 | ||
|
|
fdc554b3c2 | ||
|
|
f1377618b8 | ||
|
|
1670c26313 | ||
|
|
3a404501f7 | ||
|
|
2fbb899c60 | ||
|
|
4a262e1ea4 | ||
|
|
868869deab | ||
|
|
7d3f40d89b | ||
|
|
4b53afc973 | ||
|
|
a31f283c9b | ||
|
|
8d401680dd | ||
|
|
df636c1db9 | ||
|
|
efc8cd6513 | ||
|
|
f5c4b338f2 | ||
|
|
3d2d380820 | ||
|
|
a099e321c0 | ||
|
|
34bc646439 | ||
|
|
147134b495 | ||
|
|
7ddf02e0b9 | ||
|
|
aa91582aba | ||
|
|
39a5ad981c | ||
|
|
59aabaad08 | ||
|
|
106e2214b5 | ||
|
|
3022c6a447 | ||
|
|
a4eacb75c0 | ||
|
|
05ca13d925 | ||
|
|
c01b426a87 | ||
|
|
3a2ff433ed | ||
|
|
0122e6c603 | ||
|
|
cc151e727e | ||
|
|
76b2695e9d | ||
|
|
1e72458985 | ||
|
|
ba2a4dee25 | ||
|
|
f8319e44f1 | ||
|
|
ff581a41e9 | ||
|
|
b4bd41de60 | ||
|
|
0b5b54521f | ||
|
|
17f28f3f0a | ||
|
|
8ef0035dc0 | ||
|
|
34edfd649b | ||
|
|
671e2346ae | ||
|
|
464c832883 | ||
|
|
0e9cd5e1f6 | ||
|
|
08fbb60538 | ||
|
|
8787616ae0 | ||
|
|
eea9dd2435 | ||
|
|
f518fee7c9 | ||
|
|
6e9b8b7d5d | ||
|
|
39f37f5c59 | ||
|
|
d36693c1d8 | ||
|
|
90ff7e4cec | ||
|
|
0355e743a7 | ||
|
|
e84f343a93 | ||
|
|
27e077c570 | ||
|
|
7a3dbefffa | ||
|
|
37e1cb372c | ||
|
|
ca0a7c483d | ||
|
|
3bc59bc237 | ||
|
|
19131ef2dc | ||
|
|
f7fd42f16c | ||
|
|
b3369a8b98 | ||
|
|
c840c226de | ||
|
|
3ea406da58 | ||
|
|
275eaeba96 | ||
|
|
3a08a27dcd | ||
|
|
3a2c372325 | ||
|
|
0140f4c8df | ||
|
|
8c79851880 | ||
|
|
eefefc8623 | ||
|
|
1bcee6f320 | ||
|
|
c0d6c797dd | ||
|
|
8bd67de770 | ||
|
|
053a495755 | ||
|
|
196abc4a88 | ||
|
|
e332a00cf9 | ||
|
|
5dd2980e96 | ||
|
|
4ecc0019ba | ||
|
|
be15a9b6b5 | ||
|
|
05e1872ccb | ||
|
|
3a57693458 | ||
|
|
6a5741a540 | ||
|
|
d93ccc7a69 | ||
|
|
7379a4abba | ||
|
|
2de51b6909 | ||
|
|
a3600700c2 | ||
|
|
37e3fb995e | ||
|
|
26f8d3c79c | ||
|
|
88f74795b8 | ||
|
|
74377dcb40 | ||
|
|
240185c07e | ||
|
|
65707046dd | ||
|
|
6f30ad8314 | ||
|
|
f2ac3ae8d7 | ||
|
|
4ecd75bea7 | ||
|
|
5dac69db66 | ||
|
|
91c5de6408 | ||
|
|
d65877f851 | ||
|
|
3df6791ebd | ||
|
|
06a93e697b | ||
|
|
ffad44ce10 | ||
|
|
4775c8ab23 | ||
|
|
7992b1e2a9 | ||
|
|
3fdb75b9fa | ||
|
|
3b0d8ece54 | ||
|
|
7a20bc0ad9 | ||
|
|
0194d5296a | ||
|
|
ef55859eb0 | ||
|
|
b5db51c1ac | ||
|
|
5106372a4b | ||
|
|
6686fdd1a4 | ||
|
|
48eb11ada0 | ||
|
|
f72ad75db2 | ||
|
|
4a8fb113ae | ||
|
|
03a0a5db6b | ||
|
|
8b56b01cee | ||
|
|
52d20c8e5b | ||
|
|
b0ac19e4d1 | ||
|
|
e8d4e857dd | ||
|
|
bf549b8f86 | ||
|
|
b79ac3176f | ||
|
|
e12216dc5e | ||
|
|
f7603371f6 | ||
|
|
f80e2a8849 | ||
|
|
a30e2ef32a | ||
|
|
2825ccaf17 | ||
|
|
e1e0304b98 | ||
|
|
5f4ef51da9 | ||
|
|
98f7d032eb | ||
|
|
5b32d61a1e | ||
|
|
fd80f9e63f | ||
|
|
52ff0b2e62 | ||
|
|
aa0c3a77b3 | ||
|
|
a5fbf1b18b | ||
|
|
7d3bf14ea6 | ||
|
|
a8325474cf | ||
|
|
8a09d2670a | ||
|
|
30d8241e2d | ||
|
|
e33d50860b | ||
|
|
3b4340525d | ||
|
|
e6033f31cc | ||
|
|
c14d93b008 | ||
|
|
ed48d4fcb4 | ||
|
|
2541330a07 | ||
|
|
58aaf508fc | ||
|
|
e6644c0601 | ||
|
|
194f568363 | ||
|
|
963fbb6ed8 | ||
|
|
88185b7a88 | ||
|
|
3c6213774b | ||
|
|
c35d199809 | ||
|
|
67ca5a9d24 | ||
|
|
8edc991786 | ||
|
|
f59ef6dcee | ||
|
|
1ca25ceca8 | ||
|
|
0a0410d506 | ||
|
|
5f8b503ae3 | ||
|
|
9e253f98f4 | ||
|
|
d17af1fbc7 | ||
|
|
f3920b883d | ||
|
|
1abfdf5441 | ||
|
|
1c3613c669 | ||
|
|
627f9b3363 | ||
|
|
388ae6f296 | ||
|
|
24a09bc44d | ||
|
|
5ea3237772 | ||
|
|
9c094fc19f | ||
|
|
2912dfd8c0 | ||
|
|
a3fa59eaa8 | ||
|
|
290bcb143e | ||
|
|
bb9fdde26e | ||
|
|
a9e72b579e | ||
|
|
fe565b97ad | ||
|
|
1422d45a9f | ||
|
|
869f0fc070 | ||
|
|
cc1a865a86 | ||
|
|
5ce2196268 | ||
|
|
fe50b7c966 | ||
|
|
e02d977c5d | ||
|
|
d82965f140 | ||
|
|
2623569d67 | ||
|
|
2637758372 | ||
|
|
87a2f6b60b | ||
|
|
5e1291d7c4 | ||
|
|
1214aed3a7 | ||
|
|
e96cd19295 | ||
|
|
f37643b93e | ||
|
|
2a9f65c870 | ||
|
|
11b594bec6 | ||
|
|
047b334752 | ||
|
|
c2bb49287a | ||
|
|
2d932dd26b | ||
|
|
03e6739bc9 | ||
|
|
b360e8dd02 | ||
|
|
d72e95fccc | ||
|
|
60f241e0db | ||
|
|
9a7d6151ae | ||
|
|
ac34d4d2be | ||
|
|
8cae820cb8 | ||
|
|
b89fd2b915 | ||
|
|
4070ed9da9 | ||
|
|
6c7f666bb3 | ||
|
|
36fc50d2f1 | ||
|
|
15b2372daa | ||
|
|
b7b52febe3 | ||
|
|
a29a279693 | ||
|
|
b693f1af29 | ||
|
|
41f7909597 | ||
|
|
52167fc32d | ||
|
|
a060fe7374 | ||
|
|
f6450e0a5d | ||
|
|
6dec16ff2b | ||
|
|
8807f4775f | ||
|
|
4b0457b6ee | ||
|
|
6e05ecd1f9 | ||
|
|
16cbb134aa | ||
|
|
f267c3e714 | ||
|
|
e4f46c4276 | ||
|
|
67b9b86940 | ||
|
|
3f73bd0b31 | ||
|
|
8aca098801 | ||
|
|
831794f5eb | ||
|
|
5eb0a08727 | ||
|
|
4572ed5984 | ||
|
|
e81a06513a | ||
|
|
c17107da40 | ||
|
|
a8a7fbdae8 | ||
|
|
2990d9ab75 | ||
|
|
132eb393d0 | ||
|
|
8f81f9b523 | ||
|
|
b28e882b9c | ||
|
|
f5cc175adc | ||
|
|
2a7df193ce | ||
|
|
d974100585 | ||
|
|
9bf956e2da | ||
|
|
bb1bef3676 | ||
|
|
da21a56783 | ||
|
|
749578716a | ||
|
|
9153d71626 | ||
|
|
fae5eaf07e | ||
|
|
df0c0f346d | ||
|
|
75ae960d1a | ||
|
|
06be39a71c | ||
|
|
01bcc332cb | ||
|
|
f519162c61 | ||
|
|
21786017b0 | ||
|
|
79c45399b8 | ||
|
|
6f34b90e15 | ||
|
|
520d79b399 | ||
|
|
7f68777418 | ||
|
|
05eb1d791b | ||
|
|
cad3a8d233 | ||
|
|
fe970cfe2c | ||
|
|
d4052bfe6e | ||
|
|
4836b08998 | ||
|
|
fa7e58f45f | ||
|
|
0aec2f123d | ||
|
|
025baf4d74 | ||
|
|
49f0f74338 | ||
|
|
fd75256cbd | ||
|
|
4b4bc0c97e | ||
|
|
118d826f40 | ||
|
|
bfbdc82d22 | ||
|
|
6edcf92e7d | ||
|
|
79d258814e | ||
|
|
87dae1a7e2 | ||
|
|
4043f8534f | ||
|
|
9df5f68590 | ||
|
|
623cd45286 | ||
|
|
366a81407b | ||
|
|
471d828d5e | ||
|
|
5d48b7b38f | ||
|
|
b67c7beb3c | ||
|
|
86e41f1895 | ||
|
|
3fd35cdb94 | ||
|
|
f00cac7672 | ||
|
|
5420853a88 | ||
|
|
fe3b52f020 | ||
|
|
d07875981a | ||
|
|
9a93f9e340 | ||
|
|
1e4906bb5a | ||
|
|
50d3c47369 | ||
|
|
feda997a99 | ||
|
|
992f54c4e1 |
No files matched your search
@@ -0,0 +1,12 @@
|
||||
name: No Template
|
||||
description: Create a standard issue, no template involved.
|
||||
labels: [palera1n help]
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description:
|
||||
placeholder: Anyone else has issues with ...? If so, I found a solution.
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Mention us on X (formerly known as Twitter)
|
||||
url: https://twitter.com/palera1n
|
||||
about: Mention us about your issue if you're not comfortable with using Github issues.
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Feature Request
|
||||
description: Request a feature in palera1n!
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: textarea
|
||||
id: feature-request
|
||||
attributes:
|
||||
label: Feature Description
|
||||
description:
|
||||
placeholder: I want ... to be added to palera1n, because ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: detailed-description
|
||||
attributes:
|
||||
label: Start going into detail..
|
||||
description:
|
||||
placeholder: I think it should also include ..., because of convenience.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
name: Create Issue
|
||||
description: Ask help for palera1n regarding support or generally how it works!
|
||||
labels: [palera1n help]
|
||||
body:
|
||||
- type: input
|
||||
id: device
|
||||
attributes:
|
||||
label: Device
|
||||
description: What is the device that you're using with palera1n? (iPhone, iPad, iPod Touch, appleTV, iBridge (T2))
|
||||
placeholder: iPhone X
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What is version you're running? (i.e. iOS, iPadOS, tvOS, bridgeOS
|
||||
placeholder: iOS 15.6
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: passcode-enabled
|
||||
attributes:
|
||||
label: Passcode?
|
||||
description: Is your passcode enabled?
|
||||
options:
|
||||
- label: Passcode is enabled.
|
||||
required: false
|
||||
- type: textarea
|
||||
id: detailed-description
|
||||
attributes:
|
||||
label: Start going into detail..
|
||||
description:
|
||||
placeholder: My device couldn't boot jailbroken. I have checked ... using ..., none of the solutions I've been given are working for me. I don't know what to do.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: familiarity
|
||||
attributes:
|
||||
label: Familiarity with palera1n
|
||||
description: Are you familiar with palera1n and how to use it?
|
||||
options:
|
||||
- label: I am familiar with palera1n and how to use it!
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: familiarity-command-line
|
||||
attributes:
|
||||
label: Familiarity with CLI
|
||||
description: Are you familiar with the command-line in anyway? (i.e. Terminal.app, Konsole)
|
||||
options:
|
||||
- label: I am familiar with the command-line!
|
||||
required: false
|
||||
+436
-201
@@ -11,14 +11,22 @@ on:
|
||||
- 'CMakeLists.txt'
|
||||
- '.github/workflows/build.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'docs/**'
|
||||
- 'patches/**'
|
||||
- 'include/**'
|
||||
- 'Makefile'
|
||||
- 'CMakeLists.txt'
|
||||
- '.github/workflows/build.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies (packages)
|
||||
run: |
|
||||
@@ -28,8 +36,12 @@ jobs:
|
||||
- name: Build Documentation
|
||||
run: |
|
||||
make -j$(nproc) docs
|
||||
mkdir ready
|
||||
cp docs/*.html docs/mandoc.css ready
|
||||
mkdir -p ready/docs
|
||||
cp docs/*.html docs/mandoc.css docs/palera1n.1 ready/docs
|
||||
|
||||
- name: Get branch name
|
||||
id: branch-name
|
||||
uses: tj-actions/branch-names@v9
|
||||
|
||||
- name: Upload artifact
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -38,11 +50,11 @@ jobs:
|
||||
host: ${{ secrets.NICKCHAN_FTP_HOST }}
|
||||
port: ${{ secrets.NICKCHAN_FTP_PORT }}
|
||||
username: palera1n
|
||||
privateKey: ${{ secrets.NICKCHAN_FTP_KEY }}
|
||||
password: ${{ secrets.NICKCHAN_FTP_PASS }}
|
||||
forceUpload: true
|
||||
dryRun: false
|
||||
localDir: 'ready/'
|
||||
remoteDir: '/palera1n/artifacts/c-rewrite'
|
||||
remoteDir: "/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch || github.ref_name }}/${{ github.run_number }}"
|
||||
|
||||
build-darwin:
|
||||
strategy:
|
||||
@@ -59,25 +71,27 @@ jobs:
|
||||
- arch: arm64
|
||||
gnu_triple: aarch64-apple-darwin
|
||||
os: iphoneos
|
||||
minos: 14.0
|
||||
runs-on: macos-latest
|
||||
minos: 7.0
|
||||
runs-on: macos-15
|
||||
env:
|
||||
MBEDTLS_VERSION: 3.3.0
|
||||
MBEDTLS_VERSION: 3.5.2
|
||||
READLINE_VERSION: 8.2
|
||||
SLANG_VERSION: 2.3.3
|
||||
NEWT_VERSION: 0.52.23
|
||||
POPT_VERSION: 1.19
|
||||
LIBIMOBILEDEVICE_COMMIT: ed0d66d0341562731bb19928dfe48155509fa7a7
|
||||
LIBIRECOVERY_COMMIT: 7ce02c347b7c26e59498e6af31c9da51018d0fa1
|
||||
LIBIMOBILEDEVICE_GLUE_COMMIT: 362f7848ac89b74d9dd113b38b51ecb601f76094
|
||||
LIBPLIST_COMMIT: 2117b8fdb6b4096455bd2041a63e59a028120136
|
||||
LIBUSBMUXD_COMMIT: a7f0543fb1ecb20ac7121c0fd77297200e0e43fc
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies (packages)
|
||||
run: |
|
||||
sudo /usr/local/bin/pip3 install jsonschema jinja2
|
||||
brew install make autoconf automake pkg-config gnu-sed gettext
|
||||
brew install make autoconf automake pkg-config gnu-sed gettext libtool
|
||||
sudo rm -rf /usr/local/Frameworks/Python*
|
||||
curl -LO https://github.com/ProcursusTeam/ldid/releases/download/v2.1.5-procursus7/ldid_macosx_x86_64
|
||||
sudo install -m755 ldid_macosx_x86_64 /usr/local/bin/ldid
|
||||
@@ -86,25 +100,9 @@ jobs:
|
||||
run: |
|
||||
echo "SDK=$(xcrun -sdk ${{ matrix.os }} --show-sdk-path)" >> $GITHUB_ENV
|
||||
|
||||
- name: Download dependencies (source code)
|
||||
- name: Select correct Xcode
|
||||
run: |
|
||||
curl -LOOOOOO \
|
||||
https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v${{ env.MBEDTLS_VERSION }}.tar.gz \
|
||||
https://mirror-hk.koddos.net/gnu/readline/readline-${{ env.READLINE_VERSION }}.tar.gz \
|
||||
https://www.jedsoft.org/releases/slang/slang-${{ env.SLANG_VERSION }}.tar.bz2 \
|
||||
https://releases.pagure.org/newt/newt-${{ env.NEWT_VERSION }}.tar.gz \
|
||||
https://github.com/rpm-software-management/popt/archive/refs/tags/popt-${{ env.POPT_VERSION }}-release.tar.gz
|
||||
|
||||
tar -xf v${{ env.MBEDTLS_VERSION }}.tar.gz
|
||||
tar -xf readline-${{ env.READLINE_VERSION }}.tar.gz
|
||||
tar -xjf slang-${{ env.SLANG_VERSION }}.tar.bz2
|
||||
tar -xf newt-${{ env.NEWT_VERSION }}.tar.gz
|
||||
tar -xf popt-${{ env.POPT_VERSION }}-release.tar.gz
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libplist
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libimobiledevice-glue
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libirecovery
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libusbmuxd
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libimobiledevice
|
||||
sudo xcode-select -s /Applications/Xcode_16.2.app
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
@@ -116,16 +114,21 @@ jobs:
|
||||
echo "CC=$(xcrun --find cc)" >> $GITHUB_ENV
|
||||
echo "CXX=$(xcrun --find c++)" >> $GITHUB_ENV
|
||||
echo "CPP=$(xcrun --find cc) -E" >> $GITHUB_ENV
|
||||
echo "CFLAGS=-g -Os -arch ${{ matrix.arch }} -m${{ matrix.os }}-version-min=${{ matrix.minos }} -isysroot ${{ env.SDK }} -isystem $(pwd)/sysroot/usr/local/include -Os" >> $GITHUB_ENV
|
||||
echo "CPPFLAGS=-g -Os -arch ${{ matrix.arch }} -m${{ matrix.os }}-version-min=${{ matrix.minos }} -isysroot ${{ env.SDK }} -isystem $(pwd)/sysroot/usr/local/include -Wno-error-implicit-function-declaration -Os" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS=-stdlib=libc++ -g -Os -isysroot ${{ env.SDK }} -arch ${{ matrix.arch }} -m${{ matrix.os }}-version-min=${{ matrix.minos }} -isystem $(pwd)/sysroot/usr/local/include -Os" >> $GITHUB_ENV
|
||||
echo "CFLAGS=-g -Os -isystem ${{ env.SDK }}/usr/include/c++/v1 -arch ${{ matrix.arch }} -m${{ matrix.os }}-version-min=${{ matrix.minos }} -isysroot ${{ env.SDK }} -isystem $(pwd)/sysroot/usr/local/include -Os -g -flto=full -Wl,-object_path_lto,lto.o -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64" >> $GITHUB_ENV
|
||||
echo "CPPFLAGS=-g -Os -isystem ${{ env.SDK }}/usr/include/c++/v1 -arch ${{ matrix.arch }} -m${{ matrix.os }}-version-min=${{ matrix.minos }} -isysroot ${{ env.SDK }} -isystem $(pwd)/sysroot/usr/local/include -Wno-error-implicit-function-declaration -Os -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS=-stdlib=libc++ -g -Os -isystem$(TARGET_SYSROOT)/usr/include/c++/v1 -isysroot ${{ env.SDK }} -arch ${{ matrix.arch }} -m${{ matrix.os }}-version-min=${{ matrix.minos }} -isystem $(pwd)/sysroot/usr/local/include -Os -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64" >> $GITHUB_ENV
|
||||
echo "LDFLAGS=-g -Wl,-dead_strip -arch ${{ matrix.arch }} -isysroot ${{ env.SDK }} -m${{ matrix.os }}-version-min=${{ matrix.minos }} -L$(pwd)/sysroot/usr/local/lib" >> $GITHUB_ENV
|
||||
echo "CFLAGS_FOR_BUILD=-arch $(uname -m) -isysroot $(xcrun -sdk macosx --show-sdk-path) -Os" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS_FOR_BUILD=-stdlib=libc++ -arch $(uname -m) -isysroot $(xcrun -sdk macosx --show-sdk-path) -Os" >> $GITHUB_ENV
|
||||
echo "CPPFLAGS_FOR_BUILD=-arch $(uname -m) -isysroot $(xcrun -sdk macosx --show-sdk-path) -Wno-error-implicit-function-declaration -Os" >> $GITHUB_ENV
|
||||
echo "LDFLAGS_FOR_BUILD=-Wl,-dead_strip" >> $GITHUB_ENV
|
||||
mkdir -p $(pwd)/sysroot/usr/local/lib
|
||||
ln -sf $(pwd)/sysroot/usr/local/lib{,64}
|
||||
|
||||
- name: Prepare iPhoneOS environment
|
||||
if: matrix.os == 'iphoneos'
|
||||
run: |
|
||||
echo "FAKE_PLATFORM=2" >> $GITHUB_ENV
|
||||
echo "FAKE_SDK=7.0" >> $GITHUB_ENV
|
||||
echo "FAKE_MINOS=7.0" >> $GITHUB_ENV
|
||||
|
||||
- name: Prepare headers
|
||||
if: matrix.os != 'macosx'
|
||||
@@ -159,7 +162,59 @@ jobs:
|
||||
gsed -E /'__API_UNAVAILABLE'/d < ${TARGET_SYSROOT}/usr/include/pthread.h > sysroot/usr/local/include/pthread.h
|
||||
gsed -i -E s/'__API_UNAVAILABLE\(.*\)'// sysroot/usr/local/include/IOKit/IOKitLib.h
|
||||
|
||||
- name: Check dependencies cache
|
||||
run: |
|
||||
echo "target: ${{ matrix.os }}-${{ matrix.arch }}" > cache.txt
|
||||
echo "mbedtls ${{ env.MBEDTLS_VERSION }}" >> cache.txt
|
||||
echo "readline: ${{ env.READLINE_VERSION }}" >> cache.txt
|
||||
echo "libimobiledevice: ${{ env.LIBIMOBILEDEVICE_COMMIT }}" >> cache.txt
|
||||
echo "libirecovery: ${{ env.LIBIRECOVERY_COMMIT }}" >> cache.txt
|
||||
echo "libimobiledevice-glue: ${{ env.LIBIMOBILEDEVICE_GLUE_COMMIT }}" >> cache.txt
|
||||
echo "libplist: ${{ env.LIBPLIST_COMMIT }}" >> cache.txt
|
||||
echo "libusbmuxd: ${{ env.LIBUSBMUXD_COMMIT }}" >> cache.txt
|
||||
echo "cc: $($(xcrun --find cc) --version)" >> cache.txt
|
||||
echo "CACHE_TXT_CHECKSUM=sysroot-$(shasum -a 512 cache.txt | cut -d' ' -f1)" >> $GITHUB_ENV
|
||||
|
||||
- name: Download cached sysroot
|
||||
id: sysroot_cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: sysroot-${{ env.CACHE_TXT_CHECKSUM }}.txz
|
||||
key: sysroot-${{ env.CACHE_TXT_CHECKSUM }}
|
||||
|
||||
- name: Extract cached sysroot
|
||||
if: steps.sysroot_cache.outputs.cache-hit == 'true'
|
||||
run: |
|
||||
xz -dcT0 sysroot-${{ env.CACHE_TXT_CHECKSUM }}.txz | tar -x
|
||||
|
||||
- name: Setup sysroot
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
mkdir -p $(pwd)/sysroot/usr/local/lib
|
||||
ln -sf $(pwd)/sysroot/usr/local/lib{,64}
|
||||
|
||||
- name: Download dependencies (source code)
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
curl -LOOOOOO \
|
||||
https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v${{ env.MBEDTLS_VERSION }}.tar.gz \
|
||||
https://mirror-hk.koddos.net/gnu/readline/readline-${{ env.READLINE_VERSION }}.tar.gz
|
||||
|
||||
tar -xf v${{ env.MBEDTLS_VERSION }}.tar.gz
|
||||
tar -xf readline-${{ env.READLINE_VERSION }}.tar.gz
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libplist
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libimobiledevice-glue
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libirecovery
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libusbmuxd
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libimobiledevice
|
||||
cd libplist && git fetch origin ${{ env.LIBPLIST_COMMIT }} && git reset --hard ${{ env.LIBPLIST_COMMIT }} && cd ..
|
||||
cd libirecovery && git fetch origin ${{ env.LIBIRECOVERY_COMMIT }} && git reset --hard ${{ env.LIBIRECOVERY_COMMIT }} && cd ..
|
||||
cd libimobiledevice-glue && git fetch origin ${{ env.LIBIMOBILEDEVICE_GLUE_COMMIT }} && git reset --hard ${{ env.LIBIMOBILEDEVICE_GLUE_COMMIT }} && cd ..
|
||||
cd libimobiledevice && git fetch origin ${{ env.LIBIMOBILEDEVICE_COMMIT }} && git reset --hard ${{ env.LIBIMOBILEDEVICE_COMMIT }} && cd ..
|
||||
cd libusbmuxd && git fetch origin ${{ env.LIBUSBMUXD_COMMIT }} && git reset --hard ${{ env.LIBUSBMUXD_COMMIT }} && cd ..
|
||||
|
||||
- name: Build Mbed TLS
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd mbedtls-${{ env.MBEDTLS_VERSION }}
|
||||
cat ../patches/mbedtls/0001-Allow-empty-x509-cert-issuer.patch | patch -sN -d . -p1
|
||||
@@ -184,6 +239,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build readline
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd readline-${{ env.READLINE_VERSION }}
|
||||
CC=clang CXX=clang++ ./configure ${{ env.CONFIGURE_ARGS }} ac_cv_type_sig_atomic_t=no
|
||||
@@ -191,52 +247,8 @@ jobs:
|
||||
gmake -j$(sysctl -n hw.ncpu) install DESTDIR=${{ env.DESTDIR }}
|
||||
cd ..
|
||||
|
||||
- name: Build S-Lang
|
||||
run: |
|
||||
cd slang-${{ env.SLANG_VERSION }}
|
||||
./configure \
|
||||
${{ env.CONFIGURE_ARGS }} \
|
||||
--without-x \
|
||||
--without-pcre \
|
||||
--without-onig \
|
||||
--without-z \
|
||||
--without-png \
|
||||
--without-iconv
|
||||
gmake -j$(sysctl -n hw.ncpu) static
|
||||
gmake -j$(sysctl -n hw.ncpu) install-static DESTDIR=${{ env.DESTDIR }}
|
||||
cd ..
|
||||
|
||||
- name: Build popt
|
||||
run: |
|
||||
cd popt-popt-${{ env.POPT_VERSION }}-release
|
||||
autoreconf -fiv
|
||||
./configure \
|
||||
${{ env.CONFIGURE_ARGS }} \
|
||||
--without-libiconv-prefix \
|
||||
--without-libintl-prefix \
|
||||
--disable-nls \
|
||||
--disable-werror
|
||||
gmake -j$(sysctl -n hw.ncpu)
|
||||
gmake -j$(sysctl -n hw.ncpu) install DESTDIR=${{ env.DESTDIR }}
|
||||
cd ..
|
||||
|
||||
- name: Build newt
|
||||
run: |
|
||||
cd newt-${{ env.NEWT_VERSION }}
|
||||
./configure \
|
||||
${{ env.CONFIGURE_ARGS }} \
|
||||
--with-readline=gnu \
|
||||
--without-python \
|
||||
--without-tcl \
|
||||
--disable-nls
|
||||
gmake -j$(sysctl -n hw.ncpu) libnewt.a
|
||||
mkdir -p ${{ env.DESTDIR }}/usr/local/{lib/pkgconfig,include}
|
||||
install -m644 libnewt.pc ${{ env.DESTDIR }}/usr/local/lib/pkgconfig
|
||||
install -m644 libnewt.a ${{ env.DESTDIR }}/usr/local/lib
|
||||
install -m644 newt.h ${{ env.DESTDIR }}/usr/local/include
|
||||
cd ..
|
||||
|
||||
- name: Build libplist
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libplist
|
||||
autoreconf -fiv
|
||||
@@ -246,6 +258,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libimobiledevice-glue
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libimobiledevice-glue
|
||||
autoreconf -fiv
|
||||
@@ -255,6 +268,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libirecovery
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
sudo cp -a sysroot/usr/local/* /usr/local
|
||||
cd libirecovery
|
||||
@@ -270,6 +284,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libusbmuxd
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libusbmuxd
|
||||
autoreconf -fiv
|
||||
@@ -279,10 +294,11 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libimobiledevice
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libimobiledevice
|
||||
autoreconf -fiv
|
||||
./configure ${{ env.CONFIGURE_ARGS }} --with-mbedtls --enable-debug
|
||||
./configure ${{ env.CONFIGURE_ARGS }} --with-mbedtls --disable-debug --disable-wireless-pairing
|
||||
echo -e 'all:\ninstall:' > tools/Makefile
|
||||
gmake -j$(sysctl -n hw.ncpu)
|
||||
gmake -j$(sysctl -n hw.ncpu) install DESTDIR=${{ env.DESTDIR }}
|
||||
@@ -293,25 +309,30 @@ jobs:
|
||||
cp -a sysroot/${{ env.PREFIX }}/{include,lib} dep_root
|
||||
find dep_root -name '*.dylib' -delete
|
||||
find dep_root -name '*.la' -delete
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DSTATIC=1 -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_CROSSCOMPILING=true \
|
||||
-DCMAKE_SYSTEM_NAME=Darwin \
|
||||
-DCMAKE_C_COMPILER="${{ env.CC }}" \
|
||||
-DCMAKE_C_FLAGS='${{ env.CFLAGS }}' \
|
||||
-DCMAKE_FIND_ROOT_PATH="${{ env.DESTDIR }}" \
|
||||
-DCMAKE_INSTALL_PREFIX="${{ env.PREFIX }}" \
|
||||
-DSTATIC=1
|
||||
make -j$(sysctl -n hw.ncpu)
|
||||
cd ..
|
||||
mkdir -p ready
|
||||
mv build/src/palera1n palera1n-${{ matrix.os }}-${{ matrix.arch }}
|
||||
gmake -j$(sysctl -n hw.ncpu) ROOTFUL=1
|
||||
cp src/palera1n palera1n-${{ matrix.os }}-${{ matrix.arch }}
|
||||
dsymutil palera1n-${{ matrix.os }}-${{ matrix.arch }}
|
||||
strip palera1n-${{ matrix.os }}-${{ matrix.arch }}
|
||||
ldid -s palera1n-${{ matrix.os }}-${{ matrix.arch }}
|
||||
mkdir -p ready
|
||||
tar -zcf ready/dep_root-${{ matrix.os }}-${{ matrix.arch }}.tgz dep_root
|
||||
|
||||
- name: Build palera1n (Development)
|
||||
run: |
|
||||
gmake -j$(sysctl -n hw.ncpu) clean
|
||||
gmake -j$(sysctl -n hw.ncpu) DEV_BUILD=1 TUI=1 ROOTFUL=1
|
||||
cp src/palera1n palera1n-${{ matrix.os }}-${{ matrix.arch }}.development
|
||||
|
||||
- name: Prepare artifact
|
||||
run: |
|
||||
mkdir -p ready/build_depends
|
||||
tar -zcf ready/build_depends/dep_root-${{ matrix.os }}-${{ matrix.arch }}.tgz dep_root
|
||||
if [ "${{ matrix.os }}" == "macosx" ]; then
|
||||
ldid -S palera1n-${{ matrix.os }}-${{ matrix.arch }}{,.development}
|
||||
else
|
||||
ldid -Ssrc/usb.xml palera1n-${{ matrix.os }}-${{ matrix.arch }}{,.development}
|
||||
fi
|
||||
|
||||
- name: Get branch name
|
||||
id: branch-name
|
||||
uses: tj-actions/branch-names@v9
|
||||
|
||||
- name: Upload artifact
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -320,50 +341,170 @@ jobs:
|
||||
host: ${{ secrets.NICKCHAN_FTP_HOST }}
|
||||
port: ${{ secrets.NICKCHAN_FTP_PORT }}
|
||||
username: palera1n
|
||||
privateKey: ${{ secrets.NICKCHAN_FTP_KEY }}
|
||||
password: ${{ secrets.NICKCHAN_FTP_PASS }}
|
||||
forceUpload: true
|
||||
dryRun: false
|
||||
localDir: 'ready/'
|
||||
remoteDir: '/palera1n/artifacts/c-rewrite'
|
||||
remoteDir: "/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch || github.ref_name }}/${{ github.run_number }}"
|
||||
|
||||
- name: Upload ${{ matrix.os }} thin ${{ matrix.arch }} build
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-${{ matrix.os }}-${{ matrix.arch }}
|
||||
path: palera1n-${{ matrix.os }}-${{ matrix.arch }}
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload ${{ matrix.os }} thin ${{ matrix.arch }} build (Development)
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-${{ matrix.os }}-${{ matrix.arch }}.development
|
||||
path: palera1n-${{ matrix.os }}-${{ matrix.arch }}.development
|
||||
retention-days: 1
|
||||
|
||||
|
||||
- name: Upload ${{ matrix.os }} thin ${{ matrix.arch }} debug symbols
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-${{ matrix.os }}-${{ matrix.arch }}.dSYM
|
||||
path: palera1n-${{ matrix.os }}-${{ matrix.arch }}.dSYM
|
||||
retention-days: 1
|
||||
|
||||
- name: Generate cached sysroot archive
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
tar -c sysroot | xz -zce9T 0 > sysroot-${{ env.CACHE_TXT_CHECKSUM }}.txz
|
||||
|
||||
darwin-dist:
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
runs-on: macos-latest
|
||||
needs: build-darwin
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Procursus
|
||||
uses: beerpiss/[email protected]
|
||||
with:
|
||||
packages: sed coreutils
|
||||
cache: true
|
||||
mirror: 'https://apt.procurs.us/'
|
||||
|
||||
- name: Download all Darwin artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
- name: Prepare artifact
|
||||
run: |
|
||||
find .
|
||||
lipo -create -arch arm64 ./palera1n-macosx-arm64/palera1n-macosx-arm64 -arch x86_64 ./palera1n-macosx-x86_64/palera1n-macosx-x86_64 -output palera1n-macos
|
||||
lipo -create -arch arm64 ./palera1n-macosx-arm64.development/palera1n-macosx-arm64.development -arch x86_64 ./palera1n-macosx-x86_64.development/palera1n-macosx-x86_64.development -output palera1n-macos.development
|
||||
mkdir -p palera1n-macos.dSYM/Contents/Resources/DWARF
|
||||
cp ./palera1n-macosx-x86_64.dSYM/Contents/Info.plist palera1n-macos.dSYM/Contents
|
||||
lipo -create -arch arm64 palera1n-macosx-arm64.dSYM/Contents/Resources/DWARF/palera1n-macosx-arm64 -arch x86_64 palera1n-macosx-x86_64.dSYM/Contents/Resources/DWARF/palera1n-macosx-x86_64 -output palera1n-macos.dSYM/Contents/Resources/DWARF/palera1n-macos
|
||||
mkdir ready
|
||||
cp palera1n-macos ready/palera1n-macos-universal
|
||||
cp ./palera1n-macosx-x86_64/palera1n-macosx-x86_64 ready/palera1n-macos-x86_64
|
||||
cp ./palera1n-macosx-arm64/palera1n-macosx-arm64 ready/palera1n-macos-arm64
|
||||
cp ./palera1n-iphoneos-arm64/palera1n-iphoneos-arm64 ready/palera1n-ios
|
||||
zip -r9 ready/palera1n-ios.dSYM.zip palera1n-iphoneos-arm64.dSYM
|
||||
zip -r9 ready/palera1n-macos.dSYM.zip palera1n-macos.dSYM
|
||||
mkdir -p ready/{debian,binaries,debug_symbols,binaries_development}
|
||||
cp palera1n-macos.development ready/binaries_development/palera1n-macos-universal.development
|
||||
cp palera1n-macos ready/binaries/palera1n-macos-universal
|
||||
cp ./palera1n-macosx-x86_64/palera1n-macosx-x86_64 ready/binaries/palera1n-macos-x86_64
|
||||
cp ./palera1n-macosx-arm64/palera1n-macosx-arm64 ready/binaries/palera1n-macos-arm64
|
||||
cp ./palera1n-iphoneos-arm64/palera1n-iphoneos-arm64 ready/binaries/palera1n-iphoneos-arm64
|
||||
cp ./palera1n-macosx-x86_64.development/palera1n-macosx-x86_64.development ready/binaries_development/palera1n-macos-x86_64.development
|
||||
cp ./palera1n-macosx-arm64.development/palera1n-macosx-arm64.development ready/binaries_development/palera1n-macos-arm64.development
|
||||
cp ./palera1n-iphoneos-arm64.development/palera1n-iphoneos-arm64.development ready/binaries_development/palera1n-iphoneos-arm64.development
|
||||
zip -r9 ready/debug_symbols/palera1n-iphoneos-arm64.dSYM.zip palera1n-iphoneos-arm64.dSYM
|
||||
zip -r9 ready/debug_symbols/palera1n-macosx-arm64.dSYM.zip palera1n-macosx-arm64.dSYM
|
||||
zip -r9 ready/debug_symbols/palera1n-macosx-x86_64.dSYM.zip palera1n-macosx-x86_64.dSYM
|
||||
zip -r9 ready/debug_symbols/palera1n-macos.dSYM.zip palera1n-macos.dSYM
|
||||
|
||||
- name: Build debs
|
||||
run: |
|
||||
make -j$(sysctl -n hw.ncpu) docs
|
||||
version=$(git describe --dirty --tags --abbrev=7 | sed 's|^v||' | sed 's|-beta|~beta|')
|
||||
|
||||
# Darwin x86_64
|
||||
mkdir -p stage/DEBIAN
|
||||
mkdir -p stage/opt/procursus/bin
|
||||
mkdir -p stage/opt/procursus/usr/share/man/man1
|
||||
cp packaging/control.macosx stage/DEBIAN/control
|
||||
|
||||
gsed 's|@DEB_ARCH@|darwin-amd64|g' -i stage/DEBIAN/control
|
||||
gsed "s|@DEB_VERSION@|$version|g" -i stage/DEBIAN/control
|
||||
|
||||
ginstall -Dm644 ready/binaries/palera1n-macos-x86_64 stage/opt/procursus/bin/palera1n
|
||||
zstd -c19 docs/palera1n.1 > stage/opt/procursus/usr/share/man/man1/palera1n.1.zst
|
||||
chmod 644 stage/opt/procursus/usr/share/man/man1/palera1n.1.zst
|
||||
chmod 755 stage/opt/procursus/bin/palera1n
|
||||
|
||||
dpkg-deb --root-owner-group -Zzstd -b stage palera1n_darwin-amd64.deb
|
||||
rm -rf stage
|
||||
|
||||
# Darwin arm64
|
||||
mkdir -p stage/DEBIAN
|
||||
mkdir -p stage/opt/procursus/bin
|
||||
mkdir -p stage/opt/procursus/usr/share/man/man1
|
||||
cp packaging/control.macosx stage/DEBIAN/control
|
||||
|
||||
gsed 's|@DEB_ARCH@|darwin-arm64|g' -i stage/DEBIAN/control
|
||||
gsed "s|@DEB_VERSION@|$version|g" -i stage/DEBIAN/control
|
||||
|
||||
ginstall -Dm644 ready/binaries/palera1n-macos-arm64 stage/opt/procursus/bin/palera1n
|
||||
zstd -c19 docs/palera1n.1 > stage/opt/procursus/usr/share/man/man1/palera1n.1.zst
|
||||
chmod 644 stage/opt/procursus/usr/share/man/man1/palera1n.1.zst
|
||||
chmod 755 stage/opt/procursus/bin/palera1n
|
||||
|
||||
dpkg-deb --root-owner-group -Zzstd -b stage palera1n_darwin-arm64.deb
|
||||
rm -rf stage
|
||||
|
||||
# iPhoneOS
|
||||
mkdir -p stage/DEBIAN
|
||||
mkdir -p stage/usr/bin
|
||||
mkdir -p stage/usr/share/man/man1
|
||||
cp packaging/control stage/DEBIAN/control
|
||||
|
||||
gsed 's|@DEB_ARCH@|iphoneos-arm|g' -i stage/DEBIAN/control
|
||||
gsed "s|@DEB_VERSION@|$version|g" -i stage/DEBIAN/control
|
||||
|
||||
ginstall -Dm644 ready/binaries/palera1n-iphoneos-arm64 stage/usr/bin/palera1n
|
||||
zstd -c19 docs/palera1n.1 > stage/usr/share/man/man1/palera1n.1.zst
|
||||
chmod 644 stage/usr/share/man/man1/palera1n.1.zst
|
||||
chmod 755 stage/usr/bin/palera1n
|
||||
|
||||
dpkg-deb --root-owner-group -Zzstd -b stage palera1n_iphoneos-arm.deb
|
||||
rm -rf stage
|
||||
|
||||
# iPhoneOS (rootless)
|
||||
mkdir -p stage/DEBIAN
|
||||
mkdir -p stage/var/jb/usr/bin
|
||||
mkdir -p stage/var/jb/usr/share/man/man1
|
||||
cp packaging/control stage/DEBIAN/control
|
||||
|
||||
gsed 's|@DEB_ARCH@|iphoneos-arm64|g' -i stage/DEBIAN/control
|
||||
gsed "s|@DEB_VERSION@|$version|g" -i stage/DEBIAN/control
|
||||
|
||||
ginstall -Dm644 ready/binaries/palera1n-iphoneos-arm64 stage/var/jb/usr/bin/palera1n
|
||||
zstd -c19 docs/palera1n.1 > stage/var/jb/usr/share/man/man1/palera1n.1.zst
|
||||
chmod 644 stage/var/jb/usr/share/man/man1/palera1n.1.zst
|
||||
chmod 755 stage/var/jb/usr/bin/palera1n
|
||||
|
||||
dpkg-deb --root-owner-group -Zzstd -b stage palera1n_iphoneos-arm64.deb
|
||||
rm -rf stage
|
||||
|
||||
mv palera1n*.deb ready/debian
|
||||
|
||||
- name: Save build tag
|
||||
run: echo "$(git describe --dirty --tags --abbrev=7 | sed 's|-dirty||')" > build-tag.txt
|
||||
|
||||
- name: Upload build tag
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-tag
|
||||
path: build-tag.txt
|
||||
|
||||
- name: Get branch name
|
||||
id: branch-name
|
||||
uses: tj-actions/branch-names@v9
|
||||
|
||||
- name: Upload artifact
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -372,11 +513,11 @@ jobs:
|
||||
host: ${{ secrets.NICKCHAN_FTP_HOST }}
|
||||
port: ${{ secrets.NICKCHAN_FTP_PORT }}
|
||||
username: palera1n
|
||||
privateKey: ${{ secrets.NICKCHAN_FTP_KEY }}
|
||||
password: ${{ secrets.NICKCHAN_FTP_PASS }}
|
||||
forceUpload: true
|
||||
dryRun: false
|
||||
localDir: 'ready/'
|
||||
remoteDir: '/palera1n/artifacts/c-rewrite'
|
||||
remoteDir: "/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch || github.ref_name }}/${{ github.run_number }}"
|
||||
|
||||
build-Linux:
|
||||
strategy:
|
||||
@@ -388,29 +529,32 @@ jobs:
|
||||
- aarch64-linux-musl
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MBEDTLS_VERSION: 3.3.0
|
||||
LIBUSB_VERSION: 1.0.26
|
||||
MBEDTLS_VERSION: 3.5.2
|
||||
LIBUSB_VERSION: 1.0.27
|
||||
READLINE_VERSION: 8.2
|
||||
SLANG_VERSION: 2.3.3
|
||||
NEWT_VERSION: 0.52.23
|
||||
GPM_VERSION: 1.20.7
|
||||
POPT_VERSION: 1.19
|
||||
LIBIMOBILEDEVICE_COMMIT: ed0d66d0341562731bb19928dfe48155509fa7a7
|
||||
LIBIRECOVERY_COMMIT: 7ce02c347b7c26e59498e6af31c9da51018d0fa1
|
||||
LIBIMOBILEDEVICE_GLUE_COMMIT: 362f7848ac89b74d9dd113b38b51ecb601f76094
|
||||
USBMUXD_COMMIT: bc0b91ca856811f4393318dc83db6dc3c1ac326d
|
||||
LIBPLIST_COMMIT: 2117b8fdb6b4096455bd2041a63e59a028120136
|
||||
LIBUSBMUXD_COMMIT: a7f0543fb1ecb20ac7121c0fd77297200e0e43fc
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install build dependencies (packages)
|
||||
run: |
|
||||
sudo apt-get remove -y libssl-dev libreadline-dev
|
||||
sudo apt-get install -y pkg-config autoconf automake autopoint
|
||||
sudo apt-get install -y pkg-config autoconf automake autopoint mandoc
|
||||
sudo pip3 install jsonschema jinja2
|
||||
|
||||
- name: Download toolchain checksum
|
||||
run: |
|
||||
curl -LO https://musl.cc/SHA512SUMS
|
||||
curl -u ${{ secrets.ACTIONS_RESOURCES_LOGIN }} -LO https://static.palera.in/action-resources/musl-cross/SHA512SUMS
|
||||
echo "TOOLCHAIN_CHECKSUM="$(grep ${{ matrix.triple }}-cross.tgz SHA512SUMS | cut -d' ' -f1) >> $GITHUB_ENV
|
||||
|
||||
- name: Download toolchain (cached)
|
||||
@@ -423,7 +567,7 @@ jobs:
|
||||
- name: Download toolchain
|
||||
if: steps.toolchain_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
curl -LO https://musl.cc/${{ matrix.triple }}-cross.tgz
|
||||
curl -u ${{ secrets.ACTIONS_RESOURCES_LOGIN }} -LO https://static.palera.in/action-resources/musl-cross/${{ matrix.triple }}-cross.tgz
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
@@ -433,57 +577,96 @@ jobs:
|
||||
case ${{ matrix.triple }} in
|
||||
i486-linux-musl)
|
||||
echo "CHECKRA1N_NAME=linux-x86" >> $GITHUB_ENV
|
||||
echo "ARCH_NAME=i386" >> $GITHUB_ENV
|
||||
;;
|
||||
x86_64-linux-musl)
|
||||
echo "CHECKRA1N_NAME=linux-x86_64" >> $GITHUB_ENV
|
||||
echo "ARCH_NAME=amd64" >> $GITHUB_ENV
|
||||
;;
|
||||
armel-linux-musleabi)
|
||||
echo "CHECKRA1N_NAME=linux-armel" >> $GITHUB_ENV
|
||||
echo "ARCH_NAME=armel" >> $GITHUB_ENV
|
||||
;;
|
||||
aarch64-linux-musl)
|
||||
echo "CHECKRA1N_NAME=linux-arm64" >> $GITHUB_ENV
|
||||
echo "ARCH_NAME=arm64" >> $GITHUB_ENV
|
||||
;;
|
||||
esac
|
||||
echo "PKG_CONFIG_PATH=$(pwd)/sysroot/usr/local/lib/pkgconfig" >> $GITHUB_ENV
|
||||
echo "CFLAGS=-g -fdata-sections -ffunction-sections -I$(pwd)/sysroot/usr/local/include -L$(pwd)/sysroot/usr/local/lib" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS=-g -fdata-sections -ffunction-sections -I$(pwd)/sysroot/usr/local/include -L$(pwd)/sysroot/usr/local/lib" >> $GITHUB_ENV
|
||||
echo "CFLAGS=-g -fdata-sections -ffunction-sections -I$(pwd)/sysroot/usr/local/include -L$(pwd)/sysroot/usr/local/lib -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64" >> $GITHUB_ENV
|
||||
echo "CXXFLAGS=-g -fdata-sections -ffunction-sections -I$(pwd)/sysroot/usr/local/include -L$(pwd)/sysroot/usr/local/lib -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64" >> $GITHUB_ENV
|
||||
echo "LDFLAGS=-g -Wl,--gc-sections -fdata-sections -ffunction-sections -I$(pwd)/sysroot/usr/local/include -L$(pwd)/sysroot/usr/local/lib" >> $GITHUB_ENV
|
||||
echo "INSTALL=$(command -v install) --strip-program=${{ matrix.triple }}-strip" >> $GITHUB_ENV
|
||||
echo "DESTDIR=$(pwd)/sysroot" >> $GITHUB_ENV
|
||||
echo "PREFIX=/usr/local" >> $GITHUB_ENV
|
||||
echo "CONFIGURE_ARGS=--build=x86_64-linux-gnu --host=${{ matrix.triple }} --prefix=/usr/local --disable-shared --enable-static" >> $GITHUB_ENV
|
||||
echo "CROSS_COMPILE=${{ matrix.triple }}-" >> $GITHUB_ENV
|
||||
|
||||
- name: Check dependencies cache
|
||||
run: |
|
||||
echo "target: ${{ matrix.triple }}" > cache.txt
|
||||
echo "mbedtls ${{ env.MBEDTLS_VERSION }}" >> cache.txt
|
||||
echo "readline: ${{ env.READLINE_VERSION }}" >> cache.txt
|
||||
echo "libimobiledevice: ${{ env.LIBIMOBILEDEVICE_COMMIT }}" >> cache.txt
|
||||
echo "libirecovery: ${{ env.LIBIRECOVERY_COMMIT }}" >> cache.txt
|
||||
echo "libimobiledevice-glue: ${{ env.LIBIMOBILEDEVICE_GLUE_COMMIT }}" >> cache.txt
|
||||
echo "libplist: ${{ env.LIBPLIST_COMMIT }}" >> cache.txt
|
||||
echo "libusbmuxd: ${{ env.LIBUSBMUXD_COMMIT }}" >> cache.txt
|
||||
echo "usbmuxd: ${{ env.USBMUXD_COMMIT }}" >> cache.txt
|
||||
echo "cc: $(${{ env.CROSS_COMPILE }}gcc --version)" >> cache.txt
|
||||
echo "CACHE_TXT_CHECKSUM=sysroot-$(sha512sum cache.txt | cut -d' ' -f1)" >> $GITHUB_ENV
|
||||
|
||||
- name: Download cached sysroot
|
||||
id: sysroot_cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: sysroot-${{ env.CACHE_TXT_CHECKSUM }}.txz
|
||||
key: sysroot-${{ env.CACHE_TXT_CHECKSUM }}
|
||||
|
||||
- name: Extract cached sysroot
|
||||
if: steps.sysroot_cache.outputs.cache-hit == 'true'
|
||||
run: |
|
||||
xz -dcT0 sysroot-${{ env.CACHE_TXT_CHECKSUM }}.txz | tar -x
|
||||
|
||||
- name: Setup sysroot
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
mkdir -p $(pwd)/sysroot/usr/local/lib
|
||||
ln -sf $(pwd)/sysroot/usr/local/lib{,64}
|
||||
|
||||
- name: Download dependencies (source code)
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
curl -LOOOOOOO \
|
||||
https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v${{ env.MBEDTLS_VERSION }}.tar.gz \
|
||||
https://github.com/libusb/libusb/releases/download/v${{ env.LIBUSB_VERSION }}/libusb-${{ env.LIBUSB_VERSION }}.tar.bz2 \
|
||||
https://mirror-hk.koddos.net/gnu/readline/readline-${{ env.READLINE_VERSION }}.tar.gz \
|
||||
https://www.jedsoft.org/releases/slang/slang-${{ env.SLANG_VERSION }}.tar.bz2 \
|
||||
https://releases.pagure.org/newt/newt-${{ env.NEWT_VERSION }}.tar.gz \
|
||||
https://github.com/telmich/gpm/archive/refs/tags/${{ env.GPM_VERSION }}.tar.gz \
|
||||
https://github.com/rpm-software-management/popt/archive/refs/tags/popt-${{ env.POPT_VERSION }}-release.tar.gz
|
||||
https://github.com/telmich/gpm/archive/refs/tags/${{ env.GPM_VERSION }}.tar.gz
|
||||
|
||||
tar -xf v${{ env.MBEDTLS_VERSION }}.tar.gz
|
||||
tar -xjf libusb-${{ env.LIBUSB_VERSION }}.tar.bz2
|
||||
tar -xf readline-${{ env.READLINE_VERSION }}.tar.gz
|
||||
tar -xjf slang-${{ env.SLANG_VERSION }}.tar.bz2
|
||||
tar -xf newt-${{ env.NEWT_VERSION }}.tar.gz
|
||||
tar -xf ${{ env.GPM_VERSION }}.tar.gz
|
||||
tar -xf popt-${{ env.POPT_VERSION }}-release.tar.gz
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libplist
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libimobiledevice-glue
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libirecovery
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libusbmuxd
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libimobiledevice
|
||||
git clone --depth=1 https://github.com/libimobiledevice/usbmuxd
|
||||
cd libplist && git fetch origin ${{ env.LIBPLIST_COMMIT }} && git reset --hard ${{ env.LIBPLIST_COMMIT }} && cd ..
|
||||
cd libirecovery && git fetch origin ${{ env.LIBIRECOVERY_COMMIT }} && git reset --hard ${{ env.LIBIRECOVERY_COMMIT }} && cd ..
|
||||
cd libimobiledevice-glue && git fetch origin ${{ env.LIBIMOBILEDEVICE_GLUE_COMMIT }} && git reset --hard ${{ env.LIBIMOBILEDEVICE_GLUE_COMMIT }} && cd ..
|
||||
cd usbmuxd && git fetch origin ${{ env.USBMUXD_COMMIT }} && git reset --hard ${{ env.USBMUXD_COMMIT }} && cd ..
|
||||
cd libimobiledevice && git fetch origin ${{ env.LIBIMOBILEDEVICE_COMMIT }} && git reset --hard ${{ env.LIBIMOBILEDEVICE_COMMIT }} && cd ..
|
||||
cd libusbmuxd && git fetch origin ${{ env.LIBUSBMUXD_COMMIT }} && git reset --hard ${{ env.LIBUSBMUXD_COMMIT }} && cd ..
|
||||
|
||||
- name: Build Mbed TLS
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd mbedtls-${{ env.MBEDTLS_VERSION }}
|
||||
cat ../patches/mbedtls/0001-Allow-empty-x509-cert-issuer.patch | patch -sN -d . -p1
|
||||
mkdir build
|
||||
if [ "${{ matrix.triple }}" = "i486-linux-musl" ]; then sed -i '/define MBEDTLS_AESNI_C/d' include/mbedtls/mbedtls_config.h; fi
|
||||
cd build
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
@@ -503,6 +686,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libusb
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libusb-${{ env.LIBUSB_VERSION }}
|
||||
./configure ${{ env.CONFIGURE_ARGS }} --disable-udev
|
||||
@@ -511,6 +695,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build readline
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd readline-${{ env.READLINE_VERSION }}
|
||||
./configure ${{ env.CONFIGURE_ARGS }}
|
||||
@@ -518,22 +703,8 @@ jobs:
|
||||
make -j$(nproc) install DESTDIR=${{ env.DESTDIR }}
|
||||
cd ..
|
||||
|
||||
- name: Build S-Lang
|
||||
run: |
|
||||
cd slang-${{ env.SLANG_VERSION }}
|
||||
./configure \
|
||||
${{ env.CONFIGURE_ARGS }} \
|
||||
--without-x \
|
||||
--without-pcre \
|
||||
--without-onig \
|
||||
--without-z \
|
||||
--without-png \
|
||||
--without-iconv
|
||||
gmake -j$(sysctl -n hw.ncpu) static
|
||||
gmake -j$(sysctl -n hw.ncpu) install-static DESTDIR=${{ env.DESTDIR }}
|
||||
cd ..
|
||||
|
||||
- name: Build GPM
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd gpm-${{ env.GPM_VERSION }}
|
||||
cat ../patches/gpm/*.patch | patch -sN -d . -p1
|
||||
@@ -544,38 +715,8 @@ jobs:
|
||||
gmake -j$(sysctl -n hw.ncpu) install DESTDIR=${{ env.DESTDIR }}
|
||||
cd ..
|
||||
|
||||
- name: Build popt
|
||||
run: |
|
||||
cd popt-popt-${{ env.POPT_VERSION }}-release
|
||||
autoreconf -fiv
|
||||
./configure \
|
||||
${{ env.CONFIGURE_ARGS }} \
|
||||
--without-libiconv-prefix \
|
||||
--without-libintl-prefix \
|
||||
--disable-nls \
|
||||
--disable-werror
|
||||
gmake -j$(sysctl -n hw.ncpu)
|
||||
gmake -j$(sysctl -n hw.ncpu) install DESTDIR=${{ env.DESTDIR }}
|
||||
cd ..
|
||||
|
||||
- name: Build newt
|
||||
run: |
|
||||
cd newt-${{ env.NEWT_VERSION }}
|
||||
./configure \
|
||||
${{ env.CONFIGURE_ARGS }} \
|
||||
--with-readline=gnu \
|
||||
--without-python \
|
||||
--without-tcl \
|
||||
--disable-nls \
|
||||
--with-gpm-support
|
||||
gmake -j$(sysctl -n hw.ncpu) libnewt.a
|
||||
mkdir -p ${{ env.DESTDIR }}/usr/local/{lib/pkgconfig,include}
|
||||
install -m644 libnewt.pc ${{ env.DESTDIR }}/usr/local/lib/pkgconfig
|
||||
install -m644 libnewt.a ${{ env.DESTDIR }}/usr/local/lib
|
||||
install -m644 newt.h ${{ env.DESTDIR }}/usr/local/include
|
||||
cd ..
|
||||
|
||||
- name: Build libplist
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libplist
|
||||
autoreconf -fiv
|
||||
@@ -585,6 +726,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libimobiledevice-glue
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libimobiledevice-glue
|
||||
autoreconf -fiv
|
||||
@@ -594,6 +736,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libirecovery (sorta)
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
sudo mv /usr/local /usr/local.bak
|
||||
sudo ln -s ${{ env.DESTDIR }}${{ env.PREFIX }} /usr/local
|
||||
@@ -607,6 +750,7 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libusbmuxd
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libusbmuxd
|
||||
autoreconf -fiv
|
||||
@@ -616,10 +760,11 @@ jobs:
|
||||
cd ..
|
||||
|
||||
- name: Build libimobiledevice
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd libimobiledevice
|
||||
autoreconf -fiv
|
||||
./configure ${{ env.CONFIGURE_ARGS }} --with-mbedtls --enable-debug
|
||||
./configure ${{ env.CONFIGURE_ARGS }} --with-mbedtls --disable-debug --disable-wireless-pairing
|
||||
echo -e 'all:\ninstall:' > tools/Makefile
|
||||
make -j$(nproc)
|
||||
make -j$(nproc) install DESTDIR=${{ env.DESTDIR }}
|
||||
@@ -627,35 +772,79 @@ jobs:
|
||||
sudo rm /usr/local
|
||||
sudo mv /usr/local.bak /usr/local
|
||||
|
||||
- name: Build usbmuxd
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd usbmuxd
|
||||
autoreconf -fiv
|
||||
./configure ${{ env.CONFIGURE_ARGS }} --without-systemd
|
||||
${{ matrix.triple }}-gcc ${{ env.CFLAGS }} -I${{ env.DESTDIR }}/${{ env.PREFIX }}/include/libusb-1.0 src/*.c \
|
||||
-DHAVE_CONFIG_H -no-pie \
|
||||
-I. -static ${{ env.LDFLAGS }}} -limobiledevice-1.0 -lusbmuxd-2.0 -limobiledevice-glue-1.0 \
|
||||
-lplist-2.0 -lusb-1.0 -lmbedtls -lmbedcrypto -lmbedx509 -lpthread -o usbmuxd
|
||||
mkdir -p ${{ env.DESTDIR }}/${{ env.PREFIX }}/sbin
|
||||
${{ matrix.triple }}-objcopy --only-keep-debug usbmuxd usbmuxd.debug
|
||||
${{ matrix.triple }}-strip --strip-debug --strip-unneeded usbmuxd
|
||||
${{ matrix.triple }}-objcopy --add-gnu-debuglink=usbmuxd.debug usbmuxd
|
||||
install -m755 usbmuxd usbmuxd.debug ${{ env.DESTDIR }}/${{ env.PREFIX }}/sbin
|
||||
cd ..
|
||||
|
||||
- name: Build palera1n
|
||||
run: |
|
||||
cp -a sysroot/${{ env.PREFIX }}/{include,lib} dep_root
|
||||
cp -a ${{ env.DESTDIR }}/${{ env.PREFIX }}/{include,lib} dep_root
|
||||
find dep_root -name '*.so' -delete
|
||||
find dep_root -name '*.la' -delete
|
||||
mkdir build
|
||||
cd build
|
||||
CC="${{ matrix.triple }}-gcc" cmake .. -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${{ env.PREFIX }} \
|
||||
-DCMAKE_FIND_ROOT_PATH=${{ env.DESTDIR }}${{ env.PREFIX }} \
|
||||
-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
|
||||
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
|
||||
-DCMAKE_C_FLAGS="-I${{ env.DESTDIR }}${{ env.PREFIX }}/include \
|
||||
-L${{ env.DESTDIR }}${{ env.PREFIX }}/lib -Wl,-rpath,${{ env.PREFIX }}/lib" -DSTATIC=1
|
||||
make -j$(nproc) CC="${{ matrix.triple }}-gcc"
|
||||
CC="${{ matrix.triple }}-gcc" make -j$(nproc) ROOTFUL=1
|
||||
cp src/palera1n palera1n.release
|
||||
|
||||
- name: Seperate debug symbols
|
||||
run: |
|
||||
${{ matrix.triple }}-objcopy --only-keep-debug build/src/palera1n palera1n.debug
|
||||
${{ matrix.triple }}-strip --strip-debug --strip-unneeded build/src/palera1n
|
||||
${{ matrix.triple }}-objcopy --add-gnu-debuglink=palera1n.debug build/src/palera1n
|
||||
${{ matrix.triple }}-objcopy --only-keep-debug palera1n.release palera1n.debug
|
||||
${{ matrix.triple }}-strip --strip-debug --strip-unneeded palera1n.release
|
||||
${{ matrix.triple }}-objcopy --add-gnu-debuglink=palera1n.debug palera1n.release
|
||||
chmod -x palera1n.debug
|
||||
|
||||
|
||||
- name: Build palera1n (Development)
|
||||
run: |
|
||||
CC="${{ matrix.triple }}-gcc" make -j$(nproc) clean
|
||||
CC="${{ matrix.triple }}-gcc" make -j$(nproc) DEV_BUILD=1 ROOTFUL=1
|
||||
cp src/palera1n palera1n.development
|
||||
|
||||
- name: Prepare artifact
|
||||
run: |
|
||||
mkdir ready
|
||||
mv palera1n.debug ready/palera1n-${{ env.CHECKRA1N_NAME }}.debug
|
||||
mv build/src/palera1n ready/palera1n-${{ env.CHECKRA1N_NAME }}
|
||||
tar -zcf ready/dep_root_${{ matrix.triple }}.tgz dep_root
|
||||
mkdir -p ready/{binaries,debian,binaries_development,build_depends,debug_symbols} usbmuxd-static
|
||||
mv palera1n.debug ready/debug_symbols/palera1n-${{ env.CHECKRA1N_NAME }}.debug
|
||||
mv palera1n.release ready/binaries/palera1n-${{ env.CHECKRA1N_NAME }}
|
||||
mv palera1n.development ready/binaries_development/palera1n-${{ env.CHECKRA1N_NAME }}.development
|
||||
tar -zcf ready/build_depends/dep_root_${{ matrix.triple }}.tgz dep_root
|
||||
install -m755 sysroot/${{ env.PREFIX }}/sbin/usbmuxd usbmuxd-static/usbmuxd-${{ env.CHECKRA1N_NAME }}
|
||||
install -m755 sysroot/${{ env.PREFIX }}/sbin/usbmuxd.debug usbmuxd-static/usbmuxd-${{ env.CHECKRA1N_NAME }}.debug
|
||||
|
||||
- name: Build debs
|
||||
run: |
|
||||
version=$(git describe --dirty --tags --abbrev=7 | sed 's|^v||' | sed 's|-beta|~beta|')
|
||||
|
||||
make -j$(nproc) docs
|
||||
mkdir -p stage/DEBIAN
|
||||
mkdir -p stage/usr/bin
|
||||
mkdir -p stage/usr/share/man/man1
|
||||
cp packaging/control stage/DEBIAN/control
|
||||
|
||||
sed 's|@DEB_ARCH@|${{ env.ARCH_NAME }}|g' -i stage/DEBIAN/control
|
||||
sed "s|@DEB_VERSION@|$version|g" -i stage/DEBIAN/control
|
||||
|
||||
install -Dm644 ready/binaries/palera1n-${{ env.CHECKRA1N_NAME }} stage/usr/bin/palera1n
|
||||
gzip -c9 docs/palera1n.1 > stage/usr/share/man/man1/palera1n.1.gz
|
||||
chmod 755 stage/usr/bin/palera1n
|
||||
chmod 644 stage/usr/share/man/man1/palera1n.1.gz
|
||||
|
||||
dpkg-deb --root-owner-group -b stage palera1n_${{ env.ARCH_NAME }}.deb
|
||||
mv palera1n*.deb ready/debian
|
||||
rm -rf stage
|
||||
|
||||
- name: Get branch name
|
||||
id: branch-name
|
||||
uses: tj-actions/branch-names@v9
|
||||
|
||||
- name: Upload artifact
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -664,8 +853,54 @@ jobs:
|
||||
host: ${{ secrets.NICKCHAN_FTP_HOST }}
|
||||
port: ${{ secrets.NICKCHAN_FTP_PORT }}
|
||||
username: palera1n
|
||||
privateKey: ${{ secrets.NICKCHAN_FTP_KEY }}
|
||||
password: ${{ secrets.NICKCHAN_FTP_PASS }}
|
||||
forceUpload: true
|
||||
dryRun: false
|
||||
localDir: 'ready/'
|
||||
remoteDir: '/palera1n/artifacts/c-rewrite'
|
||||
remoteDir: "/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch || github.ref_name }}/${{ github.run_number }}"
|
||||
|
||||
- name: Upload usbmuxd artifact
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: wangyucode/[email protected]
|
||||
with:
|
||||
host: ${{ secrets.NICKCHAN_FTP_HOST }}
|
||||
port: ${{ secrets.NICKCHAN_FTP_PORT }}
|
||||
username: palera1n
|
||||
password: ${{ secrets.NICKCHAN_FTP_PASS }}
|
||||
forceUpload: true
|
||||
dryRun: false
|
||||
localDir: 'usbmuxd-static/'
|
||||
remoteDir: "/palera1n/artifacts/usbmuxd-static"
|
||||
|
||||
- name: Generate cached sysroot archive
|
||||
if: steps.sysroot_cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
tar -c sysroot | xz -zce9T 0 > sysroot-${{ env.CACHE_TXT_CHECKSUM }}.txz
|
||||
|
||||
finish-build:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
needs: [build-docs, build-darwin, darwin-dist, build-Linux]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get branch name
|
||||
id: branch-name
|
||||
uses: tj-actions/branch-names@v9
|
||||
|
||||
- name: Download build tag
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-tag
|
||||
|
||||
- uses: geekyeggo/delete-artifact@v2
|
||||
with:
|
||||
name: '*'
|
||||
failOnError: false
|
||||
|
||||
- name: Send Discord build message
|
||||
run: |
|
||||
COMMITMESSAGE=`git log --pretty=format:'- \`%h\` %s' -1 --reverse` &&
|
||||
(curl "${{ secrets.DISCORD_WEBHOOK }}" -sS -H "Content-Type:application/json" -X POST -d "{\"content\":null,\"embeds\":[{\"title\":\"[palera1n:${{ steps.branch-name.outputs.ref_branch }}] Nightly Build ${{ github.run_number }}\",\"url\":\"https://github.com/palera1n/palera1n/actions/runs/${GITHUB_RUN_ID}\",\"color\":2829617,\"fields\":[{\"name\":\"Build tag\",\"value\":\"- \`$(cat build-tag.txt | sed 's|\n||')\`\"},{\"name\":\"Destination\",\"value\":\"- https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}\"},{\"name\":\"Documentation\",\"value\":\"- [palera1n.1.html](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/docs/palera1n.1.html)\"},{\"name\":\"Main Artifacts\",\"value\":\"- [palera1n-iphoneos-arm64](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/binaries/palera1n-iphoneos-arm64)\n- [palera1n-linux-arm64](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/binaries/palera1n-linux-arm64)\n- [palera1n-linux-armel](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/binaries/palera1n-linux-armel)\n- [palera1n-linux-x86](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/binaries/palera1n-linux-x86)\n- [palera1n-linux-x86_64](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/binaries/palera1n-linux-x86_64)\n- [palera1n-macos-universal](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/binaries/palera1n-macos-universal)\"}],\"footer\":{\"text\":\"${{ github.actor }}\", \"icon_url\": \"https://github.com/${{ github.actor }}.png\",\"timestamp\":\"$(date -u +"%FT%TZ")\"}}],\"username\":\"GitHub Actions\",\"avatar_url\":\"https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png\"}")
|
||||
|
||||
@@ -4,6 +4,7 @@ dep_root/**
|
||||
!contrib/.keep
|
||||
contrib/
|
||||
*.o
|
||||
dep_root*.tgz
|
||||
.vscode
|
||||
checkra1n*
|
||||
payload.c
|
||||
@@ -11,6 +12,7 @@ src/palera1n
|
||||
!xxd-embedded.h
|
||||
src/binpack.dmg
|
||||
src/ramdisk.dmg
|
||||
src/ramdisk.dmg.lzma
|
||||
src/xxd-*.c
|
||||
.DS_Store
|
||||
!palera1n.1
|
||||
@@ -20,3 +22,8 @@ docs/*.html
|
||||
build
|
||||
src/*.dmg.c
|
||||
.idea
|
||||
src/stage2/
|
||||
src/libcheckra1nhelper.dylib*
|
||||
src/Pongo.bin
|
||||
sysroot
|
||||
compile.sh
|
||||
@@ -1,22 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(palera1n)
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
set(CMAKE_CXX_STANDARD 99)
|
||||
set(SRC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(DEP ${SRC}/dep_root)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(STATIC 0)
|
||||
set(CMAKE_SUPPRESS_REGENERATION ON)
|
||||
|
||||
set(CMAKE_BUILD_TYPE BUILD_TYPE)
|
||||
|
||||
|
||||
add_custom_target(distclean
|
||||
COMMAND sh -c "find src -name '*.o' -type f -delete"
|
||||
COMMAND sh -c "find src -perm -u+x -type f -delete"
|
||||
)
|
||||
#add_custom_target(distclean
|
||||
# COMMAND sh -c "rm -rf *"
|
||||
# )
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(docs)
|
||||
@@ -2,13 +2,16 @@ SRC = $(shell pwd)
|
||||
DEP = $(SRC)/dep_root
|
||||
STRIP = strip
|
||||
CC ?= cc
|
||||
CFLAGS += -I$(DEP)/include -I$(SRC)/include -I$(SRC)
|
||||
CFLAGS += -Wall -Wextra -DPALERAIN_VERSION=\"2.0.0\" -Wall -Wextra -Wno-unused-parameter
|
||||
CFLAGS += -Wno-unused-variable -I$(SRC)/src -std=c99 -pedantic-errors -D_C99_SOURCE -D_POSIX_C_SOURCE=199506L -D_DARWIN_C_SOURCE
|
||||
CFLAGS += -isystem $(DEP)/include -I$(SRC)/include -I$(SRC) -D_XOPEN_SOURCE=500
|
||||
CFLAGS += -Wall -Wextra -Wno-unused-parameter -DPALERAIN_VERSION=\"2.1\" -DHAVE_LIBIMOBILEDEVICE
|
||||
CFLAGS += -Wno-unused-variable -I$(SRC)/src -std=c99 -pedantic-errors -D_C99_SOURCE -D_POSIX_C_SOURCE=200112L
|
||||
LIBS += $(DEP)/lib/libimobiledevice-1.0.a $(DEP)/lib/libirecovery-1.0.a $(DEP)/lib/libusbmuxd-2.0.a
|
||||
LIBS += $(DEP)/lib/libimobiledevice-glue-1.0.a $(DEP)/lib/libplist-2.0.a -pthread
|
||||
LIBS += $(DEP)/lib/libimobiledevice-glue-1.0.a $(DEP)/lib/libplist-2.0.a -pthread -lm
|
||||
ifeq ($(TARGET_OS),)
|
||||
TARGET_OS = $(shell uname -s)
|
||||
UNAME = $(TARGET_OS)
|
||||
else
|
||||
UNAME = $(shell uname -s)
|
||||
endif
|
||||
ifeq ($(TARGET_OS),Darwin)
|
||||
CFLAGS += -Wno-nullability-extension
|
||||
@@ -16,22 +19,27 @@ ifeq (,$(findstring version-min=, $(CFLAGS)))
|
||||
CFLAGS += -mmacosx-version-min=10.8
|
||||
endif
|
||||
LDFLAGS += -Wl,-dead_strip
|
||||
LIBS += -framework CoreFoundation -framework SystemConfiguration -framework IOKit -framework Security
|
||||
LIBS += -framework CoreFoundation -framework IOKit
|
||||
else
|
||||
CFLAGS += -fdata-sections -ffunction-sections
|
||||
LDFLAGS += -static -no-pie -Wl,--gc-sections
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
endif
|
||||
LIBS += $(DEP)/lib/libmbedtls.a $(DEP)/lib/libmbedcrypto.a $(DEP)/lib/libmbedx509.a $(DEP)/lib/libreadline.a
|
||||
|
||||
ifeq ($(DEV_BUILD),1)
|
||||
LIBS += $(DEP)/lib/libnewt.a $(DEP)/lib/libpopt.a $(DEP)/lib/libslang.a
|
||||
ifeq ($(TUI),1)
|
||||
ifeq ($(TARGET_OS),Linux)
|
||||
LIBS += $(DEP)/lib/libgpm.a
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(DEV_BUILD),1)
|
||||
CFLAGS += -O0 -g -DDEV_BUILD -fno-omit-frame-pointer
|
||||
ifeq ($(ASAN),1)
|
||||
BUILD_STYLE=ASAN
|
||||
CFLAGS += -fsanitize=address,undefined -fsanitize-address-use-after-return=runtime
|
||||
else ifeq ($(TSAN),1)
|
||||
BUILD_STYLE=TSAN
|
||||
CFLAGS += -fsanitize=thread,undefined
|
||||
else
|
||||
BUILD_STYLE = DEVELOPMENT
|
||||
endif
|
||||
@@ -39,13 +47,31 @@ else
|
||||
CFLAGS += -Os -g
|
||||
BUILD_STYLE = RELEASE
|
||||
endif
|
||||
BUILD_DATE := $(shell LANG=C date)
|
||||
LIBS += -lc
|
||||
|
||||
ifeq ($(TARGET_OS),Linux)
|
||||
ifneq ($(shell echo '$(BUILD_STYLE)' | grep -q '[A-Z]\+SAN' && echo 1),1)
|
||||
LDFLAGS += -static -no-pie
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(BAKERAIN_DEVELOPE_R),)
|
||||
CFLAGS += -DBAKERAIN_DEVELOPE_R="\"$(BAKERAIN_DEVELOPE_R)\""
|
||||
endif
|
||||
|
||||
BUILD_NUMBER := $(shell git rev-list --count HEAD)
|
||||
BUILD_TAG := $(shell git describe --dirty --tags --abbrev=7)
|
||||
BUILD_WHOAMI := $(shell whoami)
|
||||
BUILD_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
||||
BUILD_COMMIT := $(shell git rev-parse HEAD)
|
||||
|
||||
CFLAGS += -DBUILD_STYLE=\"$(BUILD_STYLE)\" -DBUILD_DATE="\"$(BUILD_DATE)\"" -DBUILD_WHOAMI=\"$(BUILD_WHOAMI)\" -DBUILD_TAG=\"$(BUILD_TAG)\"
|
||||
CFLAGS += -DBUILD_STYLE="\"$(BUILD_STYLE)\"" -DBUILD_TAG="\"$(BUILD_TAG)\""
|
||||
CFLAGS += -DBUILD_NUMBER="\"$(BUILD_NUMBER)\"" -DBUILD_BRANCH="\"$(BUILD_BRANCH)\""
|
||||
CFLAGS += -DBUILD_COMMIT="\"$(BUILD_COMMIT)\""
|
||||
|
||||
export SRC DEP CC CFLAGS LDFLAGS LIBS TARGET_OS DEV_BUILD BUILD_DATE BUILD_TAG BUILD_WHOAMI BUILD_STYLE
|
||||
CPATH =
|
||||
LIBRARY_PATH =
|
||||
|
||||
export SRC DEP UNAME CC CFLAGS LDFLAGS LIBS SHELL TARGET_OS DEV_BUILD BUILD_DATE BUILD_TAG BUILD_WHOAMI BUILD_STYLE BUILD_NUMBER BUILD_BRANCH
|
||||
|
||||
all: palera1n
|
||||
|
||||
@@ -57,13 +83,13 @@ clean:
|
||||
$(MAKE) -C docs clean
|
||||
|
||||
download-deps:
|
||||
$(MAKE) -C src checkra1n-macos checkra1n-linux-arm64 checkra1n-linux-armel checkra1n-linux-x86 checkra1n-linux-x86_64 checkra1n-kpf-pongo ramdisk.dmg binpack.dmg
|
||||
$(MAKE) -C src $(patsubst %, resources/%, checkra1n-macos checkra1n-linux-arm64 checkra1n-linux-armel checkra1n-linux-x86 checkra1n-linux-x86_64 checkra1n-kpf-pongo ramdisk.dmg binpack.dmg Pongo.bin)
|
||||
|
||||
docs:
|
||||
$(MAKE) -C docs
|
||||
|
||||
distclean: clean
|
||||
rm -rf palera1n-* palera1n*.dSYM src/checkra1n-* src/checkra1n-kpf-pongo src/ramdisk.dmg src/binpack.dmg
|
||||
$(MAKE) -C src distclean
|
||||
|
||||
.PHONY: all palera1n clean docs distclean
|
||||
|
||||
@@ -1,97 +1,133 @@
|
||||
<h1 align="center">
|
||||
palera1n
|
||||
</h1>
|
||||
# palera1n
|
||||
[](https://github.com/palera1n/palera1n/releases)
|
||||
[](https://github.com/palera1n/palera1n/releases)
|
||||
[](https://github.com/palera1n/palera1n/blob/main/LICENSE)
|
||||
|
||||
<p align="center">
|
||||
<a href="#">
|
||||
<img src="https://img.shields.io/badge/made%20with-love-E760A4.svg" alt="Made with love"></img>
|
||||
</a>
|
||||
<a href="https://github.com/palera1n/palera1n-c/blob/main/LICENSE" target="_blank">
|
||||
<img src="https://img.shields.io/github/license/palera1n/palera1n-c.svg" alt="License"></img>
|
||||
</a>
|
||||
<a href="https://github.com/palera1n/palera1n-c/graphs/contributors" target="_blank">
|
||||
<img src="https://img.shields.io/github/contributors/palera1n/palera1n-c.svg" alt="Contributors"></img>
|
||||
</a>
|
||||
<a href="https://github.com/palera1n/palera1n-c/commits/main" target="_blank">
|
||||
<img src="https://img.shields.io/github/commit-activity/w/palera1n/palera1n-c.svg" alt="Commits"></img>
|
||||
</a>
|
||||
<img src="https://img.shields.io/github/search/palera1n/palera1n-c/goto.svg" alt="goto counter"></img>
|
||||
<a href="https://dsc.gg/palera1n" target="_blank">
|
||||
<img src="https://img.shields.io/discord/1028398973452570725?label=discord" alt="Discord"></img>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
iOS 15.0-16.3 work in progress, semi-tethered checkm8 jailbreak
|
||||
</p>
|
||||
Jailbreak for A8 through A11, T2 devices, on iOS/iPadOS/tvOS 15.0, bridgeOS 5.0 and higher.
|
||||
|
||||
# BEFORE YOU USE
|
||||
|
||||
This is mainly for ROOTLESS, and is NOT READY. It was made public so you can contribute and explore the code. This is not the final product.
|
||||
|
||||
This version of palera1n supports booting fakefs setups with the `-f` option. No arguments required.
|
||||
|
||||
This version of palera1n is able to create fakefs with the `-c` option, however as of right now if the `/jbin/loader.app`
|
||||
doesn't exist (which is true for any fakefs created with this version of palera1n), the loader that appears would be rootless.
|
||||
|  |
|
||||
|:--: |
|
||||
| A screenshot of palera1n being used in a Terminal |
|
||||
|
||||
Loader app does appear on rootless, and you can use the SSH server listening at 127.0.0.1:44 (IPv4) or ::1:44 (IPv6).
|
||||
## Device Support
|
||||
|
||||
If the device is previously jailbroken, the jailbreak environment is automatically prepared.
|
||||
You can use the `-s` option to skip this behaviour.
|
||||
<!--- Mobile --->
|
||||
|
||||
Usbmuxd is only required for starting in normal mode, it is not required when started from recovery or DFU mode. (Usbmuxd is preinstalled with macOS)
|
||||
| iPhone(s) | iPad(s) | iPod(s) | Apple TV(s) |
|
||||
|- |- |- |- |
|
||||
| iPhone 6s | iPad mini 4 | iPod Touch (7th generation) | Apple TV HD |
|
||||
| iPhone 6s Plus | iPad (5th generation) | | Apple TV 4K (1st generation) |
|
||||
| iPhone SE (2016) | iPad (6th generation) | | |
|
||||
| iPhone 7 | iPad (7th generation) | | |
|
||||
| iPhone 7 Plus | iPad Pro (9.7") | | |
|
||||
| iPhone 8 | iPad Pro (12.9") (1st generation) | | |
|
||||
| iPhone 8 Plus | iPad Pro (10.5") | | |
|
||||
| iPhone X | iPad Pro (12.9") (2nd generation) | | |
|
||||
| | iPad Air 2 | | |
|
||||
|
||||
You can obtain the latest build of palera1n-c [here](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/).
|
||||
|
||||
# This is a work in progress.
|
||||
> Note that on `A11` (iPhone X, 8, 8 Plus), **you must disable your passcode while in the jailbroken state** (on iOS 16, you need to **reset your device** before proceeding with palera1n).
|
||||
|
||||
Read this throughly, feel free to ask questions, know the risks. If you want to ask questions, either:
|
||||
<!--- T2 --->
|
||||
<details>
|
||||
<summary>Apple T2 Device Support (click to expand)</summary>
|
||||
|
||||
1. Ask in the [palera1n Discord](https://discord.gg/4S3yUMxuQH)
|
||||
2. Ask in the r/jailbreak Discord #palera1n channel
|
||||
| Apple T2 |
|
||||
|- |
|
||||
| Apple T2 iMac20,1 |
|
||||
| Apple T2 iMac20,2 |
|
||||
| |
|
||||
| Apple T2 MacBookAir8,1 |
|
||||
| Apple T2 MacBookAir8,2 |
|
||||
| Apple T2 MacBookAir9,1 |
|
||||
| |
|
||||
| Apple T2 MacBookPro15,1 |
|
||||
| Apple T2 MacBookPro15,2 |
|
||||
| Apple T2 MacBookPro15,3 |
|
||||
| Apple T2 MacBookPro15,4 |
|
||||
| Apple T2 MacBookPro16,1 |
|
||||
| Apple T2 MacBookPro16,2 |
|
||||
| Apple T2 MacBookPro16,3 |
|
||||
| Apple T2 MacBookPro16,4 |
|
||||
| |
|
||||
| Apple T2 iMacPro1,1 |
|
||||
| Apple T2 Macmini8,1 |
|
||||
| Apple T2 MacPro7,1 |
|
||||
| |
|
||||
| iBridge2,11 (Unknown Mac) |
|
||||
| iBridge2,13 (Unknown Mac) |
|
||||
|
||||
Please, please, please, provide necessary info:
|
||||
|
||||
- iOS version and device (eg. iPhone 7+ 15.1, iPhone 6s 15.3.1)
|
||||
- Computer's OS and version (eg. Ubuntu 22.04, macOS 13.0)
|
||||
- The command you ran
|
||||
|
||||
**DO NOT** harass tweak devs if tweaks don't work. Refer to [here](https://github.com/itsnebulalol/ios15-tweaks) for compatiblity.
|
||||
</details>
|
||||
|
||||
# Patreons
|
||||
|
||||
Thank you so much to our Patreons that make the future development possible! You may sub [here](https://patreon.com/palera1n), if you'd like to. If you subscribe, please message [Nebula](https://twitter.com/itsnebulalol) in any way preferred to have you put here.
|
||||
## Computer Requirements
|
||||
1. **USB-A** cables are recommended to use, USB-C to may have issues with palera1n and getting into DFU mode.
|
||||
> Due to USB-C cables having different accessory IDs, your device may not be able to be recognized when using USB-C due to not being able to assert to its USB voltage pin.
|
||||
|
||||
<a href="https://github.com/samh06"><img width=64 src="https://user-images.githubusercontent.com/18669106/206333607-881d7ca1-f3bf-4e18-b620-25de0c527315.png"></img></a>
|
||||
<a href="https://havoc.app"><img width=64 src="https://docs.havoc.app/img/standard_icon.png"></img></a>
|
||||
<a href="https://twitter.com/yyyyyy_public"><img width=64 src="https://pbs.twimg.com/profile_images/1429332550112079876/dQQgsURc_400x400.jpg"></img></a>
|
||||
<a href="https://twitter.com/0xSp00kyb0t"><img width=64 src="https://pbs.twimg.com/profile_images/1603601553226620935/1t4yD1bD_400x400.jpg"></img></a>
|
||||
<a href="https://chariz.com"><img width=64 src="https://chariz.com/img/favicon.png"></img></a>
|
||||
<a href="https://twitter.com/stars6220"><img width=64 src="https://pbs.twimg.com/profile_images/1606990218925670400/Y4JBl6OS_400x400.jpg"></img></a>
|
||||
<a href="https://github.com/beast9265"><img width=64 src="https://avatars.githubusercontent.com/u/79794946?v=4"></img></a>
|
||||
2. **Linux or macOS computer**
|
||||
> AMD CPUs (not AMD Mobile) have an issue where it causes them to have a very low success rate with checkm8 exploit. It is not recommended that you use them with palera1n.
|
||||
|
||||
# What does this do?
|
||||
> USB-C port on Apple Silicon Macs *may* require manual unplugging and replugging of the lightning cable after checkm8 exploit. This problem may be solved by connecting via USB hub, though extensions can vary.
|
||||
|
||||
It boots the device with patches for the jailbreak.
|
||||
## Usage
|
||||
```
|
||||
Usage: palera1n [-DEhpvVdsSLRnPI] [-e boot arguments] [-k Pongo image] [-o overlay file] [-r ramdisk file] [-K KPF file] [-i checkra1n file]
|
||||
|
||||
**WARNING**: I am NOT responsible for any data loss. The user of this program accepts responsibility should something happen to their device. While nothing should happen, jailbreaking has risks in itself. If your device is stuck in recovery, please run `futurerestore --exit-recovery`, or use `irecovery -n`.
|
||||
--version Print version
|
||||
--force-revert Remove jailbreak
|
||||
-d, --demote Demote
|
||||
-D, --dfuhelper Exit after entering DFU
|
||||
-e, --boot-args <boot arguments> XNU boot arguments
|
||||
-E, --enter-recovery Enter recovery mode
|
||||
-h, --help Show this help
|
||||
-i, --override-checkra1n <file> Override checkra1n
|
||||
-k, --override-pongo <file> Override Pongo image
|
||||
-K, --override-kpf <file> Override kernel patchfinder
|
||||
-L, --jbinit-log-to-file Make jbinit log to /cores/jbinit.log (can be read from sandbox while jailbroken)
|
||||
-n, --exit-recovery Exit recovery mode
|
||||
-I, --device-info Print info about the connected device
|
||||
-o, --override-overlay <file> Override overlay
|
||||
-p, --pongo-shell Boots to PongoOS shell
|
||||
-P, --pongo-full Boots to a PongoOS shell with default images already uploaded
|
||||
-r, --override-ramdisk <file> Override ramdisk
|
||||
-R, --reboot-device Reboot connected device in normal mode
|
||||
-s, --safe-mode Enter safe mode
|
||||
-S, --no-colors Disable colors on the command line
|
||||
-v, --debug-logging Enable debug logging
|
||||
This option can be repeated for extra verbosity.
|
||||
-V, --verbose-boot Verbose boot
|
||||
|
||||
On A11, you **must disable your passcode while in the jailbroken state**. We don't have an A11 SEP exploit yet.
|
||||
Environmental variables:
|
||||
TMPDIR temporary diretory (path the built-in checkra1n will be extracted to)
|
||||
```
|
||||
|
||||
<!--# Usage
|
||||
See the [wiki](https://github.com/palera1n/palera1n-c/wiki).-->
|
||||
## Installing
|
||||
Visit https://palera.in
|
||||
|
||||
# Credits
|
||||
## Disclaimers
|
||||
We are **NOT** responsible for any data loss, or the result of a device being bricked. When using palera1n, the user should accept responsibility if anything happens to their device during the process.
|
||||
- If your device is stuck in recovery, please run futurerestore `--exit-recovery`, or use `irecovery -n`, or `palera1n -n`.
|
||||
- If you're unable to get out of recovery via these methods please restore with iTunes or Finder.
|
||||
- palera1n **will not work** in VirtualBox, VMware or any virtual machine that doesn't support PCI passthrough.
|
||||
|
||||
- [Nebula](https://github.com/itsnebulalol), palera1n owner and Python rewrite lead developer
|
||||
- [Nathan](https://github.com/verygenericname)
|
||||
- [Mineek](https://github.com/mineek)
|
||||
- [Nick Chan](https://github.com/asdfugil)
|
||||
- [Amy](https://github.com/elihwyma) for the [Pogo](https://github.com/elihwyma/Pogo) app
|
||||
- [checkra1n](https://github.com/checkra1n) for the base of the kpf
|
||||
- [the Procursus Team](https://github.com/ProcursusTeam) for the amazing [bootstrap](https://github.com/ProcursusTeam/Procursus)
|
||||
- [F121](https://github.com/F121Live) for helping test
|
||||
- [Tom](https://github.com/guacaplushy) for a couple patches and bugfixes
|
||||
- [Nick Chan](https://github.com/asdfugil) general help with patches and jbinit
|
||||
- [Serena](https://github.com/SerenaKit) for helping with boot ramdisk
|
||||
- [Évelyne](https://github.com/evelyneee) for ElleKit, rootless tweak injection
|
||||
## Troubleshooting
|
||||
Make sure you're following the guides provided [here](https://palera.in), also when asking for support make sure you provide full details on your device, such as:
|
||||
- iPhone/iPad/iPod/Apple TV
|
||||
- iOS Version
|
||||
- Passcode enabled?
|
||||
- Verbose from palera1n (specifying `-Vv` within palera1n)
|
||||
- Panic logs, if panicked then send latest `panic-full` log from your device.
|
||||
|
||||
Create an issue here: https://github.com/palera1n/palera1n/issues/new/choose
|
||||
|
||||
## Credits
|
||||
|
||||
[All credits for palera1n can be found here](https://palera.in/)
|
||||
|
||||
If proper credit isn't shown please message us or create an issue.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 287 KiB |
@@ -1,4 +0,0 @@
|
||||
add_custom_target(
|
||||
docs
|
||||
COMMAND sh -c "mandoc -T html -O style=mandoc.css palera1n.1 > palera1n.1.html"
|
||||
)
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
PAGES = palera1n.1.html
|
||||
PAGES = palera1n.1.html p1ctl.8.html
|
||||
|
||||
all: $(PAGES)
|
||||
|
||||
%.1.html: %.1
|
||||
mandoc -T html -O style=mandoc.css palera1n.1 > palera1n.1.html
|
||||
%.html: %
|
||||
mandoc -T html -O style=mandoc.css $< > $@
|
||||
|
||||
clean:
|
||||
rm -f $(PAGES)
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
.\"-
|
||||
.\" Copyright (c.Xc 2024 Nick Chan
|
||||
.\" SPDX-License-Identifier: MIT
|
||||
.\"
|
||||
.Dd "6 April 2024"
|
||||
.Dt p1ctl 8
|
||||
.Sh NAME
|
||||
.Nm p1ctl
|
||||
.Nd command-line access to palera1n loader
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Ar subcommand
|
||||
.Op subcommand options
|
||||
.Op subcommand arguments
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
provide a command-line interface to the graphical palera1n loader.
|
||||
.Pp
|
||||
.Nm
|
||||
interfaces with the palera1n daemon as well as palera1n's launchd hook.
|
||||
|
||||
.Sh SUBCOMMANDS
|
||||
.Bl -tag -width -indent
|
||||
.It Xo Ar bootstrap Op Fl s
|
||||
.Op Fl S Ar password
|
||||
.Ar bootstrap-file
|
||||
.Xc
|
||||
Deploy a bootstrap from a zstd compressed tarball. With no additional options specified,
|
||||
a new password for the mobile user will be prompted for. The bootstrap you are deploying
|
||||
must match the jailbreak type (rootful or rootless) you are using.
|
||||
.Bl -tag -width -indent
|
||||
.It Fl s
|
||||
Do not prompt for the password and do not set the mobile password.
|
||||
.It Fl S Ar password
|
||||
Do not prompt and set the mobile password to the password specified.
|
||||
.El
|
||||
.Pp
|
||||
.Em NOTE:
|
||||
Unlike the graphical palera1n loader, this command only deploys the bootstrap itself,
|
||||
it does not add additional repositories nor install additional packages.
|
||||
.It Xo Ar exitsafe
|
||||
.Xc
|
||||
Exit
|
||||
.Nm palera1n
|
||||
safe mode, and trigger a userspace reboot. This command will succeed
|
||||
even if the device is not currently in safe mode. In this case, a userspace reboot
|
||||
is still triggered.
|
||||
.Pp
|
||||
.Em NOTE:
|
||||
Many tweak injection packages also provide their own safe mode, p1ctl does not
|
||||
recognize and cannot control those safe modes.
|
||||
.It Xo Ar help Op Ar subcommand
|
||||
.Xc
|
||||
Prints help text. If
|
||||
.Ar subcommand
|
||||
is specified, print help about the subcommand.
|
||||
.It Xo Ar kbase
|
||||
.Xc
|
||||
Print a hexadecimal representation of the kernel base.
|
||||
.It Xo Ar kslide
|
||||
.Xc
|
||||
Print a hexadecimal representation of the kernel slide.
|
||||
.It Xo Ar palera1n_flags
|
||||
.Xc
|
||||
Print a representation of the palera1n flags, which corresponds to the options passed
|
||||
to
|
||||
.Xr palera1n 1
|
||||
as well as hints to the palera1n userspace stack set by
|
||||
.Nm PongoOS
|
||||
\[char46]
|
||||
By default, a hexadecimal representation of the flags will be printed.
|
||||
.Bl -tag -width -indent
|
||||
.It Fl d
|
||||
Read the flags from the ramdisk block device instead of getting them by interfacing with palera1n daemon.
|
||||
.It Fl s
|
||||
Print a string representation of the flags. Each line will contain one flag, and the strings always start
|
||||
with palerain_option_, and unknown flags are represented as palerain_option_undefined.
|
||||
.El
|
||||
.It Xo Ar reboot-userspace
|
||||
.Xc
|
||||
Unmount /Developer if mounted and then reboot the userspace.
|
||||
This command exists because the /Developer mount will be broken
|
||||
after a plain userspace reboot, which breaks debugging in Xcode.
|
||||
.Nm palera1n
|
||||
also hooks the
|
||||
.Xr reboot3 3
|
||||
call so that rebooting userspace using
|
||||
.Xr launchctl 1
|
||||
does not break the /Developer mount.
|
||||
.It Xo Ar reload
|
||||
.Xc
|
||||
Causes the
|
||||
.Nm palera1n
|
||||
launchd hook to re-probe the environment and update its internal state.
|
||||
This will affect the internal environmental variables passed onto new processes,
|
||||
and is typically used after bootstrapping or reverting installs.
|
||||
.It Xo Ar revert-install
|
||||
.Xc
|
||||
Remove jailbreak files from the device. This command is not supported on rootful with fakefs. On rootful with realfs, the device will reboot after issuing this command.
|
||||
.Pp
|
||||
To remove jailbreak files on rootful with fakefs, use
|
||||
.Xr palera1n 1
|
||||
on your computer with the
|
||||
.Fl -force-revert
|
||||
.Fl f
|
||||
options instead.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr palera1n 1
|
||||
+146
-67
@@ -1,33 +1,40 @@
|
||||
.\"-
|
||||
.\" Copyright (c) 2023 Nick Chan
|
||||
.\" Copyright (c) 2024 Nick Chan
|
||||
.\" SPDX-License-Identifier: MIT
|
||||
.\"
|
||||
.Dd "06 February 2023"
|
||||
.Dt "Nick Chan utilities manual" 1 "palera1n"
|
||||
.Dd "23 December 2024"
|
||||
.Dt palera1n 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm palera1n
|
||||
.Nd iOS 15+ arm64 iOS/iPadOS jailbreaking tool
|
||||
.Nd arm64 iOS/iPadOS/tvOS 15.0-26.0, bridgeOS 5.0-10.0 jailbreaking tool
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl cCdDEfhlnLOpRsvV
|
||||
.Op Fl cCdDEfhIlLnpRsSTvV
|
||||
.Op Fl e Ar Boot arguments
|
||||
.Op Fl k Ar Pongo image
|
||||
.Op Fl o Ar overlay file
|
||||
.Op Fl r Ar ramdisk file
|
||||
.Op Fl K Ar KPF file
|
||||
.Op Fl i Ar checkra1n file
|
||||
.Op Fl -version
|
||||
.Op Fl -force-revert
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
jailbreaks any iOS/iPadOS device with an arm64 (arm64e excluded) on iOS 15+,
|
||||
jailbreaks an arm64 (arm64e excluded) iOS/iPadOS/tvOS 15.0-26.0, bridgeOS 5.0-10.0 device,
|
||||
utilizing the
|
||||
.Em checkm8
|
||||
bootROM exploit.
|
||||
.Pp
|
||||
.Nm
|
||||
provides rootful and rootless jailbreak modes.
|
||||
On iOS/iPadOS 15.0 and later and on tvOS 18.2 or later,
|
||||
.Nm
|
||||
is able to jailbreak the device in fakefs-rootful mode, where /
|
||||
is writable, as well as rootless mode, where / cannot be written to.
|
||||
On tvOS and bridgeOS,
|
||||
only rootful is supported. On versions where fakefs-rootful is not
|
||||
applicable, palera1n modifies the actual root filesystem instead
|
||||
of making a fakefs
|
||||
.Pp
|
||||
Due to the nature of the
|
||||
.Em checkm8
|
||||
@@ -48,8 +55,11 @@ On iOS 16, the passcode must be off since restore, and
|
||||
from settings app counts as a restore.
|
||||
A backup may be used in this case.
|
||||
.Pp
|
||||
In the remainder of this document, the term "iOS" and "iPadOS" will be used interchangably
|
||||
as the difference is negligible as far as the jailbreak is concerened.
|
||||
.Pp
|
||||
.Sh SUPPORTED DEVICES
|
||||
As described above, arm64 iOS/iPadOS 15+ devices are supported, here is an explicit
|
||||
As described above, arm64 iOS 15.0-18.0 devices are supported, here is an explicit
|
||||
list of supported devicecs:
|
||||
|
||||
.Bl -tag -compact
|
||||
@@ -79,8 +89,32 @@ list of supported devicecs:
|
||||
.It iPod Touch (7th generation)
|
||||
.El
|
||||
|
||||
Support for other arm64 Darwin devices, including Apple TV, HomePod and iBridge
|
||||
on Darwin 21 and above could be added, but they are currently unsupported.
|
||||
.Bl -tag -compact
|
||||
.It Apple TV HD
|
||||
.It Apple TV 4K (1st generation)
|
||||
.El
|
||||
|
||||
.Bl -tag -compact
|
||||
.It Apple T2 iMacPro1,1
|
||||
.It Apple T2 MacBookPro15,1
|
||||
.It Apple T2 MacBookPro15,2
|
||||
.It Apple T2 Macmini8,1
|
||||
.It Apple T2 MacPro7,1
|
||||
.It Apple T2 MacBookPro15,3
|
||||
.It Apple T2 MacBookAir8,1
|
||||
.It Apple T2 MacBookPro15,4
|
||||
.It Apple T2 MacBookAir8,2
|
||||
.It Apple T2 MacBookPro16,1
|
||||
.It Apple T2 MacBookAir9,1
|
||||
.It Apple T2 MacBookPro16,2
|
||||
.It Apple T2 iMac20,1
|
||||
.It Apple T2 iMac20,2
|
||||
.It Apple T2 MacBookPro16,3
|
||||
.It Apple T2 MacBookPro16,4
|
||||
.El
|
||||
|
||||
Support for the A8 HomePod on Darwin 21 and above could be added,
|
||||
but it is currently unsupported.
|
||||
|
||||
arm64e devices will NEVER be supported.
|
||||
|
||||
@@ -90,7 +124,7 @@ arm64e devices will NEVER be supported.
|
||||
Prints the program version and exit.
|
||||
.It Fl -force-revert
|
||||
Remove the jailbreak while keeping user data. Some jailbreak files may remain
|
||||
after running this command. Additionally, jailbreak apps will 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
|
||||
still has their icons. When used with
|
||||
.Fl f , -fakefs ,
|
||||
@@ -99,33 +133,37 @@ 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 , -fakefs
|
||||
\[char46]
|
||||
.It Fl B , -setup-fakefs-partial
|
||||
Like
|
||||
.Fl c , -setup-fakefs
|
||||
but the size of the created fakefs is smaller at the expense of having unwritable
|
||||
parts in rarely-written paths. When jailbreaking 16 GB devices, this option must be used
|
||||
when setting up fakefs for rootful, as they do not have enough storage for full fakefs.
|
||||
This flag is supported on iOS/iPadOS 15.0 or later and tvOS 18.2 or later, as they
|
||||
require fakefs for rootful.
|
||||
.It Fl c , -setup-fakefs
|
||||
When used with
|
||||
.Fl f , -fakefs ,
|
||||
Create the new APFS volume required for rootful. Will fail if one already exists.
|
||||
.It Fl C , -setup-fakefs-forced
|
||||
When used with
|
||||
.Fl f , -fakefs ,
|
||||
behaves like
|
||||
.Fl c , -setup-fakefs ,
|
||||
but existing fakefs, if exists, will be overwritten instead.
|
||||
creates the new APFS volume required for rootful. Will fail if one already exists.
|
||||
This flag is supported on iOS/iPadOS 15.0 or later and tvOS 18.2 or later, as they
|
||||
require fakefs for rootful.
|
||||
.It Fl C , -clean-fakefs
|
||||
This option is not currently supported and is a no-operation in this version of
|
||||
.Nm
|
||||
\[char46]
|
||||
.It Fl d , -demote
|
||||
Set the effective production fuse to 0, so as to enable hardware debugging features.
|
||||
.It Fl D , -dfuhelper-only
|
||||
.It Fl D , -dfuhelper
|
||||
Execute the DFU helper to guide the user into putting the device into DFU mode
|
||||
then exit.
|
||||
.It Fl e , -boot-args Ar boot arguments
|
||||
Specify custom XNU kernel command line. The
|
||||
.Em rootdev=md0
|
||||
argument is used by
|
||||
.Nm
|
||||
and cannot be overriden. Additionally, the
|
||||
Specify custom XNU kernel command line. Additionally, the
|
||||
.Em wdt=-1
|
||||
argument is used during fakefs setup.
|
||||
.It Fl E , -enter-recovery
|
||||
Exit after entering recovery mode.q
|
||||
Exit after entering recovery mode.
|
||||
.It Fl f , -fakefs
|
||||
Jailbreak in rootful mode.
|
||||
Proceed in rootful mode. Despite its name, this applies to both full, partial fakefs, as well as realfs, and it still applies even when trying to force revert.
|
||||
.It Fl h , -help
|
||||
Prints help text.
|
||||
.It Fl i , -checkra1n-file Ar checkra1n file
|
||||
@@ -139,18 +177,10 @@ Override the kernel patchfinder PongoOS module. The module is required to suppor
|
||||
root filesystem in paleinfo with
|
||||
.Em rootfs
|
||||
command. If in doubt, use
|
||||
.Sy https://github.com/guacaplushy/PongoOS
|
||||
.Sy https://github.com/palera1n/PongoOS
|
||||
iOS15 branch or your own fork of it.
|
||||
.It Fl l , -rootless
|
||||
Jailbreak in rootless mode, this is the default when neither
|
||||
.Fl l , -rootless
|
||||
and
|
||||
.Fl f , -fakefs
|
||||
is specified.
|
||||
.Fl L , -jbinit-log-to-file
|
||||
Makes jbinit log to
|
||||
.Em /cores/jbinit.log
|
||||
This file may be viewed from sandboxed applications while jailbroken.
|
||||
Proceed in rootless mode. This option is only supported on iOS/iPadOS.
|
||||
.It Fl n , -exit-recovery
|
||||
Exit recovery mode and exit.
|
||||
.It Fl o , -override-overlay Ar overlay file
|
||||
@@ -162,8 +192,6 @@ at the root of it, as well as a dmg named
|
||||
.Em loader.dmg
|
||||
at the root of it. Otherwise, the device will not boot. It is also expected that it
|
||||
contains a shell, a ssh server, and various command line utilities.
|
||||
.It Fl O , -disable-ohio
|
||||
Disable ohio (disable analytics)
|
||||
.It Fl p , -pongo-shell
|
||||
Exit after booting into a clean PongoOS shell
|
||||
.It Fl P , -pongo-full
|
||||
@@ -171,27 +199,33 @@ Like
|
||||
.Fl p , -pongo-shell
|
||||
but default images and options have been uploaded and applied respectively.
|
||||
.It Fl r , -override-ramdisk Ar ramdisk file
|
||||
Override the ramdisk. At a very minimum, it should contain a
|
||||
.Em /sbin/launchd
|
||||
Override the ramdisk. At a very minimum, it should contain
|
||||
.Em /cores/ploosh
|
||||
as well as a fake dyld
|
||||
.Em /usr/lib/dyld
|
||||
where the logic is expected to be in.
|
||||
.It Fl R , -reboot-device
|
||||
Reboot device in normal mode and exit.
|
||||
.It Fl s , -safe-mode
|
||||
Enter safe mode. An alert will be displayed. Jailbreak daemons nor early boot executable files
|
||||
Enter safe mode. An alert will be displayed on iOS/iPadOS/tvOS. Jailbreak daemons nor early boot executable files
|
||||
specified (see
|
||||
.Sy FILES
|
||||
section below) will be executed. The loader app and the built in SSH server can still be used,
|
||||
as well as any jailbreak-specific apps you have installed.
|
||||
.It Fl S , -no-colors
|
||||
Disable colors on the command line. External programs like checkra1n clones may still output colors.
|
||||
.It Fl T , -telnetd
|
||||
Enable the TELNET daemon on port 46, all interfaces. Please note that there is no authentication and is therefore insecure.
|
||||
.It Fl v , -debug-logging
|
||||
Enable debug logging. The option may be repeated for extra verbosity.
|
||||
.It Fl V , -verbose-boot
|
||||
Boots the device in verbose mode, allowing boot logs to be seen.
|
||||
.It Fl I , -device-info
|
||||
Prints info about device and exits.
|
||||
.El
|
||||
.Sh ENVIRONMENTAL VARIABLES
|
||||
.Bl -tag -width -indent
|
||||
.It TMPDIR
|
||||
.It Ev TMPDIR
|
||||
This environmental variable should contain the a directory for temporary
|
||||
files. Without the
|
||||
.Fl i , -override-checkra1n
|
||||
@@ -201,13 +235,13 @@ is extracted and executed here. When not set, /tmp is used.
|
||||
.Sh EXAMPLES
|
||||
To (re-)jailbreak in rootless mode:
|
||||
.Pp
|
||||
.Dl "palera1n"
|
||||
.Dl "palera1n -l"
|
||||
.Pp
|
||||
To setup fakefs for rootful mode:
|
||||
.Pp
|
||||
.Dl "palera1n -fc"
|
||||
.Ppq
|
||||
After the device has rebooted, follow the following example.
|
||||
.Pp
|
||||
After the device has rebooted into recovery mode, follow the following example.
|
||||
.Pp
|
||||
To re-jailbreak in rootful mode:
|
||||
.Pp
|
||||
@@ -225,6 +259,10 @@ To verbose boot in rootful mode:
|
||||
.Pp
|
||||
.Dl "palera1n -Vf"
|
||||
.Pp
|
||||
To create a partial fakefs with bind mounts:
|
||||
.Pp
|
||||
.Dl "palera1n -Bf"
|
||||
.Pp
|
||||
To exit recovery mode:
|
||||
.Pp
|
||||
.Dl "palera1n -n"
|
||||
@@ -232,7 +270,7 @@ To exit recovery mode:
|
||||
.Sh CAVEATS
|
||||
.Pp
|
||||
.Em -v
|
||||
is not a real XNU boot argument. It is intercepted by iBoot. However, since XNU
|
||||
is not a real XNU boot argument. It is interpreted by iBoot. However, since XNU
|
||||
boot arguments are set in PongoOS, which is ran after iBoot has ran, it does nothing.
|
||||
To verbose boot, use the
|
||||
.Fl V , -verbose-boot
|
||||
@@ -247,17 +285,39 @@ version of the Procursus fork of
|
||||
before they can be ran on a device jailbroken with
|
||||
.Nm
|
||||
\[char46]
|
||||
.Sh POST INSTLLATION
|
||||
The palera1n loader app will take up to 30 seconds to appear on the homescreen after the
|
||||
.Pp
|
||||
When using rootful mode, the
|
||||
.Fl f , -fakefs
|
||||
flag must be specified at all times. It does not matter whether you want to create fakefs,
|
||||
create partial fakefs, rejailbreak or remove jailbreak.
|
||||
.Pp
|
||||
Due to a stock bug, using the
|
||||
.Fl V , -verbose-boot
|
||||
option might cause some versions for tvOS to crash and not boot.
|
||||
.Pp
|
||||
Offical Apple USB-C cables as well as some other USB-C cables cannot be used to enter DFU mode.
|
||||
USB-A cable with male USB-C to female USB-A adapter works fine.
|
||||
.Sh POST INSTALLATION (iOS/iPadOS)
|
||||
The palera1n loader app will take up to 1 minute to appear on the homescreen after the
|
||||
device has booted. If it does not appear, you can try using the shortcut:
|
||||
.Pp
|
||||
.Sy https://www.icloud.com/shortcuts/8cd5f489c8854ee0ab9ee38f2e62f87d
|
||||
.Lk https://www.icloud.com/shortcuts/8cd5f489c8854ee0ab9ee38f2e62f87d
|
||||
.Pp
|
||||
to open it. After opening the loader app, press install to install a bootstrap as well as
|
||||
the
|
||||
.Em Sileo
|
||||
package manager.
|
||||
You can install other package managers from settings of the loader app.
|
||||
to open it. After opening the loader app, select a package manager to install.
|
||||
This will also bootstrap your device.
|
||||
.Pp
|
||||
A built-in SSH server runs on port 44 on loopback interfaces.
|
||||
.Sh POST INSTALLATION (tvOS)
|
||||
.Pp
|
||||
The palera1n loader app will appear on homescreen. Open the loader and select a package manager to install.
|
||||
This will also bootstrap your device.
|
||||
.Pp
|
||||
A built-in SSH server runs on port 44 on all interfaces.
|
||||
.Sh POST INSTALLATION (bridgeOS)
|
||||
.Pp
|
||||
A built-in SSH server runs on port 44 on all interfaces.
|
||||
.Pp
|
||||
Bootstrapping is currently not supported on this device.
|
||||
.Sh FILES
|
||||
During the jailbreak process, a temporary filesystem is mounted on /cores as a place
|
||||
to stash jailbreak files needed during the boot process. No files are ever written
|
||||
@@ -266,11 +326,7 @@ loader app to install additional jailbreak files.
|
||||
|
||||
.Bl -tag -width "/var/jb/Library/LaunchDaemons"
|
||||
.It Pa /cores
|
||||
The location of the temporary filesystem where jailbreak files are stash during boot.
|
||||
.It Pa /cores/jbinit.log
|
||||
When
|
||||
.Fl L
|
||||
is used, the log file of jbinit.
|
||||
The location of the temporary filesystem where jailbreak files are stashed during boot.
|
||||
.It Pa /Library/LaunchDaemons
|
||||
The directory where jailbreak-specific
|
||||
.Xr launchd.plist 5
|
||||
@@ -290,20 +346,42 @@ has been mounted.
|
||||
.El
|
||||
.Sh BUGS
|
||||
.Nm
|
||||
may crash if the machine it is running on:
|
||||
may crash if the machine it is running on has non-compliant USB devices plugged in.
|
||||
.Pp
|
||||
.Dl "- Has no USB ports"
|
||||
.Pp
|
||||
.Dl "- Has non-compliant USB devices plugged in"
|
||||
.Sh NOTES
|
||||
.Nm
|
||||
injects a dylib into launchd to allow the
|
||||
will fail to initialize on Linux when there are no USB devices plugged in.
|
||||
Usually this is not a problem on PCs since the built-in root hubs are also
|
||||
USB devices. However, on platforms such as Apple Silicon Macs in Linux, since
|
||||
there are no built-in USB hubs, at least one USB device needs to be manually
|
||||
plugged in for palera1n to be initialized.
|
||||
.Pp
|
||||
The exploit may also work less reliably on some hosts, like AMD desktops, or some MediaTek devices.
|
||||
.Pp
|
||||
The built-in SSH server might be not accessible with password after bootstrapping rootful,
|
||||
since the bootstrap uses a custom crypt() function that is not supported
|
||||
by the built-in SSH server.
|
||||
.Pp
|
||||
There are no DFU instructions for iBridge T2 as there are no known ways to connect to the T2's USB
|
||||
interface when macOS has been booted.
|
||||
.Sh DEPRECATED AND REMOVED FUNCTIONALITY
|
||||
There was an option in
|
||||
.Nm
|
||||
to force create the fakefs even when one already exists (which would overwrite
|
||||
the existing fakefs), by setting the palerain_option_setup_rootful_forced flag
|
||||
in palera1n flags. This option was removed because using
|
||||
.Fl -force-revert
|
||||
and
|
||||
.Fl c
|
||||
at the same time has exactly the same effect.
|
||||
.Pp
|
||||
The hook that enabled
|
||||
.Sy launchctl runstats
|
||||
command to be used on the device.
|
||||
has been removed, since it leaks memory in launchd.
|
||||
.Sh SEE ALSO
|
||||
.Xr launchd 8
|
||||
.Xr launchd.plist 5
|
||||
.Xr ldid 1
|
||||
.Xr p1ctl 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
@@ -314,4 +392,5 @@ December 13, 2022. Later, the first attempt to rewrite palera1n into C begins on
|
||||
01 2023. The
|
||||
.Nm
|
||||
utility described here is the second attempt, which first started on January 16, 2023,
|
||||
using checkra1n 1337 and the plush KPF.
|
||||
using checkra1n 1337 and a custom KPF.
|
||||
Something happened on August 15, 2023.
|
||||
@@ -1,20 +0,0 @@
|
||||
curl -LOOOOOO \
|
||||
https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v3.3.0.tar.gz \
|
||||
https://github.com/libusb/libusb/releases/download/1.0.26/libusb-1.0.26.tar.bz2 \
|
||||
https://mirror-hk.koddos.net/gnu/readline/readline-8.2.tar.gz \
|
||||
https://www.jedsoft.org/releases/slang/slang-2.3.3.tar.bz2 \
|
||||
https://releases.pagure.org/newt/newt-0.52.23.tar.gz \
|
||||
https://github.com/rpm-software-management/popt/archive/master-release.tar.gz
|
||||
|
||||
tar xf master.tar.gz
|
||||
tar xf libusb-1.0.26.tar.bz2
|
||||
tar xf readline-8.2.tar.gz
|
||||
tar xf slang-2.3.3.tar.bz2
|
||||
tar xf newt-0.52.23.tar.gz
|
||||
tar xf master-release.tar.gz
|
||||
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libplist
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libimobiledevice-glue
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libirecovery
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libusbmuxd
|
||||
git clone --depth=1 https://github.com/libimobiledevice/libimobiledevice
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* pongoOS - https://checkra.in
|
||||
*
|
||||
* Copyright (C) 2019-2022 checkra1n team
|
||||
*
|
||||
* This file is part of pongoOS.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef _KERNINFO_H
|
||||
#define _KERNINFO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_BOOTARGS_LEN 256
|
||||
|
||||
#define checkrain_option_none 0x00000000
|
||||
#define checkrain_option_all 0x7fffffff
|
||||
#define checkrain_option_failure 0x80000000
|
||||
|
||||
// Host options
|
||||
#define checkrain_option_verbose_logging (1 << 0)
|
||||
#define checkrain_option_demote (1 << 1)
|
||||
#define checkrain_option_early_exit (1 << 2)
|
||||
#define checkrain_option_quick_mode (1 << 3)
|
||||
#define checkrain_option_pongo_shell (1 << 4)
|
||||
#define checkrain_option_pongo_full (1 << 5)
|
||||
|
||||
// KPF options
|
||||
#define checkrain_option_verbose_boot (1 << 0)
|
||||
|
||||
// Global options
|
||||
#define checkrain_option_safemode (1 << 0)
|
||||
#define checkrain_option_bind_mount (1 << 1)
|
||||
#define checkrain_option_overlay (1 << 2)
|
||||
#define checkrain_option_force_revert (1 << 7) /* keep this at 7 */
|
||||
|
||||
// palera1n option
|
||||
#define palerain_option_rootful (1 << 0) /* rootful jailbreak */
|
||||
#define palerain_option_jbinit_log_to_file (1 << 1) /* log to /cores/jbinit.log */
|
||||
#define palerain_option_setup_rootful (1 << 2) /* create fakefs */
|
||||
#define palerain_option_setup_rootful_forced (1 << 3) /* create fakefs over an existing one */
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
#define palerain_option_test1 (1 << 29)
|
||||
#define palerain_option_test2 (1 << 30)
|
||||
#endif
|
||||
|
||||
// palerain host options
|
||||
#define host_option_dfuhelper_only (1 << 0) /* dfuhelper only */
|
||||
#define host_option_pongo_exit (1 << 1) /* boot to clean pongo shell */
|
||||
#ifdef DEV_BUILD
|
||||
#define host_option_tui (1 << 2) /* use terminal user interface */
|
||||
#else
|
||||
#define host_option_res1 (1 << 2) /* reserved */
|
||||
#endif
|
||||
#define host_option_demote (1 << 3) /* Demote effective production fuse status */
|
||||
#define host_option_no_ohio (1 << 4) /* Disable Ohio (Analytics) */
|
||||
#define host_option_pongo_full (1 << 5) /* Boot to pongo with default images and options */
|
||||
#define host_option_palerain_version (1 << 6) /* Print version */
|
||||
#define host_option_exit_recovery (1 << 7) /* Exit recovery mode */
|
||||
#define host_option_reboot_device (1 << 8) /* Reboot device in normal mode */
|
||||
#define host_option_enter_recovery (1 << 9) /* Enter recovery mode */
|
||||
|
||||
#define PALEINFO_MAGIC 'PLSH'
|
||||
#define PALEINFO_CIGAM 'HSLP'
|
||||
|
||||
typedef uint32_t checkrain_option_t, *checkrain_option_p;
|
||||
|
||||
typedef enum {
|
||||
jailbreak_capability_tfp0 = 1 << 0,
|
||||
jailbreak_capability_userspace_reboot = 1 << 1,
|
||||
jailbreak_capability_dyld_ignore_os = 1 << 2, // TODO: This needs a better name
|
||||
} jailbreak_capability_t, *jailbreak_capability_p;
|
||||
|
||||
#define DEFAULT_CAPABILITIES (jailbreak_capability_tfp0|jailbreak_capability_userspace_reboot)
|
||||
struct kerninfo {
|
||||
uint64_t size;
|
||||
uint64_t base;
|
||||
uint64_t slide;
|
||||
checkrain_option_t flags;
|
||||
};
|
||||
struct paleinfo {
|
||||
uint32_t magic; // 'PLSH' / 0x504c5348
|
||||
uint32_t version; // 1
|
||||
checkrain_option_t flags;
|
||||
char rootdev[0x10];
|
||||
};
|
||||
struct kpfinfo {
|
||||
struct kerninfo k;
|
||||
checkrain_option_t kpf_flags;
|
||||
char bootargs[MAX_BOOTARGS_LEN];
|
||||
};
|
||||
|
||||
#define checkrain_set_option(options, option, enabled) do { \
|
||||
if (enabled) \
|
||||
options = (checkrain_option_t)(options | option); \
|
||||
else \
|
||||
options = (checkrain_option_t)(options & ~option); \
|
||||
} while (0);
|
||||
|
||||
static inline bool checkrain_option_enabled(checkrain_option_t flags, checkrain_option_t opt)
|
||||
{
|
||||
if(flags == checkrain_option_failure)
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
case checkrain_option_safemode:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (flags & opt) != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* jbinit - https://github.com/palera1n/jbinit
|
||||
*
|
||||
* This file is part of jbinit
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PALEINFO_H
|
||||
#define PALEINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PALEINFO_VERSION 2U
|
||||
typedef uint64_t palerain_option_t;
|
||||
|
||||
// unified palera1n options
|
||||
#define palerain_option_rootful (UINT64_C(1) << 0) /* rootful jailbreak */
|
||||
#define palerain_option_rootless (UINT64_C(1) << 1) /* rootless jailbreak */
|
||||
#define palerain_option_setup_rootful (UINT64_C(1) << 2) /* create fakefs */
|
||||
// (UINT64_C(1) << 3) /* Deprecated and removed */
|
||||
#define palerain_option_setup_partial_root (UINT64_C(1) << 4) /* fakefs creating should be partial */
|
||||
#define palerain_option_checkrain_is_clone (UINT64_C(1) << 5) /* supplied checkra1n is checkra1n clone */
|
||||
#define palerain_option_rootless_livefs (UINT64_C(1) << 6) /* mount root livefs on rootless */
|
||||
#define palerain_option_ssv (UINT64_C(1) << 7) /* has signed system volume */
|
||||
// (UINT64_C(1) << 8) /* reserved */
|
||||
#define palerain_option_clean_fakefs (UINT64_C(1) << 9) /* clean fakefs, but does not delete it */
|
||||
#define palerain_option_tui (UINT64_C(1) << 10) /* terminal user interface */
|
||||
// #define palerain_option_gui (UINT64_C(1) << 11) /* graphical user interface*/
|
||||
#define palerain_option_dfuhelper_only (UINT64_C(1) << 12) /* dfuhelper only */
|
||||
#define palerain_option_pongo_exit (UINT64_C(1) << 13) /* boot to clean pongo shell */
|
||||
#define palerain_option_demote (UINT64_C(1) << 14) /* Demote effective production fuse status */
|
||||
#define palerain_option_pongo_full (UINT64_C(1) << 15) /* Boot to pongo with default images and options */
|
||||
#define palerain_option_palerain_version (UINT64_C(1) << 16) /* Print version */
|
||||
#define palerain_option_exit_recovery (UINT64_C(1) << 17) /* Exit recovery mode */
|
||||
#define palerain_option_reboot_device (UINT64_C(1) << 18) /* Reboot device in normal mode */
|
||||
#define palerain_option_enter_recovery (UINT64_C(1) << 19) /* Enter recovery mode */
|
||||
#define palerain_option_device_info (UINT64_C(1) << 20) /* Print device info */
|
||||
#define palerain_option_no_colors (UINT64_C(1) << 21) /* no colors */
|
||||
#define palerain_option_bind_mount (UINT64_C(1) << 22) /* bind mounts should be used (always true iOS 15+)*/
|
||||
#define palerain_option_overlay (UINT64_C(1) << 23) /* there is an overlay (should always be true) */
|
||||
#define palerain_option_force_revert (UINT64_C(1) << 24) /* Unjailbreak */
|
||||
#define palerain_option_safemode (UINT64_C(1) << 25) /* Enter safe mode */
|
||||
#define palerain_option_verbose_boot (UINT64_C(1) << 26) /* verbose boot */
|
||||
// #define palerain_option_sf_ssh (UINT64_C(1) << 27) /* safe mode with bootstrap ssh */
|
||||
// #define palerain_option_sf_launchdaemons (UINT64_C(1) << 28) /* safe mode with launchdaemons */
|
||||
// #define palerain_option_emerg_mode (UINT64_C(1) << 29) /* emergency mode (early boot usb shell) */
|
||||
#define palerain_option_jbinit_log_to_file (UINT64_C(1) << 30) /* deprecated (kept for compatibility) */
|
||||
#define palerain_option_cli (UINT64_C(1) << 31) /* CLI mode */
|
||||
#define palerain_option_telnetd (UINT64_C(1) << 32) /* Enable TELNET daemon */
|
||||
|
||||
#define palerain_option_flower_chain (UINT64_C(1) << 61) /* Flower chain */
|
||||
#define palerain_option_test1 (UINT64_C(1) << 62) /* Developer test option 1 */
|
||||
#define palerain_option_test2 (UINT64_C(1) << 63) /* Developer test option 2 */
|
||||
|
||||
#define PALEINFO_MAGIC 'PLSH'
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic warning "-Wpadded"
|
||||
|
||||
/* paleinfo version 2, appended to ramdisk */
|
||||
struct paleinfo {
|
||||
uint32_t magic; /* 'PLSH' */
|
||||
uint32_t version; /* 2 */
|
||||
uint64_t kbase; /* kernel base */
|
||||
uint64_t kslide; /* kernel slide */
|
||||
uint64_t flags; /* unified palera1n flags */
|
||||
char rootdev[0x10]; /* ex. disk0s1s8 */
|
||||
};
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#endif
|
||||
+34
-37
@@ -2,11 +2,11 @@
|
||||
#define PALERAIN_H
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#define _DARWIN_C_SOURCE 1
|
||||
#define NSIG __DARWIN_NSIG
|
||||
#endif
|
||||
|
||||
#include "xxd-embedded.h"
|
||||
#include "kerninfo.h"
|
||||
#include "paleinfo.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
@@ -24,6 +24,9 @@
|
||||
|
||||
#define palerain_option_case_version palerain_option_case(0)
|
||||
#define palerain_option_case_force_revert palerain_option_case(1)
|
||||
#define palerain_option_case_libcheckra1nhelper_path palerain_option_case(2)
|
||||
#define palerain_option_case_cli palerain_option_case(3)
|
||||
|
||||
|
||||
#ifdef USE_LIBUSB
|
||||
#include <libusb-1.0/libusb.h>
|
||||
@@ -31,7 +34,8 @@
|
||||
#define USB_RET_SUCCESS LIBUSB_SUCCESS
|
||||
#define USB_RET_NOT_RESPONDING LIBUSB_ERROR_OTHER
|
||||
#define USB_RET_IO LIBUSB_ERROR_IO
|
||||
typedef int usb_ret_t;
|
||||
#define USB_RET_NO_DEVICE LIBUSB_ERROR_NO_DEVICE
|
||||
typedef int32_t usb_ret_t;
|
||||
typedef libusb_device_handle *usb_device_handle_t;
|
||||
|
||||
typedef struct stuff
|
||||
@@ -51,7 +55,8 @@ usb_ret_t USBBulkUpload(usb_device_handle_t handle, void *data, int len);
|
||||
|
||||
#define USB_RET_SUCCESS KERN_SUCCESS
|
||||
#define USB_RET_NOT_RESPONDING kIOReturnNotResponding
|
||||
#define USB_RET_IO kIOReturnNotResponding
|
||||
#define USB_RET_IO kIOReturnNotReady
|
||||
#define USB_RET_NO_DEVICE kIOReturnNoDevice
|
||||
|
||||
typedef IOReturn usb_ret_t;
|
||||
typedef IOUSBInterfaceInterface245 **usb_device_handle_t;
|
||||
@@ -67,7 +72,7 @@ usb_ret_t USBBulkUpload(usb_device_handle_t handle, void *data, uint32_t len);
|
||||
#endif
|
||||
|
||||
#ifndef PALERAIN_VERSION
|
||||
#define PALERAIN_VERSION "2.0.0"
|
||||
#define PALERAIN_VERSION "2.2.1"
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
@@ -78,8 +83,8 @@ usb_ret_t USBBulkUpload(usb_device_handle_t handle, void *data, uint32_t len);
|
||||
#define MH_CIGAM_64 0xcffaedfe
|
||||
#define MH_KEXT_BUNDLE 0xb
|
||||
|
||||
typedef int cpu_type_t;
|
||||
typedef int cpu_subtype_t;
|
||||
typedef int32_t cpu_type_t;
|
||||
typedef int32_t cpu_subtype_t;
|
||||
|
||||
#define CPU_ARCH_ABI64 0x01000000
|
||||
#define CPU_TYPE_ARM ((cpu_type_t) 12)
|
||||
@@ -98,6 +103,8 @@ struct mach_header_64
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef void *(*pthread_start_t)(void *);
|
||||
|
||||
// Keep in sync with Pongo
|
||||
#define PONGO_USB_VENDOR 0x05ac
|
||||
#define PONGO_USB_PRODUCT 0x4141
|
||||
@@ -127,7 +134,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
int mode;
|
||||
unsigned int cpid;
|
||||
int cpid;
|
||||
char product_type[0x20];
|
||||
char display_name[0x20];
|
||||
char iboot_ver[0x20];
|
||||
@@ -136,9 +143,9 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t magic; /* 0xd803b376*/
|
||||
unsigned char* ptr; /* pointer to the override file in memory */
|
||||
unsigned int len; /* length of override file */
|
||||
uint32_t len; /* length of override file */
|
||||
unsigned char* orig_ptr; /* pointer to the overriden file */
|
||||
unsigned int orig_len; /* length of the overriden file */
|
||||
uint32_t orig_len; /* length of the overriden file */
|
||||
int fd; /* file descriptor of the override file */
|
||||
} override_file_t;
|
||||
|
||||
@@ -147,12 +154,12 @@ typedef unsigned char niarelap_file_t[];
|
||||
extern unsigned int verbose;
|
||||
|
||||
extern char* pongo_path;
|
||||
#ifdef DEV_BUILD
|
||||
#ifdef TUI
|
||||
extern bool tui_started;
|
||||
#endif
|
||||
|
||||
extern checkrain_option_t host_flags;
|
||||
extern checkrain_option_p host_flags_p;
|
||||
extern uint64_t palerain_flags;
|
||||
extern uint64_t* palerain_flags_p;
|
||||
|
||||
extern pthread_t dfuhelper_thread, pongo_thread;
|
||||
extern int pongo_thr_running, dfuhelper_thr_running;
|
||||
@@ -161,7 +168,7 @@ extern niarelap_file_t *kpf_to_upload_1, *ramdisk_to_upload_1, *overlay_to_uploa
|
||||
extern niarelap_file_t **kpf_to_upload, **ramdisk_to_upload, **overlay_to_upload;
|
||||
extern override_file_t override_ramdisk, override_kpf, override_overlay;
|
||||
|
||||
extern uint32_t checkrain_flags, palerain_flags, kpf_flags;
|
||||
extern uint64_t palerain_flags;
|
||||
extern pthread_mutex_t log_mutex;
|
||||
|
||||
extern pthread_mutex_t spin_mutex, found_pongo_mutex, ecid_dfu_wait_mutex;
|
||||
@@ -169,22 +176,18 @@ extern pthread_mutex_t spin_mutex, found_pongo_mutex, ecid_dfu_wait_mutex;
|
||||
extern int pongo_thr_running, dfuhelper_thr_running;
|
||||
extern bool device_has_booted;
|
||||
extern char xargs_cmd[0x270];
|
||||
extern char checkrain_flags_cmd[0x20];
|
||||
extern char palerain_flags_cmd[0x20];
|
||||
extern char kpf_flags_cmd[0x20];
|
||||
extern char dtpatch_cmd[0x20];
|
||||
extern char rootfs_cmd[512];
|
||||
extern char palerain_flags_cmd[0x30];
|
||||
extern char* ext_checkra1n;
|
||||
|
||||
void thr_cleanup(void* ptr);
|
||||
void* dfuhelper(void* ptr);
|
||||
int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxname, char* __restrict format, ...);
|
||||
int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxname, const char* __restrict format, ...);
|
||||
/* devhelper helpers */
|
||||
void devinfo_free(devinfo_t *dev);
|
||||
bool cpid_is_arm64(unsigned int cpid);
|
||||
/* devhelper commands */
|
||||
int subscribe_cmd(usbmuxd_event_cb_t device_event_cb, irecv_device_event_cb_t irecv_event_cb);
|
||||
int unsubscribe_cmd();
|
||||
int unsubscribe_cmd(void);
|
||||
int devinfo_cmd(devinfo_t *dev, const char *udid);
|
||||
int enter_recovery_cmd(const char* udid);
|
||||
int reboot_cmd(const char* udid);
|
||||
@@ -193,37 +196,31 @@ int recvinfo_cmd(recvinfo_t* info, const uint64_t ecid);
|
||||
int autoboot_cmd(const uint64_t ecid);
|
||||
int exitrecv_cmd(const uint64_t ecid);
|
||||
|
||||
int exec_checkra1n();
|
||||
int exec_checkra1n(void);
|
||||
int override_file(override_file_t *finfo, niarelap_file_t** orig, unsigned int *orig_len, char *filename);
|
||||
void* pongo_helper(void* ptr);
|
||||
const unsigned char *
|
||||
boyermoore_horspool_memmem(const unsigned char* haystack, size_t hlen,
|
||||
const unsigned char* needle, size_t nlen);
|
||||
|
||||
|
||||
extern void* pongo_usb_callback(void* arg);
|
||||
usb_ret_t USBControlTransfer(usb_device_handle_t handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t wLength, void *data, uint32_t *wLenDone);
|
||||
const char *usb_strerror(usb_ret_t err);
|
||||
int wait_for_pongo();
|
||||
int issue_pongo_command();
|
||||
int upload_pongo_file();
|
||||
int tui();
|
||||
int wait_for_pongo(void);
|
||||
int tui(void);
|
||||
int optparse(int argc, char* argv[]);
|
||||
|
||||
bool get_spin();
|
||||
bool get_spin(void);
|
||||
bool set_spin(bool val);
|
||||
bool get_found_pongo();
|
||||
bool get_found_pongo(void);
|
||||
void* pongo_helper(void* _);
|
||||
bool set_found_pongo(bool val);
|
||||
uint64_t get_ecid_wait_for_dfu();
|
||||
uint64_t get_ecid_wait_for_dfu(void);
|
||||
uint64_t set_ecid_wait_for_dfu(uint64_t ecid);
|
||||
|
||||
void write_stdout(char *buf, uint32_t len);
|
||||
void io_start(stuff_t *stuff);
|
||||
void io_stop(stuff_t *stuff);
|
||||
|
||||
void print_credits();
|
||||
void print_credits(void);
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
#include <newt.h>
|
||||
newtComponent get_tui_log();
|
||||
newtComponent set_tui_log(newtComponent co);
|
||||
#endif
|
||||
#endif
|
||||
+150
-14
@@ -10,16 +10,61 @@
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <newt.h>
|
||||
#include <paleinfo.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#define WIDTH 76
|
||||
#define HEIGHT 19
|
||||
|
||||
#define PI_LOG_COLOR NEWT_COLORSET_CUSTOM(0)
|
||||
#define PI_STEP_CURRENT NEWT_COLORSET_CUSTOM(1)
|
||||
#define PI_STEP_OTHER NEWT_COLORSET_CUSTOM(2)
|
||||
#define CHECKBOX_STATE(flags, opt) (flags & opt) != 0 ? '*' : ' '
|
||||
|
||||
#define CHECKBOX_STATE(flags, opt) checkrain_option_enabled(flags, opt) ? '*' : ' '
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
#define CLEAR_SCREEN printf("\033[2J")
|
||||
#define RESETFONT printf("\x1b[0m")
|
||||
#define PRINTAT(x, y, str) printf("\x1b[%d;%dH%s", y, x, str)
|
||||
#define PRINTATT(x, y, str) PRINTAT(tui_x_offset + x, tui_y_offset + y, str)
|
||||
#define PRINTATLEN(x, y, str, len) printf("\x1b[%d;%dH%." STR(len) "s", y, x, str)
|
||||
#define PRINTATLENT(x, y, str, len) PRINTATLEN(tui_x_offset + x, tui_y_offset + y, str, len)
|
||||
#define MOVETO(x, y) printf("\x1b[%d;%dH", y, x)
|
||||
#define MOVETOT(x, y) MOVETO(tui_x_offset + x, tui_y_offset + y)
|
||||
#define SETCOLOR(fg, bg) printf("\x1b[%d;%dm", fg, bg)
|
||||
#define SETCOLORA(fg, bg, a) printf("\x1b[" STR(fg) ";" STR(bg) ";" STR(a) "m")
|
||||
#define COLOR(fg, bg) "\x1b[" STR(fg) ";" STR(bg) "m"
|
||||
#define FG_BLACK 30
|
||||
#define FG_YELLOW 33
|
||||
#define FG_BLUE 34
|
||||
#define FG_WHITE 37
|
||||
#define BG_BLACK 40
|
||||
#define BG_YELLOW 43
|
||||
#define BG_BLUE 44
|
||||
#define BG_WHITE 47
|
||||
#define NONE 0
|
||||
#define BOLD 1
|
||||
extern bool supports_bright_colors;
|
||||
#define FG_BRIGHT_BLACK 90
|
||||
#define FG_BRIGHT_WHITE 97
|
||||
#define BG_BRIGHT_BLACK 100
|
||||
#define BG_BRIGHT_WHITE 107
|
||||
#define G1D4(set) printf("\x1b\x29%c", set)
|
||||
#define DSGON putchar('\x0e'); G1D4('0')
|
||||
#define DSGOFF putchar('\x0f'); G1D4('B')
|
||||
#define MOUSEON printf("\x1b[?1003h")
|
||||
#define MOUSEOFF printf("\x1b[?1003l")
|
||||
#define CIVIS printf("\x1b[?25l")
|
||||
#define CNORM printf("\x1b[?25h")
|
||||
#define SMCUP printf("\x1b[?1049h")
|
||||
#define RMCUP printf("\x1b[?1049l")
|
||||
#define DRAWLINE(x, y, len) \
|
||||
MOVETO(x, y); \
|
||||
DSGON; \
|
||||
for (int i = 0; i < len; i++) { \
|
||||
putchar(0x71); \
|
||||
} \
|
||||
DSGOFF;
|
||||
#define DRAWLINET(x, y, len) DRAWLINE(tui_x_offset + x, tui_y_offset + y, len)
|
||||
|
||||
typedef enum tui_screens {
|
||||
ERROR_SCREEN = -1,
|
||||
@@ -27,22 +72,113 @@ typedef enum tui_screens {
|
||||
MAIN_SCREEN = 1,
|
||||
OPTIONS_SCREEN = 2,
|
||||
ENTER_DFU_SCREEN = 3,
|
||||
JAILBREAKING_SCREEN = 4,
|
||||
JAILBREAK_SCREEN = 4,
|
||||
ENTER_RECOVERY_SCREEN = 5
|
||||
} tui_screen_t;
|
||||
|
||||
typedef struct bitfield_checkbox_info {
|
||||
checkrain_option_p flags_p;
|
||||
checkrain_option_t opt;
|
||||
uint64_t* flags_p;
|
||||
uint64_t opt;
|
||||
} tui_bit_info_t;
|
||||
|
||||
tui_screen_t tui_screen_main();
|
||||
tui_screen_t tui_screen_options();
|
||||
tui_screen_t tui_screen_enter_recovery();
|
||||
tui_screen_t tui_screen_enter_dfu();
|
||||
tui_screen_t tui_screen_jailbreak();
|
||||
tui_screen_t tui_screen_main(void);
|
||||
void tui_screen_main_redraw(void);
|
||||
tui_screen_t tui_screen_options(void);
|
||||
void tui_screen_options_redraw(void);
|
||||
tui_screen_t tui_screen_enter_recovery(void);
|
||||
void tui_screen_enter_recovery_redraw(void);
|
||||
tui_screen_t tui_screen_enter_dfu(void);
|
||||
void tui_screen_enter_dfu_redraw(void);
|
||||
tui_screen_t tui_screen_jailbreak(void);
|
||||
void tui_screen_jailbreak_redraw(void);
|
||||
|
||||
int redraw_screen();
|
||||
int redraw_screen(void);
|
||||
|
||||
void tui_draw_rectangle(int x1, int y1, int x2, int y2);
|
||||
|
||||
#ifdef BUILD_TAG
|
||||
#define TUI_VERSION BUILD_TAG
|
||||
#else
|
||||
#define TUI_VERSION "Unknown Version"
|
||||
#endif
|
||||
|
||||
extern int tui_x_offset;
|
||||
extern int tui_y_offset;
|
||||
|
||||
extern int tui_mouse_x;
|
||||
extern int tui_mouse_y;
|
||||
|
||||
enum {
|
||||
TUI_INPUT_NONE,
|
||||
TUI_INPUT_LEFT,
|
||||
TUI_INPUT_RIGHT,
|
||||
TUI_INPUT_UP,
|
||||
TUI_INPUT_DOWN,
|
||||
TUI_INPUT_MOUSE_MOVE,
|
||||
TUI_INPUT_MOUSE_DOWN,
|
||||
TUI_INPUT_MOUSE_UP,
|
||||
TUI_INPUT_SELECT,
|
||||
TUI_INPUT_TAB,
|
||||
TUI_INPUT_TAB_BACK,
|
||||
TUI_INPUT_BACKSPACE,
|
||||
TUI_INPUT_ESCAPE,
|
||||
};
|
||||
|
||||
enum {
|
||||
TUI_EVENT_INPUT,
|
||||
TUI_EVENT_CONNECTED_DEVICES_CHANGED,
|
||||
TUI_EVENT_JAILBREAK_STATUS_CHANGED
|
||||
};
|
||||
|
||||
int tui_get_input(void);
|
||||
void *tui_input_thread(void *arg);
|
||||
int tui_get_event(void);
|
||||
int tui_try_get_event(void);
|
||||
|
||||
extern int tui_last_event;
|
||||
extern int tui_last_input;
|
||||
extern sem_t *tui_event_semaphore;
|
||||
extern char tui_last_key;
|
||||
|
||||
void tui_devhelper(void);
|
||||
|
||||
enum tui_device_mode {
|
||||
TUI_DEVICE_MODE_NORMAL,
|
||||
TUI_DEVICE_MODE_RECOVERY,
|
||||
TUI_DEVICE_MODE_DFU
|
||||
};
|
||||
|
||||
struct tui_connected_device {
|
||||
uint64_t ecid;
|
||||
char udid[44];
|
||||
char version[0x20];
|
||||
bool arm64;
|
||||
enum tui_device_mode mode;
|
||||
char product_type[0x20];
|
||||
char display_name[0x20];
|
||||
unsigned int cpid;
|
||||
bool requires_passcode_disabled;
|
||||
bool passcode_state;
|
||||
struct tui_connected_device *next;
|
||||
};
|
||||
|
||||
extern struct tui_connected_device *tui_connected_devices;
|
||||
|
||||
void tui_jailbreak(void);
|
||||
extern bool tui_is_jailbreaking;
|
||||
extern int tui_jailbreak_stage;
|
||||
extern char *tui_jailbreak_status;
|
||||
|
||||
void tui_jailbreak_status_changed(void);
|
||||
|
||||
extern bool tui_is_restarting;
|
||||
void tui_terminate(int sig);
|
||||
|
||||
extern bool tui_options_safe_mode;
|
||||
extern bool tui_options_verbose_boot;
|
||||
extern bool tui_options_force_revert;
|
||||
extern bool tui_options_flower_chain;
|
||||
|
||||
extern char tui_options_boot_args[0x1e0 + 1];
|
||||
|
||||
#endif
|
||||
+22
-8
@@ -1,16 +1,30 @@
|
||||
#ifndef XXD_EMBEDDED_H
|
||||
#define XXD_EMBEDDED_H
|
||||
|
||||
extern unsigned char checkra1n[];
|
||||
extern unsigned int checkra1n_len;
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
extern unsigned char checkra1n_kpf_pongo[];
|
||||
extern unsigned int checkra1n_kpf_pongo_len;
|
||||
#include <stdint.h>
|
||||
|
||||
extern unsigned char ramdisk_dmg[];
|
||||
extern unsigned int ramdisk_dmg_len;
|
||||
extern uint8_t checkra1n[];
|
||||
extern uint32_t checkra1n_len;
|
||||
|
||||
extern unsigned char binpack_dmg[];
|
||||
extern unsigned int binpack_dmg_len;
|
||||
extern uint8_t checkra1n_kpf_pongo_lzma[];
|
||||
extern uint32_t checkra1n_kpf_pongo_lzma_len;
|
||||
|
||||
extern uint8_t ramdisk_dmg_lzma[];
|
||||
extern uint32_t ramdisk_dmg_lzma_len;
|
||||
|
||||
extern uint8_t binpack_dmg[];
|
||||
extern uint32_t binpack_dmg_len;
|
||||
|
||||
extern uint8_t Pongo_bin[];
|
||||
extern uint32_t Pongo_bin_len;
|
||||
|
||||
#if defined(__APPLE__) && (TARGET_OS_IPHONE || defined(DEV_BUILD) || defined(FORCE_HELPER))
|
||||
extern uint8_t libcheckra1nhelper_dylib[];
|
||||
extern uint32_t libcheckra1nhelper_dylib_len;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
Package: palera1n
|
||||
Name: palera1n
|
||||
Version: @DEB_VERSION@
|
||||
Architecture: @DEB_ARCH@
|
||||
Maintainer: palera1n team
|
||||
Author: palera1n team
|
||||
Depends: usbmuxd
|
||||
Section: Utilities
|
||||
Priority: optional
|
||||
Homepage: https://palera.in
|
||||
Description: iOS 15.0+ semi-tethered checkm8 jailbreak
|
||||
palera1n is an iOS/iPadOS 15.0+ semi tethered jailbreak
|
||||
based on the checkm8 exploit.
|
||||
.
|
||||
palera1n is able to jailbreak the device in fakefs-rootful mode,
|
||||
where / is writable, as well as rootless mode, where / cannot be
|
||||
written to.
|
||||
.
|
||||
IMPORTANT: This does NOT make palera1n untethered or allow you to
|
||||
jailbreak your current device without a computer. It just allows
|
||||
you to jailbreak another iDevice using this device, given you have
|
||||
an appropriate cable. Also, the success rate is likely to be bad.
|
||||
@@ -0,0 +1,16 @@
|
||||
Package: palera1n
|
||||
Name: palera1n
|
||||
Version: @DEB_VERSION@
|
||||
Architecture: @DEB_ARCH@
|
||||
Maintainer: palera1n team
|
||||
Author: palera1n team
|
||||
Section: Utilities
|
||||
Priority: optional
|
||||
Homepage: https://palera.in
|
||||
Description: iOS 15.0+ semi-tethered checkm8 jailbreak
|
||||
palera1n is an iOS/iPadOS 15.0+ semi tethered jailbreak
|
||||
based on the checkm8 exploit.
|
||||
.
|
||||
palera1n is able to jailbreak the device in fakefs-rootful mode,
|
||||
where / is writable, as well as rootless mode, where / cannot be
|
||||
written to.
|
||||
@@ -1,6 +1,6 @@
|
||||
From 632cdb6de3f1693fb90d60d81552b723e8dd5e84 Mon Sep 17 00:00:00 2001
|
||||
From a2d012f3ba459f6debe636b576ad9aeab7b3c2aa Mon Sep 17 00:00:00 2001
|
||||
From: Nick Chan <[email protected]>
|
||||
Date: Wed, 25 Jan 2023 01:53:00 +0800
|
||||
Date: Sat, 27 May 2023 23:50:23 +0800
|
||||
Subject: [PATCH] Allow empty x509 cert issuer
|
||||
|
||||
---
|
||||
@@ -8,25 +8,24 @@ Subject: [PATCH] Allow empty x509 cert issuer
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/library/x509_crt.c b/library/x509_crt.c
|
||||
index 0eee97cb6..46702f683 100644
|
||||
index cf62532f2..ef25b3d77 100644
|
||||
--- a/library/x509_crt.c
|
||||
+++ b/library/x509_crt.c
|
||||
@@ -1185,14 +1185,14 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
|
||||
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
- mbedtls_x509_crt_free( crt );
|
||||
- return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
|
||||
+ // mbedtls_x509_crt_free( crt );
|
||||
+ // return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
|
||||
@@ -1061,13 +1061,13 @@ static int x509_crt_parse_der_core(mbedtls_x509_crt *crt,
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
- mbedtls_x509_crt_free(crt);
|
||||
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
|
||||
+ /*mbedtls_x509_crt_free(crt);
|
||||
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);*/
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
|
||||
{
|
||||
- mbedtls_x509_crt_free( crt );
|
||||
- return( ret );
|
||||
+ // mbedtls_x509_crt_free( crt );
|
||||
+ // return( ret );
|
||||
if ((ret = mbedtls_x509_get_name(&p, p + len, &crt->issuer)) != 0) {
|
||||
- mbedtls_x509_crt_free(crt);
|
||||
- return ret;
|
||||
+ /*mbedtls_x509_crt_free(crt);
|
||||
+ return ret;*/
|
||||
}
|
||||
|
||||
crt->issuer_raw.len = p - crt->issuer_raw.p;
|
||||
|
||||
@@ -1,344 +0,0 @@
|
||||
#execute_process(COMMAND sh -c "cd ../dep_root && sh ../download_deps.sh")
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
|
||||
|
||||
#set(SRC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
#set(DEP ${SRC}/../dep_root)
|
||||
|
||||
cmake_parse_arguments(palera1n "" "" "-arch" ${ARGN})
|
||||
|
||||
set(CHECKRA1N_VERSION 0.1337.1)
|
||||
if( ${LDID})
|
||||
set(LDID ldid)
|
||||
endif()
|
||||
if( ${LIPO})
|
||||
set(LIPO lipo)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CHECKRA1N_FILE_NAME checkra1n-macos)
|
||||
else()
|
||||
set(CHECKRA1N_FILE_NAME checkra1n-linux-${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
add_executable(palera1n
|
||||
binpack.dmg.c
|
||||
checkra1n-kpf-pongo.c
|
||||
checkra1n.c
|
||||
devhelper.c
|
||||
dfuhelper.c
|
||||
exec_checkra1n.c
|
||||
lock_vars.c
|
||||
lockdown_helper.c
|
||||
log.c
|
||||
main.c
|
||||
optparse.c
|
||||
override_file.c
|
||||
pongo_helper.c
|
||||
credits.c
|
||||
ramdisk.dmg.c
|
||||
../include/kerninfo.h
|
||||
../include/palerain.h
|
||||
../include/ANSI-color-codes.h
|
||||
../include/tui.h
|
||||
../include/xxd-embedded.h
|
||||
)
|
||||
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -pedantic-errors -g)
|
||||
|
||||
# adds dev mode files
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
get_property(MY_TARGET_SOURCES TARGET palera1n PROPERTY SOURCES)
|
||||
list(APPEND MY_TARGET_SOURCES tui_main.c
|
||||
tui_screen_enter_dfu.c
|
||||
tui_screen_enter_recovery.c
|
||||
tui_screen_jailbreak.c
|
||||
tui_screen_main.c
|
||||
tui_screen_options.c)
|
||||
set_property(TARGET palera1n PROPERTY SOURCES ${MY_TARGET_SOURCES})
|
||||
|
||||
|
||||
elseif(CMAKE_BUILD_TYPE STREQUAL "ASAN")
|
||||
get_property(MY_TARGET_SOURCES TARGET palera1n PROPERTY SOURCES)
|
||||
list(APPEND MY_TARGET_SOURCES tui_main.c
|
||||
tui_screen_enter_dfu.c
|
||||
tui_screen_enter_recovery.c
|
||||
tui_screen_jailbreak.c
|
||||
tui_screen_main.c
|
||||
tui_screen_options.c)
|
||||
set_property(TARGET palera1n PROPERTY SOURCES ${MY_TARGET_SOURCES})
|
||||
add_compile_options(-fsanitize=address,undefined -fsanitize-address-use-after-return=runtime)
|
||||
elseif(CMAKE_BUILD_TYPE STREQUAL "TSAN")
|
||||
get_property(MY_TARGET_SOURCES TARGET palera1n PROPERTY SOURCES)
|
||||
list(APPEND MY_TARGET_SOURCES tui_main.c
|
||||
tui_screen_enter_dfu.c
|
||||
tui_screen_enter_recovery.c
|
||||
tui_screen_jailbreak.c
|
||||
tui_screen_main.c
|
||||
tui_screen_options.c)
|
||||
set_property(TARGET palera1n PROPERTY SOURCES ${MY_TARGET_SOURCES})
|
||||
add_compile_options(-fsanitize=thread,undefined)
|
||||
else()
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
endif()
|
||||
|
||||
#message("Testing for Clang/LLVM")
|
||||
#string(TOLOWER CMAKE_C_COMPILER_ID COMPILER)
|
||||
|
||||
#if(CMAKE_C_COMPILER_ID MATCHES "AppleClang" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# message("Using clang/llvm! Enabling -flto=full! Please make sure clang is up to date, or else compile will fail")
|
||||
# add_compile_options(-flto=full)
|
||||
#else()
|
||||
# message("Not using clang/llvm! Using normal lto/no lto!")
|
||||
# add_compile_options(-flto)
|
||||
#endif()
|
||||
|
||||
|
||||
|
||||
#add_custom_command(TARGET palera1n
|
||||
# COMMAND sh -c "curl -LO https://assets.checkra.in/downloads/preview/${CHECKRA1N_VERSION}/${CHECKRA1N_FILE_NAME} && chmod 755 ${CHECKRA1N_FILE_NAME}"
|
||||
# )
|
||||
#
|
||||
#if(APPLE)
|
||||
# add_custom_command(TARGET palera1n
|
||||
# COMMAND sh -c "ldid -Scheckra1n.plist checkra1n"
|
||||
# )
|
||||
# add_custom_command(TARGET palera1n
|
||||
# COMMAND lipo -thin ${CMAKE_SYSTEM_PROCESSOR} -output checkra1n checkra1n-macos
|
||||
# )
|
||||
# if(CFLAGS MATCHES "version-min=")
|
||||
# add_custom_command(TARGET palera1n
|
||||
# COMMAND sh -c "vtool -remove-build-version 1 -replace -output checkra1n checkra1n && vtool -set-build-version $(FAKE_PLATFORM) $(FAKE_MINOS) $(FAKE_SDK) -replace -output checkra1n checkra1n && install_name_tool -change /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit /System/Library/Frameworks/IOKit.framework/IOKit checkra1n && install_name_tool -change /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation checkra1n && ${LDID} -Susb.xml checkra1n"
|
||||
# )
|
||||
# endif()
|
||||
#else()
|
||||
# execute_process(
|
||||
# COMMAND cp ${CHECKRA1N_FILE_NAME} ../src/checkra1n
|
||||
# )
|
||||
#endif()
|
||||
|
||||
#ifneq (,$(findstring arm64, $(CFLAGS)))
|
||||
#$(LIPO) -thin arm64 -output checkra1n checkra1n-macos
|
||||
#else ifneq (,$(findstring x86_64, $(CFLAGS)))
|
||||
#$(LIPO) -thin x86_64 -output checkra1n checkra1n-macos
|
||||
#else ifeq ($(shell arch),i386)
|
||||
#$(LIPO) -thin x86_64 -output checkra1n checkra1n-macos
|
||||
#else
|
||||
#$(LIPO) -thin $(shell arch) -output checkra1n checkra1n-
|
||||
|
||||
if(APPLE)
|
||||
if(${LIBUSB})
|
||||
target_compile_definitions(palera1n PRIVATE -DUSE_LIBUSB)
|
||||
get_property(MY_TARGET_SOURCES TARGET palera1n PROPERTY SOURCES)
|
||||
list(APPEND MY_TARGET_SOURCES
|
||||
usb_libusb.c)
|
||||
set_property(TARGET palera1n PROPERTY SOURCES ${MY_TARGET_SOURCES})
|
||||
target_link_libraries(palera1n
|
||||
${DEP}/lib/libusb-1.0.a
|
||||
)
|
||||
else()
|
||||
get_property(MY_TARGET_SOURCES TARGET palera1n PROPERTY SOURCES)
|
||||
list(APPEND MY_TARGET_SOURCES
|
||||
usb_iokit.c)
|
||||
set_property(TARGET palera1n PROPERTY SOURCES ${MY_TARGET_SOURCES})
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if(IOS AND CMAKE_C_FLAGS MATCHES "arm64")
|
||||
add_custom_command(
|
||||
COMMAND sh -c "curl -Lo checkra1n-macos https://assets.checkra.in/downloads/preview/0.1337.1/${CHECKRA1N_FILE_NAME} "
|
||||
COMMAND lipo -thin arm64 -output checkra1n checkra1n-macos
|
||||
COMMAND sh -c "vtool -remove-build-version 1 -replace -output checkra1n checkra1n && vtool -set-build-version $(FAKE_PLATFORM) $(FAKE_MINOS) $(FAKE_SDK) -replace -output checkra1n checkra1n && install_name_tool -change /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit /System/Library/Frameworks/IOKit.framework/IOKit checkra1n && install_name_tool -change /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation checkra1n && ${LDID} -Susb.xml checkra1n"
|
||||
COMMAND sh -c "curl -Lo binpack.dmg https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg"
|
||||
COMMAND sh -c "curl -Lo ramdisk.dmg https://cdn.nickchan.lol/palera1n/c-rewrite/deps/ramdisk.dmg"
|
||||
COMMAND sh -c "curl -Lo checkra1n-kpf-pongo https://github.com/guacaplushy/checkp4le/raw/main/binaries/checkra1n-kpf-pongo"
|
||||
COMMAND pwd
|
||||
COMMAND xxd -iC checkra1n checkra1n.c
|
||||
COMMAND xxd -iC binpack.dmg binpack.dmg.c
|
||||
COMMAND xxd -iC ramdisk.dmg ramdisk.dmg.c
|
||||
COMMAND xxd -iC checkra1n-kpf-pongo checkra1n-kpf-pongo.c
|
||||
OUTPUT checkra1n.c checkra1n-kpf-pongo.c ramdisk.dmg.c binpack.dmg.c binpack.dmg ramdisk.dmg checkra1n-kpf-pongo
|
||||
)
|
||||
elseif(CMAKE_C_FLAGS MATCHES "arm64")
|
||||
add_custom_command(
|
||||
COMMAND sh -c "curl -Lo checkra1n-macos https://assets.checkra.in/downloads/preview/0.1337.1/${CHECKRA1N_FILE_NAME} "
|
||||
COMMAND lipo -thin arm64 -output checkra1n checkra1n-macos
|
||||
COMMAND sh -c "curl -Lo binpack.dmg https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg"
|
||||
COMMAND sh -c "curl -Lo ramdisk.dmg https://cdn.nickchan.lol/palera1n/c-rewrite/deps/ramdisk.dmg"
|
||||
COMMAND sh -c "curl -Lo checkra1n-kpf-pongo https://github.com/guacaplushy/checkp4le/raw/main/binaries/checkra1n-kpf-pongo"
|
||||
COMMAND pwd
|
||||
COMMAND xxd -iC checkra1n checkra1n.c
|
||||
COMMAND xxd -iC binpack.dmg binpack.dmg.c
|
||||
COMMAND xxd -iC ramdisk.dmg ramdisk.dmg.c
|
||||
COMMAND xxd -iC checkra1n-kpf-pongo checkra1n-kpf-pongo.c
|
||||
OUTPUT checkra1n.c checkra1n-kpf-pongo.c ramdisk.dmg.c binpack.dmg.c binpack.dmg ramdisk.dmg checkra1n-kpf-pongo
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
COMMAND sh -c "curl -Lo checkra1n-macos https://assets.checkra.in/downloads/preview/0.1337.1/${CHECKRA1N_FILE_NAME} "
|
||||
COMMAND lipo -thin x86_64 -output checkra1n checkra1n-macos
|
||||
COMMAND sh -c "curl -Lo binpack.dmg https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg"
|
||||
COMMAND sh -c "curl -Lo ramdisk.dmg https://cdn.nickchan.lol/palera1n/c-rewrite/deps/ramdisk.dmg"
|
||||
COMMAND sh -c "curl -Lo checkra1n-kpf-pongo https://github.com/guacaplushy/checkp4le/raw/main/binaries/checkra1n-kpf-pongo"
|
||||
COMMAND pwd
|
||||
COMMAND xxd -iC checkra1n checkra1n.c
|
||||
COMMAND xxd -iC binpack.dmg binpack.dmg.c
|
||||
COMMAND xxd -iC ramdisk.dmg ramdisk.dmg.c
|
||||
COMMAND xxd -iC checkra1n-kpf-pongo checkra1n-kpf-pongo.c
|
||||
OUTPUT checkra1n.c checkra1n-kpf-pongo.c ramdisk.dmg.c binpack.dmg.c binpack.dmg ramdisk.dmg checkra1n-kpf-pongo
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
add_custom_command(
|
||||
COMMAND sh -c "curl -Lo checkra1n https://assets.checkra.in/downloads/preview/0.1337.1/${CHECKRA1N_FILE_NAME} "
|
||||
COMMAND sh -c "curl -Lo binpack.dmg https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg"
|
||||
COMMAND sh -c "curl -Lo ramdisk.dmg https://cdn.nickchan.lol/palera1n/c-rewrite/deps/ramdisk.dmg"
|
||||
COMMAND sh -c "curl -Lo checkra1n-kpf-pongo https://github.com/guacaplushy/checkp4le/raw/main/binaries/checkra1n-kpf-pongo"
|
||||
COMMAND pwd
|
||||
COMMAND xxd -iC checkra1n checkra1n.c
|
||||
COMMAND xxd -iC binpack.dmg binpack.dmg.c
|
||||
COMMAND xxd -iC ramdisk.dmg ramdisk.dmg.c
|
||||
COMMAND xxd -iC checkra1n-kpf-pongo checkra1n-kpf-pongo.c
|
||||
OUTPUT checkra1n.c checkra1n-kpf-pongo.c ramdisk.dmg.c binpack.dmg.c binpack.dmg ramdisk.dmg checkra1n-kpf-pongo
|
||||
)
|
||||
target_compile_definitions(palera1n PRIVATE -DUSE_LIBUSB)
|
||||
get_property(MY_TARGET_SOURCES TARGET palera1n PROPERTY SOURCES)
|
||||
list(APPEND MY_TARGET_SOURCES
|
||||
usb_libusb.c)
|
||||
set_property(TARGET palera1n PROPERTY SOURCES ${MY_TARGET_SOURCES})
|
||||
target_link_libraries(palera1n
|
||||
${DEP}/lib/libusb-1.0.a
|
||||
)
|
||||
target_compile_definitions(palera1n PRIVATE -DUSE_LIBUSB)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
../include
|
||||
${SRC}
|
||||
)
|
||||
|
||||
|
||||
target_compile_definitions(palera1n PRIVATE -DPALERAIN_VERSION=\"2.0.0\")
|
||||
|
||||
target_include_directories(palera1n PRIVATE
|
||||
${SRC}/include
|
||||
${SRC}
|
||||
${DEP}/include
|
||||
)
|
||||
|
||||
#if(${STATIC})
|
||||
target_link_libraries(palera1n
|
||||
${DEP}/lib/libimobiledevice-1.0.a
|
||||
${DEP}/lib/libirecovery-1.0.a
|
||||
${DEP}/lib/libusbmuxd-2.0.a
|
||||
${DEP}/lib/libimobiledevice-glue-1.0.a
|
||||
${DEP}/lib/libplist-2.0.a
|
||||
${DEP}/lib/libmbedtls.a
|
||||
${DEP}/lib/libmbedcrypto.a
|
||||
${DEP}/lib/libmbedx509.a
|
||||
${DEP}/lib/libreadline.a
|
||||
)
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
if(NOT APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-static")
|
||||
endif()
|
||||
#else()
|
||||
# find_library(LIBIMOBILEDEVICE libimobiledevice)
|
||||
# if (NOT CORE_FOUNDATION)
|
||||
# message(FATAL_ERROR "libimobiledevice not found")
|
||||
# endif()
|
||||
# target_link_libraries(palera1n ${LIBIMOBILEDEVICE})
|
||||
#
|
||||
# find_library(LIR libirecovery)
|
||||
# if (NOT SYSCONF)
|
||||
# message(FATAL_ERROR "libirecovery not found")
|
||||
# endif()
|
||||
# target_link_libraries(palera1n ${LIR})
|
||||
#
|
||||
# find_library(USBMUXD usbmuxd)
|
||||
# if (NOT SEC)
|
||||
# message(FATAL_ERROR "usbmuxd not found")
|
||||
# endif()
|
||||
# target_link_libraries(palera1n ${USBMUXD})
|
||||
#
|
||||
# find_library(GLUE libimobiledevice-glue)
|
||||
# if (NOT IOKIT)
|
||||
# message(FATAL_ERROR "libimobiledevice-glue not found")
|
||||
# endif()
|
||||
# target_link_libraries(palera1n ${GLUE})
|
||||
#
|
||||
## target_link_libraries(palera1n
|
||||
## imobiledevice-1.0
|
||||
## irecovery-1.0
|
||||
## usbmuxd-2.0
|
||||
## imobiledevice-glue-1.0
|
||||
## plist-2.0
|
||||
## mbedtls
|
||||
## mbedcrypto
|
||||
## mbedx509
|
||||
## readline
|
||||
## usb-1.0
|
||||
## )
|
||||
#endif()
|
||||
#if(APPLE)
|
||||
# add_compile_options(palera1n
|
||||
# -framework CoreFoundation
|
||||
# -framework SystemConfiguration
|
||||
# -framework IOKit
|
||||
# -framework Security
|
||||
# )
|
||||
#endif()
|
||||
|
||||
if(APPLE)
|
||||
find_library(CORE_FOUNDATION CoreFoundation)
|
||||
if (NOT CORE_FOUNDATION)
|
||||
message(FATAL_ERROR "CoreFoundation not found")
|
||||
endif()
|
||||
target_link_libraries(palera1n ${CORE_FOUNDATION})
|
||||
|
||||
find_library(SYSCONF SystemConfiguration)
|
||||
if (NOT SYSCONF)
|
||||
message(FATAL_ERROR "SystemConfiguration not found")
|
||||
endif()
|
||||
target_link_libraries(palera1n ${SYSCONF})
|
||||
|
||||
find_library(SEC Security)
|
||||
if (NOT SEC)
|
||||
message(FATAL_ERROR "Security not found")
|
||||
endif()
|
||||
target_link_libraries(palera1n ${SEC})
|
||||
|
||||
find_library(IOKIT IOKit)
|
||||
if (NOT IOKIT)
|
||||
message(FATAL_ERROR "IOKit not found")
|
||||
endif()
|
||||
target_link_libraries(palera1n ${IOKIT})
|
||||
endif()
|
||||
add_compile_options(palera1n
|
||||
-static -no-pie -Wl,--gc-sections
|
||||
)
|
||||
|
||||
|
||||
if(!BUILD_DATE)
|
||||
execute_process(COMMAND date OUTPUT_VARIABLE BUILD_DATE)
|
||||
endif()
|
||||
if(!BUILD_TAG)
|
||||
execute_process(COMMAND git describe --dirty --tags --abbrev=7 OUTPUT_VARIABLE BUILD_TAG)
|
||||
endif()
|
||||
if(!BUILD_WHOAMI)
|
||||
execute_process(COMMAND whoami OUTPUT_VARIABLE BUILD_WHOAMI)
|
||||
endif ()
|
||||
|
||||
set(INCLUDE_DIR /usr/local/include)
|
||||
include_directories (${INCLUDE_DIR})
|
||||
|
||||
|
||||
add_compile_definitions(
|
||||
BUILD_DATE="${BUILD_DATE}"
|
||||
BUILD_TAG="${BUILD_TAG}"
|
||||
BUILD_WHOAMI="${BUILD_WHOAMI}"
|
||||
BUILD_STYLE="${CMAKE_BUILD_TYPE}"
|
||||
)
|
||||
+133
-42
@@ -1,106 +1,197 @@
|
||||
all: palera1n
|
||||
|
||||
OBJECTS = main.o dfuhelper.o devhelper.o lockdown_helper.o
|
||||
OBJECTS += optparse.o override_file.o log.o lock_vars.o credits.o
|
||||
OBJECTS += fake_embedded.o exec_checkra1n.o pongo_helper.o
|
||||
OBJDIR = obj
|
||||
GENDIR = gen
|
||||
RESOURCES_DIR = resources
|
||||
|
||||
C_SRC = $(wildcard *.c)
|
||||
OBJS = $(patsubst %,$(OBJDIR)/%,$(C_SRC:.c=.c.o))
|
||||
|
||||
ifeq (,$(findstring macosx, $(CFLAGS)))
|
||||
ifneq (,$(findstring version-min=, $(CFLAGS)))
|
||||
ifneq ($(NO_EMBED_HELPER),1)
|
||||
C_SRC += $(GENDIR)/gen-libcheckra1nhelper.dylib.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(NO_EMBED_HELPER),1)
|
||||
CFLAGS += -DNO_EMBED_HELPER
|
||||
endif
|
||||
|
||||
ifeq ($(DFUHELPER_AUTO_ONLY),1)
|
||||
CFLAGS += -DDFUHELPER_AUTO_ONLY
|
||||
endif
|
||||
|
||||
ifeq ($(FORCE_HELPER),1)
|
||||
ifneq ($(NO_EMBED_HELPER),1)
|
||||
C_SRC += $(GENDIR)/gen-libcheckra1nhelper.dylib.c
|
||||
endif
|
||||
CFLAGS += -DFORCE_HELPER
|
||||
BUILD_OPTIONS += FORCE_HELPER
|
||||
endif
|
||||
|
||||
ifneq ($(NO_RAMDISK),1)
|
||||
OBJECTS += xxd-ramdisk.dmg.o
|
||||
C_SRC += $(GENDIR)/gen-ramdisk.dmg.lzma.c
|
||||
else
|
||||
CFLAGS += -DNO_RAMDISK
|
||||
CFLAGS += -DNO_RAMDISK -DRAMDISK_COMPRESSED_SIZE=\"0\"
|
||||
BUILD_OPTIONS += NO_RAMDISK
|
||||
endif
|
||||
ifneq ($(NO_KPF),1)
|
||||
OBJECTS += xxd-checkra1n-kpf-pongo.o
|
||||
C_SRC += $(GENDIR)/gen-checkra1n-kpf-pongo.lzma.c
|
||||
else
|
||||
CFLAGS += -DNO_KPF
|
||||
BUILD_OPTIONS += NO_KPF
|
||||
endif
|
||||
ifneq ($(NO_BINPACK),1)
|
||||
OBJECTS += xxd-binpack.dmg.o
|
||||
ifneq ($(NO_OVERLAY),1)
|
||||
C_SRC += $(GENDIR)/gen-binpack.dmg.c
|
||||
else
|
||||
CFLAGS += -DNO_BINPACK
|
||||
CFLAGS += -DNO_OVERLAY
|
||||
BUILD_OPTIONS += NO_OVERLAY
|
||||
endif
|
||||
ifneq ($(NO_CHECKRAIN),1)
|
||||
OBJECTS += xxd-checkra1n.o
|
||||
C_SRC += $(GENDIR)/gen-checkra1n.c
|
||||
else
|
||||
CFLAGS += -DNO_CHECKRAIN
|
||||
BUILD_OPTIONS += NO_CHECKRAIN
|
||||
endif
|
||||
|
||||
ifeq ($(DEV_BUILD),1)
|
||||
OBJECTS += tui_screen_enter_recovery.o tui_screen_enter_dfu.o tui_main.o
|
||||
OBJECTS += tui_screen_jailbreak.o tui_screen_main.o tui_screen_options.o
|
||||
ifneq ($(NO_CUSTOM_PONGO),1)
|
||||
C_SRC += $(GENDIR)/gen-Pongo.bin.c
|
||||
else
|
||||
CFLAGS += -DNO_CUSTOM_PONGO
|
||||
BUILD_OPTIONS += NO_CUSTOM_PONGO
|
||||
endif
|
||||
|
||||
CHECKRA1N_VERSION ?= 0.1337.1
|
||||
ifeq ($(TUI),1)
|
||||
BUILD_OPTIONS += TUI
|
||||
CFLAGS += -DTUI
|
||||
endif
|
||||
|
||||
CHECKRA1N_VERSION ?= 0.1337.3
|
||||
LIPO = lipo
|
||||
LDID = ldid
|
||||
|
||||
ifeq ($(TARGET_OS),Darwin)
|
||||
ifneq ($(USE_LIBUSB),1)
|
||||
OBJECTS += usb_iokit.o
|
||||
else
|
||||
LIBS += -framework SystemConfiguration -framework Security
|
||||
BUILD_OPTIONS += USE_LIBUSB
|
||||
endif
|
||||
# add lto and debug symbols for lto
|
||||
CFLAGS += -flto=full -g
|
||||
LDFLAGS += -Wl,-object_path_lto,obj/lto.o
|
||||
else
|
||||
USE_LIBUSB = 1
|
||||
endif
|
||||
|
||||
ifeq ($(USE_LIBUSB),1)
|
||||
OBJECTS += usb_libusb.o
|
||||
CFLAGS += -DUSE_LIBUSB=1
|
||||
LIBS += $(DEP)/lib/libusb-1.0.a
|
||||
endif
|
||||
|
||||
checkra1n-%:
|
||||
curl -LO https://assets.checkra.in/downloads/preview/$(CHECKRA1N_VERSION)/$@
|
||||
ifneq ($(ROOTFUL),0)
|
||||
CFLAGS += -DROOTFUL=1
|
||||
BUILD_OPTIONS += ROOTFUL
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_OPTIONS),)
|
||||
BUILD_OPTIONS = (none)
|
||||
endif
|
||||
|
||||
CFLAGS += -DBUILD_OPTIONS=\""$(BUILD_OPTIONS)"\"
|
||||
|
||||
ifeq ($(TARGET_OS),Linux)
|
||||
ifeq ($(UNAME),Linux)
|
||||
ifeq ($(CHECKRA1N_NAME),)
|
||||
ifeq ($(shell arch),x86_64)
|
||||
CHECKRA1N_NAME := linux-x86_64
|
||||
else ifeq ($(shell arch | grep -q 'i[3-7]86' && echo 1),1)
|
||||
CHECKRA1N_NAME := linux-x86
|
||||
else ifeq ($(shell arch | grep -v '\(arm\|aarch\)[a-z]\?\+64' | grep -q arm && echo 1),1)
|
||||
CHECKRA1N_NAME := linux-armel
|
||||
else ifeq ($(shell arch | grep -q '\(arm\|aarch\)[a-z]\?\+64' && echo 1),1)
|
||||
CHECKRA1N_NAME := linux-arm64
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
$(RESOURCES_DIR)/checkra1n-%:
|
||||
curl -Lfo $@ https://assets.checkra.in/downloads/preview/$(CHECKRA1N_VERSION)/$$(echo $@ | cut -d/ -f2)
|
||||
chmod 755 $@
|
||||
|
||||
checkra1n: checkra1n-macos usb.xml
|
||||
$(RESOURCES_DIR)/checkra1n: $(RESOURCES_DIR)/checkra1n-macos usb.xml
|
||||
ifeq ($(TARGET_OS),Darwin)
|
||||
ifneq (,$(findstring arm64, $(CFLAGS)))
|
||||
$(LIPO) -thin arm64 -output checkra1n checkra1n-macos
|
||||
$(LIPO) -thin arm64 -output $(RESOURCES_DIR)/checkra1n $(RESOURCES_DIR)/checkra1n-macos
|
||||
else ifneq (,$(findstring x86_64, $(CFLAGS)))
|
||||
$(LIPO) -thin x86_64 -output checkra1n checkra1n-macos
|
||||
$(LIPO) -thin x86_64 -output $(RESOURCES_DIR)/checkra1n $(RESOURCES_DIR)/checkra1n-macos
|
||||
else ifeq ($(shell arch),i386)
|
||||
$(LIPO) -thin x86_64 -output checkra1n checkra1n-macos
|
||||
$(LIPO) -thin x86_64 -output $(RESOURCES_DIR)/checkra1n $(RESOURCES_DIR)/checkra1n-macos
|
||||
else
|
||||
$(LIPO) -thin $(shell arch) -output checkra1n checkra1n-macos
|
||||
$(LIPO) -thin $(shell arch) -output $(RESOURCES_DIR)/checkra1n $(RESOURCES_DIR)/checkra1n-macos
|
||||
endif
|
||||
ifeq (,$(findstring macosx, $(CFLAGS)))
|
||||
ifneq (,$(findstring version-min=, $(CFLAGS)))
|
||||
vtool -remove-build-version 1 -replace -output checkra1n checkra1n
|
||||
vtool -set-build-version $(FAKE_PLATFORM) $(FAKE_MINOS) $(FAKE_SDK) -replace -output checkra1n checkra1n
|
||||
install_name_tool -change /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit /System/Library/Frameworks/IOKit.framework/IOKit checkra1n
|
||||
install_name_tool -change /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation checkra1n
|
||||
$(LDID) -Susb.xml checkra1n
|
||||
vtool -remove-build-version 1 -replace -output $(RESOURCES_DIR)/checkra1n $(RESOURCES_DIR)/checkra1n
|
||||
vtool -set-build-version $(FAKE_PLATFORM) $(FAKE_MINOS) $(FAKE_SDK) -replace -output $(RESOURCES_DIR)/checkra1n $(RESOURCES_DIR)/checkra1n
|
||||
install_name_tool -change /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit /System/Library/Frameworks/IOKit.framework/IOKit $(RESOURCES_DIR)/checkra1n
|
||||
install_name_tool -change /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation $(RESOURCES_DIR)/checkra1n
|
||||
$(LDID) -Susb.xml $(RESOURCES_DIR)/checkra1n
|
||||
endif
|
||||
endif
|
||||
else
|
||||
cp checkra1n-$(CHECKRA1N_NAME) checkra1n
|
||||
cp $(RESOURCES_DIR)/checkra1n-$(CHECKRA1N_NAME) $(RESOURCES_DIR)/checkra1n
|
||||
endif
|
||||
|
||||
xxd-%.c: %
|
||||
xxd -iC $< > $@
|
||||
$(GENDIR)/gen-%.c: $(RESOURCES_DIR)/%
|
||||
echo '#include <stdint.h>' > $(RESOURCES_DIR)/../$@
|
||||
cd $(RESOURCES_DIR) && xxd -iC $$(echo $< | cut -d/ -f2) | sed -e 's/unsigned int/uint32_t/' -e 's/unsigned char/uint8_t/' >> ../$@
|
||||
|
||||
%.o: %.c $(wildcard ../include/*.h)
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
palera1n: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o palera1n
|
||||
$(OBJDIR)/pongo_helper.c.o: pongo_helper.c $(wildcard ../include/*.h) $(RESOURCES_DIR)/ramdisk.dmg $(RESOURCES_DIR)/checkra1n-kpf-pongo
|
||||
$(CC) -c -o $@ $(CFLAGS) -DRAMDISK_UNCOMPRESSED_SIZE="\"$$(wc -c < $(RESOURCES_DIR)/ramdisk.dmg | tr -d ' ')\"" -DKPF_UNCOMPRESSED_SIZE="\"$$(wc -c < $(RESOURCES_DIR)/checkra1n-kpf-pongo | tr -d ' ')\"" $<
|
||||
|
||||
$(OBJDIR)/%.c.o: $(GENDIR)/gen-%.c $(wildcard ../include/*.h)
|
||||
$(CC) $(CFLAGS) -c -o $<
|
||||
|
||||
$(OBJDIR)/%.c.o: %.c $(wildcard ../include/*.h)
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
palera1n: $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o palera1n
|
||||
ifeq (,$(findstring macosx, $(CFLAGS)))
|
||||
ifneq (,$(findstring version-min=, $(CFLAGS)))
|
||||
$(LDID) -Susb.xml palera1n
|
||||
endif
|
||||
endif
|
||||
|
||||
checkra1n-kpf-pongo:
|
||||
curl -LO https://github.com/guacaplushy/checkp4le/raw/main/binaries/checkra1n-kpf-pongo
|
||||
$(RESOURCES_DIR)/libcheckra1nhelper.dylib: chkstk.S
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -shared chkstk.S -o $@
|
||||
|
||||
ramdisk.dmg:
|
||||
curl -LO https://cdn.nickchan.lol/palera1n/c-rewrite/deps/ramdisk.dmg
|
||||
$(RESOURCES_DIR)/checkra1n-kpf-pongo:
|
||||
curl -Lfo $@ https://cdn.nickchan.lol/palera1n/artifacts/kpf/iOS15/checkra1n-kpf-pongo
|
||||
|
||||
binpack.dmg:
|
||||
curl -LO https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg
|
||||
$(RESOURCES_DIR)/ramdisk.dmg.lzma: $(RESOURCES_DIR)/ramdisk.dmg
|
||||
xz --format=lzma -vfc6ekT 0 $< > $@
|
||||
|
||||
$(RESOURCES_DIR)/checkra1n-kpf-pongo.lzma: $(RESOURCES_DIR)/checkra1n-kpf-pongo
|
||||
xz --format=lzma -vfc6ekT 0 $< > $@
|
||||
|
||||
$(RESOURCES_DIR)/ramdisk.dmg:
|
||||
curl -Lfo $@ https://cdn.nickchan.lol/palera1n/c-rewrite/deps/ramdisk.dmg
|
||||
|
||||
$(RESOURCES_DIR)/binpack.dmg:
|
||||
curl -Lfo $@ https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg
|
||||
|
||||
$(RESOURCES_DIR)/Pongo.bin:
|
||||
curl -Lfo $@ https://cdn.nickchan.lol/palera1n/artifacts/kpf/iOS15/Pongo.bin
|
||||
|
||||
clean:
|
||||
rm -rf *.o palera1n checkra1n checkra1n.c palera1n.dSYM
|
||||
rm -rf $(OBJDIR)/*.o $(GENDIR)/*.c $(GENDIR)/*.o palera1n palera1n.dSYM libcheckra1nhelper.dylib
|
||||
|
||||
distclean: clean
|
||||
rm -rf $(RESOURCES_DIR)/*
|
||||
|
||||
.PHONY: all clean
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const unsigned char *
|
||||
boyermoore_horspool_memmem(const unsigned char* haystack, size_t hlen,
|
||||
const unsigned char* needle, size_t nlen)
|
||||
{
|
||||
size_t scan = 0;
|
||||
size_t bad_char_skip[UCHAR_MAX + 1]; /* Officially called:
|
||||
* bad character shift */
|
||||
|
||||
/* Sanity checks on the parameters */
|
||||
if (nlen <= 0 || !haystack || !needle)
|
||||
return NULL;
|
||||
|
||||
/* ---- Preprocess ---- */
|
||||
/* Initialize the table to default value */
|
||||
/* When a character is encountered that does not occur
|
||||
* in the needle, we can safely skip ahead for the whole
|
||||
* length of the needle.
|
||||
*/
|
||||
for (scan = 0; scan <= UCHAR_MAX; scan = scan + 1)
|
||||
bad_char_skip[scan] = nlen;
|
||||
|
||||
/* C arrays have the first byte at [0], therefore:
|
||||
* [nlen - 1] is the last byte of the array. */
|
||||
size_t last = nlen - 1;
|
||||
|
||||
/* Then populate it with the analysis of the needle */
|
||||
for (scan = 0; scan < last; scan = scan + 1)
|
||||
bad_char_skip[needle[scan]] = last - scan;
|
||||
|
||||
/* ---- Do the matching ---- */
|
||||
|
||||
/* Search the haystack, while the needle can still be within it. */
|
||||
while (hlen >= nlen)
|
||||
{
|
||||
/* scan from the end of the needle */
|
||||
for (scan = last; haystack[scan] == needle[scan]; scan = scan - 1)
|
||||
if (scan == 0) /* If the first byte matches, we've found it. */
|
||||
{
|
||||
return haystack;
|
||||
}
|
||||
|
||||
/* otherwise, we need to skip some bytes and start again.
|
||||
Note that here we are getting the skip value based on the last byte
|
||||
of needle, no matter where we didn't match. So if needle is: "abcd"
|
||||
then we are skipping based on 'd' and that value will be 4, and
|
||||
for "abcdd" we again skip on 'd' but the value will be only 1.
|
||||
The alternative of pretending that the mismatched character was
|
||||
the last character is slower in the normal case (E.g. finding
|
||||
"abcd" in "...azcd..." gives 4 by using 'd' but only
|
||||
4-2==2 using 'z'. */
|
||||
hlen -= bad_char_skip[haystack[last]];
|
||||
haystack += bad_char_skip[haystack[last]];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#define _PTHREAD_STRUCT_DIRECT_STACKADDR_OFFSET -48
|
||||
#define _PTHREAD_STRUCT_DIRECT_STACKBOTTOM_OFFSET -40
|
||||
|
||||
.align 4
|
||||
_thread_chkstk_darwin:
|
||||
.globl ___chkstk_darwin
|
||||
___chkstk_darwin: // %w9/x9 == alloca size
|
||||
stp x10, x11, [sp, #-16]
|
||||
|
||||
// validate that the frame pointer is on our stack (no alt stack)
|
||||
mrs x10, TPIDRRO_EL0
|
||||
|
||||
// (%sp - pthread_self()->stackaddr) > 0 ?
|
||||
#if defined(__ARM64_ARCH_8_32__)
|
||||
ubfx x9, x9, #0, #32
|
||||
ldur w11, [x10, _PTHREAD_STRUCT_DIRECT_STACKADDR_OFFSET]
|
||||
#else
|
||||
ldur x11, [x10, _PTHREAD_STRUCT_DIRECT_STACKADDR_OFFSET]
|
||||
#endif
|
||||
subs x11, sp, x11
|
||||
b.hs Lprobe
|
||||
|
||||
// %sp <= pthread_self()->stackbottom ?
|
||||
#if defined(__ARM64_ARCH_8_32__)
|
||||
ldur w11, [x10, _PTHREAD_STRUCT_DIRECT_STACKBOTTOM_OFFSET]
|
||||
#else
|
||||
ldur x11, [x10, _PTHREAD_STRUCT_DIRECT_STACKBOTTOM_OFFSET]
|
||||
#endif
|
||||
mov x10, sp
|
||||
cmp x10, x11
|
||||
b.ls Lprobe
|
||||
|
||||
// %sp - (uintptr_t)%x9 < pthread_self()->stackbottom ?
|
||||
subs x10, x10, x9
|
||||
b.lo Lcrash
|
||||
cmp x10, x11
|
||||
b.lo Lcrash
|
||||
|
||||
Lexit:
|
||||
ldp x10, x11, [sp, #-16]
|
||||
ret
|
||||
|
||||
Lcrash:
|
||||
// POSIX mandates that stack overflow crashes with SIGSEGV
|
||||
// so load an address in the guard page and dereference it
|
||||
//
|
||||
// x11 contains pthread_self()->stackbottom already
|
||||
ldr x11, [x11, #-8]
|
||||
// if main_thread caused stack growth with setrlimit()
|
||||
// fall into Lprobe and eventually cause SIGSEGV.
|
||||
|
||||
Lprobe:
|
||||
mov x10, sp
|
||||
cmp x9, #0x1000
|
||||
b.lo Lend
|
||||
Lloop:
|
||||
sub x10, x10, #0x1000
|
||||
ldr x11, [x10]
|
||||
sub x9, x9, #0x1000
|
||||
cmp x9, #0x1000
|
||||
b.hi Lloop
|
||||
Lend:
|
||||
sub x10, x10, x9
|
||||
ldr x11, [x10]
|
||||
b Lexit
|
||||
+22
-16
@@ -1,19 +1,25 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define EE fprintf
|
||||
#define Q }
|
||||
#define P print_credits() {
|
||||
#define BAKERAIN_DEVELOPER "dora2ios"
|
||||
#define O void
|
||||
#define Y )
|
||||
#define Z (
|
||||
#define R stdout
|
||||
#define S ,
|
||||
#define T ;
|
||||
#define A "# == palera1n-c == \n#\n"
|
||||
#define B "# Made by: Nick Chan, Tom, Mineek, Nebula, llsc12\n#\n"
|
||||
#define C "# Thanks to: " BAKERAIN_DEVELOPER ", pythonplayer, tihmstar, nikias\n"
|
||||
#define D "# (libimobiledevice), checkra1n team (Siguza, axi0mx, littlelailo\n"
|
||||
#define E "# et al.), Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)\n\n"
|
||||
#ifndef BAKERAIN_DEVELOPE_R
|
||||
#define BAKERAIN_DEVELOPE_R "kok3shidoll"
|
||||
#endif
|
||||
#define THE_PLUSH "Ploosh"
|
||||
|
||||
O P EE Z R S A B C D E Y T Q
|
||||
#define NEKO_DEVELOPE_R "HAHALOSAH"
|
||||
|
||||
#define T void
|
||||
#define R print_credits(void) {
|
||||
#define O fprintf(
|
||||
#define U stderr,
|
||||
#define B "#\n# palera1n: " BUILD_TAG " \n#\n"
|
||||
#define L "# ======== Made by =======\n"
|
||||
#define E "# Made by: Nick Chan, " THE_PLUSH ", Khcrysalis, Mineek, staturnz, " BAKERAIN_DEVELOPE_R ", " NEKO_DEVELOPE_R " \n"
|
||||
#define M "# ======== Thanks to =======\n"
|
||||
#define A "# Thanks to: llsc12, Nebula, Lrdsnow, nikias (libimobiledevice),\n"
|
||||
#define K "# checkra1n team (Siguza, axi0mx, littlelailo et al.),\n"
|
||||
#define I "# Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)\n"
|
||||
#define N "# ==========================\n\n"
|
||||
#define G );
|
||||
#define S }
|
||||
|
||||
T R O U B L E M A K I N G S
|
||||
+96
-92
@@ -28,8 +28,6 @@
|
||||
#include <libimobiledevice/diagnostics_relay.h>
|
||||
#include <plist/plist.h>
|
||||
|
||||
#include "lockdown_helper.h"
|
||||
|
||||
#ifdef HAVE_LIB_TV_CONTROL
|
||||
#include <libtvcontrol.h>
|
||||
#endif
|
||||
@@ -37,6 +35,7 @@
|
||||
#include <palerain.h>
|
||||
|
||||
irecv_device_event_context_t irecvctx = NULL;
|
||||
usbmuxd_subscription_context_t usbmuxdctx = NULL;
|
||||
|
||||
void devinfo_free(devinfo_t *dev) {
|
||||
free(dev->buildVersion);
|
||||
@@ -75,33 +74,35 @@ bool cpid_is_arm64(unsigned int cpid) {
|
||||
* ========== 0x8960 ===========
|
||||
* (ARM64) A7
|
||||
*/
|
||||
if (
|
||||
cpid == 0x8960 || cpid == 0x7000 || cpid == 0x7001
|
||||
|| cpid == 0x8000 || cpid == 0x8001 || cpid == 0x8003
|
||||
|| cpid == 0x8010 || cpid == 0x8011 || cpid == 0x8012
|
||||
|| cpid == 0x8015
|
||||
|
||||
) return true;
|
||||
return false;
|
||||
return (
|
||||
cpid == 0x8960 || cpid == 0x7000 || cpid == 0x7001 ||
|
||||
cpid == 0x8000 || cpid == 0x8001 || cpid == 0x8003 ||
|
||||
cpid == 0x8010 || cpid == 0x8011 || cpid == 0x8012 ||
|
||||
cpid == 0x8015
|
||||
);
|
||||
}
|
||||
|
||||
int subscribe_cmd(usbmuxd_event_cb_t device_event_cb, irecv_device_event_cb_t irecv_event_cb)
|
||||
{
|
||||
usbmuxd_subscribe(device_event_cb, NULL);
|
||||
irecv_device_event_subscribe(&irecvctx, irecv_event_cb, NULL);
|
||||
int ret;
|
||||
if ((ret = usbmuxd_events_subscribe(&usbmuxdctx, device_event_cb, NULL))) return ret;
|
||||
if ((ret = irecv_device_event_subscribe(&irecvctx, irecv_event_cb, NULL))) return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unsubscribe_cmd()
|
||||
int unsubscribe_cmd(void)
|
||||
{
|
||||
usbmuxd_unsubscribe();
|
||||
irecv_device_event_unsubscribe(irecvctx);
|
||||
int ret;
|
||||
if ((ret = usbmuxd_events_unsubscribe(usbmuxdctx))) return ret;
|
||||
if ((ret = irecv_device_event_unsubscribe(irecvctx))) return ret;
|
||||
irecvctx = NULL;
|
||||
usbmuxdctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int devinfo_cmd(devinfo_t *dev, const char *udid)
|
||||
{
|
||||
int ret;
|
||||
uint64_t this_ecid = 0;
|
||||
char *productType = NULL;
|
||||
char *productVersion = NULL;
|
||||
@@ -110,79 +111,79 @@ int devinfo_cmd(devinfo_t *dev, const char *udid)
|
||||
char *CPUArchitecture = NULL;
|
||||
idevice_t device = NULL;
|
||||
lockdownd_client_t lockdown = NULL;
|
||||
if (idevice_new(&device, udid) != IDEVICE_E_SUCCESS)
|
||||
if ((ret = idevice_new_with_options(&device, udid, IDEVICE_LOOKUP_USBMUX)) != IDEVICE_E_SUCCESS)
|
||||
{
|
||||
LOG(LOG_ERROR, "Error connecting to device.");
|
||||
LOG(LOG_ERROR, "Error connecting to device: %d (%s)", ret, lockdownd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
if (lockdownd_client_new(device, &lockdown, "palera1n") != LOCKDOWN_E_SUCCESS)
|
||||
if ((ret = lockdownd_client_new_with_handshake(device, &lockdown, "palera1n")) != LOCKDOWN_E_SUCCESS)
|
||||
{
|
||||
idevice_free(device);
|
||||
LOG(LOG_ERROR, "Device is not in normal mode.");
|
||||
(void)idevice_free(device);
|
||||
LOG(LOG_ERROR, "Device is not in normal mode: %d (%s)", ret, lockdownd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
plist_t node = NULL;
|
||||
if (lockdownd_get_value(lockdown, NULL, "UniqueChipID", &node) != LOCKDOWN_E_SUCCESS)
|
||||
if ((ret = lockdownd_get_value(lockdown, NULL, "UniqueChipID", &node)) != LOCKDOWN_E_SUCCESS)
|
||||
{
|
||||
lockdownd_client_free(lockdown);
|
||||
idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting ECID");
|
||||
(void)lockdownd_client_free(lockdown);
|
||||
(void)idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting ECID: %d (%s)", ret, lockdownd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
plist_get_uint_val(node, &this_ecid);
|
||||
plist_free(node);
|
||||
|
||||
node = NULL;
|
||||
if (lockdownd_get_value(lockdown, NULL, "ProductType", &node) != LOCKDOWN_E_SUCCESS)
|
||||
if ((ret = lockdownd_get_value(lockdown, NULL, "ProductType", &node)) != LOCKDOWN_E_SUCCESS)
|
||||
{
|
||||
lockdownd_client_free(lockdown);
|
||||
idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting product type");
|
||||
(void)lockdownd_client_free(lockdown);
|
||||
(void)idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting product type: %d (%s)", ret, lockdownd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
plist_get_string_val(node, &productType);
|
||||
plist_free(node);
|
||||
|
||||
node = NULL;
|
||||
if (lockdownd_get_value(lockdown, NULL, "CPUArchitecture", &node) != LOCKDOWN_E_SUCCESS)
|
||||
if ((ret = lockdownd_get_value(lockdown, NULL, "CPUArchitecture", &node)) != LOCKDOWN_E_SUCCESS)
|
||||
{
|
||||
lockdownd_client_free(lockdown);
|
||||
idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting CPU type");
|
||||
(void)lockdownd_client_free(lockdown);
|
||||
(void)idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting CPU type: %d (%s)", ret, lockdownd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
plist_get_string_val(node, &CPUArchitecture);
|
||||
plist_free(node);
|
||||
|
||||
node = NULL;
|
||||
if (lockdownd_get_value(lockdown, NULL, "ProductVersion", &node) != LOCKDOWN_E_SUCCESS)
|
||||
if ((ret = lockdownd_get_value(lockdown, NULL, "ProductVersion", &node)) != LOCKDOWN_E_SUCCESS)
|
||||
{
|
||||
lockdownd_client_free(lockdown);
|
||||
idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting product version");
|
||||
(void)lockdownd_client_free(lockdown);
|
||||
(void)idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting product version: %d (%s)", ret, lockdownd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
plist_get_string_val(node, &productVersion);
|
||||
plist_free(node);
|
||||
|
||||
node = NULL;
|
||||
if (lockdownd_get_value(lockdown, NULL, "BuildVersion", &node) != LOCKDOWN_E_SUCCESS)
|
||||
if ((ret = lockdownd_get_value(lockdown, NULL, "BuildVersion", &node)) != LOCKDOWN_E_SUCCESS)
|
||||
{
|
||||
lockdownd_client_free(lockdown);
|
||||
idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting build version");
|
||||
(void)lockdownd_client_free(lockdown);
|
||||
(void)idevice_free(device);
|
||||
LOG(LOG_ERROR, "Error getting build version: %d (%s)", ret, lockdownd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
plist_get_string_val(node, &buildVersion);
|
||||
plist_free(node);
|
||||
lockdownd_client_free(lockdown);
|
||||
idevice_free(device);
|
||||
(void)lockdownd_client_free(lockdown);
|
||||
(void)idevice_free(device);
|
||||
|
||||
irecv_device_t rcvydev;
|
||||
if (irecv_devices_get_device_by_product_type(productType, &rcvydev) == IRECV_E_SUCCESS)
|
||||
{
|
||||
displayName = rcvydev->display_name;
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
displayName = productType;
|
||||
}
|
||||
@@ -207,23 +208,22 @@ int enter_recovery_cmd(const char* udid) {
|
||||
LOG(LOG_ERROR, "Could not connect to lockdownd: %s", lockdownd_strerror(ldret));
|
||||
return -1;
|
||||
}
|
||||
do {
|
||||
ldret = lockdownd_enter_recovery(lockdown);
|
||||
if (ldret == LOCKDOWN_E_SESSION_INACTIVE) {
|
||||
lockdownd_client_free(lockdown);
|
||||
lockdown = NULL;
|
||||
if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &lockdown, "palera1n"))) {
|
||||
LOG(LOG_ERROR, "Could not connect to lockdownd: %s", lockdownd_strerror(ldret));
|
||||
return -1;
|
||||
}
|
||||
ldret = lockdownd_enter_recovery(lockdown);
|
||||
}
|
||||
ldret = lockdownd_enter_recovery(lockdown);
|
||||
if (ldret == LOCKDOWN_E_SESSION_INACTIVE) {
|
||||
lockdownd_client_free(lockdown);
|
||||
lockdown = NULL;
|
||||
ldret = lockdownd_client_new_with_handshake(device, &lockdown, "palera1n");
|
||||
if (ldret != LOCKDOWN_E_SUCCESS) {
|
||||
LOG(LOG_ERROR, "Could not trigger entering recovery mode: %s", lockdownd_strerror(ldret));
|
||||
LOG(LOG_ERROR, "Could not connect to lockdownd: %s", lockdownd_strerror(ldret));
|
||||
return -1;
|
||||
}
|
||||
lockdownd_client_free(lockdown);
|
||||
} while (0);
|
||||
ldret = lockdownd_enter_recovery(lockdown);
|
||||
}
|
||||
if (ldret != LOCKDOWN_E_SUCCESS) {
|
||||
LOG(LOG_ERROR, "Could not trigger entering recovery mode: %s", lockdownd_strerror(ldret));
|
||||
return -1;
|
||||
}
|
||||
lockdownd_client_free(lockdown);
|
||||
idevice_free(device);
|
||||
return 0;
|
||||
}
|
||||
@@ -240,8 +240,8 @@ int reboot_cmd(const char* udid) {
|
||||
if (diagnostics_relay_restart(diag, DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT) != DIAGNOSTICS_RELAY_E_SUCCESS) {
|
||||
LOG(LOG_ERROR, "Could not reboot device.");
|
||||
}
|
||||
diagnostics_relay_goodbye(diag);
|
||||
diagnostics_relay_client_free(diag);
|
||||
(void)diagnostics_relay_goodbye(diag);
|
||||
(void)diagnostics_relay_client_free(diag);
|
||||
} else {
|
||||
LOG(LOG_ERROR, "Could not connect to device.");
|
||||
return -1;
|
||||
@@ -300,9 +300,9 @@ int passstat_cmd(unsigned char* status, const char* udid) {
|
||||
derr = diagnostics_relay_query_mobilegestalt(diagnostics_client, keys, &node);
|
||||
|
||||
plist_free(keys);
|
||||
diagnostics_relay_client_free(diagnostics_client);
|
||||
lockdownd_service_descriptor_free(service);
|
||||
idevice_free(dev);
|
||||
(void)diagnostics_relay_client_free(diagnostics_client);
|
||||
(void)lockdownd_service_descriptor_free(service);
|
||||
(void)idevice_free(dev);
|
||||
|
||||
if (derr != DIAGNOSTICS_RELAY_E_SUCCESS || !node)
|
||||
{
|
||||
@@ -320,7 +320,7 @@ int passstat_cmd(unsigned char* status, const char* udid) {
|
||||
plist_get_string_val(status_node, &passstat_status);
|
||||
if (!status || strncmp(passstat_status, "Succ", 4))
|
||||
{
|
||||
if (passstat_status)
|
||||
if (passstat_status)
|
||||
free(passstat_status);
|
||||
passstat_status = NULL;
|
||||
plist_free(node);
|
||||
@@ -347,20 +347,16 @@ int passstat_cmd(unsigned char* status, const char* udid) {
|
||||
int recvinfo_cmd(recvinfo_t* info, const uint64_t ecid) {
|
||||
irecv_client_t client = NULL;
|
||||
irecv_error_t err = irecv_open_with_ecid(&client, ecid);
|
||||
if (err != IRECV_E_SUCCESS) {
|
||||
LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
int mode = 0;
|
||||
irecv_get_mode(client, &mode);
|
||||
err = irecv_get_mode(client, &mode);
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
char *ibootver = NULL;
|
||||
irecv_getenv(client, "build-version", &ibootver);
|
||||
err = irecv_getenv(client, "build-version", &ibootver);
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
irecv_device_t device;
|
||||
err = irecv_devices_get_device_by_client(client, &device);
|
||||
if (err != IRECV_E_SUCCESS) {
|
||||
LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
info->mode = mode;
|
||||
info->cpid = device->chip_id;
|
||||
snprintf(info->product_type, 0x20, "%s", device->product_type);
|
||||
@@ -369,33 +365,41 @@ int recvinfo_cmd(recvinfo_t* info, const uint64_t ecid) {
|
||||
free(ibootver);
|
||||
irecv_close(client);
|
||||
return 0;
|
||||
err:
|
||||
LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int autoboot_cmd(const uint64_t ecid) {
|
||||
irecv_client_t client = NULL;
|
||||
irecv_error_t err = irecv_open_with_ecid(&client, ecid);
|
||||
if (err == IRECV_E_SUCCESS) {
|
||||
irecv_setenv(client, "auto-boot", "true");
|
||||
irecv_saveenv(client);
|
||||
irecv_close(client);
|
||||
return 0;
|
||||
} else {
|
||||
LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err));
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
err = irecv_setenv(client, "auto-boot", "true");
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
err = irecv_saveenv(client);
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
err = irecv_close(client);
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
return 0;
|
||||
err:
|
||||
LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int exitrecv_cmd(const uint64_t ecid) {
|
||||
irecv_client_t client = NULL;
|
||||
irecv_error_t err = irecv_open_with_ecid(&client, ecid);
|
||||
if (err == IRECV_E_SUCCESS) {
|
||||
irecv_setenv(client, "auto-boot", "true");
|
||||
irecv_saveenv(client);
|
||||
irecv_reboot(client);
|
||||
irecv_close(client);
|
||||
return 0;
|
||||
} else {
|
||||
LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
err = irecv_setenv(client, "auto-boot", "true");
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
err = irecv_saveenv(client);
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
err = irecv_reboot(client);
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
err = irecv_close(client);
|
||||
if (err != IRECV_E_SUCCESS) goto err;
|
||||
return 0;
|
||||
err:
|
||||
LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
+208
-71
@@ -30,22 +30,36 @@
|
||||
#define FORMAT_KEY_VALUE 1
|
||||
#define FORMAT_XML 2
|
||||
|
||||
#define NOHOME (cpid == 0x8015 || (cpid == 0x8010 && (bdid == 0x08 || bdid == 0x0a || bdid == 0x0c || bdid == 0x0e)))
|
||||
#define NO_PHYSICAL_HOME_BUTTON (cpid == 0x8015 || (cpid == 0x8010 && (bdid == 0x08 || bdid == 0x0a || bdid == 0x0c || bdid == 0x0e)))
|
||||
#define IS_APPLE_TV_HD (cpid == 0x7000 && bdid == 0x34)
|
||||
#define IS_APPLE_TV_4K (cpid == 0x8011 && bdid == 0x02)
|
||||
#define IS_APPLE_HOME1 (cpid == 0x7000 && bdid == 0x38)
|
||||
#define IS_APPLE_HOME2 (cpid == 0x7000 && bdid == 0x1a)
|
||||
#define IS_APPLE_HOME (IS_APPLE_HOME1 || IS_APPLE_HOME1)
|
||||
#define IS_APPLETV (IS_APPLE_TV_4K || IS_APPLE_TV_HD || IS_APPLE_HOME)
|
||||
|
||||
int dfuhelper_thr_running = false;
|
||||
|
||||
void step(int time, int time2, char *text, bool (*cond)(uint64_t), uint64_t cond_arg) {
|
||||
static void step(int time, int time2, char *text, bool (*cond)(uint64_t), uint64_t cond_arg) {
|
||||
for (int i = time2; i < time; i++) {
|
||||
printf(CYN "\r\033[K%s (%d)" CRESET, text, time - i + time2);
|
||||
printf(
|
||||
(palerain_flags & palerain_option_no_colors)
|
||||
? "\r\033[K%s (%d)"
|
||||
: BCYN "\r\033[K%s (%d)" CRESET, text, time - i + time2
|
||||
);
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
if (cond != NULL && cond(cond_arg)) pthread_exit(NULL);
|
||||
}
|
||||
printf(CYN "\r%s (%d)" CRESET, text, time2);
|
||||
printf(
|
||||
(palerain_flags & palerain_option_no_colors)
|
||||
? "\r%s (%d)"
|
||||
: CYN "\r%s (%d)" CRESET, text, time2
|
||||
);
|
||||
if (time2 == 0) puts("");
|
||||
}
|
||||
|
||||
int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) {
|
||||
static int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) {
|
||||
devinfo_t dev;
|
||||
int ret;
|
||||
ret = devinfo_cmd(&dev, usbmuxd_device->udid);
|
||||
@@ -56,10 +70,29 @@ int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) {
|
||||
if (strcmp(dev.CPUArchitecture, "arm64")) {
|
||||
devinfo_free(&dev);
|
||||
LOG(LOG_WARNING, "Ignoring non-arm64 device...");
|
||||
LOG(LOG_WARNING, "palera1n doesn't and never will work on A12+ (arm64e)");
|
||||
return -1;
|
||||
}
|
||||
if (!strncmp(dev.productType, "iPhone10,", strlen("iPhone10,"))) {
|
||||
LOG(LOG_VERBOSE2, "Product %s requires passcode to be disabled", dev.productType);
|
||||
|
||||
if ((palerain_flags & palerain_option_device_info)) {
|
||||
printf("Mode: normal\n");
|
||||
printf("ProductType: %s\n", dev.productType);
|
||||
printf("Architecture: %s\n", dev.CPUArchitecture);
|
||||
printf("Version: %s\n", dev.productVersion);
|
||||
printf("DisplayName: %s\n", dev.displayName);
|
||||
|
||||
device_has_booted = true;
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For Booting Linux etc */
|
||||
if (!getenv("PALERA1N_BYPASS_PASSCODE_CHECK") &&
|
||||
!strncmp(dev.productType, "iPhone10,", strlen("iPhone10,")
|
||||
)) {
|
||||
if (!(palerain_flags & palerain_option_device_info))
|
||||
LOG(LOG_VERBOSE2, "Product %s requires passcode to be disabled", dev.productType);
|
||||
unsigned char passcode_state = 0;
|
||||
ret = passstat_cmd(&passcode_state, usbmuxd_device->udid);
|
||||
if (ret != 0) {
|
||||
@@ -69,15 +102,26 @@ int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) {
|
||||
}
|
||||
if (passcode_state) {
|
||||
LOG(LOG_ERROR, "Passcode must be disabled on this device");
|
||||
LOG(LOG_ERROR, "Additionally, passcode must never be set since restore on iOS 16+");
|
||||
if (!(palerain_flags & palerain_option_device_info))
|
||||
LOG(LOG_ERROR, "Additionally, passcode must never be set since a restore on iOS 16+");
|
||||
devinfo_free(&dev);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
LOG(LOG_INFO, "Telling device with udid %s to enter recovery mode immediately", usbmuxd_device->udid);
|
||||
|
||||
if (getenv("PALERA1N_BYPASS_PASSCODE_CHECK"))
|
||||
LOG(LOG_WARNING, "Bypassed passcode check");
|
||||
|
||||
if (verbose > 1) {
|
||||
/* (LOG_VERBOSE - 3) or below*/
|
||||
LOG(LOG_INFO, "Telling device with udid %s to enter recovery mode immediately", usbmuxd_device->udid);
|
||||
} else {
|
||||
/* At least (LOG_VERBOSE2 - 3) */
|
||||
LOG(LOG_INFO, "Entering recovery mode");
|
||||
}
|
||||
enter_recovery_cmd(usbmuxd_device->udid);
|
||||
devinfo_free(&dev);
|
||||
if (checkrain_option_enabled(host_flags, host_option_enter_recovery)) {
|
||||
if ((palerain_flags & palerain_option_enter_recovery)) {
|
||||
device_has_booted = true;
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
@@ -89,50 +133,86 @@ static bool conditional(uint64_t ecid) {
|
||||
return get_ecid_wait_for_dfu() != ecid;
|
||||
}
|
||||
|
||||
void* connected_recovery_mode(struct irecv_device_info* info) {
|
||||
static void* connected_recovery_mode(struct irecv_device_info* info) {
|
||||
int ret;
|
||||
uint64_t ecid;
|
||||
uint32_t cpid, bdid;
|
||||
cpid = info->cpid;
|
||||
ecid = info->ecid;
|
||||
bdid = info->bdid;
|
||||
if (!cpid_is_arm64(info->cpid)) {
|
||||
info = NULL;
|
||||
if (!cpid_is_arm64(cpid)) {
|
||||
LOG(LOG_WARNING, "Ignoring non-arm64 device...");
|
||||
return NULL;
|
||||
}
|
||||
sleep(1);
|
||||
ret = autoboot_cmd(info->ecid);
|
||||
ret = autoboot_cmd(ecid);
|
||||
if (ret) {
|
||||
LOG(LOG_ERROR, "Cannot set auto-boot back to true");
|
||||
return NULL;
|
||||
}
|
||||
#if !defined(DFUHELPER_AUTO_ONLY)
|
||||
if (IS_APPLE_TV_4K) {
|
||||
LOG(LOG_INFO, "Depending on your connection method, you might need to press a button on your cable/board during reboot");
|
||||
}
|
||||
LOG(LOG_INFO, "Press Enter when ready for DFU mode");
|
||||
getchar();
|
||||
step(3, 0, "Get ready", NULL, 0);
|
||||
if (NOHOME)
|
||||
step(4, 2, "Hold volume down + side button", NULL, 0);
|
||||
else
|
||||
step(4, 2, "Hold home + power button", NULL, 0);
|
||||
set_ecid_wait_for_dfu(info->ecid);
|
||||
ret = exitrecv_cmd(info->ecid);
|
||||
info = NULL;
|
||||
if (ret) {
|
||||
LOG(LOG_ERROR, "Cannot exit recovery mode");
|
||||
set_ecid_wait_for_dfu(0);
|
||||
return NULL;
|
||||
#endif
|
||||
if (IS_APPLETV) {
|
||||
if (IS_APPLE_TV_HD) {
|
||||
step(10, 8, "Hold menu + play button", NULL, 0);
|
||||
set_ecid_wait_for_dfu(ecid);
|
||||
ret = exitrecv_cmd(ecid);
|
||||
if (ret) {
|
||||
LOG(LOG_ERROR, "Cannot exit recovery mode");
|
||||
set_ecid_wait_for_dfu(0);
|
||||
return NULL;
|
||||
}
|
||||
printf("\r\033[K");
|
||||
step(8, 0, "Hold menu + play button", conditional, ecid);
|
||||
} else if (IS_APPLE_TV_4K) {
|
||||
step(2, 0, "About to reboot device", NULL, 0);
|
||||
set_ecid_wait_for_dfu(ecid);
|
||||
ret = exitrecv_cmd(ecid);
|
||||
if (ret) {
|
||||
LOG(LOG_ERROR, "Cannot exit recovery mode");
|
||||
set_ecid_wait_for_dfu(0);
|
||||
return NULL;
|
||||
}
|
||||
step(4, 0, "Waiting for device to reconnect in DFU mode", conditional, ecid);
|
||||
} else if (IS_APPLE_HOME) {
|
||||
step(6, 4, "Put device in upside down orientation", NULL, 0);
|
||||
set_ecid_wait_for_dfu(ecid);
|
||||
ret = exitrecv_cmd(ecid);
|
||||
if (ret) {
|
||||
LOG(LOG_ERROR, "Cannot exit recovery mode");
|
||||
set_ecid_wait_for_dfu(0);
|
||||
return NULL;
|
||||
}
|
||||
step(4, 0, "Put device upside down orientation", conditional, ecid);
|
||||
}
|
||||
} else if (cpid != 0x8012) {
|
||||
if (NO_PHYSICAL_HOME_BUTTON)
|
||||
step(4, 2, "Hold volume down + side button", NULL, 0);
|
||||
else
|
||||
step(4, 2, "Hold home + power button", NULL, 0);
|
||||
set_ecid_wait_for_dfu(ecid);
|
||||
ret = exitrecv_cmd(ecid);
|
||||
if (ret) {
|
||||
LOG(LOG_ERROR, "Cannot exit recovery mode");
|
||||
set_ecid_wait_for_dfu(0);
|
||||
return NULL;
|
||||
}
|
||||
printf("\r\033[K");
|
||||
if (NO_PHYSICAL_HOME_BUTTON) {
|
||||
step(2, 0, "Hold volume down + side button", NULL, 0);
|
||||
step(10, 0, "Hold volume down button", conditional, ecid);
|
||||
} else {
|
||||
step(2, 0, "Hold home + power button", NULL, 0);
|
||||
step(10, 0, "Hold home button", conditional, ecid);
|
||||
}
|
||||
}
|
||||
printf("\r\033[K");
|
||||
bool nohome = NOHOME;
|
||||
if (nohome)
|
||||
step(2, 0, "Hold volume down + side button", NULL, 0);
|
||||
else
|
||||
step(2, 0, "Hold home + power Button", NULL, 0);
|
||||
if (nohome)
|
||||
step(10, 0, "Hold volume down button", conditional, ecid);
|
||||
else
|
||||
step(10, 0, "Hold home button", conditional, ecid);
|
||||
if (get_ecid_wait_for_dfu() != ecid) {
|
||||
} else {
|
||||
if (get_ecid_wait_for_dfu() == ecid) {
|
||||
LOG(LOG_WARNING, "Whoops, device did not enter DFU mode");
|
||||
LOG(LOG_INFO, "Waiting for device to reconnect...");
|
||||
set_ecid_wait_for_dfu(0);
|
||||
@@ -143,30 +223,37 @@ void* connected_recovery_mode(struct irecv_device_info* info) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* connected_dfu_mode(struct irecv_device_info* info) {
|
||||
static void* connected_dfu_mode(struct irecv_device_info* info) {
|
||||
if (get_ecid_wait_for_dfu() == info->ecid) {
|
||||
set_ecid_wait_for_dfu(0);
|
||||
puts("");
|
||||
LOG(LOG_INFO, "Device entered DFU mode successfully");
|
||||
}
|
||||
unsigned int bdid = info->bdid;
|
||||
unsigned int cpid = info->cpid;
|
||||
if (IS_APPLE_HOME) {
|
||||
step(2, 0, "Put device in upright orientation", NULL, 0);
|
||||
}
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void device_event_cb(const usbmuxd_event_t *event, void* userdata) {
|
||||
static void device_event_cb(const usbmuxd_event_t *event, void* userdata) {
|
||||
if (event->device.conn_type != CONNECTION_TYPE_USB) return;
|
||||
switch (event->event) {
|
||||
case UE_DEVICE_ADD:
|
||||
LOG(LOG_VERBOSE, "Normal mode device connected");
|
||||
if (checkrain_option_enabled(host_flags, host_option_exit_recovery)) {
|
||||
if ((palerain_flags & palerain_option_exit_recovery)) {
|
||||
break;
|
||||
} else if (checkrain_option_enabled(host_flags, host_option_reboot_device)) {
|
||||
reboot_cmd(event->device.udid);
|
||||
LOG(LOG_INFO, "Restarted device");
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
} else if ((palerain_flags & palerain_option_reboot_device)) {
|
||||
int ret = reboot_cmd(event->device.udid);
|
||||
if (!ret) {
|
||||
LOG(LOG_INFO, "Restarted device");
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
break;
|
||||
}
|
||||
@@ -178,37 +265,87 @@ void device_event_cb(const usbmuxd_event_t *event, void* userdata) {
|
||||
}
|
||||
}
|
||||
|
||||
void irecv_device_event_cb(const irecv_device_event_t *event, void* userdata) {
|
||||
static void irecv_device_event_cb(const irecv_device_event_t *event, void* userdata) {
|
||||
pthread_t recovery_thread, dfu_thread;
|
||||
int ret;
|
||||
|
||||
switch(event->type) {
|
||||
case IRECV_DEVICE_ADD:
|
||||
if (event->mode == IRECV_K_RECOVERY_MODE_1 || event->mode == IRECV_K_RECOVERY_MODE_2 || event->mode == IRECV_K_RECOVERY_MODE_3 || event->mode == IRECV_K_RECOVERY_MODE_4) {
|
||||
LOG(LOG_VERBOSE, "Recovery mode device %ld connected", event->device_info->ecid);
|
||||
if (checkrain_option_enabled(host_flags, host_option_exit_recovery)) {
|
||||
exitrecv_cmd(event->device_info->ecid);
|
||||
LOG(LOG_INFO, "Exited recovery mode");
|
||||
device_has_booted = true;
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread);
|
||||
pthread_exit(NULL);
|
||||
break;
|
||||
}
|
||||
if (checkrain_option_enabled(host_flags, host_option_enter_recovery) ||
|
||||
checkrain_option_enabled(host_flags, host_option_reboot_device)) return;
|
||||
pthread_create(&recovery_thread, NULL, (void* (*)(void*))connected_recovery_mode, event->device_info);
|
||||
} else if (event->mode == IRECV_K_DFU_MODE) {
|
||||
LOG(LOG_VERBOSE, "DFU mode device %ld connected", event->device_info->ecid);
|
||||
if (
|
||||
checkrain_option_enabled(host_flags, host_option_exit_recovery) ||
|
||||
checkrain_option_enabled(host_flags, host_option_enter_recovery) ||
|
||||
checkrain_option_enabled(host_flags, host_option_reboot_device)) {
|
||||
if (event->mode == IRECV_K_RECOVERY_MODE_1 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_2 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_3 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_4) {
|
||||
if (!(palerain_flags & palerain_option_device_info))
|
||||
LOG(LOG_VERBOSE, "Recovery mode device %" PRIu64 " connected", event->device_info->ecid);
|
||||
if ((palerain_flags & palerain_option_exit_recovery)) {
|
||||
ret = exitrecv_cmd(event->device_info->ecid);
|
||||
if (!ret) {
|
||||
LOG(LOG_INFO, "Exited recovery mode");
|
||||
device_has_booted = true;
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
} else {
|
||||
LOG(LOG_WARNING, "Could not exit recovery mode");
|
||||
}
|
||||
if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread);
|
||||
pthread_exit(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((palerain_flags & palerain_option_device_info)) {
|
||||
recvinfo_t info;
|
||||
ret = recvinfo_cmd(&info, event->device_info->ecid);
|
||||
if (ret) {
|
||||
LOG(LOG_WARNING, "Could not get info from device");
|
||||
} else {
|
||||
printf("Mode: Recovery\n");
|
||||
printf("ProductType: %s\n", info.product_type);
|
||||
printf("DisplayName: %s\n", info.display_name);
|
||||
|
||||
device_has_booted = true;
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
}
|
||||
if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread);
|
||||
pthread_exit(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((palerain_flags & palerain_option_enter_recovery) ||
|
||||
(palerain_flags & palerain_option_reboot_device)) return;
|
||||
pthread_create(&recovery_thread, NULL, (pthread_start_t)connected_recovery_mode, event->device_info);
|
||||
} else if (event->mode == IRECV_K_DFU_MODE) {
|
||||
if (!(palerain_flags & palerain_option_device_info))
|
||||
LOG(LOG_VERBOSE, "DFU mode device %" PRIu64 " connected", event->device_info->ecid);
|
||||
|
||||
if ((palerain_flags & palerain_option_device_info)) {
|
||||
recvinfo_t info;
|
||||
ret = recvinfo_cmd(&info, event->device_info->ecid);
|
||||
if (ret) {
|
||||
LOG(LOG_WARNING, "Could not get info from device");
|
||||
} else {
|
||||
printf("Mode: DFU\n");
|
||||
printf("ProductType: %s\n", info.product_type);
|
||||
printf("DisplayName: %s\n", info.display_name);
|
||||
|
||||
device_has_booted = true;
|
||||
set_spin(0);
|
||||
unsubscribe_cmd();
|
||||
}
|
||||
if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread);
|
||||
pthread_exit(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
(palerain_flags & palerain_option_exit_recovery) ||
|
||||
(palerain_flags & palerain_option_enter_recovery) ||
|
||||
(palerain_flags & palerain_option_reboot_device)) {
|
||||
break;
|
||||
}
|
||||
pthread_create(&dfu_thread, NULL, (pthread_start_t)connected_dfu_mode, event->device_info);
|
||||
}
|
||||
pthread_create(&dfu_thread, NULL, (void* (*)(void*))connected_dfu_mode, event->device_info);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case IRECV_DEVICE_REMOVE:
|
||||
LOG(LOG_VERBOSE, "Recovery mode device disconnected");
|
||||
break;
|
||||
@@ -217,8 +354,8 @@ void irecv_device_event_cb(const irecv_device_event_t *event, void* userdata) {
|
||||
|
||||
void *dfuhelper(void* ptr) {
|
||||
dfuhelper_thr_running = true;
|
||||
subscribe_cmd(device_event_cb, irecv_device_event_cb);
|
||||
set_spin(1);
|
||||
subscribe_cmd(device_event_cb, irecv_device_event_cb);
|
||||
while (get_spin()) {
|
||||
sleep(1);
|
||||
};
|
||||
|
||||
+153
-32
@@ -11,63 +11,170 @@
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
extern char* gOverrideLibcheckra1nHelper;
|
||||
|
||||
#include <palerain.h>
|
||||
#ifdef TUI
|
||||
#include <tui.h>
|
||||
#endif
|
||||
#include <xxd-embedded.h>
|
||||
char* pongo_path = NULL;
|
||||
bool external_pongo = false;
|
||||
char* ext_checkra1n = NULL;
|
||||
|
||||
#define tmpdir getenv("TMPDIR") == NULL ? "/tmp" : getenv("TMPDIR")
|
||||
|
||||
int exec_checkra1n() {
|
||||
int exec_checkra1n(void) {
|
||||
LOG(LOG_INFO, "About to execute checkra1n");
|
||||
int fd, ret;
|
||||
int fd_checkra1n, fd_pongo, ret;
|
||||
char* checkra1n_path = NULL;
|
||||
#ifndef NO_CUSTOM_PONGO
|
||||
if (pongo_path == NULL) {
|
||||
pongo_path = malloc(strlen(tmpdir) + 20);
|
||||
if (pongo_path == NULL) {
|
||||
LOG(LOG_FATAL, "memory allocation failed\n");
|
||||
return -1;
|
||||
}
|
||||
snprintf(pongo_path, strlen(tmpdir) + 20, "%s/Pongo.bin.XXXXXX", tmpdir);
|
||||
fd_pongo = mkstemp(pongo_path);
|
||||
if (fd_pongo == -1) {
|
||||
LOG(LOG_FATAL, "Cannot open temporary file %s: %d (%s)", pongo_path, errno, strerror(errno));
|
||||
free(pongo_path);
|
||||
return -1;
|
||||
}
|
||||
ssize_t didWrite_Pongo_bin = write(fd_pongo, Pongo_bin, Pongo_bin_len);
|
||||
if (didWrite_Pongo_bin != (ssize_t)Pongo_bin_len) {
|
||||
LOG(LOG_FATAL, "Size written to %s does not match expected: %zd != %" PRIu32 ": %d (%s)", pongo_path, didWrite_Pongo_bin, Pongo_bin_len, errno, strerror(errno));
|
||||
close(fd_pongo);
|
||||
unlink(pongo_path);
|
||||
free(pongo_path);
|
||||
pongo_path = NULL;
|
||||
return -1;
|
||||
}
|
||||
} else external_pongo = true;
|
||||
#endif
|
||||
if (ext_checkra1n != NULL) {
|
||||
checkra1n_path = ext_checkra1n;
|
||||
goto checkra1n_exec;
|
||||
} else {
|
||||
checkra1n_path = malloc(strlen(tmpdir) + 20);
|
||||
if (checkra1n_path == NULL) {
|
||||
LOG(LOG_FATAL, "memory allocation failed\n");
|
||||
return -1;
|
||||
}
|
||||
snprintf(checkra1n_path, strlen(tmpdir) + 20, "%s/checkra1n.XXXXXX", tmpdir);
|
||||
fd_checkra1n = mkstemp(checkra1n_path);
|
||||
if (fd_checkra1n == -1) {
|
||||
LOG(LOG_FATAL, "Cannot open temporary file %s: %d (%s)", checkra1n_path, errno, strerror(errno));
|
||||
free(checkra1n_path);
|
||||
checkra1n_path = NULL;
|
||||
return -1;
|
||||
}
|
||||
ssize_t didWrite_checkra1n = write(fd_checkra1n, checkra1n, checkra1n_len);
|
||||
if (didWrite_checkra1n != (ssize_t)checkra1n_len) {
|
||||
LOG(LOG_FATAL, "Size written to %s does not match expected: %zd != %" PRIu32 ": %d (%s)", checkra1n_path, didWrite_checkra1n, checkra1n_len, errno, strerror(errno));
|
||||
close(fd_checkra1n);
|
||||
unlink(checkra1n_path);
|
||||
free(checkra1n_path);
|
||||
checkra1n_path = NULL;
|
||||
return -1;
|
||||
}
|
||||
close(fd_checkra1n);
|
||||
ret = chmod(checkra1n_path, 0700);
|
||||
if (ret) {
|
||||
LOG(LOG_FATAL, "Cannot chmod %s: %d (%s)", checkra1n_path, errno, strerror(errno));
|
||||
unlink(checkra1n_path);
|
||||
free(checkra1n_path);
|
||||
checkra1n_path = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
checkra1n_path = malloc(strlen(tmpdir) + 20);
|
||||
snprintf(checkra1n_path, strlen(tmpdir) + 20, "%s/checkra1n.XXXXXX", tmpdir);
|
||||
fd = mkstemp(checkra1n_path);
|
||||
if (fd == -1) {
|
||||
LOG(LOG_FATAL, "Cannot open temporary file: %d (%s)", errno, strerror(errno));
|
||||
return -1;
|
||||
#if defined(__APPLE__) && defined(__arm64__) && (TARGET_OS_IPHONE || defined(FORCE_HELPER))
|
||||
char* libcheckra1nhelper_dylib_path = NULL;
|
||||
{
|
||||
struct utsname name;
|
||||
uname(&name);
|
||||
unsigned long darwinMajor = strtoul(name.release, NULL, 10);
|
||||
assert(darwinMajor != 0);
|
||||
#if !defined(FORCE_HELPER)
|
||||
if (darwinMajor < 20) {
|
||||
#endif
|
||||
if (gOverrideLibcheckra1nHelper) {
|
||||
libcheckra1nhelper_dylib_path = gOverrideLibcheckra1nHelper;
|
||||
goto setenv_ra1n;
|
||||
}
|
||||
libcheckra1nhelper_dylib_path = malloc(strlen(tmpdir) + 40);
|
||||
if (libcheckra1nhelper_dylib_path == NULL) {
|
||||
LOG(LOG_FATAL, "memory allocation failed\n");
|
||||
return -1;
|
||||
}
|
||||
snprintf(libcheckra1nhelper_dylib_path, strlen(tmpdir) + 40, "%s/libcheckra1nhelper.dylib.XXXXXX", tmpdir);
|
||||
int helper_fd = mkstemp(libcheckra1nhelper_dylib_path);
|
||||
if (helper_fd == -1) {
|
||||
LOG(LOG_FATAL, "Cannot open temporary file: %d (%s)", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
ssize_t didWrite_libcheckra1nhelper = write(helper_fd, libcheckra1nhelper_dylib, libcheckra1nhelper_dylib_len);
|
||||
if ((unsigned int)didWrite_libcheckra1nhelper != libcheckra1nhelper_dylib_len) {
|
||||
LOG(LOG_FATAL, "Size written does not match expected: %zd != %" PRIu32 ": %d (%s)", didWrite_libcheckra1nhelper, libcheckra1nhelper_dylib_len, errno, strerror(errno));
|
||||
close(helper_fd);
|
||||
unlink(libcheckra1nhelper_dylib_path);
|
||||
return -1;
|
||||
}
|
||||
close(helper_fd);
|
||||
ret = chmod(libcheckra1nhelper_dylib_path, 0700);
|
||||
if (ret) {
|
||||
LOG(LOG_FATAL, "Cannot chmod %s: %d (%s)", libcheckra1nhelper_dylib_path, errno, strerror(errno));
|
||||
unlink(libcheckra1nhelper_dylib_path);
|
||||
return -1;
|
||||
}
|
||||
setenv_ra1n:
|
||||
setenv("DYLD_INSERT_LIBRARIES", libcheckra1nhelper_dylib_path, 1);
|
||||
#if !defined(FORCE_HELPER)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ssize_t didWrite = write(fd, checkra1n, checkra1n_len);
|
||||
if (didWrite != (ssize_t)checkra1n_len) {
|
||||
LOG(LOG_FATAL, "Size written does not match expected: %lld != %d: %d (%s)", didWrite, checkra1n_len, errno, strerror(errno));
|
||||
close(fd);
|
||||
unlink(checkra1n_path);
|
||||
return -1;
|
||||
#endif
|
||||
char args[0x10] = "-E";
|
||||
if ((palerain_flags & palerain_option_demote)) strncat(args, "d", 0xf);
|
||||
if (!(palerain_flags & palerain_option_checkrain_is_clone)) {
|
||||
strncat(args, "p", 0xf);
|
||||
if (verbose >= 2) strncat(args, "v", 0xf);
|
||||
if ((palerain_flags & palerain_option_no_colors)) strncat(args, "n", 0xf);
|
||||
} else {
|
||||
strncat(args, "R", 0xf);
|
||||
}
|
||||
close(fd);
|
||||
ret = chmod(checkra1n_path, 0700);
|
||||
if (ret) {
|
||||
LOG(LOG_FATAL, "Cannot chmod %s: %d (%s)", checkra1n_path, errno, strerror(errno));
|
||||
unlink(checkra1n_path);
|
||||
return -1;
|
||||
}
|
||||
checkra1n_exec: {};
|
||||
char args[0x10] = "-pE";
|
||||
if (checkrain_option_enabled(host_flags, host_option_demote)) strncat(args, "d", 0xf);
|
||||
if (verbose >= 2) strncat(args, "v", 0xf);
|
||||
if (pongo_path != NULL) strncat(args, "k", 0xf); // keep this at last
|
||||
LOG(LOG_VERBOSE5, args);
|
||||
if (pongo_path != NULL) LOG(LOG_VERBOSE5, pongo_path);
|
||||
pid_t pid;
|
||||
char* checkra1n_argv[] = {
|
||||
posix_spawn_file_actions_t action;
|
||||
posix_spawn_file_actions_init(&action);
|
||||
#ifdef TUI
|
||||
if (tui_is_jailbreaking) {
|
||||
// silence checkra1n
|
||||
posix_spawn_file_actions_addopen(&action, 1, "/dev/null", O_WRONLY, 0);
|
||||
posix_spawn_file_actions_addopen(&action, 2, "/dev/null", O_WRONLY, 0);
|
||||
}
|
||||
#endif
|
||||
ret = posix_spawn(&pid, checkra1n_path, &action, NULL, (char* []){
|
||||
checkra1n_path,
|
||||
args,
|
||||
"-k",
|
||||
pongo_path,
|
||||
NULL
|
||||
};
|
||||
ret = posix_spawn(&pid, checkra1n_path, NULL, NULL, checkra1n_argv, environ);
|
||||
if (pongo_path != NULL) free(pongo_path);
|
||||
pongo_path = NULL;
|
||||
}, environ);
|
||||
posix_spawn_file_actions_destroy(&action);
|
||||
if (ret) {
|
||||
LOG(LOG_FATAL, "Cannot posix spawn %s: %d (%s)", checkra1n_path, errno, strerror(errno));
|
||||
if (ext_checkra1n != NULL) unlink(checkra1n_path);
|
||||
@@ -81,5 +188,19 @@ checkra1n_exec: {};
|
||||
checkra1n_path = NULL;
|
||||
}
|
||||
waitpid(pid, NULL, 0);
|
||||
if (!external_pongo && pongo_path != NULL) {
|
||||
unlink(pongo_path);
|
||||
}
|
||||
if (pongo_path != NULL) free(pongo_path);
|
||||
pongo_path = NULL;
|
||||
#if defined(__APPLE__) && defined(__arm64__) && (TARGET_OS_IPHONE || defined(FORCE_HELPER))
|
||||
if (libcheckra1nhelper_dylib_path != NULL) {
|
||||
if (!gOverrideLibcheckra1nHelper) unlink(libcheckra1nhelper_dylib_path);
|
||||
unsetenv("DYLD_INSERT_LIBRARIES");
|
||||
unsetenv("DYLD_FORCE_FLAT_NAMESPACE");
|
||||
if (!gOverrideLibcheckra1nHelper) free(libcheckra1nhelper_dylib_path);
|
||||
libcheckra1nhelper_dylib_path = NULL;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
+15
-5
@@ -1,13 +1,13 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef NO_KPF
|
||||
unsigned char* checkra1n_kpf_pongo = NULL;
|
||||
unsigned int checkra1n_kpf_pongo_len = 0;
|
||||
unsigned char* checkra1n_kpf_pongo_lzma = NULL;
|
||||
unsigned int checkra1n_kpf_pongo_lzma_len = 0;
|
||||
#endif
|
||||
|
||||
#ifdef NO_RAMDISK
|
||||
unsigned char* ramdisk_dmg = NULL;
|
||||
unsigned int ramdisk_dmg_len = 0;
|
||||
unsigned char* ramdisk_dmg_lzma = NULL;
|
||||
unsigned int ramdisk_dmg_lzma_len = 0;
|
||||
#endif
|
||||
|
||||
#ifdef NO_CHECKRAIN
|
||||
@@ -15,7 +15,17 @@ unsigned char* checkra1n = NULL;
|
||||
unsigned int checkra1n_len = 0;
|
||||
#endif
|
||||
|
||||
#ifdef NO_BINPACK
|
||||
#ifdef NO_OVERLAY
|
||||
unsigned char* binpack_dmg = NULL;
|
||||
unsigned int binpack_dmg_len = 0;
|
||||
#endif
|
||||
|
||||
#ifdef NO_CUSTOM_PONGO
|
||||
unsigned char* Pongo_bin = NULL;
|
||||
unsigned int Pongo_bin_len = 0;
|
||||
#endif
|
||||
|
||||
#ifdef NO_EMBED_HELPER
|
||||
unsigned char* libcheckra1nhelper_dylib = NULL;
|
||||
unsigned int libcheckra1nhelper_dylib_len = 0;
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
*.o
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
.
|
||||
+24
-49
@@ -27,55 +27,46 @@
|
||||
#include <ANSI-color-codes.h>
|
||||
#include <palerain.h>
|
||||
#include <xxd-embedded.h>
|
||||
#include <kerninfo.h>
|
||||
#include <paleinfo.h>
|
||||
|
||||
pthread_mutex_t spin_mutex, found_pongo_mutex, ecid_dfu_wait_mutex;
|
||||
#ifdef DEV_BUILD
|
||||
#include <newt.h>
|
||||
pthread_mutex_t tui_log_mutex;
|
||||
newtComponent tui_log_output = NULL;
|
||||
#endif
|
||||
|
||||
bool spin, found_pongo = 0;
|
||||
uint64_t ecid_wait_for_dfu = 0;
|
||||
|
||||
bool get_spin() {
|
||||
LOG(LOG_VERBOSE5, "locking spin mutex for get");
|
||||
pthread_mutex_lock(&spin_mutex);
|
||||
bool ret = spin;
|
||||
LOG(LOG_VERBOSE5, "UN-locking spin mutex, spin value is %d", spin);
|
||||
pthread_mutex_unlock(&spin_mutex);
|
||||
static bool get_locked_bool(bool* val, pthread_mutex_t* mutex) {
|
||||
// fprintf(stderr, "%s: val = %p mutex = %p\n", __func__, (void*)val, (void*)mutex);
|
||||
pthread_mutex_lock(mutex);
|
||||
bool ret = *val;
|
||||
pthread_mutex_unlock(mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool set_spin(bool val) {
|
||||
LOG(LOG_VERBOSE5, "locking spin mutex for set spin = %d", val);
|
||||
pthread_mutex_lock(&spin_mutex);
|
||||
spin = val;
|
||||
LOG(LOG_VERBOSE5, "UN-locking spin mutex after setting spin\n");
|
||||
pthread_mutex_unlock(&spin_mutex);
|
||||
return val;
|
||||
static bool set_locked_bool(bool* val, bool newval, pthread_mutex_t* mutex) {
|
||||
// fprintf(stderr, "%s: val = %p mutex = %p, newval = %d\n", __func__, (void*)val, (void*)mutex, newval);
|
||||
pthread_mutex_lock(mutex);
|
||||
*val = newval;
|
||||
pthread_mutex_unlock(mutex);
|
||||
return newval;
|
||||
}
|
||||
|
||||
bool get_found_pongo() {
|
||||
LOG(LOG_VERBOSE5, "locking found pongo mutex for get");
|
||||
pthread_mutex_lock(&found_pongo_mutex);
|
||||
bool ret = found_pongo;
|
||||
LOG(LOG_VERBOSE5, "UN-locking pongo mutex, found_pongo value is %d", found_pongo);
|
||||
pthread_mutex_unlock(&found_pongo_mutex);
|
||||
return ret;
|
||||
bool get_spin(void) {
|
||||
return get_locked_bool(&spin, &spin_mutex);
|
||||
}
|
||||
|
||||
bool set_spin(bool newval) {
|
||||
return set_locked_bool(&spin, newval, &spin_mutex);
|
||||
}
|
||||
|
||||
bool get_found_pongo(void) {
|
||||
return get_locked_bool(&found_pongo, &found_pongo_mutex);
|
||||
}
|
||||
|
||||
bool set_found_pongo(bool val) {
|
||||
LOG(LOG_VERBOSE5, "locking found pongo mutex for set found_pongo = %d", val);
|
||||
pthread_mutex_lock(&found_pongo_mutex);
|
||||
found_pongo = val;
|
||||
LOG(LOG_VERBOSE5, "UN-locking pongo mutex after setting found_pongo");
|
||||
pthread_mutex_unlock(&found_pongo_mutex);
|
||||
return val;
|
||||
return set_locked_bool(&found_pongo, val, &found_pongo_mutex);
|
||||
}
|
||||
|
||||
uint64_t get_ecid_wait_for_dfu() {
|
||||
uint64_t get_ecid_wait_for_dfu(void) {
|
||||
LOG(LOG_VERBOSE5, "locking ecid wait for dfu mutex for get");
|
||||
pthread_mutex_lock(&ecid_dfu_wait_mutex);
|
||||
uint64_t ret = ecid_wait_for_dfu;
|
||||
@@ -92,19 +83,3 @@ uint64_t set_ecid_wait_for_dfu(uint64_t ecid) {
|
||||
pthread_mutex_unlock(&ecid_dfu_wait_mutex);
|
||||
return ecid;
|
||||
}
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
newtComponent get_tui_log() {
|
||||
pthread_mutex_lock(&tui_log_mutex);
|
||||
newtComponent ret = tui_log_output;
|
||||
pthread_mutex_unlock(&tui_log_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
newtComponent set_tui_log(newtComponent co) {
|
||||
pthread_mutex_lock(&tui_log_mutex);
|
||||
tui_log_output = co;
|
||||
pthread_mutex_unlock(&tui_log_mutex);
|
||||
return co;
|
||||
}
|
||||
#endif
|
||||
@@ -1,255 +0,0 @@
|
||||
#ifndef HAVE_LIBIMOBILEDEVICE
|
||||
#include "lockdown_helper.h"
|
||||
#include <usbmuxd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define log_debug(...) fprintf(stderr, __VA_ARGS__); fputc('\n', stderr)
|
||||
#else
|
||||
#define log_debug(...)
|
||||
#endif
|
||||
#define log_error(...) fprintf(stderr, __VA_ARGS__); fputc('\n', stderr)
|
||||
|
||||
int lockdown_connect_handle(uint32_t handle)
|
||||
{
|
||||
int fd = usbmuxd_connect(handle, 62078);
|
||||
if (fd < 0) {
|
||||
log_debug("Can't connect to lockownd on device #%u", handle);
|
||||
return fd;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int lockdown_connect_udid(const char* udid)
|
||||
{
|
||||
usbmuxd_device_info_t device;
|
||||
if (usbmuxd_get_device_by_udid(udid, &device) < 0) {
|
||||
log_debug("Can't find device %s", udid);
|
||||
return -ENOENT;
|
||||
}
|
||||
return lockdown_connect_handle(device.handle);
|
||||
}
|
||||
|
||||
void lockdown_disconnect(int fd)
|
||||
{
|
||||
usbmuxd_disconnect(fd);
|
||||
}
|
||||
|
||||
int lockdown_check_type(int fd, const char* type_match);
|
||||
|
||||
static const char QUERY_TYPE_REQUEST[] = "____<plist version=\"1.0\"><dict><key>Label</key><string>palera1n</string><key>Request</key><string>QueryType</string></dict></plist>";
|
||||
static const char GET_VALUE_DOMAIN_REQUEST_FMT[] = "____<plist version=\"1.0\"><dict><key>Label</key><string>palera1n</string><key>Domain</key><string>%s</string><key>Key</key><string>%s</string><key>Request</key><string>GetValue</string></dict></plist>";
|
||||
static const char GET_VALUE_REQUEST_FMT[] = "____<plist version=\"1.0\"><dict><key>Label</key><string>palera1n</string><key>Key</key><string>%s</string><key>Request</key><string>GetValue</string></dict></plist>";
|
||||
static const char VALUE_KEY_NODE[] = "<key>Value</key>";
|
||||
static const char INTEGER_NODE[] = "<integer>";
|
||||
static const char STRING_NODE[] = "<string>";
|
||||
static const char ENTER_RECOVERY_REQUEST[] = "____<plist version=\"1.0\"><dict><key>Label</key><string>palera1n</string><key>Request</key><string>EnterRecovery</string></dict></plist>";
|
||||
static const char ERROR_KEY_NODE[] = "<key>Error</key>";
|
||||
static const char ENTER_RECOVERY_STRING_NODE[] = "<string>EnterRecovery</string>";
|
||||
static const int VALUE_KEY_NODE_SIZE = sizeof(VALUE_KEY_NODE)-1;
|
||||
static const int INTEGER_NODE_SIZE = sizeof(INTEGER_NODE)-1;
|
||||
static const int STRING_NODE_SIZE = sizeof(STRING_NODE)-1;
|
||||
static const int ERROR_KEY_NODE_SIZE = sizeof(ERROR_KEY_NODE)-1;
|
||||
|
||||
static void skip_ws(char** cur, char* end)
|
||||
{
|
||||
char* p = *cur;
|
||||
while (p < end && ((*p == ' ') || (*p == '\t') || (*p == '\r') || (*p == '\n'))) {
|
||||
p++;
|
||||
}
|
||||
*cur = p;
|
||||
}
|
||||
|
||||
static char* _send_request_and_get_reply(int fd, const char* request, uint32_t len, uint32_t* received)
|
||||
{
|
||||
uint32_t sent_bytes = 0;
|
||||
usbmuxd_send(fd, request, len, &sent_bytes);
|
||||
if (sent_bytes != len) {
|
||||
usbmuxd_disconnect(fd);
|
||||
log_error("Failed to send data payload");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t recv_bytes = 0;
|
||||
uint32_t besize = 0;
|
||||
int r = usbmuxd_recv(fd, (char*)&besize, sizeof(besize), &recv_bytes);
|
||||
if (recv_bytes != sizeof(besize)) {
|
||||
usbmuxd_disconnect(fd);
|
||||
log_error("Failed to get size of packet (%d)", r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t resp_size = ntohl(besize);
|
||||
char* resp = (char*)malloc(resp_size+1);
|
||||
|
||||
recv_bytes = 0;
|
||||
usbmuxd_recv(fd, resp, resp_size, &recv_bytes);
|
||||
if (recv_bytes != resp_size) {
|
||||
usbmuxd_disconnect(fd);
|
||||
free(resp);
|
||||
log_error("Failed to receive payload");
|
||||
return NULL;
|
||||
}
|
||||
resp[resp_size] = '\0';
|
||||
*received = resp_size;
|
||||
return resp;
|
||||
}
|
||||
|
||||
int lockdown_check_type(int fd, const char* type_match)
|
||||
{
|
||||
unsigned char tmp[512];
|
||||
uint32_t len = (uint32_t)snprintf((char*)tmp, 512, QUERY_TYPE_REQUEST);
|
||||
uint32_t belen = htonl(len-4);
|
||||
*(uint32_t*)tmp = belen;
|
||||
uint32_t resp_size = 0;
|
||||
char* resp = _send_request_and_get_reply(fd, (char*)tmp, len, &resp_size);
|
||||
if (!resp) {
|
||||
log_error("Failed to get lockdown type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = (strstr(resp, type_match) == NULL) ? -1 : 0;
|
||||
free(resp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int lockdown_get_uint_value(int fd, const char* domain, const char* key, uint64_t* value)
|
||||
{
|
||||
char tmp[1024];
|
||||
uint32_t len;
|
||||
if (domain) {
|
||||
len = snprintf(tmp, 1024, GET_VALUE_DOMAIN_REQUEST_FMT, domain, key);
|
||||
} else {
|
||||
len = snprintf(tmp, 1024, GET_VALUE_REQUEST_FMT, key);
|
||||
}
|
||||
*(uint32_t*)&tmp = htonl(len-4);
|
||||
|
||||
uint32_t resp_size = 0;
|
||||
char* resp = _send_request_and_get_reply(fd, tmp, len, &resp_size);
|
||||
if (!resp) {
|
||||
log_error("Failed to get value for key %s", key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* p = strstr(resp, VALUE_KEY_NODE);
|
||||
if (!p) {
|
||||
log_debug("Failed to get Value key node?!");
|
||||
return -1;
|
||||
}
|
||||
p += VALUE_KEY_NODE_SIZE;
|
||||
skip_ws(&p, resp+resp_size);
|
||||
if (p >= resp+resp_size) {
|
||||
log_debug("Failed to get value node");
|
||||
return -1;
|
||||
}
|
||||
if (strncmp(p, INTEGER_NODE, INTEGER_NODE_SIZE) != 0) {
|
||||
log_debug("Failed to parse value node");
|
||||
return -1;
|
||||
}
|
||||
p += INTEGER_NODE_SIZE;
|
||||
*value = (uint64_t)strtoll(p, NULL, 10);
|
||||
free(resp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lockdown_get_string_value(int fd, const char* domain, const char* key, char** value)
|
||||
{
|
||||
char tmp[1024];
|
||||
uint32_t len;
|
||||
if (domain) {
|
||||
len = snprintf(tmp, 1024, GET_VALUE_DOMAIN_REQUEST_FMT, domain, key);
|
||||
} else {
|
||||
len = snprintf(tmp, 1024, GET_VALUE_REQUEST_FMT, key);
|
||||
}
|
||||
*(uint32_t*)&tmp = htonl(len-4);
|
||||
|
||||
uint32_t resp_size = 0;
|
||||
char* resp = _send_request_and_get_reply(fd, tmp, len, &resp_size);
|
||||
if (!resp) {
|
||||
log_error("Failed to get value for key %s", key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* p = strstr(resp, VALUE_KEY_NODE);
|
||||
if (!p) {
|
||||
log_debug("Failed to get Value key node?!");
|
||||
free(resp);
|
||||
return -1;
|
||||
}
|
||||
p += VALUE_KEY_NODE_SIZE;
|
||||
skip_ws(&p, resp+resp_size);
|
||||
if (p >= resp+resp_size) {
|
||||
log_debug("Failed to get value node");
|
||||
free(resp);
|
||||
return -1;
|
||||
}
|
||||
if (strncmp(p, STRING_NODE, STRING_NODE_SIZE) != 0) {
|
||||
log_debug("Failed to parse value node");
|
||||
free(resp);
|
||||
return -1;
|
||||
}
|
||||
p += STRING_NODE_SIZE;
|
||||
char* str_start = p;
|
||||
while (*p != '<' && *p != '\0') p++;
|
||||
if (*p == '\0') {
|
||||
log_debug("Failed to parse string value node");
|
||||
free(resp);
|
||||
return -1;
|
||||
}
|
||||
size_t str_len = p - str_start;
|
||||
*value = (char*)malloc(str_len + 1);
|
||||
snprintf(*value, str_len, "%s", str_start);
|
||||
(*value)[str_len] = '\0';
|
||||
free(resp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lockdown_enter_recovery(int fd)
|
||||
{
|
||||
char tmp[512];
|
||||
uint32_t len = (uint32_t)snprintf(tmp, 512, ENTER_RECOVERY_REQUEST);
|
||||
*(uint32_t*)&tmp = htonl(len-4);
|
||||
uint32_t resp_size = 0;
|
||||
char* resp = _send_request_and_get_reply(fd, tmp, len, &resp_size);
|
||||
if (!resp) {
|
||||
log_error("Failed to enter recover?");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = -1;
|
||||
char* p = strstr(resp, ERROR_KEY_NODE);
|
||||
if (p) {
|
||||
char* str_start = NULL;
|
||||
size_t str_len = 0;
|
||||
p += ERROR_KEY_NODE_SIZE;
|
||||
skip_ws(&p, resp+resp_size);
|
||||
if (*p && !strncmp(p, STRING_NODE, STRING_NODE_SIZE)) {
|
||||
p += STRING_NODE_SIZE;
|
||||
str_start = p;
|
||||
while (*p != '<' && *p != '\0') p++;
|
||||
if (*p == '<') {
|
||||
str_len = p - str_start;
|
||||
}
|
||||
}
|
||||
if (str_start && str_len > 0) {
|
||||
log_error("ERROR: Failed to make device enter recovery mode: %.*s", (int)str_len, str_start);
|
||||
} else {
|
||||
log_error("ERROR: Failed to make device enter recovery mode: (unknown error)");
|
||||
}
|
||||
result = -2;
|
||||
} else {
|
||||
result = (strstr(resp, ENTER_RECOVERY_STRING_NODE) == NULL) ? -1 : 0;
|
||||
}
|
||||
free(resp);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
#ifndef __LOCKDOWN_HELPER_H
|
||||
#define __LOCKDOWN_HELPER_H
|
||||
|
||||
#ifndef HAVE_LIBIMOBILEDEVICE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int lockdown_connect_udid(const char* udid);
|
||||
int lockdown_connect_handle(uint32_t handle);
|
||||
|
||||
void lockdown_disconnect(int fd);
|
||||
|
||||
int lockdown_check_type(int fd, const char* type_match);
|
||||
|
||||
int lockdown_get_uint_value(int fd, const char* domain, const char* key, uint64_t* value);
|
||||
int lockdown_get_string_value(int fd, const char* domain, const char* key, char** value);
|
||||
|
||||
int lockdown_enter_recovery(int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -8,11 +8,18 @@
|
||||
#include <ANSI-color-codes.h>
|
||||
#include <palerain.h>
|
||||
|
||||
int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxname, char *__restrict format, ...)
|
||||
#ifdef TUI
|
||||
#include <tui.h>
|
||||
#endif
|
||||
|
||||
int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxname, const char *__restrict format, ...)
|
||||
{
|
||||
#ifdef TUI
|
||||
if (tui_started) return 0;
|
||||
#endif
|
||||
if (verbose >= 5
|
||||
#ifdef DEV_BUILD
|
||||
&& !checkrain_option_enabled(host_flags, host_option_tui)
|
||||
#ifdef TUI
|
||||
&& !(palerain_flags & palerain_option_tui)
|
||||
#endif
|
||||
) fprintf(stderr, "p1_log: loglevel %d from %s:%d:%s()\n", loglevel, fname, lineno, fxname);
|
||||
int ret = 0;
|
||||
@@ -23,7 +30,7 @@ int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxna
|
||||
va_start(args, format);
|
||||
if (verbose < (loglevel - 3) && loglevel > LOG_INFO) {
|
||||
if (verbose >= 5
|
||||
#ifdef DEV_BUILD
|
||||
#ifdef TUI
|
||||
&& !tui_started
|
||||
#endif
|
||||
) fprintf(stderr, "p1_log: hid log with high log level (%d < %d)\n", verbose, loglevel - 3);
|
||||
@@ -57,38 +64,41 @@ int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxna
|
||||
snprintf(colour_bold, 0x10, "%s", BWHT);
|
||||
break;
|
||||
}
|
||||
#ifdef DEV_BUILD
|
||||
if (checkrain_option_enabled(host_flags, host_option_tui) && tui_started) {
|
||||
newtComponent co = get_tui_log();
|
||||
if (co == NULL) {
|
||||
return 0; /* 0 bytes printed */
|
||||
}
|
||||
char printbuf[0x200];
|
||||
ret = vsnprintf(printbuf, 0x200, format, args);
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
newtTextboxSetText(co, printbuf);
|
||||
} else
|
||||
#endif
|
||||
if ((palerain_flags & palerain_option_no_colors)) {
|
||||
colour[0] = '\0';
|
||||
colour_bold[0] = '\0';
|
||||
}
|
||||
{
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
char timestring[0x80];
|
||||
time_t curtime;
|
||||
time(&curtime);
|
||||
struct tm* timeinfo = localtime(&curtime);
|
||||
snprintf(timestring, 0x80, "%s[%s%02d/%02d/%d %02d:%02d:%02d%s]", CRESET, HBLK, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_year - 100, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, CRESET);
|
||||
if (verbose >= 2) {
|
||||
if (!(palerain_flags & palerain_option_no_colors))
|
||||
snprintf(timestring, 0x80, "%s[%s%02d/%02d/%d %02d:%02d:%02d%s]", CRESET, HBLK, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_year - 100, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, CRESET);
|
||||
else
|
||||
snprintf(timestring, 0x80, "[%02d/%02d/%d %02d:%02d:%02d]", timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_year - 100, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
||||
if (verbose >= 2 && !(palerain_flags & palerain_option_no_colors)) {
|
||||
printf("%s| - %s%s <%s> " CRESET "%s" HBLU "%s" CRESET ":" BLU "%d" CRESET ":" BMAG "%s()" CRESET ": \n%s| ----> ", colour_bold, timestring, colour_bold, type, WHT, fname, lineno, fxname, colour_bold);
|
||||
} else {
|
||||
} else if (!(palerain_flags & palerain_option_no_colors)) {
|
||||
printf(" - %s %s<%s>%s: ", timestring, colour_bold, type, CRESET);
|
||||
} else if (verbose >= 2 && (palerain_flags & palerain_option_no_colors)) {
|
||||
printf("%s| - %s%s <%s> %s:%d:%s(): \n%s| ----> ", colour_bold, timestring, colour_bold, type, fname, lineno, fxname, colour_bold);
|
||||
} else if ((palerain_flags & palerain_option_no_colors)) {
|
||||
printf(" - %s %s<%s>: ", timestring, colour_bold, type);
|
||||
}
|
||||
printf("%s", colour);
|
||||
ret = vprintf(format, args);
|
||||
va_end(args);
|
||||
|
||||
if (verbose < 2)
|
||||
if (verbose < 2 && !(palerain_flags & palerain_option_no_colors))
|
||||
printf(CRESET "\n");
|
||||
else
|
||||
else if (!(palerain_flags & palerain_option_no_colors))
|
||||
printf("\n%s-%s\n", colour, CRESET);
|
||||
else if (verbose < 2)
|
||||
printf("\n");
|
||||
else
|
||||
printf("\n%s-\n", colour);
|
||||
fflush(stdout);
|
||||
}
|
||||
pthread_mutex_unlock(&log_mutex);
|
||||
|
||||
+68
-58
@@ -7,6 +7,7 @@
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
@@ -16,7 +17,6 @@
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/mman.h>
|
||||
@@ -27,18 +27,19 @@
|
||||
#include <ANSI-color-codes.h>
|
||||
#include <palerain.h>
|
||||
#include <xxd-embedded.h>
|
||||
#include <kerninfo.h>
|
||||
#include <paleinfo.h>
|
||||
|
||||
#define CMD_LEN_MAX 512
|
||||
#define OVERRIDE_MAGIC 0xd803b376
|
||||
|
||||
unsigned int verbose = 0;
|
||||
char xargs_cmd[0x270] = "xargs ", checkrain_flags_cmd[0x20] = "deadbeef", palerain_flags_cmd[0x20] = "deadbeef";
|
||||
char kpf_flags_cmd[0x20] = "deadbeef", dtpatch_cmd[0x20] = "deadbeef", rootfs_cmd[512] = "deadbeef";
|
||||
/* we want to write to them so don't use string literals */
|
||||
char xargs_cmd[0x270] = { 'x', 'a', 'r', 'g', 's', '\0' },
|
||||
palerain_flags_cmd[0x30] = { 'd', 'e', 'a', 'd', 'b', 'e', 'e', 'f', '\0' };
|
||||
extern char** environ;
|
||||
|
||||
niarelap_file_t* kpf_to_upload_1 = &checkra1n_kpf_pongo;
|
||||
niarelap_file_t* ramdisk_to_upload_1 = &ramdisk_dmg;
|
||||
niarelap_file_t* kpf_to_upload_1 = &checkra1n_kpf_pongo_lzma;
|
||||
niarelap_file_t* ramdisk_to_upload_1 = &ramdisk_dmg_lzma;
|
||||
niarelap_file_t* overlay_to_upload_1 = &binpack_dmg;
|
||||
|
||||
niarelap_file_t** kpf_to_upload = &kpf_to_upload_1;
|
||||
@@ -47,7 +48,7 @@ niarelap_file_t** overlay_to_upload = &overlay_to_upload_1;
|
||||
|
||||
override_file_t override_ramdisk, override_kpf, override_overlay;
|
||||
|
||||
uint32_t checkrain_flags = 0, palerain_flags = 0, kpf_flags = 0;
|
||||
uint64_t palerain_flags = 0;
|
||||
|
||||
pthread_mutex_t log_mutex;
|
||||
pthread_t dfuhelper_thread, pongo_thread;
|
||||
@@ -56,9 +57,9 @@ void thr_cleanup(void* ptr) {
|
||||
*(int*)ptr = 0;
|
||||
}
|
||||
|
||||
int build_checks() {
|
||||
#if defined(__APPLE__)
|
||||
static int build_checks(void) {
|
||||
#ifndef NO_CHECKRAIN
|
||||
#if defined(__APPLE__)
|
||||
struct mach_header_64* c1_header = (struct mach_header_64*)&checkra1n[0];
|
||||
if (c1_header->magic != MH_MAGIC_64 && c1_header->magic != MH_CIGAM_64) {
|
||||
LOG(LOG_FATAL, "Broken build: checkra1n is not a thin Mach-O");
|
||||
@@ -69,59 +70,89 @@ int build_checks() {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NO_KPF
|
||||
struct mach_header_64 *kpf_hdr = (struct mach_header_64 *)checkra1n_kpf_pongo;
|
||||
if (kpf_hdr->magic != MH_MAGIC_64 && kpf_hdr->magic != MH_CIGAM_64) {
|
||||
LOG(LOG_FATAL, "Broken build: Invalid kernel patchfinder: Not thin 64-bit Mach-O");
|
||||
return -1;
|
||||
} else
|
||||
if (kpf_hdr->filetype != MH_KEXT_BUNDLE) {
|
||||
LOG(LOG_FATAL, "Broken build: Invalid kernel patchfinder: Not a kext bundle");
|
||||
return -1;
|
||||
} else if (kpf_hdr->cputype != CPU_TYPE_ARM64) {
|
||||
LOG(LOG_FATAL, "Broken build: Invalid kernel patchfinder: CPU type is not arm64");
|
||||
return -1;
|
||||
if (checkra1n_len <= (UCHAR_MAX + 1)) {
|
||||
LOG(LOG_FATAL, "checkra1n too small");
|
||||
}
|
||||
if (boyermoore_horspool_memmem(&checkra1n[0], checkra1n_len, (const unsigned char *)"[ra1npoc15-part] thanks to", strlen("[ra1npoc15-part] thanks to")) != NULL) {
|
||||
palerain_flags |= palerain_option_checkrain_is_clone;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
#ifdef TUI
|
||||
bool tui_started = false;
|
||||
#endif
|
||||
|
||||
int palera1n(int argc, char *argv[]) {
|
||||
#ifdef USE_LIBUSB
|
||||
void log_cb(libusb_context *ctx, enum libusb_log_level level, const char *str) {
|
||||
LOG(level + 0, str);
|
||||
}
|
||||
#endif
|
||||
|
||||
// save argc, argv, and envp for restarting
|
||||
|
||||
int saved_argc;
|
||||
char** saved_argv;
|
||||
char** saved_envp;
|
||||
|
||||
static int palera1n(int argc, char *argv[], char *envp[]) {
|
||||
saved_argc = argc;
|
||||
saved_argv = argv;
|
||||
saved_envp = envp;
|
||||
|
||||
print_credits();
|
||||
int ret = 0;
|
||||
pthread_mutex_init(&log_mutex, NULL);
|
||||
pthread_mutex_init(&spin_mutex, NULL);
|
||||
pthread_mutex_init(&found_pongo_mutex, NULL);
|
||||
pthread_mutex_init(&ecid_dfu_wait_mutex, NULL);
|
||||
if ((ret = build_checks())) return ret;
|
||||
print_credits();
|
||||
if ((ret = optparse(argc, argv))) goto cleanup;
|
||||
if (checkrain_option_enabled(host_flags, host_option_palerain_version)) goto normal_exit;
|
||||
#ifdef DEV_BUILD
|
||||
if (checkrain_option_enabled(host_flags, host_option_tui)) {
|
||||
if (!(palerain_flags & palerain_option_device_info) && (palerain_flags & palerain_option_palerain_version)) goto normal_exit;
|
||||
#ifdef TUI
|
||||
if ((palerain_flags & palerain_option_tui) || (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO) && !(palerain_flags & palerain_option_cli))) {
|
||||
ret = tui();
|
||||
if (ret) goto cleanup;
|
||||
else goto normal_exit;
|
||||
}
|
||||
#endif
|
||||
LOG(LOG_INFO, "Waiting for devices");
|
||||
#ifdef USE_LIBUSB
|
||||
{
|
||||
libusb_set_log_cb(NULL, log_cb, LIBUSB_LOG_CB_GLOBAL);
|
||||
libusb_context* ctx = NULL;
|
||||
int test_libusb = libusb_init(&ctx);
|
||||
if (test_libusb) {
|
||||
LOG(LOG_ERROR, "cannot initialize libusb: %d (%s)\n", test_libusb, libusb_strerror(test_libusb));
|
||||
libusb_exit(ctx);
|
||||
goto cleanup;
|
||||
}
|
||||
libusb_exit(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(palerain_flags & palerain_option_device_info))
|
||||
LOG(LOG_INFO, "Waiting for devices");
|
||||
|
||||
if (getenv("USBMUXD_SOCKET_ADDRESS") == NULL && access("/var/run/usbmuxd", F_OK) != 0)
|
||||
LOG(LOG_WARNING, "/var/run/usbmuxd not found, normal mode device detection will not work.");
|
||||
|
||||
pthread_create(&pongo_thread, NULL, pongo_helper, NULL);
|
||||
pthread_create(&dfuhelper_thread, NULL, dfuhelper, NULL);
|
||||
pthread_join(dfuhelper_thread, NULL);
|
||||
set_spin(0);
|
||||
if (checkrain_option_enabled(host_flags, host_option_dfuhelper_only) ||
|
||||
checkrain_option_enabled(host_flags, host_option_reboot_device) ||
|
||||
checkrain_option_enabled(host_flags, host_option_exit_recovery) ||
|
||||
checkrain_option_enabled(host_flags, host_option_enter_recovery) ||
|
||||
device_has_booted)
|
||||
if ((palerain_flags & (palerain_option_dfuhelper_only |
|
||||
palerain_option_reboot_device |
|
||||
palerain_option_exit_recovery |
|
||||
palerain_option_enter_recovery |
|
||||
palerain_option_device_info)
|
||||
) || device_has_booted)
|
||||
goto normal_exit;
|
||||
pthread_cancel(pongo_thread);
|
||||
pthread_join(pongo_thread, NULL);
|
||||
if (exec_checkra1n()) goto cleanup;
|
||||
|
||||
if (checkrain_option_enabled(host_flags, host_option_pongo_exit) || checkrain_option_enabled(host_flags, host_option_demote))
|
||||
if ((palerain_flags & (palerain_option_pongo_exit | palerain_option_demote)))
|
||||
goto normal_exit;
|
||||
set_spin(1);
|
||||
sleep(2);
|
||||
@@ -132,27 +163,6 @@ int palera1n(int argc, char *argv[]) {
|
||||
sleep(1);
|
||||
}
|
||||
normal_exit:
|
||||
if (access("/usr/bin/curl", F_OK) == 0 && !checkrain_option_enabled(host_flags, host_option_no_ohio)) {
|
||||
LOG(LOG_VERBOSE4, "Ohio");
|
||||
char* ohio_argv[] = {
|
||||
"/usr/bin/curl",
|
||||
"-sX",
|
||||
"POST",
|
||||
"-d",
|
||||
"{\"app_name\": \"palera1n_c-rewrite\"}",
|
||||
"-H",
|
||||
"Content-Type: application/json",
|
||||
"-H",
|
||||
"User-Agent: python-requests/99 palera1n-c-rewrite/0",
|
||||
"-o",
|
||||
"/dev/null",
|
||||
"https://ohio.itsnebula.net/hit",
|
||||
NULL
|
||||
};
|
||||
pid_t pid;
|
||||
posix_spawn(&pid, ohio_argv[0], NULL, NULL, ohio_argv, environ);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (override_kpf.magic == OVERRIDE_MAGIC) {
|
||||
munmap(override_kpf.ptr, (size_t)override_kpf.len);
|
||||
@@ -175,6 +185,6 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
return palera1n(argc, argv);
|
||||
int main (int argc, char* argv[], char* envp[]) {
|
||||
return palera1n(argc, argv, envp);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
*.o
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
.
|
||||
+204
-73
@@ -9,15 +9,22 @@
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <palerain.h>
|
||||
#include <sys/mman.h>
|
||||
#include <inttypes.h>
|
||||
#ifdef TUI
|
||||
#include <tui.h>
|
||||
#endif
|
||||
|
||||
checkrain_option_t host_flags = 0;
|
||||
checkrain_option_p host_flags_p = &host_flags;
|
||||
uint64_t* palerain_flags_p = &palerain_flags;
|
||||
char* gOverrideLibcheckra1nHelper = NULL;
|
||||
|
||||
static struct option longopts[] = {
|
||||
{"setup-partial-fakefs", no_argument, NULL, 'B'},
|
||||
{"setup-fakefs", no_argument, NULL, 'c'},
|
||||
{"setup-fakefs-forced", no_argument, NULL, 'C'},
|
||||
{"clean-fakefs", no_argument, NULL, 'C'},
|
||||
{"dfuhelper", no_argument, NULL, 'D'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"pongo-shell", no_argument, NULL, 'p'},
|
||||
@@ -27,72 +34,93 @@ static struct option longopts[] = {
|
||||
{"boot-args", required_argument, NULL, 'e'},
|
||||
{"fakefs", no_argument, NULL, 'f'},
|
||||
{"rootless", no_argument, NULL, 'l'},
|
||||
{"jbinit-log-to-file", no_argument, NULL, 'L'},
|
||||
{"demote", no_argument, NULL, 'd'},
|
||||
{"force-revert", no_argument, NULL, palerain_option_case_force_revert},
|
||||
{"no-colors", no_argument, NULL, 'S'},
|
||||
{"safe-mode", no_argument, NULL, 's'},
|
||||
{"telnetd", no_argument, NULL, 'T'},
|
||||
{"version", no_argument, NULL, palerain_option_case_version},
|
||||
{"override-libcheckra1nhelper", required_argument, NULL, palerain_option_case_libcheckra1nhelper_path},
|
||||
{"override-pongo", required_argument, NULL, 'k'},
|
||||
{"override-overlay", required_argument, NULL, 'o'},
|
||||
{"override-ramdisk", required_argument, NULL, 'r'},
|
||||
{"override-kpf", required_argument, NULL, 'K'},
|
||||
{"disable-ohio", no_argument, NULL, 'O'},
|
||||
{"override-checkra1n", required_argument, NULL, 'i'},
|
||||
{"reboot-device", no_argument, NULL, 'R'},
|
||||
{"exit-recovery", no_argument, NULL, 'n'},
|
||||
{"enter-recovery", no_argument, NULL, 'E'},
|
||||
{"device-info", no_argument, NULL, 'I'},
|
||||
#ifdef DEV_BUILD
|
||||
{"test1", no_argument, NULL, '1'},
|
||||
{"test2", no_argument, NULL, '2'},
|
||||
#endif
|
||||
#ifdef TUI
|
||||
{"tui", no_argument, NULL, 't'},
|
||||
#endif
|
||||
{"cli", no_argument, NULL, palerain_option_case_cli},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
static int usage(int e, char* prog_name)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-"
|
||||
"DEhpvVldsSTLRnPI"
|
||||
#ifdef DEV_BUILD
|
||||
"Usage: %s [-12cCdDEfhlLnOpRstvV]"
|
||||
#else
|
||||
"Usage: %s [-cCdDEfhlLnOpRsvV]"
|
||||
"12"
|
||||
#endif
|
||||
" [-e boot arguments] [-k Pongo image] [-o overlay file] [-r ramdisk file] [-K KPF file] [-i checkra1n file]\n"
|
||||
"Copyright (C) 2023, palera1n team, All Rights Reserved.\n\n"
|
||||
"iOS/iPadOS 15+ arm64 jailbreaking tool\n\n"
|
||||
#ifdef ROOTFUL
|
||||
"cCfB"
|
||||
#endif
|
||||
#ifdef TUI
|
||||
"t"
|
||||
#endif
|
||||
"] [-e boot arguments] [-k Pongo image] [-o overlay file] [-r ramdisk file] [-K KPF file] [-i checkra1n file]\n"
|
||||
"Copyright (C) 2024, palera1n team, All Rights Reserved.\n\n"
|
||||
"iOS/iPadOS/tvOS 15.0-26.0, bridgeOS 5.0-10.0 arm64 jailbreaking tool\n\n"
|
||||
"\t--version\t\t\t\tPrint version\n"
|
||||
"\t--force-revert\t\t\t\tRemove jailbreak\n"
|
||||
#ifdef DEV_BUILD
|
||||
"\t-1, --test1\t\t\t\tSet palerain_option_test1\n"
|
||||
"\t-2, --test2\t\t\t\tSet palerain_option_test2\n"
|
||||
#endif
|
||||
#ifdef ROOTFUL
|
||||
"\t-B, --setup-partial-fakefs\t\tSetup partial fakefs\n"
|
||||
"\t-c, --setup-fakefs\t\t\tSetup fakefs\n"
|
||||
"\t-C, --setup-fakefs-forced\t\tSetup fakefs and overwrite any existing ones\n"
|
||||
"\t-C, --clean-fakefs\t\t\tClean fakefs\n"
|
||||
#endif
|
||||
"\t-d, --demote\t\t\t\tDemote\n"
|
||||
"\t-D, --dfuhelper-only\t\t\tExit after entering DFU\n"
|
||||
"\t-D, --dfuhelper\t\t\t\tExit after entering DFU\n"
|
||||
"\t-e, --boot-args <boot arguments>\tXNU boot arguments\n"
|
||||
"\t-E, --enter-recovery\t\t\tEnter recovery mode\n"
|
||||
#ifdef ROOTFUL
|
||||
"\t-f, --fakefs \t\t\t\tBoots fakefs\n"
|
||||
#endif
|
||||
"\t-h, --help\t\t\t\tShow this help\n"
|
||||
"\t-i, --override-checkra1n <file>\t\tOverride checkra1n\n"
|
||||
"\t-k, --override-pongo <file>\t\tOverride Pongo image\n"
|
||||
"\t-K, --override-kpf <file>\t\tOverride kernel patchfinder\n"
|
||||
#ifdef ROOTFUL
|
||||
"\t-l, --rootless\t\t\t\tBoots rootless. This is the default\n"
|
||||
#endif
|
||||
"\t-L, --jbinit-log-to-file\t\tMake jbinit log to /cores/jbinit.log (can be read from sandbox while jailbroken)\n"
|
||||
"\t-n, --exit-recovery\t\t\tExit recovery mode\n"
|
||||
"\t-I, --device-info\t\t\tPrint info about the connected device\n"
|
||||
"\t-o, --override-overlay <file>\t\tOverride overlay\n"
|
||||
"\t-O, --disable-ohio\t\t\tDisable Ohio\n"
|
||||
"\t-p, --pongo-shell\t\t\tBoots to PongoOS shell\n"
|
||||
"\t-P, --pongo-full\t\t\tBoots to a PongoOS shell with default images already uploaded\n"
|
||||
"\t-r, --override-ramdisk <file>\t\tOverride ramdisk\n"
|
||||
"\t-R, --reboot-device\t\t\tReboot connected device in normal mode\n"
|
||||
"\t-s, --safe-mode\t\t\t\tEnter safe mode\n"
|
||||
"\t-S, --no-colors\t\t\t\tDisable colors on the command line\n"
|
||||
"\t-T, --telnetd\t\t\t\tEnable TELNET daemon on port 46 (insecure)\n"
|
||||
"\t-v, --debug-logging\t\t\tEnable debug logging\n"
|
||||
"\t\tThis option can be repeated for extra verbosity.\n"
|
||||
"\t-V, --verbose-boot\t\t\tVerbose boot\n"
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
"\t-t, --tui\t\t\t\tTerminal user interface\n"
|
||||
#ifdef TUI
|
||||
"\t-t, --tui\t\t\t\tForce interactive TUI\n"
|
||||
"\t--cli\t\t\t\t\tForce cli mode\n"
|
||||
#endif
|
||||
"\nEnvironmental variables:\n"
|
||||
"\tTMPDIR\t\ttemporary diretory (path the built-in checkra1n will be extracted to)\n"
|
||||
@@ -104,32 +132,37 @@ static int usage(int e, char* prog_name)
|
||||
int optparse(int argc, char* argv[]) {
|
||||
int opt;
|
||||
int index;
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
"DEhpvVlLdsSTtRnPIe:o:r:K:k:i:"
|
||||
#ifdef DEV_BUILD
|
||||
"12cCDEhpvVldsOLftRnPe:o:r:K:k:i:",
|
||||
#else
|
||||
"cCDEhpvVldsOLfRnPe:o:r:K:k:i:",
|
||||
"12"
|
||||
#endif
|
||||
longopts, NULL)) != -1)
|
||||
#ifdef ROOTFUL
|
||||
"fCcB"
|
||||
#endif
|
||||
,longopts, NULL)) != -1)
|
||||
{
|
||||
switch (opt) {
|
||||
#ifdef ROOTFUL
|
||||
case 'B':
|
||||
palerain_flags |= palerain_option_setup_partial_root;
|
||||
palerain_flags |= palerain_option_setup_rootful;
|
||||
break;
|
||||
case 'c':
|
||||
palerain_flags |= palerain_option_setup_rootful;
|
||||
kpf_flags |= checkrain_option_verbose_boot;
|
||||
break;
|
||||
case 'C':
|
||||
palerain_flags |= palerain_option_setup_rootful;
|
||||
palerain_flags |= palerain_option_setup_rootful_forced;
|
||||
kpf_flags |= checkrain_option_verbose_boot;
|
||||
palerain_flags |= palerain_option_clean_fakefs;
|
||||
break;
|
||||
#endif
|
||||
case 'p':
|
||||
host_flags |= host_option_pongo_exit;
|
||||
palerain_flags |= palerain_option_pongo_exit;
|
||||
break;
|
||||
case 'P':
|
||||
host_flags |= host_option_pongo_full;
|
||||
palerain_flags |= palerain_option_pongo_full;
|
||||
break;
|
||||
case 'D':
|
||||
host_flags |= host_option_dfuhelper_only;
|
||||
palerain_flags |= palerain_option_dfuhelper_only;
|
||||
break;
|
||||
case 'h':
|
||||
usage(0, argv[0]);
|
||||
@@ -138,37 +171,48 @@ int optparse(int argc, char* argv[]) {
|
||||
verbose++;
|
||||
break;
|
||||
case 'V':
|
||||
kpf_flags |= checkrain_option_verbose_boot;
|
||||
palerain_flags |= palerain_option_verbose_boot;
|
||||
#ifdef TUI
|
||||
tui_options_verbose_boot = true;
|
||||
#endif
|
||||
break;
|
||||
case 'e':
|
||||
if (strstr(optarg, "rootdev=") != NULL) {
|
||||
LOG(LOG_FATAL, "The boot arg rootdev= is already used by palera1n and cannot be overriden");
|
||||
return -1;
|
||||
} else if (strlen(optarg) > (sizeof(xargs_cmd) - 0x20)) {
|
||||
if (strlen(optarg) > (sizeof(xargs_cmd) - 0x20)) {
|
||||
LOG(LOG_FATAL, "Boot arguments too long");
|
||||
return -1;
|
||||
}
|
||||
snprintf(xargs_cmd, sizeof(xargs_cmd), "xargs %s", optarg);
|
||||
#ifdef TUI
|
||||
snprintf(tui_options_boot_args, sizeof(tui_options_boot_args), "%s", optarg);
|
||||
#endif
|
||||
break;
|
||||
#ifdef ROOTFUL
|
||||
case 'f':
|
||||
snprintf(rootfs_cmd, sizeof(rootfs_cmd), "rootfs %s", optarg);
|
||||
snprintf(dtpatch_cmd, 0x20, "dtpatch %s", optarg);
|
||||
palerain_flags |= palerain_option_rootful;
|
||||
palerain_flags &= ~palerain_option_rootless;
|
||||
break;
|
||||
#endif
|
||||
case 'l':
|
||||
palerain_flags &= ~palerain_option_rootful;
|
||||
palerain_flags |= palerain_option_rootless;
|
||||
break;
|
||||
case 'L':
|
||||
palerain_flags |= palerain_option_jbinit_log_to_file;
|
||||
break;
|
||||
case 'd':
|
||||
host_flags |= host_option_demote;
|
||||
palerain_flags |= palerain_option_demote;
|
||||
break;
|
||||
case 'E':
|
||||
host_flags |= host_option_enter_recovery;
|
||||
palerain_flags |= palerain_option_enter_recovery;
|
||||
break;
|
||||
case 's':
|
||||
checkrain_flags |= checkrain_option_safemode;
|
||||
palerain_flags |= palerain_option_safemode;
|
||||
#ifdef TUI
|
||||
tui_options_safe_mode = true;
|
||||
#endif
|
||||
break;
|
||||
case 'T':
|
||||
palerain_flags |= palerain_option_telnetd;
|
||||
break;
|
||||
case 'k':
|
||||
if (access(optarg, F_OK) != 0) {
|
||||
@@ -176,18 +220,22 @@ int optparse(int argc, char* argv[]) {
|
||||
return -1;
|
||||
}
|
||||
pongo_path = malloc(strlen(optarg) + 1);
|
||||
strcpy(pongo_path, optarg);
|
||||
if (pongo_path == NULL) {
|
||||
LOG(LOG_FATAL, "memory allocation failed");
|
||||
return -1;
|
||||
}
|
||||
snprintf(pongo_path, strlen(optarg) + 1, "%s", optarg);
|
||||
break;
|
||||
case 'o':
|
||||
if (override_file(&override_overlay, overlay_to_upload, &binpack_dmg_len, optarg))
|
||||
return 1;
|
||||
break;
|
||||
case 'r':
|
||||
if (override_file(&override_ramdisk, ramdisk_to_upload, &ramdisk_dmg_len, optarg))
|
||||
if (override_file(&override_ramdisk, ramdisk_to_upload, &ramdisk_dmg_lzma_len, optarg))
|
||||
return 1;
|
||||
break;
|
||||
case 'K':
|
||||
if (override_file(&override_kpf, kpf_to_upload, &checkra1n_kpf_pongo_len, optarg))
|
||||
if (override_file(&override_kpf, kpf_to_upload, &checkra1n_kpf_pongo_lzma_len, optarg))
|
||||
return 1;
|
||||
struct mach_header_64* hdr = (struct mach_header_64*)override_kpf.ptr;
|
||||
if (hdr->magic != MH_MAGIC_64 && hdr->magic != MH_CIGAM_64) {
|
||||
@@ -209,23 +257,60 @@ int optparse(int argc, char* argv[]) {
|
||||
} else if (!(st.st_mode & S_IXUSR) && !(st.st_mode & S_IXGRP) && !(st.st_mode & S_IXOTH)) {
|
||||
LOG(LOG_FATAL, "%s is not executable", optarg);
|
||||
return -1;
|
||||
};
|
||||
} else if (!S_ISREG(st.st_mode)) {
|
||||
LOG(LOG_FATAL, "%s is not a regular file", optarg);
|
||||
return -1;
|
||||
}
|
||||
if (st.st_size < (UCHAR_MAX+1)) {
|
||||
LOG(LOG_FATAL, "%s too small", optarg);
|
||||
return -1;
|
||||
}
|
||||
int checkra1n_fd = open(optarg, O_RDONLY);
|
||||
if (checkra1n_fd == -1) {
|
||||
LOG(LOG_FATAL, "Cannot open %s: %d (%s)", optarg, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
void* addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, checkra1n_fd, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
LOG(LOG_ERROR, "Failed to map file %s: %d (%s)", optarg, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (boyermoore_horspool_memmem(addr, st.st_size, (const unsigned char*)"[ra1npoc15-part] thanks to", strlen("[ra1npoc15-part] thanks to")) != NULL)
|
||||
{
|
||||
palerain_flags |= palerain_option_checkrain_is_clone;
|
||||
LOG(LOG_VERBOSE3, "%s is checkra1n clone", optarg);
|
||||
}
|
||||
else
|
||||
{
|
||||
palerain_flags &= ~palerain_option_checkrain_is_clone;
|
||||
LOG(LOG_VERBOSE3, "%s is checkra1n", optarg);
|
||||
}
|
||||
munmap(addr, st.st_size);
|
||||
close(checkra1n_fd);
|
||||
ext_checkra1n = calloc(1, strlen(optarg) + 1);
|
||||
snprintf(ext_checkra1n, strlen(optarg) + 1, "%s", optarg);
|
||||
break;
|
||||
case 'R':
|
||||
host_flags |= host_option_reboot_device;
|
||||
palerain_flags |= palerain_option_reboot_device;
|
||||
break;
|
||||
case 'n':
|
||||
host_flags |= host_option_exit_recovery;
|
||||
palerain_flags |= palerain_option_exit_recovery;
|
||||
break;
|
||||
case 'O':
|
||||
host_flags |= host_option_no_ohio;
|
||||
case 'I':
|
||||
palerain_flags |= palerain_option_device_info;
|
||||
break;
|
||||
case 'S':
|
||||
palerain_flags |= palerain_option_no_colors;
|
||||
break;
|
||||
#ifdef TUI
|
||||
case 't':
|
||||
palerain_flags |= palerain_option_tui;
|
||||
break;
|
||||
#endif
|
||||
case palerain_option_case_cli:
|
||||
palerain_flags |= palerain_option_cli;
|
||||
break;
|
||||
#ifdef DEV_BUILD
|
||||
case 't':
|
||||
host_flags |= host_option_tui;
|
||||
break;
|
||||
case '1':
|
||||
palerain_flags |= palerain_option_test1;
|
||||
break;
|
||||
@@ -234,56 +319,93 @@ int optparse(int argc, char* argv[]) {
|
||||
break;
|
||||
#endif
|
||||
case palerain_option_case_force_revert:
|
||||
checkrain_flags |= checkrain_option_force_revert;
|
||||
palerain_flags |= palerain_option_force_revert;
|
||||
#ifdef TUI
|
||||
tui_options_force_revert = true;
|
||||
#endif
|
||||
break;
|
||||
case palerain_option_case_version:
|
||||
host_flags |= host_option_palerain_version;
|
||||
palerain_flags |= palerain_option_palerain_version;
|
||||
break;
|
||||
case palerain_option_case_libcheckra1nhelper_path:
|
||||
printf("meow\n");
|
||||
gOverrideLibcheckra1nHelper = calloc(1, strlen(optarg) + 1);
|
||||
if (!gOverrideLibcheckra1nHelper) {
|
||||
return -1;
|
||||
}
|
||||
snprintf(gOverrideLibcheckra1nHelper, strlen(optarg) + 1, "%s", optarg);
|
||||
break;
|
||||
default:
|
||||
usage(1, argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checkrain_option_enabled(host_flags, host_option_palerain_version)) {
|
||||
printf("palera1n version " PALERAIN_VERSION ": " BUILD_DATE "; " BUILD_WHOAMI ":" BUILD_TAG "/" BUILD_STYLE "\n");
|
||||
if ((palerain_flags & palerain_option_palerain_version)) {
|
||||
printf(
|
||||
"palera1n " PALERAIN_VERSION "\n"
|
||||
BUILD_COMMIT " " BUILD_NUMBER " (" BUILD_BRANCH ")\n\n"
|
||||
"Build style: " BUILD_STYLE "\n"
|
||||
"Build tag: " BUILD_TAG "\n"
|
||||
#ifdef USE_LIBUSB
|
||||
"USB backend: libusb\n"
|
||||
#else
|
||||
"USB backend: IOKit\n"
|
||||
#endif
|
||||
"Build options: " BUILD_OPTIONS "\n"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (checkrain_option_enabled(checkrain_flags, checkrain_option_force_revert) && checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful)) {
|
||||
LOG(LOG_WARNING, "force revert and setup rootful requested at the same time, behaviour here is undefined");
|
||||
if (palerain_flags & palerain_option_telnetd) {
|
||||
LOG(LOG_WARNING, "telnetd is enabled, this is a security hole");
|
||||
}
|
||||
|
||||
snprintf(checkrain_flags_cmd, 0x20, "checkra1n_flags 0x%x", checkrain_flags);
|
||||
snprintf(palerain_flags_cmd, 0x20, "palera1n_flags 0x%x", palerain_flags);
|
||||
snprintf(kpf_flags_cmd, 0x20, "kpf_flags 0x%x", kpf_flags);
|
||||
LOG(LOG_VERBOSE3, "checkrain_flags: %s", checkrain_flags_cmd);
|
||||
if ((palerain_flags & (palerain_option_tui)) && (palerain_flags & (palerain_option_cli))) {
|
||||
LOG(LOG_FATAL, "cannot specify both --tui and --cli");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((palerain_flags & (palerain_option_exit_recovery | palerain_option_enter_recovery | palerain_option_reboot_device | palerain_option_device_info | palerain_option_dfuhelper_only | palerain_option_pongo_exit | palerain_option_pongo_full)) > 0) {
|
||||
palerain_flags &= ~palerain_option_tui;
|
||||
palerain_flags |= palerain_option_cli;
|
||||
} else {
|
||||
#ifdef ROOTFUL
|
||||
if ((palerain_flags & (palerain_option_rootless | palerain_option_rootful)) == 0) {
|
||||
LOG(LOG_FATAL, "Please specify rootful (-f) or rootless (-l)");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
palerain_flags |= palerain_option_rootless;
|
||||
#endif
|
||||
}
|
||||
|
||||
snprintf(palerain_flags_cmd, 0x30, "palera1n_flags 0x%" PRIx64, palerain_flags);
|
||||
LOG(LOG_VERBOSE3, "palerain_flags: %s", palerain_flags_cmd);
|
||||
LOG(LOG_VERBOSE3, "kpf_flags: %s", kpf_flags_cmd);
|
||||
LOG(LOG_VERBOSE3, "host_flags: 0x%x", host_flags);
|
||||
if (override_kpf.magic == OVERRIDE_MAGIC) {
|
||||
LOG(LOG_VERBOSE4, "kpf override length %u -> %u", override_kpf.orig_len, checkra1n_kpf_pongo_len);
|
||||
LOG(LOG_VERBOSE4, "kpf override length %" PRIu32 " -> %" PRIu32, override_kpf.orig_len, checkra1n_kpf_pongo_lzma_len);
|
||||
LOG(LOG_VERBOSE4, "kpf override ptr %p -> %p", override_kpf.orig_ptr, **kpf_to_upload);
|
||||
}
|
||||
if (override_ramdisk.magic == OVERRIDE_MAGIC) {
|
||||
LOG(LOG_VERBOSE4, "ramdisk override length %u -> %u", override_ramdisk.orig_len, ramdisk_dmg_len);
|
||||
LOG(LOG_VERBOSE4, "ramdisk override length %" PRIu32 " -> %" PRIu32, override_ramdisk.orig_len, ramdisk_dmg_lzma_len);
|
||||
LOG(LOG_VERBOSE4, "ramdisk override ptr %p -> %p", override_ramdisk.orig_ptr, **ramdisk_to_upload);
|
||||
}
|
||||
if (override_overlay.magic == OVERRIDE_MAGIC) {
|
||||
LOG(LOG_VERBOSE4, "overlay override length %u -> %u", override_overlay.orig_len, binpack_dmg_len);
|
||||
LOG(LOG_VERBOSE4, "overlay override length %" PRIu32 " -> %" PRIu32, override_overlay.orig_len, binpack_dmg_len);
|
||||
LOG(LOG_VERBOSE4, "overlay override ptr %p -> %p", override_overlay.orig_ptr, **overlay_to_upload);
|
||||
}
|
||||
|
||||
if (!checkrain_option_enabled(palerain_flags, palerain_option_rootful)) {
|
||||
if (checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful) || checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful_forced)) {
|
||||
#ifdef ROOTFUL
|
||||
if (!(palerain_flags & palerain_option_rootful)) {
|
||||
if ((palerain_flags & palerain_option_setup_rootful)) {
|
||||
LOG(LOG_FATAL, "Cannot setup rootful when rootless is requested. Use -f to enable rootful mode.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!(
|
||||
checkrain_option_enabled(host_flags, host_option_dfuhelper_only) ||
|
||||
checkrain_option_enabled(host_flags, host_option_enter_recovery) ||
|
||||
checkrain_option_enabled(host_flags, host_option_exit_recovery) ||
|
||||
checkrain_option_enabled(host_flags, host_option_reboot_device)))
|
||||
(palerain_flags & palerain_option_dfuhelper_only) ||
|
||||
(palerain_flags & palerain_option_enter_recovery) ||
|
||||
(palerain_flags & palerain_option_exit_recovery) ||
|
||||
(palerain_flags & palerain_option_reboot_device)))
|
||||
{
|
||||
#ifdef NO_CHECKRAIN
|
||||
if (checkra1n_len == 0 && ext_checkra1n == NULL)
|
||||
@@ -291,10 +413,10 @@ int optparse(int argc, char* argv[]) {
|
||||
LOG(LOG_FATAL, "checkra1n omitted in build but no override specified");
|
||||
return -1;
|
||||
}
|
||||
if (!(checkrain_option_enabled(host_flags, host_option_pongo_exit) || checkrain_option_enabled(host_flags, host_option_pongo_exit)))
|
||||
if (!((palerain_flags & palerain_option_pongo_exit) || (palerain_flags & palerain_option_pongo_exit)))
|
||||
{
|
||||
#ifdef NO_KPF
|
||||
if (checkra1n_kpf_pongo_len == 0)
|
||||
if (checkra1n_kpf_pongo_lzma_len == 0)
|
||||
{
|
||||
LOG(LOG_FATAL, "kernel patchfinder omitted in build but no override specified");
|
||||
return -1;
|
||||
@@ -302,6 +424,13 @@ int optparse(int argc, char* argv[]) {
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NO_EMBED_HELPER
|
||||
if (libcheckra1nhelper_dylib_len == 0 && gOverrideLibcheckra1nHelper == NULL) {
|
||||
LOG(LOG_FATAL, "checkra1n helper omitted in build but no override specified");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (index = optind; index < argc; index++)
|
||||
@@ -320,8 +449,10 @@ int optparse(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
if (verbose >= 2) setenv("LIBUSB_DEBUG", "1", 1);
|
||||
|
||||
if (verbose >= 3)
|
||||
{
|
||||
libusbmuxd_set_debug_level(verbose - 2);
|
||||
irecv_set_debug_level(1);
|
||||
setenv("LIBUSB_DEBUG", "2", 1);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
int override_file(override_file_t *finfo, niarelap_file_t** orig, unsigned int *orig_len, char *filename) {
|
||||
int ret = 0;
|
||||
int fd = open(filename, O_RDONLY);
|
||||
|
||||
+114
-29
@@ -11,12 +11,20 @@
|
||||
#include <sys/stat.h> // fstst
|
||||
|
||||
#include <palerain.h>
|
||||
#ifdef TUI
|
||||
#include <tui.h>
|
||||
#endif
|
||||
#include <ANSI-color-codes.h>
|
||||
|
||||
bool device_has_booted = 0;
|
||||
int pongo_thr_running = 0;
|
||||
|
||||
#define ERR(...) LOG(LOG_VERBOSE, __VA_ARGS__)
|
||||
|
||||
static int issue_pongo_command(usb_device_handle_t, char*);
|
||||
static int upload_pongo_file(usb_device_handle_t, unsigned char*, unsigned int);
|
||||
static void write_stdout(char *buf, uint32_t len);
|
||||
|
||||
void* pongo_helper(void* ptr) {
|
||||
pongo_thr_running = 1;
|
||||
pthread_cleanup_push(thr_cleanup, &pongo_thr_running);
|
||||
@@ -28,57 +36,120 @@ void* pongo_helper(void* ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *pongo_usb_callback(void *arg) {
|
||||
static void *pongo_usb_callback(stuff_t *arg) {
|
||||
if (get_found_pongo())
|
||||
return NULL;
|
||||
set_found_pongo(1);
|
||||
if (checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful)) {
|
||||
#ifdef ROOTFUL
|
||||
if ((palerain_flags & palerain_option_setup_rootful)) {
|
||||
strncat(xargs_cmd, " wdt=-1", 0x270 - strlen(xargs_cmd) - 1);
|
||||
}
|
||||
#endif
|
||||
LOG(LOG_INFO, "Found PongoOS USB Device");
|
||||
usb_device_handle_t handle = *(usb_device_handle_t *)arg;
|
||||
if (palerain_flags & palerain_option_pongo_exit)
|
||||
goto done;
|
||||
|
||||
usb_device_handle_t handle = arg->handle;
|
||||
#ifdef TUI
|
||||
if (tui_is_jailbreaking) {
|
||||
tui_jailbreak_stage = 4;
|
||||
tui_jailbreak_status = "Sending PongoOS commands";
|
||||
tui_jailbreak_status_changed();
|
||||
}
|
||||
#endif
|
||||
issue_pongo_command(handle, NULL);
|
||||
issue_pongo_command(handle, "fuse lock");
|
||||
issue_pongo_command(handle, "sep auto");
|
||||
upload_pongo_file(handle, **kpf_to_upload, checkra1n_kpf_pongo_len);
|
||||
issue_pongo_command(handle, "modload");
|
||||
issue_pongo_command(handle, kpf_flags_cmd);
|
||||
issue_pongo_command(handle, checkrain_flags_cmd);
|
||||
issue_pongo_command(handle, palerain_flags_cmd);
|
||||
if (checkrain_option_enabled(palerain_flags, palerain_option_rootful))
|
||||
{
|
||||
issue_pongo_command(handle, "rootfs");
|
||||
#ifdef TUI
|
||||
if (tui_is_jailbreaking) {
|
||||
tui_jailbreak_stage = 5;
|
||||
tui_jailbreak_status = "Sending KPF";
|
||||
tui_jailbreak_status_changed();
|
||||
}
|
||||
#endif
|
||||
upload_pongo_file(handle, **kpf_to_upload, checkra1n_kpf_pongo_lzma_len);
|
||||
if (*kpf_to_upload == &checkra1n_kpf_pongo_lzma) {
|
||||
issue_pongo_command(handle, "modload " KPF_UNCOMPRESSED_SIZE);
|
||||
} else {
|
||||
issue_pongo_command(handle, "modload");
|
||||
}
|
||||
issue_pongo_command(handle, palerain_flags_cmd);
|
||||
#ifdef NO_RAMDISK
|
||||
if (ramdisk_dmg_len != 0)
|
||||
if (ramdisk_dmg_lzma_len != 0)
|
||||
#endif
|
||||
{
|
||||
strncat(xargs_cmd, " rootdev=md0", 0x270 - strlen(xargs_cmd) - 1);
|
||||
upload_pongo_file(handle, **ramdisk_to_upload, ramdisk_dmg_len);
|
||||
issue_pongo_command(handle, "ramdisk");
|
||||
#ifdef TUI
|
||||
if (tui_is_jailbreaking) {
|
||||
tui_jailbreak_stage = 6;
|
||||
tui_jailbreak_status = "Sending ramdisk";
|
||||
tui_jailbreak_status_changed();
|
||||
}
|
||||
#endif
|
||||
upload_pongo_file(handle, **ramdisk_to_upload, ramdisk_dmg_lzma_len);
|
||||
if ((*ramdisk_to_upload) == &ramdisk_dmg_lzma)
|
||||
issue_pongo_command(handle, "ramdisk " RAMDISK_UNCOMPRESSED_SIZE);
|
||||
else {
|
||||
issue_pongo_command(handle, "ramdisk");
|
||||
}
|
||||
}
|
||||
#ifdef NO_BINPACK
|
||||
#ifdef NO_OVERLAY
|
||||
if (binpack_dmg_len != 0)
|
||||
#endif
|
||||
{
|
||||
#ifdef TUI
|
||||
if (tui_is_jailbreaking) {
|
||||
tui_jailbreak_stage = 7;
|
||||
tui_jailbreak_status = "Sending binpack";
|
||||
tui_jailbreak_status_changed();
|
||||
}
|
||||
#endif
|
||||
upload_pongo_file(handle, **overlay_to_upload, binpack_dmg_len);
|
||||
issue_pongo_command(handle, "overlay");
|
||||
}
|
||||
issue_pongo_command(handle, xargs_cmd);
|
||||
if (checkrain_option_enabled(host_flags, host_option_pongo_full)) goto done;
|
||||
if ((palerain_flags & palerain_option_pongo_full)) goto done;
|
||||
|
||||
#ifdef TUI
|
||||
if (tui_is_jailbreaking) {
|
||||
tui_jailbreak_stage = 8;
|
||||
tui_jailbreak_status = "Booting";
|
||||
tui_jailbreak_status_changed();
|
||||
}
|
||||
#endif
|
||||
issue_pongo_command(handle, "bootx");
|
||||
LOG(LOG_INFO, "Booting Kernel...");
|
||||
#ifdef ROOTFUL
|
||||
if ((palerain_flags & palerain_option_setup_partial_root)) {
|
||||
LOG(LOG_INFO, "Please wait up to 5 minutes for the bindfs to be created.");
|
||||
LOG(LOG_INFO, "Once the device reboots into recovery mode, run again without the -B (Create BindFS) option to jailbreak.");
|
||||
} else if ((palerain_flags & palerain_option_setup_rootful)) {
|
||||
LOG(LOG_INFO, "Please wait up to 10 minutes for the fakefs to be created.");
|
||||
LOG(LOG_INFO, "Once the device reboots into recovery mode, run again without the -c (Create FakeFS) option to jailbreak.");
|
||||
}
|
||||
#endif
|
||||
if (dfuhelper_thr_running) {
|
||||
pthread_cancel(dfuhelper_thread);
|
||||
dfuhelper_thr_running = false;
|
||||
}
|
||||
done:
|
||||
device_has_booted = true;
|
||||
|
||||
#ifdef TUI
|
||||
if (tui_is_jailbreaking) {
|
||||
tui_jailbreak_stage = 9;
|
||||
tui_jailbreak_status = "All Done";
|
||||
tui_is_jailbreaking = false;
|
||||
tui_jailbreak_status_changed();
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LIBUSB
|
||||
libusb_unref_device(arg->dev);
|
||||
#endif
|
||||
set_spin(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int issue_pongo_command(usb_device_handle_t handle, char *command)
|
||||
static int issue_pongo_command(usb_device_handle_t handle, char *command)
|
||||
{
|
||||
uint32_t outpos = 0;
|
||||
uint32_t outlen = 0;
|
||||
@@ -129,10 +200,10 @@ fetch_output:
|
||||
bad:
|
||||
if (ret != USB_RET_SUCCESS)
|
||||
{
|
||||
if (ret == USB_RET_NOT_RESPONDING)
|
||||
return 0;
|
||||
if (command != NULL && (!strncmp("boot", command, 4) && ret == USB_RET_IO))
|
||||
return 0;
|
||||
if (command != NULL && (!strncmp("boot", command, 4))) {
|
||||
if (ret == USB_RET_IO || ret == USB_RET_NO_DEVICE || ret == USB_RET_NOT_RESPONDING)
|
||||
return 0;
|
||||
}
|
||||
LOG(LOG_ERROR, "USB error: %s", usb_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
@@ -140,7 +211,7 @@ bad:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int upload_pongo_file(usb_device_handle_t handle, unsigned char *buf, unsigned int buf_len)
|
||||
static int upload_pongo_file(usb_device_handle_t handle, unsigned char *buf, unsigned int buf_len)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = USBControlTransfer(handle, 0x21, 1, 0, 0, 4, &buf_len, NULL);
|
||||
@@ -149,19 +220,28 @@ int upload_pongo_file(usb_device_handle_t handle, unsigned char *buf, unsigned i
|
||||
ret = USBBulkUpload(handle, buf, buf_len);
|
||||
if (ret == USB_RET_SUCCESS)
|
||||
{
|
||||
LOG(LOG_VERBOSE, "Uploaded %llu bytes to PongoOS", (unsigned long long)buf_len);
|
||||
if (verbose < 3 || verbose > 4) {
|
||||
LOG(LOG_VERBOSE, "Uploaded %llu bytes to PongoOS", (unsigned long long)buf_len);
|
||||
} else {
|
||||
if ((palerain_flags & palerain_option_no_colors))
|
||||
printf("/send mem:%p:%p\nUploaded %llu bytes]\n", (void*)buf, (void*)(buf + buf_len), (unsigned long long)buf_len);
|
||||
else
|
||||
printf("/send mem:%p:%p\n" BCYN "[Uploaded %llu bytes]\n" CRESET, (void*)buf, (void*)(buf + buf_len), (unsigned long long)buf_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (verbose >= 3) printf("pongoOS> ");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void io_start(stuff_t *stuff)
|
||||
{
|
||||
int r = pthread_create(&stuff->th, NULL, &pongo_usb_callback, &stuff->handle);
|
||||
int r = pthread_create(&stuff->th, NULL, (pthread_start_t)pongo_usb_callback, stuff);
|
||||
if(r != 0)
|
||||
{
|
||||
ERR("pthread_create: %s", strerror(r));
|
||||
exit(-1); // TODO: ok with libusb?
|
||||
set_spin(0);
|
||||
return;
|
||||
}
|
||||
pthread_join(stuff->th, NULL);
|
||||
}
|
||||
@@ -172,17 +252,22 @@ void io_stop(stuff_t *stuff)
|
||||
if(r != 0)
|
||||
{
|
||||
ERR("pthread_cancel: %s", strerror(r));
|
||||
exit(-1); // TODO: ok with libusb?
|
||||
set_spin(0);
|
||||
return;
|
||||
}
|
||||
r = pthread_join(stuff->th, NULL);
|
||||
if(r != 0)
|
||||
{
|
||||
ERR("pthread_join: %s", strerror(r));
|
||||
exit(-1); // TODO: ok with libusb?
|
||||
set_spin(0);
|
||||
return;
|
||||
}
|
||||
#ifdef USE_LIBUSB
|
||||
libusb_unref_device(stuff->dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
void write_stdout(char *buf, uint32_t len)
|
||||
static void write_stdout(char *buf, uint32_t len)
|
||||
{
|
||||
while(len > 0) {
|
||||
if (verbose >= 3) {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -0,0 +1,220 @@
|
||||
#ifdef TUI
|
||||
|
||||
#include <palerain.h>
|
||||
#include <tui.h>
|
||||
|
||||
static irecv_device_t tui_get_recovery_device(uint64_t ecid) {
|
||||
irecv_client_t client = NULL;
|
||||
for (int i = 0; i <= 5; i++) {
|
||||
irecv_error_t err = irecv_open_with_ecid(&client, ecid);
|
||||
if (err == IRECV_E_UNSUPPORTED) {
|
||||
return NULL;
|
||||
}
|
||||
else if (err != IRECV_E_SUCCESS)
|
||||
sleep(1);
|
||||
else
|
||||
break;
|
||||
|
||||
if (i == 5) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
irecv_device_t device = NULL;
|
||||
irecv_devices_get_device_by_client(client, &device);
|
||||
irecv_close(client);
|
||||
return device;
|
||||
}
|
||||
|
||||
struct tui_connected_device *tui_connected_devices = NULL;
|
||||
|
||||
static void* tui_connected_recovery_mode(struct irecv_device_info* info) {
|
||||
//printf("Recovery mode device %" PRIu64 " connected\n", info->ecid);
|
||||
tui_last_event = TUI_EVENT_CONNECTED_DEVICES_CHANGED;
|
||||
sem_post(tui_event_semaphore);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* tui_disconnected_recovery_mode(struct irecv_device_info* info) {
|
||||
//printf("Recovery mode device %" PRIu64 " disconnected\n", info->ecid);
|
||||
tui_last_event = TUI_EVENT_CONNECTED_DEVICES_CHANGED;
|
||||
sem_post(tui_event_semaphore);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* tui_connected_dfu_mode(struct irecv_device_info* info) {
|
||||
//printf("DFU mode device %" PRIu64 " connected\n", info->ecid);
|
||||
tui_last_event = TUI_EVENT_CONNECTED_DEVICES_CHANGED;
|
||||
sem_post(tui_event_semaphore);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* tui_disconnected_dfu_mode(struct irecv_device_info* info) {
|
||||
//printf("DFU mode device %" PRIu64 " disconnected\n", info->ecid);
|
||||
tui_last_event = TUI_EVENT_CONNECTED_DEVICES_CHANGED;
|
||||
sem_post(tui_event_semaphore);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int tui_connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) {
|
||||
struct tui_connected_device *tui_dev = malloc(sizeof(struct tui_connected_device));
|
||||
strcpy(tui_dev->udid, usbmuxd_device->udid);
|
||||
tui_dev->next = tui_connected_devices;
|
||||
tui_dev->mode = TUI_DEVICE_MODE_NORMAL;
|
||||
tui_connected_devices = tui_dev;
|
||||
devinfo_t dev;
|
||||
int ret;
|
||||
ret = devinfo_cmd(&dev, usbmuxd_device->udid);
|
||||
if (ret != 0) {
|
||||
LOG(LOG_ERROR, "Unable to get device information");
|
||||
free(tui_dev);
|
||||
return 0;
|
||||
}
|
||||
snprintf(tui_dev->product_type, sizeof(tui_dev->product_type), "%s", dev.productType);
|
||||
snprintf(tui_dev->display_name, sizeof(tui_dev->display_name), "%s", dev.displayName);
|
||||
tui_dev->ecid = dev.ecid;
|
||||
if (strncmp(dev.CPUArchitecture, "arm64", strlen("arm64"))) {
|
||||
tui_dev->arm64 = false;
|
||||
} else {
|
||||
tui_dev->arm64 = true;
|
||||
}
|
||||
sprintf(tui_dev->version, "%s", dev.productVersion);
|
||||
if (!strncmp(dev.productType, "iPhone10,", strlen("iPhone10,"))) {
|
||||
tui_dev->requires_passcode_disabled = true;
|
||||
unsigned char passcode_state = 0;
|
||||
ret = passstat_cmd(&passcode_state, usbmuxd_device->udid);
|
||||
if (ret != 0) {
|
||||
LOG(LOG_ERROR, "Failed to get passcode state");
|
||||
devinfo_free(&dev);
|
||||
free(tui_dev);
|
||||
return -1;
|
||||
}
|
||||
tui_dev->passcode_state = passcode_state;
|
||||
}
|
||||
|
||||
//enter_recovery_cmd(usbmuxd_device->udid);
|
||||
devinfo_free(&dev);
|
||||
|
||||
tui_last_event = TUI_EVENT_CONNECTED_DEVICES_CHANGED;
|
||||
sem_post(tui_event_semaphore);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tui_disconnected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) {
|
||||
struct tui_connected_device *cur = tui_connected_devices;
|
||||
struct tui_connected_device *prev = NULL;
|
||||
while (cur) {
|
||||
if (!strcmp(cur->udid, usbmuxd_device->udid)) {
|
||||
if (prev) {
|
||||
prev->next = cur->next;
|
||||
} else {
|
||||
tui_connected_devices = cur->next;
|
||||
}
|
||||
free(cur);
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
tui_last_event = TUI_EVENT_CONNECTED_DEVICES_CHANGED;
|
||||
sem_post(tui_event_semaphore);
|
||||
}
|
||||
|
||||
static void tui_device_event_cb(const usbmuxd_event_t *event, void* userdata) {
|
||||
if (event->device.conn_type != CONNECTION_TYPE_USB) return;
|
||||
switch (event->event) {
|
||||
case UE_DEVICE_ADD:
|
||||
LOG(LOG_VERBOSE, "Normal mode device connected");
|
||||
tui_connected_normal_mode(&event->device);
|
||||
break;
|
||||
case UE_DEVICE_REMOVE:
|
||||
LOG(LOG_VERBOSE, "Normal mode device disconnected");
|
||||
tui_disconnected_normal_mode(&event->device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void tui_irecv_device_event_cb(const irecv_device_event_t *event, void* userdata) {
|
||||
pthread_t recovery_thread, dfu_thread;
|
||||
int ret;
|
||||
|
||||
switch(event->type) {
|
||||
case IRECV_DEVICE_ADD: {
|
||||
struct tui_connected_device *dev = malloc(sizeof(struct tui_connected_device));
|
||||
dev->ecid = event->device_info->ecid;
|
||||
dev->next = tui_connected_devices;
|
||||
dev->arm64 = cpid_is_arm64(event->device_info->cpid);
|
||||
/*recvinfo_t info;
|
||||
ret = recvinfo_cmd(&info, event->device_info->ecid);
|
||||
if (ret) {
|
||||
LOG(LOG_WARNING, "Could not get info from device");
|
||||
} else {
|
||||
snprintf(dev->product_type, sizeof(dev->product_type), "%s", info.product_type);
|
||||
snprintf(dev->display_name, sizeof(dev->display_name), "%s", info.display_name);
|
||||
}*/
|
||||
irecv_device_t device = tui_get_recovery_device(event->device_info->ecid);
|
||||
if (!device) {
|
||||
LOG(LOG_WARNING, "Could not get info from device");
|
||||
free(dev);
|
||||
return;
|
||||
}
|
||||
snprintf(dev->product_type, sizeof(dev->product_type), "%s", device->product_type);
|
||||
snprintf(dev->display_name, sizeof(dev->display_name), "%s", device->display_name);
|
||||
dev->cpid = device->chip_id;
|
||||
tui_connected_devices = dev;
|
||||
|
||||
if (event->mode == IRECV_K_RECOVERY_MODE_1 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_2 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_3 ||
|
||||
event->mode == IRECV_K_RECOVERY_MODE_4) {
|
||||
|
||||
dev->mode = TUI_DEVICE_MODE_RECOVERY;
|
||||
pthread_create(&recovery_thread, NULL, (pthread_start_t)tui_connected_recovery_mode, event->device_info);
|
||||
} else if (event->mode == IRECV_K_DFU_MODE) {
|
||||
dev->mode = TUI_DEVICE_MODE_DFU;
|
||||
pthread_create(&dfu_thread, NULL, (pthread_start_t)tui_connected_dfu_mode, event->device_info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IRECV_DEVICE_REMOVE: {
|
||||
struct tui_connected_device *cur = tui_connected_devices;
|
||||
struct tui_connected_device *prev = NULL;
|
||||
while (cur) {
|
||||
if (cur->ecid == event->device_info->ecid) {
|
||||
if (prev) {
|
||||
prev->next = cur->next;
|
||||
} else {
|
||||
tui_connected_devices = cur->next;
|
||||
}
|
||||
if (cur->mode == TUI_DEVICE_MODE_RECOVERY) {
|
||||
LOG(LOG_VERBOSE, "Recovery mode device %" PRIu64 " disconnected", event->device_info->ecid);
|
||||
pthread_create(&recovery_thread, NULL, (pthread_start_t)tui_disconnected_recovery_mode, event->device_info);
|
||||
} else if (cur->mode == TUI_DEVICE_MODE_DFU) {
|
||||
LOG(LOG_VERBOSE, "DFU mode device %" PRIu64 " disconnected", event->device_info->ecid);
|
||||
pthread_create(&dfu_thread, NULL, (pthread_start_t)tui_disconnected_dfu_mode, event->device_info);
|
||||
}
|
||||
free(cur);
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tui_devhelper(void) {
|
||||
subscribe_cmd(tui_device_event_cb, tui_irecv_device_event_cb);
|
||||
}
|
||||
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
#ifdef TUI
|
||||
|
||||
#include <tui.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <gpm.h>
|
||||
#endif
|
||||
|
||||
int tui_mouse_x = 0;
|
||||
int tui_mouse_y = 0;
|
||||
int tui_mouse_button = -1;
|
||||
|
||||
int tui_last_event = -1;
|
||||
int tui_last_input = -1;
|
||||
sem_t *tui_event_semaphore;
|
||||
char tui_last_key = 0;
|
||||
|
||||
#ifdef __linux__
|
||||
bool using_gpm = false;
|
||||
#endif
|
||||
|
||||
int tui_get_input(void) {
|
||||
char c = getc(stdin);
|
||||
if (c == '\x1b' && getc(stdin) == '[') {
|
||||
char c3 = getc(stdin);
|
||||
switch (c3) {
|
||||
case 'D':
|
||||
return TUI_INPUT_LEFT;
|
||||
case 'C':
|
||||
return TUI_INPUT_RIGHT;
|
||||
case 'A':
|
||||
return TUI_INPUT_UP;
|
||||
case 'B':
|
||||
return TUI_INPUT_DOWN;
|
||||
case 'Z':
|
||||
return TUI_INPUT_TAB_BACK;
|
||||
case 'M': {
|
||||
char c4 = getc(stdin);
|
||||
char c5 = getc(stdin);
|
||||
char c6 = getc(stdin);
|
||||
|
||||
int new_mouse_x = c5 - 33;
|
||||
if (new_mouse_x < 0) new_mouse_x += 256;
|
||||
int new_mouse_y = c6 - 33;
|
||||
if (new_mouse_y < 0) new_mouse_y += 256;
|
||||
int mouse_button = c4 & 3;
|
||||
|
||||
if (tui_mouse_x != new_mouse_x || tui_mouse_y != new_mouse_y) {
|
||||
tui_mouse_x = new_mouse_x;
|
||||
tui_mouse_y = new_mouse_y;
|
||||
return TUI_INPUT_MOUSE_MOVE;
|
||||
}
|
||||
|
||||
if (tui_mouse_button != (c4 & 1)) {
|
||||
tui_mouse_button = c4 & 1;
|
||||
if (tui_mouse_button == 0) {
|
||||
return TUI_INPUT_MOUSE_DOWN;
|
||||
} else {
|
||||
return TUI_INPUT_MOUSE_UP;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tui_last_key = c;
|
||||
|
||||
if (c == '\x0d' || c == ' ') {
|
||||
return TUI_INPUT_SELECT;
|
||||
}
|
||||
|
||||
if (c == '\t') {
|
||||
return TUI_INPUT_TAB;
|
||||
}
|
||||
|
||||
if (c == '\x7f') {
|
||||
return TUI_INPUT_BACKSPACE;
|
||||
}
|
||||
|
||||
if (c == '\x1b') {
|
||||
return TUI_INPUT_ESCAPE;
|
||||
}
|
||||
|
||||
return TUI_INPUT_NONE;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
void *tui_gpm_thread(void *arg) {
|
||||
Gpm_Event event;
|
||||
while (1) {
|
||||
if (Gpm_GetEvent(&event) == -1) {
|
||||
exit(1);
|
||||
}
|
||||
tui_mouse_x = event.x - 1;
|
||||
tui_mouse_y = event.y - 1;
|
||||
if (event.type & GPM_MOVE) {
|
||||
tui_last_event = TUI_EVENT_INPUT;
|
||||
tui_last_input = TUI_INPUT_MOUSE_MOVE;
|
||||
sem_post(tui_event_semaphore);
|
||||
}
|
||||
if (event.buttons & 4) {
|
||||
if (event.type & GPM_DOWN) {
|
||||
tui_mouse_button = 1;
|
||||
tui_last_event = TUI_EVENT_INPUT;
|
||||
tui_last_input = TUI_INPUT_MOUSE_DOWN;
|
||||
sem_post(tui_event_semaphore);
|
||||
} else if (event.type & GPM_UP) {
|
||||
tui_mouse_button = 0;
|
||||
tui_last_event = TUI_EVENT_INPUT;
|
||||
tui_last_input = TUI_INPUT_MOUSE_UP;
|
||||
sem_post(tui_event_semaphore);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *tui_input_thread(void *arg) {
|
||||
#ifdef __linux__
|
||||
if (strncmp(getenv("TERM"), "linux", 5) == 0) {
|
||||
Gpm_Connect conn;
|
||||
Gpm_Event event;
|
||||
conn.eventMask = GPM_UP | GPM_DOWN;
|
||||
conn.defaultMask = ~0;
|
||||
conn.minMod = 0;
|
||||
conn.maxMod = 0xffff;
|
||||
if (Gpm_Open(&conn, 0) != -1) {
|
||||
using_gpm = true;
|
||||
pthread_t gpm_thread;
|
||||
pthread_create(&gpm_thread, NULL, tui_gpm_thread, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while (1) {
|
||||
int input = tui_get_input();
|
||||
tui_last_event = TUI_EVENT_INPUT;
|
||||
tui_last_input = input;
|
||||
sem_post(tui_event_semaphore);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tui_get_event(void) {
|
||||
sem_wait(tui_event_semaphore);
|
||||
int last_event = tui_last_event;
|
||||
tui_last_event = -1;
|
||||
return last_event;
|
||||
}
|
||||
|
||||
int tui_try_get_event(void) {
|
||||
int ret = sem_trywait(tui_event_semaphore);
|
||||
if (ret == 0) {
|
||||
int last_event = tui_last_event;
|
||||
tui_last_event = -1;
|
||||
return last_event;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
+202
-47
@@ -1,6 +1,13 @@
|
||||
#ifdef TUI
|
||||
#ifdef __APPLE__
|
||||
#define _DARWIN_C_SOURCE
|
||||
#else
|
||||
#define _DEFAULT_SOURCE
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@@ -8,94 +15,242 @@
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <palerain.h>
|
||||
#include <tui.h>
|
||||
|
||||
int redraw_screen() {
|
||||
#ifdef __APPLE__
|
||||
int proc_pidpath(int pid, void * buffer, uint32_t buffersize);
|
||||
char random_sem_name[sizeof("palera1n.tui_event_semaphore") + 16 + 1];
|
||||
#endif
|
||||
|
||||
static int tui_state = 0;
|
||||
|
||||
int tui_x_offset = 0;
|
||||
int tui_y_offset = 0;
|
||||
|
||||
bool supports_bright_colors = true;
|
||||
|
||||
static struct termios saved_termios;
|
||||
|
||||
int redraw_screen(void) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
CLEAR_SCREEN;
|
||||
MOVETO(0, 0);
|
||||
|
||||
struct winsize w;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
if (w.ws_col < 80 || w.ws_row < 24) {
|
||||
LOG(LOG_FATAL, "Terminal size must be at least 80x24");
|
||||
printf("\033[37;41mERROR: Terminal size must be at least 80x24!");
|
||||
fflush(stdout);
|
||||
return -1;
|
||||
}
|
||||
tui_y_offset = (w.ws_row - 24) / 2;
|
||||
for (int i = 0; i < tui_y_offset; i++) {
|
||||
printf("\n");
|
||||
}
|
||||
tui_x_offset = (w.ws_col - 80) / 2;
|
||||
|
||||
const char* tui_version = TUI_VERSION;
|
||||
if (tui_version[0] == 'v') tui_version++;
|
||||
|
||||
tui_draw_rectangle(0, 0, 79, 23);
|
||||
MOVETOT((int)(80 - (strlen("[palera1n - Version ]") + strlen(tui_version) ) - 1), 1);
|
||||
printf("[palera1n - Version %s]", tui_version);
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
switch(tui_state) {
|
||||
case MAIN_SCREEN:
|
||||
tui_screen_main_redraw();
|
||||
break;
|
||||
case OPTIONS_SCREEN:
|
||||
tui_screen_options_redraw();
|
||||
break;
|
||||
case ENTER_RECOVERY_SCREEN:
|
||||
tui_screen_enter_recovery_redraw();
|
||||
break;
|
||||
case ENTER_DFU_SCREEN:
|
||||
tui_screen_enter_dfu_redraw();
|
||||
break;
|
||||
case JAILBREAK_SCREEN:
|
||||
tui_screen_jailbreak_redraw();
|
||||
break;
|
||||
}
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int destroy_window() {
|
||||
static int destroy_window(void) {
|
||||
if (!tui_started) return 0;
|
||||
tui_started = false;
|
||||
tcsetattr(STDIN_FILENO, 0, &saved_termios);
|
||||
MOUSEOFF;
|
||||
CLEAR_SCREEN;
|
||||
|
||||
MOVETO(0, 0);
|
||||
RMCUP;
|
||||
CNORM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_window() {
|
||||
static int init_window(void) {
|
||||
setlocale(LC_ALL, NULL);
|
||||
setenv(
|
||||
"NEWT_COLORS",
|
||||
"root=,black\n"
|
||||
"border=lightgray,black\n"
|
||||
"title=lightgray,black\n"
|
||||
"roottext=red,black\n"
|
||||
"label=lightgray,black\n"
|
||||
"entry=lightgray,black\n"
|
||||
"window=red,black\n"
|
||||
"textbox=lightgray,black\n"
|
||||
"button=black,lightgray\n"
|
||||
"compactbutton=lightgray,black\n"
|
||||
"listbox=lightgray,black\n"
|
||||
"actlistbox=black,lightgray\n"
|
||||
"actsellistbox=black,lightgray\n"
|
||||
"checkbox=lightgray,black\n"
|
||||
"actcheckbox=black,lightgray\n",
|
||||
0);
|
||||
|
||||
tui_started = true;
|
||||
newtInit();
|
||||
int cols, rows;
|
||||
newtGetScreenSize(&cols, &rows);
|
||||
if (cols < 80 || rows < 24) {
|
||||
newtFinished();
|
||||
struct winsize w;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
if (w.ws_col < 80 || w.ws_row < 24) {
|
||||
tui_started = false;
|
||||
LOG(LOG_FATAL, "Terminal size must be at least 80x24");
|
||||
return -1;
|
||||
}
|
||||
LOG(LOG_VERBOSE3, "cols: %d, rows: %d\n", cols, rows);
|
||||
newtCls();
|
||||
newtSetColor(PI_LOG_COLOR, "yellow", "black");
|
||||
newtSetColor(PI_STEP_CURRENT, "lightgray", "black");
|
||||
newtSetColor(PI_STEP_OTHER, "gray", "black");
|
||||
newtDrawRootText(0, 0, "palera1n version 2.0.0");
|
||||
newtPushHelpLine(NULL);
|
||||
LOG(LOG_VERBOSE3, "cols: %d, rows: %d\n", w.ws_col, w.ws_row);
|
||||
SMCUP;
|
||||
CIVIS;
|
||||
fflush(stdout);
|
||||
struct termios term;
|
||||
tcgetattr(STDIN_FILENO, &term);
|
||||
tcgetattr(STDIN_FILENO, &saved_termios);
|
||||
cfmakeraw(&term);
|
||||
term.c_lflag |= ISIG;
|
||||
tcsetattr(STDIN_FILENO, 0, &term);
|
||||
|
||||
MOUSEON;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tui() {
|
||||
bool tui_is_restarting = false;
|
||||
|
||||
extern int saved_argc;
|
||||
extern char** saved_argv;
|
||||
extern char** saved_envp;
|
||||
|
||||
void tui_terminate(int sig) {
|
||||
destroy_window();
|
||||
if (tui_is_restarting) {
|
||||
#ifdef __APPLE__
|
||||
sem_close(tui_event_semaphore);
|
||||
sem_unlink(random_sem_name);
|
||||
char pathbuf[4096];
|
||||
if (proc_pidpath(getpid(), pathbuf, sizeof(pathbuf)) <= 0) {
|
||||
LOG(LOG_FATAL, "Failed to get path of running executable");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
execve(pathbuf, saved_argv, saved_envp);
|
||||
#elif defined(__linux__)
|
||||
execve("/proc/self/exe", saved_argv, saved_envp);
|
||||
#endif
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void resize_handler(int sig) {
|
||||
redraw_screen();
|
||||
}
|
||||
|
||||
int tui(void) {
|
||||
if (strncmp(getenv("TERM"), "xterm", 5) != 0) {
|
||||
supports_bright_colors = false;
|
||||
}
|
||||
srand(time(NULL));
|
||||
int ret = 0;
|
||||
if ((ret = init_window())) return ret;
|
||||
ret = MAIN_SCREEN;
|
||||
signal(SIGINT, tui_terminate);
|
||||
signal(SIGTERM, tui_terminate);
|
||||
signal(SIGQUIT, tui_terminate);
|
||||
signal(SIGWINCH, resize_handler);
|
||||
|
||||
#ifdef __APPLE__
|
||||
// generate a 16 character random hex string from urandom
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
LOG(LOG_FATAL, "Failed to open /dev/urandom");
|
||||
return -1;
|
||||
}
|
||||
uint8_t random[8];
|
||||
if (read(fd, random, 8) != 8) {
|
||||
LOG(LOG_FATAL, "Failed to read from /dev/urandom");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
sprintf(&random_sem_name[i * 2], "%02x", random[i]);
|
||||
}
|
||||
sem_unlink(random_sem_name);
|
||||
tui_event_semaphore = sem_open(random_sem_name, O_CREAT, 0644, 0);
|
||||
#else
|
||||
tui_event_semaphore = malloc(sizeof(sem_t));
|
||||
sem_init(tui_event_semaphore, 0, 0);
|
||||
#endif
|
||||
pthread_t input_thread;
|
||||
pthread_create(&input_thread, NULL, tui_input_thread, NULL);
|
||||
|
||||
tui_devhelper();
|
||||
|
||||
tui_state = MAIN_SCREEN;
|
||||
while (1) {
|
||||
switch (ret) {
|
||||
switch (tui_state) {
|
||||
case ERROR_SCREEN:
|
||||
goto out;
|
||||
break;
|
||||
case EXIT_SCREEN:
|
||||
goto out;
|
||||
break;
|
||||
case MAIN_SCREEN:
|
||||
ret = tui_screen_main();
|
||||
tui_state = tui_screen_main();
|
||||
break;
|
||||
case OPTIONS_SCREEN:
|
||||
ret = tui_screen_options();
|
||||
tui_state = tui_screen_options();
|
||||
break;
|
||||
case ENTER_RECOVERY_SCREEN:
|
||||
ret = tui_screen_enter_recovery();
|
||||
tui_state = tui_screen_enter_recovery();
|
||||
break;
|
||||
case ENTER_DFU_SCREEN:
|
||||
ret = tui_screen_enter_dfu();
|
||||
tui_state = tui_screen_enter_dfu();
|
||||
break;
|
||||
case JAILBREAKING_SCREEN:
|
||||
ret = tui_screen_jailbreak();
|
||||
case JAILBREAK_SCREEN:
|
||||
tui_state = tui_screen_jailbreak();
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
goto out;
|
||||
}
|
||||
newtPopWindow();
|
||||
}
|
||||
out:
|
||||
newtFinished();
|
||||
tui_started = false;
|
||||
destroy_window();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tui_draw_rectangle(int x1, int y1, int x2, int y2) {
|
||||
if (x1 == x2 || y1 == y2) return;
|
||||
DSGON;
|
||||
MOVETOT(x1 + 1, y1 + 1);
|
||||
printf("%c", 0x6C);
|
||||
for (int x = x1 + 1; x < x2; x++) {
|
||||
putchar(0x71);
|
||||
}
|
||||
putchar(0x6B);
|
||||
MOVETOT(x1 + 1, y2 + 1);
|
||||
putchar(0x6D);
|
||||
for (int x = x1 + 1; x < x2; x++) {
|
||||
putchar(0x71);
|
||||
}
|
||||
putchar(0x6A);
|
||||
for (int y = y1 + 1; y < y2; y++) {
|
||||
PRINTATT(x1 + 1, y + 1, "\x78");
|
||||
PRINTATT(x2 + 1, y + 1, "\x78");
|
||||
}
|
||||
DSGOFF;
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
+459
-1
@@ -1,3 +1,4 @@
|
||||
#ifdef TUI
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -12,4 +13,461 @@
|
||||
#include <palerain.h>
|
||||
#include <tui.h>
|
||||
|
||||
tui_screen_t tui_screen_enter_dfu() { return JAILBREAKING_SCREEN; }
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <palerain.h>
|
||||
#include <tui.h>
|
||||
|
||||
static int tui_enter_dfu_nav_selection = 1;
|
||||
static bool tui_device_is_entering_dfu = false;
|
||||
static int tui_enter_dfu_status = 0;
|
||||
|
||||
enum {
|
||||
DEVICE_TYPE_IPHONE_SE,
|
||||
DEVICE_TYPE_IPHONE_6S,
|
||||
DEVICE_TYPE_IPHONE_7_8,
|
||||
DEVICE_TYPE_IPHONE_X,
|
||||
DEVICE_TYPE_IPAD,
|
||||
DEVICE_TYPE_IPOD_TOUCH
|
||||
} device_type;
|
||||
|
||||
static int tui_product_type_to_device_type(char *product_type) {
|
||||
if (strcmp(product_type, "iPhone8,1") == 0 || strcmp(product_type, "iPhone8,2") == 0) {
|
||||
return DEVICE_TYPE_IPHONE_6S;
|
||||
}
|
||||
if (strcmp(product_type, "iPhone8,4") == 0) return DEVICE_TYPE_IPHONE_SE;
|
||||
if (strcmp(product_type, "iPhone9,1") == 0 || strcmp(product_type, "iPhone9,2") == 0
|
||||
|| strcmp(product_type, "iPhone9,3") == 0 || strcmp(product_type, "iPhone9,4") == 0) {
|
||||
return DEVICE_TYPE_IPHONE_7_8;
|
||||
}
|
||||
if (strcmp(product_type, "iPhone10,1") == 0 || strcmp(product_type, "iPhone10,2") == 0
|
||||
|| strcmp(product_type, "iPhone10,4") == 0 || strcmp(product_type, "iPhone10,5") == 0) {
|
||||
return DEVICE_TYPE_IPHONE_7_8;
|
||||
}
|
||||
if (strcmp(product_type, "iPhone10,3") == 0 || strcmp(product_type, "iPhone10,6") == 0) {
|
||||
return DEVICE_TYPE_IPHONE_X;
|
||||
}
|
||||
if (strncmp(product_type, "iPad", strlen("iPad")) == 0) {
|
||||
return DEVICE_TYPE_IPAD;
|
||||
}
|
||||
if (strcmp(product_type, "iPod9,1") == 0) {
|
||||
return DEVICE_TYPE_IPOD_TOUCH;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return DEVICE_TYPE_IPHONE_SE;
|
||||
}
|
||||
|
||||
static int tui_enter_dfu_device_type = DEVICE_TYPE_IPHONE_SE;
|
||||
|
||||
static int tui_enter_dfu_loading_progress = 1;
|
||||
|
||||
static void tui_screen_enter_dfu_nav(void) {
|
||||
MOVETOT(80 - 22, 23);
|
||||
printf("%s[ Cancel ]" COLOR(FG_WHITE, BG_BLACK) " %s[ %s ]" COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_device_is_entering_dfu || tui_enter_dfu_status == 1 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : tui_enter_dfu_nav_selection == 0 ? "\033[30;107m" : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 23 && tui_mouse_x <= tui_x_offset + 80 - 23 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
),
|
||||
tui_device_is_entering_dfu || tui_enter_dfu_status == 1 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : tui_enter_dfu_nav_selection == 1 ? "\033[30;107m" : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 12 && tui_mouse_x <= tui_x_offset + 80 - 12 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
),
|
||||
tui_enter_dfu_status == 2 ? "Retry" : "Start"
|
||||
);
|
||||
}
|
||||
|
||||
void tui_screen_enter_dfu_redraw(void) {
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
switch(tui_enter_dfu_status) {
|
||||
case 0:
|
||||
PRINTATT(3, 3, "Time to put the device into DFU mode. Locate the buttons as marked below on");
|
||||
PRINTATT(3, 4, "your device and check the instructions on the right *before* clicking Start.");
|
||||
break;
|
||||
case 1:
|
||||
PRINTATT(3, 3, "Device entered DFU mode successfully.");
|
||||
break;
|
||||
case 2:
|
||||
PRINTATT(3, 3, "Whoops, the device didn't enter DFU mode. Click Retry to try again.");
|
||||
break;
|
||||
}
|
||||
|
||||
tui_screen_enter_dfu_nav();
|
||||
|
||||
switch(tui_enter_dfu_device_type) {
|
||||
case DEVICE_TYPE_IPHONE_SE:
|
||||
case DEVICE_TYPE_IPAD:
|
||||
if (tui_enter_dfu_loading_progress > 0 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 6, "1. Click Start");
|
||||
if (tui_enter_dfu_loading_progress > 0) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
if (!tui_device_is_entering_dfu || tui_enter_dfu_loading_progress > 4 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 7, "2. Press and hold the Top and");
|
||||
MOVETOT(54, 8);
|
||||
printf("Home buttons together (%d)", tui_enter_dfu_loading_progress > 4 ? 0 : tui_enter_dfu_loading_progress < 1 ? 4 : 5 - tui_enter_dfu_loading_progress);
|
||||
if (!tui_device_is_entering_dfu || tui_enter_dfu_loading_progress > 4) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
if (tui_enter_dfu_loading_progress < 5 || tui_enter_dfu_loading_progress > 14 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 9, "3. Release the Top button BUT");
|
||||
PRINTATT(54, 10, "KEEP HOLDING the Home");
|
||||
MOVETOT(54, 11);
|
||||
printf("button (%d)", tui_enter_dfu_loading_progress > 14 ? 0 : tui_enter_dfu_loading_progress < 5 ? 10 : 15 - tui_enter_dfu_loading_progress);
|
||||
if (tui_enter_dfu_loading_progress < 5 || tui_enter_dfu_loading_progress > 14) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
break;
|
||||
case DEVICE_TYPE_IPHONE_6S:
|
||||
if (tui_enter_dfu_loading_progress > 0 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 6, "1. Click Start");
|
||||
if (tui_enter_dfu_loading_progress > 0) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
if (!tui_device_is_entering_dfu || tui_enter_dfu_loading_progress > 4 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 7, "2. Press and hold the Side");
|
||||
PRINTATT(54, 8, "and Home buttons together");
|
||||
MOVETOT(54, 9);
|
||||
printf("(%d)", tui_enter_dfu_loading_progress > 4 ? 0 : tui_enter_dfu_loading_progress < 1 ? 4 : 5 - tui_enter_dfu_loading_progress);
|
||||
if (!tui_device_is_entering_dfu || tui_enter_dfu_loading_progress > 4) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
if (tui_enter_dfu_loading_progress < 5 || tui_enter_dfu_loading_progress > 14 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 10, "3. Release the Side button");
|
||||
PRINTATT(54, 11, "BUT KEEP HOLDING the Home");
|
||||
MOVETOT(54, 12);
|
||||
printf("button (%d)", tui_enter_dfu_loading_progress > 14 ? 0 : tui_enter_dfu_loading_progress < 5 ? 10 : 15 - tui_enter_dfu_loading_progress);
|
||||
if (tui_enter_dfu_loading_progress < 5 || tui_enter_dfu_loading_progress > 14) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
break;
|
||||
case DEVICE_TYPE_IPHONE_7_8:
|
||||
case DEVICE_TYPE_IPHONE_X:
|
||||
tui_draw_rectangle(17, 5, 33, 21);
|
||||
PRINTATT(17, 10, "|");
|
||||
MOVETOT(5, 11);
|
||||
printf("%sVolume down-", tui_enter_dfu_loading_progress > 14 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : COLOR(FG_YELLOW, BG_BLACK));
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
putchar('|');
|
||||
DSGON;
|
||||
MOVETOT(35, 10);
|
||||
putchar(0x78);
|
||||
DSGOFF;
|
||||
printf("%s-Side button", tui_enter_dfu_loading_progress > 4 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : COLOR(FG_YELLOW, BG_BLACK));
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
|
||||
if (tui_enter_dfu_loading_progress > 0 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 6, "1. Click Start");
|
||||
if (tui_enter_dfu_loading_progress > 0) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
if (!tui_device_is_entering_dfu || tui_enter_dfu_loading_progress > 4 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 7, "2. Press and hold the Side");
|
||||
PRINTATT(54, 8, "and Volume down buttons");
|
||||
MOVETOT(54, 9);
|
||||
printf("together (%d)", tui_enter_dfu_loading_progress > 4 ? 0 : tui_enter_dfu_loading_progress < 1 ? 4 : 5 - tui_enter_dfu_loading_progress);
|
||||
if (!tui_device_is_entering_dfu || tui_enter_dfu_loading_progress > 4) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
if (tui_enter_dfu_loading_progress < 5 || tui_enter_dfu_loading_progress > 14 || tui_enter_dfu_status == 2) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
}
|
||||
PRINTATT(51, 10, "3. Release the Side button");
|
||||
PRINTATT(54, 11, "BUT KEEP HOLDING the");
|
||||
MOVETOT(54, 12);
|
||||
printf("Volume down button (%d)", tui_enter_dfu_loading_progress > 14 ? 0 : tui_enter_dfu_loading_progress < 5 ? 10 : 15 - tui_enter_dfu_loading_progress);
|
||||
if (tui_enter_dfu_loading_progress < 5 || tui_enter_dfu_loading_progress > 14) {
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch(tui_enter_dfu_device_type) {
|
||||
case DEVICE_TYPE_IPHONE_SE:
|
||||
tui_draw_rectangle(18, 6, 32, 21);
|
||||
tui_draw_rectangle(24, 19, 26, 20);
|
||||
for (int y = 9; y < 20; y++) {
|
||||
SETCOLOR(FG_BLACK, BG_BRIGHT_BLACK);
|
||||
PRINTATT(20, y, " ");
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
PRINTATT(23, 8, "o ===");
|
||||
PRINTATT(18, 11, "|");
|
||||
PRINTATT(18, 12, "|");
|
||||
MOVETOT(30, 6);
|
||||
printf("__ %s-Top button", tui_enter_dfu_loading_progress > 4 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : COLOR(FG_YELLOW, BG_BLACK));
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
MOVETOT(31, 20);
|
||||
printf("%s-Home button", tui_enter_dfu_loading_progress > 14 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : COLOR(FG_YELLOW, BG_BLACK));
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
|
||||
break;
|
||||
case DEVICE_TYPE_IPHONE_6S:
|
||||
tui_draw_rectangle(17, 5, 33, 21);
|
||||
tui_draw_rectangle(24, 19, 26, 20);
|
||||
for (int y = 8; y < 20; y++) {
|
||||
SETCOLOR(FG_BLACK, BG_BRIGHT_BLACK);
|
||||
PRINTATT(19, y, " ");
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
PRINTATT(23, 7, "o ===");
|
||||
PRINTATT(17, 10, "|");
|
||||
PRINTATT(17, 11, "|");
|
||||
MOVETOT(35, 10);
|
||||
printf("|%s-Side button", tui_enter_dfu_loading_progress > 4 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : COLOR(FG_YELLOW, BG_BLACK));
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
MOVETOT(30, 20);
|
||||
printf("%s-Home button", tui_enter_dfu_loading_progress > 14 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : COLOR(FG_YELLOW, BG_BLACK));
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
break;
|
||||
case DEVICE_TYPE_IPHONE_7_8:
|
||||
tui_draw_rectangle(24, 19, 26, 20);
|
||||
for (int y = 8; y < 20; y++) {
|
||||
SETCOLOR(FG_BLACK, BG_BRIGHT_BLACK);
|
||||
PRINTATT(19, y, " ");
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
PRINTATT(23, 7, "o ===");
|
||||
|
||||
break;
|
||||
case DEVICE_TYPE_IPHONE_X:
|
||||
SETCOLOR(FG_BLACK, BG_BRIGHT_BLACK);
|
||||
PRINTATT(19, 7, " ");
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
printf(" ");
|
||||
SETCOLOR(FG_BLACK, BG_BRIGHT_BLACK);
|
||||
printf(" ");
|
||||
SETCOLOR(FG_BLACK, BG_BRIGHT_BLACK);
|
||||
for (int y = 8; y < 22; y++) {
|
||||
PRINTATT(19, y, " ");
|
||||
}
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
|
||||
DSGON;
|
||||
MOVETOT(35, 11);
|
||||
putchar(0x78);
|
||||
DSGOFF;
|
||||
|
||||
break;
|
||||
case DEVICE_TYPE_IPAD:
|
||||
tui_draw_rectangle(14, 6, 36, 21);
|
||||
tui_draw_rectangle(24, 19, 26, 20);
|
||||
for (int y = 9; y < 20; y++) {
|
||||
SETCOLOR(FG_BLACK, BG_BRIGHT_BLACK);
|
||||
PRINTATT(16, y, " ");
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
}
|
||||
PRINTATT(23, 8, "o ===");
|
||||
PRINTATT(14, 11, "|");
|
||||
PRINTATT(14, 12, "|");
|
||||
MOVETOT(33, 6);
|
||||
printf("__ %s-Top button", tui_enter_dfu_loading_progress > 4 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : COLOR(FG_YELLOW, BG_BLACK));
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
MOVETOT(29, 21);
|
||||
printf("%s-Home button", tui_enter_dfu_loading_progress > 14 ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : COLOR(FG_YELLOW, BG_BLACK));
|
||||
SETCOLOR(FG_BRIGHT_WHITE, BG_BLACK);
|
||||
|
||||
break;
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// TODO: IMPLEMENT REAL ENTER RECOVERY
|
||||
static int dfu_time = 0;
|
||||
|
||||
static tui_screen_t tui_enter_dfu(void) {
|
||||
if (tui_connected_devices && !tui_connected_devices->next) {
|
||||
if (tui_connected_devices->mode == TUI_DEVICE_MODE_NORMAL) {
|
||||
tui_enter_dfu_status = 0;
|
||||
return ENTER_RECOVERY_SCREEN;
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
tui_enter_dfu_loading_progress = 1;
|
||||
while(1) {
|
||||
if (++i % 10 == 0) {
|
||||
tui_enter_dfu_loading_progress++;
|
||||
}
|
||||
redraw_screen();
|
||||
usleep(100000);
|
||||
int event = tui_try_get_event();
|
||||
if (event == TUI_EVENT_CONNECTED_DEVICES_CHANGED) {
|
||||
if (tui_connected_devices && !tui_connected_devices->next) {
|
||||
if (tui_connected_devices->mode == TUI_DEVICE_MODE_RECOVERY || tui_connected_devices->mode == TUI_DEVICE_MODE_NORMAL) {
|
||||
tui_enter_dfu_status = 2;
|
||||
tui_device_is_entering_dfu = false;
|
||||
return ENTER_DFU_SCREEN;
|
||||
} else {
|
||||
tui_enter_dfu_status = 1;
|
||||
tui_device_is_entering_dfu = false;
|
||||
tui_enter_dfu_loading_progress = 15;
|
||||
redraw_screen();
|
||||
sleep(3);
|
||||
tui_jailbreak();
|
||||
return JAILBREAK_SCREEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i > 10 * (60 + 15)) {
|
||||
return MAIN_SCREEN;
|
||||
}
|
||||
if (i == 10 * 2) {
|
||||
exitrecv_cmd(tui_connected_devices->ecid);
|
||||
}
|
||||
}
|
||||
redraw_screen();
|
||||
fflush(stdout);
|
||||
sleep(3);
|
||||
return JAILBREAK_SCREEN;
|
||||
}
|
||||
|
||||
static int tui_enter_dfu_nav_mouse_select = -1;
|
||||
|
||||
tui_screen_t tui_screen_enter_dfu(void) {
|
||||
if (tui_connected_devices && !tui_connected_devices->next) {
|
||||
tui_enter_dfu_device_type = tui_product_type_to_device_type(tui_connected_devices->product_type);
|
||||
}
|
||||
|
||||
tui_device_is_entering_dfu = false;
|
||||
tui_enter_dfu_loading_progress = 0;
|
||||
tui_enter_dfu_nav_selection = 1;
|
||||
redraw_screen();
|
||||
|
||||
tui_device_is_entering_dfu = false;
|
||||
tui_enter_dfu_loading_progress = 0;
|
||||
|
||||
while(1) {
|
||||
int event = tui_get_event();
|
||||
switch (event) {
|
||||
case TUI_EVENT_CONNECTED_DEVICES_CHANGED:
|
||||
break;
|
||||
case TUI_EVENT_INPUT: {
|
||||
int input = tui_last_input;
|
||||
if (input == TUI_INPUT_NONE) continue;
|
||||
if (tui_device_is_entering_dfu) continue;
|
||||
|
||||
switch (input) {
|
||||
case TUI_INPUT_LEFT:
|
||||
case TUI_INPUT_RIGHT:
|
||||
tui_enter_dfu_nav_selection = !tui_enter_dfu_nav_selection;
|
||||
redraw_screen();
|
||||
break;
|
||||
case TUI_INPUT_SELECT:
|
||||
switch(tui_enter_dfu_nav_selection) {
|
||||
case 0:
|
||||
return MAIN_SCREEN;
|
||||
case 1:
|
||||
tui_device_is_entering_dfu = true;
|
||||
redraw_screen();
|
||||
return tui_enter_dfu();
|
||||
}
|
||||
case TUI_INPUT_MOUSE_MOVE:
|
||||
tui_screen_enter_dfu_nav();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_DOWN:
|
||||
if (tui_mouse_y == tui_y_offset + 22) {
|
||||
if (tui_mouse_x >= tui_x_offset + 80 - 23 && tui_mouse_x <= tui_x_offset + 80 - 23 + 10) {
|
||||
tui_enter_dfu_nav_selection = 0;
|
||||
tui_enter_dfu_nav_mouse_select = 0;
|
||||
redraw_screen();
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 12 && tui_mouse_x <= tui_x_offset + 80 - 12 + 10) {
|
||||
tui_enter_dfu_nav_selection = 1;
|
||||
tui_enter_dfu_nav_mouse_select = 1;
|
||||
redraw_screen();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_UP:
|
||||
if (tui_mouse_y == tui_y_offset + 22) {
|
||||
if (tui_mouse_x >= tui_x_offset + 80 - 23 && tui_mouse_x <= tui_x_offset + 80 - 23 + 10) {
|
||||
return MAIN_SCREEN;
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 12 && tui_mouse_x <= tui_x_offset + 80 - 12 + 10) {
|
||||
tui_device_is_entering_dfu = true;
|
||||
redraw_screen();
|
||||
return tui_enter_dfu();
|
||||
}
|
||||
}
|
||||
tui_enter_dfu_nav_mouse_select = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MAIN_SCREEN;
|
||||
}
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef TUI
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -8,8 +9,201 @@
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <poll.h>
|
||||
#include <palerain.h>
|
||||
#include <tui.h>
|
||||
|
||||
tui_screen_t tui_screen_enter_recovery() { return ENTER_DFU_SCREEN; }
|
||||
int tui_enter_recovery_nav_selection = 1;
|
||||
bool tui_device_is_entering_recovery = false;
|
||||
bool tui_enter_recovery_mode_failed = false;
|
||||
|
||||
static void tui_screen_enter_recovery_nav(void) {
|
||||
MOVETOT(80 - 22, 23);
|
||||
printf("%s[ Back ]" COLOR(FG_WHITE, BG_BLACK) " %s[ Next ]" COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_device_is_entering_recovery ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : tui_enter_recovery_nav_selection == 0 ? "\033[30;107m" : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 23 && tui_mouse_x <= tui_x_offset + 80 - 23 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
),
|
||||
tui_device_is_entering_recovery ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : tui_enter_recovery_nav_selection == 1 ? "\033[30;107m" : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 12 && tui_mouse_x <= tui_x_offset + 80 - 12 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static char enter_recovery_loading[9][8] = {
|
||||
"........",
|
||||
"|.......",
|
||||
".|......",
|
||||
"..|.....",
|
||||
"...|....",
|
||||
"....|...",
|
||||
".....|..",
|
||||
"......|.",
|
||||
".......|"
|
||||
};
|
||||
|
||||
static char enter_recovery_loading_troll[9][8] = {
|
||||
".......",
|
||||
"t......",
|
||||
".r.....",
|
||||
"..o....",
|
||||
"...l...",
|
||||
"....l..",
|
||||
".....e.",
|
||||
"......d",
|
||||
};
|
||||
|
||||
static bool is_troll;
|
||||
static int tui_enter_recovery_loading_progress = 0;
|
||||
|
||||
static void tui_screen_enter_recovery_loading(void) {
|
||||
SETCOLOR(FG_YELLOW, BG_BLACK);
|
||||
PRINTATT(3, 8, "Entering recovery mode ");
|
||||
printf("%.8s", is_troll ? enter_recovery_loading_troll[tui_enter_recovery_loading_progress] : enter_recovery_loading[tui_enter_recovery_loading_progress]);
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void tui_screen_enter_recovery_redraw(void) {
|
||||
PRINTATT(3, 3, "The device needs to be put into DFU mode to apply the jailbreak. This is a");
|
||||
PRINTATT(3, 4, "manual process and we will guide you through it.");
|
||||
PRINTATT(3, 5, "In order to prevent filesystem corruption through hard reset, the device");
|
||||
PRINTATT(3, 6, "will be put into recovery mode first. Click Next when you are ready.");
|
||||
|
||||
if (tui_enter_recovery_mode_failed) {
|
||||
SETCOLOR(FG_YELLOW, BG_BLACK);
|
||||
PRINTATT(3, 8, "Hmm... device did not enter recovery mode!? Click Next to try again...");
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
tui_screen_enter_recovery_nav();
|
||||
if (tui_device_is_entering_recovery) {
|
||||
tui_screen_enter_recovery_loading();
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static int recovery_time = 0;
|
||||
|
||||
static tui_screen_t tui_enter_recovery(void) {
|
||||
enter_recovery_cmd(tui_connected_devices->udid);
|
||||
is_troll = false;
|
||||
if (rand() % 1000 == 0) {
|
||||
is_troll = true;
|
||||
}
|
||||
int i = 0;
|
||||
recovery_time = 0;
|
||||
while(1) {
|
||||
redraw_screen();
|
||||
tui_enter_recovery_loading_progress++;
|
||||
tui_enter_recovery_loading_progress %= 9;
|
||||
// 100ms sleep
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 100000000;
|
||||
nanosleep(&ts, NULL);
|
||||
|
||||
int event = tui_try_get_event();
|
||||
if (event == TUI_EVENT_CONNECTED_DEVICES_CHANGED) {
|
||||
if (tui_connected_devices && !tui_connected_devices->next && tui_connected_devices->mode == TUI_DEVICE_MODE_RECOVERY) {
|
||||
SETCOLOR(FG_YELLOW, BG_BLACK);
|
||||
PRINTATT(3, 8, "Device is now in recovery mode.");
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
fflush(stdout);
|
||||
|
||||
sleep(3);
|
||||
|
||||
return ENTER_DFU_SCREEN;
|
||||
}
|
||||
}
|
||||
if (i > 60 * 10) {
|
||||
tui_enter_recovery_mode_failed = true;
|
||||
return ENTER_RECOVERY_SCREEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int tui_enter_recovery_nav_mouse_select = -1;
|
||||
|
||||
tui_screen_t tui_screen_enter_recovery(void) {
|
||||
tui_device_is_entering_recovery = false;
|
||||
tui_enter_recovery_loading_progress = 0;
|
||||
tui_enter_recovery_nav_selection = 1;
|
||||
redraw_screen();
|
||||
|
||||
while(1) {
|
||||
int event = tui_get_event();
|
||||
switch (event) {
|
||||
case TUI_EVENT_CONNECTED_DEVICES_CHANGED:
|
||||
tui_enter_recovery_mode_failed = false;
|
||||
return MAIN_SCREEN;
|
||||
case TUI_EVENT_INPUT: {
|
||||
int input = tui_last_input;
|
||||
if (input == TUI_INPUT_NONE) continue;
|
||||
if (tui_device_is_entering_recovery) continue;
|
||||
|
||||
switch (input) {
|
||||
case TUI_INPUT_LEFT:
|
||||
case TUI_INPUT_RIGHT:
|
||||
tui_enter_recovery_nav_selection = !tui_enter_recovery_nav_selection;
|
||||
redraw_screen();
|
||||
break;
|
||||
case TUI_INPUT_SELECT:
|
||||
switch(tui_enter_recovery_nav_selection) {
|
||||
case 0:
|
||||
tui_enter_recovery_mode_failed = false;
|
||||
return MAIN_SCREEN;
|
||||
case 1:
|
||||
tui_device_is_entering_recovery = true;
|
||||
redraw_screen();
|
||||
return tui_enter_recovery();
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_MOVE:
|
||||
tui_screen_enter_recovery_nav();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_DOWN:
|
||||
if (tui_mouse_y == tui_y_offset + 22) {
|
||||
if (tui_mouse_x >= tui_x_offset + 80 - 23 && tui_mouse_x <= tui_x_offset + 80 - 23 + 10) {
|
||||
tui_enter_recovery_nav_selection = 0;
|
||||
tui_enter_recovery_nav_mouse_select = 0;
|
||||
tui_screen_enter_recovery_nav();
|
||||
fflush(stdout);
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 12 && tui_mouse_x <= tui_x_offset + 80 - 12 + 10) {
|
||||
tui_enter_recovery_nav_selection = 1;
|
||||
tui_enter_recovery_nav_mouse_select = 1;
|
||||
tui_screen_enter_recovery_nav();
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_UP:
|
||||
if (tui_mouse_y == tui_y_offset + 22) {
|
||||
if (tui_mouse_x >= tui_x_offset + 80 - 23 && tui_mouse_x <= tui_x_offset + 80 - 23 + 10) {
|
||||
return MAIN_SCREEN;
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 12 && tui_mouse_x <= tui_x_offset + 80 - 12 + 10) {
|
||||
tui_device_is_entering_recovery = true;
|
||||
redraw_screen();
|
||||
return tui_enter_recovery();
|
||||
}
|
||||
}
|
||||
tui_enter_recovery_nav_mouse_select = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tui_enter_recovery_mode_failed = false;
|
||||
return MAIN_SCREEN;
|
||||
}
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
+162
-1
@@ -1,3 +1,4 @@
|
||||
#ifdef TUI
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -12,4 +13,164 @@
|
||||
#include <palerain.h>
|
||||
#include <tui.h>
|
||||
|
||||
tui_screen_t tui_screen_jailbreak() { return EXIT_SCREEN; }
|
||||
bool tui_is_jailbreaking = false;
|
||||
|
||||
static void tui_screen_jailbreak_nav(void) {
|
||||
if (tui_is_jailbreaking) {
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
} else {
|
||||
SETCOLOR(FG_BLACK, BG_BRIGHT_WHITE);
|
||||
}
|
||||
PRINTATT(80 - 11, 23, "[ Done ]");
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
static pthread_t tui_jailbreak_thread_id;
|
||||
|
||||
int tui_jailbreak_stage = 0;
|
||||
char *tui_jailbreak_status = NULL;
|
||||
|
||||
void tui_jailbreak_status_changed(void) {
|
||||
tui_last_event = TUI_EVENT_JAILBREAK_STATUS_CHANGED;
|
||||
sem_post(tui_event_semaphore);
|
||||
}
|
||||
|
||||
static void *tui_jailbreak_thread(void *arg) {
|
||||
tui_jailbreak_stage = 1;
|
||||
tui_jailbreak_status = "About to execute checkra1n";
|
||||
|
||||
tui_jailbreak_status_changed();
|
||||
|
||||
if (!tui_connected_devices || tui_connected_devices->next || tui_connected_devices->mode != TUI_DEVICE_MODE_DFU) {
|
||||
tui_jailbreak_status = "ERROR: No single device in DFU mode found";
|
||||
tui_jailbreak_status_changed();
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tui_jailbreak_stage = 2;
|
||||
tui_jailbreak_status = "Running exploit";
|
||||
tui_jailbreak_status_changed();
|
||||
|
||||
if (exec_checkra1n() != 0) {
|
||||
tui_jailbreak_status = "ERROR: Failed to run exploit";
|
||||
tui_jailbreak_status_changed();
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tui_jailbreak_stage = 3;
|
||||
tui_jailbreak_status = "Waiting for PongoOS";
|
||||
tui_jailbreak_status_changed();
|
||||
|
||||
sleep(2);
|
||||
pthread_create(&pongo_thread, NULL, pongo_helper, NULL);
|
||||
|
||||
// pongo helper will take care of the rest
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void tui_jailbreak(void) {
|
||||
tui_is_jailbreaking = true;
|
||||
if (tui_options_verbose_boot) {
|
||||
palerain_flags |= palerain_option_verbose_boot;
|
||||
} else {
|
||||
palerain_flags &= ~palerain_option_verbose_boot;
|
||||
}
|
||||
|
||||
if (tui_options_safe_mode) {
|
||||
palerain_flags |= palerain_option_safemode;
|
||||
} else {
|
||||
palerain_flags &= ~palerain_option_safemode;
|
||||
}
|
||||
|
||||
if (tui_options_force_revert) {
|
||||
palerain_flags |= palerain_option_force_revert;
|
||||
} else {
|
||||
palerain_flags &= ~palerain_option_force_revert;
|
||||
}
|
||||
|
||||
snprintf(palerain_flags_cmd, 0x30, "palera1n_flags 0x%" PRIx64, palerain_flags);
|
||||
snprintf(xargs_cmd, sizeof(xargs_cmd), "xargs %s", tui_options_boot_args);
|
||||
|
||||
pthread_create(&tui_jailbreak_thread_id, NULL, tui_jailbreak_thread, NULL);
|
||||
}
|
||||
|
||||
void tui_screen_jailbreak_redraw(void) {
|
||||
PRINTATT(3, 3, "Installing jailbreak, this will take a moment. If the device asks for a");
|
||||
PRINTATT(3, 4, "passcode please enter it. Do not disconnect the device until finished.");
|
||||
|
||||
if (tui_jailbreak_status) {
|
||||
SETCOLOR(FG_YELLOW, BG_BLACK);
|
||||
PRINTATT(3, 6, tui_jailbreak_status);
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
tui_draw_rectangle(5, 9, 80 - 6, 9 + 2);
|
||||
MOVETOT(6 + 1, 10 + 1);
|
||||
SETCOLOR(FG_BLACK, BG_WHITE);
|
||||
for (int i = 0; i < ((80 - 12) * ((float)tui_jailbreak_stage / 9)); i++) {
|
||||
putchar(' ');
|
||||
}
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
|
||||
tui_screen_jailbreak_nav();
|
||||
}
|
||||
|
||||
static int tui_jailbreak_nav_mouse_select = -1;
|
||||
|
||||
tui_screen_t tui_screen_jailbreak(void) {
|
||||
redraw_screen();
|
||||
|
||||
while(1) {
|
||||
int event = tui_get_event();
|
||||
switch (event) {
|
||||
case TUI_EVENT_INPUT: {
|
||||
int input = tui_last_input;
|
||||
if (input == TUI_INPUT_NONE) continue;
|
||||
|
||||
switch (input) {
|
||||
case TUI_INPUT_SELECT:
|
||||
if (!tui_is_jailbreaking) {
|
||||
tui_is_restarting = true;
|
||||
tui_terminate(0);
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_DOWN:
|
||||
if (tui_mouse_y == tui_y_offset + 24 - 2 &&
|
||||
tui_mouse_x >= tui_x_offset + 80 - 12 &&
|
||||
tui_mouse_x <= tui_x_offset + 80 - 12 + 10) {
|
||||
tui_jailbreak_nav_mouse_select = 0;
|
||||
redraw_screen();
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_UP:
|
||||
if (tui_jailbreak_nav_mouse_select == 0) {
|
||||
tui_jailbreak_nav_mouse_select = -1;
|
||||
if (!tui_is_jailbreaking) {
|
||||
tui_is_restarting = true;
|
||||
tui_terminate(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TUI_EVENT_JAILBREAK_STATUS_CHANGED:
|
||||
redraw_screen();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SCREEN;
|
||||
}
|
||||
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
+365
-32
@@ -1,3 +1,4 @@
|
||||
#ifdef TUI
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -12,36 +13,368 @@
|
||||
#include <palerain.h>
|
||||
#include <tui.h>
|
||||
|
||||
tui_screen_t tui_screen_main() {
|
||||
int ret = MAIN_SCREEN;
|
||||
bool can_start = false;
|
||||
newtCenteredWindow(WIDTH, HEIGHT, NULL);
|
||||
newtComponent optionsButton = newtCompactButton(46, 18, "Options");
|
||||
newtComponent startButton = newtCompactButton(57, 18, "Start");
|
||||
newtComponent exitButton = newtCompactButton(66, 18, "Exit");
|
||||
newtComponent welcome = newtLabel(1, 0, "Welcome to palera1n!");
|
||||
newtComponent deviceMsg = newtTextbox(1, 2, 40, 3, NEWT_FLAG_WRAP);
|
||||
set_tui_log(deviceMsg);
|
||||
LOG(LOG_INFO, "Connect your iPhone, iPad or iPod Touch to begin.");
|
||||
newtTextboxSetColors(deviceMsg, PI_LOG_COLOR, PI_LOG_COLOR);
|
||||
set_tui_log(deviceMsg);
|
||||
newtComponent form = newtForm(NULL, NULL, 0);
|
||||
newtFormAddComponents(form, optionsButton, startButton, exitButton, welcome,
|
||||
deviceMsg, NULL);
|
||||
newtRunForm(form);
|
||||
newtRefresh();
|
||||
newtComponent buttonPressed = newtFormGetCurrent(form);
|
||||
if (buttonPressed == optionsButton) {
|
||||
ret = OPTIONS_SCREEN;
|
||||
} else if (buttonPressed == startButton) {
|
||||
if (can_start)
|
||||
ret = ENTER_RECOVERY_SCREEN;
|
||||
else
|
||||
ret = MAIN_SCREEN;
|
||||
} else if (buttonPressed == exitButton) {
|
||||
ret = EXIT_SCREEN;
|
||||
}
|
||||
set_tui_log(NULL);
|
||||
newtFormDestroy(form);
|
||||
return ret;
|
||||
static int tui_compare_versions(const char *firstVersion, const char *secondVersion);
|
||||
|
||||
static bool showing_ecid = false;
|
||||
|
||||
static char palera1n_logo[17][16] = {
|
||||
" ++ ",
|
||||
" #@@# ",
|
||||
" +@@@@+ ",
|
||||
" :@@@@@@: ",
|
||||
" #@@@@@@# ",
|
||||
" +@@@@@@@@+ ",
|
||||
" :#*@@@@@@*#: ",
|
||||
" %###@@@@###% ",
|
||||
" .####%@@%####. ",
|
||||
" @############@ ",
|
||||
"=@@*########*@@=",
|
||||
"+@@@@%####%@@@@+",
|
||||
":@@@@%%**%%@@@@:",
|
||||
" +@@%%*@@*%%@@+ ",
|
||||
" ++%@@@@%++ ",
|
||||
" :++: "
|
||||
};
|
||||
|
||||
static char random_quotes[][150] = {
|
||||
"panic(cpu 1 caller 0xfffffff0232bd958): SEP Panic",
|
||||
"Now with Apple TV support!",
|
||||
"checkra1n will open source in 2020",
|
||||
"Try running palera1n on a Intel 80486!",
|
||||
"\"iOS 15 with SSV is unhackable\", but here we are.",
|
||||
"initproc exited -- exit reason namespace 1 subcode0x7 description: none",
|
||||
"totally not checkra1n",
|
||||
"Because the command line wasn't easy enough",
|
||||
"Checkra1n wrapper?",
|
||||
""
|
||||
};
|
||||
|
||||
#define PALERA1N_URL "https://palera.in"
|
||||
|
||||
static int tui_main_nav_selection = 1;
|
||||
static bool quick_mode_enabled = false;
|
||||
static bool tui_can_start = false;
|
||||
static int random_quote;
|
||||
|
||||
bool easter_egg = false;
|
||||
|
||||
void tui_screen_main_nav(void) {
|
||||
MOVETOT(80 - 52, 23);
|
||||
printf("[%c] %sQuick Mode " COLOR(FG_WHITE, BG_BLACK) " %s[ Options ]" COLOR(FG_WHITE, BG_BLACK) " %s[ Start ]" COLOR(FG_WHITE, BG_BLACK) " %s[ Quit ]" COLOR(FG_WHITE, BG_BLACK), quick_mode_enabled ? 'x' : ' ',
|
||||
tui_main_nav_selection == 0 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 49 && tui_mouse_x <= tui_x_offset + 80 - 49 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
),
|
||||
tui_main_nav_selection == 1 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 37 && tui_mouse_x <= tui_x_offset + 80 - 37 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
),
|
||||
tui_main_nav_selection == 2 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : !tui_can_start ? (supports_bright_colors ? COLOR(FG_BRIGHT_BLACK, BG_BLACK) : COLOR(FG_BLUE, BG_BLACK)) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 25 && tui_mouse_x <= tui_x_offset + 80 - 25 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
),
|
||||
tui_main_nav_selection == 3 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 13 && tui_mouse_x <= tui_x_offset + 80 - 13 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void tui_screen_main_redraw(void) {
|
||||
PRINTATT(3, 2, "Welcome to palera1n!");
|
||||
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
PRINTATT(3, 9, "Made by: Nick Chan, Ploosh, Khcrysalis, Mineek");
|
||||
PRINTATT(3, 10, "staturnz, kok3shidoll, ");
|
||||
if ((tui_mouse_y == tui_y_offset + 9 && tui_mouse_x >= tui_x_offset + 25 && tui_mouse_x <= tui_x_offset + 25 + 8) || easter_egg) {
|
||||
SETCOLORA(FG_BRIGHT_WHITE, BG_BLACK, BOLD);
|
||||
}
|
||||
printf("HAHALOSAH");
|
||||
RESETFONT;
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
PRINTATT(3, 12, "Thanks to: llsc12, nebula,");
|
||||
PRINTATT(3, 13, "nikias (libimobiledevice), checkra1n");
|
||||
PRINTATT(3, 14, "(Siguza, axi0mx, littlelailo et al.), Procursus");
|
||||
PRINTATT(3, 15, "Team (Hayden Seay, Cameron Katri, Keto et.al),");
|
||||
PRINTATT(80 - (int)sizeof(PALERA1N_URL), 21, PALERA1N_URL);
|
||||
PRINTATT(80 - (int)sizeof("@palera1n"), 20, "@palera1n");
|
||||
PRINTATT(3, 20, "With <3 from HAHALOSAH");
|
||||
PRINTATT(3, 21, "Note: Backup your stuff. Use at your own risk.");
|
||||
DRAWLINET(2, 22, 78);
|
||||
DRAWLINET(2, 3, 50);
|
||||
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
DRAWLINET(2, 11, 50);
|
||||
DRAWLINET(2, 16, 50);
|
||||
|
||||
for (int y = 0; y < 16; y++) {
|
||||
PRINTATLENT(80 - 22, y + 4, palera1n_logo[y], 16);
|
||||
}
|
||||
|
||||
SETCOLOR(FG_YELLOW, BG_BLACK);
|
||||
if (tui_connected_devices == NULL) {
|
||||
PRINTATT(3, 5, "Connect your iPhone, iPad, iPod Touch, or Apple");
|
||||
PRINTATT(3, 6, "TV to begin.");
|
||||
tui_can_start = false;
|
||||
} else if (tui_connected_devices->next != NULL) {
|
||||
PRINTATT(3, 5, "Please attach only one device.");
|
||||
tui_can_start = false;
|
||||
} else {
|
||||
if (strlen(tui_connected_devices->display_name) == 0) {
|
||||
PRINTATT(3, 5, "ERROR: Failed to open device in recovery/DFU mode");
|
||||
PRINTATT(3, 6, "Please reopen palera1n and try again.");
|
||||
} else if (tui_connected_devices->mode == TUI_DEVICE_MODE_NORMAL) {
|
||||
MOVETOT(3, 5);
|
||||
int ecid_y;
|
||||
if (!tui_connected_devices->arm64) {
|
||||
printf("Sorry, %s (iOS %s) is not supported.", tui_connected_devices->display_name, tui_connected_devices->version);
|
||||
ecid_y = 6;
|
||||
tui_can_start = false;
|
||||
} else if (tui_compare_versions(tui_connected_devices->version, "15.0") < 0) {
|
||||
printf("Sorry, %s is supported, but iOS", tui_connected_devices->display_name);
|
||||
MOVETOT(3, 6);
|
||||
printf("%s is not.", tui_connected_devices->version);
|
||||
PRINTATT(3, 7, "Supported versions are 15.0+");
|
||||
ecid_y = 8;
|
||||
tui_can_start = false;
|
||||
} else if (tui_connected_devices->requires_passcode_disabled) {
|
||||
printf("Sorry, this devices passcode must be disabled on %s.", tui_connected_devices->version);
|
||||
MOVETOT(3, 6);
|
||||
printf("On 16.0+, you must reset the phone to factory settings");
|
||||
MOVETOT(3, 7);
|
||||
printf("and not have a passcode enabled ever since last restore.");
|
||||
ecid_y = 8;
|
||||
tui_can_start = false;
|
||||
} else {
|
||||
printf("%s (%s) connected in Normal mode.", tui_connected_devices->display_name, tui_connected_devices->version);
|
||||
ecid_y = 6;
|
||||
tui_can_start = true;
|
||||
}
|
||||
if (showing_ecid) {
|
||||
MOVETOT(3, ecid_y);
|
||||
printf("ECID: 0x%" PRIx64 " ", tui_connected_devices->ecid);
|
||||
} else {
|
||||
PRINTATT(3, ecid_y, "Press (E) to show ECID.");
|
||||
}
|
||||
} else if (tui_connected_devices->mode == TUI_DEVICE_MODE_RECOVERY) {
|
||||
MOVETOT(3, 5);
|
||||
printf("%s connected in Recovery mode.", tui_connected_devices->display_name);
|
||||
if (showing_ecid) {
|
||||
MOVETOT(3, 6);
|
||||
printf("ECID: 0x%" PRIx64 " ", tui_connected_devices->ecid);
|
||||
} else {
|
||||
PRINTATT(3, 6, "Press (E) to show ECID.");
|
||||
}
|
||||
PRINTATT(3, 7, "NOTE: Ensure installed iOS is in range 15.0+");
|
||||
tui_can_start = true;
|
||||
} else if (tui_connected_devices->mode == TUI_DEVICE_MODE_DFU) {
|
||||
MOVETOT(3, 5);
|
||||
printf("%s connected in DFU mode.", tui_connected_devices->display_name);
|
||||
if (showing_ecid) {
|
||||
MOVETOT(3, 6);
|
||||
printf("ECID: 0x%" PRIx64 " ", tui_connected_devices->ecid);
|
||||
} else {
|
||||
PRINTATT(3, 6, "Press (E) to show ECID.");
|
||||
}
|
||||
#ifdef DEV_BUILD
|
||||
tui_can_start = true;
|
||||
#else
|
||||
PRINTATT(3, 7, "Please connect device in Normal/Recovery mode");
|
||||
PRINTATT(3, 8, "or run palera1n in CLI mode");
|
||||
tui_can_start = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!tui_can_start && tui_main_nav_selection == 2) {
|
||||
tui_main_nav_selection = 1;
|
||||
}
|
||||
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
|
||||
for (int y = 0; y < 3; y++) {
|
||||
PRINTATLEN(tui_x_offset + 3, tui_y_offset + 17 + y, random_quotes[random_quote] + y * 50, 50);
|
||||
}
|
||||
|
||||
tui_screen_main_nav();
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static int tui_main_nav_mouse_select = -1;
|
||||
|
||||
tui_screen_t tui_screen_main(void) {
|
||||
random_quote = ((unsigned int)((rand()+rand())/2)) % 8;
|
||||
redraw_screen();
|
||||
|
||||
while(1) {
|
||||
int event = tui_get_event();
|
||||
switch (event) {
|
||||
case TUI_EVENT_CONNECTED_DEVICES_CHANGED:
|
||||
redraw_screen();
|
||||
break;
|
||||
case TUI_EVENT_INPUT: {
|
||||
int input = tui_last_input;
|
||||
|
||||
switch (input) {
|
||||
case TUI_INPUT_NONE:
|
||||
if (tui_last_key == 'E' || tui_last_key == 'e') {
|
||||
showing_ecid = !showing_ecid;
|
||||
tui_screen_main_redraw();
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_LEFT:
|
||||
case TUI_INPUT_TAB_BACK:
|
||||
if (--tui_main_nav_selection == -1) tui_main_nav_selection = 3;
|
||||
if (tui_main_nav_selection == 2 && !tui_can_start) tui_main_nav_selection = 1;
|
||||
tui_screen_main_nav();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case TUI_INPUT_RIGHT:
|
||||
case TUI_INPUT_TAB:
|
||||
if (++tui_main_nav_selection == 4) tui_main_nav_selection = 0;
|
||||
if (tui_main_nav_selection == 2 && !tui_can_start) tui_main_nav_selection = 3;
|
||||
tui_screen_main_nav();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case TUI_INPUT_SELECT:
|
||||
switch(tui_main_nav_selection) {
|
||||
case 0:
|
||||
quick_mode_enabled = !quick_mode_enabled;
|
||||
tui_screen_main_nav();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case 1:
|
||||
return OPTIONS_SCREEN;
|
||||
case 2:
|
||||
if (tui_can_start) {
|
||||
if (tui_connected_devices->mode == TUI_DEVICE_MODE_NORMAL) {
|
||||
return ENTER_RECOVERY_SCREEN;
|
||||
} else if (tui_connected_devices->mode == TUI_DEVICE_MODE_RECOVERY) {
|
||||
return ENTER_DFU_SCREEN;
|
||||
} else if (tui_connected_devices->mode == TUI_DEVICE_MODE_DFU) {
|
||||
tui_jailbreak();
|
||||
return JAILBREAK_SCREEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
return EXIT_SCREEN;
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_MOVE:
|
||||
tui_screen_main_redraw();
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_DOWN:
|
||||
if ((tui_mouse_y == tui_y_offset + 9 && tui_mouse_x >= tui_x_offset + 25 && tui_mouse_x <= tui_x_offset + 25 + 8)) {
|
||||
easter_egg = true;
|
||||
break;
|
||||
}
|
||||
if (tui_mouse_y == tui_y_offset + 22) {
|
||||
if (tui_mouse_x >= tui_x_offset + 80 - 49 && tui_mouse_x <= tui_x_offset + 80 - 49 + 10) {
|
||||
tui_main_nav_selection = 0;
|
||||
tui_main_nav_mouse_select = 0;
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 37 && tui_mouse_x <= tui_x_offset + 80 - 37 + 10) {
|
||||
tui_main_nav_selection = 1;
|
||||
tui_main_nav_mouse_select = 1;
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 25 && tui_mouse_x <= tui_x_offset + 80 - 25 + 10) {
|
||||
if (tui_can_start) {
|
||||
tui_main_nav_selection = 2;
|
||||
tui_main_nav_mouse_select = 2;
|
||||
}
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 13 && tui_mouse_x <= tui_x_offset + 80 - 13 + 10) {
|
||||
tui_main_nav_selection = 3;
|
||||
tui_main_nav_mouse_select = 3;
|
||||
}
|
||||
tui_screen_main_nav();
|
||||
fflush(stdout);
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_UP:
|
||||
if (tui_mouse_y == tui_y_offset + 22) {
|
||||
if (tui_mouse_x >= tui_x_offset + 80 - 49 && tui_mouse_x <= tui_x_offset + 80 - 49 + 10 && tui_main_nav_mouse_select == 0) {
|
||||
quick_mode_enabled = !quick_mode_enabled;
|
||||
redraw_screen();
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 37 && tui_mouse_x <= tui_x_offset + 80 - 37 + 10 && tui_main_nav_mouse_select == 1) {
|
||||
return OPTIONS_SCREEN;
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 25 && tui_mouse_x <= tui_x_offset + 80 - 25 + 10 && tui_main_nav_mouse_select == 2) {
|
||||
if (tui_can_start) {
|
||||
if (tui_connected_devices->mode == TUI_DEVICE_MODE_NORMAL) {
|
||||
return ENTER_RECOVERY_SCREEN;
|
||||
} else if (tui_connected_devices->mode == TUI_DEVICE_MODE_RECOVERY) {
|
||||
return ENTER_DFU_SCREEN;
|
||||
} else if (tui_connected_devices->mode == TUI_DEVICE_MODE_DFU) {
|
||||
tui_jailbreak();
|
||||
return JAILBREAK_SCREEN;
|
||||
}
|
||||
}
|
||||
} else if (tui_mouse_x >= tui_x_offset + 80 - 13 && tui_mouse_x <= tui_x_offset + 80 - 13 + 10 && tui_main_nav_mouse_select == 3) {
|
||||
return EXIT_SCREEN;
|
||||
}
|
||||
}
|
||||
tui_main_nav_mouse_select = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return MAIN_SCREEN;
|
||||
}
|
||||
|
||||
static int tui_version_extract_component(const char *version, int index) {
|
||||
int component = 0;
|
||||
int componentIndex = 0;
|
||||
for (int i = 0; version[i] != '\0'; i++) {
|
||||
if (version[i] == '.') {
|
||||
componentIndex++;
|
||||
if (componentIndex > index) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (componentIndex == index) {
|
||||
component *= 10;
|
||||
component += version[i] - '0';
|
||||
}
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
static int tui_compare_versions(const char *firstVersion, const char *secondVersion) {
|
||||
if (strcmp(firstVersion, secondVersion) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int firstVersionMajor = tui_version_extract_component(firstVersion, 0);
|
||||
int firstVersionMinor = tui_version_extract_component(firstVersion, 1);
|
||||
int firstVersionPatch = tui_version_extract_component(firstVersion, 2);
|
||||
|
||||
int secondVersionMajor = tui_version_extract_component(secondVersion, 0);
|
||||
int secondVersionMinor = tui_version_extract_component(secondVersion, 1);
|
||||
int secondVersionPatch = tui_version_extract_component(secondVersion, 2);
|
||||
|
||||
if (firstVersionMajor != secondVersionMajor) {
|
||||
return firstVersionMajor - secondVersionMajor;
|
||||
}
|
||||
|
||||
if (firstVersionMinor != secondVersionMinor) {
|
||||
return firstVersionMinor - secondVersionMinor;
|
||||
}
|
||||
|
||||
return firstVersionPatch - secondVersionPatch;
|
||||
}
|
||||
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
+318
-54
@@ -1,3 +1,4 @@
|
||||
#ifdef TUI
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -12,66 +13,329 @@
|
||||
#include <palerain.h>
|
||||
#include <tui.h>
|
||||
|
||||
void bitfield_check_cb(newtComponent box, void* data) {
|
||||
if (newtCheckboxGetValue(box) == ' ') {
|
||||
*((tui_bit_info_t*)data)->flags_p = *((tui_bit_info_t*)data)->flags_p &~ ((tui_bit_info_t*)data)->opt;
|
||||
} else if (newtCheckboxGetValue(box) == '*') {
|
||||
*((tui_bit_info_t*)data)->flags_p |= ((tui_bit_info_t*)data)->opt;
|
||||
} else assert(0);
|
||||
static int tui_options_nav_selection = 0;
|
||||
static int tui_options_nav_mouse_select = 0;
|
||||
|
||||
static bool tui_options_allow_untested = false;
|
||||
bool tui_options_safe_mode = false;
|
||||
bool tui_options_verbose_boot = false;
|
||||
bool tui_options_force_revert = false;
|
||||
bool tui_options_flower_chain = true;
|
||||
|
||||
bool tui_options_is_editing_boot_args = false;
|
||||
|
||||
char tui_options_boot_args[0x1e0 + 1] = {0};
|
||||
|
||||
int tui_options_boot_args_cursor = 0;
|
||||
int tui_options_boot_args_offset = 0;
|
||||
|
||||
void tui_screen_options_nav(void) {
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
MOVETOT(80 - 11, 23);
|
||||
printf("%s[ Back ]" COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_options_nav_selection == 0 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 80 - 12 && tui_mouse_x <= tui_x_offset + 80 - 12 + 10
|
||||
) && (tui_mouse_y == tui_y_offset + 22) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
)
|
||||
);
|
||||
#ifdef DEV_BUILD
|
||||
PRINTATT(3, 23, "DEV_BUILD");
|
||||
#endif
|
||||
}
|
||||
|
||||
extern bool easter_egg;
|
||||
|
||||
tui_screen_t tui_screen_options() {
|
||||
tui_bit_info_t verbose_info = { &kpf_flags, checkrain_option_verbose_boot };
|
||||
tui_bit_info_t rootful_info = { &palerain_flags, palerain_option_rootful };
|
||||
tui_bit_info_t setup_rootful_info = { &palerain_flags, palerain_option_setup_rootful };
|
||||
tui_bit_info_t force_revert_info = { &checkrain_flags, checkrain_option_force_revert };
|
||||
tui_bit_info_t safemode_info = { &checkrain_flags, checkrain_option_safemode };
|
||||
void tui_screen_options_options(void) {
|
||||
SETCOLOR( FG_BRIGHT_BLACK, BG_BLACK);
|
||||
MOVETOT(3, 8);
|
||||
printf("[%c] %sAllow untested iOS/iPadOS versions" COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_options_allow_untested ? ' ' : ' ',
|
||||
COLOR(FG_BLACK, FG_BRIGHT_BLACK));
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
MOVETOT(3, 9);
|
||||
printf("[%c] %sSafe Mode " COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_options_safe_mode ? 'x' : ' ',
|
||||
tui_options_nav_selection == 1 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 5 && tui_mouse_x <= tui_x_offset + 5 + 34
|
||||
) && (tui_mouse_y == tui_y_offset + 8) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
));
|
||||
MOVETOT(3, 10);
|
||||
printf("[%c] %sVerbose Boot " COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_options_verbose_boot ? 'x' : ' ',
|
||||
tui_options_nav_selection == 2 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 5 && tui_mouse_x <= tui_x_offset + 5 + 34
|
||||
) && (tui_mouse_y == tui_y_offset + 9) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
));
|
||||
MOVETOT(3, 11);
|
||||
printf("[%c] %sForce Revert " COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_options_force_revert ? 'x' : ' ',
|
||||
tui_options_nav_selection == 3 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 5 && tui_mouse_x <= tui_x_offset + 5 + 34
|
||||
) && (tui_mouse_y == tui_y_offset + 10) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
));
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
DRAWLINET(3, 13, 76);
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
MOVETOT(7, 15);
|
||||
printf("%sBoot Arguments: " COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_options_nav_selection == 4 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 5 && tui_mouse_x <= tui_x_offset + 5 + 34
|
||||
) && (
|
||||
tui_mouse_y == tui_y_offset + 14 || tui_mouse_y == tui_y_offset + 15
|
||||
) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
));
|
||||
const char* boot_args_hint = tui_options_is_editing_boot_args ? "(press ENTER when done)" : " (press ENTER to edit)";
|
||||
MOVETOT((int)(80 - 5 - strlen(boot_args_hint)), 15);
|
||||
printf("%s", boot_args_hint);
|
||||
MOVETOT(3, 17);
|
||||
printf("[%c] %s%s " COLOR(FG_WHITE, BG_BLACK),
|
||||
tui_options_flower_chain ? 'x' : ' ',
|
||||
tui_options_nav_selection == 5 ? COLOR(FG_BLACK, BG_BRIGHT_WHITE) : (
|
||||
(
|
||||
tui_mouse_x >= tui_x_offset + 5 && tui_mouse_x <= tui_x_offset + 5 + 34
|
||||
) && (tui_mouse_y == tui_y_offset + 16) ? COLOR(FG_BLACK, BG_WHITE) : ""
|
||||
), easter_egg ? "Neko Chain " : "Flower Chain");
|
||||
|
||||
static checkrain_option_t flower_flags = 0, flower_option_flower_chain = (1 << 0);
|
||||
tui_bit_info_t flower_chain_info = { &flower_flags, flower_option_flower_chain };
|
||||
|
||||
const char* bootargs_entered = NULL;
|
||||
int ret = MAIN_SCREEN;
|
||||
MOVETOT(7, 16);
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(tui_options_is_editing_boot_args ? FG_YELLOW : FG_WHITE, BG_BRIGHT_BLACK);
|
||||
} else {
|
||||
SETCOLOR(tui_options_is_editing_boot_args ? FG_YELLOW : FG_WHITE, BG_BLUE);
|
||||
}
|
||||
int boot_args_len = strlen(tui_options_boot_args);
|
||||
|
||||
newtCenteredWindow(WIDTH, HEIGHT, NULL);
|
||||
newtComponent backButton = newtCompactButton(66, 18, "Back");
|
||||
if ((tui_options_boot_args_cursor - tui_options_boot_args_offset) > (68 - 1)) {
|
||||
tui_options_boot_args_offset += (tui_options_boot_args_cursor - tui_options_boot_args_offset) - (68 - 1);
|
||||
}
|
||||
if ((tui_options_boot_args_cursor - tui_options_boot_args_offset) < 0) {
|
||||
tui_options_boot_args_offset = tui_options_boot_args_cursor;
|
||||
}
|
||||
if ((tui_options_boot_args_offset + 68 - 1) > boot_args_len && boot_args_len >= 68 - 1) {
|
||||
tui_options_boot_args_offset = boot_args_len - 68 + 1;
|
||||
}
|
||||
|
||||
newtComponent optionsNotice = newtTextbox(1, 0, WIDTH - 2, 3, NEWT_FLAG_WRAP);
|
||||
newtTextboxSetText(optionsNotice, "You may set the following options. If you don't know what they mean you'll probably have no reason to set them.");
|
||||
// newtTextboxSetColors(optionsNotice, NEWT_COLORSET_LABEL, NEWT_COLORSET_LABEL);
|
||||
for (int i = 0; i < 68; i++) {
|
||||
putchar(((i + tui_options_boot_args_offset) < boot_args_len) ? tui_options_boot_args[i + tui_options_boot_args_offset] : ' ');
|
||||
}
|
||||
|
||||
newtComponent verboseBootBox = newtCheckbox(1, 3, "Verbose boot", CHECKBOX_STATE(kpf_flags, checkrain_option_verbose_boot), NULL, NULL);
|
||||
newtComponent rootfulBox = newtCheckbox(1, 4, "Rootful", CHECKBOX_STATE(palerain_flags, palerain_option_rootful), NULL, NULL);
|
||||
newtComponent rootfulSetupBox = newtCheckbox(1, 5, "Setup fakefs", CHECKBOX_STATE(palerain_flags, palerain_option_setup_rootful), NULL, NULL);
|
||||
newtComponent forceRevertBox = newtCheckbox(1, 6, "Restore system", CHECKBOX_STATE(checkrain_flags, checkrain_option_force_revert), NULL, NULL);
|
||||
newtComponent safeModeBox = newtCheckbox(1, 7, "Safe mode", CHECKBOX_STATE(checkrain_flags, checkrain_option_safemode), NULL, NULL);
|
||||
if (tui_options_is_editing_boot_args) {
|
||||
MOVETOT((int)(7 + tui_options_boot_args_cursor - tui_options_boot_args_offset), 16);
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_YELLOW);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_YELLOW);
|
||||
}
|
||||
putchar(tui_options_boot_args_cursor < boot_args_len ? tui_options_boot_args[tui_options_boot_args_cursor] : ' ');
|
||||
}
|
||||
|
||||
newtComponentAddCallback(verboseBootBox, bitfield_check_cb, &verbose_info);
|
||||
newtComponentAddCallback(rootfulBox, bitfield_check_cb, &rootful_info);
|
||||
newtComponentAddCallback(rootfulSetupBox, bitfield_check_cb, &setup_rootful_info);
|
||||
newtComponentAddCallback(forceRevertBox, bitfield_check_cb, &force_revert_info);
|
||||
newtComponentAddCallback(safeModeBox, bitfield_check_cb, &safemode_info);
|
||||
|
||||
newtComponent bootCmdlineLabel = newtLabel(1, 8, "Kernel command line:");
|
||||
newtComponent bootCmdlineEntry = newtEntry(1, 9, &xargs_cmd[6], WIDTH - 2, &bootargs_entered, NEWT_ENTRY_SCROLL);
|
||||
|
||||
newtComponent flowerChainBox = newtCheckbox(1, 10, "Flower chain", CHECKBOX_STATE(flower_flags, flower_option_flower_chain), NULL, NULL);
|
||||
newtComponentAddCallback(flowerChainBox, bitfield_check_cb, &flower_chain_info);
|
||||
|
||||
|
||||
newtComponent form = newtForm(NULL, NULL, 0);
|
||||
newtFormAddComponents(form, backButton, verboseBootBox, rootfulBox,
|
||||
rootfulSetupBox, forceRevertBox, safeModeBox, bootCmdlineLabel,
|
||||
bootCmdlineEntry, flowerChainBox, optionsNotice,
|
||||
NULL);
|
||||
newtRunForm(form);
|
||||
newtRefresh();
|
||||
snprintf(xargs_cmd, 0x270, "xargs %s", bootargs_entered);
|
||||
newtComponent buttonPressed = newtFormGetCurrent(form);
|
||||
if (buttonPressed == backButton) {
|
||||
ret = MAIN_SCREEN;
|
||||
} else ret = MAIN_SCREEN;
|
||||
newtFormDestroy(form);
|
||||
return ret;
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
MOVETOT(5, 16);
|
||||
printf(tui_options_boot_args_offset > 0 ? "<<" : " ");
|
||||
MOVETOT(75, 16);
|
||||
printf((strlen(tui_options_boot_args) - tui_options_boot_args_offset) > 68 ? ">>" : " ");
|
||||
}
|
||||
|
||||
void tui_screen_options_redraw(void) {
|
||||
SETCOLOR(FG_WHITE, BG_BLACK);
|
||||
PRINTATT(3, 3, "You may set the following options. If you don't know what they mean you'll");
|
||||
PRINTATT(3, 4, "probably have no reason to set them.");
|
||||
if (supports_bright_colors) {
|
||||
SETCOLOR(FG_BRIGHT_BLACK, BG_BLACK);
|
||||
} else {
|
||||
SETCOLOR(FG_BLUE, BG_BLACK);
|
||||
}
|
||||
DRAWLINET(3, 6, 76);
|
||||
tui_screen_options_nav();
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
tui_screen_t tui_screen_options(void) {
|
||||
redraw_screen();
|
||||
|
||||
while(1) {
|
||||
int event = tui_get_event();
|
||||
if (event != TUI_EVENT_INPUT) continue;
|
||||
int input = tui_last_input;
|
||||
|
||||
switch (input) {
|
||||
case TUI_INPUT_DOWN:
|
||||
case TUI_INPUT_TAB:
|
||||
if (tui_options_is_editing_boot_args) break;
|
||||
if (++tui_options_nav_selection > 5) tui_options_nav_selection = 0;
|
||||
tui_screen_options_nav();
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case TUI_INPUT_UP:
|
||||
case TUI_INPUT_TAB_BACK:
|
||||
if (tui_options_is_editing_boot_args) break;
|
||||
if (--tui_options_nav_selection < 0) tui_options_nav_selection = 5;
|
||||
tui_screen_options_nav();
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case TUI_INPUT_SELECT:
|
||||
if (tui_options_is_editing_boot_args && tui_last_key == ' ' && tui_options_boot_args[strlen(tui_options_boot_args)] == '\x00') {
|
||||
int len = strlen(tui_options_boot_args);
|
||||
tui_options_boot_args[len] = ' ';
|
||||
tui_options_boot_args[len + 1] = '\x00';
|
||||
tui_options_boot_args_cursor++;
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
break;
|
||||
}
|
||||
switch(tui_options_nav_selection) {
|
||||
case 0:
|
||||
return MAIN_SCREEN;
|
||||
// case 1:
|
||||
// tui_options_allow_untested = !tui_options_allow_untested;
|
||||
// break;
|
||||
case 1:
|
||||
tui_options_safe_mode = !tui_options_safe_mode;
|
||||
break;
|
||||
case 2:
|
||||
tui_options_verbose_boot = !tui_options_verbose_boot;
|
||||
break;
|
||||
case 3:
|
||||
tui_options_force_revert = !tui_options_force_revert;
|
||||
break;
|
||||
case 4:
|
||||
tui_options_is_editing_boot_args = !tui_options_is_editing_boot_args;
|
||||
tui_options_boot_args_cursor = tui_options_is_editing_boot_args ? strlen(tui_options_boot_args) : 0;
|
||||
break;
|
||||
case 5:
|
||||
tui_options_flower_chain = !tui_options_flower_chain;
|
||||
break;
|
||||
}
|
||||
tui_screen_options_nav();
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_MOVE:
|
||||
tui_screen_options_nav();
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_DOWN:
|
||||
if (tui_mouse_y == tui_y_offset + 24 - 2 &&
|
||||
tui_mouse_x >= tui_x_offset + 80 - 12 &&
|
||||
tui_mouse_x <= tui_x_offset + 80 - 12 + 10) {
|
||||
tui_options_nav_selection = 0;
|
||||
tui_options_nav_mouse_select = 0;
|
||||
redraw_screen();
|
||||
}
|
||||
|
||||
#define MOUSEDOWN_HANDLER(y, val) \
|
||||
if (tui_mouse_y == tui_y_offset + y && \
|
||||
tui_mouse_x >= tui_x_offset + 5 - 4 && \
|
||||
tui_mouse_x <= tui_x_offset + 5 + 34) { \
|
||||
tui_options_nav_selection = val; \
|
||||
tui_options_nav_mouse_select = val; \
|
||||
tui_screen_options_nav(); \
|
||||
tui_screen_options_options(); \
|
||||
fflush(stdout); \
|
||||
}
|
||||
|
||||
if (!tui_options_is_editing_boot_args) {
|
||||
MOUSEDOWN_HANDLER(8, 1);
|
||||
MOUSEDOWN_HANDLER(9, 2);
|
||||
MOUSEDOWN_HANDLER(10, 3);
|
||||
MOUSEDOWN_HANDLER(16, 5);
|
||||
}
|
||||
|
||||
MOUSEDOWN_HANDLER(14, 4);
|
||||
MOUSEDOWN_HANDLER(15, 4);
|
||||
|
||||
#undef MOUSEDOWN_HANDLER
|
||||
break;
|
||||
case TUI_INPUT_MOUSE_UP:
|
||||
if (tui_mouse_y == tui_y_offset + 24 - 2 &&
|
||||
tui_mouse_x >= tui_x_offset + 80 - 12 &&
|
||||
tui_mouse_x <= tui_x_offset + 80 - 12 + 10 &&
|
||||
tui_options_nav_mouse_select == 0) {
|
||||
return MAIN_SCREEN;
|
||||
}
|
||||
|
||||
#define MOUSEUP_HANDLER(y, val, option, e) \
|
||||
if (tui_mouse_y == tui_y_offset + y && \
|
||||
tui_mouse_x >= tui_x_offset + 5 - 4 && \
|
||||
tui_mouse_x <= tui_x_offset + 5 + 34 && \
|
||||
tui_options_nav_mouse_select == val) { \
|
||||
tui_options_##option = !tui_options_##option; \
|
||||
e \
|
||||
tui_screen_options_nav(); \
|
||||
tui_screen_options_options(); \
|
||||
fflush(stdout); \
|
||||
}
|
||||
|
||||
if (!tui_options_is_editing_boot_args) {
|
||||
MOUSEUP_HANDLER(8, 1, safe_mode, );
|
||||
MOUSEUP_HANDLER(9, 2, verbose_boot, );
|
||||
MOUSEUP_HANDLER(10, 3, force_revert, );
|
||||
MOUSEUP_HANDLER(16, 5, flower_chain, );
|
||||
}
|
||||
|
||||
#define BOOTARGS_HANDLER \
|
||||
tui_options_boot_args_cursor = tui_options_is_editing_boot_args ? strlen(tui_options_boot_args) : 0;
|
||||
|
||||
MOUSEUP_HANDLER(14, 4, is_editing_boot_args, BOOTARGS_HANDLER);
|
||||
MOUSEUP_HANDLER(15, 4, is_editing_boot_args, BOOTARGS_HANDLER);
|
||||
#undef MOUSEUP_HANDLER
|
||||
tui_options_nav_mouse_select = -1;
|
||||
break;
|
||||
case TUI_INPUT_BACKSPACE:
|
||||
if (tui_options_is_editing_boot_args && tui_options_boot_args_cursor > 0) {
|
||||
memmove(tui_options_boot_args + tui_options_boot_args_cursor - 1, tui_options_boot_args + tui_options_boot_args_cursor, strlen(tui_options_boot_args) - tui_options_boot_args_cursor);
|
||||
tui_options_boot_args[strlen(tui_options_boot_args) - 1] = '\x00';
|
||||
tui_options_boot_args_cursor--;
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_NONE:
|
||||
if (tui_options_is_editing_boot_args && tui_options_boot_args[strlen(tui_options_boot_args)] == '\x00') {
|
||||
int len = strlen(tui_options_boot_args);
|
||||
memmove(tui_options_boot_args + tui_options_boot_args_cursor + 1, tui_options_boot_args + tui_options_boot_args_cursor, strlen(tui_options_boot_args) - tui_options_boot_args_cursor);
|
||||
tui_options_boot_args[tui_options_boot_args_cursor] = tui_last_key;
|
||||
tui_options_boot_args[len + 1] = '\x00';
|
||||
tui_options_boot_args_cursor++;
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_LEFT:
|
||||
if (tui_options_is_editing_boot_args) {
|
||||
if (tui_options_boot_args_cursor > 0) {
|
||||
tui_options_boot_args_cursor--;
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TUI_INPUT_RIGHT:
|
||||
if (tui_options_is_editing_boot_args) {
|
||||
if (tui_options_boot_args_cursor < (int)strlen(tui_options_boot_args)) {
|
||||
tui_options_boot_args_cursor++;
|
||||
tui_screen_options_options();
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
@@ -5,8 +5,6 @@
|
||||
<true/>
|
||||
<key>com.apple.private.security.no-container</key>
|
||||
<true/>
|
||||
<key>com.apple.private.skip-library-validation</key>
|
||||
<true/>
|
||||
<key>com.apple.security.iokit-user-client-class</key>
|
||||
<array>
|
||||
<string>IOUserClient</string>
|
||||
|
||||
+6
-1
@@ -24,6 +24,7 @@
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef USE_LIBUSB
|
||||
#include <errno.h>
|
||||
#include <fcntl.h> // open
|
||||
#include <pthread.h>
|
||||
@@ -207,7 +208,7 @@ static const int pongo_usb_product = PONGO_USB_PRODUCT;
|
||||
|
||||
int wait_for_pongo(void) {
|
||||
kern_return_t ret;
|
||||
stuff_t stuff;
|
||||
stuff_t stuff = {0};
|
||||
io_iterator_t found, lost;
|
||||
|
||||
void* cfdict_keys[3];
|
||||
@@ -250,3 +251,7 @@ int wait_for_pongo(void) {
|
||||
CFRelease(cfdict);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
+62
-59
@@ -38,7 +38,7 @@
|
||||
#include <sys/stat.h> // fstst
|
||||
|
||||
#include <palerain.h>
|
||||
#define ERR(...) LOG(LOG_VERBOSE, __VA_ARGS__)
|
||||
#define ERR(...) LOG(LOG_ERROR, __VA_ARGS__)
|
||||
|
||||
void io_start(stuff_t *stuff);
|
||||
void io_stop(stuff_t *stuff);
|
||||
@@ -114,12 +114,12 @@ usb_ret_t USBBulkUpload(usb_device_handle_t handle, void *data, int len)
|
||||
|
||||
static int FoundDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *arg)
|
||||
{
|
||||
LOG(LOG_VERBOSE, "PongoOS USB Device connected");
|
||||
stuff_t *stuff = arg;
|
||||
if(stuff->handle)
|
||||
{
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
LOG(LOG_VERBOSE, "PongoOS USB Device connected");
|
||||
|
||||
libusb_device_handle *handle;
|
||||
int r = libusb_open(dev, &handle);
|
||||
@@ -162,15 +162,16 @@ static int FoundDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_e
|
||||
|
||||
static int LostDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *arg)
|
||||
{
|
||||
LOG(LOG_VERBOSE, "PongoOS USB Device disconnected");
|
||||
stuff_t *stuff = arg;
|
||||
if(stuff->dev != dev)
|
||||
{
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
LOG(LOG_VERBOSE, "PongoOS USB Device disconnected");
|
||||
|
||||
io_stop(stuff);
|
||||
libusb_close(stuff->handle);
|
||||
libusb_unref_device(dev);
|
||||
stuff->handle = NULL;
|
||||
stuff->dev = NULL;
|
||||
|
||||
@@ -179,10 +180,11 @@ static int LostDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_ev
|
||||
|
||||
int wait_for_pongo(void)
|
||||
{
|
||||
stuff_t stuff;
|
||||
stuff_t stuff = {0};
|
||||
libusb_hotplug_callback_handle hp[2];
|
||||
libusb_context* ctx = NULL;
|
||||
|
||||
int r = libusb_init(NULL);
|
||||
int r = libusb_init(&ctx);
|
||||
if(r != LIBUSB_SUCCESS)
|
||||
{
|
||||
ERR("libusb_init: %s", libusb_error_name(r));
|
||||
@@ -192,75 +194,76 @@ int wait_for_pongo(void)
|
||||
if(!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
|
||||
{
|
||||
ERR("libusb: no hotplug capability");
|
||||
libusb_exit(NULL);
|
||||
libusb_exit(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, PONGO_USB_VENDOR, PONGO_USB_PRODUCT, LIBUSB_HOTPLUG_MATCH_ANY, FoundDevice, &stuff, &hp[0]);
|
||||
r = libusb_hotplug_register_callback(ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, PONGO_USB_VENDOR, PONGO_USB_PRODUCT, LIBUSB_HOTPLUG_MATCH_ANY, LostDevice, &stuff, &hp[1]);
|
||||
if(r != LIBUSB_SUCCESS)
|
||||
{
|
||||
ERR("libusb_hotplug: %s", libusb_error_name(r));
|
||||
libusb_exit(NULL);
|
||||
libusb_exit(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, PONGO_USB_VENDOR, PONGO_USB_PRODUCT, LIBUSB_HOTPLUG_MATCH_ANY, LostDevice, &stuff, &hp[1]);
|
||||
if(r != LIBUSB_SUCCESS)
|
||||
{
|
||||
ERR("libusb_hotplug: %s", libusb_error_name(r));
|
||||
libusb_exit(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
libusb_device **list;
|
||||
ssize_t sz = libusb_get_device_list(NULL, &list);
|
||||
if(sz < 0)
|
||||
{
|
||||
ERR("libusb_get_device_list: %s", libusb_error_name((int)sz));
|
||||
libusb_exit(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(ssize_t i = 0; i < sz; ++i)
|
||||
{
|
||||
struct libusb_device_descriptor desc;
|
||||
r = libusb_get_device_descriptor(list[i], &desc);
|
||||
if(r != LIBUSB_SUCCESS)
|
||||
{
|
||||
ERR("libusb_get_device_descriptor: %s", libusb_error_name(r));
|
||||
// continue anyway
|
||||
}
|
||||
if(desc.idVendor != PONGO_USB_VENDOR || desc.idProduct != PONGO_USB_PRODUCT)
|
||||
{
|
||||
libusb_unref_device(list[i]);
|
||||
continue;
|
||||
}
|
||||
r = FoundDevice(NULL, list[i], LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, &stuff);
|
||||
for(ssize_t j = i + 1; j < sz; ++j)
|
||||
{
|
||||
libusb_unref_device(list[j]);
|
||||
}
|
||||
if(r != LIBUSB_SUCCESS)
|
||||
{
|
||||
libusb_free_device_list(list, 0);
|
||||
libusb_exit(NULL);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
libusb_free_device_list(list, 0);
|
||||
|
||||
while(get_spin())
|
||||
{
|
||||
r = libusb_handle_events(NULL);
|
||||
while (1) {
|
||||
r = libusb_handle_events(ctx);
|
||||
if(r != LIBUSB_SUCCESS)
|
||||
{
|
||||
ERR("libusb_handle_events: %s", libusb_error_name(r));
|
||||
break;
|
||||
}
|
||||
|
||||
libusb_device **list;
|
||||
ssize_t sz = libusb_get_device_list(ctx, &list);
|
||||
bool done = false;
|
||||
if(sz < 0)
|
||||
{
|
||||
ERR("libusb_get_device_list: %s", libusb_error_name((int)sz));
|
||||
libusb_exit(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(ssize_t i = 0; i < sz; ++i)
|
||||
{
|
||||
struct libusb_device_descriptor desc;
|
||||
r = libusb_get_device_descriptor(list[i], &desc);
|
||||
if(r != LIBUSB_SUCCESS)
|
||||
{
|
||||
ERR("libusb_get_device_descriptor: %s", libusb_error_name(r));
|
||||
// continue anyway
|
||||
}
|
||||
if(desc.idVendor != PONGO_USB_VENDOR || desc.idProduct != PONGO_USB_PRODUCT)
|
||||
{
|
||||
libusb_unref_device(list[i]);
|
||||
continue;
|
||||
}
|
||||
r = FoundDevice(ctx, list[i], LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, &stuff);
|
||||
for (ssize_t j = i; j < sz; ++j) {
|
||||
libusb_unref_device(list[j]);
|
||||
}
|
||||
|
||||
if(r != LIBUSB_SUCCESS)
|
||||
{
|
||||
libusb_free_device_list(list, 0);
|
||||
libusb_exit(ctx);
|
||||
return -1;
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
libusb_free_device_list(list, 0);
|
||||
|
||||
if (done) goto end;
|
||||
}
|
||||
|
||||
libusb_exit(NULL);
|
||||
return 0;
|
||||
end:
|
||||
libusb_exit(ctx);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* ISO C forbids an empty translation unit */
|
||||
extern char** environ;
|
||||
#endif
|
||||
Reference in new issue
Block a user