2323import com .sun .jna .Platform ;
2424import com .sun .jna .Pointer ;
2525import com .sun .jna .ptr .IntByReference ;
26+ import com .sun .jna .ptr .LongByReference ;
2627import com .sun .jna .ptr .PointerByReference ;
2728import javafx .concurrent .Task ;
2829import javafx .scene .control .ButtonType ;
3637public class LibimobiledeviceUtil {
3738
3839 public static long getECID () throws LibimobiledeviceException {
39- return Long . parseLong ( getKeyFromConnectedDevice ("UniqueChipID" , PlistType . INTEGER ));
40+ return getPlistLong ( getLockdownValuePlist ("UniqueChipID" ));
4041 }
4142
4243 public static String getDeviceModelIdentifier () throws LibimobiledeviceException {
43- return getKeyFromConnectedDevice ( "ProductType" , PlistType . STRING );
44+ return getPlistString ( getLockdownValuePlist ( "ProductType" ) );
4445 }
4546
4647 public static String getBoardConfig () throws LibimobiledeviceException {
47- return getKeyFromConnectedDevice ( "HardwareModel" , PlistType . STRING );
48+ return getPlistString ( getLockdownValuePlist ( "HardwareModel" ) );
4849 }
4950
5051 public static String getApNonceNormalMode () throws LibimobiledeviceException {
51- return LibimobiledeviceUtil . plistDataToString (LibimobiledeviceUtil .getMobileGestaltKey ("ApNonce" ), ByteOrder .BIG_ENDIAN );
52+ return plistDataToHexString (LibimobiledeviceUtil .getLockdownValuePlist ("ApNonce" ), ByteOrder .BIG_ENDIAN );
5253 }
5354
5455 public static String getGenerator () throws LibimobiledeviceException {
55- return "0x" + LibimobiledeviceUtil . plistDataToString ( LibimobiledeviceUtil . getMobileGestaltKey ("BootNonce" ), ByteOrder .LITTLE_ENDIAN );
56+ return "0x" + plistDataToHexString ( getLockdownValuePlist ("BootNonce" ), ByteOrder .LITTLE_ENDIAN );
5657 }
5758
5859 public static void exitRecovery (Pointer irecvClient ) throws LibimobiledeviceException {
@@ -135,17 +136,17 @@ protected Void call() throws LibimobiledeviceException {
135136 }
136137 throwIfNeeded (errorCode , ErrorCodeType .lockdownd_error );
137138
138- PointerByReference service = new PointerByReference ();
139+ PointerByReference plist = new PointerByReference ();
139140 // don't reset timeout
140141 errorCode = -17 ;
141142 while (errorCode == -17 && System .currentTimeMillis () < endTime ) {
142143 if (!sleep (1000 )) {
143144 return null ;
144145 }
145- errorCode = lockdownd_start_service (lockdown .getValue (), "com.apple.mobile.diagnostics_relay" , service );
146+ errorCode = lockdownd_get_value (lockdown .getValue (), Pointer . NULL , "BootNonce" , plist );
146147 }
147148 if (errorCode == 0 ) {
148- lockdownd_service_descriptor_free ( service .getValue ());
149+ Libplist . free ( plist .getValue ());
149150 }
150151 lockdownd_client_free (lockdown .getValue ());
151152 idevice_free (device .getValue ());
@@ -201,45 +202,10 @@ private static String getApnonce(Pointer irecv_client) {
201202 return Utils .bytesToHex (apnonceBytes , ByteOrder .BIG_ENDIAN );
202203 }
203204
204- private static String getKeyFromConnectedDevice (String key , PlistType plistType ) throws LibimobiledeviceException {
205- if (plistType == null ) {
206- plistType = PlistType .STRING ;
207- }
208- if (key == null ) {
209- key = "" ;
210- }
211-
212- Pointer client = lockdowndClientFromConnectedDevice ();
213- PointerByReference plist_value = new PointerByReference ();
214- int lockdowndGetValueErrorCode = lockdownd_get_value (client , Pointer .NULL , key , plist_value );
215- if (lockdowndGetValueErrorCode == -8 ) {
216- // try again, and if it doesn't work, show an error to the user + throw an exception
217- // it always works the second time
218- lockdownd_client_free (client );
219- client = lockdowndClientFromConnectedDevice ();
220- throwIfNeeded (lockdownd_get_value (client , Pointer .NULL , key , plist_value ), ErrorCodeType .lockdownd_error );
221- } else {
222- throwIfNeeded (lockdowndGetValueErrorCode , ErrorCodeType .lockdownd_error );
223- }
224- lockdownd_client_free (client );
225- if (plistType .equals (PlistType .INTEGER )) {
226- PointerByReference xml_doc = new PointerByReference ();
227- Libplist .toXml (plist_value .getValue (), xml_doc , new PointerByReference ());
228- Libplist .free (plist_value .getValue ());
229- String toReturn = xml_doc .getValue ().getString (0 , "UTF-8" );
230- return toReturn .substring (toReturn .indexOf ("<integer>" ) + "<integer>" .length (), toReturn .indexOf ("</integer>" ));
231- } else {
232- PointerByReference toReturn = new PointerByReference ();
233- Libplist .getStringVal (plist_value .getValue (), toReturn );
234- Libplist .free (plist_value .getValue ());
235- return toReturn .getValue ().getString (0 , "UTF-8" );
236- }
237- }
238-
239205 /**
240206 * Returns a plist with the root element being the requested item.
241207 * <p>
242- * It will look something like this:
208+ * It will look something like this (might have different type) :
243209 * <pre>
244210 * {@code
245211 * <?xml version="1.0" encoding="UTF-8"?>
@@ -252,34 +218,25 @@ private static String getKeyFromConnectedDevice(String key, PlistType plistType)
252218 * }
253219 * </pre>
254220 */
255- private static Pointer getMobileGestaltKey (String key ) throws LibimobiledeviceException {
256- PointerByReference device = new PointerByReference ();
257- throwIfNeeded (idevice_new (device , Pointer .NULL ), ErrorCodeType .idevice_error );
258- PointerByReference client = new PointerByReference ();
259- throwIfNeeded (lockdownd_client_new_with_handshake (device .getValue (), client , "blobsaver" ), ErrorCodeType .lockdownd_error );
260- PointerByReference service = new PointerByReference ();
261- throwIfNeeded (lockdownd_start_service (client .getValue (), "com.apple.mobile.diagnostics_relay" , service ), ErrorCodeType .lockdownd_error );
262- lockdownd_client_free (client .getValue ());
263-
264- PointerByReference diagnosticsRelayClient = new PointerByReference ();
265- throwIfNeeded (diagnostics_relay_client_new (device .getValue (), service .getValue (), diagnosticsRelayClient ), ErrorCodeType .diagnostics_relay_error );
266-
267- Pointer keys = Libplist .newArray ();
268- Libplist .arrayAppendItem (keys , Libplist .newString (key ));
269- PointerByReference plistResult = new PointerByReference ();
270- throwIfNeeded (diagnostics_relay_query_mobilegestalt (diagnosticsRelayClient .getValue (), keys , plistResult ), ErrorCodeType .diagnostics_relay_error );
271- Pointer plistApnonce = Libplist .dictGetItem (Libplist .dictGetItem (plistResult .getValue (), "MobileGestalt" ), key );
272-
273- diagnostics_relay_goodbye (diagnosticsRelayClient .getValue ());
274- diagnostics_relay_client_free (diagnosticsRelayClient .getValue ());
275- lockdownd_service_descriptor_free (service .getValue ());
276- idevice_free (device .getValue ());
277- Libplist .free (keys );
221+ private static Pointer getLockdownValuePlist (String key ) throws LibimobiledeviceException {
222+ Pointer client = lockdowndClientFromConnectedDevice ();
223+ PointerByReference plist = new PointerByReference ();
224+ int lockdowndGetValueErrorCode = lockdownd_get_value (client , Pointer .NULL , key , plist );
225+ if (lockdowndGetValueErrorCode == -8 ) {
226+ // try again, and if it doesn't work, show an error to the user + throw an exception
227+ // it always works the second time
228+ lockdownd_client_free (client );
229+ client = lockdowndClientFromConnectedDevice ();
230+ throwIfNeeded (lockdownd_get_value (client , Pointer .NULL , key , plist ), ErrorCodeType .lockdownd_error );
231+ } else {
232+ throwIfNeeded (lockdowndGetValueErrorCode , ErrorCodeType .lockdownd_error );
233+ }
234+ lockdownd_client_free (client );
278235
279- return plistApnonce ;
236+ return plist . getValue () ;
280237 }
281238
282- private static String plistDataToString (Pointer plist , ByteOrder byteOrder ) {
239+ private static String plistDataToHexString (Pointer plist , ByteOrder byteOrder ) {
283240 IntByReference apnonceLength = new IntByReference ();
284241 byte [] apnonceBytes = Libplist .getDataPtr (plist , apnonceLength ).getByteArray (0 , apnonceLength .getValue ());
285242 String toReturn = Utils .bytesToHex (apnonceBytes , byteOrder );
@@ -288,6 +245,27 @@ private static String plistDataToString(Pointer plist, ByteOrder byteOrder) {
288245 return toReturn ;
289246 }
290247
248+ private static long getPlistLong (Pointer plist ) {
249+ LongByReference reference = new LongByReference ();
250+ Libplist .getUintVal (plist , reference );
251+ Libplist .free (plist );
252+ return reference .getValue ();
253+ }
254+
255+ private static String getPlistString (Pointer plist ) {
256+ PointerByReference reference = new PointerByReference ();
257+ Libplist .getStringVal (plist , reference );
258+ Libplist .free (plist );
259+ return reference .getValue ().getString (0 , "UTF-8" );
260+ }
261+
262+ // Useful for debugging
263+ private static String plistToXml (Pointer plist ) {
264+ PointerByReference xml_doc = new PointerByReference ();
265+ Libplist .toXml (plist , xml_doc , new PointerByReference ());
266+ return xml_doc .getValue ().getString (0 , "UTF-8" );
267+ }
268+
291269 private static Pointer lockdowndClientFromConnectedDevice () throws LibimobiledeviceException {
292270 PointerByReference device = new PointerByReference ();
293271 throwIfNeeded (idevice_new (device , Pointer .NULL ), ErrorCodeType .idevice_error );
@@ -306,12 +284,8 @@ static void enterRecovery() throws LibimobiledeviceException {
306284 lockdownd_client_free (client );
307285 }
308286
309- private enum PlistType {
310- STRING , INTEGER
311- }
312-
313287 private enum ErrorCodeType {
314- idevice_error , lockdownd_error , irecv_error , diagnostics_relay_error
288+ idevice_error , lockdownd_error , irecv_error
315289 }
316290
317291 private static void throwIfNeeded (int errorCode , ErrorCodeType errorType ) throws LibimobiledeviceException {
@@ -350,9 +324,6 @@ private static void throwIfNeeded(int errorCode, ErrorCodeType errorType) throws
350324 message = "irecovery error: code=" + errorCode +
351325 "\n \n If your device is still in recovery mode, use the \" Exit Recovery Mode\" option from the help menu." ;
352326 reportableError = true ;
353- } else if (errorType .equals (ErrorCodeType .diagnostics_relay_error )) {
354- message = "Diagnostics Relay error: code=" + errorCode ;
355- reportableError = true ;
356327 }
357328 throw new LibimobiledeviceException (message , errorType , errorCode , reportableError );
358329 }
0 commit comments