Minor code refactor

* Fixes #103
 * Fixes #98
This commit is contained in:
Cryptiiiic 2022-10-07 18:38:24 -07:00
parent 40b254b582
commit 2160321938
No known key found for this signature in database
GPG key ID: 6027B509EFE3A76B
11 changed files with 183 additions and 39 deletions

View file

@ -23,6 +23,14 @@ jobs:
/Users/runner/work/futurerestore/futurerestore/.github/workflows/mac-bootstrap.sh
/Users/runner/work/futurerestore/futurerestore/.github/workflows/mac-build.sh
/Users/runner/work/futurerestore/futurerestore/.github/workflows/mac-post.sh
- name: Versioning
id: Versioning
uses: actions/upload-artifact@v2
with:
name: Versioning
path: |
/Users/runner/work/futurerestore/futurerestore/latest_build_sha.txt
/Users/runner/work/futurerestore/futurerestore/latest_build_num.txt
- name: macOS RELEASE Archive
id: macOS-RELEASE-Archive
uses: actions/upload-artifact@v2

View file

@ -32,4 +32,6 @@ make -j4 -l4 -C cmake-build-asan-arm64
llvm-strip -s cmake-build-release-x86_64/src/futurerestore
codesign --deep --force --sign - cmake-build-release-x86_64/src/futurerestore
llvm-strip -s cmake-build-release-arm64/src/futurerestore
codesign --deep --force --sign - cmake-build-release-arm64/src/futurerestore

View file

@ -7,12 +7,18 @@ export BASE=/Users/runner/work/futurerestore/futurerestore/
cd ${BASE}
export FUTURERESTORE_VERSION=$(git rev-list --count HEAD | tr -d '\n')
export FUTURERESTORE_VERSION_SHA=$(git rev-parse HEAD | tr -d '\n')
export FUTURERESTORE_VERSION_RELEASE=$(cat version.txt | tr -d '\n')
echo -n $FUTURERESTORE_VERSION_SHA > latest_build_sha.txt
echo -n $FUTURERESTORE_VERSION > latest_build_num.txt
lipo -create -arch x86_64 cmake-build-release-x86_64/src/futurerestore -arch arm64 cmake-build-release-arm64/src/futurerestore -output futurerestore
codesign --deep --force --sign - futurerestore
tar cpPJf "futurerestore-macOS-${FUTURERESTORE_VERSION_RELEASE}-Build_${FUTURERESTORE_VERSION}-RELEASE.tar.xz" futurerestore
rm -rf futurerestore
lipo -create -arch x86_64 cmake-build-debug-x86_64/src/futurerestore -arch arm64 cmake-build-debug-arm64/src/futurerestore -output futurerestore
codesign --deep --force --sign - futurerestore
tar cpPJf "futurerestore-macOS-${FUTURERESTORE_VERSION_RELEASE}-Build_${FUTURERESTORE_VERSION}-DEBUG.tar.xz" futurerestore
rm -rf futurerestore
lipo -create -arch x86_64 cmake-build-asan-x86_64/src/futurerestore -arch arm64 cmake-build-asan-arm64/src/futurerestore -output futurerestore
codesign --deep --force --sign - futurerestore
tar cpPJf "futurerestore-macOS-${FUTURERESTORE_VERSION_RELEASE}-Build_${FUTURERESTORE_VERSION}-ASAN.tar.xz" futurerestore

3
.gitignore vendored
View file

@ -69,3 +69,6 @@ xcuserdata
*.zst
*.shsh2
*.shsh
.cmake
Testing
*.cbp

View file

@ -31,7 +31,7 @@ if("${CMAKE_HOST_SYSTEM_NAME}" MATCHES "Darwin")
set(ARCH "${CMAKE_SYSTEM_PROCESSOR}")
endif()
endif()
if(NOT DEFINED MINVER OR NOT DEFINED "$ENV{MINVER}" AND DEFINED NO_PKGCFG AND "$ENV{NO_PKGCFG}" MATCHES "1")
if((NOT DEFINED MINVER OR NOT DEFINED "$ENV{MINVER}") AND (DEFINED NO_PKGCFG OR "$ENV{NO_PKGCFG}" MATCHES "1"))
if("${ARCH}" STREQUAL "x86_64" OR "$ENV{ARCH}" STREQUAL "x86_64")
set(MINVER -mmacosx-version-min=10.12)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12)

View file

