Skip to content

Commit 315f18f

Browse files
Merge branch 'master' into disable-update-check
2 parents 46c7822 + dd72111 commit 315f18f

File tree

23 files changed

+290
-195
lines changed

23 files changed

+290
-195
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676

7777
## Installation
7878
1. Ensure that your device is rooted.
79-
2. Install the Xposed Framework on your device.
79+
2. Install the Xposed Framework (recommend [this](https://github.com/JingMatrix/LSPosed) LPosed) on
80+
your device.
8081
3. Download the WaEnhancer from the [Actions](https://github.com/Dev4Mod/WaEnhancer/actions) section.
8182
4. Install the WaEnhancer APK.
8283
5. Enable the WaEnhancer module in the Xposed Installer app.

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

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import android.view.LayoutInflater;
1010
import android.view.Menu;
1111
import android.view.MenuInflater;
12+
import android.view.MenuItem;
1213
import android.view.View;
1314
import android.view.ViewGroup;
1415
import android.widget.FrameLayout;
@@ -866,9 +867,12 @@ public synchronized static Method loadSendPresenceMethod(ClassLoader loader) thr
866867

867868
public synchronized static Method loadPinnedLimitMethod(ClassLoader loader) throws Exception {
868869
return UnobfuscatorCache.getInstance().getMethod(loader, () -> {
869-
var method = findFirstMethodUsingStrings(loader, StringMatchType.Contains, "count_progress");
870+
var methodList = dexkit.findMethod(FindMethod.create().matcher(MethodMatcher.create().addUsingString("count_progress").paramCount(1, 2)));
871+
if (methodList.isEmpty()) throw new Exception("PinnedLimit method not found");
872+
var menuItemName = MenuItem.class.getName();
873+
var method = methodList.parallelStream().filter(m -> m.getParamTypes().get(0).getName().equals(menuItemName)).findFirst().orElse(null);
870874
if (method == null) throw new Exception("PinnedLimit method not found");
871-
return method;
875+
return method.getMethodInstance(loader);
872876
});
873877
}
874878

@@ -960,23 +964,13 @@ public synchronized static Method loadChatLimitDelete2Method(ClassLoader loader)
960964

961965
public synchronized static Method loadNewMessageMethod(ClassLoader loader) throws Exception {
962966
return UnobfuscatorCache.getInstance().getMethod(loader, () -> {
963-
var clazzMessage = loadFMessageClass(loader);
964-
var clazzData = Objects.requireNonNull(dexkit.getClassData(clazzMessage));
965-
var methodData = clazzData.findMethod(new FindMethod().matcher(new MethodMatcher().addUsingString("\n").returnType(String.class)));
966-
if (methodData.isEmpty()) {
967-
var field = clazzMessage.getDeclaredField("A02");
968-
methodData = clazzData.findMethod(new FindMethod().matcher(new MethodMatcher().addUsingField(DexSignUtil.getFieldDescriptor(field)).returnType(String.class)));
969-
}
970-
if (methodData.isEmpty()) {
971-
var csClazzData = dexkit.findClass(FindClass.create().matcher(ClassMatcher.create().addUsingString("FMessageSystemScheduledCallStart/setData index out of bounds: "))).singleOrNull();
972-
if (csClazzData != null) {
973-
var csClazz = csClazzData.getInstance(loader);
974-
var field = csClazz.getDeclaredField("A02");
975-
methodData = clazzData.findMethod(new FindMethod().matcher(new MethodMatcher().addUsingField(DexSignUtil.getFieldDescriptor(field)).returnType(String.class)));
976-
}
977-
}
978-
if (methodData.isEmpty()) throw new RuntimeException("NewMessage method not found");
979-
return methodData.get(0).getMethodInstance(loader);
967+
var clazzMessageName = loadFMessageClass(loader).getName();
968+
var listMethods = dexkit.findMethod(FindMethod.create().searchPackages("com.whatsapp").matcher(MethodMatcher.create().addUsingString("extra_payment_note", StringMatchType.Equals)));
969+
if (listMethods.isEmpty()) throw new Exception("NewMessage method not found");
970+
var invokes = listMethods.get(0).getInvokes();
971+
var method = invokes.parallelStream().filter(invoke -> clazzMessageName.equals(invoke.getDeclaredClass().getName()) && invoke.getReturnType() != null && invoke.getReturnType().getName().equals("java.lang.String")).findFirst().orElse(null);
972+
if (method == null) throw new RuntimeException("NewMessage method not found");
973+
return method.getMethodInstance(loader);
980974
});
981975
}
982976

@@ -988,15 +982,17 @@ public synchronized static Method loadOriginalMessageKey(ClassLoader loader) thr
988982
});
989983
}
990984

