mirror of
https://github.com/palera1n/palera1n.git
synced 2026-10-21 09:47:01 +02:00
chore: add some code documentation
This commit is contained in:
5 files changed
+57
-3
No files matched your search
@@ -45,12 +45,14 @@ static uint64_t get_hex_field(const char *serial, const char *field) {
|
||||
return p ? strtoull(p + strlen(field), nullptr, 16) : 0;
|
||||
}
|
||||
|
||||
// get device info from a recovery mode serial number
|
||||
void get_recovery_info(char *sn, const char **ecid, const char **product_model, const char **product_name)
|
||||
{
|
||||
static char cpid_buf[16];
|
||||
static char ecid_buf[32];
|
||||
static char bdid_buf[16];
|
||||
|
||||
// we can get the model based on cpid and bdid
|
||||
uint16_t cpid_val = (uint16_t)get_hex_field(sn, "CPID:");
|
||||
uint32_t bdid_val = (uint32_t)get_hex_field(sn, "BDID:");
|
||||
uint64_t ecid_val = get_hex_field(sn, "ECID:");
|
||||
@@ -64,6 +66,7 @@ void get_recovery_info(char *sn, const char **ecid, const char **product_model,
|
||||
*product_model = nullptr;
|
||||
*product_name = nullptr;
|
||||
|
||||
// cpid+bdid -> product type & product name
|
||||
for (int i = 0; irecv_devices[i].product_type; i++) {
|
||||
if (irecv_devices[i].cpid == cpid_val &&
|
||||
irecv_devices[i].bdid == bdid_val) {
|
||||
@@ -74,6 +77,7 @@ void get_recovery_info(char *sn, const char **ecid, const char **product_model,
|
||||
}
|
||||
}
|
||||
|
||||
// iPhone9,3 -> iPhone 7 (GSM)
|
||||
void get_name_from_product_type(const char *product_type, const char **name) {
|
||||
*name = nullptr;
|
||||
for (int i = 0; irecv_devices[i].product_type; i++) {
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#ifndef MAIN__DEVICE_INFO_H
|
||||
#define MAIN__DEVICE_INFO_H
|
||||
|
||||
// stolen from irecovery, I dont think an array
|
||||
// of devices can be copyrighted?
|
||||
struct irecv_device {
|
||||
const char *product_type;
|
||||
const char *board;
|
||||
|
||||
@@ -85,6 +85,7 @@ int stage_to_progress(int stage)
|
||||
}
|
||||
|
||||
const char* err_to_string(int err) {
|
||||
// error codes should be the same between both checkm8 backends
|
||||
switch (err) {
|
||||
case 0: return "";
|
||||
case 1: return "-p1_client_err_abort_success";
|
||||
@@ -112,6 +113,14 @@ const char* err_to_string(int err) {
|
||||
|
||||
#if WITH_CIDERRAIN
|
||||
|
||||
// MARK: exploit (libciderra1n)
|
||||
// NOTE: this backend is NOT publicly available
|
||||
|
||||
// ciderra1n is based on the checkra1n 1337 implementation
|
||||
// of the checkm8 exploit using DFU aborts instead of usb resets
|
||||
// this supports Linux (liteusb), and Darwin (IOKit)
|
||||
// this also supports A7 devices.
|
||||
|
||||
int exploit(int *stage)
|
||||
{
|
||||
LOG("Waiting for devices...");
|
||||
@@ -142,6 +151,7 @@ int exploit(int *stage)
|
||||
|
||||
if (flag & kDeviceDFUModeFlag) {
|
||||
if (flag & kDeviceStandardPwnedDFUModeFlag) {
|
||||
// we cant do shit sorry
|
||||
LOG_ERROR("Found an unknown pwned DFU mode device");
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
@@ -149,6 +159,7 @@ int exploit(int *stage)
|
||||
}
|
||||
|
||||
if (flag & kDevicePwnedDFUModeFlag) {
|
||||
// we cant do shit sorry
|
||||
LOG_ERROR("Detected pwned DFU mode device, please enter normal DFU mode.");
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
@@ -156,6 +167,7 @@ int exploit(int *stage)
|
||||
}
|
||||
|
||||
if (!(flag & kDeviceNotSoftDFUModeFlag)) {
|
||||
// we cant do shit sorry
|
||||
LOG_ERROR("Found soft-DFU mode device");
|
||||
usb_close(client);
|
||||
*stage = STAGE_ERROR;
|
||||
@@ -240,6 +252,11 @@ int exploit(int *stage)
|
||||
*stage = STAGE_ERROR;
|
||||
break; // err
|
||||
}
|
||||
|
||||
// assume everything went well, though
|
||||
// depending on the components sent to
|
||||
// the device, the device may not even
|
||||
// boot at all (not our fault xD)
|
||||
*stage = STAGE_DONE;
|
||||
break; // success
|
||||
}
|
||||
@@ -262,6 +279,15 @@ int exploit(int *stage)
|
||||
|
||||
#else // WITH_CIDERRAIN
|
||||
|
||||
// MARK: exploit (libopenra1n)
|
||||
// NOTE: this backend is publicly available
|
||||
|
||||
// openra1n is based on the gaster implementation of the exploit
|
||||
// which is the more well-known implementation of checkm8
|
||||
// this supports Windows (Libusb), Linux (Libusb), and Darwin (IOKit)
|
||||
// on the contrary while gaster *does* support A7, openra1n does not.
|
||||
// (yet to be implemented, cc @Mineek)
|
||||
|
||||
int exploit(int *stage)
|
||||
{
|
||||
LOG("Waiting for devices...");
|
||||
@@ -279,10 +305,14 @@ int exploit(int *stage)
|
||||
init_usb_handle(&pongoHandle, VID_APPLE, PID_PONGO);
|
||||
|
||||
for (;;) {
|
||||
// pongoOS is checked first
|
||||
if (wait_usb_handle(&pongoHandle)) {
|
||||
LOG("Found pongo mode device");
|
||||
*stage = STAGE_PONGO;
|
||||
|
||||
if (palera1n_flags & palerain_option_pongo_exit)
|
||||
goto pongo_done;
|
||||
|
||||
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));
|
||||
@@ -290,10 +320,16 @@ int exploit(int *stage)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// assume everything went well, though
|
||||
// depending on the components sent to
|
||||
// the device, the device may not even
|
||||
// boot at all (not our fault xD)
|
||||
pongo_done:
|
||||
*stage = STAGE_DONE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// DFU is checked second
|
||||
if (wait_usb_handle(&dfuHandle)) {
|
||||
char *sn = get_usb_serial_number(&dfuHandle);
|
||||
if (!sn) goto reloop;
|
||||
@@ -307,6 +343,7 @@ int exploit(int *stage)
|
||||
}
|
||||
|
||||
if (dfu_serial_number_is_pwned(sn)) {
|
||||
// we cant do shit sorry
|
||||
LOG_ERROR("Detected pwned DFU mode device, please enter normal DFU mode.");
|
||||
free(sn);
|
||||
*stage = STAGE_ERROR;
|
||||
@@ -343,6 +380,7 @@ int exploit(int *stage)
|
||||
*stage = STAGE_RESET;
|
||||
goto reloop;
|
||||
}
|
||||
|
||||
*stage = STAGE_SPRAY;
|
||||
goto reloop;
|
||||
case STAGE_SPRAY:
|
||||
|
||||
+12
-2
@@ -44,6 +44,8 @@
|
||||
#include "globals.h"
|
||||
#include "paleinfo.h"
|
||||
|
||||
#define CMD_LENGTH_MAX 512
|
||||
|
||||
p1_transfer_ret_t issue_pongo_command(const p1_usb_handle_t *handle, const char *command)
|
||||
{
|
||||
p1_transfer_ret_t result;
|
||||
@@ -52,7 +54,7 @@ p1_transfer_ret_t issue_pongo_command(const p1_usb_handle_t *handle, const char
|
||||
uint32_t outlen = 0;
|
||||
uint8_t in_progress = 1;
|
||||
|
||||
char command_buf[512];
|
||||
char command_buf[CMD_LENGTH_MAX];
|
||||
char stdout_buf[0x2000];
|
||||
|
||||
memset(stdout_buf, 0, sizeof(stdout_buf));
|
||||
@@ -60,7 +62,9 @@ p1_transfer_ret_t issue_pongo_command(const p1_usb_handle_t *handle, const char
|
||||
if (command != NULL) {
|
||||
size_t len = strlen(command);
|
||||
|
||||
if (len > 510) {
|
||||
// unlikely to happen, unless we add support for pongoterm
|
||||
// TODO: discuss on adding a pongoterm
|
||||
if (len > CMD_LENGTH_MAX) {
|
||||
LOG_ERROR("Pongo command too long: %s", command);
|
||||
result.ret = 1;
|
||||
return result;
|
||||
@@ -87,6 +91,7 @@ p1_transfer_ret_t issue_pongo_command(const p1_usb_handle_t *handle, const char
|
||||
if (strncmp(command,"boot",4) == 0) goto result;
|
||||
}
|
||||
|
||||
// TODO: does this work correctly?
|
||||
while (in_progress) {
|
||||
#if WITH_CIDERRAIN
|
||||
result = usb_ctrl_transfer(handle, 0xA1, 2, 0, 0, &in_progress, sizeof(in_progress));
|
||||
@@ -194,6 +199,8 @@ p1_checkm8_err_t send_compressed_pongo(p1_usb_handle_t *handle, const uint8_t *p
|
||||
return cr;
|
||||
}
|
||||
|
||||
// TODO: support early-exit but with all embedded artifacts already loaded
|
||||
|
||||
p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle)
|
||||
{
|
||||
p1_transfer_ret_t result;
|
||||
@@ -217,6 +224,7 @@ p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle)
|
||||
result = upload_buffer_to_pongo(handle, g_payload_kpf.data, g_payload_kpf.data_len);
|
||||
if (result.ret != 0) goto bad;
|
||||
|
||||
// TODO: discuss on adding support for compressed artifacts
|
||||
// embedded artifacts are lzma compressed, mostly for binary size
|
||||
// this tells pongo to decompress after sending the KPF
|
||||
// overwritten artifacts should not be compressed, so we always
|
||||
@@ -241,6 +249,7 @@ p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle)
|
||||
result = upload_buffer_to_pongo(handle, g_payload_ramdisk.data, g_payload_ramdisk.data_len);
|
||||
if (result.ret != 0) goto bad;
|
||||
|
||||
// TODO: discuss on adding support for compressed artifacts
|
||||
// embedded artifacts are lzma compressed, mostly for binary size
|
||||
// this tells pongo to decompress after sending the ramdisk
|
||||
// overwritten artifacts should not be compressed, so we always
|
||||
@@ -269,6 +278,7 @@ p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle)
|
||||
if (result.ret != 0) goto bad;
|
||||
}
|
||||
|
||||
// TODO: why do we check results
|
||||
result = issue_pongo_command(handle, "bootx");
|
||||
if (result.ret != 0) goto bad;
|
||||
|
||||
|
||||
+1
-1
@@ -47,9 +47,9 @@ typedef checkm8_err_t p1_checkm8_err_t;
|
||||
#endif
|
||||
|
||||
#define PONGO_MAX_SZ (0x7fe00)
|
||||
// used for checking overridden files (KPF mainly)
|
||||
#define MACHO_MAGIC_32 (const unsigned char[]){ 0xCE, 0xFA, 0xED, 0xFE }
|
||||
#define MACHO_MAGIC_64 (const unsigned char[]){ 0xCF, 0xFA, 0xED, 0xFE }
|
||||
#define CMD_LENGTH_MAX 512
|
||||
|
||||
p1_checkm8_err_t send_compressed_pongo(p1_usb_handle_t *handle, const uint8_t *pongo_bin, const size_t pongo_bin_length);
|
||||
p1_checkm8_err_t send_full_pongo_jailbreak(p1_usb_handle_t *handle);
|
||||
|
||||
Reference in new issue
Block a user