mirror of
https://github.com/palera1n/palera1n.git
synced 2026-10-23 18:49:48 +02:00
Compare commits
39
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
No files matched your search
@@ -24,7 +24,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-docs:
|
build-docs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
@@ -39,6 +39,10 @@ jobs:
|
|||||||
mkdir ready
|
mkdir ready
|
||||||
cp docs/*.html docs/mandoc.css docs/palera1n.1 ready
|
cp docs/*.html docs/mandoc.css docs/palera1n.1 ready
|
||||||
|
|
||||||
|
- name: Get branch name
|
||||||
|
id: branch-name
|
||||||
|
uses: tj-actions/branch-names@v7
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
uses: wangyucode/[email protected]
|
uses: wangyucode/[email protected]
|
||||||
@@ -50,7 +54,7 @@ jobs:
|
|||||||
forceUpload: true
|
forceUpload: true
|
||||||
dryRun: false
|
dryRun: false
|
||||||
localDir: 'ready/'
|
localDir: 'ready/'
|
||||||
remoteDir: '/palera1n/artifacts/c-rewrite'
|
remoteDir: '/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}'
|
||||||
|
|
||||||
build-darwin:
|
build-darwin:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -70,7 +74,7 @@ jobs:
|
|||||||
minos: 7.0
|
minos: 7.0
|
||||||
runs-on: macos-12
|
runs-on: macos-12
|
||||||
env:
|
env:
|
||||||
MBEDTLS_VERSION: 3.3.0
|
MBEDTLS_VERSION: 3.4.0
|
||||||
READLINE_VERSION: 8.2
|
READLINE_VERSION: 8.2
|
||||||
SLANG_VERSION: 2.3.3
|
SLANG_VERSION: 2.3.3
|
||||||
NEWT_VERSION: 0.52.23
|
NEWT_VERSION: 0.52.23
|
||||||
@@ -325,6 +329,10 @@ jobs:
|
|||||||
mkdir -p ready
|
mkdir -p ready
|
||||||
tar -zcf ready/dep_root-${{ matrix.os }}-${{ matrix.arch }}.tgz dep_root
|
tar -zcf ready/dep_root-${{ matrix.os }}-${{ matrix.arch }}.tgz dep_root
|
||||||
|
|
||||||
|
- name: Get branch name
|
||||||
|
id: branch-name
|
||||||
|
uses: tj-actions/branch-names@v7
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
uses: wangyucode/[email protected]
|
uses: wangyucode/[email protected]
|
||||||
@@ -336,7 +344,7 @@ jobs:
|
|||||||
forceUpload: true
|
forceUpload: true
|
||||||
dryRun: false
|
dryRun: false
|
||||||
localDir: 'ready/'
|
localDir: 'ready/'
|
||||||
remoteDir: '/palera1n/artifacts/c-rewrite'
|
remoteDir: '/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}'
|
||||||
|
|
||||||
- name: Upload ${{ matrix.os }} thin ${{ matrix.arch }} build
|
- name: Upload ${{ matrix.os }} thin ${{ matrix.arch }} build
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
@@ -353,7 +361,7 @@ jobs:
|
|||||||
name: palera1n-${{ matrix.os }}-${{ matrix.arch }}.dSYM
|
name: palera1n-${{ matrix.os }}-${{ matrix.arch }}.dSYM
|
||||||
path: palera1n-${{ matrix.os }}-${{ matrix.arch }}.dSYM
|
path: palera1n-${{ matrix.os }}-${{ matrix.arch }}.dSYM
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
darwin-dist:
|
darwin-dist:
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
@@ -461,6 +469,19 @@ jobs:
|
|||||||
dpkg-deb -Zzstd -b stage palera1n_iphoneos-arm64.deb
|
dpkg-deb -Zzstd -b stage palera1n_iphoneos-arm64.deb
|
||||||
mv palera1n*.deb ready/
|
mv palera1n*.deb ready/
|
||||||
rm -rf stage
|
rm -rf stage
|
||||||
|
|
||||||
|
- 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@v3
|
||||||
|
with:
|
||||||
|
name: build-tag
|
||||||
|
path: build-tag.txt
|
||||||
|
|
||||||
|
- name: Get branch name
|
||||||
|
id: branch-name
|
||||||
|
uses: tj-actions/branch-names@v7
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
@@ -473,7 +494,7 @@ jobs:
|
|||||||
forceUpload: true
|
forceUpload: true
|
||||||
dryRun: false
|
dryRun: false
|
||||||
localDir: 'ready/'
|
localDir: 'ready/'
|
||||||
remoteDir: '/palera1n/artifacts/c-rewrite'
|
remoteDir: '/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}'
|
||||||
|
|
||||||
build-Linux:
|
build-Linux:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -485,7 +506,7 @@ jobs:
|
|||||||
- aarch64-linux-musl
|
- aarch64-linux-musl
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
MBEDTLS_VERSION: 3.3.0
|
MBEDTLS_VERSION: 3.4.0
|
||||||
LIBUSB_VERSION: 1.0.26
|
LIBUSB_VERSION: 1.0.26
|
||||||
READLINE_VERSION: 8.2
|
READLINE_VERSION: 8.2
|
||||||
SLANG_VERSION: 2.3.3
|
SLANG_VERSION: 2.3.3
|
||||||
@@ -771,6 +792,10 @@ jobs:
|
|||||||
mv palera1n*.deb ready/
|
mv palera1n*.deb ready/
|
||||||
rm -rf stage
|
rm -rf stage
|
||||||
|
|
||||||
|
- name: Get branch name
|
||||||
|
id: branch-name
|
||||||
|
uses: tj-actions/branch-names@v7
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
uses: wangyucode/[email protected]
|
uses: wangyucode/[email protected]
|
||||||
@@ -782,4 +807,27 @@ jobs:
|
|||||||
forceUpload: true
|
forceUpload: true
|
||||||
dryRun: false
|
dryRun: false
|
||||||
localDir: 'ready/'
|
localDir: 'ready/'
|
||||||
remoteDir: '/palera1n/artifacts/c-rewrite'
|
remoteDir: '/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}'
|
||||||
|
|
||||||
|
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@v3
|
||||||
|
|
||||||
|
- name: Get branch name
|
||||||
|
id: branch-name
|
||||||
|
uses: tj-actions/branch-names@v7
|
||||||
|
|
||||||
|
- name: Download build tag
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: build-tag
|
||||||
|
|
||||||
|
- 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 }}/palera1n.1.html)\"},{\"name\":\"Main Artifacts\",\"value\":\"- [palera1n-ios](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-ios)\n- [palera1n-linux-arm64](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-linux-arm64)\n- [palera1n-linux-armel](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-linux-armel)\n- [palera1n-linux-x86](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/$${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/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 }}/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 }}/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,11 +4,11 @@ SRC = $(shell pwd)
|
|||||||
DEP = $(SRC)/dep_root
|
DEP = $(SRC)/dep_root
|
||||||
STRIP = strip
|
STRIP = strip
|
||||||
CC ?= cc
|
CC ?= cc
|
||||||
CFLAGS += -I$(DEP)/include -I$(SRC)/include -I$(SRC)
|
CFLAGS += -I$(DEP)/include -I$(SRC)/include -I$(SRC) -D_XOPEN_SOURCE=500
|
||||||
CFLAGS += -Wall -Wextra -Wno-unused-parameter -DPALERAIN_VERSION=\"2.0.0\"
|
CFLAGS += -Wall -Wextra -Wno-unused-parameter -DPALERAIN_VERSION=\"2.0.0\"
|
||||||
CFLAGS += -Wno-unused-variable -I$(SRC)/src -std=c99 -pedantic-errors -D_C99_SOURCE -D_POSIX_C_SOURCE=200112L
|
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-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),)
|
ifeq ($(TARGET_OS),)
|
||||||
TARGET_OS = $(shell uname -s)
|
TARGET_OS = $(shell uname -s)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -2,36 +2,20 @@
|
|||||||
<source media="(prefers-color-scheme: light)" srcset="https://cdn.discordapp.com/attachments/1028398976640229380/1088049124441604136/IMG_0033.png">
|
<source media="(prefers-color-scheme: light)" srcset="https://cdn.discordapp.com/attachments/1028398976640229380/1088049124441604136/IMG_0033.png">
|
||||||
<img align="left" height="120" src="https://cdn.discordapp.com/attachments/1017854329887129611/1073858292159352862/thing.png" alt="palera1n logo" style="float: left;"/>
|
<img align="left" height="120" src="https://cdn.discordapp.com/attachments/1017854329887129611/1073858292159352862/thing.png" alt="palera1n logo" style="float: left;"/>
|
||||||
</picture>
|
</picture>
|
||||||
<h3 align="right">An iOS 15.0-16.4.1 work-in-progress, <br>semi-tethered checkm8 jailbreak</h3>
|
|
||||||
|
|
||||||
<p align="right" >
|
<br clear="both"/>
|
||||||
<strong><a href="https://cdn.nickchan.lol/palera1n/c-rewrite/releases/v2.0.0-beta.4/palera1n.1.html">Usage</a></strong>
|
|
||||||
•
|
|
||||||
<strong><a href="https://github.com/palera1n/palera1n/graphs/contributors">Contributors</a></strong>
|
|
||||||
•
|
|
||||||
<strong><a href="https://dsc.gg/palera1n">Discord</a></strong>
|
|
||||||
•
|
|
||||||
<strong><a href="https://twitter.com/palera1n">Twitter</a></strong>
|
|
||||||
</p>
|
|
||||||
<div class="clear"></div>
|
|
||||||
|
|
||||||
## If you want a jailbreak, you should read the [guide](https://palera.in).
|
## Information
|
||||||
|
- Guides to palera1n can be found [here](https://ios.cfw.guide/installing-palera1n).
|
||||||
### You can obtain v2.0.0 beta [here](https://github.com/palera1n/palera1n/releases).
|
- Full documentation can be also found [here](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/palera1n.1.html).
|
||||||
If you need an older v2.0.0 beta, please get it [here](https://github.com/palera1n/palera1n-c/releases/tag/v2.0.0-beta.4).
|
|
||||||
|
|
||||||
# Warnings
|
|
||||||
- This palera1n rewrite has noticeably different arguments compared to the shell version of palera1n.
|
|
||||||
- Highly recommended that you take a look at how to use palera1n-c [here](https://cdn.nickchan.lol/palera1n/c-rewrite/releases/v2.0.0-beta.1/palera1n.1.html).
|
|
||||||
|
|
||||||
- This does **NOT** support tethered creation or booting. You must use the older [shell version of palera1n](https://github.com/palera1n/palera1n/tree/legacy) (clone with `-b legacy`).
|
|
||||||
|
|
||||||
|
## Warnings
|
||||||
- We are **NOT** responsible for any data loss, or the result of a device being bricked. The user of this program accepts responsibility should something happen to their device. While nothing should happen, jailbreaking has risks in itself.
|
- We are **NOT** responsible for any data loss, or the result of a device being bricked. 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`.
|
- If your device is stuck in recovery, please run futurerestore `--exit-recovery`, or use `irecovery -n`.
|
||||||
|
|
||||||
- palera1n will never work in VirtualBox, VMware or any virtual machine that doesn't support PCI passthrough.
|
- palera1n will never work in VirtualBox, VMware or any virtual machine that doesn't support PCI passthrough.
|
||||||
|
|
||||||
# Requirements
|
## Requirements
|
||||||
- A checkm8 vulnerable iOS device on iOS 15.x or 16.x (`A8` - `A11`)
|
- A checkm8 vulnerable iOS device on iOS 15.x or 16.x (`A8` - `A11`)
|
||||||
- If using rootful, you will need **5-10GB of space** for the fakefs. This means 16GB devices cannot use the full fakefs creation. However, you can change the arguments to `-Bf` to create a fakefs with bind mounts, so it uses a smaller size, at the expense having unwritable parts in rarely-written paths, and then boot it
|
- If using rootful, you will need **5-10GB of space** for the fakefs. This means 16GB devices cannot use the full fakefs creation. However, you can change the arguments to `-Bf` to create a fakefs with bind mounts, so it uses a smaller size, at the expense having unwritable parts in rarely-written paths, and then boot it
|
||||||
- On `A11`, **you must disable your passcode while in the jailbroken state** (on iOS 16, you need to **reset your device** before proceeding with palera1n).
|
- On `A11`, **you must disable your passcode while in the jailbroken state** (on iOS 16, you need to **reset your device** before proceeding with palera1n).
|
||||||
@@ -46,7 +30,7 @@ If you need an older v2.0.0 beta, please get it [here](https://github.com/palera
|
|||||||
- USB-C port on Apple Silicon Macs may require manual unplugging and replugging of the lightning cable after checkm8 exploit.
|
- 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 USBHub.
|
- This problem may be solved by connecting via USBHub.
|
||||||
|
|
||||||
# Need help?
|
## Need help?
|
||||||
|
|
||||||
Make sure you provide full details on your device, such as:
|
Make sure you provide full details on your device, such as:
|
||||||
- iDevice
|
- iDevice
|
||||||
@@ -54,19 +38,15 @@ Make sure you provide full details on your device, such as:
|
|||||||
- Passcode enabled?
|
- Passcode enabled?
|
||||||
- Logs, if panicked then send latest `panic-full` log from your iDevice.
|
- Logs, if panicked then send latest `panic-full` log from your iDevice.
|
||||||
|
|
||||||
Using `-V` and `-v` would help with debugging.
|
Using `-VvL` would help with debugging.
|
||||||
|
|
||||||
Join the [Support Discord](https://dsc.gg/palera1n), and create a thread in [#support](https://discord.com/channels/1028398973452570725/1028730487700738130) or ask in [#general](https://discord.com/channels/1028398973452570725/1028398976640229380).
|
Join the [Support Discord](https://dsc.gg/palera1n), and create a thread in [#support](https://discord.com/channels/1028398973452570725/1028730487700738130) or ask in [#general](https://discord.com/channels/1028398973452570725/1028398976640229380).
|
||||||
|
|
||||||
# Credits
|
## Credits
|
||||||
<details><summary>palera1n-c Contributors and Credits</summary>
|
<details><summary>Credits</summary>
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
- [Nick Chan](https://github.com/asdfugil) for the rewrite
|
- [Lakhan Lothiyi](https://github.com/llsc12) for older palera1n loader app
|
||||||
- [Nebula](https://github.com/itsnebulalol) - palera1n owner and manager
|
|
||||||
- [Mineek](https://github.com/mineek)
|
|
||||||
- [Tom](https://github.com/plooshi) for updated ploosh kpf and universal loader
|
|
||||||
- [Lakhan Lothiyi](https://github.com/llsc12) for palera1n loader app
|
|
||||||
- [checkra1n](https://github.com/checkra1n) for the base of the kpf
|
- [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)
|
- [the Procursus Team](https://github.com/ProcursusTeam) for the amazing [bootstrap](https://github.com/ProcursusTeam/Procursus)
|
||||||
- [Évelyne](https://github.com/evelyneee) for [ElleKit](https://github.com/evelyneee/ellekit), rootless tweak injection
|
- [Évelyne](https://github.com/evelyneee) for [ElleKit](https://github.com/evelyneee/ellekit), rootless tweak injection
|
||||||
|
|||||||
+15
-3
@@ -6,7 +6,7 @@
|
|||||||
.Dt palera1n 1
|
.Dt palera1n 1
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm palera1n
|
.Nm palera1n
|
||||||
.Nd iOS 15.0-16.4.1 arm64 iOS/iPadOS jailbreaking tool
|
.Nd iOS 15.0-16.5 arm64 iOS/iPadOS jailbreaking tool
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl cCdDEfhIlLnpRsSvV
|
.Op Fl cCdDEfhIlLnpRsSvV
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
.Op Fl -force-revert
|
.Op Fl -force-revert
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
jailbreaks any iOS/iPadOS device with an arm64 (arm64e excluded) on iOS 15.0-16.4.1,
|
jailbreaks any iOS/iPadOS device with an arm64 (arm64e excluded) on iOS 15.0-16.5,
|
||||||
utilizing the
|
utilizing the
|
||||||
.Em checkm8
|
.Em checkm8
|
||||||
bootROM exploit.
|
bootROM exploit.
|
||||||
@@ -52,7 +52,7 @@ In the remainder of this document, the term "iOS" and "iPadOS" will be used inte
|
|||||||
as the difference is negligible as far as the jailbreak is concerened.
|
as the difference is negligible as far as the jailbreak is concerened.
|
||||||
.Pp
|
.Pp
|
||||||
.Sh SUPPORTED DEVICES
|
.Sh SUPPORTED DEVICES
|
||||||
As described above, arm64 iOS 15.0-16.4.1 devices are supported, here is an explicit
|
As described above, arm64 iOS 15.0-16.5 devices are supported, here is an explicit
|
||||||
list of supported devicecs:
|
list of supported devicecs:
|
||||||
|
|
||||||
.Bl -tag -compact
|
.Bl -tag -compact
|
||||||
@@ -113,6 +113,18 @@ This option currently does not work on iOS 16.
|
|||||||
When used with
|
When used with
|
||||||
.Fl f , -fakefs ,
|
.Fl f , -fakefs ,
|
||||||
creates the new APFS volume required for rootful. Will fail if one already exists.
|
creates the new APFS volume required for rootful. Will fail if one already exists.
|
||||||
|
.It Fl C , -clean-fakefs
|
||||||
|
This reverts the fakefs to the
|
||||||
|
.Em orig-fs
|
||||||
|
snapshot that is created when the fakefs
|
||||||
|
is first created, then the device will continue to boot jailbroken. This option
|
||||||
|
allows resetting the rootful environment without deleting the entire fakefs.
|
||||||
|
Note that this option will not work if the fakefs is created in an older version
|
||||||
|
of palera1n that does not create the
|
||||||
|
.Em orig-fs
|
||||||
|
snapshot on the fakefs. This option will also remove some jailbreak files inside
|
||||||
|
of /var. The files in /var will not be deleted when a userspace reboot is done
|
||||||
|
with this flag set.
|
||||||
.It Fl d , -demote
|
.It Fl d , -demote
|
||||||
Set the effective production fuse to 0, so as to enable hardware debugging features.
|
Set the effective production fuse to 0, so as to enable hardware debugging features.
|
||||||
.It Fl D , -dfuhelper
|
.It Fl D , -dfuhelper
|
||||||
|
|||||||
@@ -61,6 +61,11 @@
|
|||||||
#define palerain_option_setup_partial_root (1 << 4) /* fakefs creating should be partial */
|
#define palerain_option_setup_partial_root (1 << 4) /* fakefs creating should be partial */
|
||||||
#define palerain_option_checkrain_is_clone (1 << 5) /* supplied checkra1n is checkra1n clone */
|
#define palerain_option_checkrain_is_clone (1 << 5) /* supplied checkra1n is checkra1n clone */
|
||||||
#define palerain_option_rootless_livefs (1 << 6) /* mount root livefs on rootless */
|
#define palerain_option_rootless_livefs (1 << 6) /* mount root livefs on rootless */
|
||||||
|
/* reserved values */
|
||||||
|
// #define palerain_option_no_ssv (1 << 7) /* no signed system volume */
|
||||||
|
// #define palerain_option_force_fakefs (1 << 8) /* force fakefs, even without SSV */
|
||||||
|
// #define palerain_option_rootless (1 << 9) /* rootless jailbreak */
|
||||||
|
#define palerain_option_clean_fakefs (1 << 10) /* clean fakefs, but does not delete it */
|
||||||
|
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
#define palerain_option_test1 (1 << 29)
|
#define palerain_option_test1 (1 << 29)
|
||||||
|
|||||||
+2
-2
@@ -8,8 +8,8 @@ Depends: usbmuxd
|
|||||||
Section: Utilities
|
Section: Utilities
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Homepage: https://palera.in
|
Homepage: https://palera.in
|
||||||
Description: iOS 15.0-16.4.1 semi-tethered checkm8 jailbreak
|
Description: iOS 15.0-16.5 semi-tethered checkm8 jailbreak
|
||||||
palera1n is an iOS/iPadOS 15.0-15.3.1 semi tethered jailbreak
|
palera1n is an iOS/iPadOS 15.0-16.5 semi tethered jailbreak
|
||||||
based on the checkm8 exploit.
|
based on the checkm8 exploit.
|
||||||
.
|
.
|
||||||
palera1n is able to jailbreak the device in fakefs-rootful mode,
|
palera1n is able to jailbreak the device in fakefs-rootful mode,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ Author: palera1n team
|
|||||||
Section: Utilities
|
Section: Utilities
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Homepage: https://palera.in
|
Homepage: https://palera.in
|
||||||
Description: iOS 15.0-16.4.1 semi-tethered checkm8 jailbreak
|
Description: iOS 15.0-16.5 semi-tethered checkm8 jailbreak
|
||||||
palera1n is an iOS/iPadOS 15.0-15.3.1 semi tethered jailbreak
|
palera1n is an iOS/iPadOS 15.0-16.5 semi tethered jailbreak
|
||||||
based on the checkm8 exploit.
|
based on the checkm8 exploit.
|
||||||
.
|
.
|
||||||
palera1n is able to jailbreak the device in fakefs-rootful mode,
|
palera1n is able to jailbreak the device in fakefs-rootful mode,
|
||||||
|
|||||||
@@ -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]>
|
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
|
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(-)
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
diff --git a/library/x509_crt.c b/library/x509_crt.c
|
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
|
--- a/library/x509_crt.c
|
||||||
+++ b/library/x509_crt.c
|
+++ b/library/x509_crt.c
|
||||||
@@ -1185,14 +1185,14 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
|
@@ -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 )
|
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||||
{
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||||
- mbedtls_x509_crt_free( crt );
|
- mbedtls_x509_crt_free(crt);
|
||||||
- return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
|
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
|
||||||
+ // mbedtls_x509_crt_free( crt );
|
+ /*mbedtls_x509_crt_free(crt);
|
||||||
+ // return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
|
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
|
if ((ret = mbedtls_x509_get_name(&p, p + len, &crt->issuer)) != 0) {
|
||||||
{
|
- mbedtls_x509_crt_free(crt);
|
||||||
- mbedtls_x509_crt_free( crt );
|
- return ret;
|
||||||
- return( ret );
|
+ /*mbedtls_x509_crt_free(crt);
|
||||||
+ // mbedtls_x509_crt_free( crt );
|
+ return ret;*/
|
||||||
+ // return( ret );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
crt->issuer_raw.len = p - crt->issuer_raw.p;
|
crt->issuer_raw.len = p - crt->issuer_raw.p;
|
||||||
|
|||||||
+1
-1
@@ -140,7 +140,7 @@ checkra1n-kpf-pongo:
|
|||||||
curl -LO https://cdn.nickchan.lol/palera1n/artifacts/kpf/checkra1n-kpf-pongo
|
curl -LO https://cdn.nickchan.lol/palera1n/artifacts/kpf/checkra1n-kpf-pongo
|
||||||
|
|
||||||
ramdisk.dmg:
|
ramdisk.dmg:
|
||||||
curl -LO https://cdn.nickchan.lol/palera1n/artifacts/jbinit_rootless/ramdisk.dmg
|
curl -LO https://cdn.nickchan.lol/palera1n/c-rewrite/deps/ramdisk.dmg
|
||||||
|
|
||||||
binpack.dmg:
|
binpack.dmg:
|
||||||
curl -LO https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg
|
curl -LO https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg
|
||||||
|
|||||||
+8
-3
@@ -21,6 +21,7 @@ static bool force_use_verbose_boot = false;
|
|||||||
static struct option longopts[] = {
|
static struct option longopts[] = {
|
||||||
{"setup-partial-fakefs", no_argument, NULL, 'B'},
|
{"setup-partial-fakefs", no_argument, NULL, 'B'},
|
||||||
{"setup-fakefs", no_argument, NULL, 'c'},
|
{"setup-fakefs", no_argument, NULL, 'c'},
|
||||||
|
{"clean-fakefs", no_argument, NULL, 'c'},
|
||||||
{"dfuhelper", no_argument, NULL, 'D'},
|
{"dfuhelper", no_argument, NULL, 'D'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"pongo-shell", no_argument, NULL, 'p'},
|
{"pongo-shell", no_argument, NULL, 'p'},
|
||||||
@@ -64,14 +65,14 @@ static int usage(int e, char* prog_name)
|
|||||||
"12"
|
"12"
|
||||||
#endif
|
#endif
|
||||||
#ifdef ROOTFUL
|
#ifdef ROOTFUL
|
||||||
"cfB"
|
"cCfB"
|
||||||
#endif
|
#endif
|
||||||
#ifdef TUI
|
#ifdef TUI
|
||||||
"t"
|
"t"
|
||||||
#endif
|
#endif
|
||||||
"] [-e boot arguments] [-k Pongo image] [-o overlay file] [-r ramdisk file] [-K KPF file] [-i checkra1n file]\n"
|
"] [-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"
|
"Copyright (C) 2023, palera1n team, All Rights Reserved.\n\n"
|
||||||
"iOS/iPadOS 15.0-16.4.1 arm64 jailbreaking tool\n\n"
|
"iOS/iPadOS 15.0-16.5 arm64 jailbreaking tool\n\n"
|
||||||
"\t--version\t\t\t\tPrint version\n"
|
"\t--version\t\t\t\tPrint version\n"
|
||||||
"\t--force-revert\t\t\t\tRemove jailbreak\n"
|
"\t--force-revert\t\t\t\tRemove jailbreak\n"
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
@@ -81,6 +82,7 @@ static int usage(int e, char* prog_name)
|
|||||||
#ifdef ROOTFUL
|
#ifdef ROOTFUL
|
||||||
"\t-B, --setup-partial-fakefs\t\tSetup partial fakefs\n"
|
"\t-B, --setup-partial-fakefs\t\tSetup partial fakefs\n"
|
||||||
"\t-c, --setup-fakefs\t\t\tSetup fakefs\n"
|
"\t-c, --setup-fakefs\t\t\tSetup fakefs\n"
|
||||||
|
"\t-C, --clean-fakefs\t\t\tClean fakefs\n"
|
||||||
#endif
|
#endif
|
||||||
"\t-d, --demote\t\t\t\tDemote\n"
|
"\t-d, --demote\t\t\t\tDemote\n"
|
||||||
"\t-D, --dfuhelper\t\t\t\tExit after entering DFU\n"
|
"\t-D, --dfuhelper\t\t\t\tExit after entering DFU\n"
|
||||||
@@ -126,7 +128,7 @@ int optparse(int argc, char* argv[]) {
|
|||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
"12"
|
"12"
|
||||||
#endif
|
#endif
|
||||||
"fcB"
|
"fCcB"
|
||||||
,longopts, NULL)) != -1)
|
,longopts, NULL)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
@@ -139,6 +141,9 @@ int optparse(int argc, char* argv[]) {
|
|||||||
palerain_flags |= palerain_option_setup_rootful;
|
palerain_flags |= palerain_option_setup_rootful;
|
||||||
kpf_flags |= checkrain_option_verbose_boot;
|
kpf_flags |= checkrain_option_verbose_boot;
|
||||||
break;
|
break;
|
||||||
|
case 'C':
|
||||||
|
palerain_flags |= palerain_option_clean_fakefs;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
host_flags |= host_option_pongo_exit;
|
host_flags |= host_option_pongo_exit;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+51
-52
@@ -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)
|
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;
|
stuff_t *stuff = arg;
|
||||||
if(stuff->handle)
|
if(stuff->handle)
|
||||||
{
|
{
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
LOG(LOG_VERBOSE, "PongoOS USB Device connected");
|
||||||
|
|
||||||
libusb_device_handle *handle;
|
libusb_device_handle *handle;
|
||||||
int r = libusb_open(dev, &handle);
|
int r = libusb_open(dev, &handle);
|
||||||
@@ -162,12 +162,12 @@ 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)
|
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;
|
stuff_t *stuff = arg;
|
||||||
if(stuff->dev != dev)
|
if(stuff->dev != dev)
|
||||||
{
|
{
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
LOG(LOG_VERBOSE, "PongoOS USB Device disconnected");
|
||||||
|
|
||||||
io_stop(stuff);
|
io_stop(stuff);
|
||||||
libusb_close(stuff->handle);
|
libusb_close(stuff->handle);
|
||||||
@@ -181,6 +181,7 @@ static int LostDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_ev
|
|||||||
int wait_for_pongo(void)
|
int wait_for_pongo(void)
|
||||||
{
|
{
|
||||||
stuff_t stuff;
|
stuff_t stuff;
|
||||||
|
stuff.handle = NULL;
|
||||||
libusb_hotplug_callback_handle hp[2];
|
libusb_hotplug_callback_handle hp[2];
|
||||||
libusb_context* ctx = NULL;
|
libusb_context* ctx = NULL;
|
||||||
|
|
||||||
@@ -198,14 +199,6 @@ int wait_for_pongo(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = libusb_hotplug_register_callback(ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, PONGO_USB_VENDOR, PONGO_USB_PRODUCT, LIBUSB_HOTPLUG_MATCH_ANY, FoundDevice, &stuff, &hp[0]);
|
|
||||||
if(r != LIBUSB_SUCCESS)
|
|
||||||
{
|
|
||||||
ERR("libusb_hotplug: %s", libusb_error_name(r));
|
|
||||||
libusb_exit(ctx);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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]);
|
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)
|
if(r != LIBUSB_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -214,55 +207,61 @@ int wait_for_pongo(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_device **list;
|
while (1) {
|
||||||
ssize_t sz = libusb_get_device_list(ctx, &list);
|
|
||||||
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 + 1; j < sz; ++j)
|
|
||||||
{
|
|
||||||
libusb_unref_device(list[j]);
|
|
||||||
}
|
|
||||||
if(r != LIBUSB_SUCCESS)
|
|
||||||
{
|
|
||||||
libusb_free_device_list(list, 0);
|
|
||||||
libusb_exit(ctx);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
libusb_free_device_list(list, 0);
|
|
||||||
|
|
||||||
while(get_spin())
|
|
||||||
{
|
|
||||||
r = libusb_handle_events(ctx);
|
r = libusb_handle_events(ctx);
|
||||||
if(r != LIBUSB_SUCCESS)
|
if(r != LIBUSB_SUCCESS)
|
||||||
{
|
{
|
||||||
ERR("libusb_handle_events: %s", libusb_error_name(r));
|
ERR("libusb_handle_events: %s", libusb_error_name(r));
|
||||||
break;
|
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(ctx);
|
end:
|
||||||
return 0;
|
libusb_exit(ctx);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Reference in new issue
Block a user