Skip to content

Commit 9fe7002

Browse files
committed
Refactor receipt handling to improve user JID validation and key message retrieval
Signed-off-by: Dev4Mod <[email protected]>
1 parent ba93429 commit 9fe7002

File tree

5 files changed

+54
-28
lines changed

5 files changed

+54
-28
lines changed

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,17 +206,22 @@ public synchronized static Method loadGhostModeMethod(ClassLoader classLoader) t
206206
public synchronized static Method loadReceiptMethod(ClassLoader classLoader) throws Exception {
207207
return UnobfuscatorCache.getInstance().getMethod(classLoader, () -> {
208208
var classDeviceJid = Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "jid.DeviceJid");
209+
var classPhoneUserJid = Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "jid.PhoneUserJid");
209210
var methods = dexkit.findMethod(
210211
FindMethod.create()
211-
.matcher(MethodMatcher.create().addUsingString("receipt")
212-
.paramCount(2, 7)
213-
.paramTypes(null, classDeviceJid, null, null, null, null, null)
212+
.matcher(MethodMatcher.create()
213+
.addUsingString("receipt")
214+
.paramCount(5, 8)
214215
)
215216
);
216-
if (methods.isEmpty())
217-
throw new NoSuchMethodError("Receipt method not found");
218217

219-
return methods.get(0).getMethodInstance(classLoader);
218+
for (var method : methods) {
219+
var params = method.getParamTypeNames();
220+
if (params.contains(classDeviceJid.getName()) && params.contains(classPhoneUserJid.getName()))
221+
return method.getMethodInstance(classLoader);
222+
}
223+
224+
throw new NoSuchMethodError("Receipt method not found");
220225
});
221226
}
222227

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
488488
}
489489
var mediaType = results.get(0);
490490
var audioType = results.get(1);
491-
if ((int) mediaType.second != 2 && (int) mediaType.second != 9) return;
491+
if (mediaType.second != 2 && mediaType.second != 9) return;
492492
param.args[audioType.first] = audio_type - 1; // 1 = voice notes || 0 = audio voice
493493
}
494494
});
@@ -559,6 +559,7 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
559559
if (message.arg1 != 5) return;
560560
BaseBundle baseBundle = (BaseBundle) message.obj;
561561
var jid = baseBundle.getString("jid");
562+
if (TextUtils.isEmpty(jid)) return;
562563
var userjid = new FMessageWpp.UserJid(jid);
563564
if (userjid.isGroup()) return;
564565
var name = WppCore.getContactName(userjid);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,8 @@ private static void updateMessageStatusView(String rawJid, List<FMessageWpp> mes
426426

427427
private void sendBlueTick(FMessageWpp.UserJid userJid) {
428428
CompletableFuture.runAsync(() -> {
429-
if (Objects.equals(userJid.getPhoneNumber(), Utils.getMyNumber())) return;
429+
if (Objects.equals(userJid.getPhoneNumber(), Utils.getMyNumber()) || Objects.requireNonNullElse(userJid.getUserRawString(), "").contains("lid_me"))
430+
return;
430431
var messages = new ArrayList<FMessageWpp>();
431432
var hideSeenMessagesssages = MessageHistory.getInstance().getHideSeenMessages(userJid.getPhoneRawString(), MessageHistory.MessageType.MESSAGE_TYPE, false);
432433
for (var message : hideSeenMessagesssages) {

app/src/main/java/com/wmods/wppenhacer/xposed/features/privacy/HideReceipt.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.wmods.wppenhacer.xposed.features.privacy;
22

3+
import static com.wmods.wppenhacer.xposed.features.privacy.HideSeen.getKeyMessage;
4+
35
import androidx.annotation.NonNull;
46

57
import com.wmods.wppenhacer.xposed.core.Feature;
@@ -37,10 +39,14 @@ public void doHook() throws Exception {
3739
XposedBridge.hookMethod(method, new XC_MethodHook() {
3840
@Override
3941
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
40-
var userJid = ReflectionUtils.getArg(param.args, Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "jid.Jid"), 0);
41-
var currentUserJid = new FMessageWpp.UserJid(userJid);
42-
var key = ReflectionUtils.getArg(param.args, FMessageWpp.Key.TYPE, 0);
43-
var fmessage = new FMessageWpp.Key(key).getFMessage();
42+
var userJidObject = ReflectionUtils.getArg(param.args, Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "jid.Jid"), 0);
43+
if (userJidObject == null) return;
44+
var strings = ReflectionUtils.findClassesOfType(((Method) param.method).getParameterTypes(), String.class);
45+
FMessageWpp.Key keyMessage = getKeyMessage(param, userJidObject, strings);
46+
if (keyMessage == null)
47+
return;
48+
var currentUserJid = new FMessageWpp.UserJid(userJidObject);
49+
var fmessage = keyMessage.getFMessage();
4450
if (fmessage != null) {
4551
currentUserJid = fmessage.getKey().remoteJid;
4652
if (MessageHistory.getInstance().getHideSeenMessage(fmessage.getKey().remoteJid.getPhoneRawString(), fmessage.getKey().messageID, fmessage.isViewOnce() ? MessageHistory.MessageType.VIEW_ONCE_TYPE : MessageHistory.MessageType.MESSAGE_TYPE) != null) {
@@ -49,7 +55,7 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
4955
}
5056
var privacy = CustomPrivacy.getJSON(currentUserJid.getPhoneNumber());
5157
var customHideReceipt = privacy.optBoolean("HideReceipt", hideReceipt);
52-
var msgTypeIdx = ReflectionUtils.findIndexOfType(((Method) param.method).getParameterTypes(), String.class);
58+
var msgTypeIdx = strings.get(strings.size() - 1).first;
5359
var customHideRead = privacy.optBoolean("HideSeen", hideread);
5460
if (param.args[msgTypeIdx] != "sender" && (customHideReceipt || ghostmode)) {
5561
if (WppCore.getCurrentConversation() == null || customHideRead)

app/src/main/java/com/wmods/wppenhacer/xposed/features/privacy/HideSeen.java

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.wmods.wppenhacer.xposed.features.privacy;
22

3+
import android.text.TextUtils;
4+
import android.util.Pair;
5+
36
import androidx.annotation.NonNull;
47

58
import com.wmods.wppenhacer.xposed.core.Feature;
@@ -13,6 +16,7 @@
1316
import org.luckypray.dexkit.query.enums.StringMatchType;
1417

1518
import java.lang.reflect.Method;
19+
import java.util.List;
1620
import java.util.Objects;
1721
import java.util.Set;
1822

@@ -27,6 +31,19 @@ public HideSeen(ClassLoader loader, XSharedPreferences preferences) {
2731
super(loader, preferences);
2832
}
2933

34+
protected static FMessageWpp.Key getKeyMessage(XC_MethodHook.MethodHookParam param, Object userJidObject, List<Pair<Integer, Class<? extends String>>> strings) {
35+
var keyObject = ReflectionUtils.getArg(param.args, FMessageWpp.Key.TYPE, 0);
36+
if (keyObject == null) {
37+
if (strings.size() < 2)
38+
return null;
39+
var idMessage = (String) param.args[strings.get(0).first];
40+
var userJid = new FMessageWpp.UserJid(userJidObject);
41+
return new FMessageWpp.Key(idMessage, userJid, false);
42+
} else {
43+
return new FMessageWpp.Key(keyObject);
44+
}
45+
}
46+
3047
@Override
3148
public void doHook() throws Exception {
3249

@@ -52,16 +69,10 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
5269
return;
5370
}
5471
var lid = (String) XposedHelpers.getObjectField(sendReadReceiptJob, "jid");
55-
logDebug(lid);
56-
FMessageWpp.UserJid userJid = null;
57-
try {
58-
userJid = new FMessageWpp.UserJid(lid);
59-
if (userJid.isNull()) return;
60-
} catch (Throwable e) {
61-
// WhatsApp crashes when attempting to create UserJid from MeJid or LidMeJid
62-
// and this issue can be ignored since we don't need to hide something from ourself
72+
if (TextUtils.isEmpty(lid) || lid.contains("lid_me") || lid.contains("status_me"))
6373
return;
64-
}
74+
FMessageWpp.UserJid userJid = new FMessageWpp.UserJid(lid);
75+
if (userJid.isNull()) return;
6576
var privacy = CustomPrivacy.getJSON(userJid.getPhoneNumber());
6677

6778
var customHideRead = privacy.optBoolean("HideSeen", hideread);
@@ -95,23 +106,25 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
95106

96107

97108
Method ReceiptMethod = Unobfuscator.loadReceiptMethod(classLoader);
98-
logDebug(Unobfuscator.getMethodDescriptor(ReceiptMethod));
109+
logDebug("ReceiptMethod", Unobfuscator.getMethodDescriptor(ReceiptMethod));
99110

100111
XposedBridge.hookMethod(ReceiptMethod, new XC_MethodHook() {
101112
@Override
102113
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
103114
if (WppCore.getCurrentConversation() != WppCore.getCurrentActivity()) return;
104-
var keyObject = ReflectionUtils.getArg(param.args, FMessageWpp.Key.TYPE, 0);
105-
var keyMessage = new FMessageWpp.Key(keyObject);
115+
var userJidObject = ReflectionUtils.getArg(param.args, Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "jid.Jid"), 0);
116+
if (userJidObject == null) return;
117+
var strings = ReflectionUtils.findClassesOfType(((Method) param.method).getParameterTypes(), String.class);
118+
FMessageWpp.Key keyMessage = getKeyMessage(param, userJidObject, strings);
119+
if (keyMessage == null)
120+
return;
106121
var fmessage = keyMessage.getFMessage();
107122
if (fmessage != null) {
108123
if (MessageHistory.getInstance().getHideSeenMessage(keyMessage.remoteJid.getUserRawString(), keyMessage.messageID, fmessage.isViewOnce() ? MessageHistory.MessageType.VIEW_ONCE_TYPE : MessageHistory.MessageType.MESSAGE_TYPE) != null) {
109124
return;
110125
}
111126
}
112-
var userJid = ReflectionUtils.getArg(param.args, Unobfuscator.findFirstClassUsingName(classLoader, StringMatchType.EndsWith, "jid.Jid"), 0);
113-
if (userJid == null) return;
114-
var msgTypeIdx = ReflectionUtils.findIndexOfType(((Method) param.method).getParameterTypes(), String.class);
127+
var msgTypeIdx = strings.get(strings.size() - 1).first;
115128
if (!Objects.equals("read", param.args[msgTypeIdx])) return;
116129
var privacy = CustomPrivacy.getJSON(keyMessage.remoteJid.getPhoneNumber());
117130
var customHideRead = privacy.optBoolean("HideSeen", hideread);

0 commit comments

Comments
 (0)