From cd759172e5df8256252104f86a844aa58ca58e43 Mon Sep 17 00:00:00 2001 From: kooritea Date: Sun, 18 Jul 2021 18:07:59 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kooritea/fcmfix/xposed/BroadcastFix.java | 2 +- .../xposed/MiuiLocalNotificationFix.java | 4 +- .../fcmfix/xposed/ReconnectManagerFix.java | 93 +++++++++++++++---- .../kooritea/fcmfix/xposed/XposedModule.java | 13 +-- 4 files changed, 82 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/kooritea/fcmfix/xposed/BroadcastFix.java b/app/src/main/java/com/kooritea/fcmfix/xposed/BroadcastFix.java index b405284..a5f1af9 100644 --- a/app/src/main/java/com/kooritea/fcmfix/xposed/BroadcastFix.java +++ b/app/src/main/java/com/kooritea/fcmfix/xposed/BroadcastFix.java @@ -73,7 +73,7 @@ protected void beforeHookedMethod(MethodHookParam methodHookParam) throws Throwa methodHookParam.args[appOp_args_index] = Integer.valueOf(11); } intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - printLog("Send Forced Start Broadcast: " + target,false); + printLog("Send Forced Start Broadcast: " + target); } } } diff --git a/app/src/main/java/com/kooritea/fcmfix/xposed/MiuiLocalNotificationFix.java b/app/src/main/java/com/kooritea/fcmfix/xposed/MiuiLocalNotificationFix.java index 63c60a5..7d94712 100644 --- a/app/src/main/java/com/kooritea/fcmfix/xposed/MiuiLocalNotificationFix.java +++ b/app/src/main/java/com/kooritea/fcmfix/xposed/MiuiLocalNotificationFix.java @@ -50,12 +50,12 @@ protected void startHook(){ protected void afterHookedMethod(MethodHookParam methodHookParam) throws Throwable { if(targetIsAllow((String)methodHookParam.args[3])){ methodHookParam.setResult(true); - printLog("Allow LocalNotification " + methodHookParam.args[3],false); + printLog("Allow LocalNotification " + methodHookParam.args[3]); } } }); }else{ - printLog("Not found isAllowLocalNotification in com.android.server.notification.NotificationManagerServiceInjector",true); + printLog("Not found isAllowLocalNotification in com.android.server.notification.NotificationManagerServiceInjector"); } } diff --git a/app/src/main/java/com/kooritea/fcmfix/xposed/ReconnectManagerFix.java b/app/src/main/java/com/kooritea/fcmfix/xposed/ReconnectManagerFix.java index 4e31d43..1c8c3d8 100644 --- a/app/src/main/java/com/kooritea/fcmfix/xposed/ReconnectManagerFix.java +++ b/app/src/main/java/com/kooritea/fcmfix/xposed/ReconnectManagerFix.java @@ -34,7 +34,10 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -100,34 +103,29 @@ protected void startHook() throws Exception { final SharedPreferences sharedPreferences = context.getSharedPreferences("fcmfix_config", Context.MODE_PRIVATE); String versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName; if (!sharedPreferences.getBoolean("isInit", false)) { - this.printLog("fcmfix_config init",true); + this.printLog("fcmfix_config init"); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean("isInit", true); - editor.putBoolean("enable", false); editor.putLong("heartbeatInterval", 117000L); - editor.putString("timer_class", ""); - editor.putString("timer_settimeout_method", ""); - editor.putString("timer_next_time_property", ""); - editor.putString("timer_intent_property", ""); editor.putString("gms_version", versionName); editor.commit(); - this.sendUpdateNotification("[xposed-fcmfix]请初始化fcmfix配置"); - return; - } - if (!sharedPreferences.getBoolean("enable", false)) { - this.printLog("ReconnectManagerFix配置文件enable标识为false,退出",true); - return; + findAndUpdateHookTarget(sharedPreferences); } if (!sharedPreferences.getString("gms_version", "").equals(versionName)) { - this.printLog("gms已更新,请重新编辑fcmfix_config.xml",true); + this.printLog("gms已更新: " + sharedPreferences.getString("gms_version", "") + "->" + versionName); SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putBoolean("enable", false); - editor.putString("gms_version", versionName); + editor.putString("gms_version", versionName);; editor.commit(); - this.sendUpdateNotification("[xposed-fcmfix]gms已更新,请更新fcmfix.xml"); + findAndUpdateHookTarget(sharedPreferences); + } + if (!sharedPreferences.getBoolean("enable", false)) { + this.printLog("当前配置文件enable标识为false,FCMFIX退出"); return; } - this.printLog("ReconnectManagerFix读取配置已成功,timer_class: " + sharedPreferences.getString("timer_class", ""),true); + this.printLog("timer_class: "+ sharedPreferences.getString("timer_class", "")); + this.printLog("timer_intent_property: "+ sharedPreferences.getString("timer_intent_property", "")); + this.printLog("timer_next_time_property: "+ sharedPreferences.getString("timer_next_time_property", "")); + this.printLog("timer_settimeout_method: "+ sharedPreferences.getString("timer_settimeout_method", "")); XposedHelpers.findAndHookMethod(XposedHelpers.findClass(sharedPreferences.getString("timer_class", ""), loadPackageParam.classLoader), sharedPreferences.getString("timer_settimeout_method", ""), long.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(final MethodHookParam param) throws Throwable { @@ -152,7 +150,7 @@ public void run() { long nextConnectionTime = XposedHelpers.getLongField(param.thisObject, sharedPreferences.getString("timer_next_time_property", "")); if (nextConnectionTime != 0 && nextConnectionTime - SystemClock.elapsedRealtime() < 0) { AndroidAppHelper.currentApplication().getApplicationContext().sendBroadcast(new Intent("com.google.android.intent.action.GCM_RECONNECT")); - printLog("Send broadcast GCM_RECONNECT",false); + printLog("Send broadcast GCM_RECONNECT"); } } }, (long) param.args[0] + 5000); @@ -162,6 +160,8 @@ public void run() { } private void sendUpdateNotification(String text) { + printLog(text); + text = "[fcmfix]" + text; Context context = AndroidAppHelper.currentApplication().getApplicationContext(); NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); this.createFcmfixChannel(notificationManager); @@ -208,4 +208,61 @@ public void onReceive(Context context, Intent intent) { } }; + private void findAndUpdateHookTarget(SharedPreferences sharedPreferences){ + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putBoolean("enable", false); + printLog("开始自动寻找hook点"); + try{ + Class heartbeatChimeraAlarm = XposedHelpers.findClass("com.google.android.gms.gcm.connection.HeartbeatChimeraAlarm",loadPackageParam.classLoader); + for(Constructor heartbeatChimeraAlarmConstructor : heartbeatChimeraAlarm.getConstructors()){ + String timerClass = ""; + String timerNextTimeProperty = ""; + String timerIntentProperty = ""; + String timerSettimeoutMethod = ""; + for(Class paramClazz : heartbeatChimeraAlarmConstructor.getParameterTypes()){ + timerClass = ""; + timerNextTimeProperty = ""; + timerIntentProperty = ""; + timerSettimeoutMethod = ""; + for(Field field : paramClazz.getDeclaredFields()){ + if(field.getType() == Intent.class&& Modifier.isPrivate(field.getModifiers())){ + timerIntentProperty = field.getName(); + } + if(field.getType() == long.class && Modifier.isPrivate(field.getModifiers())){ + timerNextTimeProperty = field.getName(); + } + if(!"".equals(timerNextTimeProperty) && !"".equals(timerIntentProperty)){ + break; + } + } + for(Method method : paramClazz.getMethods()){ + if(method.getParameterTypes().length == 1 && method.getParameterTypes()[0] == long.class && Modifier.isFinal(method.getModifiers()) && Modifier.isPublic(method.getModifiers())){ + timerSettimeoutMethod = method.getName(); + break; + } + } + if(!"".equals(timerNextTimeProperty) && !"".equals(timerIntentProperty) && !"".equals(timerSettimeoutMethod)){ + timerClass = paramClazz.getName(); + break; + } + } + if(!"".equals(timerNextTimeProperty) && !"".equals(timerIntentProperty) && !"".equals(timerSettimeoutMethod) && !"".equals(timerClass)){ + editor.putBoolean("enable", true); + editor.putString("timer_class", timerClass); + editor.putString("timer_settimeout_method", timerSettimeoutMethod); + editor.putString("timer_next_time_property", timerNextTimeProperty); + editor.putString("timer_intent_property", timerIntentProperty); + this.sendUpdateNotification("自动更新配置文件成功"); + break; + } + } + }catch (Exception e){ + editor.putBoolean("enable", false); + printLog("自动寻找hook点失败"+e.getMessage()); + this.sendUpdateNotification("自动更新配置文件失败,请手动更新。"); + e.printStackTrace(); + } + editor.commit(); + } + } diff --git a/app/src/main/java/com/kooritea/fcmfix/xposed/XposedModule.java b/app/src/main/java/com/kooritea/fcmfix/xposed/XposedModule.java index e816d8c..a836a49 100644 --- a/app/src/main/java/com/kooritea/fcmfix/xposed/XposedModule.java +++ b/app/src/main/java/com/kooritea/fcmfix/xposed/XposedModule.java @@ -24,18 +24,13 @@ protected XposedModule(final XC_LoadPackage.LoadPackageParam loadPackageParam){ protected abstract void onCanReadConfig() throws Exception; private boolean isRegisterUnlockBroadcastReceive = false; - protected void printLog(String text, boolean isInitLog){ - if(isInitLog){ - XposedBridge.log("[fcmfix] "+ text); - } + protected void printLog(String text){ Intent log = new Intent("com.kooritea.fcmfix.log"); log.putExtra("text",text); try{ AndroidAppHelper.currentApplication().getApplicationContext().sendBroadcast(log); }catch (Exception e){ XposedBridge.log("[fcmfix] "+ text); - // 没有作用域 -// e.printStackTrace();; } } @@ -49,7 +44,7 @@ protected void checkUserDeviceUnlock(Context context){ try { this.onCanReadConfig(); } catch (Exception e) { - printLog("读取配置文件初始化失败: " + e.getMessage(),true); + printLog("读取配置文件初始化失败: " + e.getMessage()); } } else { isRegisterUnlockBroadcastReceive = true; @@ -65,13 +60,13 @@ protected void checkUserDeviceUnlock(Context context){ public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_USER_UNLOCKED.equals(action)) { - printLog("User Device Unlock Broadcast",true); + printLog("User Device Unlock Broadcast"); try { onCanReadConfig(); AndroidAppHelper.currentApplication().getApplicationContext().unregisterReceiver(unlockBroadcastReceive); isRegisterUnlockBroadcastReceive = false; } catch (Exception e) { - printLog("读取配置文件初始化失败: " + e.getMessage(),true); + printLog("读取配置文件初始化失败: " + e.getMessage()); } } }