991-
992985
public synchronized static Method loadNewMessageWithMediaMethod(ClassLoader loader) throws Exception {
993-
var clazzMessage = Objects.requireNonNull(dexkit.getClassData(loadFMessageClass(loader)));
994-
var methodData = clazzMessage.findMethod(new FindMethod().matcher(new MethodMatcher().addUsingNumber(0x200000).returnType(String.class)));
995-
if (methodData.isEmpty()) {
996-
methodData = clazzMessage.findMethod(new FindMethod().matcher(new MethodMatcher().addUsingString("video").returnType(String.class)));
997-
if (methodData.isEmpty()) return null;
998-
}
999-
return methodData.get(0).getMethodInstance(loader);
986+
return UnobfuscatorCache.getInstance().getMethod(loader, () -> {
987+
var methodList = dexkit.findMethod(FindMethod.create().matcher(MethodMatcher.create().addUsingString("INSERT_TABLE_MESSAGE_QUOTED", StringMatchType.Equals)));
988+
if (methodList.isEmpty()) throw new Exception("NewMessageWithMedia method not found");
989+
var methodData = methodList.get(0);
990+
var invokes = methodData.getInvokes();
991+
var clazzMessageName = loadFMessageClass(loader).getName();
992+
var method = invokes.parallelStream().filter(invoke -> clazzMessageName.equals(invoke.getDeclaredClass().getName()) && invoke.getReturnType() != null && invoke.getReturnType().getName().equals("java.lang.String")).findFirst().orElse(null);
993+
if (method == null) throw new RuntimeException("NewMessageWithMedia method not found");
994+
return method.getMethodInstance(loader);
995+
});
1000996
}
1001997

1002998
public synchronized static Method loadMessageEditMethod(ClassLoader loader) throws Exception {

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import android.graphics.drawable.shapes.RectShape;
1919
import android.os.Bundle;
2020
import android.text.TextUtils;
21+
import android.util.DisplayMetrics;
2122
import android.util.Log;
2223
import android.util.LruCache;
2324
import android.view.View;
@@ -50,6 +51,7 @@
5051
import java.util.Arrays;
5152
import java.util.HashMap;
5253
import java.util.Objects;
54+
import java.util.Properties;
5355
import java.util.concurrent.CompletableFuture;
5456

5557
import cz.vutbr.web.css.CSSFactory;
@@ -75,6 +77,7 @@ public class CustomView extends Feature {
7577
private static File themeDir;
7678
private final HashMap<String, Drawable> chacheDrawables = new HashMap<>();
7779
private final HashMap<String, DocumentFile> chacheUris = new HashMap<>();
80+
private Properties properties;
7881

7982
public CustomView(@NonNull ClassLoader loader, @NonNull XSharedPreferences preferences) {
8083
super(loader, preferences);
@@ -92,6 +95,10 @@ public void doHook() throws Throwable {
9295
if ((TextUtils.isEmpty(filter_itens) && TextUtils.isEmpty(folder_theme) && TextUtils.isEmpty(custom_css)) || !prefs.getBoolean("custom_filters", true))
9396
return;
9497

98+
properties = Utils.extractProperties(prefs.getString("custom_css", ""));
99+
100+
changeDPI();
101+
95102
hookDrawableViews();
96103

97104
themeDir = new File(ThemePreference.rootDirectory, folder_theme);
@@ -105,11 +112,46 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
105112
var activity = (Activity) param.thisObject;
106113
View rootView = activity.getWindow().getDecorView().getRootView();
107114
rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> CompletableFuture.runAsync(() -> registerCssRules(activity, (ViewGroup) rootView, sheet)));
115+
108116
}
109117
});
110118

