Skip to content

Commit 97e32f5

Browse files
committed
Refactor class loading and improve method finding in Unobfuscator
Signed-off-by: Dev4Mod <[email protected]>
1 parent d19680b commit 97e32f5

File tree

4 files changed

+43
-25
lines changed

4 files changed

+43
-25
lines changed

app/src/main/java/com/wmods/wppenhacer/xposed/core/devkit/Unobfuscator.java

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,12 @@ public synchronized static Class<?> findFirstClassUsingStringsFilter(ClassLoader
150150
}
151151

152152
public synchronized static Class<?> findFirstClassUsingName(ClassLoader classLoader, StringMatchType type, String name) throws Exception {
153-
var result = dexkit.findClass(FindClass.create().matcher(ClassMatcher.create().className(name, type)));
154-
if (result.isEmpty()) return null;
155-
return result.get(0).getInstance(classLoader);
153+
return UnobfuscatorCache.getInstance().getClass(classLoader, name, () -> {
154+
var result = dexkit.findClass(FindClass.create().matcher(ClassMatcher.create().className(name, type)));
155+
if (result.isEmpty())
156+
throw new ClassNotFoundException("Class not found: " + name);
157+
return result.get(0).getInstance(classLoader);
158+
});
156159
}
157160

158161
public synchronized static String getMethodDescriptor(Method method) {
@@ -1495,9 +1498,12 @@ public synchronized static Class getFilterView(ClassLoader loader) throws Except
14951498

14961499
public synchronized static Class loadActionUser(ClassLoader loader) throws Exception {
14971500
return UnobfuscatorCache.getInstance().getClass(loader, () -> {
1498-
var results = dexkit.findClass(new FindClass().matcher(new ClassMatcher().addUsingString("UserActions/reportIfBadTime: time=")));
1499-
if (results.isEmpty()) throw new RuntimeException("ActionUser class not found");
1500-
return results.get(0).getInstance(loader);
1501+
for (String s : List.of("UserActions/reportIfBadTime: time=", "UserActions/createFMessageTextFromUserInputs", "UserActions/userActionKeepInChat")) {
1502+
var clazz = findFirstClassUsingStrings(loader, StringMatchType.Contains, s);
1503+
if (clazz != null)
1504+
return clazz;
1505+
}
1506+
throw new ClassNotFoundException("ActionUser class not found");
15011507
});
15021508
}
15031509

@@ -1533,7 +1539,10 @@ public synchronized static Method loadOnInsertReceipt(ClassLoader classLoader) t
15331539

15341540
public synchronized static Method loadSendAudioTypeMethod(ClassLoader classLoader) throws Exception {
15351541
return UnobfuscatorCache.getInstance().getMethod(classLoader, () -> {
1536-
var method = classLoader.loadClass("com.whatsapp.status.playback.MessageReplyActivity").getMethod("onActivityResult", int.class, int.class, android.content.Intent.class);
1542+
var classMsgReplyAct = Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "MessageReplyActivity");
1543+
if (classMsgReplyAct == null)
1544+
throw new ClassNotFoundException("Class MessageReplyActivity not found");
1545+
var method = classMsgReplyAct.getMethod("onActivityResult", int.class, int.class, android.content.Intent.class);
15371546
var methodData = Objects.requireNonNull(dexkit.getMethodData(method));
15381547
var invokes = methodData.getInvokes();
15391548
for (var invoke : invokes) {
@@ -1544,7 +1553,7 @@ public synchronized static Method loadSendAudioTypeMethod(ClassLoader classLoade
15441553
return m1;
15451554
}
15461555
}
1547-
throw new RuntimeException("SendAudioType method not found");
1556+
throw new NoSuchMethodException("SendAudioType method not found");
15481557
});
15491558
}
15501559

@@ -1941,16 +1950,18 @@ public static Class<?> loadFilterItemClass(ClassLoader classLoader) throws Excep
19411950
MethodMatcher.create().addUsingNumber(Utils.getID("invisible_height_placeholder", "id"))
19421951
.addUsingNumber(Utils.getID("container_view", "id"))
19431952
));
1944-
if (methodList.isEmpty()) {
1945-
var applyClazz = findFirstClassUsingStrings(classLoader, StringMatchType.Contains, "has_seen_detected_outcomes_nux");
1946-
if (applyClazz != null) {
1947-
methodList = dexkit.findMethod(FindMethod.create().matcher(
1948-
MethodMatcher.create().paramTypes(View.class, applyClazz)
1949-
));
1950-
}
1953+
if (!methodList.isEmpty())
1954+
return methodList.get(0).getClassInstance(classLoader);
1955+
1956+
for (var s : List.of("ConversationsFilter/selectFilter", "has_seen_detected_outcomes_nux")) {
1957+
var applyClazz = findFirstClassUsingStrings(classLoader, StringMatchType.Contains, s);
1958+
if (applyClazz == null) continue;
1959+
methodList = dexkit.findMethod(FindMethod.create().matcher(
1960+
MethodMatcher.create().paramTypes(View.class, applyClazz)
1961+
));
1962+
if (!methodList.isEmpty()) return methodList.get(0).getClassInstance(classLoader);
19511963
}
1952-
if (methodList.isEmpty()) throw new RuntimeException("FilterItemClass Not Found");
1953-
return methodList.get(0).getClassInstance(classLoader);
1964+
throw new RuntimeException("FilterItemClass Not Found");
19541965
});
19551966
}
19561967