@ -44,26 +44,29 @@ Usage: `futurerestore [OPTIONS] iPSW`
| ` -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 |
| ` -3 ` | ` --use-pwndfu ` | Restoring devices with Odysseus method. Device needs to be in pwned DFU mode already |
| ` -4 ` | ` --no-ibss ` | Restoring devices with Odysseus method. For checkm8/iPwnder32 specifically, bootrom needs to be patched already with unless iPwnder. |
| ` -5 ` | ` --rdsk PATH ` | Set custom restore ramdisk for entering restoremode(requires use-pwndfu) |
| ` -6 ` | ` --rkrn PATH ` | Set custom restore kernelcache for entering restoremode(requires use-pwndfu) |
| ` -7 ` | ` --set-nonce ` | Set custom nonce from your blob then exit recovery(requires use-pwndfu) |
| ` -7 ` | ` --set-nonce=0xNONCE ` | Set custom nonce then exit recovery(requires use-pwndfu) |
| ` -8 ` | ` --serial ` | Enable serial during boot(requires serial cable and use-pwndfu) |
| ` -9 ` | ` --boot-args "BOOTARGS" ` | Set custom restore boot-args(PROCEED WITH CAUTION)(requires use-pwndfu) |
| ` -a ` | ` --no-cache ` | Disable cached patched iBSS/iBEC(requires use-pwndfu) |
| ` -f ` | ` --skip-blob ` | Skip SHSH blob validation(PROCEED WITH CAUTION)(requires use-pwndfu) |
| ` -0 ` | ` --latest-sep ` | Use latest signed SEP instead of manually specifying one |
| ` -j ` | ` --no-rsep ` | Choose not to send Restore Mode SEP firmware command |
| ` -1 ` | ` --latest-baseband ` | Use latest signed baseband instead of manually specifying one |
| ` -2 ` | ` --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) |
Deprecated/Legacy Options:
| option (short) | option (long) | description |
|----------------|-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| ` -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) |
---
# 1) Prometheus (64-bit device) - APNonce recreation with generator method

@ -1 +1 @@
Subproject commit 97ab482cf251b83e71887f9cd7a8f1d9e066e671
Subproject commit 46039a322f595e60a9c089a25f302fc80238e8c8

2
external/tsschecker vendored

@ -1 +1 @@
Subproject commit 6e55c67ec78df55b8185c17ea2f79f838d0c034b
Subproject commit ad4c0d92f42e2cd2e90efdb38ed7fc11dd356656

View file

@ -77,7 +77,7 @@ void safe_mkdir(const char *path, int mode) {
seteuid(newID);
setegid(newID);
}
mkdir(path, mode);
__mkdir(path, mode);
if(newID > -1) {
setuid(id);
setgid(id1);
@ -140,10 +140,29 @@ futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu, bool noIBSS, b
_setNonce(setNonce), _serial(serial), _noRestore(noRestore), _noRSEP(noRSEP) {
_client = idevicerestore_client_new();
retassure(_client != nullptr, "Could not create idevicerestore client\n");
struct stat st{0};
char *tmpdir = std::getenv("TMPDIR");
if(tmpdir != nullptr ) {
std::string TMPDIR(tmpdir);
if(!TMPDIR.empty() && stat(tmpdir, &st) > -1) {
futurerestoreTempPath = TMPDIR +"/futurerestore";
roseTempPath = futurerestoreTempPath + "/rose.bin";
seTempPath = futurerestoreTempPath + "/se.sefw";
veridianDGMTempPath = futurerestoreTempPath + "/veridianDGM.der";
veridianFWMTempPath = futurerestoreTempPath + "/veridianFWM.plist";
basebandTempPath = futurerestoreTempPath + "/baseband.bbfw";
basebandManifestTempPath = futurerestoreTempPath + "/basebandManifest.plist";
sepTempPath = futurerestoreTempPath + "/sep.im4p";
sepManifestTempPath = futurerestoreTempPath + "/sepManifest.plist";
}
}
if (stat(futurerestoreTempPath.c_str(), &st) == -1) safe_mkdir(futurerestoreTempPath.c_str(), 0755);
// TODO: implement windows CI and enable update check
#ifndef WIN32
this->checkForUpdates();
#endif
nocache = 1; //tsschecker nocache
_foundnonce = -1;
_useCustomLatest = false;
@ -2363,3 +2382,76 @@ std::string futurerestore::getGeneratorFromSHSH2(plist_t shsh2) {
return {genstr};
}
// TODO: implement windows CI and enable update check
#ifndef WIN32
void futurerestore::checkForUpdates() {
info("Checking for updates...\n\n");
std::string num = futurerestoreTempPath + "/latest_build_num.txt";
std::string sha = futurerestoreTempPath + "/latest_build_sha.txt";
std::string url = "https://nightly.link/futurerestore/futurerestore/workflows/ci/main/Versioning.zip";
bool fail = false;
if(downloadPartialzip(url.c_str(), "latest_build_num.txt", num.c_str())) {
fail = true;
}
if(downloadPartialzip(url.c_str(), "latest_build_sha.txt", sha.c_str())) {
fail = true;
}
struct stat st{0};
if(fail || stat(num.c_str(), &st) == -1 || stat(sha.c_str(), &st) == -1) {
info("ERROR: failed to check for futurerestore updates! continuing...\n");
return;
}
char *num_data = nullptr;
size_t num_size = 0;
std::ifstream numFileStream(num, std::ios::binary | std::ios::in | std::ios::ate);
retassure(numFileStream.good(), "%s: failed init file stream for %s!\n", __func__, num.c_str());
num_size = numFileStream.tellg();
numFileStream.seekg(0, std::ios_base::beg);
std::allocator<uint8_t> alloc;
retassure(num_data = (char *)alloc.allocate(num_size),
"%s: failed to allocate memory for %s\n", __func__, num.c_str());
numFileStream.read(reinterpret_cast<char*>(num_data),
num_size);
retassure(numFileStream.good(), "%s: failed to read file stream for %s!\n", __func__, num.c_str());
retassure(*(uint64_t *) (num_data) != 0,
"%s: failed to load num versioning file for %s with the size %zu!\n",
__func__, num.c_str(), num_size);
this->latest_num = std::string(num_data);
char *sha_data = nullptr;
size_t sha_size = 0;
std::ifstream shaFileStream(sha, std::ios::binary | std::ios::in | std::ios::ate);
retassure(shaFileStream.good(), "%s: failed init file stream for %s!\n", __func__, sha.c_str());
sha_size = shaFileStream.tellg();
shaFileStream.seekg(0, std::ios_base::beg);
retassure(sha_data = (char *)alloc.allocate(sha_size),
"%s: failed to allocate memory for %s\n", __func__, sha.c_str());
shaFileStream.read(reinterpret_cast<char*>(sha_data),
sha_size);
retassure(shaFileStream.good(), "%s: failed to read file stream for %s!\n", __func__, sha.c_str());
retassure(*(uint64_t *) (sha_data) != 0,
"%s: failed to load sha versioning file for %s with the size %zu!\n",
__func__, sha.c_str(), sha_size);
this->latest_sha = std::string(sha_data);
if(this->latest_num.empty() || this->latest_sha.empty()) {
info("ERROR: failed to check for futurerestore updates! continuing...\n");
return;
}
bool updated = false;
if(std::equal(this->current_sha.begin(), this->current_sha.end(), this->latest_sha.begin())) {
updated = true;
} else {
if(std::stoi(this->current_num) < std::stoi(this->latest_num)) {
info("Error: Futurerestore is outdated! Please download the latest futurerestore! exitting...\n");
exit(-1);
} else {
updated = true;
}
}
if(updated) {
info("Futurerestore is up to date!\n");
}
}
#endif

View file

@ -88,6 +88,15 @@ class futurerestore {
std::string _basebandPath;
std::string _basebandManifestPath;
// TODO: implement windows CI and enable update check
#ifndef WIN32
std::string latest_num;
std::string latest_sha;
std::string current_num = VERSION_COMMIT_COUNT;
std::string current_sha = VERSION_COMMIT_SHA;
#endif
const char *_custom_nonce = nullptr;
const char *_boot_args = nullptr;
@ -122,6 +131,11 @@ public:
char *getLatestFirmwareUrl();
std::string getSepManifestPath(){return _sepManifestPath;}
std::string getBasebandManifestPath(){return _basebandManifestPath;}
// TODO: implement windows CI and enable update check
#ifndef WIN32
void checkForUpdates();
#endif
void downloadLatestRose();
void downloadLatestSE();
void downloadLatestSavage();

View file

@ -79,6 +79,8 @@ static struct option longopts[] = {
#define FLAG_CUSTOM_LATEST_BETA 1 << 17
#define FLAG_NO_RSEP_FR 1 << 18
bool manual = false;
void cmd_help(){
printf("Usage: futurerestore [OPTIONS] iPSW\n");
printf("Allows restoring to non-matching firmware with custom SEP+baseband\n");
@ -97,29 +99,33 @@ void cmd_help(){
#ifdef HAVE_LIBIPATCHER
printf("\nOptions for downgrading with Odysseus:\n");
printf(" --use-pwndfu\t\t\tRestoring devices with Odysseus method. Device needs to be in pwned DFU mode already\n");
printf(" --no-ibss\t\t\t\tRestoring devices with Odysseus method. For checkm8/iPwnder32 specifically, bootrom needs to be patched already with unless iPwnder.\n");
printf(" --rdsk PATH\t\t\tSet custom restore ramdisk for entering restoremode(requires use-pwndfu)\n");
printf(" --rkrn PATH\t\t\tSet custom restore kernelcache for entering restoremode(requires use-pwndfu)\n");
printf(" --set-nonce\t\t\tSet custom nonce from your blob then exit recovery(requires use-pwndfu)\n");
printf(" --set-nonce=0xNONCE\t\tSet custom nonce then exit recovery(requires use-pwndfu)\n");
printf(" --serial\t\t\t\tEnable serial during boot(requires serial cable and use-pwndfu)\n");
printf(" --boot-args\t\t\tSet custom restore boot-args(PROCEED WITH CAUTION)(requires use-pwndfu)\n");
printf(" --no-cache\t\t\tDisable cached patched iBSS/iBEC(requires use-pwndfu)\n");
printf(" --skip-blob\t\t\tSkip SHSH blob validation(PROCEED WITH CAUTION)(requires use-pwndfu)\n");
printf(" -3, --use-pwndfu\t\t\tRestoring devices with Odysseus method. Device needs to be in pwned DFU mode already\n");
printf(" -4, --no-ibss\t\t\t\tRestoring devices with Odysseus method. For checkm8/iPwnder32 specifically, bootrom needs to be patched already with unless iPwnder.\n");
printf(" -5, --rdsk PATH\t\t\tSet custom restore ramdisk for entering restoremode(requires use-pwndfu)\n");
printf(" -6, --rkrn PATH\t\t\tSet custom restore kernelcache for entering restoremode(requires use-pwndfu)\n");
printf(" -7, --set-nonce\t\t\tSet custom nonce from your blob then exit recovery(requires use-pwndfu)\n");
printf(" -7, --set-nonce=0xNONCE\t\tSet custom nonce then exit recovery(requires use-pwndfu)\n");
printf(" -8, --serial\t\t\t\tEnable serial during boot(requires serial cable and use-pwndfu)\n");
printf(" -9, --boot-args\t\t\tSet custom restore boot-args(PROCEED WITH CAUTION)(requires use-pwndfu)\n");
printf(" -a, --no-cache\t\t\tDisable cached patched iBSS/iBEC(requires use-pwndfu)\n");
printf(" -f, --skip-blob\t\t\tSkip SHSH blob validation(PROCEED WITH CAUTION)(requires use-pwndfu)\n");
#endif
printf("\nOptions for SEP:\n");
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(" -0, --latest-sep\t\t\tUse latest signed SEP instead of manually specifying one\n");
if(manual) {
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\t\t\tChoose not to send Restore Mode SEP firmware command\n");
printf("\nOptions for baseband:\n");
printf(" --latest-baseband\t\t\tUse latest signed baseband instead of manually specifying one\n");
printf(" -b, --baseband PATH\t\t\tBaseband to be flashed\n");
printf(" -p, --baseband-manifest PATH\t\tBuildManifest for requesting baseband ticket\n");
printf(" --no-baseband\t\t\tSkip checks and don't flash baseband\n");
printf(" -1, --latest-baseband\t\t\tUse latest signed baseband instead of manually specifying one\n");
if(manual) {
printf(" -b, --baseband PATH\t\t\tBaseband to be flashed\n");
printf(" -p, --baseband-manifest PATH\t\tBuildManifest for requesting baseband ticket\n");
}
printf(" -2, --no-baseband\t\t\tSkip checks and don't flash baseband\n");
printf(" \t\t\tOnly use this for device without a baseband (eg. iPod touch or some Wi-Fi only iPads)\n\n");
}
@ -165,6 +171,12 @@ int main_r(int argc, const char * argv[]) {
t_devicevals devVals = {nullptr};
t_iosVersion versVals = {nullptr};
char *legacy = std::getenv("FUTURERESTORE_I_SOLEMNLY_SWEAR_THAT_I_AM_UP_TO_NO_GOOD");
manual = legacy != nullptr;
if(manual) {
info("WARNING: User specified to enable Deprecated/Legacy options, at risk of boot loop!\n");
}
if (argc == 1){
cmd_help();
return -1;
@ -180,15 +192,19 @@ int main_r(int argc, const char * argv[]) {
apticketPaths.push_back(optarg);
break;
case 'b': // long option: "baseband"; can be called as short option
retassure(manual, "--baseband is Deprecated!");
basebandPath = optarg;
break;
case 'p': // long option: "baseband-manifest"; can be called as short option
retassure(manual, "--baseband-manifest is Deprecated!");
basebandManifestPath = optarg;
break;
case 's': // long option: "sep"; can be called as short option
retassure(manual, "--sep is Deprecated!");
sepPath = optarg;
break;
case 'm': // long option: "sep-manifest"; can be called as short option
retassure(manual, "--sep-manifest is Deprecated!");
sepManifestPath = optarg;
break;
case 'w': // long option: "wait"; can be called as short option