111119
}
112120

121+
private void changeDPI() {
122+
123+
String dpiStr = null;
124+
if (!Objects.equals(prefs.getString("change_dpi", "0"), "0")) {
125+
dpiStr = prefs.getString("change_dpi", "0");
126+
} else if (properties.getProperty("change_dpi") != null) {
127+
dpiStr = properties.getProperty("change_dpi");
128+
}
129+
130+
if (dpiStr == null) return;
131+
132+
int dpi = 0;
133+
try {
134+
dpi = Integer.parseInt(dpiStr);
135+
} catch (NumberFormatException e) {
136+
logDebug("Error parsing dpi: " + e.getMessage());
137+
}
138+
if (dpi != 0) {
139+
dpi = dpi == 0 ? Integer.parseInt(properties.getProperty("change_dpi")) : dpi;
140+
var res = Utils.getApplication().getResources();
141+
DisplayMetrics runningMetrics = res.getDisplayMetrics();
142+
DisplayMetrics newMetrics;
143+
if (runningMetrics != null) {
144+
newMetrics = new DisplayMetrics();
145+
newMetrics.setTo(runningMetrics);
146+
} else {
147+
newMetrics = res.getDisplayMetrics();
148+
}
149+
newMetrics.density = dpi / 160f;
150+
newMetrics.densityDpi = dpi;
151+
res.getDisplayMetrics().setTo(newMetrics);
152+
}
153+
}
154+
113155
private void hookDrawableViews() {
114156
XposedHelpers.findAndHookMethod(View.class, "setBackground", Drawable.class, new XC_MethodHook() {
115157
@Override

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ protected void beforeHookedMethod(MethodHookParam param) throws Exception {
6161
var fMessage = new FMessageWpp(param.args[0]);
6262
var messageKey = fMessage.getKey();
6363
var deviceJid = fMessage.getDeviceJid();
64-
var id = fMessage.getRowId();
6564
var messageID = (String) XposedHelpers.getObjectField(fMessage.getObject(), "A01");
6665
// Caso o proprio usuario tenha deletado o status
6766
if (WppCore.getPrivBoolean(messageID + "_delpass", false)) {

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,22 @@ public void doHook() throws Throwable {
4444
@Override
4545
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
4646
var fieldObjects = Arrays.stream(param.method.getDeclaringClass().getDeclaredFields()).map(field -> ReflectionUtils.getObjectField(field, param.thisObject)).filter(Objects::nonNull).collect(Collectors.toList());
47-
var menuManager = fieldObjects.stream().filter(menuManagerClass::isInstance).findFirst().orElse(null);
48-
var menuField = ReflectionUtils.getFieldByExtendType(menuManagerClass, Menu.class);
49-
var menu = (Menu) ReflectionUtils.getObjectField(menuField, menuManager);
50-
var fragmentInstance = fieldObjects.stream().filter(StatusPlaybackBaseFragmentClass::isInstance).findFirst().orElse(null);
47+
48+
Object fragmentInstance;
49+
if (param.thisObject != null && StatusPlaybackContactFragmentClass.isInstance(param.thisObject)) {
50+
fragmentInstance = param.thisObject;
51+
} else {
52+
fragmentInstance = fieldObjects.stream().filter(StatusPlaybackBaseFragmentClass::isInstance).findFirst().orElse(null);
53+
}
54+
55+
Menu menu;
56+
if (param.args.length > 0 && param.args[0] instanceof Menu) {
57+
menu = (Menu) param.args[0];
58+
} else {
59+
var menuManager = fieldObjects.stream().filter(menuManagerClass::isInstance).findFirst().orElse(null);
60+
var menuField = ReflectionUtils.getFieldByExtendType(menuManagerClass, Menu.class);
61+
menu = (Menu) ReflectionUtils.getObjectField(menuField, menuManager);
62+
}
5163

5264
var index = (int) XposedHelpers.getObjectField(fragmentInstance, "A00");
5365
var listStatus = (List) listStatusField.get(fragmentInstance);

0 commit comments

Comments
 (0)