app/src/main/java/com/wmods/wppenhacer/xposed/core/devkit/UnobfuscatorCache.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,15 @@ private Method getMethodFromString(ClassLoader loader, String value) {
269269

270270

271271
public Class<?> getClass(ClassLoader loader, FunctionCall<Class<?>> functionCall) throws Exception {
272-
var methodName = getKeyName();
273-
String value = sPrefsCacheHooks.getString(methodName, null);
272+
return getClass(loader, getKeyName(), functionCall);
273+
}
274+
275+
public Class<?> getClass(ClassLoader loader, String key, FunctionCall<Class<?>> functionCall) throws Exception {
276+
String value = sPrefsCacheHooks.getString(key, null);
274277
if (value == null) {
275278
Class<?> result = functionCall.call();
276-
if (result == null) throw new Exception("Class is null: " + methodName);
277-
saveClass(methodName, result);
279+
if (result == null) throw new ClassNotFoundException("Class not found: " + key);
280+
saveClass(key, result);
278281
return result;
279282
}
280283
return XposedHelpers.findClass(value, loader);

app/src/main/java/com/wmods/wppenhacer/xposed/features/customization/ShowOnline.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,14 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
176176
if (WppCore.isGroup(jid)) return;
177177

178178
var tokenDBInstance = fieldTokenDBInstance.get(mInstancePresence);
179+
log(tokenDBInstance.getClass().toString());
179180
var tokenData = ReflectionUtils.callMethod(tcTokenMethod, tokenDBInstance, jidObject);
180181
var tokenObj = tokenClass.getConstructors()[0].newInstance(tokenData == null ? null : XposedHelpers.getObjectField(tokenData, "A01"));
181182
sendPresenceMethod.invoke(null, jidObject, null, tokenObj, mInstancePresence);
183+
logDebug("sendPresenceMethod", sendPresenceMethod);
182184

183185
var status = (String) ReflectionUtils.callMethod(getStatusUser, mStatusUser, object, false);
186+
log(status);
184187
var currentPosition = (int) ReflectionUtils.callMethod(getAdapterPositionMethod, viewHolder);
185188
if (currentPosition != position) return;
186189
if (!TextUtils.isEmpty(status) && status.trim().equals(UnobfuscatorCache.getInstance().getString("online"))) {

app/src/main/java/com/wmods/wppenhacer/xposed/features/general/Others.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.wmods.wppenhacer.xposed.utils.Utils;
2424

2525
import org.json.JSONObject;
26+
import org.luckypray.dexkit.query.enums.StringMatchType;
2627

2728
import java.lang.reflect.Modifier;
2829
import java.util.ArrayList;
@@ -280,8 +281,8 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
280281
private void callInfo() throws Exception {
281282
if (!prefs.getBoolean("call_info", false)) return;
282283

283-
var clsCallEventCallback = classLoader.loadClass("com.whatsapp.calling.service.VoiceServiceEventCallback");
284-
Class<?> clsWamCall = classLoader.loadClass("com.whatsapp.fieldstats.events.WamCall");
284+
var clsCallEventCallback = Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "VoiceServiceEventCallback");
285+
Class<?> clsWamCall = Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "WamCall");
285286

286287
XposedBridge.hookAllMethods(clsCallEventCallback, "fieldstatsReady", new XC_MethodHook() {
287288
@Override
@@ -444,7 +445,7 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
444445
}
445446
}
446447
});
447-
var voicenoteClass = classLoader.loadClass("com.whatsapp.search.views.itemviews.VoiceNoteProfileAvatarView");
448+
var voicenoteClass = Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "VoiceNoteProfileAvatarView");
448449
var method = ReflectionUtils.findAllMethodsUsingFilter(voicenoteClass, method1 -> method1.getParameterCount() == 4 && method1.getParameterTypes()[0] == int.class && method1.getReturnType().equals(void.class));
449450
XposedBridge.hookMethod(method[method.length - 1], new XC_MethodHook() {
450451
@SuppressLint("SetTextI18n")
@@ -496,7 +497,7 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
496497

497498

498499
private void autoNextStatus() throws Exception {
499-
Class<?> StatusPlaybackContactFragmentClass = classLoader.loadClass("com.whatsapp.status.playback.fragment.StatusPlaybackContactFragment");
500+
Class<?> StatusPlaybackContactFragmentClass = Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "StatusPlaybackContactFragment");
500501
var runNextStatusMethod = Unobfuscator.loadNextStatusRunMethod(classLoader);
501502
XposedBridge.hookMethod(runNextStatusMethod, new XC_MethodHook() {
502503
@Override

0 commit comments

Comments
 (0)