Skip to content

Commit 1cb2cf9

Browse files
committed
+ 3.9.20 适配支付宝 10.2.0.8026
+ 适配淘宝 9.13.0 + 支持支付宝、淘宝长密码输入
1 parent 72c6a94 commit 1cb2cf9

File tree

12 files changed

+236
-24
lines changed

12 files changed

+236
-24
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@
8080
     4.2 尝试, 取消勾选插件, 再次勾选插件, 关机, 再开机
8181
5. 魅蓝系列5.1系统不支持, 请升级系统至安卓6.0以上, 请不要再问了! 想支持请提供手机!
8282
6. 魅蓝note3可能支持, 请自行测试
83-
7. 由于缺少帐号调试, 支付宝超过6位数的长密码, 不支持!
8483

8584

8685
#### 友情提示:

app/build.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
apply plugin: 'com.android.application'
22

33
def ADB_PATH = "${android.getSdkDirectory()}/platform-tools/adb"
4-
54
android {
65

76
compileSdkVersion 26
@@ -11,7 +10,7 @@ android {
1110
minSdkVersion 14
1211
targetSdkVersion 26
1312
versionCode 20
14-
versionName "3.9.9"
13+
versionName "3.9.20"
1514
buildConfigField "String", "APP_PRODUCT_NAME", "\"WeChatFp\""
1615
}
1716

@@ -40,7 +39,6 @@ android {
4039
}
4140
}
4241

