This commit is contained in:
tihmstar 2016-09-15 14:22:49 +02:00
parent f06be0c339
commit 56aab40cf2
6 changed files with 1030 additions and 5 deletions

9
.gitmodules vendored Normal file
View file

@ -0,0 +1,9 @@
[submodule "external/img4tool"]
path = external/img4tool
url = ssh://git@tihmstar.net:23/img4tool.git
[submodule "external/tsschecker"]
path = external/tsschecker
url = git@github.com:tihmstar/tsschecker.git
[submodule "external/idevicerestore"]
path = external/idevicerestore
url = git@github.com:tihmstar/idevicerestore.git

View file

@ -8,6 +8,39 @@
/* Begin PBXBuildFile section */
878587471D89CFDC008689F0 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 878587461D89CFDC008689F0 /* main.cpp */; };
878587A71D89D56E008689F0 /* libplist.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 878587A61D89D56E008689F0 /* libplist.3.dylib */; };
878587AB1D89D590008689F0 /* libimobiledevice.6.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 878587AA1D89D590008689F0 /* libimobiledevice.6.dylib */; };
878587AD1D89D59E008689F0 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 878587AC1D89D59E008689F0 /* libz.tbd */; };
878587AF1D89D5A5008689F0 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 878587AE1D89D5A5008689F0 /* libcurl.tbd */; };
878587B11D89D5B0008689F0 /* libcrypto.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 878587B01D89D5B0008689F0 /* libcrypto.tbd */; };
878587B31D89D5D5008689F0 /* libzip.4.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 878587B21D89D5D5008689F0 /* libzip.4.dylib */; };
878587B51D89D5E6008689F0 /* libpartialzip-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 878587B41D89D5E6008689F0 /* libpartialzip-1.0.0.dylib */; };
878587B71D89D637008689F0 /* libirecovery.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 878587B61D89D637008689F0 /* libirecovery.2.dylib */; };
8799B0B21D89D99D002F4D5F /* futurerestore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8799B0B01D89D99D002F4D5F /* futurerestore.cpp */; };
8799B0B31D89DAE7002F4D5F /* idevicerestore.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785875C1D89D1C1008689F0 /* idevicerestore.c */; settings = {COMPILER_FLAGS = "-D HAVE_CONFIG_H=1 "; }; };
8799B0B41D89DAF6002F4D5F /* tss.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587761D89D1C1008689F0 /* tss.c */; };
8799B0B51D89DAFF002F4D5F /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587511D89D1C1008689F0 /* common.c */; };
8799B0B61D89DAFF002F4D5F /* dfu.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587531D89D1C1008689F0 /* dfu.c */; };
8799B0B71D89DAFF002F4D5F /* normal.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785876C1D89D1C1008689F0 /* normal.c */; };
8799B0B81D89DAFF002F4D5F /* recovery.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785876E1D89D1C1008689F0 /* recovery.c */; };
8799B0B91D89DB0D002F4D5F /* img3.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785875E1D89D1C1008689F0 /* img3.c */; };
8799B0BB1D89DB12002F4D5F /* download.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587551D89D1C1008689F0 /* download.c */; };
8799B0BC1D89DB27002F4D5F /* ipsw.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587621D89D1C1008689F0 /* ipsw.c */; };
8799B0BD1D89DB27002F4D5F /* limera1n.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587641D89D1C1008689F0 /* limera1n.c */; };
8799B0BE1D89DB27002F4D5F /* restore.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587701D89D1C1008689F0 /* restore.c */; };
8799B0BF1D89DB38002F4D5F /* asr.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785874F1D89D1C1008689F0 /* asr.c */; };
8799B0C01D89DB38002F4D5F /* fdr.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587581D89D1C1008689F0 /* fdr.c */; };
8799B0C11D89DB38002F4D5F /* fls.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785875A1D89D1C1008689F0 /* fls.c */; };
8799B0C21D89DB46002F4D5F /* thread.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587741D89D1C1008689F0 /* thread.c */; };
8799B0C31D89DB4B002F4D5F /* socket.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587721D89D1C1008689F0 /* socket.c */; };
8799B0C41D89DB55002F4D5F /* mbn.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785876A1D89D1C1008689F0 /* mbn.c */; };
8799B0C51D89DB67002F4D5F /* locking.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587671D89D1C1008689F0 /* locking.c */; };
8799B0C81D89E2BD002F4D5F /* img4tool.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587901D89D1ED008689F0 /* img4tool.c */; };
8799B0C91D89E2C3002F4D5F /* img4.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785878E1D89D1ED008689F0 /* img4.c */; };
8799B0CA1D89E371002F4D5F /* img4.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587601D89D1C1008689F0 /* img4.c */; };
8799B0CB1D89F796002F4D5F /* tsschecker.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785879F1D89D2BA008689F0 /* tsschecker.c */; };
8799B0CC1D89F7B9002F4D5F /* download.c in Sources */ = {isa = PBXBuildFile; fileRef = 878587981D89D2BA008689F0 /* download.c */; };
8799B0CD1D89F7B9002F4D5F /* jsmn.c in Sources */ = {isa = PBXBuildFile; fileRef = 8785879A1D89D2BA008689F0 /* jsmn.c */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -25,6 +58,70 @@
/* Begin PBXFileReference section */
878587431D89CFDC008689F0 /* futurerestore */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = futurerestore; sourceTree = BUILT_PRODUCTS_DIR; };
878587461D89CFDC008689F0 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
8785874F1D89D1C1008689F0 /* asr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asr.c; sourceTree = "<group>"; };
878587501D89D1C1008689F0 /* asr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asr.h; sourceTree = "<group>"; };
878587511D89D1C1008689F0 /* common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = common.c; sourceTree = "<group>"; };
878587521D89D1C1008689F0 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
878587531D89D1C1008689F0 /* dfu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dfu.c; sourceTree = "<group>"; };
878587541D89D1C1008689F0 /* dfu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dfu.h; sourceTree = "<group>"; };
878587551D89D1C1008689F0 /* download.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = download.c; sourceTree = "<group>"; };
878587561D89D1C1008689F0 /* download.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = download.h; sourceTree = "<group>"; };
878587571D89D1C1008689F0 /* endianness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = endianness.h; sourceTree = "<group>"; };
878587581D89D1C1008689F0 /* fdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fdr.c; sourceTree = "<group>"; };
878587591D89D1C1008689F0 /* fdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fdr.h; sourceTree = "<group>"; };
8785875A1D89D1C1008689F0 /* fls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fls.c; sourceTree = "<group>"; };
8785875B1D89D1C1008689F0 /* fls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fls.h; sourceTree = "<group>"; };
8785875C1D89D1C1008689F0 /* idevicerestore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = idevicerestore.c; sourceTree = "<group>"; };
8785875D1D89D1C1008689F0 /* idevicerestore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = idevicerestore.h; sourceTree = "<group>"; };
8785875E1D89D1C1008689F0 /* img3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = img3.c; sourceTree = "<group>"; };
8785875F1D89D1C1008689F0 /* img3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = img3.h; sourceTree = "<group>"; };
878587601D89D1C1008689F0 /* img4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = img4.c; sourceTree = "<group>"; };
878587611D89D1C1008689F0 /* img4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = img4.h; sourceTree = "<group>"; };
878587621D89D1C1008689F0 /* ipsw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ipsw.c; sourceTree = "<group>"; };
878587631D89D1C1008689F0 /* ipsw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipsw.h; sourceTree = "<group>"; };
878587641D89D1C1008689F0 /* limera1n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = limera1n.c; sourceTree = "<group>"; };
878587651D89D1C1008689F0 /* limera1n.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = limera1n.h; sourceTree = "<group>"; };
878587661D89D1C1008689F0 /* limera1n_payload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = limera1n_payload.h; sourceTree = "<group>"; };
878587671D89D1C1008689F0 /* locking.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locking.c; sourceTree = "<group>"; };
878587681D89D1C1008689F0 /* locking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = locking.h; sourceTree = "<group>"; };
8785876A1D89D1C1008689F0 /* mbn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mbn.c; sourceTree = "<group>"; };
8785876B1D89D1C1008689F0 /* mbn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mbn.h; sourceTree = "<group>"; };
8785876C1D89D1C1008689F0 /* normal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = normal.c; sourceTree = "<group>"; };
8785876D1D89D1C1008689F0 /* normal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = normal.h; sourceTree = "<group>"; };
8785876E1D89D1C1008689F0 /* recovery.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = recovery.c; sourceTree = "<group>"; };
8785876F1D89D1C1008689F0 /* recovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = recovery.h; sourceTree = "<group>"; };
878587701D89D1C1008689F0 /* restore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = restore.c; sourceTree = "<group>"; };
878587711D89D1C1008689F0 /* restore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = restore.h; sourceTree = "<group>"; };
878587721D89D1C1008689F0 /* socket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = socket.c; sourceTree = "<group>"; };
878587731D89D1C1008689F0 /* socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socket.h; sourceTree = "<group>"; };
878587741D89D1C1008689F0 /* thread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = thread.c; sourceTree = "<group>"; };
878587751D89D1C1008689F0 /* thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thread.h; sourceTree = "<group>"; };
878587761D89D1C1008689F0 /* tss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tss.c; sourceTree = "<group>"; };
878587771D89D1C1008689F0 /* tss.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tss.h; sourceTree = "<group>"; };
8785878C1D89D1ED008689F0 /* all_img4tool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = all_img4tool.h; sourceTree = "<group>"; };
8785878E1D89D1ED008689F0 /* img4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = img4.c; sourceTree = "<group>"; };
8785878F1D89D1ED008689F0 /* img4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = img4.h; sourceTree = "<group>"; };
878587901D89D1ED008689F0 /* img4tool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = img4tool.c; sourceTree = "<group>"; };
878587941D89D243008689F0 /* img4tool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = img4tool.h; sourceTree = "<group>"; };
878587951D89D290008689F0 /* config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
878587971D89D2BA008689F0 /* all_tsschecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = all_tsschecker.h; sourceTree = "<group>"; };
878587981D89D2BA008689F0 /* download.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = download.c; sourceTree = "<group>"; };
878587991D89D2BA008689F0 /* download.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = download.h; sourceTree = "<group>"; };
8785879A1D89D2BA008689F0 /* jsmn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jsmn.c; sourceTree = "<group>"; };
8785879B1D89D2BA008689F0 /* jsmn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jsmn.h; sourceTree = "<group>"; };
8785879F1D89D2BA008689F0 /* tsschecker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tsschecker.c; sourceTree = "<group>"; };
878587A01D89D2BA008689F0 /* tsschecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tsschecker.h; sourceTree = "<group>"; };
878587A61D89D56E008689F0 /* libplist.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libplist.3.dylib; path = ../../../../usr/local/lib/libplist.3.dylib; sourceTree = "<group>"; };
878587A81D89D578008689F0 /* libirecovery.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libirecovery.1.dylib; path = ../../../../usr/local/lib/libirecovery.1.dylib; sourceTree = "<group>"; };
878587AA1D89D590008689F0 /* libimobiledevice.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libimobiledevice.6.dylib; path = ../../../../usr/local/lib/libimobiledevice.6.dylib; sourceTree = "<group>"; };
878587AC1D89D59E008689F0 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
878587AE1D89D5A5008689F0 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; };
878587B01D89D5B0008689F0 /* libcrypto.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcrypto.tbd; path = usr/lib/libcrypto.tbd; sourceTree = SDKROOT; };
878587B21D89D5D5008689F0 /* libzip.4.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libzip.4.dylib; path = ../../../../usr/local/lib/libzip.4.dylib; sourceTree = "<group>"; };
878587B41D89D5E6008689F0 /* libpartialzip-1.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libpartialzip-1.0.0.dylib"; path = "../../../../usr/local/lib/libpartialzip-1.0.0.dylib"; sourceTree = "<group>"; };
878587B61D89D637008689F0 /* libirecovery.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libirecovery.2.dylib; path = ../../../../usr/local/lib/libirecovery.2.dylib; 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>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -32,6 +129,14 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
878587B71D89D637008689F0 /* libirecovery.2.dylib in Frameworks */,
878587B51D89D5E6008689F0 /* libpartialzip-1.0.0.dylib in Frameworks */,
878587B31D89D5D5008689F0 /* libzip.4.dylib in Frameworks */,
878587B11D89D5B0008689F0 /* libcrypto.tbd in Frameworks */,
878587AF1D89D5A5008689F0 /* libcurl.tbd in Frameworks */,
878587AD1D89D59E008689F0 /* libz.tbd in Frameworks */,
878587AB1D89D590008689F0 /* libimobiledevice.6.dylib in Frameworks */,
878587A71D89D56E008689F0 /* libplist.3.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -41,6 +146,15 @@
8785873A1D89CFDC008689F0 = {
isa = PBXGroup;
children = (
878587B61D89D637008689F0 /* libirecovery.2.dylib */,
878587B41D89D5E6008689F0 /* libpartialzip-1.0.0.dylib */,
878587B21D89D5D5008689F0 /* libzip.4.dylib */,
878587B01D89D5B0008689F0 /* libcrypto.tbd */,
878587AE1D89D5A5008689F0 /* libcurl.tbd */,
878587AC1D89D59E008689F0 /* libz.tbd */,
878587AA1D89D590008689F0 /* libimobiledevice.6.dylib */,
878587A81D89D578008689F0 /* libirecovery.1.dylib */,
878587A61D89D56E008689F0 /* libplist.3.dylib */,
878587451D89CFDC008689F0 /* futurerestore */,
878587441D89CFDC008689F0 /* Products */,
);
@ -57,11 +171,101 @@
878587451D89CFDC008689F0 /* futurerestore */ = {
isa = PBXGroup;
children = (
878587951D89D290008689F0 /* config.h */,
8785874D1D89D1A4008689F0 /* external */,
8799B0B11D89D99D002F4D5F /* futurerestore.hpp */,
8799B0B01D89D99D002F4D5F /* futurerestore.cpp */,
878587461D89CFDC008689F0 /* main.cpp */,
);
path = futurerestore;
sourceTree = "<group>";
};
8785874D1D89D1A4008689F0 /* external */ = {
isa = PBXGroup;
children = (
878587961D89D2BA008689F0 /* tsschecker */,
8785878B1D89D1ED008689F0 /* img4tool */,
8785874E1D89D1C1008689F0 /* idevicerestore */,
);
name = external;
sourceTree = "<group>";
};
8785874E1D89D1C1008689F0 /* idevicerestore */ = {
isa = PBXGroup;
children = (
8785874F1D89D1C1008689F0 /* asr.c */,
878587501D89D1C1008689F0 /* asr.h */,
878587511D89D1C1008689F0 /* common.c */,
878587521D89D1C1008689F0 /* common.h */,
878587531D89D1C1008689F0 /* dfu.c */,
878587541D89D1C1008689F0 /* dfu.h */,
878587551D89D1C1008689F0 /* download.c */,
878587561D89D1C1008689F0 /* download.h */,
878587571D89D1C1008689F0 /* endianness.h */,
878587581D89D1C1008689F0 /* fdr.c */,
878587591D89D1C1008689F0 /* fdr.h */,
8785875A1D89D1C1008689F0 /* fls.c */,
8785875B1D89D1C1008689F0 /* fls.h */,
8785875C1D89D1C1008689F0 /* idevicerestore.c */,
8785875D1D89D1C1008689F0 /* idevicerestore.h */,
8785875E1D89D1C1008689F0 /* img3.c */,
8785875F1D89D1C1008689F0 /* img3.h */,
878587601D89D1C1008689F0 /* img4.c */,
878587611D89D1C1008689F0 /* img4.h */,
878587621D89D1C1008689F0 /* ipsw.c */,
878587631D89D1C1008689F0 /* ipsw.h */,
878587641D89D1C1008689F0 /* limera1n.c */,
878587651D89D1C1008689F0 /* limera1n.h */,
878587661D89D1C1008689F0 /* limera1n_payload.h */,
878587671D89D1C1008689F0 /* locking.c */,
878587681D89D1C1008689F0 /* locking.h */,
8785876A1D89D1C1008689F0 /* mbn.c */,
8785876B1D89D1C1008689F0 /* mbn.h */,
8785876C1D89D1C1008689F0 /* normal.c */,
8785876D1D89D1C1008689F0 /* normal.h */,
8785876E1D89D1C1008689F0 /* recovery.c */,
8785876F1D89D1C1008689F0 /* recovery.h */,
878587701D89D1C1008689F0 /* restore.c */,
878587711D89D1C1008689F0 /* restore.h */,
878587721D89D1C1008689F0 /* socket.c */,
878587731D89D1C1008689F0 /* socket.h */,
878587741D89D1C1008689F0 /* thread.c */,
878587751D89D1C1008689F0 /* thread.h */,
878587761D89D1C1008689F0 /* tss.c */,
878587771D89D1C1008689F0 /* tss.h */,
);
name = idevicerestore;
path = external/idevicerestore/src;
sourceTree = SOURCE_ROOT;
};
8785878B1D89D1ED008689F0 /* img4tool */ = {
isa = PBXGroup;
children = (
8785878C1D89D1ED008689F0 /* all_img4tool.h */,
8785878F1D89D1ED008689F0 /* img4.h */,
8785878E1D89D1ED008689F0 /* img4.c */,
878587941D89D243008689F0 /* img4tool.h */,
878587901D89D1ED008689F0 /* img4tool.c */,
);
name = img4tool;
path = external/img4tool/img4tool;
sourceTree = SOURCE_ROOT;
};
878587961D89D2BA008689F0 /* tsschecker */ = {
isa = PBXGroup;
children = (
878587971D89D2BA008689F0 /* all_tsschecker.h */,
878587991D89D2BA008689F0 /* download.h */,
878587981D89D2BA008689F0 /* download.c */,
8785879B1D89D2BA008689F0 /* jsmn.h */,
8785879A1D89D2BA008689F0 /* jsmn.c */,
878587A01D89D2BA008689F0 /* tsschecker.h */,
8785879F1D89D2BA008689F0 /* tsschecker.c */,
);
name = tsschecker;
path = external/tsschecker/tsschecker;
sourceTree = SOURCE_ROOT;
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -118,7 +322,32 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8799B0C11D89DB38002F4D5F /* fls.c in Sources */,
8799B0B41D89DAF6002F4D5F /* tss.c in Sources */,
8799B0C01D89DB38002F4D5F /* fdr.c in Sources */,
8799B0BC1D89DB27002F4D5F /* ipsw.c in Sources */,
8799B0CC1D89F7B9002F4D5F /* download.c in Sources */,
8799B0B91D89DB0D002F4D5F /* img3.c in Sources */,
8799B0B51D89DAFF002F4D5F /* common.c in Sources */,
8799B0C41D89DB55002F4D5F /* mbn.c in Sources */,
8799B0B81D89DAFF002F4D5F /* recovery.c in Sources */,
8799B0B31D89DAE7002F4D5F /* idevicerestore.c in Sources */,
8799B0C81D89E2BD002F4D5F /* img4tool.c in Sources */,
8799B0BB1D89DB12002F4D5F /* download.c in Sources */,
8799B0B71D89DAFF002F4D5F /* normal.c in Sources */,
8799B0CD1D89F7B9002F4D5F /* jsmn.c in Sources */,
8799B0C31D89DB4B002F4D5F /* socket.c in Sources */,
8799B0C21D89DB46002F4D5F /* thread.c in Sources */,
8799B0B61D89DAFF002F4D5F /* dfu.c in Sources */,
8799B0BD1D89DB27002F4D5F /* limera1n.c in Sources */,
8799B0C51D89DB67002F4D5F /* locking.c in Sources */,
878587471D89CFDC008689F0 /* main.cpp in Sources */,
8799B0BF1D89DB38002F4D5F /* asr.c in Sources */,
8799B0BE1D89DB27002F4D5F /* restore.c in Sources */,
8799B0CB1D89F796002F4D5F /* tsschecker.c in Sources */,
8799B0C91D89E2C3002F4D5F /* img4.c in Sources */,
8799B0CA1D89E371002F4D5F /* img4.c in Sources */,
8799B0B21D89D99D002F4D5F /* futurerestore.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -209,14 +438,24 @@
8785874B1D89CFDC008689F0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
HEADER_SEARCH_PATHS = "";
LIBRARY_SEARCH_PATHS = /usr/local/lib;
OTHER_CFLAGS = "";
PRODUCT_NAME = "$(TARGET_NAME)";
USER_HEADER_SEARCH_PATHS = "/usr/local/include /opt/local/include";
};
name = Debug;
};
8785874C1D89CFDC008689F0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
HEADER_SEARCH_PATHS = "";
LIBRARY_SEARCH_PATHS = /usr/local/lib;
OTHER_CFLAGS = "";
PRODUCT_NAME = "$(TARGET_NAME)";
USER_HEADER_SEARCH_PATHS = "/usr/local/include /opt/local/include";
};
name = Release;
};
@ -239,6 +478,7 @@
8785874C1D89CFDC008689F0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};

22
futurerestore/config.h Normal file
View file

@ -0,0 +1,22 @@
//
// config.h
// futurerestore
//
// Created by tihmstar on 04.09.16.
// Copyright © 2016 tihmstar. All rights reserved.
//
#ifndef config_h
#define config_h
#define IMG4TOOL_NOMAIN
//idevicerestore config
#define IDEVICERESTORE_NOMAIN
#define PACKAGE_URL "http://libimobiledevice.org"
#endif /* config_h */

View file

@ -0,0 +1,538 @@
//
// futurerestore.cpp
// futurerestore
//
// Created by tihmstar on 14.09.16.
// Copyright © 2016 tihmstar. All rights reserved.
//
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
#include "futurerestore.hpp"
#include "common.h"
#include "all_tsschecker.h"
#include "../external/img4tool/img4tool/img4.h"
#include "img4tool.h"
#include "normal.h"
#include "recovery.h"
#include "ipsw.h"
#include "locking.h"
#include "restore.h"
#define NONCESIZE 20
#define USEC_PER_SEC 1000000
#define reterror(code,msg ...) error(msg),throw int(code)
#define safeFree(buf) if (buf) free(buf), buf = NULL
#define safePlistFree(buf) if (buf) plist_free(buf), buf = NULL
futurerestore::futurerestore(){
_client = idevicerestore_client_new();
if (_client == NULL) throw std::string("could not create idevicerestore client\n");
_didInit = false;
_apticket = NULL;
_im4m = NULL;
}
bool futurerestore::init(){
if (_didInit) return _didInit;
return _didInit = (check_mode(_client) != MODE_UNKNOWN);
}
uint64_t futurerestore::getDeviceEcid(){
if (!_didInit) reterror(-1, "did not init");
uint64_t ecid;
get_ecid(_client, &ecid);
return ecid;
}
int futurerestore::getDeviceMode(bool reRequest){
if (!_didInit) reterror(-1, "did not init");
if (!reRequest && _client->mode->index != MODE_UNKNOWN) {
return _client->mode->index;
}else{
normal_client_free(_client);
recovery_client_free(_client);
return check_mode(_client);
}
}
void futurerestore::putDeviceIntoRecovery(){
if (!_didInit) reterror(-1, "did not init");
getDeviceMode(false);
info("Found device in %s mode\n", _client->mode->string);
if (_client->mode->index == MODE_NORMAL) {
info("Entering recovery mode...\n");
if (normal_enter_recovery(_client) < 0) {
reterror(-2,"Unable to place device into recovery mode from %s mode\n", _client->mode->string);
}
}else if (_client->mode->index == MODE_RECOVERY){
info("Device already in Recovery mode\n");
}else{
reterror(-3, "unsupported devicemode, please put device in recovery mode or normal mode\n");
}
free(_client->udid);
_client->udid = NULL;
normal_client_free(_client);
recovery_client_free(_client);
}
void futurerestore::setAutoboot(bool val){
if (!_didInit) reterror(-1, "did not init");
if (getDeviceMode(false) != MODE_RECOVERY){
reterror(-2, "can't set autoboot, when device isn't in recovery mode\n");
}
if (_client->recovery || recovery_client_new(_client) == 0) {
if (recovery_set_autoboot(_client, val)){
reterror(-3,"Setting auto-boot failed?!\n");
}
} else {
reterror(-4,"Could not connect to device in recovery mode.\n");
}
}
bool futurerestore::nonceMatchesApTicket(){
if (!_didInit) reterror(-1, "did not init");
if (getDeviceMode(true) != MODE_RECOVERY) reterror(-10, "Device not in recovery mode, can't check apnonce\n");
unsigned char* realnonce;
int realNonceSize = 0;
recovery_get_ap_nonce(_client, &realnonce, &realNonceSize);
return memcmp(realnonce, (unsigned const char*)getNonceFromIM4M(_im4m), realNonceSize) == 0;
}
void futurerestore::waitForNonce(const char *nonce){
if (!_didInit) reterror(-1, "did not init");
setAutoboot(false);
unsigned char* realnonce;
int realNonceSize = 0;
info("waiting for nonce: ");
int i = 0;
for (i = 0; i < NONCESIZE; i++) {
info("%02x ", ((unsigned char *)nonce)[i]);
}
info("\n");
do {
if (realNonceSize){
recovery_send_reset(_client);
recovery_client_free(_client);
usleep(1*USEC_PER_SEC);
}
while (getDeviceMode(true) != MODE_RECOVERY) usleep(USEC_PER_SEC*0.5);
if (recovery_client_new(_client)) reterror(-4,"Could not connect to device in recovery mode.\n");
recovery_get_ap_nonce(_client, &realnonce, &realNonceSize);
info("Got ApNonce from device: ");
int i = 0;
for (i = 0; i < realNonceSize; i++) {
info("%02x ", realnonce[i]);
}
info("\n");
} while (memcmp(realnonce, (unsigned const char*)nonce, realNonceSize) != 0);
info("Device has requested ApNonce now\n");
setAutoboot(true);
}
void futurerestore::waitForNonce(){
if (!_im4m) reterror(-1, "No IM4M loaded\n");
waitForNonce(getNonceFromIM4M(_im4m));
}
void futurerestore::loadAPTicket(const char *apticketPath){
if (_apticket) plist_free(_apticket), _apticket = NULL;
FILE *f = fopen(apticketPath,"rb");
fseek(f, 0, SEEK_END);
size_t fSize = ftell(f);
fseek(f, 0, SEEK_SET);
char *buf = (char*)malloc(fSize);
fread(buf, fSize, 1, f);
fclose(f);
if (memcmp(buf, "bplist00", 8) == 0)
plist_from_bin(buf, (uint32_t)fSize, &_apticket);
else
plist_from_xml(buf, (uint32_t)fSize, &_apticket);
if (_im4m) free(_im4m);
plist_t ticket = plist_dict_get_item(_apticket, "ApImg4Ticket");
uint64_t im4msize=0;
plist_get_data_val(ticket, &_im4m, &im4msize);
}
void futurerestore::loadAPTicket(string apticketPath){
loadAPTicket(apticketPath.c_str());
}
int futurerestore::doRestore(const char *ipsw, bool noerase){
int err = 0;
struct idevicerestore_client_t* client = _client;
int unused;
int result = 0;
int delete_fs = 0;
char* filesystem = NULL;
plist_t buildmanifest = NULL;
plist_t sepbuildmanifest = NULL;
plist_t basebandbuildmanifest = NULL;
plist_t build_identity = NULL;
plist_t sep_build_identity = NULL;
plist_t bb_build_identity = NULL;
client->ipsw = strdup(ipsw);
if (!noerase) client->flags |= FLAG_ERASE;
getDeviceMode(true);
info("Found device in %s mode\n", client->mode->string);
if (client->mode->index != MODE_RECOVERY) reterror(-6, "device not in recovery mode\n");
// discover the device type
if (check_hardware_model(client) == NULL || client->device == NULL) {
reterror(-2,"ERROR: Unable to discover device model\n");
}
info("Identified device as %s, %s\n", client->device->hardware_model, client->device->product_type);
if (!nonceMatchesApTicket()) reterror(-20, "Devicenonce does not match APTicket nonce\n");
// verify if ipsw file exists
if (access(client->ipsw, F_OK) < 0) {
error("ERROR: Firmware file %s does not exist.\n", client->ipsw);
return -1;
}
info("Extracting BuildManifest from IPSW\n");
if (ipsw_extract_build_manifest(client->ipsw, &buildmanifest, &unused) < 0) {
reterror(-3,"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 */
if (build_manifest_check_compatibility(buildmanifest, client->device->product_type) < 0) {
reterror(-4,"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);
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->tss = _apticket;
plist_dict_remove_item(client->tss, "BBTicket");
plist_dict_remove_item(client->tss, "BasebandFirmware");
if (noerase) {
build_identity = build_manifest_get_build_identity_for_model_with_restore_behavior(buildmanifest, client->device->hardware_model, "Update");
if (!build_identity) {
build_identity = build_manifest_get_build_identity_for_model(buildmanifest, client->device->hardware_model);
}
}else{
build_identity = build_manifest_get_build_identity_for_model_with_restore_behavior(buildmanifest, client->device->hardware_model, "Erase");
if (build_identity == NULL) {
reterror(-5,"ERROR: Unable to find any build identities\n");
}
}
sepbuildmanifest = loadPlistFromFile(_sepManifestPath);
sep_build_identity = build_manifest_get_build_identity_for_model_with_restore_behavior(sepbuildmanifest, client->device->hardware_model, "Erase");
if (sep_build_identity == NULL) {
reterror(-5,"ERROR: Unable to find any build identities for sep\n");
}
basebandbuildmanifest = loadPlistFromFile(_basebandManifestPath);
bb_build_identity = build_manifest_get_build_identity_for_model_with_restore_behavior(basebandbuildmanifest, client->device->hardware_model, "Erase");
if (bb_build_identity == NULL) {
reterror(-5,"ERROR: Unable to find any build identities for baseband\n");
}
plist_t bb_manifest = plist_dict_get_item(bb_build_identity, "Manifest");
plist_t bb_baseband = plist_copy(plist_dict_get_item(bb_manifest, "BasebandFirmware"));
plist_t info = plist_dict_get_item(build_identity, "Info");
plist_t manifest = plist_dict_get_item(info, "Manifest");
plist_dict_set_item(manifest, "BasebandFirmware", bb_baseband);
client->bbfwtmp = (char*)_basebandPath;
/* print information about current build identity */
build_identity_print_information(build_identity);
// Get filesystem name from build identity
char* fsname = NULL;
if (build_identity_get_component_path(build_identity, "OS", &fsname) < 0) {
error("ERROR: Unable get path for filesystem component\n");
return -1;
}
// check if we already have an extracted filesystem
struct stat st;
memset(&st, '\0', sizeof(struct stat));
char tmpf[1024];
if (client->cache_dir) {
if (stat(client->cache_dir, &st) < 0) {
mkdir_with_parents(client->cache_dir, 0755);
}
strcpy(tmpf, client->cache_dir);
strcat(tmpf, "/");
char *ipswtmp = strdup(client->ipsw);
strcat(tmpf, basename(ipswtmp));
free(ipswtmp);
} else {
strcpy(tmpf, client->ipsw);
}
char* p = strrchr((const char*)tmpf, '.');
if (p) {
*p = '\0';
}
if (stat(tmpf, &st) < 0) {
__mkdir(tmpf, 0755);
}
strcat(tmpf, "/");
strcat(tmpf, fsname);
memset(&st, '\0', sizeof(struct stat));
if (stat(tmpf, &st) == 0) {
off_t fssize = 0;
ipsw_get_file_size(client->ipsw, fsname, &fssize);
if ((fssize > 0) && (st.st_size == fssize)) {
info("Using cached filesystem from '%s'\n", tmpf);
filesystem = strdup(tmpf);
}
}
if (!filesystem) {
char extfn[1024];
strcpy(extfn, tmpf);
strcat(extfn, ".extract");
char lockfn[1024];
strcpy(lockfn, tmpf);
strcat(lockfn, ".lock");
lock_info_t li;
lock_file(lockfn, &li);
FILE* extf = NULL;
if (access(extfn, F_OK) != 0) {
extf = fopen(extfn, "w");
}
unlock_file(&li);
if (!extf) {
// use temp filename
filesystem = tempnam(NULL, "ipsw_");
if (!filesystem) {
error("WARNING: Could not get temporary filename, using '%s' in current directory\n", fsname);
filesystem = strdup(fsname);
}
delete_fs = 1;
} else {
// use <fsname>.extract as filename
filesystem = strdup(extfn);
fclose(extf);
}
remove(lockfn);
// Extract filesystem from IPSW
info("Extracting filesystem from IPSW\n");
if (ipsw_extract_to_file_with_progress(client->ipsw, fsname, filesystem, 1) < 0) {
reterror(-7,"ERROR: Unable to extract filesystem from IPSW\n");
}
if (strstr(filesystem, ".extract")) {
// rename <fsname>.extract to <fsname>
remove(tmpf);
rename(filesystem, tmpf);
free(filesystem);
filesystem = strdup(tmpf);
}
}
if ((client->build_major > 8)) {
if (!client->image4supported) {
/* send ApTicket */
if (recovery_send_ticket(client) < 0) {
error("WARNING: Unable to send APTicket\n");
}
}
}
/* now we load the iBEC */
if (recovery_send_ibec(client, build_identity) < 0) {
reterror(-8,"ERROR: Unable to send iBEC\n");
}
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 */
sleep(7);
check_mode(client);
//do magic
get_sep_nonce(client, &client->sepnonce, &client->sepnonce_size);
get_ap_nonce(client, &client->nonce, &client->nonce_size);
get_ecid(client, &client->ecid);
if (client->mode->index == MODE_RECOVERY) {
if (client->srnm == NULL) {
reterror(-9,"ERROR: could not retrieve device serial number. Can't continue.\n");
}
if (recovery_enter_restore(client, build_identity) < 0) {
reterror(-10,"ERROR: Unable to place device into restore mode\n");
}
recovery_client_free(client);
}
if (get_tss_response(client, sep_build_identity, &client->septss) < 0) {
reterror(-11,"ERROR: Unable to get SHSH blobs for SEP\n");
}
FILE *fsep = fopen(_sepPath, "r");
fseek(fsep, 0, SEEK_END);
client->sepfwdatasize = ftell(fsep);
fseek(fsep, 0, SEEK_SET);
client->sepfwdata = (char*)malloc(client->sepfwdatasize);
fread(client->sepfwdata, 1, client->sepfwdatasize, fsep);
fclose(fsep);
if (client->mode->index == MODE_RESTORE) {
info("About to restore device... \n");
result = restore_device(client, build_identity, filesystem);
if (result < 0) {
reterror(-11,"ERROR: Unable to restore device\n");
}
}
info("Cleaning up...\n");
error:
safeFree(client->sepfwdata);
safePlistFree(buildmanifest);
safePlistFree(sepbuildmanifest);
safePlistFree(basebandbuildmanifest);
safePlistFree(build_identity);
safePlistFree(sep_build_identity);
safePlistFree(bb_build_identity);
if (delete_fs && filesystem) unlink(filesystem);
if (!result && !err) info("DONE\n");
return result ? abs(result) : err;
}
futurerestore::~futurerestore(){
idevicerestore_client_free(_client);
safeFree(_im4m);
safePlistFree(_apticket);
}
#pragma mark static methods
char *futurerestore::getNonceFromIM4M(const char* im4m){
char *ret = NULL;
t_asn1Tag *mainSet = NULL;
t_asn1Tag *manbSet = NULL;
t_asn1Tag *manpSet = NULL;
char *nonceOctet = NULL;
char *bnch = NULL;
char *manb = NULL;
char *manp = NULL;
if (!im4m) reterror(-15, "Got empty IM4M\n");
if (asn1ElementsInObject(im4m)< 3){
error("unexpected number of Elements in IM4M sequence\n");
goto error;
}
mainSet = asn1ElementAtIndex(im4m, 2);
manb = getValueForTagInSet((char*)mainSet, 0x4d414e42); //MANB priv Tag
if (asn1ElementsInObject(manb)< 2){
error("unexpected number of Elements in MANB sequence\n");
goto error;
}
manbSet = asn1ElementAtIndex(manb, 1);
manp = getValueForTagInSet((char*)manbSet, 0x4d414e50); //MANP priv Tag
if (asn1ElementsInObject(manp)< 2){
error("unexpected number of Elements in MANP sequence\n");
goto error;
}
manpSet = asn1ElementAtIndex(manp, 1);
bnch = getValueForTagInSet((char*)manpSet, 0x424e4348); //BNCH priv Tag
if (asn1ElementsInObject(bnch)< 2){
error("unexpected number of Elements in BNCH sequence\n");
goto error;
}
nonceOctet = (char*)asn1ElementAtIndex(bnch, 1);
ret = (char*)malloc(NONCESIZE);
if (ret){
nonceOctet++;
memcpy(ret, nonceOctet + asn1Len(nonceOctet).sizeBytes, NONCESIZE);
}
error:
return ret;
}
char *futurerestore::getNonceFromAPTicket(const char* apticketPath){
char *ret = NULL;
if (char *im4m = im4mFormShshFile(apticketPath)){
ret = getNonceFromIM4M(im4m);
free(im4m);
}
return ret;
}
plist_t futurerestore::loadPlistFromFile(const char *path){
plist_t ret = NULL;
FILE *f = fopen(path,"rb");
if (!f){
error("could not open file %s\n",path);
return NULL;
}
fseek(f, 0, SEEK_END);
size_t bufSize = ftell(f);
fseek(f, 0, SEEK_SET);
char *buf = (char*)malloc(bufSize);
if (!buf){
error("failed to alloc memory\n");
return NULL;
}
fread(buf, 1, bufSize, f);
fclose(f);
if (memcmp(buf, "bplist00", 8) == 0)
plist_from_bin(buf, (uint32_t)bufSize, &ret);
else
plist_from_xml(buf, (uint32_t)bufSize, &ret);
free(buf);
return ret;
}

View file

@ -0,0 +1,62 @@
//
// futurerestore.hpp
// futurerestore
//
// Created by tihmstar on 14.09.16.
// Copyright © 2016 tihmstar. All rights reserved.
//
#ifndef futurerestore_hpp
#define futurerestore_hpp
#include "config.h"
#include <stdio.h>
#include "idevicerestore.h"
using namespace std;
class futurerestore {
struct idevicerestore_client_t* _client;
bool _didInit;
plist_t _apticket;
char *_im4m;
const char *_sepManifestPath;
const char *_basebandManifestPath;
const char *_sepPath;
const char *_basebandPath;
public:
futurerestore();
bool init();
int getDeviceMode(bool reRequest);
uint64_t getDeviceEcid();
void putDeviceIntoRecovery();
void setAutoboot(bool val);
void waitForNonce();
void waitForNonce(const char *nonce);
void loadAPTicket(const char *apticketPath);
void loadAPTicket(string apticketPath);
bool nonceMatchesApTicket();
void setSepManifestPath(const char *sepManifestPath){_sepManifestPath = sepManifestPath;};
void setBasebandManifestPath(const char *basebandManifestPath){_basebandManifestPath = basebandManifestPath;};
void setSepPath(const char *sepPath){_sepPath = sepPath;};
void setBasebandPath(const char *basebandPath){_basebandPath = basebandPath;};
int doRestore(const char *ipsw, bool noerase);
~futurerestore();
static char *getNonceFromIM4M(const char* im4m);
static char *getNonceFromAPTicket(const char* apticketPath);
static plist_t loadPlistFromFile(const char *path);
};
#endif /* futurerestore_hpp */

View file

@ -1,4 +1,4 @@
//
// main.cpp
// futurerestore
//
@ -7,9 +7,163 @@
//
#include <iostream>
#include <getopt.h>
#include "futurerestore.hpp"
#include "all_tsschecker.h"
#include "tsschecker.h"
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
return 0;
#define safeFree(buf) if (buf) free(buf), buf = NULL
#define safePlistFree(buf) if (buf) plist_free(buf), buf = NULL
static struct option longopts[] = {
{ "apticket", required_argument, NULL, 't' },
{ "baseband", required_argument, NULL, 'b' },
{ "baseband-plist", required_argument, NULL, 'p' },
{ "sep", required_argument, NULL, 's' },
{ "sep-manifest", required_argument, NULL, 'm' },
{ "wait", no_argument, NULL, 'w' },
{ "update", no_argument, NULL, 'u' },
{ "debug", no_argument, NULL, 'd' },
{ NULL, 0, NULL, 0 }
};
#define FLAG_WAIT 1 << 0
#define FLAG_UPDATE 1 << 1
void cmd_help(){
printf("Usage: futurerestore [OPTIONS] IPSW\n");
printf("Allows restoring nonmatching iOS/Sep/Baseband\n\n");
printf(" -t, --apticket PATH\t\tApticket used for restoring\n");
printf(" -b, --baseband PATH\t\tBaseband to be flashed\n");
printf(" -p, --baseband-manifest PATH\t\tBuildmanifest for requesting baseband ticket\n");
printf(" -s, --sep PATH\t\tSep to be flashed\n");
printf(" -m, --sep-manifest PATH\t\tBuildmanifest for requesting sep ticket\n");
printf(" -w, --wait\t\tkeep rebooting until nonce matches APTicket\n");
printf(" -u, --update\t\tupdate instead of erase install\n");
printf("\n");
}
using namespace std;
int main(int argc, const char * argv[]) {
#define reterror(code,a ...) do {error(a); err = code; goto error;} while (0)
int err=0;
int res = 0;
int optindex = 0;
int opt = 0;
long flags = 0;
int isSepManifestSigned = 0;
int isBasebandSigned = 0;
const char *ipsw = NULL;
const char *apticketPath = NULL;
const char *basebandPath = NULL;
const char *basebandManifestPath = NULL;
const char *sepPath = NULL;
const char *sepManifestPath = NULL;
t_devicevals devVals;
t_iosVersion versVals;
memset(&devVals, 0, sizeof(devVals));
memset(&versVals, 0, sizeof(versVals));
if (argc == 1){
cmd_help();
return -1;
}
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wud", longopts, &optindex)) > 0) {
switch (opt) {
case 't': // long option: "apticket"; can be called as short option
apticketPath = optarg;
break;
case 'b': // long option: "baseband"; can be called as short option
basebandPath = optarg;
break;
case 'p': // long option: "baseband-plist"; can be called as short option
basebandManifestPath = optarg;
break;
case 's': // long option: "sep"; can be called as short option
sepPath = optarg;
break;
case 'm': // long option: "sep-manifest"; can be called as short option
sepManifestPath = optarg;
break;
case 'w': // long option: "wait"; can be called as short option
flags |= FLAG_WAIT;
break;
case 'u': // long option: "update"; can be called as short option
flags |= FLAG_UPDATE;
break;
case 'd': // long option: "debug"; can be called as short option
idevicerestore_debug = 1;
break;
default:
cmd_help();
return -1;
}
}
if (argc-optind == 1) {
argc -= optind;
argv += optind;
ipsw = argv[0];
}
futurerestore client;
client.init();
if (apticketPath) client.loadAPTicket(apticketPath);
if (flags & FLAG_WAIT){
client.putDeviceIntoRecovery();
client.waitForNonce();
}
if (!(apticketPath && basebandPath && basebandManifestPath && sepPath && sepManifestPath && ipsw)) {
if (!(flags & FLAG_WAIT) || ipsw){
error("missing argument\n");
cmd_help();
err = -2;
}else{
info("done\n");
}
goto error;
}
versVals.basebandMode = kBasebandModeWithoutBaseband;
if (!(isSepManifestSigned = isManifestSignedForDevice(sepManifestPath, NULL, devVals, versVals))){
reterror(-3,"sep firmware isn't signed\n");
}
versVals.basebandMode = kBasebandModeOnlyBaseband;
if (!(isBasebandSigned = isManifestSignedForDevice(basebandManifestPath, NULL, devVals, versVals))){
reterror(-3,"baseband firmware isn't signed\n");
}
client.setSepPath(sepPath);
client.setSepManifestPath(sepManifestPath);
client.setBasebandPath(basebandPath);
client.setBasebandManifestPath(basebandManifestPath);
client.putDeviceIntoRecovery();
try {
res = client.doRestore(ipsw, flags & FLAG_UPDATE);
} catch (int error) {
if (error == -20) error("maybe you forgot -w ?\n");
err = error;
}
cout << "Done: restoring "<< (res ? "succeeded" : "failed");
if (!res) cout << ". Errorcode="<<err;
cout<<endl;
error:
return err;
#undef reterror
}