20
20
import java .text .SimpleDateFormat ;
21
21
import java .util .ArrayList ;
22
22
import java .util .Date ;
23
+ import java .util .List ;
23
24
import java .util .Scanner ;
24
25
25
26
import de .robv .android .xposed .IXposedHookLoadPackage ;
29
30
import de .robv .android .xposed .XposedHelpers ;
30
31
import de .robv .android .xposed .callbacks .XC_LoadPackage ;
31
32
33
+ /**
34
+ * @noinspection ALL
35
+ */
32
36
public class Module implements IXposedHookLoadPackage , IXposedHookZygoteInit {
33
37
34
38
@@ -38,39 +42,50 @@ public class Module implements IXposedHookLoadPackage, IXposedHookZygoteInit {
38
42
* Init the preferences
39
43
*/
40
44
private String initPreferences () {
41
- XposedPreferences .loadPreferences ();
42
- XposedPreferences .reloadPrefs ();
45
+ try {
46
+ XposedPreferences .loadPreferences ();
47
+ XposedPreferences .reloadPrefs ();
43
48
44
- if (XposedPreferences .getPrefs ().getString ("Mode" , "Normal" ).equals ("Normal" )) {
45
- XposedBridge .log ("(IGExperiments) Using class name from Github" );
49
+ String mode = XposedPreferences .getPrefs ().getString ("Mode" , "Normal" );
46
50
47
- return "Normal" ;
48
- } else if (XposedPreferences .getPrefs ().getString ("Mode" , "Normal" ).equals ("Auto" )) {
49
- XposedBridge .log ("(IGExperiments) Dynamic searching" );
51
+ if (mode .equals ("Normal" )) {
52
+ XposedBridge .log ("(IGExperiments) Using class name from Github" );
53
+ return "Normal" ;
54
+ } else if (mode .equals ("Auto" )) {
55
+ XposedBridge .log ("(IGExperiments) Dynamic searching" );
56
+ return "Auto" ;
57
+ }
50
58
51
- return "Auto" ;
52
- }
53
- XposedBridge .log ("(IGExperiments) Using class name from preferences" );
54
- return "Hecker" ;
59
+ XposedBridge .log ("(IGExperiments) Using class name from preferences" );
60
+ return "Hecker" ;
55
61
62
+ } catch (Exception e ) {
63
+ XposedBridge .log ("(IGExperiments) Exception in initPreferences, defaulting to 'Normal': " + e .getMessage ());
64
+ return "Normal" ; // Default to "Normal" if an exception occurs
65
+ }
56
66
}
57
67
58
68
59
69
/**
60
70
* Initialize the class and method to hook
61
71
*/
62
72
private void initElemToHook () {
63
- className = XposedPreferences .getPrefs ().getString ("className" , "" );
64
- methodName = XposedPreferences .getPrefs ().getString ("methodName" , "" );
65
- secondClassName = XposedPreferences .getPrefs ().getString ("secondClassName" , "" );
73
+ try {
74
+ className = XposedPreferences .getPrefs ().getString ("className" , "" );
75
+ methodName = XposedPreferences .getPrefs ().getString ("methodName" , "" );
76
+ secondClassName = XposedPreferences .getPrefs ().getString ("secondClassName" , "" );
66
77
67
78
68
- if (className .equals ("" )) {
69
- XposedBridge .log ("(IGExperiments) No class name found, using default" );
70
- className = Utils .DEFAULT_CLASS_TO_HOOK ;
71
- methodName = Utils .DEFAULT_METHOD_TO_HOOK ;
72
- secondClassName = Utils .DEFAULT_SECOND_CLASS_TO_HOOK ;
79
+ if (className .equals ("" )) {
80
+ XposedBridge .log ("(IGExperiments) No class name found, using default" );
81
+ className = Utils .DEFAULT_CLASS_TO_HOOK ;
82
+ methodName = Utils .DEFAULT_METHOD_TO_HOOK ;
83
+ secondClassName = Utils .DEFAULT_SECOND_CLASS_TO_HOOK ;
84
+ }
85
+ } catch (Exception ignored ) {
86
+
73
87
}
88
+
74
89
}
75
90
76
91
@ Override
@@ -174,7 +189,7 @@ protected Object replaceHookedMethod(MethodHookParam param) {
174
189
175
190
success = true ;
176
191
177
- // Dynamic search logic
192
+ // Dynamic search logic
178
193
} else if (type .equals ("Auto" )) {
179
194
try {
180
195
// Fixed method and second class
@@ -192,72 +207,83 @@ protected Object replaceHookedMethod(MethodHookParam param) {
192
207
String majorVersion = versionParts [0 ];
193
208
int majorVersionNumber = Integer .parseInt (majorVersion );
194
209
195
- if (majorVersionNumber >= 334 ) { // if the instagram version starts with 334 or more it would be compatible with auto mode
210
+ if (majorVersionNumber >= 334 ) { // Check if Instagram version is compatible with auto mode
196
211
XposedBridge .log (getTime () + "(IGExperiments) Searching for the correct class to hook..." );
197
212
198
213
// Try to hook into multiple class names incrementally
199
- String characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
214
+ String characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
215
+ int hookCount = 0 ; // Counter for successful hooks
216
+
217
+ // Initialize a list to store the names of successfully hooked classes
218
+ List <String > hookedClasses = new ArrayList <>();
200
219
201
220
outerLoop :
202
221
for (char first : characters .toCharArray ()) {
203
222
for (char second : characters .toCharArray ()) {
204
223
for (char third : characters .toCharArray ()) {
205
224
String classToHook = "X." + first + second + third ; // Generate class name
206
225
try {
207
- // DEV PURPOSES
208
- // XposedBridge.log("(IGExperiments) Attempting to inspect class: " + classToHook);
209
-
226
+ // Attempt to find the target class and second target class
210
227
Class <?> targetClass = XposedHelpers .findClass (classToHook , lpparam .classLoader );
211
228
Class <?> secondTargetClass = XposedHelpers .findClass (secondClassToHook , lpparam .classLoader );
212
229
213
- // Check if the method returns a Boolean
214
- boolean hasIsEmployee = false ;
215
- for (Method method : targetClass .getDeclaredMethods ()) {
216
- if (method .getReturnType () == Boolean .TYPE ) {
217
- hasIsEmployee = true ;
218
- break ;
230
+ // Catch NoClassDefFoundError within the method inspection loop
231
+ try {
232
+ //XposedBridge.log("Trying class: " + classToHook);
233
+ // Check if the target class has a Boolean-returning method named A00 with one parameter
234
+ for (Method method : targetClass .getDeclaredMethods ()) {
235
+ if (method .getName ().equals ("A00" ) &&
236
+ method .getReturnType () == Boolean .TYPE &&
237
+ method .getParameterCount () == 1 ) {
238
+
239
+ XposedBridge .log ("(IGExperiments) Hooking into class: " + classToHook );
240
+ XposedHelpers .findAndHookMethod (targetClass , "A00" , secondTargetClass ,
241
+ new XC_MethodReplacement () {
242
+ @ Override
243
+ protected Object replaceHookedMethod (MethodHookParam param ) {
244
+ //XposedBridge.log("(IGExperiments) Successfully Hooked into class: " + classToHook);
245
+ return true ;
246
+ }
247
+ });
248
+
249
+ // Add to the list of hooked classes
250
+ hookedClasses .add (classToHook );
251
+ hookCount ++; // Increment counter for each successful hook
252
+ break ; // No need to check further methods in this class
253
+ }
219
254
}
255
+ } catch (NoClassDefFoundError e ) {
256
+ // Log and continue to the next class if NoClassDefFoundError is encountered
257
+ //XposedBridge.log("(IGExperiments) Dependency not found while inspecting " + classToHook + ", skipping.");
258
+ continue ;
220
259
}
221
260
222
- if (!hasIsEmployee ) {
223
- // DEV PURPOSES
224
- // XposedBridge.log("(IGExperiments) Class " + classToHook + " does not return a Boolean, skipping...");
225
- continue ; // Skip this class if it doesn't have the expected method
226
- }
227
-
228
- XposedBridge .log ("(IGExperiments) Found target class with 'is_employee': " + classToHook );
229
-
230
- // Hook the method A00 in this class
231
- XposedHelpers .findAndHookMethod (targetClass , methodToHook , secondTargetClass ,
232
- new XC_MethodReplacement () {
233
- @ Override
234
- protected Object replaceHookedMethod (MethodHookParam param ) {
235
- XposedBridge .log ("(IGExperiments) Successfully Hooked into class: " + classToHook );
236
- return true ;
237
- }
238
- });
239
-
240
- success = true ; // Mark as successful if a method was hooked
241
- break outerLoop ; // Exit loop if successful
242
261
} catch (XposedHelpers .ClassNotFoundError e ) {
243
- // If the class doesn't exist, continue trying
244
- XposedBridge .log ("(IGExperiments) Class " + classToHook + " not found, trying next." );
262
+ //XposedBridge.log("(IGExperiments) Class " + classToHook + " not found, trying next.");
245
263
} catch (NoSuchMethodError e ) {
246
- XposedBridge .log ("(IGExperiments) Method A00 not found in class: " + classToHook );
264
+ // XposedBridge.log("(IGExperiments) Method A00 not found in class: " + classToHook);
247
265
} catch (Exception e ) {
248
- XposedBridge .log ("(IGExperiments) Failed to hook class: " + classToHook + ", error: " + e .getMessage ());
266
+ // XposedBridge.log("(IGExperiments) Failed to hook class: " + classToHook + ", error: " + e.getMessage());
249
267
}
250
268
}
251
269
}
252
270
}
253
271
254
- if (!success ) {
272
+ // After completing the loop, check if multiple hooks were set and show a toast
273
+ if (hookCount > 1 ) {
274
+ showToast ("Multiple hooks set. Please disable the module if you encounter issues." );
275
+ }
276
+ if (!hookedClasses .isEmpty ()) {
277
+ XposedBridge .log ("(IGExperiments) Successfully hooked classes:" );
278
+ for (String hookedClass : hookedClasses ) {
279
+ XposedBridge .log ("(IGExperiments) Hooked class: " + hookedClass );
280
+ }
281
+ } else {
255
282
XposedBridge .log ("(IGExperiments) No matching class found." );
256
283
}
257
284
258
-
259
285
} else {
260
- showToast ("Versions that are older than 334.x aren't compatible with auto mode!\n Try another mode." );
286
+ showToast ("Versions older than 334.x aren't compatible with auto mode! Try another mode." );
261
287
}
262
288
263
289
@@ -286,7 +312,7 @@ protected Object replaceHookedMethod(MethodHookParam param) {
286
312
private static String getJSONContent () {
287
313
try {
288
314
Log .println (Log .INFO , "IGexperiments" , "Reading raw content from github file" );
289
- URL url = new URL ("https://raw.githubusercontent.com/ReSo7200/IGexperiments /master/classes_to_hook .json" );
315
+ URL url = new URL ("https://raw.githubusercontent.com/ReSo7200/IGExperimentsUpdates /master/hooks .json" );
290
316
StrictMode .ThreadPolicy policy = new StrictMode .ThreadPolicy .Builder ().permitAll ().build ();
291
317
StrictMode .setThreadPolicy (policy );
292
318
Scanner s = new Scanner (url .openStream ());
0 commit comments