1
1
package com .emeryferrari .iosrr ;
2
2
import javax .swing .*;
3
3
import java .awt .event .*;
4
+ import java .io .*;
4
5
public class Display {
5
6
private Display () {}
6
7
private static final Display CLASS_OBJ = new Display ();
7
- private static JFrame FRAME = new JFrame (RRConst .NAME + " - v " + RRConst .VERSION );
8
+ private static JFrame FRAME = new JFrame (RRConst .NAME + " " + RRConst .VERSION );
8
9
private static JLabel TITLE = new JLabel (RRConst .TITLE );
10
+ private static JLabel DESC = new JLabel (RRConst .DESC );
9
11
private static JButton KEY_SALT_BUTTON = new JButton (RRConst .KEY_SALT_BUTTON );
10
12
private static JButton FILE_BUTTON = new JButton (RRConst .FILE_BUTTON );
11
13
private static JButton SSH_BUTTON = new JButton (RRConst .SSH_BUTTON );
12
14
private static JButton IPROXY_BUTTON = new JButton (RRConst .IPROXY_BUTTON );
15
+ private static JButton ITUNES_BACKUP = new JButton (RRConst .ITUNES_BACKUP );
16
+ private static InfoPlist [] plists = null ;
17
+ private static boolean initialized = false ;
13
18
public static void createDisplay () {
14
- Display .FRAME .setDefaultCloseOperation (JFrame .EXIT_ON_CLOSE );
15
- Display .FRAME .setSize (800 , 600 );
16
- Display .FRAME .setLayout (new BoxLayout (FRAME .getContentPane (), BoxLayout .Y_AXIS ));
17
- Display .KEY_SALT_BUTTON .addActionListener (Display .CLASS_OBJ .new KeySaltButtonListener ());
18
- Display .FILE_BUTTON .addActionListener (Display .CLASS_OBJ .new FileButtonListener ());
19
- Display .SSH_BUTTON .addActionListener (Display .CLASS_OBJ .new SSHButtonListener ());
20
- Display .IPROXY_BUTTON .addActionListener (Display .CLASS_OBJ .new IproxyButtonListener ());
21
- Display .IPROXY_BUTTON .setEnabled (false );
19
+ if (!initialized ) {
20
+ Display .FRAME .setDefaultCloseOperation (JFrame .EXIT_ON_CLOSE );
21
+ Display .FRAME .setSize (800 , 600 );
22
+ Display .FRAME .setLayout (new BoxLayout (FRAME .getContentPane (), BoxLayout .Y_AXIS ));
23
+ Display .KEY_SALT_BUTTON .addActionListener (Display .CLASS_OBJ .new KeySaltButtonListener ());
24
+ Display .FILE_BUTTON .addActionListener (Display .CLASS_OBJ .new FileButtonListener ());
25
+ Display .SSH_BUTTON .addActionListener (Display .CLASS_OBJ .new SSHButtonListener ());
26
+ Display .IPROXY_BUTTON .addActionListener (Display .CLASS_OBJ .new IproxyButtonListener ());
27
+ Display .IPROXY_BUTTON .setEnabled (false );
28
+ Display .ITUNES_BACKUP .addActionListener (Display .CLASS_OBJ .new ItunesBackupListener ());
29
+ initialized = true ;
30
+ }
22
31
Display .FRAME .getContentPane ().add (Display .TITLE );
32
+ Display .FRAME .getContentPane ().add (Display .DESC );
23
33
Display .FRAME .getContentPane ().add (Display .KEY_SALT_BUTTON );
24
34
Display .FRAME .getContentPane ().add (Display .FILE_BUTTON );
25
35
Display .FRAME .getContentPane ().add (Display .SSH_BUTTON );
26
- Display .FRAME .getContentPane ().add (Display .IPROXY_BUTTON );
36
+ Display .FRAME .getContentPane ().add (Display .ITUNES_BACKUP );
27
37
Display .FRAME .setVisible (true );
28
38
}
39
+ public class ItunesBackupListener implements ActionListener {
40
+ public void actionPerformed (ActionEvent ev ) {
41
+ try {
42
+ OperatingSystem currentOS = RestrictionsRecovery .identifyHostOS ();
43
+ String backupPath = System .getProperty ("user.home" ) + "\\ " ;
44
+ if (currentOS == OperatingSystem .WINDOWS ) {
45
+ String y = JOptionPane .showInputDialog ("Are you using the Microsoft Store version of iTunes? (y/n)" );
46
+ if (y .equalsIgnoreCase ("y" ) || y .equalsIgnoreCase ("yes" )) {
47
+ backupPath += "Apple\\ MobileSync\\ Backup\\ " ;
48
+ } else {
49
+ backupPath += "AppData\\ Roaming\\ Apple Computer\\ MobileSync\\ Backup\\ " ;
50
+ }
51
+ } else if (currentOS == OperatingSystem .MACOSMOJAVE || currentOS == OperatingSystem .MACOSCATALINA ) {
52
+
53
+ } else {
54
+ throw new Exception ("Your OS is not supported because it is not possible to install iTunes on your OS." );
55
+ }
56
+ File backupLocation = new File (backupPath );
57
+ String [] backups = backupLocation .list (new FilenameFilter () {
58
+ @ Override
59
+ public boolean accept (File current , String name ) {
60
+ return new File (current , name ).isDirectory ();
61
+ }
62
+ });
63
+ Display .FRAME .getContentPane ().removeAll ();
64
+ Display .FRAME .getContentPane ().add (new JLabel (RRConst .ITUNES_BACKUPS ));
65
+ plists = new InfoPlist [backups .length ];
66
+ for (int i = 0 ; i < backups .length ; i ++) {
67
+ InfoPlist plist = InfoPlist .getInstance (backupPath + backups [i ] + "\\ " );
68
+ plists [i ] = plist ;
69
+ if (plist != null ) {
70
+ JButton button = new JButton (plist .getDeviceName () + " / " + plist .getiOSVersion () + " / " + plist .getBackupDate () + " / " + plist .getDisplayName ());
71
+ if (plist .getiOSRelease () < 7 || plist .getiOSRelease () > 11 ) {
72
+ button .setEnabled (false );
73
+ }
74
+ button .addActionListener (Display .CLASS_OBJ .new BackupListener (i ));
75
+ Display .FRAME .getContentPane ().add (button );
76
+ }
77
+ }
78
+ JButton back = new JButton ("Back" );
79
+ back .addActionListener (new BackListener ());
80
+ Display .FRAME .getContentPane ().add (back );
81
+ Display .refresh ();
82
+ } catch (Exception ex ) {
83
+ Display .handleException (ex , true );
84
+ }
85
+ }
86
+ }
87
+ public class BackupListener implements ActionListener {
88
+ private int index ;
89
+ public BackupListener (int index ) {
90
+ this .index = index ;
91
+ }
92
+ public void actionPerformed (ActionEvent ev ) {
93
+ try {
94
+ KeySaltPair pair = PropertyListReader .getKeyAndSaltFromPlist (plists [index ].getFile () + "398bc9c2aeeab4cb0c12ada0f52eea12cf14f40b" );
95
+ Display .FRAME .getContentPane ().add (new JLabel ("<html><body><strong>Calculating passcode...</strong></body></html>" ));
96
+ Display .refresh ();
97
+ String passcode = RestrictionsRecovery .calculate (pair .getKey (), pair .getSalt (), false );
98
+ if (passcode == null ) {
99
+ throw new Exception ("Passcode could not be found. Key and salt does not correspond to any passcode between 0000 and 9999." );
100
+ } else {
101
+ JOptionPane .showMessageDialog (null , "Passcode: " + passcode );
102
+ }
103
+ Display .FRAME .getContentPane ().removeAll ();
104
+ Display .createDisplay ();
105
+ Display .refresh ();
106
+ } catch (Exception ex ) {
107
+ Display .handleException (ex , true );
108
+ }
109
+ }
110
+ }
111
+ public static void refresh () {
112
+ Display .FRAME .revalidate ();
113
+ Display .FRAME .repaint ();
114
+ }
115
+ public static class BackListener implements ActionListener {
116
+ public void actionPerformed (ActionEvent ev ) {
117
+ Display .FRAME .getContentPane ().removeAll ();
118
+ Display .createDisplay ();
119
+ Display .refresh ();
120
+ }
121
+ }
29
122
public class KeySaltButtonListener implements ActionListener {
30
123
public void actionPerformed (ActionEvent ev ) {
31
124
try {
32
125
String key = JOptionPane .showInputDialog ("Key?" );
33
126
String salt = JOptionPane .showInputDialog ("Salt?" );
127
+ Display .DESC .setText ("<html><b>Calculating passcode...</b></html>" );
128
+ Display .refresh ();
34
129
String passcode = RestrictionsRecovery .calculate (key , salt , false );
35
130
if (passcode == null ) {
36
- throw new Exception ();
131
+ throw new Exception ("Passcode could not be found. Key and salt does not correspond to any passcode between 0000 and 9999." );
37
132
} else {
38
133
JOptionPane .showMessageDialog (null , "Passcode: " + passcode );
39
134
}
40
135
} catch (Exception ex ) {
41
- Display .handleException (ex );
136
+ Display .handleException (ex , true );
42
137
}
138
+ Display .DESC .setText (RRConst .DESC );
139
+ Display .refresh ();
43
140
}
44
141
}
45
142
public class FileButtonListener implements ActionListener {
46
143
public void actionPerformed (ActionEvent ev ) {
47
144
try {
48
- String file = JOptionPane .showInputDialog ("Property list path?" );
145
+ String file = JOptionPane .showInputDialog ("Property list path? (Do not include quotes) " );
49
146
KeySaltPair pair = PropertyListReader .getKeyAndSaltFromPlist (file );
147
+ Display .DESC .setText ("<html><b>Calculating passcode...</b></html>" );
148
+ Display .refresh ();
50
149
String passcode = RestrictionsRecovery .calculate (pair .getKey (), pair .getSalt (), false );
51
150
if (passcode == null ) {
52
- throw new Exception ();
151
+ throw new Exception ("Passcode could not be found. Key and salt does not correspond to any passcode between 0000 and 9999." );
53
152
} else {
54
153
JOptionPane .showMessageDialog (null , "Passcode: " + passcode );
55
154
}
56
155
} catch (Exception ex ) {
57
- Display .handleException (ex );
156
+ Display .handleException (ex , true );
58
157
}
158
+ Display .DESC .setText (RRConst .DESC );
159
+ Display .refresh ();
59
160
}
60
161
}
61
162
public class SSHButtonListener implements ActionListener {
@@ -64,26 +165,32 @@ public void actionPerformed(ActionEvent ev) {
64
165
String ip = JOptionPane .showInputDialog ("Device IP address?" );
65
166
String password = JOptionPane .showInputDialog ("Device root password?" );
66
167
String port = JOptionPane .showInputDialog ("Device SSH port?" );
168
+ Display .DESC .setText ("<html><b>Calculating passcode...</b></html>" );
169
+ Display .refresh ();
67
170
RestrictionsRecovery .downloadViaSSH (ip , Integer .parseInt (port ), password , false );
68
171
KeySaltPair pair = PropertyListReader .getKeyAndSaltFromPlist ("password.plist" );
69
172
String passcode = RestrictionsRecovery .calculate (pair .getKey (), pair .getSalt (), false );
70
173
if (passcode == null ) {
71
- throw new Exception ();
174
+ throw new Exception ("Passcode could not be found. Key and salt does not correspond to any passcode between 0000 and 9999." );
72
175
} else {
73
176
JOptionPane .showMessageDialog (null , "Passcode: " + passcode );
74
177
}
75
178
} catch (Exception ex ) {
76
- Display .handleException (ex );
179
+ Display .handleException (ex , true );
77
180
}
181
+ Display .DESC .setText (RRConst .DESC );
182
+ Display .refresh ();
78
183
}
79
184
}
80
185
public class IproxyButtonListener implements ActionListener {
81
186
public void actionPerformed (ActionEvent ev ) {
82
187
// not implemented yet
83
188
}
84
189
}
85
- private static void handleException (Exception ex ) {
190
+ private static void handleException (Exception ex , boolean message ) {
86
191
ex .printStackTrace ();
87
- JOptionPane .showMessageDialog (null , "Error occurred while calculating the passcode. Check the console for details." );
192
+ if (message ) {
193
+ JOptionPane .showMessageDialog (null , "Error: " + ex .getClass ().toString ().split (" " )[1 ] + ": " + ex .getMessage ());
194
+ }
88
195
}
89
196
}
0 commit comments