summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2024-10-15 22:09:43 +0200
committerGravatar Nikias Bassen2024-10-15 22:09:43 +0200
commit151c680feb6a0775d1b979dbdfca2ac6fdfc8cad (patch)
tree5ced724a09715e506df91a51fb8a9b7f69b9b057 /src
parentf4a18ee13dd84d76dd6ebb9b21cd6bce6f37e4ec (diff)
downloadidevicerestore-151c680feb6a0775d1b979dbdfca2ac6fdfc8cad.tar.gz
idevicerestore-151c680feb6a0775d1b979dbdfca2ac6fdfc8cad.tar.bz2
Fix iPhone 16 restore from normal mode and add support for RecoveryOS
Diffstat (limited to 'src')
-rw-r--r--src/common.h3
-rw-r--r--src/dfu.c2
-rw-r--r--src/idevicerestore.c60
-rw-r--r--src/idevicerestore.h2
-rw-r--r--src/img4.c193
-rw-r--r--src/img4.h2
-rw-r--r--src/normal.c26
-rw-r--r--src/normal.h1
-rw-r--r--src/recovery.c2
-rw-r--r--src/restore.c391
10 files changed, 578 insertions, 104 deletions
diff --git a/src/common.h b/src/common.h
index 8085a1a..872d2f9 100644
--- a/src/common.h
+++ b/src/common.h
@@ -104,7 +104,9 @@ struct idevicerestore_client_t {
int nonce_size;
int image4supported;
plist_t build_manifest;
+ plist_t firmware_preflight_info;
plist_t preflight_info;
+ plist_t parameters;
char* udid;
char* srnm;
ipsw_archive_t ipsw;
@@ -131,6 +133,7 @@ struct idevicerestore_client_t {
cond_t device_event_cond;
int ignore_device_add_events;
plist_t macos_variant;
+ plist_t recovery_variant;
char* restore_variant;
char* filesystem;
int delete_fs;
diff --git a/src/dfu.c b/src/dfu.c
index 8557c29..e6b45af 100644
--- a/src/dfu.c
+++ b/src/dfu.c
@@ -168,7 +168,7 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide
unsigned char* data = NULL;
uint32_t size = 0;
- if (personalize_component(component, component_data, component_size, tss, &data, &size) < 0) {
+ if (personalize_component(client, component, component_data, component_size, tss, &data, &size) < 0) {
error("ERROR: Unable to get personalized component: %s\n", component);
free(component_data);
return -1;
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index fb0b329..b8bb1d0 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -1227,6 +1227,29 @@ int idevicerestore_start(struct idevicerestore_client_t* client)
} else {
free(nonce);
}
+ if (client->mode == MODE_NORMAL) {
+ plist_t ap_params = normal_get_lockdown_value(client, NULL, "ApParameters");
+ if (ap_params) {
+ if (!client->parameters) {
+ client->parameters = plist_new_dict();
+ }
+ plist_dict_merge(&client->parameters, ap_params);
+ plist_t p_sep_nonce = plist_dict_get_item(ap_params, "SepNonce");
+ uint64_t sep_nonce_size = 0;
+ const char* sep_nonce = plist_get_data_ptr(p_sep_nonce, &sep_nonce_size);
+ info("Getting SepNonce in normal mode... ");
+ int i = 0;
+ for (i = 0; i < sep_nonce_size; i++) {
+ info("%02x ", (unsigned char)sep_nonce[i]);
+ }
+ info("\n");
+ plist_free(ap_params);
+ }
+ plist_t req_nonce_slot = plist_access_path(build_identity, 2, "Info", "RequiresNonceSlot");
+ if (req_nonce_slot) {
+ plist_dict_set_item(client->parameters, "RequiresNonceSlot", plist_copy(req_nonce_slot));
+ }
+ }
}
if (client->flags & FLAG_QUIT) {
@@ -1263,8 +1286,12 @@ int idevicerestore_start(struct idevicerestore_client_t* client)
plist_t recovery_variant = plist_access_path(build_identity, 2, "Info", "RecoveryVariant");
if (recovery_variant) {
const char* recovery_variant_str = plist_get_string_ptr(recovery_variant, NULL);
- plist_t recovery_build_identity = build_manifest_get_build_identity_for_model_with_variant(client->build_manifest, client->device->hardware_model, recovery_variant_str, 1);
- if (get_tss_response(client, recovery_build_identity, &client->tss_recoveryos_root_ticket) < 0) {
+ client->recovery_variant = build_manifest_get_build_identity_for_model_with_variant(client->build_manifest, client->device->hardware_model, recovery_variant_str, 1);
+ if (!client->recovery_variant) {
+ error("ERROR: Variant '%s' not found in BuildManifest\n", recovery_variant_str);
+ return -1;
+ }
+ if (get_tss_response(client, client->recovery_variant, &client->tss_recoveryos_root_ticket) < 0) {
error("ERROR: Unable to get SHSH blobs for this device (%s)\n", recovery_variant_str);
return -1;
}
@@ -1614,6 +1641,9 @@ void idevicerestore_client_free(struct idevicerestore_client_t* client)
if (client->build_manifest) {
plist_free(client->build_manifest);
}
+ if (client->firmware_preflight_info) {
+ plist_free(client->firmware_preflight_info);
+ }
if (client->preflight_info) {
plist_free(client->preflight_info);
}
@@ -2276,17 +2306,21 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident
/* populate parameters */
plist_t parameters = plist_new_dict();
+ plist_dict_merge(&parameters, client->parameters);
+
plist_dict_set_item(parameters, "ApECID", plist_new_uint(client->ecid));
if (client->nonce) {
plist_dict_set_item(parameters, "ApNonce", plist_new_data((const char*)client->nonce, client->nonce_size));
}
- unsigned char* sep_nonce = NULL;
- unsigned int sep_nonce_size = 0;
- get_sep_nonce(client, &sep_nonce, &sep_nonce_size);
- if (sep_nonce) {
- plist_dict_set_item(parameters, "ApSepNonce", plist_new_data((const char*)sep_nonce, sep_nonce_size));
- free(sep_nonce);
+ if (!plist_dict_get_item(parameters, "SepNonce")) {
+ unsigned char* sep_nonce = NULL;
+ unsigned int sep_nonce_size = 0;
+ get_sep_nonce(client, &sep_nonce, &sep_nonce_size);
+ if (sep_nonce) {
+ plist_dict_set_item(parameters, "ApSepNonce", plist_new_data((const char*)sep_nonce, sep_nonce_size));
+ free(sep_nonce);
+ }
}
plist_dict_set_item(parameters, "ApProductionMode", plist_new_bool(1));
@@ -2344,7 +2378,7 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident
if (client->mode == MODE_NORMAL) {
/* normal mode; request baseband ticket aswell */
plist_t pinfo = NULL;
- normal_get_preflight_info(client, &pinfo);
+ normal_get_firmware_preflight_info(client, &pinfo);
if (pinfo) {
plist_dict_copy_data(parameters, pinfo, "BbNonce", "Nonce");
plist_dict_copy_uint(parameters, pinfo, "BbChipID", "ChipID");
@@ -2365,6 +2399,10 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident
tss_request_add_vinyl_tags(request, parameters, NULL);
}
}
+ client->firmware_preflight_info = pinfo;
+ pinfo = NULL;
+
+ normal_get_preflight_info(client, &pinfo);
client->preflight_info = pinfo;
}
@@ -2718,7 +2756,7 @@ int extract_component(ipsw_archive_t ipsw, const char* path, unsigned char** com
return 0;
}
-int personalize_component(const char *component_name, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** personalized_component, unsigned int* personalized_component_size)
+int personalize_component(struct idevicerestore_client_t* client, const char *component_name, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** personalized_component, unsigned int* personalized_component_size)
{
unsigned char* component_blob = NULL;
unsigned int component_blob_size = 0;
@@ -2727,7 +2765,7 @@ int personalize_component(const char *component_name, const unsigned char* compo
if (tss_response && plist_dict_get_item(tss_response, "ApImg4Ticket")) {
/* stitch ApImg4Ticket into IMG4 file */
- img4_stitch_component(component_name, component_data, component_size, tss_response, &stitched_component, &stitched_component_size);
+ img4_stitch_component(component_name, component_data, component_size, client->parameters, tss_response, &stitched_component, &stitched_component_size);
} else {
/* try to get blob for current component from tss response */
if (tss_response && tss_response_get_blob_by_entry(tss_response, component_name, &component_blob) < 0) {
diff --git a/src/idevicerestore.h b/src/idevicerestore.h
index 5afcf1a..fe9d11f 100644
--- a/src/idevicerestore.h
+++ b/src/idevicerestore.h
@@ -115,7 +115,7 @@ int build_identity_has_component(plist_t build_identity, const char* component);
int build_identity_get_component_path(plist_t build_identity, const char* component, char** path);
int ipsw_extract_filesystem(ipsw_archive_t ipsw, plist_t build_identity, char** filesystem);
int extract_component(ipsw_archive_t ipsw, const char* path, unsigned char** component_data, unsigned int* component_size);
-int personalize_component(const char *component, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** personalized_component, unsigned int* personalized_component_size);
+int personalize_component(struct idevicerestore_client_t* client, const char *component, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** personalized_component, unsigned int* personalized_component_size);
int get_preboard_manifest(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* manifest);
const char* get_component_name(const char* filename);
diff --git a/src/img4.c b/src/img4.c
index c010ce4..e9d4cca 100644
--- a/src/img4.c
+++ b/src/img4.c
@@ -26,6 +26,7 @@
#include "common.h"
#include "img4.h"
+#include "endianness.h"
#define ASN1_PRIVATE 0xc0
#define ASN1_PRIMITIVE_TAG 0x1f
@@ -395,7 +396,7 @@ static const char *_img4_get_component_tag(const char *compname)
return NULL;
}
-int img4_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** img4_data, unsigned int *img4_size)
+int img4_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, plist_t parameters, plist_t tss_response, unsigned char** img4_data, unsigned int *img4_size)
{
unsigned char* magic_header = NULL;
unsigned int magic_header_size = 0;
@@ -459,14 +460,17 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
snprintf(tbm_key, strlen(component_name)+5, "%s-TBM", component_name);
plist_t tbm_dict = plist_dict_get_item(tss_response, tbm_key);
free(tbm_key);
+ uint64_t ucon_size = 0;
+ const char* ucon_data = NULL;
+ uint64_t ucer_size = 0;
+ const char* ucer_data = NULL;
if (tbm_dict) {
plist_t dt = plist_dict_get_item(tbm_dict, "ucon");
if (!dt) {
error("ERROR: %s: Missing ucon node in %s-TBM dictionary\n", __func__, component_name);
return -1;
}
- uint64_t ucon_size = 0;
- const char* ucon_data = plist_get_data_ptr(dt, &ucon_size);
+ ucon_data = plist_get_data_ptr(dt, &ucon_size);
if (!ucon_data) {
error("ERROR: %s: Missing ucon data in %s-TBM dictionary\n", __func__, component_name);
return -1;
@@ -476,76 +480,141 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
error("ERROR: %s: Missing ucer data node in %s-TBM dictionary\n", __func__, component_name);
return -1;
}
- uint64_t ucer_size = 0;
- const char* ucer_data = plist_get_data_ptr(dt, &ucer_size);
+ ucer_data = plist_get_data_ptr(dt, &ucer_size);
if (!ucer_data) {
error("ERROR: %s: Missing ucer data in %s-TBM dictionary\n", __func__, component_name);
return -1;
}
+ }
+
+ int nonce_slot_required = plist_dict_get_bool(parameters, "RequiresNonceSlot") && (!strcmp(component_name, "SEP") || !strcmp(component_name, "SepStage1") || !strcmp(component_name, "LLB"));
- unsigned char *im4rset = (unsigned char*)malloc(16 + 8 + 8 + ucon_size + 16 + 8 + 8 + ucer_size + 16);
+ if (ucon_data || ucer_data || nonce_slot_required) {
+ size_t im4r_size = 16;
+ if (ucon_data) {
+ im4r_size += 8 + 8 + ucon_size + 16;
+ }
+ if (ucer_data) {
+ im4r_size += 8 + 8 + ucer_size + 16;
+ }
+ if (nonce_slot_required) {
+ im4r_size += 16;
+ }
+ unsigned char *im4rset = (unsigned char*)malloc(im4r_size);
unsigned char *p_im4rset = im4rset;
unsigned int im4rlen = 0;
+ // ----------- anid/snid -------
+ if (nonce_slot_required) {
+ const char* tag_name = NULL;
+ uint64_t tag_value = 0;
+ if (!strcmp(component_name, "SEP") || !strcmp(component_name, "SepStage1")) {
+ tag_name = "snid";
+ tag_value = 2;
+ if (plist_dict_get_item(parameters, "SepNonceSlotID")) {
+ tag_value = plist_dict_get_uint(parameters, "SepNonceSlotID");
+ }
+ } else {
+ tag_name = "anid";
+ tag_value = 0;
+ if (plist_dict_get_item(parameters, "ApNonceSlotID")) {
+ tag_value = plist_dict_get_uint(parameters, "ApNonceSlotID");
+ }
+ }
+ // write priv anid/snid element
+ asn1_write_priv_element(&p_im4rset, &im4rlen, __bswap_32(*(uint32_t*)tag_name));
+ // write anid/snid IA5STRING and anid/snid value
+ unsigned char inner_seq[16];
+ unsigned char *p_inner_seq = &inner_seq[0];
+ unsigned int inner_seq_hdr_len = 0;
+ asn1_write_element(&p_inner_seq, &inner_seq_hdr_len, ASN1_IA5_STRING, (void*)tag_name, -1);
+ asn1_write_element(&p_inner_seq, &inner_seq_hdr_len, ASN1_INTEGER, (void*)&tag_value, -1);
+
+ // write anid/snid sequence
+ unsigned char elem_seq[8];
+ unsigned char *p = &elem_seq[0];
+ unsigned int seq_hdr_len = 0;
+ asn1_write_element_header(ASN1_SEQUENCE | ASN1_CONSTRUCTED, inner_seq_hdr_len, &p, &seq_hdr_len);
+
+ // add size to priv anid/snid element
+ asn1_write_size(inner_seq_hdr_len + seq_hdr_len, &p_im4rset, &im4rlen);
+
+ // put it together
+ memcpy(p_im4rset, elem_seq, seq_hdr_len);
+ p_im4rset += seq_hdr_len;
+ im4rlen += seq_hdr_len;
+ memcpy(p_im4rset, inner_seq, inner_seq_hdr_len);
+ p_im4rset += inner_seq_hdr_len;
+ im4rlen += inner_seq_hdr_len;
+ }
+
// ----------- ucon ------------
- // write priv ucon element
- asn1_write_priv_element(&p_im4rset, &im4rlen, *(uint32_t*)"nocu");
-
- // write ucon IA5STRING and ucon data
- unsigned char ucon_seq[16];
- unsigned char *p_ucon_seq = &ucon_seq[0];
- unsigned int ucon_seq_hdr_len = 0;
- asn1_write_element(&p_ucon_seq, &ucon_seq_hdr_len, ASN1_IA5_STRING, (void*)"ucon", -1);
- asn1_write_element_header(ASN1_OCTET_STRING, ucon_size, &p_ucon_seq, &ucon_seq_hdr_len);
-
- // write ucon sequence
- unsigned char elem_seq[8];
- unsigned char *p = &elem_seq[0];
- unsigned int seq_hdr_len = 0;
- asn1_write_element_header(ASN1_SEQUENCE | ASN1_CONSTRUCTED, ucon_seq_hdr_len + ucon_size, &p, &seq_hdr_len);
-
- // add size to priv ucon element
- asn1_write_size(ucon_seq_hdr_len + ucon_size + seq_hdr_len, &p_im4rset, &im4rlen);
-
- // put it together
- memcpy(p_im4rset, elem_seq, seq_hdr_len);
- p_im4rset += seq_hdr_len;
- im4rlen += seq_hdr_len;
- memcpy(p_im4rset, ucon_seq, ucon_seq_hdr_len);
- p_im4rset += ucon_seq_hdr_len;
- im4rlen += ucon_seq_hdr_len;
- memcpy(p_im4rset, ucon_data, ucon_size);
- p_im4rset += ucon_size;
- im4rlen += ucon_size;
+ if (ucon_data) {
+ // write priv ucon element
+ asn1_write_priv_element(&p_im4rset, &im4rlen, *(uint32_t*)"nocu");
+
+ // write ucon IA5STRING and ucon data header
+ unsigned char inner_seq[16];
+ unsigned char *p_inner_seq = &inner_seq[0];
+ unsigned int inner_seq_hdr_len = 0;
+ asn1_write_element(&p_inner_seq, &inner_seq_hdr_len, ASN1_IA5_STRING, (void*)"ucon", -1);
+ asn1_write_element_header(ASN1_OCTET_STRING, ucon_size, &p_inner_seq, &inner_seq_hdr_len);
+
+ // write ucon sequence
+ unsigned char elem_seq[8];
+ unsigned char *p = &elem_seq[0];
+ unsigned int seq_hdr_len = 0;
+ asn1_write_element_header(ASN1_SEQUENCE | ASN1_CONSTRUCTED, inner_seq_hdr_len + ucon_size, &p, &seq_hdr_len);
+
+ // add size to priv ucon element
+ asn1_write_size(inner_seq_hdr_len + ucon_size + seq_hdr_len, &p_im4rset, &im4rlen);
+
+ // put it together
+ memcpy(p_im4rset, elem_seq, seq_hdr_len);
+ p_im4rset += seq_hdr_len;
+ im4rlen += seq_hdr_len;
+ memcpy(p_im4rset, inner_seq, inner_seq_hdr_len);
+ p_im4rset += inner_seq_hdr_len;
+ im4rlen += inner_seq_hdr_len;
+ // write ucon data
+ memcpy(p_im4rset, ucon_data, ucon_size);
+ p_im4rset += ucon_size;
+ im4rlen += ucon_size;
+ }
// ----------- ucer ------------
- // write priv ucer element
- asn1_write_priv_element(&p_im4rset, &im4rlen, *(uint32_t*)"recu");
-
- // write ucon IA5STRING and ucer data
- unsigned char ucer_seq[16];
- unsigned char *p_ucer_seq = &ucer_seq[0];
- unsigned int ucer_seq_hdr_len = 0;
- asn1_write_element(&p_ucer_seq, &ucer_seq_hdr_len, ASN1_IA5_STRING, (void*)"ucer", -1);
- asn1_write_element_header(ASN1_OCTET_STRING, ucer_size, &p_ucer_seq, &ucer_seq_hdr_len);
-
- p = &elem_seq[0];
- seq_hdr_len = 0;
- asn1_write_element_header(ASN1_SEQUENCE | ASN1_CONSTRUCTED, ucer_seq_hdr_len + ucer_size, &p, &seq_hdr_len);
-
- // add size to priv ucer element
- asn1_write_size(ucer_seq_hdr_len + ucer_size + seq_hdr_len, &p_im4rset, &im4rlen);
-
- // put it together
- memcpy(p_im4rset, elem_seq, seq_hdr_len);
- p_im4rset += seq_hdr_len;
- im4rlen += seq_hdr_len;
- memcpy(p_im4rset, ucer_seq, ucer_seq_hdr_len);
- p_im4rset += ucer_seq_hdr_len;
- im4rlen += ucer_seq_hdr_len;
- memcpy(p_im4rset, ucer_data, ucer_size);
- p_im4rset += ucer_size;
- im4rlen += ucer_size;
+ if (ucer_data) {
+ // write priv ucer element
+ asn1_write_priv_element(&p_im4rset, &im4rlen, *(uint32_t*)"recu");
+
+ // write ucer IA5STRING and ucer data header
+ unsigned char inner_seq[16];
+ unsigned char *p_inner_seq = &inner_seq[0];
+ unsigned int inner_seq_hdr_len = 0;
+ asn1_write_element(&p_inner_seq, &inner_seq_hdr_len, ASN1_IA5_STRING, (void*)"ucer", -1);
+ asn1_write_element_header(ASN1_OCTET_STRING, ucer_size, &p_inner_seq, &inner_seq_hdr_len);
+
+ // write ucer sequence
+ unsigned char elem_seq[8];
+ unsigned char *p = &elem_seq[0];
+ unsigned int seq_hdr_len = 0;
+ asn1_write_element_header(ASN1_SEQUENCE | ASN1_CONSTRUCTED, inner_seq_hdr_len + ucer_size, &p, &seq_hdr_len);
+
+ // add size to priv ucer element
+ asn1_write_size(inner_seq_hdr_len + ucer_size + seq_hdr_len, &p_im4rset, &im4rlen);
+
+ // put it together
+ memcpy(p_im4rset, elem_seq, seq_hdr_len);
+ p_im4rset += seq_hdr_len;
+ im4rlen += seq_hdr_len;
+ memcpy(p_im4rset, inner_seq, inner_seq_hdr_len);
+ p_im4rset += inner_seq_hdr_len;
+ im4rlen += inner_seq_hdr_len;
+ // write ucer data
+ memcpy(p_im4rset, ucer_data, ucer_size);
+ p_im4rset += ucer_size;
+ im4rlen += ucer_size;
+ }
// now construct IM4R
diff --git a/src/img4.h b/src/img4.h
index 1056fa6..19c1c84 100644
--- a/src/img4.h
+++ b/src/img4.h
@@ -26,7 +26,7 @@
extern "C" {
#endif
-int img4_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** img4_data, unsigned int *img4_size);
+int img4_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, plist_t parameters, plist_t tss_response, unsigned char** img4_data, unsigned int *img4_size);
int img4_create_local_manifest(plist_t request, plist_t build_identity, plist_t* manifest);
#ifdef __cplusplus
diff --git a/src/normal.c b/src/normal.c
index e699bbe..9e46080 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -342,6 +342,18 @@ static int normal_get_nonce_by_key(struct idevicerestore_client_t* client, const
int normal_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, unsigned int* nonce_size)
{
+ plist_t node = normal_get_lockdown_value(client, NULL, "ApParameters");
+ if (PLIST_IS_DICT(node)) {
+ plist_t nonce_node = plist_dict_get_item(node, "SepNonce");
+ if (nonce_node) {
+ uint64_t n_size = 0;
+ plist_get_data_val(nonce_node, (char**)nonce, &n_size);
+ *nonce_size = (unsigned int)n_size;
+ plist_free(node);
+ return 0;
+ }
+ }
+ plist_free(node);
return normal_get_nonce_by_key(client, "SEPNonce", nonce, nonce_size);
}
@@ -365,7 +377,7 @@ int normal_is_image4_supported(struct idevicerestore_client_t* client)
return bval;
}
-int normal_get_preflight_info(struct idevicerestore_client_t* client, plist_t *preflight_info)
+int normal_get_firmware_preflight_info(struct idevicerestore_client_t* client, plist_t *preflight_info)
{
uint8_t has_telephony_capability = 0;
plist_t node;
@@ -389,6 +401,18 @@ int normal_get_preflight_info(struct idevicerestore_client_t* client, plist_t *p
return 0;
}
+int normal_get_preflight_info(struct idevicerestore_client_t* client, plist_t *preflight_info)
+{
+ plist_t node = normal_get_lockdown_value(client, NULL, "PreflightInfo");
+ if (PLIST_IS_DICT(node)) {
+ *preflight_info = node;
+ } else {
+ debug("DEBUG: No PreflightInfo available.\n");
+ *preflight_info = NULL;
+ }
+ return 0;
+}
+
int normal_handle_create_stashbag(struct idevicerestore_client_t* client, plist_t manifest)
{
int result = -1;
diff --git a/src/normal.h b/src/normal.h
index 7741ac5..d3d7b0c 100644
--- a/src/normal.h
+++ b/src/normal.h
@@ -38,6 +38,7 @@ int normal_enter_recovery(struct idevicerestore_client_t* client);
int normal_is_image4_supported(struct idevicerestore_client_t* client);
int normal_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, unsigned int* nonce_size);
int normal_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, unsigned int* nonce_size);
+int normal_get_firmware_preflight_info(struct idevicerestore_client_t* client, plist_t *preflight_info);
int normal_get_preflight_info(struct idevicerestore_client_t* client, plist_t *preflight_info);
plist_t normal_get_lockdown_value(struct idevicerestore_client_t* client, const char* domain, const char* key);
int normal_handle_create_stashbag(struct idevicerestore_client_t* client, plist_t manifest);
diff --git a/src/recovery.c b/src/recovery.c
index afda4a9..c451350 100644
--- a/src/recovery.c
+++ b/src/recovery.c
@@ -305,7 +305,7 @@ int recovery_send_component(struct idevicerestore_client_t* client, plist_t buil
return -1;
}
- ret = personalize_component(component, component_data, component_size, client->tss, &data, &size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss, &data, &size);
free(component_data);
if (ret < 0) {
error("ERROR: Unable to get personalized component: %s\n", component);
diff --git a/src/restore.c b/src/restore.c
index 6fdf755..2daeea2 100644
--- a/src/restore.c
+++ b/src/restore.c
@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
#include <libgen.h>
+#include <math.h>
#include <libimobiledevice/restore.h>
#include <libimobiledevice/property_list_service.h>
#include <libimobiledevice-glue/thread.h>
@@ -1490,7 +1491,7 @@ int restore_send_component(struct idevicerestore_client_t* client, plist_t messa
return -1;
}
- ret = personalize_component(component, component_data, component_size, client->tss, &data, &size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss, &data, &size);
free(component_data);
component_data = NULL;
if (ret < 0) {
@@ -1662,7 +1663,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
return -1;
}
- ret = personalize_component(component, component_data, component_size, client->tss, &llb_data, &llb_size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss, &llb_data, &llb_size);
free(component_data);
component_data = NULL;
component_size = 0;
@@ -1718,7 +1719,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
return -1;
}
- if (personalize_component(component, component_data, component_size, client->tss, &nor_data, &nor_size) < 0) {
+ if (personalize_component(client, component, component_data, component_size, client->tss, &nor_data, &nor_size) < 0) {
free(iter);
free(comp);
free(comppath);
@@ -1765,7 +1766,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
return -1;
}
- ret = personalize_component(component, component_data, component_size, client->tss, &personalized_data, &personalized_size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss, &personalized_data, &personalized_size);
free(component_data);
component_data = NULL;
component_size = 0;
@@ -1790,7 +1791,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
return -1;
}
- ret = personalize_component(component, component_data, component_size, client->tss, &personalized_data, &personalized_size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss, &personalized_data, &personalized_size);
free(component_data);
component_data = NULL;
component_size = 0;
@@ -1815,7 +1816,7 @@ int restore_send_nor(struct idevicerestore_client_t* client, plist_t message)
return -1;
}
- ret = personalize_component(component, component_data, component_size, client->tss, &personalized_data, &personalized_size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss, &personalized_data, &personalized_size);
free(component_data);
component_data = NULL;
component_size = 0;
@@ -2518,7 +2519,7 @@ static int restore_send_image_data(struct idevicerestore_client_t *client, plist
error("ERROR: Unable to extract component: %s\n", component);
}
- ret = personalize_component(component, component_data, component_size, client->tss, &data, &size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss, &data, &size);
free(component_data);
component_data = NULL;
if (ret < 0) {
@@ -4273,7 +4274,7 @@ int restore_send_personalized_boot_object_v3(struct idevicerestore_client_t* cli
}
// Personalize IMG4
- ret = personalize_component(component, component_data, component_size, client->tss, &data, &size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss, &data, &size);
free(component_data);
component_data = NULL;
if (ret < 0) {
@@ -4439,7 +4440,7 @@ int restore_send_restore_local_policy(struct idevicerestore_client_t* client, pl
return -1;
}
- ret = personalize_component(component, component_data, component_size, client->tss_localpolicy, &data, &size);
+ ret = personalize_component(client, component, component_data, component_size, client->tss_localpolicy, &data, &size);
free(component_data);
component_data = NULL;
if (ret < 0) {
@@ -4508,6 +4509,232 @@ int restore_send_buildidentity(struct idevicerestore_client_t* client, plist_t m
return 0;
}
+int restore_send_recovery_os_file_asset_image(struct idevicerestore_client_t* client, plist_t message)
+{
+ char *fw_override_key = NULL;
+ plist_t node = plist_access_path(message, 2, "Arguments", "FWOverrideKey");
+ if (PLIST_IS_STRING(node)) {
+ plist_get_string_val(node, &fw_override_key);
+ }
+ if (!fw_override_key) {
+ error("ERROR: Failed to get FWOverrideKey from arguments. Trying to continue anyway.\n");
+ return -1;
+ }
+
+ plist_t dict = plist_new_dict();
+ if (!client->recovery_variant) {
+ error("ERROR: no RecoveryOS variant in BuildManifest. Trying to continue anyway.\n");
+ plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+ return 0;
+ }
+
+ if (strncmp(fw_override_key, "RecoveryOS", 10) != 0) {
+ error("ERROR: FWOVerrideKey has unexpected prefix\n");
+ plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+ return 0;
+ }
+
+ const char* component = fw_override_key+10;
+ char* path = NULL;
+ if (build_identity_get_component_path(client->recovery_variant, component, &path) < 0) {
+ error("ERROR: Unable to find %s path from recovery build identity. Trying to continue anyway.\n", component);
+ plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+ return 0;
+ }
+
+ unsigned char* component_data = NULL;
+ unsigned int component_size = 0;
+ int ret = extract_component(client->ipsw, path, &component_data, &component_size);
+ free(path);
+ path = NULL;
+ if (ret < 0) {
+ error("ERROR: Unable to extract component %s. Trying to continue anyway.\n", component);
+ plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+ return 0;
+ }
+
+ unsigned char* data = NULL;
+ unsigned int size = 0;
+ ret = personalize_component(client, component, component_data, component_size, client->tss_recoveryos_root_ticket, &data, &size);
+ free(component_data);
+ component_data = NULL;
+ if (ret < 0) {
+ error("ERROR: Unable to get personalized component %s. Trying to continue anyway.\n", component);
+ plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+ return 0;
+ }
+
+ info("Sending %s\n", fw_override_key);
+
+ plist_dict_set_item(dict, "AdditionalBootImages", plist_new_data((char*)data, size));
+ free(data);
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+
+ return 0;
+}
+
+int restore_send_recovery_os_iboot_fw_files_images(struct idevicerestore_client_t* client, plist_t message)
+{
+ plist_t build_id_manifest = plist_dict_get_item(client->recovery_variant, "Manifest");
+ if (!build_id_manifest) {
+ error("ERROR: Missing Manifest dictionary in build identity?!\n");
+ return -1;
+ }
+
+ plist_t firmware_files = plist_new_dict();
+
+ plist_dict_iter iter = NULL;
+ plist_dict_new_iter(build_id_manifest, &iter);
+ if (iter) {
+ char *component = NULL;
+ plist_t manifest_entry;
+ do {
+ component = NULL;
+ manifest_entry = NULL;
+ plist_dict_next_item(build_id_manifest, iter, &component, &manifest_entry);
+ if (component && PLIST_IS_DICT(manifest_entry)) {
+ uint8_t loaded_by_iboot = 0;
+ uint8_t loaded_by_iboot_stage1 = 0;
+ plist_t fw_node;
+
+ fw_node = plist_access_path(manifest_entry, 2, "Info", "IsLoadedByiBoot");
+ if (fw_node && plist_get_node_type(fw_node) == PLIST_BOOLEAN) {
+ plist_get_bool_val(fw_node, &loaded_by_iboot);
+ }
+ fw_node = plist_access_path(manifest_entry, 2, "Info", "IsLoadedByiBootStage1");
+ if (fw_node && plist_get_node_type(fw_node) == PLIST_BOOLEAN) {
+ plist_get_bool_val(fw_node, &loaded_by_iboot_stage1);
+ }
+ if (loaded_by_iboot || loaded_by_iboot_stage1) {
+ plist_t comp_path = plist_access_path(manifest_entry, 2, "Info", "Path");
+ if (comp_path) {
+ const char* path = plist_get_string_ptr(comp_path, NULL);
+ unsigned char* component_data = NULL;
+ unsigned int component_size = 0;
+ int ret = extract_component(client->ipsw, path, &component_data, &component_size);
+ if (ret == 0) {
+ unsigned char* data = NULL;
+ unsigned int size = 0;
+ ret = personalize_component(client, component, component_data, component_size, client->tss_recoveryos_root_ticket, &data, &size);
+ free(component_data);
+ component_data = NULL;
+ if (ret == 0) {
+ plist_dict_set_item(firmware_files, component, plist_new_data((char*)data, size));
+ free(data);
+ }
+ }
+ }
+ }
+ }
+ free(component);
+ } while (manifest_entry);
+ plist_mem_free(iter);
+ }
+
+ plist_t dict = plist_new_dict();
+
+ if (plist_dict_get_size(firmware_files) == 0) {
+ plist_free(firmware_files);
+ info("NOTE: No iBoot firmware files. Continuing.\n");
+ plist_dict_set_item(dict, "RecoveryOSNoAssetFound", plist_new_bool(1));
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+ return 0;
+
+ }
+
+ info("Sending iBoot additional firmware files\n");
+
+ plist_dict_set_item(dict, "AdditionalBootImages", firmware_files);
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+
+ return 0;
+}
+
+int restore_send_recovery_os_image(struct idevicerestore_client_t* client, plist_t message)
+{
+ const char* component = "OS";
+ char* path = NULL;
+ if (build_identity_get_component_path(client->recovery_variant, component, &path) < 0) {
+ error("ERROR: Unable to find %s path from build identity\n", component);
+ return -1;
+ }
+ if (!path) {
+ error("ERROR: Failed to get path for component %s\n", component);
+ return -1;
+ }
+
+ uint64_t fsize = 0;
+ ipsw_get_file_size(client->ipsw, path, &fsize);
+
+ restore_service_client_t service = _restore_get_service_client_for_data_request(client, message);
+ if (!service) {
+ error("ERROR: %s: Unable to connect to service client\n", __func__);
+ return -1;
+ }
+
+ info("Sending %s now (%" PRIu64 " bytes)\n", component, fsize);
+
+ struct _restore_send_file_data_ctx rctx;
+ rctx.client = client;
+ rctx.service = service;
+ rctx.last_progress = 0;
+
+ if (ipsw_extract_send(client->ipsw, path, 8192, (ipsw_send_cb)_restore_send_file_data, &rctx) < 0) {
+ free(path);
+ _restore_service_free(service);
+ error("ERROR: Failed to send component %s\n", component);
+ return -1;
+ }
+ free(path);
+
+ _restore_service_free(service);
+
+ info("Done sending %s\n", component);
+
+ return 0;
+}
+
+int restore_send_recovery_os_version_data(struct idevicerestore_client_t* client, plist_t message)
+{
+ plist_t build_id_info = plist_dict_get_item(client->recovery_variant, "Info");
+ if (!build_id_info) {
+ error("ERROR: Missing Info dictionary in build identity?!\n");
+ return -1;
+ }
+ plist_t version_data = plist_new_dict();
+ plist_dict_copy_item(version_data, build_id_info, "BuildNumber", NULL);
+ plist_dict_copy_item(version_data, build_id_info, "Variant", NULL);
+ plist_dict_copy_item(version_data, build_id_info, "BuildTrain", NULL);
+ plist_dict_copy_item(version_data, build_id_info, "ProductVersion", "ProductMarketingVersion");
+ char *xml = NULL;
+ uint32_t xml_len = 0;
+ plist_to_xml(version_data, &xml, &xml_len);
+ plist_free(version_data);
+
+ info("Sending RecoveryOS version data\n");
+
+ plist_t dict = plist_new_dict();
+ plist_dict_set_item(dict, "RecoveryOSVersionData", plist_new_data(xml, xml_len));
+ plist_mem_free(xml);
+ restored_send(client->restore->client, dict);
+ plist_free(dict);
+
+ return 0;
+}
+
int restore_handle_data_request_msg(struct idevicerestore_client_t* client, plist_t message)
{
plist_t node = NULL;
@@ -4702,6 +4929,34 @@ debug("%s: type = %s\n", __func__, type);
}
}
+ else if (!strcmp(type, "RecoveryOSFileAssetImage")) {
+ if (restore_send_recovery_os_file_asset_image(client, message) < 0) {
+ error("ERROR: Unable to send RecoveryOSFileImageAssetImage data\n");
+ return -1;
+ }
+ }
+
+ else if (!strcmp(type, "RecoveryOSIBootFWFilesImages")) {
+ if (restore_send_recovery_os_iboot_fw_files_images(client, message) < 0) {
+ error("ERROR: Unable to send RecoveryOSIBootFWFilesImages data\n");
+ return -1;
+ }
+ }
+
+ else if (!strcmp(type, "RecoveryOSImage")) {
+ if (restore_send_recovery_os_image(client, message) < 0) {
+ error("ERROR: Unable to send RecoveryOSImage data\n");
+ return -1;
+ }
+ }
+
+ else if (!strcmp(type, "RecoveryOSVersionData")) {
+ if (restore_send_recovery_os_version_data(client, message) < 0) {
+ error("ERROR: Unable to send RecoveryOSVersionData data\n");
+ return -1;
+ }
+ }
+
else {
// Unknown DataType!!
error("Unknown data request '%s' received\n", type);
@@ -4776,10 +5031,70 @@ static int restore_handle_restore_attestation(struct idevicerestore_client_t* cl
return 0;
}
+static void _restore_calculate_recovery_os_partition_size(struct idevicerestore_client_t* client, uint64_t* min_size, uint64_t* max_size)
+{
+ const char* asset_list[] = { "OS", "KernelCache", "DeviceTree", "iBEC", "AppleLogo", "StaticTrustCache", "iBootData", "Diags", "Ap,SystemVolumeCanonicalMetadata", "SystemVolume", "BaseSystemVolume", "Ap,BaseSystemTrustCache", "AVISP1,RTKitOS", NULL };
+
+ if (min_size) *min_size = 356;
+ if (max_size) *max_size = 420;
+
+ double total_size = 0;
+ plist_t firmware_items = plist_new_dict();
+ plist_t build_id_manifest = plist_dict_get_item(client->recovery_variant, "Manifest");
+ plist_dict_iter iter = NULL;
+ plist_dict_new_iter(build_id_manifest, &iter);
+ if (iter) {
+ char *component = NULL;
+ plist_t manifest_entry;
+ do {
+ component = NULL;
+ manifest_entry = NULL;
+ plist_dict_next_item(build_id_manifest, iter, &component, &manifest_entry);
+ if (component && PLIST_IS_DICT(manifest_entry) && plist_dict_get_item(firmware_items, component) == NULL) {
+ int add_image = 0;
+ int i = 0;
+ while (asset_list[i]) {
+ if (!strcmp(asset_list[i], component)) {
+ add_image = 1;
+ break;
+ }
+ i++;
+ }
+ plist_t fw_node;
+ fw_node = plist_access_path(manifest_entry, 2, "Info", "IsLoadedByiBoot");
+ if (fw_node && plist_get_node_type(fw_node) == PLIST_BOOLEAN) {
+ uint8_t loaded_by_iboot = 0;
+ plist_get_bool_val(fw_node, &loaded_by_iboot);
+ if (loaded_by_iboot) {
+ add_image = 1;
+ }
+ }
+ if (add_image) {
+ plist_t p_path = plist_access_path(manifest_entry, 2, "Info", "Path");
+ if (p_path) {
+ const char* path = plist_get_string_ptr(p_path, NULL);
+ uint64_t fsize = 0;
+ if (ipsw_get_file_size(client->ipsw, path, &fsize) == 0) {
+ debug("%s: Adding %s (%s, %llu bytes)\n", __func__, component, path, fsize);
+ total_size += (double)fsize / 0x100000;
+ }
+ }
+ }
+ }
+ free(component);
+ } while (manifest_entry);
+ plist_mem_free(iter);
+ }
+ total_size = ceil(total_size);
+ if (min_size) *min_size = total_size * 1.05 + 25;
+ if (max_size) *max_size = total_size * 1.25 + 25;
+}
+
// Extracted from ac2
plist_t restore_supported_data_types()
{
plist_t dict = plist_new_dict();
+ plist_dict_set_item(dict, "AuthInstallCACert", plist_new_bool(1));
plist_dict_set_item(dict, "BasebandBootData", plist_new_bool(0));
plist_dict_set_item(dict, "BasebandData", plist_new_bool(0));
plist_dict_set_item(dict, "BasebandStackData", plist_new_bool(0));
@@ -4797,20 +5112,26 @@ plist_t restore_supported_data_types()
plist_dict_set_item(dict, "FileData", plist_new_bool(0));
plist_dict_set_item(dict, "FileDataDone", plist_new_bool(0));
plist_dict_set_item(dict, "FirmwareUpdaterData", plist_new_bool(0));
+ plist_dict_set_item(dict, "FirmwareUpdaterDataV2", plist_new_bool(0));
+ plist_dict_set_item(dict, "FirmwareUpdaterDataV3", plist_new_bool(1));
+ plist_dict_set_item(dict, "FirmwareUpdaterPreflight", plist_new_bool(1));
plist_dict_set_item(dict, "GrapeFWData", plist_new_bool(0));
plist_dict_set_item(dict, "HPMFWData", plist_new_bool(0));
plist_dict_set_item(dict, "HostSystemTime", plist_new_bool(1));
plist_dict_set_item(dict, "KernelCache", plist_new_bool(0));
+ plist_dict_set_item(dict, "MessageUseStreamedImageFile", plist_new_bool(1));
plist_dict_set_item(dict, "NORData", plist_new_bool(0));
plist_dict_set_item(dict, "NitrogenFWData", plist_new_bool(1));
plist_dict_set_item(dict, "OpalFWData", plist_new_bool(0));
plist_dict_set_item(dict, "OverlayRootDataCount", plist_new_bool(0));
plist_dict_set_item(dict, "OverlayRootDataForKey", plist_new_bool(1));
+ plist_dict_set_item(dict, "OverlayRootDataForKeyIndex", plist_new_bool(1));
plist_dict_set_item(dict, "PeppyFWData", plist_new_bool(1));
plist_dict_set_item(dict, "PersonalizedBootObjectV3", plist_new_bool(0));
plist_dict_set_item(dict, "PersonalizedData", plist_new_bool(1));
plist_dict_set_item(dict, "ProvisioningData", plist_new_bool(0));
plist_dict_set_item(dict, "RamdiskFWData", plist_new_bool(1));
+ plist_dict_set_item(dict, "ReceiptManifest", plist_new_bool(1));
plist_dict_set_item(dict, "RecoveryOSASRImage", plist_new_bool(1));
plist_dict_set_item(dict, "RecoveryOSAppleLogo", plist_new_bool(1));
plist_dict_set_item(dict, "RecoveryOSDeviceTree", plist_new_bool(1));
@@ -4824,6 +5145,7 @@ plist_t restore_supported_data_types()
plist_dict_set_item(dict, "RecoveryOSRootTicketData", plist_new_bool(1));
plist_dict_set_item(dict, "RecoveryOSStaticTrustCache", plist_new_bool(1));
plist_dict_set_item(dict, "RecoveryOSVersionData", plist_new_bool(1));
+ plist_dict_set_item(dict, "RestoreLocalPolicy", plist_new_bool(1));
plist_dict_set_item(dict, "RootData", plist_new_bool(0));
plist_dict_set_item(dict, "RootTicket", plist_new_bool(0));
plist_dict_set_item(dict, "S3EOverride", plist_new_bool(0));
@@ -4834,18 +5156,10 @@ plist_t restore_supported_data_types()
plist_dict_set_item(dict, "SystemImageCanonicalMetadata", plist_new_bool(0));
plist_dict_set_item(dict, "SystemImageData", plist_new_bool(0));
plist_dict_set_item(dict, "SystemImageRootHash", plist_new_bool(0));
+ plist_dict_set_item(dict, "URLAsset", plist_new_bool(1));
plist_dict_set_item(dict, "USBCFWData", plist_new_bool(0));
plist_dict_set_item(dict, "USBCOverride", plist_new_bool(0));
- plist_dict_set_item(dict, "FirmwareUpdaterPreflight", plist_new_bool(1));
- plist_dict_set_item(dict, "ReceiptManifest", plist_new_bool(1));
- plist_dict_set_item(dict, "FirmwareUpdaterDataV2", plist_new_bool(0));
- plist_dict_set_item(dict, "RestoreLocalPolicy", plist_new_bool(1));
- plist_dict_set_item(dict, "AuthInstallCACert", plist_new_bool(1));
- plist_dict_set_item(dict, "OverlayRootDataForKeyIndex", plist_new_bool(1));
- plist_dict_set_item(dict, "FirmwareUpdaterDataV3", plist_new_bool(1));
- plist_dict_set_item(dict, "MessageUseStreamedImageFile", plist_new_bool(1));
plist_dict_set_item(dict, "UpdateVolumeOverlayRootDataCount", plist_new_bool(1));
- plist_dict_set_item(dict, "URLAsset", plist_new_bool(1));
return dict;
}
@@ -4853,8 +5167,11 @@ plist_t restore_supported_data_types()
plist_t restore_supported_message_types()
{
plist_t dict = plist_new_dict();
+ plist_dict_set_item(dict, "AsyncDataRequestMsg", plist_new_bool(1));
+ plist_dict_set_item(dict, "AsyncWait", plist_new_bool(1));
plist_dict_set_item(dict, "BBUpdateStatusMsg", plist_new_bool(0));
plist_dict_set_item(dict, "CheckpointMsg", plist_new_bool(1));
+ plist_dict_set_item(dict, "CrashLog", plist_new_bool(1));
plist_dict_set_item(dict, "DataRequestMsg", plist_new_bool(0));
plist_dict_set_item(dict, "FDRSubmit", plist_new_bool(1));
plist_dict_set_item(dict, "MsgType", plist_new_bool(0));
@@ -4864,11 +5181,9 @@ plist_t restore_supported_message_types()
plist_dict_set_item(dict, "ProvisioningInfo", plist_new_bool(0));
plist_dict_set_item(dict, "ProvisioningStatusMsg", plist_new_bool(0));
plist_dict_set_item(dict, "ReceivedFinalStatusMsg", plist_new_bool(0));
+ plist_dict_set_item(dict, "RestoreAttestation", plist_new_bool(1));
plist_dict_set_item(dict, "RestoredCrash", plist_new_bool(1));
plist_dict_set_item(dict, "StatusMsg", plist_new_bool(0));
- plist_dict_set_item(dict, "AsyncDataRequestMsg", plist_new_bool(1));
- plist_dict_set_item(dict, "AsyncWait", plist_new_bool(1));
- plist_dict_set_item(dict, "RestoreAttestation", plist_new_bool(1));
return dict;
}
@@ -5024,15 +5339,15 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
//plist_dict_set_item(opts, "AuthInstallRestoreBehavior", plist_new_string("Erase"));
plist_dict_set_item(opts, "AutoBootDelay", plist_new_uint(0));
- if (client->preflight_info) {
- plist_t bbus = plist_copy(client->preflight_info);
+ if (client->firmware_preflight_info) {
+ plist_t bbus = plist_copy(client->firmware_preflight_info);
plist_dict_remove_item(bbus, "FusingStatus");
plist_dict_remove_item(bbus, "PkHash");
plist_dict_set_item(opts, "BBUpdaterState", bbus);
- plist_dict_copy_data(opts, client->preflight_info, "BasebandNonce", "Nonce");
+ plist_dict_copy_data(opts, client->firmware_preflight_info, "BasebandNonce", "Nonce");
}
plist_dict_set_item(opts, "SupportedDataTypes", restore_supported_data_types());
@@ -5078,7 +5393,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
}
} else {
// FIXME: new on iOS 5 ?
- plist_dict_set_item(opts, "BootImageType", plist_new_string("UserOrInternal"));
+ plist_dict_set_item(opts, "BootImageType", plist_new_string("User"));
// FIXME: required?
//plist_dict_set_item(opts, "BootImageFile", plist_new_string("018-7923-347.dmg"));
plist_dict_set_item(opts, "DFUFileType", plist_new_string("RELEASE"));
@@ -5104,7 +5419,27 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
// FIXME: new on iOS 5 ?
plist_dict_set_item(opts, "SystemImageType", plist_new_string("User"));
// FIXME: does this have any effect actually?
- plist_dict_set_item(opts, "UpdateBaseband", plist_new_bool(0));
+ plist_dict_set_item(opts, "UpdateBaseband", plist_new_bool(1));
+ plist_dict_set_item(opts, "InstallDiags", plist_new_bool(0));
+ if (client->recovery_variant) {
+ plist_dict_set_item(opts, "InstallRecoveryOS", plist_new_bool(1));
+ plist_dict_set_item(opts, "RecoveryOSBundlePath", plist_new_string("/tmp/Per2.tmp"));
+ plist_t recovery_variant = plist_access_path(client->recovery_variant, 2, "Info", "Variant");
+ plist_dict_set_item(opts, "AuthInstallRecoveryOSVariant", plist_copy(recovery_variant));
+ uint64_t max_size = 0;
+ uint64_t min_size = 0;
+ _restore_calculate_recovery_os_partition_size(client, &min_size, &max_size);
+ info("Calculated recoveryOSPartitionSize as %" PRIu64 " MB\n", min_size);
+ info("Calculated recoveryOSMaxPartitionSize as %" PRIu64 " MB\n", max_size);
+ plist_dict_set_item(opts, "recoveryOSMaxPartitionSize", plist_new_uint(max_size));
+ plist_dict_set_item(opts, "recoveryOSPartitionSize", plist_new_uint(min_size));
+ }
+
+ if (plist_dict_get_bool(client->parameters, "RequiresNonceSlot")) {
+ info("Device will use nonce slots.\n");
+ } else {
+ info("Device will not use nonce slots.\n");
+ }
// Added for iOS 18.0 beta 1
plist_dict_set_item(opts, "HostHasFixFor99053849", plist_new_bool(1));
@@ -5154,10 +5489,14 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit
spp = plist_copy(spp);
} else {
spp = plist_new_dict();
+ plist_dict_set_item(spp, "1024", plist_new_uint(1280));
plist_dict_set_item(spp, "128", plist_new_uint(1280));
plist_dict_set_item(spp, "16", plist_new_uint(160));
+ plist_dict_set_item(spp, "256", plist_new_uint(1280));
plist_dict_set_item(spp, "32", plist_new_uint(320));
+ plist_dict_set_item(spp, "512", plist_new_uint(1280));
plist_dict_set_item(spp, "64", plist_new_uint(640));
+ plist_dict_set_item(spp, "768", plist_new_uint(1280));
plist_dict_set_item(spp, "8", plist_new_uint(80));
}
plist_dict_set_item(opts, "SystemPartitionPadding", spp);