mirror of
https://github.com/palera1n/palera1n.git
synced 2026-10-23 10:39:48 +02:00
refactor: libciderra1n support (#764)
* refactor refactor: remove wdi refactor: move openra1n to its own library refactor: move everything standalone file to src root * submodule * okay these shouldnt of been included * remove * readd * fix openra1n libusb * liteusb for ra1ncovery * fix action * token * whatever lwra bw apwxidix * I knew this was gonna happen * fix mac build * what if this doesnt work * okay bro * lzma resources * rename * use idevice++, fix multiple devices, enter recovery * whatever * fix * --force-enable-ssv * improve exploit stuff, mirror tui logic to gui also cooool logging for libopenra1n * fix idevice windows build * lets not be fancy * new idevice patch * easier to read * lets hope this action works! * remove useless ifs * not required for non tui * PLEASE COMPILE * gsed lmao * this might work idk * whatever bro * ah * amd fix * fix ts * fix * licensing * update paleinfo * LETS NOT do that * forgot a file
This commit is contained in:
128 files changed
+12054
-3114
No files matched your search
+389
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* palera1n - https://palera.in
|
||||
*
|
||||
* Copyright (C) 2026 palera1n team
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "exploit.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "paleinfo.h"
|
||||
#include "pongo_helper.h"
|
||||
|
||||
#if WITH_CIDERRAIN
|
||||
# include <ciderra1n/log.h>
|
||||
# include <ciderra1n/common.h>
|
||||
# include <ciderra1n/usb.h>
|
||||
# include <ciderra1n/ra1n.h>
|
||||
# include <ciderra1n/dfu.h>
|
||||
#else
|
||||
# include <openra1n/utils.h>
|
||||
# include <openra1n/checkm8.h>
|
||||
# include <openra1n/dfu.h>
|
||||
# include <openra1n/payload.h>
|
||||
# include <openra1n/shim.h>
|
||||
#endif
|
||||
|
||||
#define VID_APPLE (0x5AC)
|
||||
#define PID_PONGO (0x4141)
|
||||
#define PID_DFU (0x1227)
|
||||
|
||||
const char* stage_to_string(int stage)
|
||||
{
|
||||
switch (stage) {
|
||||
case STAGE_SETUP: return "Checking if device is ready...";
|
||||
case STAGE_SPRAY: return "Setting up the exploit (this is the heap spray)...";
|
||||
case STAGE_PATCH: return "Right before trigger (this is the real bug setup)...";
|
||||
case STAGE_YOLODFU: return "Booting PongoOS...";
|
||||
case STAGE_PONGO: return "Booting...";
|
||||
case STAGE_DONE: return "Done!";
|
||||
default: return "Waiting...";
|
||||
}
|
||||
}
|
||||
|
||||
int stage_to_progress(int stage)
|
||||
{
|
||||
switch (stage) {
|
||||
case STAGE_SETUP: return 30;
|
||||
case STAGE_SPRAY: return 40;
|
||||
case STAGE_PATCH: return 50;
|
||||
case STAGE_YOLODFU: return 60;
|
||||
case STAGE_PONGO: return 70;
|
||||
case STAGE_DONE: return 100;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* err_to_string(int err) {
|
||||
switch (err) {
|
||||
case 0: return "";
|
||||
case 1: return "-p1_client_err_abort_success";
|
||||
case 2: return "-p1_client_err_unsupported";
|
||||
case 3: return "-p1_client_err_response_size";
|
||||
case 4: return "-p1_client_err_abort";
|
||||
case 5: return "-p1_client_err_timeout";
|
||||
case 6: return "-p1_client_err_pipe_stalled";
|
||||
case 7: return "-p1_client_err_no_device";
|
||||
case 8: return "-p1_client_err_notresponding";
|
||||
case 9: return "-p1_client_err_invalid_response";
|
||||
case 10: return "-p1_client_err_async_download_failed";
|
||||
case 11: return "-p1_client_err_transaction_abort_failed";
|
||||
case 12: return "-p1_client_err_status";
|
||||
case 13: return "-p1_client_err_not_dfu_idle";
|
||||
case 14: return "-p1_client_err_no_stage1_generator";
|
||||
case 15: return "-p1_client_err_invalid_payload";
|
||||
case 16: return "-p1_client_err_no_image";
|
||||
case 17: return "-p1_client_err_not_dfu";
|
||||
case 18: return "-p1_client_err_soft_dfu";
|
||||
case 19: return "-p1_client_err_cnt_overflow";
|
||||
default: return "-p1_client_err_undefined";
|
||||
}
|
||||
}
|
||||
|
||||
#if WITH_CIDERRAIN
|
||||
|
||||
int exploit(int *stage)
|
||||
{
|
||||
LOG("Waiting for devices...");
|
||||
|
||||
*stage = STAGE_RESET;
|
||||
|
||||
client_t* client = NULL;
|
||||
if (!alloc_usb_client(&client)) {
|
||||
*stage = STAGE_ERROR;
|
||||
return RA1N_CLIENT_ERR_UNDEFINED;
|
||||
}
|
||||
|
||||
ra1n_client_err_t cr = RA1N_CLIENT_ERR_NONE;
|
||||
|
||||
uint32_t flag = 0;
|
||||
uint16_t cpid = 0;
|
||||
|
||||
for (;;) {
|
||||
if (usb_open(client) != 0) {
|
||||
// no usb device
|
||||
// slight delay is required for AMD
|
||||
usleep(500000);
|
||||
goto reloop;
|
||||
}
|
||||
|
||||
if (!usb_get_client_flag(client, &flag))
|
||||
goto reloop;
|
||||
|
||||
if (flag & kDeviceDFUModeFlag) {
|
||||
if (flag & kDeviceStandardPwnedDFUModeFlag) {
|
||||
LOG_ERROR("Found an unknown pwned DFU mode device");
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
continue; // err
|
||||
}
|
||||
|
||||
if (flag & kDevicePwnedDFUModeFlag) {
|
||||
LOG_ERROR("Detected pwned DFU mode device, please enter normal DFU mode.");
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
continue; // err
|
||||
}
|
||||
|
||||
if (!(flag & kDeviceNotSoftDFUModeFlag)) {
|
||||
LOG_ERROR("Found soft-DFU mode device");
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
}
|
||||
|
||||
LOG("Found DFU mode device");
|
||||
|
||||
if (*stage == STAGE_RESET) {
|
||||
cr = ra1n_stage_reset(client);
|
||||
if (cr == RA1N_CLIENT_ERR_NONE || cr == RA1N_CLIENT_ERR_ABORT_SUCCESS || cr == RA1N_CLIENT_ERR_NOTRESPONDING) {
|
||||
usb_reset(client, kUSBResetDevice | kUSBReEnumerate);
|
||||
usb_close(client);
|
||||
if (cr == RA1N_CLIENT_ERR_NONE) { // success
|
||||
*stage = STAGE_SETUP;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
LOG_ERROR("STAGE_RESET failed (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
} else if (*stage == STAGE_SETUP) {
|
||||
cr = ra1n_stage_setup(client);
|
||||
if (cr == RA1N_CLIENT_ERR_NONE) { // success
|
||||
usb_reset(client, kUSBResetDevice | kUSBReEnumerate);
|
||||
usb_close(client);
|
||||
*stage = STAGE_PATCH;
|
||||
continue;
|
||||
}
|
||||
LOG_ERROR("STAGE_SETUP failed (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
} else if (*stage == STAGE_PATCH) {
|
||||
cr = ra1n_stage_trigger(client, NULL);
|
||||
if (cr == RA1N_CLIENT_ERR_NONE) { // exploited
|
||||
usb_reset(client, kUSBResetDevice | kUSBReEnumerate);
|
||||
usb_close(client);
|
||||
*stage = STAGE_YOLODFU;
|
||||
LOG("Checkmate?");
|
||||
continue;
|
||||
}
|
||||
LOG_ERROR("STAGE_PATCH failed (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
} else if (*stage == STAGE_YOLODFU) {
|
||||
LOG_ERROR("STAGE_YOLODFU failed (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
}
|
||||
continue;
|
||||
} else if (flag & kDeviceYoloDFUModeFlag) {
|
||||
LOG("Found download mode device");
|
||||
|
||||
*stage = STAGE_YOLODFU;
|
||||
cr = send_compressed_pongo(client, g_payload_pongo.data, g_payload_pongo.data_len); // yoloDFU -> pongoOS
|
||||
if (cr == RA1N_CLIENT_ERR_NONE) {
|
||||
usb_reset(client, kUSBResetDevice | kUSBReEnumerate);
|
||||
usb_close(client); // success
|
||||
continue;
|
||||
}
|
||||
LOG_ERROR("Failed to send pongo image (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
} else if (flag & kDevicePongoModeFlag) {
|
||||
LOG("Found pongo mode device");
|
||||
|
||||
if (palerain_flags & palerain_option_pongo_exit) {
|
||||
usb_close(client);
|
||||
*stage = STAGE_DONE;
|
||||
break; // success
|
||||
} else {
|
||||
LOG("Booting...");
|
||||
cr = send_full_pongo_jailbreak(client);
|
||||
if (cr != RA1N_CLIENT_ERR_NONE) {
|
||||
LOG_ERROR("Failed to boot device (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
}
|
||||
*stage = STAGE_DONE;
|
||||
break; // success
|
||||
}
|
||||
|
||||
usb_close(client);
|
||||
continue;
|
||||
} else {
|
||||
LOG_ERROR("Found unknown device");
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
}
|
||||
|
||||
reloop:
|
||||
usb_close(client);
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
#else // WITH_CIDERRAIN
|
||||
|
||||
int exploit(int *stage)
|
||||
{
|
||||
LOG("Waiting for devices...");
|
||||
|
||||
struct DeviceConfiguration deviceConfig;
|
||||
struct PayloadConfiguration payloadConfig;
|
||||
|
||||
*stage = STAGE_RESET;
|
||||
checkm8_err_t cr = CHECKM8_ERR_NONE;
|
||||
|
||||
usb_handle_t dfuHandle;
|
||||
usb_handle_t pongoHandle;
|
||||
|
||||
init_usb_handle(&dfuHandle, VID_APPLE, PID_DFU);
|
||||
init_usb_handle(&pongoHandle, VID_APPLE, PID_PONGO);
|
||||
|
||||
for (;;) {
|
||||
if (wait_usb_handle(&pongoHandle)) {
|
||||
LOG("Found pongo mode device");
|
||||
*stage = STAGE_PONGO;
|
||||
|
||||
cr = send_full_pongo_jailbreak(&pongoHandle);
|
||||
if (cr != CHECKM8_ERR_NONE) {
|
||||
LOG_ERROR("Failed to boot device (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
*stage = STAGE_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*stage = STAGE_DONE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (wait_usb_handle(&dfuHandle)) {
|
||||
char *sn = get_usb_serial_number(&dfuHandle);
|
||||
if (!sn) goto reloop;
|
||||
|
||||
uint64_t cpid = dfu_serial_number_get_cpid(sn);
|
||||
if (!checkm8_find_device_configuration_for_cpid(cpid, &deviceConfig) ||
|
||||
!checkm8_find_payload_configuration_for_cpid(cpid, &payloadConfig))
|
||||
{
|
||||
free(sn);
|
||||
goto reloop;
|
||||
}
|
||||
|
||||
if (dfu_serial_number_is_pwned(sn)) {
|
||||
LOG_ERROR("Detected pwned DFU mode device, please enter normal DFU mode.");
|
||||
free(sn);
|
||||
*stage = STAGE_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (dfu_serial_number_is_in_dfu_mode(sn)) {
|
||||
LOG("Found DFU mode device");
|
||||
} else if (dfu_serial_number_is_in_yolo_dfu(sn)) {
|
||||
LOG("Found download mode device");
|
||||
*stage = STAGE_YOLODFU;
|
||||
} else {
|
||||
free(sn);
|
||||
goto reloop;
|
||||
}
|
||||
|
||||
free(sn);
|
||||
|
||||
switch (*stage) {
|
||||
case STAGE_RESET:
|
||||
cr = checkm8_stage_reset(&dfuHandle);
|
||||
if (cr != CHECKM8_ERR_NONE) { // err
|
||||
LOG_ERROR("STAGE_RESET failed (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
*stage = STAGE_RESET;
|
||||
goto reloop;
|
||||
}
|
||||
|
||||
*stage = STAGE_SETUP;
|
||||
goto reloop; // success
|
||||
case STAGE_SETUP:
|
||||
cr = checkm8_stage_setup(&dfuHandle, &deviceConfig);
|
||||
if (cr != CHECKM8_ERR_NONE) { // err
|
||||
LOG_ERROR("STAGE_SETUP failed (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
*stage = STAGE_RESET;
|
||||
goto reloop;
|
||||
}
|
||||
*stage = STAGE_SPRAY;
|
||||
goto reloop;
|
||||
case STAGE_SPRAY:
|
||||
cr = checkm8_stage_spray(&dfuHandle, &deviceConfig);
|
||||
if (cr != CHECKM8_ERR_NONE) { // err
|
||||
LOG_ERROR("STAGE_SPRAY failed (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
*stage = STAGE_RESET;
|
||||
goto reloop;
|
||||
}
|
||||
|
||||
*stage = STAGE_PATCH;
|
||||
goto reloop; // success
|
||||
case STAGE_PATCH:
|
||||
cr = checkm8_stage_patch(&dfuHandle, &deviceConfig, &payloadConfig);
|
||||
if (cr != CHECKM8_ERR_NONE) // err
|
||||
LOG_ERROR("STAGE_PATCH failed (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
|
||||
*stage = STAGE_RESET;
|
||||
LOG("Checkmate?");
|
||||
goto reloop; // success
|
||||
case STAGE_YOLODFU:
|
||||
cr = send_compressed_pongo(&dfuHandle, g_payload_pongo.data, g_payload_pongo.data_len);
|
||||
if (cr != CHECKM8_ERR_NONE) {
|
||||
LOG_ERROR("Failed to send pongo image (rv=%d, reason=%s)", cr, err_to_string(cr));
|
||||
*stage = STAGE_ERROR;
|
||||
goto cleanup; // err
|
||||
};
|
||||
|
||||
continue; // success
|
||||
}
|
||||
|
||||
reloop:
|
||||
reset_usb_handle(&dfuHandle);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
close_usb_handle(&dfuHandle);
|
||||
close_usb_handle(&pongoHandle);
|
||||
return cr;
|
||||
}
|
||||
|
||||
#endif // WITH_CIDERRAIN
|
||||
Reference in new issue
Block a user