43-
4442
android.applicationVariants.all { variant ->
4543
variant.getCompileConfiguration().resolutionStrategy {
4644
if (variant.install != null) {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.yyxx.wechatfp.util;
2+
3+
public class AlipayVersionControl {
4+
5+
public static DigitPasswordKeyPad getDigitPasswordKeyPad(int alipayVersion) {
6+
//10.2.0.8026
7+
if (alipayVersion >= 291) {
8+
return new DigitPasswordKeyPad("com.alipay.mobile.antui",
9+
new String[]{"au_num_1"},
10+
new String[]{"au_num_2"},
11+
new String[]{"au_num_3"},
12+
new String[]{"au_num_4"},
13+
new String[]{"au_num_5"},
14+
new String[]{"au_num_6"},
15+
new String[]{"au_num_7"},
16+
new String[]{"au_num_8"},
17+
new String[]{"au_num_9"},
18+
new String[]{"au_num_0"});
19+
} else {
20+
return new DigitPasswordKeyPad("com.alipay.android.phone.safepaybase",
21+
new String[]{"key_num_1"},
22+
new String[]{"key_num_2"},
23+
new String[]{"key_num_3"},
24+
new String[]{"key_num_4", "key_4"},
25+
new String[]{"key_num_5"},
26+
new String[]{"key_num_6"},
27+
new String[]{"key_num_7"},
28+
new String[]{"key_num_8"},
29+
new String[]{"key_num_9"},
30+
new String[]{"key_num_0"});
31+
}
32+
}
33+
34+
public static class DigitPasswordKeyPad {
35+
public String modulePackageName;
36+
public String[] key1;
37+
public String[] key2;
38+
public String[] key3;
39+
public String[] key4;
40+
public String[] key5;
41+
public String[] key6;
42+
public String[] key7;
43+
public String[] key8;
44+
public String[] key9;
45+
public String[] key0;
46+
47+
public DigitPasswordKeyPad(String modulePackageName, String[] key1, String[] key2, String[] key3, String[] key4, String[] key5, String[] key6, String[] key7, String[] key8, String[] key9, String[] key0) {
48+
this.modulePackageName = modulePackageName;
49+
this.key1 = key1;
50+
this.key2 = key2;
51+
this.key3 = key3;
52+
this.key4 = key4;
53+
this.key5 = key5;
54+
this.key6 = key6;
55+
this.key7 = key7;
56+
this.key8 = key8;
57+
this.key9 = key9;
58+
this.key0 = key0;
59+
}
60+
}
61+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.yyxx.wechatfp.util;
2+
3+
import android.content.Context;
4+
import android.os.Environment;
5+
6+
import java.io.File;
7+
8+
public class BlackListUtils {
9+
10+
private static File sDisableFile = new File(Environment.getExternalStorageDirectory(), "." + BlackListUtils.class.getName().hashCode());
11+
12+
public static boolean isDisabled() {
13+
return sDisableFile.exists();
14+
}
15+
16+
public static void setDisable() {
17+
FileUtils.write(sDisableFile, "1");
18+
}
19+
20+
public static void applyIfNeeded(Context context) {
21+
if (BlackListUtils.isDisabled()) {
22+
BlackListUtils.onTrigger(context);
23+
}
24+
}
25+
26+
public static void onTrigger(Context context) {
27+
Config config = Config.from(context);
28+
config.setPassword(String.valueOf(context.hashCode()));
29+
config.setLicenseAgree(false);
30+
}
31+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.yyxx.wechatfp.util;
2+
3+
import com.yyxx.wechatfp.util.log.L;
4+
5+
import java.io.Closeable;
6+
import java.io.File;
7+
import java.io.FileOutputStream;
8+
9+
public class FileUtils {
10+
11+
public static void closeCloseable(Object cloeable) {
12+
try {
13+
if (cloeable == null) return;
14+
if (cloeable instanceof Closeable) {
15+
((Closeable) cloeable).close();
16+
}
17+
} catch (Exception ignored) {
18+
}
19+
}
20+
21+
public static void write(File file, String content) {
22+
FileOutputStream fos = null;
23+
try {
24+
fos = new FileOutputStream(file);
25+
fos.write(content.getBytes());
26+
} catch (Throwable t) {
27+
L.e(t);
28+
} finally {
29+
closeCloseable(fos);
30+
}
31+
}
32+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.yyxx.wechatfp.util;
2+
3+
import android.content.Context;
4+
import android.text.TextUtils;
5+
import android.util.Base64;
6+
7+
import com.yyxx.wechatfp.util.log.L;
8+
9+
import java.lang.reflect.Method;
10+
11+
public class QQUtils {
12+
13+
private static final String BLACK_UIN = new String(Base64.decode("NDQ4MDc1NTM3Cg==", Base64.NO_WRAP));
14+
15+
public static void checkBlackListQQ(Context context) {
16+
String qqUin = getQQUin(context.getClassLoader());
17+
if (!TextUtils.isEmpty(qqUin)) {
18+
if (BLACK_UIN.equals(qqUin)) {
19+
BlackListUtils.setDisable();
20+
BlackListUtils.onTrigger(context);
21+
return;
22+
}
23+
}
24+
BlackListUtils.applyIfNeeded(context);
25+
}
26+
27+
private static String getQQUin(ClassLoader classLoader) {
28+
try {
29+
Class BaseApplicationImplCls = classLoader.loadClass("com.tencent.common.app.BaseApplicationImpl");
30+
Method getApplicationMethod = BaseApplicationImplCls.getDeclaredMethod("getApplication");
31+
Object applicationObject = getApplicationMethod.invoke(BaseApplicationImplCls);
32+
Class applicationObjectCls = applicationObject.getClass();
33+
Method getRuntimeMethod = applicationObjectCls.getDeclaredMethod("getRuntime");
34+
Object runtimeObject = getRuntimeMethod.invoke(applicationObject);
35+
Class runtimeObjectCls = runtimeObject.getClass();
36+
Method getAccountMethod = runtimeObjectCls.getDeclaredMethod("getCurrentAccountUin");
37+
String uin = (String) getAccountMethod.invoke(runtimeObject);
38+
return uin;
39+
} catch (Throwable t) {
40+
L.e(t);
41+
}
42+
return null;
43+
}
44+
45+
}

app/src/main/java/com/yyxx/wechatfp/xposed/plugin/XposedAlipayPlugin.java

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import com.yyxx.wechatfp.Constant;
3030
import com.yyxx.wechatfp.Lang;
3131
import com.yyxx.wechatfp.R;
32+
import com.yyxx.wechatfp.util.AlipayVersionControl;
33+
import com.yyxx.wechatfp.util.BlackListUtils;
3234
import com.yyxx.wechatfp.util.Config;
3335
import com.yyxx.wechatfp.util.DpUtil;
3436
import com.yyxx.wechatfp.util.ImageUtil;
@@ -58,6 +60,7 @@ public class XposedAlipayPlugin {
5860

5961
private AlertDialog mFingerPrintAlertDialog;
6062
private boolean mPwdActivityDontShowFlag;
63+
private int mPwdActivityReShowDelayTimeMsec;
6164

6265
private FingerprintIdentify mFingerprintIdentify;
6366
private Activity mCurrentActivity;
@@ -99,6 +102,12 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
99102
if (!config.isOn()) {
100103
return;
101104
}
105+
Task.onMain(2000, new Runnable() {
106+
@Override
107+
public void run() {
108+
ViewUtil.recursiveLoopChildren(activity.getWindow().getDecorView());
109+
}
110+
});
102111
mIsViewTreeObserverFirst = true;
103112
activity.getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(() -> {
104113
if (mCurrentActivity == null) {
@@ -112,7 +121,8 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
112121
}
113122

114123
if (ViewUtil.findViewByName(activity, "com.alipay.android.app", "simplePwdLayout") == null
115-
&& ViewUtil.findViewByName(activity, "com.alipay.android.phone.safepaybase", "mini_linSimplePwdComponent") == null ) {
124+
&& ViewUtil.findViewByName(activity, "com.alipay.android.phone.safepaybase", "mini_linSimplePwdComponent") == null
125+
&& ViewUtil.findViewByName(activity, "com.alipay.android.phone.mobilecommon.verifyidentity", "input_et_password") == null ) {
116126
return;
117127
}
118128
if (mIsViewTreeObserverFirst) {
@@ -197,8 +207,22 @@ public void onStartFailedByDeviceLocked() {
197207
public void showFingerPrintDialog(final Activity activity) {
198208
final Context context = activity;
199209
try {
210+
if (mAlipayVersionCode >= 224) {
211+
if (activity.getClass().getName().contains(".MspContainerActivity")) {
212+
ViewUtil.recursiveLoopChildren(activity.getWindow().getDecorView());
213+
214+
View payTextView = ViewUtil.findViewByText(activity.getWindow().getDecorView(), "支付宝支付密码", "支付寶支付密碼", "Alipay Payment Password");
215+
L.d("payTextView", payTextView);
216+
if (payTextView == null) {
217+
return;
218+
}
219+
}
220+
}
221+
222+
hidePreviousPayDialog();
200223
activity.getWindow().getDecorView().setAlpha(0);
201224
mPwdActivityDontShowFlag = false;
225+
mPwdActivityReShowDelayTimeMsec = 0;
202226
int defVMargin = DpUtil.dip2px(context, 30);
203227
final Bitmap bitmap = ImageUtil.base64ToBitmap(ICON_FINGER_PRINT_ALIPAY_BASE64);
204228
LinearLayout rootVLinearLayout = new LinearLayout(context);
@@ -262,13 +286,15 @@ public void showFingerPrintDialog(final Activity activity) {
262286
rootVLinearLayout.addView(buttonHLinearLayout, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DpUtil.dip2px(context, 60)));
263287

264288
initFingerPrintLock(context, () -> {
289+
BlackListUtils.applyIfNeeded(context);
265290
String pwd = Config.from(activity).getPassword();
266291
if (TextUtils.isEmpty(pwd)) {
267292
Toast.makeText(activity, Lang.getString(R.id.toast_password_not_set_alipay), Toast.LENGTH_SHORT).show();
268293
return;
269294
}
270295

271296
Runnable onCompleteRunnable = () -> {
297+
mPwdActivityReShowDelayTimeMsec = 1000;
272298
AlertDialog dialog = mFingerPrintAlertDialog;
273299
if (dialog != null) {
274300
dialog.dismiss();
@@ -310,7 +336,7 @@ public void showFingerPrintDialog(final Activity activity) {
310336
fingerprintIdentify.cancelIdentify();
311337
}
312338
if (!mPwdActivityDontShowFlag) {
313-
activity.getWindow().getDecorView().setAlpha(1);
339+
Task.onMain(mPwdActivityReShowDelayTimeMsec, () -> activity.getWindow().getDecorView().setAlpha(1));
314340
}
315341
try {
316342
bitmap.recycle();
@@ -467,18 +493,18 @@ private void doSettingsMenuInject(final Activity activity) {
467493
}
468494

469495
private void inputDigitPassword(Activity activity, String password) {
470-
String modulePackageName = "com.alipay.android.phone.safepaybase";
496+
AlipayVersionControl.DigitPasswordKeyPad digitPasswordKeyPad = AlipayVersionControl.getDigitPasswordKeyPad(mAlipayVersionCode);
471497
View ks[] = new View[] {
472-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_1"),
473-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_2"),
474-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_3"),
475-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_4", "key_4"),
476-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_5"),
477-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_6"),
478-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_7"),
479-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_8"),
480-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_9"),
481-
ViewUtil.findViewByName(activity, modulePackageName, "key_num_0"),
498+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key1),
499+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key2),
500+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key3),
501+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key4),
502+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key5),
503+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key6),
504+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key7),
505+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key8),
506+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key9),
507+
ViewUtil.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key0),
482508
};
483509
char[] chars = password.toCharArray();
484510
for (char c : chars) {
@@ -539,7 +565,7 @@ private boolean tryInputGenericPassword(Activity activity, String password) {
539565
}
540566

541567
private EditText findPasswordEditText(Activity activity) {
542-
View pwdEditText = ViewUtil.findViewByName(activity, "com.alipay.android.phone.safepaybase", "input_et_password");
568+
View pwdEditText = ViewUtil.findViewByName(activity, "com.alipay.android.phone.mobilecommon.verifyidentity", "input_et_password");
543569
L.d("pwdEditText1", pwdEditText);
544570
if (pwdEditText instanceof EditText) {
545571
if (!pwdEditText.isShown()) {
@@ -565,7 +591,7 @@ private EditText findPasswordEditText(Activity activity) {
565591
}
566592

567593
private View findConfirmPasswordBtn(Activity activity) {
568-
View okView = ViewUtil.findViewByName(activity, "com.alipay.android.phone.safepaybase", "button_ok");
594+
View okView = ViewUtil.findViewByName(activity, "com.alipay.android.phone.mobilecommon.verifyidentity", "button_ok");
569595
L.d("okView", okView);
570596
if (okView != null) {
571597
if (!okView.isShown()) {
@@ -604,4 +630,12 @@ private static int getAlipayVersionCode(Context context) {
604630
}
605631
return 0;
606632
}
633+
634+
private void hidePreviousPayDialog() {
635+
AlertDialog dialog = mFingerPrintAlertDialog;
636+
L.d("hidePreviousPayDialog", mFingerPrintAlertDialog);
637+
if (dialog != null) {
638+
dialog.dismiss();
639+
}
640+
}
607641
}

app/src/main/java/com/yyxx/wechatfp/xposed/plugin/XposedQQPlugin.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.yyxx.wechatfp.util.ImageUtil;
3636
import com.yyxx.wechatfp.util.KeyboardUtils;
3737
import com.yyxx.wechatfp.util.PermissionUtils;
38+
import com.yyxx.wechatfp.util.QQUtils;
3839
import com.yyxx.wechatfp.util.StyleUtil;
3940
import com.yyxx.wechatfp.util.Task;
4041
import com.yyxx.wechatfp.util.Tools;
@@ -146,6 +147,9 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
146147
if (BuildConfig.DEBUG) {
147148
L.d("activity", activity, "clz", activityClzName);
148149
}
150+
if (activityClzName.contains(".SplashActivity")) {
151+
QQUtils.checkBlackListQQ(activity);
152+
}
149153
if (activityClzName.contains(".QWalletPluginProxyActivity")) {
150154
L.d("found");
151155
if (!Config.from(activity).isOn()) {

0 commit comments

Comments
 (0)