mirror of
https://github.com/tihmstar/futurerestore.git
synced 2025-04-20 14:31:41 +00:00
Improve logging, add no rsep, add component cache
This commit is contained in:
parent
7f73214018
commit
19e30c014b
|
@ -4,6 +4,12 @@ execute_process(COMMAND git submodule update --init --recursive WORKING_DIRECTOR
|
|||
set(ignoreMe "${NO_PKGCFG} ${ASAN} ${NO_XCODE} ${ARCH}")
|
||||
set(SUBPROJECT_BUILD 1)
|
||||
set(ASAN_FLAG "")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-g -O0 -DDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG")
|
||||
set(CMAKE_C_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
if(DEFINED ASAN OR "$ENV{ASAN}" MATCHES "1")
|
||||
set(ASAN 1)
|
||||
set(ASAN_FLAG "-fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer")
|
||||
|
@ -40,12 +46,6 @@ elseif("${CMAKE_HOST_SYSTEM_NAME}" MATCHES "Linux")
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--allow-multiple-definition -pthread -mrelax-all -std=gnu++20 ${ASAN_FLAG}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--allow-multiple-definition -pthread -mrelax-all -std=gnu17 ${ASAN_FLAG}")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-g -O0 -DDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG")
|
||||
set(CMAKE_C_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
project(futurerestore)
|
||||
add_subdirectory(external/tsschecker)
|
||||
add_subdirectory(external/idevicerestore)
|
||||
|
|
59
README.md
59
README.md
|
@ -33,35 +33,36 @@ See [COMPILING](COMPILING.md)
|
|||
# Futurerestore Usage
|
||||
Usage: `futurerestore [OPTIONS] iPSW`
|
||||
|
||||
| option (short) | option (long) | description |
|
||||
|----------------|------------------------------------------|-----------------------------------------------------------------------------------|
|
||||
| ` -t ` | ` --apticket PATH ` | Signing tickets used for restoring, commonly known as blobs |
|
||||
| ` -u ` | ` --update ` | Update instead of erase install (requires appropriate APTicket) |
|
||||
| | | This parameter is recommended to not be used for downgrading. If you are jailbroken, make sure to have your orig-fs snapshot restored (Restore RootFS). |
|
||||
| ` -w ` | ` --wait ` | Keep rebooting until ApNonce matches APTicket (ApNonce collision, unreliable) |
|
||||
| ` -d ` | ` --debug ` | Show all code, use to save a log for debug testing |
|
||||
| ` -e ` | ` --exit-recovery ` | Exit recovery mode and quit |
|
||||
| ` -c ` | ` --custom-latest VERSION ` | Specify custom latest version to use for SEP, Baseband and other FirmwareUpdater components |
|
||||
| ` -g ` | ` --custom-latest-buildid BUILDID ` | Specify custom latest buildid to use for SEP, Baseband and other FirmwareUpdater components |
|
||||
| ` -i ` | ` --custom-latest-beta ` | Get custom url from list of beta firmwares |
|
||||
| | ` --use-pwndfu ` | Restoring devices with Odysseus method. Device needs to be in pwned DFU mode already |
|
||||
| | ` --no-ibss ` | Restoring devices with Odysseus method. For checkm8/iPwnder32 specifically, bootrom needs to be patched already with unless iPwnder. |
|
||||
| | ` --rdsk PATH ` | Set custom restore ramdisk for entering restoremode(requires use-pwndfu) |
|
||||
| | ` --rkrn PATH ` | Set custom restore kernelcache for entering restoremode(requires use-pwndfu) |
|
||||
| | ` --set-nonce ` | Set custom nonce from your blob then exit recovery(requires use-pwndfu) |
|
||||
| | ` --set-nonce=0xNONCE ` | Set custom nonce then exit recovery(requires use-pwndfu) |
|
||||
| | ` --serial ` | Enable serial during boot(requires serial cable and use-pwndfu) |
|
||||
| | ` --boot-args "BOOTARGS" ` | Set custom restore boot-args(PROCEED WITH CAUTION)(requires use-pwndfu) |
|
||||
| | ` --no-cache ` | Disable cached patched iBSS/iBEC(requires use-pwndfu) |
|
||||
| | ` --skip-blob ` | Skip SHSH blob validation(PROCEED WITH CAUTION)(requires use-pwndfu) |
|
||||
| | ` --latest-sep ` | Use latest signed SEP instead of manually specifying one |
|
||||
| ` -s ` | ` --sep PATH ` | Manually specify SEP to be flashed |
|
||||
| ` -m ` | ` --sep-manifest PATH ` | BuildManifest for requesting SEP ticket |
|
||||
| | ` --latest-baseband ` | Use latest signed baseband instead of manually specifying one |
|
||||
| ` -b ` | ` --baseband PATH ` | Manually specify baseband to be flashed |
|
||||
| ` -p ` | ` --baseband-manifest PATH ` | BuildManifest for requesting baseband ticket |
|
||||
| | ` --no-baseband ` | Skip checks and don't flash baseband |
|
||||
| | | Only use this for device without a baseband (eg. iPod touch or Wi-Fi only iPads) |
|
||||
| option (short) | option (long) | description |
|
||||
|----------------|-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ` -t ` | ` --apticket PATH ` | Signing tickets used for restoring, commonly known as blobs |
|
||||
| ` -u ` | ` --update ` | Update instead of erase install (requires appropriate APTicket) |
|
||||
| | | This parameter is recommended to not be used for downgrading. If you are jailbroken, make sure to have your orig-fs snapshot restored (Restore RootFS). |
|
||||
| ` -w ` | ` --wait ` | Keep rebooting until ApNonce matches APTicket (ApNonce collision, unreliable) |
|
||||
| ` -d ` | ` --debug ` | Show all code, use to save a log for debug testing |
|
||||
| ` -e ` | ` --exit-recovery ` | Exit recovery mode and quit |
|
||||
| ` -c ` | ` --custom-latest VERSION ` | Specify custom latest version to use for SEP, Baseband and other FirmwareUpdater components |
|
||||
| ` -g ` | ` --custom-latest-buildid BUILDID ` | Specify custom latest buildid to use for SEP, Baseband and other FirmwareUpdater components |
|
||||
| ` -i ` | ` --custom-latest-beta ` | Get custom url from list of beta firmwares |
|
||||
| | ` --use-pwndfu ` | Restoring devices with Odysseus method. Device needs to be in pwned DFU mode already |
|
||||
| | ` --no-ibss ` | Restoring devices with Odysseus method. For checkm8/iPwnder32 specifically, bootrom needs to be patched already with unless iPwnder. |
|
||||
| | ` --rdsk PATH ` | Set custom restore ramdisk for entering restoremode(requires use-pwndfu) |
|
||||
| | ` --rkrn PATH ` | Set custom restore kernelcache for entering restoremode(requires use-pwndfu) |
|
||||
| | ` --set-nonce ` | Set custom nonce from your blob then exit recovery(requires use-pwndfu) |
|
||||
| | ` --set-nonce=0xNONCE ` | Set custom nonce then exit recovery(requires use-pwndfu) |
|
||||
| | ` --serial ` | Enable serial during boot(requires serial cable and use-pwndfu) |
|
||||
| | ` --boot-args "BOOTARGS" ` | Set custom restore boot-args(PROCEED WITH CAUTION)(requires use-pwndfu) |
|
||||
| | ` --no-cache ` | Disable cached patched iBSS/iBEC(requires use-pwndfu) |
|
||||
| | ` --skip-blob ` | Skip SHSH blob validation(PROCEED WITH CAUTION)(requires use-pwndfu) |
|
||||
| | ` --latest-sep ` | Use latest signed SEP instead of manually specifying one |
|
||||
| ` -s ` | ` --sep PATH ` | Manually specify SEP to be flashed |
|
||||
| ` -m ` | ` --sep-manifest PATH ` | BuildManifest for requesting SEP ticket |
|
||||
| ` -j ` | ` --no-rsep ` | Choose not to send Restore Mode SEP |
|
||||
| | ` --latest-baseband ` | Use latest signed baseband instead of manually specifying one |
|
||||
| ` -b ` | ` --baseband PATH ` | Manually specify baseband to be flashed |
|
||||
| ` -p ` | ` --baseband-manifest PATH ` | BuildManifest for requesting baseband ticket |
|
||||
| | ` --no-baseband ` | Skip checks and don't flash baseband |
|
||||
| | | Only use this for device without a baseband (eg. iPod touch or Wi-Fi only iPads) |
|
||||
|
||||
---
|
||||
|
||||
|
|
2
external/idevicerestore
vendored
2
external/idevicerestore
vendored
|
@ -1 +1 @@
|
|||
Subproject commit b46637056fce7cb771f53916b1a8c527d256c5f2
|
||||
Subproject commit 97ab482cf251b83e71887f9cd7a8f1d9e066e671
|
2
external/tsschecker
vendored
2
external/tsschecker
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 9a046508ffb7cbd62d3ff50042944237389c51b4
|
||||
Subproject commit 6e55c67ec78df55b8185c17ea2f79f838d0c034b
|
|
@ -88,6 +88,7 @@ endif()
|
|||
execute_process(COMMAND cat version.txt WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE VERSION_RELEASE ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
add_definitions(
|
||||
-DHAVE_LIBIPATCHER=1
|
||||
-DCUSTOM_LOGGING=<stdlib.h>
|
||||
-DVERSION_COMMIT_COUNT="${VERSION_COMMIT_COUNT}"
|
||||
-DVERSION_COMMIT_SHA="${VERSION_COMMIT_SHA}"
|
||||
-DVERSION_RELEASE="${VERSION_RELEASE}"
|
||||
|
|
|
@ -108,9 +108,15 @@ std::string sepManifestTempPath = futurerestoreTempPath + "/sepManifest.plist";
|
|||
# include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
# define SHA1(d, n, md) CC_SHA1(d, n, md)
|
||||
# define SHA256(d, n, md) CC_SHA256(d, n, md)
|
||||
# define SHA384(d, n, md) CC_SHA384(d, n, md)
|
||||
# define SHA512(d, n, md) CC_SHA512(d, n, md)
|
||||
#else
|
||||
# include <openssl/sha.h>
|
||||
extern "C" {
|
||||
unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
|
||||
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
#ifndef HAVE_LIBIPATCHER
|
||||
|
@ -128,10 +134,10 @@ void idevice_event_cb(const idevice_event_t *event, void *userdata);
|
|||
#pragma mark futurerestore
|
||||
|
||||
futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu, bool noIBSS, bool setNonce, bool serial,
|
||||
bool noRestore) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu), _noIBSS(noIBSS),
|
||||
_setNonce(setNonce), _serial(serial), _noRestore(noRestore) {
|
||||
bool noRestore, bool noRSEP) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu), _noIBSS(noIBSS),
|
||||
_setNonce(setNonce), _serial(serial), _noRestore(noRestore), _noRSEP(noRSEP) {
|
||||
_client = idevicerestore_client_new();
|
||||
retassure(_client != nullptr, "could not create idevicerestore client\n");
|
||||
retassure(_client != nullptr, "Could not create idevicerestore client\n");
|
||||
|
||||
struct stat st{0};
|
||||
if (stat(futurerestoreTempPath.c_str(), &st) == -1) safe_mkdir(futurerestoreTempPath.c_str(), 0755);
|
||||
|
@ -468,7 +474,7 @@ uint64_t futurerestore::getBasebandGoldCertIDFromDevice() {
|
|||
plist_t node;
|
||||
node = plist_dict_get_item(_client->preflight_info, "CertID");
|
||||
if (!node || plist_get_node_type(node) != PLIST_UINT) {
|
||||
error("Unable to find required BbGoldCertId in parameters\n");
|
||||
debug("Unable to find required BbGoldCertId in parameters\n");
|
||||
return 0;
|
||||
}
|
||||
uint64_t val = 0;
|
||||
|
@ -893,6 +899,7 @@ void futurerestore::doRestore(const char *ipsw) {
|
|||
|
||||
client->ipsw = strdup(ipsw);
|
||||
if (_noRestore) client->flags |= FLAG_NO_RESTORE;
|
||||
if (_noRSEP) client->flags |= FLAG_NO_RSEP;
|
||||
if (!_isUpdateInstall) client->flags |= FLAG_ERASE;
|
||||
|
||||
irecv_device_event_subscribe(&client->irecv_e_ctx, irecv_event_cb, client);
|
||||
|
@ -1119,13 +1126,13 @@ void futurerestore::doRestore(const char *ipsw) {
|
|||
if (sephashlen == 20)
|
||||
SHA1((unsigned char *) _client->sepfwdata, (unsigned int) _client->sepfwdatasize, genHash);
|
||||
else
|
||||
SHA384((unsigned char *) _client->sepfwdata, (unsigned int) _client->sepfwdatasize, genHash);
|
||||
SHA384((const unsigned char *) _client->sepfwdata, (unsigned long) _client->sepfwdatasize, genHash);
|
||||
retassure(!memcmp(genHash, sephash, sephashlen), "ERROR: SEP does not match sepmanifest\n");
|
||||
}
|
||||
|
||||
build_identity_print_information(build_identity); // print information about current build identity
|
||||
|
||||
//check for enterpwnrecovery, because we could be in DFU mode
|
||||
//check for enterpwnrecovery, because we Could be in DFU mode
|
||||
if (_enterPwnRecoveryRequested) {
|
||||
retassure((getDeviceMode(true) == _MODE_DFU) || (getDeviceMode(false) == _MODE_RECOVERY && _noIBSS),
|
||||
"unexpected device mode\n");
|
||||
|
@ -1352,7 +1359,7 @@ void futurerestore::doRestore(const char *ipsw) {
|
|||
get_ap_nonce(client, &client->nonce, &client->nonce_size);
|
||||
|
||||
if (client->mode == 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 (client->device->chip_id < 0x8015) {
|
||||
retassure(!irecv_send_command(client->recovery->client, "bgcolor 0 255 0"),
|
||||
|
@ -1401,17 +1408,17 @@ int futurerestore::findProc(const char *procName, bool load) {
|
|||
do {
|
||||
ctlRet = sysctl(mib, mibLen, nullptr, &size, nullptr, 0);
|
||||
if (ctlRet < 0) {
|
||||
info("daemonManager: findProc: failed sysctl(KERN_PROC)!\n");
|
||||
debug("daemonManager: findProc: failed sysctl(KERN_PROC)!\n");
|
||||
return -1;
|
||||
}
|
||||
if (!size) {
|
||||
info("daemonManager: findProc: failed sysctl(KERN_PROC) size!\n");
|
||||
debug("daemonManager: findProc: failed sysctl(KERN_PROC) size!\n");
|
||||
return -1;
|
||||
}
|
||||
size += size / 10;
|
||||
procs2 = static_cast<kinfo_proc *>(realloc(procs, size));
|
||||
if (!procs2) {
|
||||
info("daemonManager: findProc: realloc failed!\n");
|
||||
debug("daemonManager: findProc: realloc failed!\n");
|
||||
safeFree(procs);
|
||||
safeFree(procs2);
|
||||
return -1;
|
||||
|
@ -1478,7 +1485,7 @@ int futurerestore::findProc(const char *procName, bool load) {
|
|||
}
|
||||
if (strcmp(cmd, procName) == 0) {
|
||||
if(!load) {
|
||||
info("daemonManager: findProc: found %s!\n", procName);
|
||||
debug("daemonManager: findProc: found %s!\n", procName);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
@ -1488,7 +1495,7 @@ int futurerestore::findProc(const char *procName, bool load) {
|
|||
|
||||
void futurerestore::daemonManager(bool load) {
|
||||
if(!load) {
|
||||
info("daemonManager: suspending invasive macOS daemons...\n");
|
||||
debug("daemonManager: suspending invasive macOS daemons...\n");
|
||||
}
|
||||
int pid = 0;
|
||||
const char *procList[] = { "MobileDeviceUpdater", "AMPDevicesAgent", "AMPDeviceDiscoveryAgent", 0};
|
||||
|
@ -1498,14 +1505,14 @@ void futurerestore::daemonManager(bool load) {
|
|||
if (load) {
|
||||
int ret = kill(pid, SIGCONT);
|
||||
} else {
|
||||
info("daemonManager: killing %s.\n", procList[i]);
|
||||
debug("daemonManager: killing %s.\n", procList[i]);
|
||||
int ret = kill(pid, SIGSTOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!load) {
|
||||
info("daemonManager: done!\n");
|
||||
debug("daemonManager: done!\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1536,19 +1543,22 @@ futurerestore::~futurerestore() {
|
|||
void futurerestore::loadFirmwareTokens() {
|
||||
if (!_firmwareTokens) {
|
||||
if (!_firmwareJson) _firmwareJson = getFirmwareJson();
|
||||
retassure(_firmwareJson, "[TSSC] could not get firmware.json\n");
|
||||
retassure(_firmwareJson, "[TSSC] Could not get firmware.json\n");
|
||||
long cnt = parseTokens(_firmwareJson, &_firmwareTokens);
|
||||
retassure(cnt > 0, "[TSSC] parsing %s.json failed\n", (0) ? "ota" : "firmware");
|
||||
}
|
||||
if(!_betaFirmwareTokens) {
|
||||
if (!_betaFirmwareJson) _betaFirmwareJson = getBetaFirmwareJson(getDeviceModelNoCopy());
|
||||
retassure(_betaFirmwareJson, "[TSSC] could not get betas json\n");
|
||||
retassure(_betaFirmwareJson, "[TSSC] Could not get betas json\n");
|
||||
long cnt = parseTokens(_betaFirmwareJson, &_betaFirmwareTokens);
|
||||
retassure(cnt > 0, "[TSSC] parsing %s.json failed\n", (0) ? "beta ota" : "beta firmware");
|
||||
}
|
||||
}
|
||||
|
||||
const char *futurerestore::getDeviceModelNoCopy() {
|
||||
if(_model) {
|
||||
return _model;
|
||||
}
|
||||
if (!_client->device || !_client->device->product_type) {
|
||||
|
||||
int mode = getDeviceMode(true);
|
||||
|
@ -1571,10 +1581,13 @@ const char *futurerestore::getDeviceModelNoCopy() {
|
|||
}
|
||||
}
|
||||
|
||||
return _client->device->product_type;
|
||||
return _model = _client->device->product_type;
|
||||
}
|
||||
|
||||
const char *futurerestore::getDeviceBoardNoCopy() {
|
||||
if(_board) {
|
||||
return _board;
|
||||
}
|
||||
if (!_client->device || !_client->device->product_type) {
|
||||
|
||||
int mode = getDeviceMode(true);
|
||||
|
@ -1596,7 +1609,7 @@ const char *futurerestore::getDeviceBoardNoCopy() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return _client->device->hardware_model;
|
||||
return _board = _client->device->hardware_model;
|
||||
}
|
||||
|
||||
char *futurerestore::getLatestManifest() {
|
||||
|
@ -1620,7 +1633,7 @@ char *futurerestore::getLatestManifest() {
|
|||
while ((bpos = strstr((char *) (versVals.version = strdup(versions[i++])), "[B]")) != nullptr) {
|
||||
free((char *) versVals.version);
|
||||
if (--versionCnt == 0)
|
||||
reterror("[TSSC] automatic selection of firmware couldn't find for non-beta versions\n");
|
||||
reterror("[TSSC] automatic selection of firmware Couldn't find for non-beta versions\n");
|
||||
}
|
||||
if(_useCustomLatest) {
|
||||
i = 0;
|
||||
|
@ -1655,9 +1668,9 @@ char *futurerestore::getLatestManifest() {
|
|||
}
|
||||
if(!_useCustomLatestBeta) {
|
||||
if(_useCustomLatestBuildID) {
|
||||
info("[TSSC] selecting latest firmware version: %s\n", versVals.buildID);
|
||||
debug("[TSSC] selecting latest firmware version: %s\n", versVals.buildID);
|
||||
} else {
|
||||
info("[TSSC] selecting latest firmware version: %s\n", versVals.version);
|
||||
debug("[TSSC] selecting latest firmware version: %s\n", versVals.version);
|
||||
}
|
||||
}
|
||||
if (bpos) *bpos = '\0';
|
||||
|
@ -1669,7 +1682,7 @@ char *futurerestore::getLatestManifest() {
|
|||
versVals.buildID); //make sure it gets freed after function finishes execution by either reaching end or throwing exception
|
||||
|
||||
if(_useCustomLatestBeta) {
|
||||
info("[TSSC] selecting latest firmware version: %s\n", _customLatestBuildID.c_str());
|
||||
debug("[TSSC] selecting latest firmware version: %s\n", _customLatestBuildID.c_str());
|
||||
_latestFirmwareUrl = getBetaURLForDevice(_betaFirmwareTokens, _customLatestBuildID.c_str());
|
||||
_latestManifest = getBuildManifest(_latestFirmwareUrl, device, nullptr, _customLatestBuildID.c_str(), 0);
|
||||
} else {
|
||||
|
@ -1680,8 +1693,8 @@ char *futurerestore::getLatestManifest() {
|
|||
_latestManifest = getBuildManifest(_latestFirmwareUrl, device, versVals.version, versVals.buildID, 0);
|
||||
}
|
||||
}
|
||||
retassure(_latestFirmwareUrl, "could not find url of latest firmware version\n");
|
||||
retassure(_latestManifest, "could not get buildmanifest of latest firmware version\n");
|
||||
retassure(_latestFirmwareUrl, "Could not find url of latest firmware version\n");
|
||||
retassure(_latestManifest, "Could not get buildmanifest of latest firmware version\n");
|
||||
}
|
||||
|
||||
return _latestManifest;
|
||||
|
@ -1696,9 +1709,20 @@ void futurerestore::downloadLatestRose() {
|
|||
char *roseStr = (elemExists("Rap,RTKitOS", manifeststr, getDeviceBoardNoCopy(), 0) ? getPathOfElementInManifest(
|
||||
"Rap,RTKitOS", manifeststr, getDeviceBoardNoCopy(), 0) : nullptr);
|
||||
if (roseStr) {
|
||||
info("downloading Rose firmware\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), roseStr, roseTempPath.c_str()),
|
||||
"could not download Rose\n");
|
||||
auto *digestString = getDigestOfElementInManifest("Rap,RTKitOS", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
unsigned char *hash = getSHA(roseTempPath);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 48)) {
|
||||
info("Using cached Rose\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
info("Downloading Rose firmware\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), roseStr, roseTempPath.c_str()),
|
||||
"Could not download Rose\n");
|
||||
}
|
||||
loadRose(roseTempPath);
|
||||
}
|
||||
}
|
||||
|
@ -1708,8 +1732,10 @@ void futurerestore::downloadLatestSE() {
|
|||
char *seStr = (elemExists("SE,UpdatePayload", manifeststr, getDeviceBoardNoCopy(), 0) ? getPathOfElementInManifest(
|
||||
"SE,UpdatePayload", manifeststr, getDeviceBoardNoCopy(), 0) : nullptr);
|
||||
if (seStr) {
|
||||
info("downloading SE firmware\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), seStr, seTempPath.c_str()), "could not download SE\n");
|
||||
// TODO: SE caching how does ProductionUpdatePayloadHash work?
|
||||
info("Downloading SE firmware\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), seStr, seTempPath.c_str()),
|
||||
"Could not download SE\n");
|
||||
loadSE(seTempPath);
|
||||
}
|
||||
}
|
||||
|
@ -1736,41 +1762,102 @@ void futurerestore::downloadLatestSavage() {
|
|||
: nullptr);
|
||||
std::array<std::string, 6> savagePaths{};
|
||||
|
||||
|
||||
if (savageB0ProdStr) {
|
||||
info("downloading Savage,B0-Prod-Patch\n\n");
|
||||
savagePaths[0] = futurerestoreTempPath + "/savageB0PP.fw";
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageB0ProdStr, savagePaths[0].c_str()),
|
||||
"could not download Savage,B0-Prod-Patch\n");
|
||||
auto *digestString = getDigestOfElementInManifest("Savage,B0-Prod-Patch", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
unsigned char *hash = getSHA(savagePaths[0], 1);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 32)) {
|
||||
info("Using cached Savage,B0-Prod-Patch.\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading Savage,B0-Prod-Patch\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageB0ProdStr, savagePaths[0].c_str()),
|
||||
"Could not download Savage,B0-Prod-Patch\n");
|
||||
}
|
||||
}
|
||||
if (savageB0DevStr) {
|
||||
info("downloading Savage,B0-Dev-Patch\n\n");
|
||||
savagePaths[1] = futurerestoreTempPath + "//savageB0DP.fw";
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageB0DevStr, savagePaths[1].c_str()),
|
||||
"could not download Savage,B0-Dev-Patch\n");
|
||||
auto *digestString = getDigestOfElementInManifest("Savage,B0-Dev-Patch", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
unsigned char *hash = getSHA(savagePaths[1], 1);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 32)) {
|
||||
info("Using cached Savage,B0-Dev-Patch.\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading Savage,B0-Dev-Patch\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageB0DevStr, savagePaths[1].c_str()),
|
||||
"Could not download Savage,B0-Dev-Patch\n");
|
||||
}
|
||||
}
|
||||
if (savageB2ProdStr) {
|
||||
info("downloading Savage,B2-Prod-Patch\n\n");
|
||||
savagePaths[2] = futurerestoreTempPath + "//savageB2PP.fw";
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageB2ProdStr, savagePaths[2].c_str()),
|
||||
"could not download Savage,B2-Prod-Patch\n");
|
||||
auto *digestString = getDigestOfElementInManifest("Savage,B2-Prod-Patch", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
unsigned char *hash = getSHA(savagePaths[2], 1);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 32)) {
|
||||
info("Using cached Savage,B2-Prod-Patch.\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading Savage,B2-Prod-Patch\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageB2ProdStr, savagePaths[2].c_str()),
|
||||
"Could not download Savage,B2-Prod-Patch\n");
|
||||
}
|
||||
}
|
||||
if (savageB2DevStr) {
|
||||
info("downloading Savage,B2-Dev-Patch\n\n");
|
||||
savagePaths[3] = futurerestoreTempPath + "//savageB2DP.fw";
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageB2DevStr, savagePaths[3].c_str()),
|
||||
"could not download Savage,B2-Dev-Patch\n");
|
||||
auto *digestString = getDigestOfElementInManifest("Savage,B2-Dev-Patch", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
unsigned char *hash = getSHA(savagePaths[3], 1);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 32)) {
|
||||
info("Using cached Savage,B2-Dev-Patch.\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading Savage,B2-Dev-Patch\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageB2DevStr, savagePaths[3].c_str()),
|
||||
"Could not download Savage,B2-Dev-Patch\n");
|
||||
}
|
||||
}
|
||||
if (savageBAProdStr) {
|
||||
info("downloading Savage,BA-Prod-Patch\n\n");
|
||||
savagePaths[4] = futurerestoreTempPath + "//savageBAPP.fw";
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageBAProdStr, savagePaths[4].c_str()),
|
||||
"could not download Savage,BA-Prod-Patch\n");
|
||||
auto *digestString = getDigestOfElementInManifest("Savage,BA-Prod-Patch", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
unsigned char *hash = getSHA(savagePaths[4], 1);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 32)) {
|
||||
info("Using cached Savage,BA-Prod-Patch.\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading Savage,BA-Prod-Patch\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageBAProdStr, savagePaths[4].c_str()),
|
||||
"Could not download Savage,BA-Prod-Patch\n");
|
||||
}
|
||||
}
|
||||
if (savageBADevStr) {
|
||||
info("downloading Savage,BA-Dev-Patch\n\n");
|
||||
savagePaths[5] = futurerestoreTempPath + "//savageBADP.fw";
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageBADevStr, savagePaths[5].c_str()),
|
||||
"could not download Savage,BA-Dev-Patch\n");
|
||||
auto *digestString = getDigestOfElementInManifest("Savage,BA-Dev-Patch", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
unsigned char *hash = getSHA(savagePaths[5], 1);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 32)) {
|
||||
info("Using cached Savage,BA-Dev-Patch.\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading Savage,BA-Dev-Patch\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), savageBADevStr, savagePaths[5].c_str()),
|
||||
"Could not download Savage,BA-Dev-Patch\n");
|
||||
}
|
||||
}
|
||||
if (savageB0ProdStr &&
|
||||
savageB0DevStr &&
|
||||
|
@ -1790,15 +1877,36 @@ void futurerestore::downloadLatestVeridian() {
|
|||
char *veridianFWMStr = (elemExists("BMU,FirmwareMap", manifeststr, getDeviceBoardNoCopy(), 0)
|
||||
? getPathOfElementInManifest("BMU,FirmwareMap", manifeststr, getDeviceBoardNoCopy(), 0)
|
||||
: nullptr);
|
||||
|
||||
if (veridianDGMStr) {
|
||||
info("downloading Veridian DigestMap\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), veridianDGMStr, veridianDGMTempPath.c_str()),
|
||||
"could not download Veridian DigestMap\n");
|
||||
auto *digestString = getDigestOfElementInManifest("BMU,DigestMap", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
unsigned char *hash = getSHA(veridianDGMTempPath);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 48)) {
|
||||
info("Using cached BMU,DigestMap(Veridian).\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading Veridian DigestMap\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), veridianDGMStr, veridianDGMTempPath.c_str()),
|
||||
"Could not download Veridian DigestMap\n");
|
||||
}
|
||||
}
|
||||
if (veridianFWMStr) {
|
||||
info("downloading Veridian FirmwareMap\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), veridianFWMStr, veridianFWMTempPath.c_str()),
|
||||
"could not download Veridian FirmwareMap\n");
|
||||
auto digestString = getDigestOfElementInManifest("BMU,FirmwareMap", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
auto hash = getSHA(veridianFWMTempPath);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 48)) {
|
||||
info("Using cached BMU,FirmwareMap(Veridian).\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading Veridian FirmwareMap\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), veridianFWMStr, veridianFWMTempPath.c_str()),
|
||||
"Could not download Veridian FirmwareMap\n");
|
||||
}
|
||||
}
|
||||
if (veridianDGMStr && veridianFWMStr)
|
||||
loadVeridian(veridianDGMTempPath, veridianFWMTempPath);
|
||||
|
@ -1826,11 +1934,12 @@ void futurerestore::downloadLatestFirmwareComponents() {
|
|||
}
|
||||
|
||||
void futurerestore::downloadLatestBaseband() {
|
||||
char *manifeststr = getLatestManifest();
|
||||
char *pathStr = getPathOfElementInManifest("BasebandFirmware", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
info("downloading Baseband\n\n");
|
||||
auto manifeststr = getLatestManifest();
|
||||
auto pathStr = getPathOfElementInManifest("BasebandFirmware", manifeststr, getDeviceBoardNoCopy(), 0);
|
||||
// TODO: Baseband caching. How on earth does basebandfirmware digest work?
|
||||
info("Downloading Baseband\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), pathStr, basebandTempPath.c_str()),
|
||||
"could not download baseband\n");
|
||||
"Could not download baseband\n");
|
||||
saveStringToFile(manifeststr, basebandManifestTempPath);
|
||||
setBasebandPath(basebandTempPath);
|
||||
setBasebandManifestPath(basebandManifestTempPath);
|
||||
|
@ -1839,10 +1948,20 @@ void futurerestore::downloadLatestBaseband() {
|
|||
}
|
||||
|
||||
void futurerestore::downloadLatestSep() {
|
||||
std::string manifestString = getLatestManifest();
|
||||
std::string pathString = getPathOfElementInManifest("SEP", manifestString.c_str(), getDeviceBoardNoCopy(), 0);
|
||||
info("downloading SEP\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), pathString.c_str(), sepTempPath.c_str()), "could not download SEP\n");
|
||||
auto manifestString = getLatestManifest();
|
||||
auto pathString = getPathOfElementInManifest("SEP", manifestString, getDeviceBoardNoCopy(), 0);
|
||||
auto *digestString = getDigestOfElementInManifest("SEP",manifestString,getDeviceBoardNoCopy(),0);
|
||||
auto *hash = getSHA(sepTempPath);
|
||||
if(hash && digestString) {
|
||||
if(!memcmp(digestString, hash, 48)) {
|
||||
info("Using cached SEP.\n");
|
||||
safeFree(digestString);
|
||||
safeFree(hash);
|
||||
}
|
||||
} else {
|
||||
info("Downloading SEP\n\n");
|
||||
retassure(!downloadPartialzip(getLatestFirmwareUrl(), pathString, sepTempPath.c_str()), "Could not download SEP\n");
|
||||
}
|
||||
saveStringToFile(manifestString, sepManifestTempPath);
|
||||
setSepPath(sepTempPath);
|
||||
setSepManifestPath(sepManifestTempPath);
|
||||
|
@ -1853,13 +1972,13 @@ void futurerestore::downloadLatestSep() {
|
|||
void futurerestore::loadSepManifest(std::string sepManifestPath) {
|
||||
this->_sepManifestPath = sepManifestPath;
|
||||
retassure(_sepbuildmanifest = loadPlistFromFile(sepManifestPath.c_str()),
|
||||
"failed to load SEP Manifest");
|
||||
"Failed to load SEP Manifest");
|
||||
}
|
||||
|
||||
void futurerestore::loadBasebandManifest(std::string basebandManifestPath) {
|
||||
this->_basebandManifestPath = basebandManifestPath;
|
||||
retassure(_basebandbuildmanifest = loadPlistFromFile(basebandManifestPath.c_str()),
|
||||
"failed to load Baseband Manifest");
|
||||
"Failed to load Baseband Manifest");
|
||||
};
|
||||
|
||||
void futurerestore::loadRose(std::string rosePath) {
|
||||
|
@ -2004,6 +2123,54 @@ void futurerestore::loadBaseband(std::string basebandPath) {
|
|||
__func__, basebandPath.c_str());
|
||||
}
|
||||
|
||||
unsigned char *futurerestore::getSHA(const std::string& filePath, int type) {
|
||||
std::ifstream fileStream(filePath);
|
||||
if(!fileStream.good()) {
|
||||
info("Cached %s not found, downloading a new one.\n", filePath.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
fileStream.seekg(0, std::ios_base::end);
|
||||
size_t dataSize = fileStream.tellg();
|
||||
fileStream.seekg(0, std::ios_base::beg);
|
||||
std::allocator<uint8_t> alloc;
|
||||
char *data = nullptr;
|
||||
if(!(data = (char *)alloc.allocate(dataSize))) {
|
||||
error("%s: failed to allocate memory for %s\n", __func__, filePath.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
fileStream.read((char *) data,
|
||||
(std::streamsize) dataSize);
|
||||
if(*(uint64_t *)(data) == 0) {
|
||||
error("%s: failed to load File for %s with the size %zu!\n",
|
||||
__func__, filePath.c_str(), dataSize);
|
||||
return nullptr;
|
||||
}
|
||||
auto *fileHash = (unsigned char *)nullptr;
|
||||
switch(type) {
|
||||
case 0:
|
||||
fileHash = (unsigned char *) alloc.allocate(48);
|
||||
SHA384((const unsigned char*)data, (unsigned int)dataSize, fileHash);
|
||||
break;
|
||||
case 1:
|
||||
fileHash = (unsigned char *) alloc.allocate(32);
|
||||
SHA256((const unsigned char*)data, (unsigned int)dataSize, fileHash);
|
||||
break;
|
||||
case 2:
|
||||
fileHash = (unsigned char *) alloc.allocate(64);
|
||||
SHA512((const unsigned char*)data, (unsigned int)dataSize, fileHash);
|
||||
break;
|
||||
case 3:
|
||||
fileHash = (unsigned char *) alloc.allocate(20);
|
||||
SHA1((const unsigned char*)data, (unsigned int)dataSize, fileHash);
|
||||
break;
|
||||
default:
|
||||
fileHash = (unsigned char *) alloc.allocate(48);
|
||||
SHA384((const unsigned char*)data, (unsigned int)dataSize, fileHash);
|
||||
break;
|
||||
}
|
||||
return fileHash;
|
||||
}
|
||||
|
||||
#pragma mark static methods
|
||||
|
||||
inline void futurerestore::saveStringToFile(std::string str, std::string path) {
|
||||
|
@ -2094,7 +2261,7 @@ plist_t futurerestore::loadPlistFromFile(const char *path) {
|
|||
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
error("could not open file %s\n", path);
|
||||
error("Could not open file %s\n", path);
|
||||
return nullptr;
|
||||
}
|
||||
fseek(f, 0, SEEK_END);
|
||||
|
@ -2138,11 +2305,31 @@ char *futurerestore::getPathOfElementInManifest(const char *element, const char
|
|||
if (plist_get_string_val(path, &pathStr), pathStr)
|
||||
goto noerror;
|
||||
|
||||
reterror("could not get %s path\n", element);
|
||||
reterror("Could not get %s path\n", element);
|
||||
noerror:
|
||||
return pathStr;
|
||||
}
|
||||
|
||||
unsigned char *futurerestore::getDigestOfElementInManifest(const char *element, const char *manifeststr, const char *boardConfig,
|
||||
int isUpdateInstall) {
|
||||
char *digestStr = nullptr;
|
||||
ptr_smart<plist_t> buildmanifest(NULL, plist_free);
|
||||
uint64_t size;
|
||||
|
||||
plist_from_xml(manifeststr, (uint32_t) strlen(manifeststr), &buildmanifest);
|
||||
|
||||
if (plist_t identity = getBuildidentityWithBoardconfig(buildmanifest._p, boardConfig, isUpdateInstall))
|
||||
if (plist_t manifest = plist_dict_get_item(identity, "Manifest"))
|
||||
if (plist_t elem = plist_dict_get_item(manifest, element))
|
||||
if (plist_t path = plist_dict_get_item(elem, "Digest"))
|
||||
if (plist_get_data_val(path, &digestStr, &size), digestStr)
|
||||
goto noerror;
|
||||
|
||||
return nullptr;
|
||||
noerror:
|
||||
return (unsigned char *)digestStr;
|
||||
}
|
||||
|
||||
bool
|
||||
futurerestore::elemExists(const char *element, const char *manifeststr, const char *boardConfig, int isUpdateInstall) {
|
||||
char *pathStr = nullptr;
|
||||
|
|
|
@ -63,7 +63,8 @@ class futurerestore {
|
|||
bool _setNonce = false;
|
||||
bool _serial = false;
|
||||
bool _noRestore = false;
|
||||
|
||||
bool _noRSEP = false;
|
||||
|
||||
char *_firmwareJson = nullptr;
|
||||
char *_betaFirmwareJson = nullptr;
|
||||
jssytok_t *_firmwareTokens = nullptr;;
|
||||
|
@ -75,9 +76,12 @@ class futurerestore {
|
|||
bool _useCustomLatestBeta = false;
|
||||
std::string _customLatest;
|
||||
std::string _customLatestBuildID;
|
||||
const char *_model = nullptr;
|
||||
const char *_board = nullptr;
|
||||
|
||||
plist_t _sepbuildmanifest = nullptr;
|
||||
plist_t _basebandbuildmanifest = nullptr;
|
||||
plist_t _buildidentity = nullptr;
|
||||
|
||||
std::string _ramdiskPath;
|
||||
std::string _kernelPath;
|
||||
|
@ -98,7 +102,7 @@ class futurerestore {
|
|||
void enterPwnRecovery(plist_t build_identity, std::string bootargs);
|
||||
|
||||
public:
|
||||
futurerestore(bool isUpdateInstall = false, bool isPwnDfu = false, bool noIBSS = false, bool setNonce = false, bool serial = false, bool noRestore = false);
|
||||
futurerestore(bool isUpdateInstall = false, bool isPwnDfu = false, bool noIBSS = false, bool setNonce = false, bool serial = false, bool noRestore = false, bool noRSEP = false);
|
||||
bool init();
|
||||
int getDeviceMode(bool reRequest);
|
||||
uint64_t getDeviceEcid();
|
||||
|
@ -138,6 +142,7 @@ public:
|
|||
void loadKernel(std::string kernelPath);
|
||||
void loadSep(std::string sepPath);
|
||||
void loadBaseband(std::string basebandPath);
|
||||
unsigned char *getSHA(const std::string& filePath, int type = 0);
|
||||
|
||||
void setCustomLatest(std::string version){_customLatest = version; _useCustomLatest = true;}
|
||||
void setCustomLatestBuildID(std::string version, bool beta){_customLatestBuildID = version; _useCustomLatest = false; _useCustomLatestBuildID = true; _useCustomLatestBeta = beta;}
|
||||
|
@ -171,8 +176,10 @@ public:
|
|||
static plist_t loadPlistFromFile(const char *path);
|
||||
static void saveStringToFile(std::string str, std::string path);
|
||||
static char *getPathOfElementInManifest(const char *element, const char *manifeststr, const char *boardConfig, int isUpdateInstall);
|
||||
static unsigned char *getDigestOfElementInManifest(const char *element, const char *manifeststr, const char *boardConfig, int isUpdateInstall);
|
||||
static bool elemExists(const char *element, const char *manifeststr, const char *boardConfig, int isUpdateInstall);
|
||||
static std::string getGeneratorFromSHSH2(plist_t shsh2);
|
||||
|
||||
};
|
||||
|
||||
#endif /* futurerestore_hpp */
|
||||
|
|
38
src/main.cpp
38
src/main.cpp
|
@ -44,6 +44,7 @@ static struct option longopts[] = {
|
|||
{ "no-restore", no_argument, nullptr, 'z' },
|
||||
{ "latest-baseband", no_argument, nullptr, '1' },
|
||||
{ "no-baseband", no_argument, nullptr, '2' },
|
||||
{ "no-rsep", no_argument, nullptr, 'j' },
|
||||
#ifdef HAVE_LIBIPATCHER
|
||||
{ "use-pwndfu", no_argument, nullptr, '3' },
|
||||
{ "no-ibss", no_argument, nullptr, '4' },
|
||||
|
@ -76,6 +77,7 @@ static struct option longopts[] = {
|
|||
#define FLAG_CUSTOM_LATEST 1 << 15
|
||||
#define FLAG_CUSTOM_LATEST_BUILDID 1 << 16
|
||||
#define FLAG_CUSTOM_LATEST_BETA 1 << 17
|
||||
#define FLAG_NO_RSEP_FR 1 << 18
|
||||
|
||||
void cmd_help(){
|
||||
printf("Usage: futurerestore [OPTIONS] iPSW\n");
|
||||
|
@ -111,6 +113,7 @@ void cmd_help(){
|
|||
printf(" --latest-sep\t\t\tUse latest signed SEP instead of manually specifying one\n");
|
||||
printf(" -s, --sep PATH\t\t\tSEP to be flashed\n");
|
||||
printf(" -m, --sep-manifest PATH\t\tBuildManifest for requesting SEP ticket\n");
|
||||
printf(" -j, --no-rsep\t\tChoose not to send Restore Mode SEP\n");
|
||||
|
||||
printf("\nOptions for baseband:\n");
|
||||
printf(" --latest-baseband\t\t\tUse latest signed baseband instead of manually specifying one\n");
|
||||
|
@ -167,7 +170,7 @@ int main_r(int argc, const char * argv[]) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:c:g:hiwude0z123456789af", longopts, &optindex)) > 0) {
|
||||
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:c:g:hiwude0z123456789afj", longopts, &optindex)) > 0) {
|
||||
switch (opt) {
|
||||
case 'h': // long option: "help"; can be called as short option
|
||||
cmd_help();
|
||||
|
@ -214,6 +217,9 @@ int main_r(int argc, const char * argv[]) {
|
|||
case '2': // long option: "no-baseband";
|
||||
flags |= FLAG_NO_BASEBAND;
|
||||
break;
|
||||
case 'j': // long option: "no-rsep";
|
||||
flags |= FLAG_NO_RSEP_FR;
|
||||
break;
|
||||
#ifdef HAVE_LIBIPATCHER
|
||||
case '3': // long option: "use-pwndfu";
|
||||
flags |= FLAG_IS_PWN_DFU;
|
||||
|
@ -286,7 +292,7 @@ int main_r(int argc, const char * argv[]) {
|
|||
return -5;
|
||||
}
|
||||
|
||||
futurerestore client(flags & FLAG_UPDATE, flags & FLAG_IS_PWN_DFU, flags & FLAG_NO_IBSS, flags & FLAG_SET_NONCE, flags & FLAG_SERIAL, flags & FLAG_NO_RESTORE_FR);
|
||||
futurerestore client(flags & FLAG_UPDATE, flags & FLAG_IS_PWN_DFU, flags & FLAG_NO_IBSS, flags & FLAG_SET_NONCE, flags & FLAG_SERIAL, flags & FLAG_NO_RESTORE_FR, flags & FLAG_NO_RSEP_FR);
|
||||
retassure(client.init(),"can't init, no device found\n");
|
||||
|
||||
printf("futurerestore init done\n");
|
||||
|
@ -384,7 +390,7 @@ int main_r(int argc, const char * argv[]) {
|
|||
}
|
||||
|
||||
if (flags & FLAG_LATEST_SEP){
|
||||
info("user specified to use latest signed SEP\n");
|
||||
info("User specified to use latest signed SEP\n");
|
||||
client.downloadLatestSep();
|
||||
}else if (!client.is32bit()){
|
||||
client.setSepPath(sepPath);
|
||||
|
@ -394,38 +400,44 @@ int main_r(int argc, const char * argv[]) {
|
|||
}
|
||||
|
||||
versVals.basebandMode = kBasebandModeWithoutBaseband;
|
||||
if (!client.is32bit() && !(isManifestSignedForDevice(client.getSepManifestPath().c_str(), &devVals, &versVals, nullptr))){
|
||||
info("Checking if SEP is being signed...\n");
|
||||
if (!client.is32bit() && !(isManifestSignedForDevice(client.getSepManifestPath().c_str(), &devVals, &versVals, nullptr))) {
|
||||
reterror("SEP firmware is NOT being signed!\n");
|
||||
} else {
|
||||
info("SEP is being signed!\n");
|
||||
}
|
||||
if (flags & FLAG_NO_BASEBAND){
|
||||
printf("\nWARNING: user specified is not to flash a baseband. This can make the restore fail if the device needs a baseband!\n");
|
||||
printf("if you added this flag by mistake, you can press CTRL-C now to cancel\n");
|
||||
info("\nWARNING: user specified is not to flash a baseband. This can make the restore fail if the device needs a baseband!\n");
|
||||
info("\nIf you added this flag by mistake, you can press CTRL-C now to cancel\n");
|
||||
int c = 10;
|
||||
printf("continuing restore in ");
|
||||
info("Continuing restore in ");
|
||||
while (c) {
|
||||
printf("%d ",c--);
|
||||
info("%d ",c--);
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
}
|
||||
printf("\n");
|
||||
info("");
|
||||
}else{
|
||||
if (flags & FLAG_LATEST_BASEBAND){
|
||||
info("user specified to use latest signed baseband\n");
|
||||
info("User specified to use latest signed baseband\n");
|
||||
client.downloadLatestBaseband();
|
||||
}else{
|
||||
client.setBasebandPath(basebandPath);
|
||||
client.setBasebandManifestPath(basebandManifestPath);
|
||||
client.loadBaseband(basebandPath);
|
||||
client.loadBasebandManifest(basebandManifestPath);
|
||||
printf("Did set SEP+baseband path and firmware\n");
|
||||
info("Did set SEP and baseband path and firmware\n");
|
||||
}
|
||||
|
||||
versVals.basebandMode = kBasebandModeOnlyBaseband;
|
||||
if (!(devVals.bbgcid = client.getBasebandGoldCertIDFromDevice())){
|
||||
printf("[WARNING] using tsschecker's fallback to get BasebandGoldCertID. This might result in invalid baseband signing status information\n");
|
||||
debug("[WARNING] using tsschecker's fallback to get BasebandGoldCertID. This might result in invalid baseband signing status information\n");
|
||||
}
|
||||
info("Checking if Baseband is being signed...\n");
|
||||
if (!(isManifestSignedForDevice(client.getBasebandManifestPath().c_str(), &devVals, &versVals, nullptr))) {
|
||||
reterror("baseband firmware is NOT being signed!\n");
|
||||
reterror("Baseband firmware is NOT being signed!\n");
|
||||
} else {
|
||||
info("Baseband is being signed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue