mirror of
https://github.com/tihmstar/futurerestore.git
synced 2024-12-22 17:35:29 +00:00
WIP updating idevicerestore
This commit is contained in:
parent
292fca0e02
commit
def6e7ba8f
2
external/idevicerestore
vendored
2
external/idevicerestore
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 5411b6bd9a2bbf85ec7ab4bef6bc7d168a5bf79b
|
Subproject commit 81867167df74c07d83b6784f48be6ca4d70ed4a4
|
|
@ -25,7 +25,7 @@
|
||||||
8799B0B71D89DAFF002F4D5F /* normal.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785876C1D89D1C1008689F0 /* normal.c */; };
|
8799B0B71D89DAFF002F4D5F /* normal.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785876C1D89D1C1008689F0 /* normal.c */; };
|
||||||
8799B0B81D89DAFF002F4D5F /* recovery.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785876E1D89D1C1008689F0 /* recovery.c */; };
|
8799B0B81D89DAFF002F4D5F /* recovery.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785876E1D89D1C1008689F0 /* recovery.c */; };
|
||||||
8799B0B91D89DB0D002F4D5F /* img3.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785875E1D89D1C1008689F0 /* img3.c */; };
|
8799B0B91D89DB0D002F4D5F /* img3.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785875E1D89D1C1008689F0 /* img3.c */; };
|
||||||
8799B0BB1D89DB12002F4D5F /* download.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587551D89D1C1008689F0 /* download.c */; };
|
8799B0BB1D89DB12002F4D5F /* download.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587551D89D1C1008689F0 /* download.c */; settings = {COMPILER_FLAGS = "-DPACKAGE_VERSION=\"\""; }; };
|
||||||
8799B0BC1D89DB27002F4D5F /* ipsw.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587621D89D1C1008689F0 /* ipsw.c */; };
|
8799B0BC1D89DB27002F4D5F /* ipsw.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587621D89D1C1008689F0 /* ipsw.c */; };
|
||||||
8799B0BD1D89DB27002F4D5F /* limera1n.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587641D89D1C1008689F0 /* limera1n.c */; };
|
8799B0BD1D89DB27002F4D5F /* limera1n.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587641D89D1C1008689F0 /* limera1n.c */; };
|
||||||
8799B0BE1D89DB27002F4D5F /* restore.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587701D89D1C1008689F0 /* restore.c */; };
|
8799B0BE1D89DB27002F4D5F /* restore.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587701D89D1C1008689F0 /* restore.c */; };
|
||||||
|
@ -39,6 +39,9 @@
|
||||||
8799B0CA1D89E371002F4D5F /* img4.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587601D89D1C1008689F0 /* img4.c */; };
|
8799B0CA1D89E371002F4D5F /* img4.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587601D89D1C1008689F0 /* img4.c */; };
|
||||||
8799B0CB1D89F796002F4D5F /* tsschecker.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785879F1D89D2BA008689F0 /* tsschecker.c */; };
|
8799B0CB1D89F796002F4D5F /* tsschecker.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785879F1D89D2BA008689F0 /* tsschecker.c */; };
|
||||||
8799B0CC1D89F7B9002F4D5F /* download.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587981D89D2BA008689F0 /* download.c */; };
|
8799B0CC1D89F7B9002F4D5F /* download.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587981D89D2BA008689F0 /* download.c */; };
|
||||||
|
87B517C3236EF36B009EAB8F /* ftab.c in Sources */ = {isa = PBXBuildFile; fileRef = 87B517C1236EF36B009EAB8F /* ftab.c */; };
|
||||||
|
87B517C6236EF3B0009EAB8F /* json_plist.c in Sources */ = {isa = PBXBuildFile; fileRef = 87B517C5236EF3B0009EAB8F /* json_plist.c */; };
|
||||||
|
87B517C9236EF3CD009EAB8F /* jsmn.c in Sources */ = {isa = PBXBuildFile; fileRef = 87B517C7236EF3CD009EAB8F /* jsmn.c */; };
|
||||||
87F574CB1E151E97008D5C4D /* libfragmentzip.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87F574CA1E151E97008D5C4D /* libfragmentzip.0.dylib */; };
|
87F574CB1E151E97008D5C4D /* libfragmentzip.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87F574CA1E151E97008D5C4D /* libfragmentzip.0.dylib */; };
|
||||||
87F574D01E151F44008D5C4D /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87F574C51E151D42008D5C4D /* libcrypto.dylib */; };
|
87F574D01E151F44008D5C4D /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87F574C51E151D42008D5C4D /* libcrypto.dylib */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
@ -129,6 +132,12 @@
|
||||||
878E1AC41F73EB3F00B1565B /* libzip.5.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libzip.5.dylib; path = ../../../../usr/local/Cellar/libzip/1.3.0/lib/libzip.5.dylib; sourceTree = "<group>"; };
|
878E1AC41F73EB3F00B1565B /* libzip.5.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libzip.5.dylib; path = ../../../../usr/local/Cellar/libzip/1.3.0/lib/libzip.5.dylib; sourceTree = "<group>"; };
|
||||||
8799B0B01D89D99D002F4D5F /* futurerestore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = futurerestore.cpp; sourceTree = "<group>"; };
|
8799B0B01D89D99D002F4D5F /* futurerestore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = futurerestore.cpp; sourceTree = "<group>"; };
|
||||||
8799B0B11D89D99D002F4D5F /* futurerestore.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = futurerestore.hpp; sourceTree = "<group>"; };
|
8799B0B11D89D99D002F4D5F /* futurerestore.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = futurerestore.hpp; sourceTree = "<group>"; };
|
||||||
|
87B517C1236EF36B009EAB8F /* ftab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ftab.c; sourceTree = "<group>"; };
|
||||||
|
87B517C2236EF36B009EAB8F /* ftab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ftab.h; sourceTree = "<group>"; };
|
||||||
|
87B517C4236EF3B0009EAB8F /* json_plist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = json_plist.h; sourceTree = "<group>"; };
|
||||||
|
87B517C5236EF3B0009EAB8F /* json_plist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = json_plist.c; sourceTree = "<group>"; };
|
||||||
|
87B517C7236EF3CD009EAB8F /* jsmn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jsmn.c; sourceTree = "<group>"; };
|
||||||
|
87B517C8236EF3CD009EAB8F /* jsmn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jsmn.h; sourceTree = "<group>"; };
|
||||||
87F574C51E151D42008D5C4D /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = ../../../../usr/lib/libcrypto.dylib; sourceTree = "<group>"; };
|
87F574C51E151D42008D5C4D /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = ../../../../usr/lib/libcrypto.dylib; sourceTree = "<group>"; };
|
||||||
87F574C71E151DA6008D5C4D /* libcommonCrypto.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcommonCrypto.tbd; path = usr/lib/system/libcommonCrypto.tbd; sourceTree = SDKROOT; };
|
87F574C71E151DA6008D5C4D /* libcommonCrypto.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcommonCrypto.tbd; path = usr/lib/system/libcommonCrypto.tbd; sourceTree = SDKROOT; };
|
||||||
87F574CA1E151E97008D5C4D /* libfragmentzip.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfragmentzip.0.dylib; path = ../../../../usr/local/lib/libfragmentzip.0.dylib; sourceTree = "<group>"; };
|
87F574CA1E151E97008D5C4D /* libfragmentzip.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfragmentzip.0.dylib; path = ../../../../usr/local/lib/libfragmentzip.0.dylib; sourceTree = "<group>"; };
|
||||||
|
@ -224,6 +233,12 @@
|
||||||
8785875F1D89D1C1008689F0 /* img3.h */,
|
8785875F1D89D1C1008689F0 /* img3.h */,
|
||||||
878587601D89D1C1008689F0 /* img4.c */,
|
878587601D89D1C1008689F0 /* img4.c */,
|
||||||
878587611D89D1C1008689F0 /* img4.h */,
|
878587611D89D1C1008689F0 /* img4.h */,
|
||||||
|
87B517C5236EF3B0009EAB8F /* json_plist.c */,
|
||||||
|
87B517C4236EF3B0009EAB8F /* json_plist.h */,
|
||||||
|
87B517C1236EF36B009EAB8F /* ftab.c */,
|
||||||
|
87B517C2236EF36B009EAB8F /* ftab.h */,
|
||||||
|
87B517C7236EF3CD009EAB8F /* jsmn.c */,
|
||||||
|
87B517C8236EF3CD009EAB8F /* jsmn.h */,
|
||||||
878587621D89D1C1008689F0 /* ipsw.c */,
|
878587621D89D1C1008689F0 /* ipsw.c */,
|
||||||
878587631D89D1C1008689F0 /* ipsw.h */,
|
878587631D89D1C1008689F0 /* ipsw.h */,
|
||||||
878587641D89D1C1008689F0 /* limera1n.c */,
|
878587641D89D1C1008689F0 /* limera1n.c */,
|
||||||
|
@ -342,6 +357,7 @@
|
||||||
8799B0B41D89DAF6002F4D5F /* tss.c in Sources */,
|
8799B0B41D89DAF6002F4D5F /* tss.c in Sources */,
|
||||||
8799B0C01D89DB38002F4D5F /* fdr.c in Sources */,
|
8799B0C01D89DB38002F4D5F /* fdr.c in Sources */,
|
||||||
8799B0BC1D89DB27002F4D5F /* ipsw.c in Sources */,
|
8799B0BC1D89DB27002F4D5F /* ipsw.c in Sources */,
|
||||||
|
87B517C3236EF36B009EAB8F /* ftab.c in Sources */,
|
||||||
8799B0CC1D89F7B9002F4D5F /* download.c in Sources */,
|
8799B0CC1D89F7B9002F4D5F /* download.c in Sources */,
|
||||||
8799B0B91D89DB0D002F4D5F /* img3.c in Sources */,
|
8799B0B91D89DB0D002F4D5F /* img3.c in Sources */,
|
||||||
8799B0B51D89DAFF002F4D5F /* common.c in Sources */,
|
8799B0B51D89DAFF002F4D5F /* common.c in Sources */,
|
||||||
|
@ -350,12 +366,14 @@
|
||||||
8799B0B31D89DAE7002F4D5F /* idevicerestore.c in Sources */,
|
8799B0B31D89DAE7002F4D5F /* idevicerestore.c in Sources */,
|
||||||
8799B0BB1D89DB12002F4D5F /* download.c in Sources */,
|
8799B0BB1D89DB12002F4D5F /* download.c in Sources */,
|
||||||
8799B0B71D89DAFF002F4D5F /* normal.c in Sources */,
|
8799B0B71D89DAFF002F4D5F /* normal.c in Sources */,
|
||||||
|
87B517C9236EF3CD009EAB8F /* jsmn.c in Sources */,
|
||||||
8799B0C31D89DB4B002F4D5F /* socket.c in Sources */,
|
8799B0C31D89DB4B002F4D5F /* socket.c in Sources */,
|
||||||
8799B0C21D89DB46002F4D5F /* thread.c in Sources */,
|
8799B0C21D89DB46002F4D5F /* thread.c in Sources */,
|
||||||
8799B0B61D89DAFF002F4D5F /* dfu.c in Sources */,
|
8799B0B61D89DAFF002F4D5F /* dfu.c in Sources */,
|
||||||
8799B0BD1D89DB27002F4D5F /* limera1n.c in Sources */,
|
8799B0BD1D89DB27002F4D5F /* limera1n.c in Sources */,
|
||||||
8799B0C51D89DB67002F4D5F /* locking.c in Sources */,
|
8799B0C51D89DB67002F4D5F /* locking.c in Sources */,
|
||||||
878587471D89CFDC008689F0 /* main.cpp in Sources */,
|
878587471D89CFDC008689F0 /* main.cpp in Sources */,
|
||||||
|
87B517C6236EF3B0009EAB8F /* json_plist.c in Sources */,
|
||||||
8799B0BF1D89DB38002F4D5F /* asr.c in Sources */,
|
8799B0BF1D89DB38002F4D5F /* asr.c in Sources */,
|
||||||
8799B0BE1D89DB27002F4D5F /* restore.c in Sources */,
|
8799B0BE1D89DB27002F4D5F /* restore.c in Sources */,
|
||||||
8799B0CB1D89F796002F4D5F /* tsschecker.c in Sources */,
|
8799B0CB1D89F796002F4D5F /* tsschecker.c in Sources */,
|
||||||
|
@ -457,6 +475,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"IDEVICERESTORE_NOMAIN=1",
|
"IDEVICERESTORE_NOMAIN=1",
|
||||||
"CUSTOM_LOGGING=1",
|
"CUSTOM_LOGGING=1",
|
||||||
|
"HAVE_REALPATH=1",
|
||||||
);
|
);
|
||||||
HEADER_SEARCH_PATHS = "";
|
HEADER_SEARCH_PATHS = "";
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
|
|
@ -79,6 +79,14 @@ extern "C"{
|
||||||
|
|
||||||
using namespace tihmstar;
|
using namespace tihmstar;
|
||||||
|
|
||||||
|
#pragma mark helpers
|
||||||
|
|
||||||
|
extern "C"{
|
||||||
|
void irecv_event_cb(const irecv_device_event_t* event, void *userdata);
|
||||||
|
void idevice_event_cb(const idevice_event_t *event, void *userdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma mark futurerestore
|
||||||
|
|
||||||
futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu){
|
futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu){
|
||||||
_client = idevicerestore_client_new();
|
_client = idevicerestore_client_new();
|
||||||
|
@ -117,7 +125,6 @@ int futurerestore::getDeviceMode(bool reRequest){
|
||||||
if (!reRequest && _client->mode && _client->mode->index != MODE_UNKNOWN) {
|
if (!reRequest && _client->mode && _client->mode->index != MODE_UNKNOWN) {
|
||||||
return _client->mode->index;
|
return _client->mode->index;
|
||||||
}else{
|
}else{
|
||||||
normal_client_free(_client);
|
|
||||||
dfu_client_free(_client);
|
dfu_client_free(_client);
|
||||||
recovery_client_free(_client);
|
recovery_client_free(_client);
|
||||||
return check_mode(_client);
|
return check_mode(_client);
|
||||||
|
@ -159,7 +166,6 @@ void futurerestore::putDeviceIntoRecovery(){
|
||||||
safeFree(_client->udid);
|
safeFree(_client->udid);
|
||||||
|
|
||||||
//these get also freed by destructor
|
//these get also freed by destructor
|
||||||
normal_client_free(_client);
|
|
||||||
dfu_client_free(_client);
|
dfu_client_free(_client);
|
||||||
recovery_client_free(_client);
|
recovery_client_free(_client);
|
||||||
}
|
}
|
||||||
|
@ -551,37 +557,51 @@ void get_custom_component(struct idevicerestore_client_t* client, plist_t build_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int futurerestore::doRestore(const char *ipsw){
|
void futurerestore::doRestore(const char *ipsw){
|
||||||
int err = 0;
|
plist_t buildmanifest = NULL;
|
||||||
//some memory might not get freed if this function throws an exception, but you probably don't want to catch that anyway.
|
|
||||||
|
|
||||||
struct idevicerestore_client_t* client = _client;
|
|
||||||
int unused;
|
|
||||||
int result = 0;
|
|
||||||
int delete_fs = 0;
|
int delete_fs = 0;
|
||||||
char* filesystem = NULL;
|
char* filesystem = NULL;
|
||||||
plist_t buildmanifest = NULL;
|
cleanup([&]{
|
||||||
|
info("Cleaning up...\n");
|
||||||
|
safeFreeCustom(buildmanifest, plist_free);
|
||||||
|
if (delete_fs && filesystem) unlink(filesystem);
|
||||||
|
});
|
||||||
|
struct idevicerestore_client_t* client = _client;
|
||||||
plist_t build_identity = NULL;
|
plist_t build_identity = NULL;
|
||||||
plist_t sep_build_identity = NULL;
|
plist_t sep_build_identity = NULL;
|
||||||
|
|
||||||
client->ipsw = strdup(ipsw);
|
client->ipsw = strdup(ipsw);
|
||||||
if (!_isUpdateInstall) client->flags |= FLAG_ERASE;
|
if (!_isUpdateInstall) client->flags |= FLAG_ERASE;
|
||||||
|
|
||||||
getDeviceMode(true);
|
irecv_device_event_subscribe(&client->irecv_e_ctx, irecv_event_cb, client);
|
||||||
|
idevice_event_subscribe(idevice_event_cb, client);
|
||||||
|
client->idevice_e_ctx = (void*)idevice_event_cb;
|
||||||
|
|
||||||
|
mutex_lock(&client->device_event_mutex);
|
||||||
|
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);
|
||||||
|
|
||||||
|
retassure(client->mode != &idevicerestore_modes[MODE_UNKNOWN], "Unable to discover device mode. Please make sure a device is attached.\n");
|
||||||
|
if (client->mode != &idevicerestore_modes[MODE_RECOVERY]) {
|
||||||
|
retassure(client->mode == &idevicerestore_modes[MODE_DFU], "Device in unexpected mode detected!");
|
||||||
|
retassure(_enterPwnRecoveryRequested, "Device in DFU mode detected, but we were expecting recovery mode!");
|
||||||
|
}else{
|
||||||
|
retassure(!_enterPwnRecoveryRequested, "--pwn-dfu was specified, but device found in recovery mode!");
|
||||||
|
}
|
||||||
|
|
||||||
info("Found device in %s mode\n", client->mode->string);
|
info("Found device in %s mode\n", client->mode->string);
|
||||||
|
mutex_unlock(&client->device_event_mutex);
|
||||||
|
|
||||||
retassure(client->mode->index == MODE_RECOVERY || (client->mode->index == MODE_DFU && _enterPwnRecoveryRequested), "device not in recovery mode\n");
|
info("Identified device as %s, %s\n", getDeviceBoardNoCopy(), getDeviceModelNoCopy());
|
||||||
|
|
||||||
// discover the device type
|
|
||||||
retassure(check_hardware_model(client) && client->device, "ERROR: Unable to discover device model\n");
|
|
||||||
|
|
||||||
info("Identified device as %s, %s\n", client->device->hardware_model, client->device->product_type);
|
|
||||||
|
|
||||||
// verify if ipsw file exists
|
// verify if ipsw file exists
|
||||||
retassure(!access(client->ipsw, F_OK),"ERROR: Firmware file %s does not exist.\n", client->ipsw);
|
retassure(!access(client->ipsw, F_OK),"ERROR: Firmware file %s does not exist.\n", client->ipsw);
|
||||||
|
|
||||||
|
|
||||||
info("Extracting BuildManifest from IPSW\n");
|
info("Extracting BuildManifest from IPSW\n");
|
||||||
|
{
|
||||||
|
int unused;
|
||||||
retassure(!ipsw_extract_build_manifest(client->ipsw, &buildmanifest, &unused),"ERROR: Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", client->ipsw);
|
retassure(!ipsw_extract_build_manifest(client->ipsw, &buildmanifest, &unused),"ERROR: Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", client->ipsw);
|
||||||
|
}
|
||||||
|
|
||||||
/* check if device type is supported by the given build manifest */
|
/* check if device type is supported by the given build manifest */
|
||||||
retassure(!build_manifest_check_compatibility(buildmanifest, client->device->product_type),"ERROR: Could not make sure this firmware is suitable for the current device. Refusing to continue.\n");
|
retassure(!build_manifest_check_compatibility(buildmanifest, client->device->product_type),"ERROR: Could not make sure this firmware is suitable for the current device. Refusing to continue.\n");
|
||||||
|
@ -750,7 +770,6 @@ int futurerestore::doRestore(const char *ipsw){
|
||||||
enterPwnRecovery(build_identity);
|
enterPwnRecovery(build_identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get filesystem name from build identity
|
// Get filesystem name from build identity
|
||||||
char* fsname = NULL;
|
char* fsname = NULL;
|
||||||
retassure(!build_identity_get_component_path(build_identity, "OS", &fsname), "ERROR: Unable get path for filesystem component\n");
|
retassure(!build_identity_get_component_path(build_identity, "OS", &fsname), "ERROR: Unable get path for filesystem component\n");
|
||||||
|
@ -785,7 +804,7 @@ int futurerestore::doRestore(const char *ipsw){
|
||||||
memset(&st, '\0', sizeof(struct stat));
|
memset(&st, '\0', sizeof(struct stat));
|
||||||
if (stat(tmpf, &st) == 0) {
|
if (stat(tmpf, &st) == 0) {
|
||||||
off_t fssize = 0;
|
off_t fssize = 0;
|
||||||
ipsw_get_file_size(client->ipsw, fsname, &fssize);
|
ipsw_get_file_size(client->ipsw, fsname, (uint64_t*)&fssize);
|
||||||
if ((fssize > 0) && (st.st_size == fssize)) {
|
if ((fssize > 0) && (st.st_size == fssize)) {
|
||||||
info("Using cached filesystem from '%s'\n", tmpf);
|
info("Using cached filesystem from '%s'\n", tmpf);
|
||||||
filesystem = strdup(tmpf);
|
filesystem = strdup(tmpf);
|
||||||
|
@ -836,25 +855,46 @@ int futurerestore::doRestore(const char *ipsw){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_rerestoreiOS9) {
|
if (_rerestoreiOS9) {
|
||||||
|
|
||||||
if (dfu_send_component(client, build_identity, "iBSS") < 0) {
|
if (dfu_send_component(client, build_identity, "iBSS") < 0) {
|
||||||
error("ERROR: Unable to send iBSS to device\n");
|
|
||||||
irecv_close(client->dfu->client);
|
irecv_close(client->dfu->client);
|
||||||
client->dfu->client = NULL;
|
client->dfu->client = NULL;
|
||||||
return -1;
|
reterror("ERROR: Unable to send iBSS to device\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reconnect */
|
/* reconnect */
|
||||||
dfu_client_free(client);
|
dfu_client_free(client);
|
||||||
sleep(2);
|
|
||||||
|
debug("Waiting for device to disconnect...\n");
|
||||||
|
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);
|
||||||
|
retassure((client->mode == &idevicerestore_modes[MODE_UNKNOWN] || (mutex_unlock(&client->device_event_mutex),0)), "Device did not disconnect. Possibly invalid iBSS. Reset device and try again");
|
||||||
|
|
||||||
|
debug("Waiting for device to reconnect...\n");
|
||||||
|
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);
|
||||||
|
retassure((client->mode == &idevicerestore_modes[MODE_DFU] || (mutex_unlock(&client->device_event_mutex),0)), "Device did not disconnect. Possibly invalid iBSS. Reset device and try again");
|
||||||
|
mutex_unlock(&client->device_event_mutex);
|
||||||
|
|
||||||
dfu_client_new(client);
|
dfu_client_new(client);
|
||||||
|
|
||||||
/* send iBEC */
|
/* send iBEC */
|
||||||
if (dfu_send_component(client, build_identity, "iBEC") < 0) {
|
if (dfu_send_component(client, build_identity, "iBEC") < 0) {
|
||||||
error("ERROR: Unable to send iBEC to device\n");
|
|
||||||
irecv_close(client->dfu->client);
|
irecv_close(client->dfu->client);
|
||||||
client->dfu->client = NULL;
|
client->dfu->client = NULL;
|
||||||
return -1;
|
reterror("ERROR: Unable to send iBEC to device\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dfu_client_free(client);
|
||||||
|
|
||||||
|
debug("Waiting for device to disconnect...\n");
|
||||||
|
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);
|
||||||
|
retassure((client->mode == &idevicerestore_modes[MODE_UNKNOWN] || (mutex_unlock(&client->device_event_mutex),0)), "Device did not disconnect. Possibly invalid iBEC. Reset device and try again");
|
||||||
|
|
||||||
|
debug("Waiting for device to reconnect...\n");
|
||||||
|
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);
|
||||||
|
retassure((client->mode == &idevicerestore_modes[MODE_RECOVERY] || (mutex_unlock(&client->device_event_mutex),0)), "Device did not disconnect. Possibly invalid iBEC. Reset device and try again");
|
||||||
|
mutex_unlock(&client->device_event_mutex);
|
||||||
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
if ((client->build_major > 8)) {
|
if ((client->build_major > 8)) {
|
||||||
if (!client->image4supported) {
|
if (!client->image4supported) {
|
||||||
|
@ -879,16 +919,18 @@ int futurerestore::doRestore(const char *ipsw){
|
||||||
|
|
||||||
printf("waiting for device to reconnect... ");
|
printf("waiting for device to reconnect... ");
|
||||||
recovery_client_free(client);
|
recovery_client_free(client);
|
||||||
/* this must be long enough to allow the device to run the iBEC */
|
|
||||||
/* FIXME: Probably better to detect if the device is back then */
|
debug("Waiting for device to disconnect...\n");
|
||||||
sleep(7);
|
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);
|
||||||
|
retassure((client->mode == &idevicerestore_modes[MODE_UNKNOWN] || (mutex_unlock(&client->device_event_mutex),0)), "Device did not disconnect. Possibly invalid iBEC. Reset device and try again");
|
||||||
|
|
||||||
|
debug("Waiting for device to reconnect...\n");
|
||||||
|
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);
|
||||||
|
retassure((client->mode == &idevicerestore_modes[MODE_RECOVERY] || (mutex_unlock(&client->device_event_mutex),0)), "Device did not disconnect. Possibly invalid iBEC. Reset device and try again");
|
||||||
|
mutex_unlock(&client->device_event_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retassure(client->mode == &idevicerestore_modes[MODE_RECOVERY], "failed to reconnect to device in recovery (iBEC) mode\n");
|
||||||
for (int i=0;getDeviceMode(true) != MODE_RECOVERY && i<40; i++) putchar('.'),usleep(USEC_PER_SEC*0.5);
|
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
retassure(check_mode(client), "failed to reconnect to device in recovery (iBEC) mode\n");
|
|
||||||
|
|
||||||
//do magic
|
//do magic
|
||||||
if (_client->image4supported) get_sep_nonce(client, &client->sepnonce, &client->sepnonce_size);
|
if (_client->image4supported) get_sep_nonce(client, &client->sepnonce, &client->sepnonce_size);
|
||||||
|
@ -899,10 +941,8 @@ int futurerestore::doRestore(const char *ipsw){
|
||||||
if (client->mode->index == MODE_RECOVERY) {
|
if (client->mode->index == MODE_RECOVERY) {
|
||||||
retassure(client->srnm,"ERROR: could not retrieve device serial number. Can't continue.\n");
|
retassure(client->srnm,"ERROR: could not retrieve device serial number. Can't continue.\n");
|
||||||
|
|
||||||
if (irecv_send_command(client->recovery->client, "bgcolor 0 255 0") != IRECV_E_SUCCESS) {
|
retassure(!irecv_send_command(client->recovery->client, "bgcolor 0 255 0"), "ERROR: Unable to set bgcolor\n");
|
||||||
error("ERROR: Unable to set bgcolor\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
info("[WARNING] Setting bgcolor to green! If you don't see a green screen, then your device didn't boot iBEC correctly\n");
|
info("[WARNING] Setting bgcolor to green! If you don't see a green screen, then your device didn't boot iBEC correctly\n");
|
||||||
sleep(2); //show the user a green screen!
|
sleep(2); //show the user a green screen!
|
||||||
|
|
||||||
|
@ -911,119 +951,114 @@ int futurerestore::doRestore(const char *ipsw){
|
||||||
recovery_client_free(client);
|
recovery_client_free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_client->image4supported) {
|
if (_client->image4supported) {
|
||||||
retassure(!get_tss_response(client, sep_build_identity, &client->septss), "ERROR: Unable to get SHSH blobs for SEP\n");
|
retassure(!get_tss_response(client, sep_build_identity, &client->septss), "ERROR: Unable to get SHSH blobs for SEP\n");
|
||||||
retassure(_client->sepfwdatasize && _client->sepfwdata, "SEP not loaded, refusing to continue");
|
retassure(_client->sepfwdatasize && _client->sepfwdata, "SEP not loaded, refusing to continue");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (client->mode->index == MODE_RESTORE) {
|
|
||||||
|
mutex_lock(&client->device_event_mutex);
|
||||||
|
debug("Waiting for device to disconnect...\n");
|
||||||
|
cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 180000);
|
||||||
|
retassure((client->mode == &idevicerestore_modes[MODE_RESTORE] || (mutex_unlock(&client->device_event_mutex),0)), "Device failed to enter restore mode");
|
||||||
|
mutex_unlock(&client->device_event_mutex);
|
||||||
|
|
||||||
info("About to restore device... \n");
|
info("About to restore device... \n");
|
||||||
|
int result = 0;
|
||||||
retassure(!(result = restore_device(client, build_identity, filesystem)), "ERROR: Unable to restore device\n");
|
retassure(!(result = restore_device(client, build_identity, filesystem)), "ERROR: Unable to restore device\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
info("Cleaning up...\n");
|
|
||||||
|
|
||||||
|
|
||||||
error:
|
|
||||||
safeFree(client->sepfwdata);
|
|
||||||
safeFreeCustom(buildmanifest,plist_free);
|
|
||||||
if (delete_fs && filesystem) unlink(filesystem);
|
|
||||||
if (!result && !err) info("DONE\n");
|
|
||||||
return result ? abs(result) : err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int futurerestore::doJustBoot(const char *ipsw, string bootargs){
|
int futurerestore::doJustBoot(const char *ipsw, string bootargs){
|
||||||
int err = 0;
|
reterror("not implemented");
|
||||||
//some memory might not get freed if this function throws an exception, but you probably don't want to catch that anyway.
|
// int err = 0;
|
||||||
|
// //some memory might not get freed if this function throws an exception, but you probably don't want to catch that anyway.
|
||||||
struct idevicerestore_client_t* client = _client;
|
//
|
||||||
int unused;
|
// struct idevicerestore_client_t* client = _client;
|
||||||
int result = 0;
|
// int unused;
|
||||||
plist_t buildmanifest = NULL;
|
// int result = 0;
|
||||||
plist_t build_identity = NULL;
|
// plist_t buildmanifest = NULL;
|
||||||
|
// plist_t build_identity = NULL;
|
||||||
client->ipsw = strdup(ipsw);
|
//
|
||||||
|
// client->ipsw = strdup(ipsw);
|
||||||
getDeviceMode(true);
|
//
|
||||||
info("Found device in %s mode\n", client->mode->string);
|
// getDeviceMode(true);
|
||||||
|
// info("Found device in %s mode\n", client->mode->string);
|
||||||
retassure((client->mode->index == MODE_DFU || client->mode->index == MODE_RECOVERY) && _enterPwnRecoveryRequested, "device not in DFU/Recovery mode\n");
|
//
|
||||||
|
// retassure((client->mode->index == MODE_DFU || client->mode->index == MODE_RECOVERY) && _enterPwnRecoveryRequested, "device not in DFU/Recovery mode\n");
|
||||||
// discover the device type
|
//
|
||||||
retassure(check_hardware_model(client) && client->device,"ERROR: Unable to discover device model\n");
|
// // discover the device type
|
||||||
info("Identified device as %s, %s\n", client->device->hardware_model, client->device->product_type);
|
// retassure(check_hardware_model(client) && client->device,"ERROR: Unable to discover device model\n");
|
||||||
|
// info("Identified device as %s, %s\n", client->device->hardware_model, client->device->product_type);
|
||||||
// verify if ipsw file exists
|
//
|
||||||
retassure(!access(client->ipsw, F_OK), "ERROR: Firmware file %s does not exist.\n", client->ipsw);
|
// // verify if ipsw file exists
|
||||||
info("Extracting BuildManifest from IPSW\n");
|
// retassure(!access(client->ipsw, F_OK), "ERROR: Firmware file %s does not exist.\n", client->ipsw);
|
||||||
|
// info("Extracting BuildManifest from IPSW\n");
|
||||||
retassure(!ipsw_extract_build_manifest(client->ipsw, &buildmanifest, &unused),"ERROR: Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", client->ipsw);
|
//
|
||||||
|
// retassure(!ipsw_extract_build_manifest(client->ipsw, &buildmanifest, &unused),"ERROR: Unable to extract BuildManifest from %s. Firmware file might be corrupt.\n", client->ipsw);
|
||||||
/* check if device type is supported by the given build manifest */
|
//
|
||||||
retassure(!build_manifest_check_compatibility(buildmanifest, client->device->product_type),"ERROR: Could not make sure this firmware is suitable for the current device. Refusing to continue.\n");
|
// /* check if device type is supported by the given build manifest */
|
||||||
|
// retassure(!build_manifest_check_compatibility(buildmanifest, client->device->product_type),"ERROR: Could not make sure this firmware is suitable for the current device. Refusing to continue.\n");
|
||||||
/* print iOS information from the manifest */
|
//
|
||||||
build_manifest_get_version_information(buildmanifest, client);
|
// /* print iOS information from the manifest */
|
||||||
|
// build_manifest_get_version_information(buildmanifest, client);
|
||||||
info("Product Version: %s\n", client->version);
|
//
|
||||||
info("Product Build: %s Major: %d\n", client->build, client->build_major);
|
// info("Product Version: %s\n", client->version);
|
||||||
|
// info("Product Build: %s Major: %d\n", client->build, client->build_major);
|
||||||
client->image4supported = is_image4_supported(client);
|
//
|
||||||
info("Device supports Image4: %s\n", (client->image4supported) ? "true" : "false");
|
// client->image4supported = is_image4_supported(client);
|
||||||
|
// info("Device supports Image4: %s\n", (client->image4supported) ? "true" : "false");
|
||||||
retassure(build_identity = getBuildidentityWithBoardconfig(buildmanifest, client->device->hardware_model, 0),"ERROR: Unable to find any build identities for IPSW\n");
|
//
|
||||||
|
// retassure(build_identity = getBuildidentityWithBoardconfig(buildmanifest, client->device->hardware_model, 0),"ERROR: Unable to find any build identities for IPSW\n");
|
||||||
|
//
|
||||||
/* print information about current build identity */
|
//
|
||||||
build_identity_print_information(build_identity);
|
// /* print information about current build identity */
|
||||||
|
// build_identity_print_information(build_identity);
|
||||||
|
//
|
||||||
//check for enterpwnrecovery, because we could be in DFU mode
|
//
|
||||||
retassure(_enterPwnRecoveryRequested, "enterPwnRecoveryRequested is not set, but required");
|
// //check for enterpwnrecovery, because we could be in DFU mode
|
||||||
|
// retassure(_enterPwnRecoveryRequested, "enterPwnRecoveryRequested is not set, but required");
|
||||||
retassure(getDeviceMode(true) == MODE_DFU || getDeviceMode(false) == MODE_RECOVERY, "unexpected device mode\n");
|
//
|
||||||
|
// retassure(getDeviceMode(true) == MODE_DFU || getDeviceMode(false) == MODE_RECOVERY, "unexpected device mode\n");
|
||||||
enterPwnRecovery(build_identity, bootargs);
|
//
|
||||||
|
// enterPwnRecovery(build_identity, bootargs);
|
||||||
client->recovery_custom_component_function = get_custom_component;
|
//
|
||||||
|
// client->recovery_custom_component_function = get_custom_component;
|
||||||
for (int i=0;getDeviceMode(true) != MODE_RECOVERY && i<40; i++) putchar('.'),usleep(USEC_PER_SEC*0.5);
|
//
|
||||||
putchar('\n');
|
// for (int i=0;getDeviceMode(true) != MODE_RECOVERY && i<40; i++) putchar('.'),usleep(USEC_PER_SEC*0.5);
|
||||||
|
// putchar('\n');
|
||||||
retassure(check_mode(client), "failed to reconnect to device in recovery (iBEC) mode\n");
|
//
|
||||||
|
// retassure(check_mode(client), "failed to reconnect to device in recovery (iBEC) mode\n");
|
||||||
get_ecid(client, &client->ecid);
|
//
|
||||||
|
// get_ecid(client, &client->ecid);
|
||||||
client->flags |= FLAG_BOOT;
|
//
|
||||||
|
// client->flags |= FLAG_BOOT;
|
||||||
if (client->mode->index == MODE_RECOVERY) {
|
//
|
||||||
retassure(client->srnm,"ERROR: could not retrieve device serial number. Can't continue.\n");
|
// if (client->mode->index == MODE_RECOVERY) {
|
||||||
|
// retassure(client->srnm,"ERROR: could not retrieve device serial number. Can't continue.\n");
|
||||||
retassure(!irecv_send_command(client->recovery->client, "bgcolor 0 255 0"), "ERROR: Unable to set bgcolor\n");
|
//
|
||||||
|
// retassure(!irecv_send_command(client->recovery->client, "bgcolor 0 255 0"), "ERROR: Unable to set bgcolor\n");
|
||||||
info("[WARNING] Setting bgcolor to green! If you don't see a green screen, then your device didn't boot iBEC correctly\n");
|
//
|
||||||
sleep(2); //show the user a green screen!
|
// info("[WARNING] Setting bgcolor to green! If you don't see a green screen, then your device didn't boot iBEC correctly\n");
|
||||||
client->image4supported = true; //dirty hack to not require apticket
|
// sleep(2); //show the user a green screen!
|
||||||
|
// client->image4supported = true; //dirty hack to not require apticket
|
||||||
retassure(!recovery_enter_restore(client, build_identity),"ERROR: Unable to place device into restore mode\n");
|
//
|
||||||
|
// retassure(!recovery_enter_restore(client, build_identity),"ERROR: Unable to place device into restore mode\n");
|
||||||
client->image4supported = false;
|
//
|
||||||
recovery_client_free(client);
|
// client->image4supported = false;
|
||||||
}
|
// recovery_client_free(client);
|
||||||
|
// }
|
||||||
info("Cleaning up...\n");
|
//
|
||||||
|
// info("Cleaning up...\n");
|
||||||
error:
|
//
|
||||||
safeFree(client->sepfwdata);
|
//error:
|
||||||
safeFreeCustom(buildmanifest, plist_free);
|
// safeFree(client->sepfwdata);
|
||||||
if (!result && !err) info("DONE\n");
|
// safeFreeCustom(buildmanifest, plist_free);
|
||||||
return result ? abs(result) : err;
|
// if (!result && !err) info("DONE\n");
|
||||||
|
// return result ? abs(result) : err;
|
||||||
}
|
}
|
||||||
|
|
||||||
futurerestore::~futurerestore(){
|
futurerestore::~futurerestore(){
|
||||||
normal_client_free(_client);
|
|
||||||
recovery_client_free(_client);
|
recovery_client_free(_client);
|
||||||
idevicerestore_client_free(_client);
|
idevicerestore_client_free(_client);
|
||||||
for (auto im4m : _im4ms){
|
for (auto im4m : _im4ms){
|
||||||
|
@ -1056,22 +1091,46 @@ const char *futurerestore::getDeviceModelNoCopy(){
|
||||||
int mode = getDeviceMode(true);
|
int mode = getDeviceMode(true);
|
||||||
retassure(mode == MODE_NORMAL || mode == MODE_RECOVERY || mode == MODE_DFU, "unexpected device mode=%d\n",mode);
|
retassure(mode == MODE_NORMAL || mode == MODE_RECOVERY || mode == MODE_DFU, "unexpected device mode=%d\n",mode);
|
||||||
|
|
||||||
retassure(check_hardware_model(_client) && _client->device, "ERROR: Unable to discover device model\n");
|
switch (mode) {
|
||||||
|
case MODE_RESTORE:
|
||||||
|
_client->device = restore_get_irecv_device(_client);
|
||||||
|
break;
|
||||||
|
case MODE_NORMAL:
|
||||||
|
_client->device = normal_get_irecv_device(_client);
|
||||||
|
break;
|
||||||
|
case MODE_DFU:
|
||||||
|
case MODE_RECOVERY:
|
||||||
|
_client->device = dfu_get_irecv_device(_client);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _client->device->product_type;
|
return _client->device->product_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *futurerestore::getDeviceBoardNoCopy(){
|
const char *futurerestore::getDeviceBoardNoCopy(){
|
||||||
if (!_client->device || !_client->device->hardware_model){
|
if (!_client->device || !_client->device->product_type){
|
||||||
|
|
||||||
int mode = getDeviceMode(true);
|
int mode = getDeviceMode(true);
|
||||||
|
retassure(mode == MODE_NORMAL || mode == MODE_RECOVERY || mode == MODE_DFU, "unexpected device mode=%d\n",mode);
|
||||||
|
|
||||||
retassure(mode == MODE_NORMAL || mode == MODE_RECOVERY, "unexpected device mode=%d\n",mode);
|
switch (mode) {
|
||||||
|
case MODE_RESTORE:
|
||||||
retassure(check_hardware_model(_client) && _client->device, "ERROR: Unable to discover device model\n");
|
_client->device = restore_get_irecv_device(_client);
|
||||||
|
break;
|
||||||
|
case MODE_NORMAL:
|
||||||
|
_client->device = normal_get_irecv_device(_client);
|
||||||
|
break;
|
||||||
|
case MODE_DFU:
|
||||||
|
case MODE_RECOVERY:
|
||||||
|
_client->device = dfu_get_irecv_device(_client);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _client->device->hardware_model;
|
return _client->device->hardware_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ public:
|
||||||
|
|
||||||
uint64_t getBasebandGoldCertIDFromDevice();
|
uint64_t getBasebandGoldCertIDFromDevice();
|
||||||
|
|
||||||
int doRestore(const char *ipsw);
|
void doRestore(const char *ipsw);
|
||||||
int doJustBoot(const char *ipsw, std::string bootargs = "");
|
int doJustBoot(const char *ipsw, std::string bootargs = "");
|
||||||
|
|
||||||
~futurerestore();
|
~futurerestore();
|
||||||
|
|
|
@ -264,12 +264,11 @@ int main_r(int argc, const char * argv[]) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (bootargs)
|
if (bootargs)
|
||||||
res = client.doJustBoot(ipsw,bootargs);
|
client.doJustBoot(ipsw,bootargs);
|
||||||
else
|
else
|
||||||
res = client.doRestore(ipsw);
|
client.doRestore(ipsw);
|
||||||
} catch (int error) {
|
} catch (tihmstar::exception &e) {
|
||||||
if (error == -20) error("maybe you forgot -w ?\n");
|
e.dump();
|
||||||
err = error;
|
|
||||||
}
|
}
|
||||||
cout << "Done: restoring "<< (!res ? "succeeded" : "failed")<<"." <<endl;
|
cout << "Done: restoring "<< (!res ? "succeeded" : "failed")<<"." <<endl;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue