<meta-data android:name="xposedmodule" android:value="true" /> <meta-data android:name="xposedminversion" android:value="2.6*" /> <meta-data android:name="xposeddescription" android:value="Uber-Driver application patch tool" /
uber.hack.XMain
public class XMain implements IXposedHookInitPackageResources, IXposedHookLoadPackage, IXposedHookZygoteInit { public void initZygote(StartupParam startupParam) throws Throwable { } public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable { } public void handleLoadPackage( LoadPackageParam paramLoadPackageParam) throws Throwable { } }
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml
. At boot time, you can get a handle once and, while running, just read your settings from it. You can also predetermine any variables, make checks. In fact, this is an analogue of the constructor method. public void handleLoadPackage( LoadPackageParam paramLoadPackageParam) throws Throwable { final LoadPackageParam llpm = paramLoadPackageParam; String packageName = llpm.packageName; if (packageName.contains("ubercab.driver")) { } }
public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable { String pkg = resparam.packageName; if (pkg.equals("com.ubercab.driver")) { } }
if (packageName.contains("ubercab.driver")) { try { XposedHelpers.findAndHookMethod( "com.ubercab.driver.feature.online.DispatchedFragment", llpm.classLoader, "onCreateView", "android.view.LayoutInflater", "android.view.ViewGroup", "android.os.Bundle", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { } } ); } catch (Throwable t) { XposedBridge.log(t); } }
try{ XposedHelpers.findAndHookMethod("com.ubercab.driver.core.app.DriverApplication", llpm.classLoader, "init", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { Application application = (Application) param.thisObject; Context context = application.getApplicationContext(); Intent intent = new Intent("uber.hack.ACTION_BACKGROUND"); context.sendBroadcast(intent); } }); } catch (Throwable t) { XposedBridge.log(t); }
param.thisObject
use the context to send a broadcast message to our receiver or service. try{ XposedHelpers.findAndHookMethod("com.htc.htcdialer.widget.DividerDrawable", paramLoadPackageParam.classLoader, "setDividerColor", "int", "int", new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { int paramInt1 = (Integer) param.args[0]; int paramInt2 = (Integer) param.args[1]; if (paramInt1 == 4) { if (paramInt2 == -13388315) param.args[1] = Color.RED; if (paramInt2 == -13128336) param.args[1] = Color.BLUE; } } }); } catch (Throwable t) { XposedBridge.log(t); }
findAndHookMethod("com.android.settings.PSService", paramLoadPackageParam.classLoader, "SetUSBNotification", "android.content.Context", boolean.class, new XC_MethodReplacement() { protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { return null; } });
public static void tweak_fix98918() { // -------------------------------------------------- // https://android-review.googlesource.com/#/c/98918/ // -------------------------------------------------- try { final Class<?> TaskRecord = XposedHelpers.findClass("com.android.server.am.TaskRecord", null); XposedHelpers.findAndHookMethod(TaskRecord, "setFrontOfTask", new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { Object mActivities = XposedHelpers.getObjectField(param.thisObject, "mActivities"); boolean foundFront = false; final int numActivities = (Integer) XposedHelpers.callMethod(mActivities, "size"); for (int activityNdx = 0; activityNdx < numActivities; activityNdx++) { final Object r = XposedHelpers.callMethod(mActivities, "get", activityNdx); if (foundFront || XposedHelpers.getBooleanField(r, "finishing")) { XposedHelpers.setBooleanField(r, "frontOfTask", false); } else { XposedHelpers.setBooleanField(r, "frontOfTask", true); foundFront = true; } } if (!foundFront && numActivities > 0) { Object get = XposedHelpers.callMethod(mActivities, "get", 0); XposedHelpers.setBooleanField(get, "frontOfTask", true); } return null; } }); } catch (Throwable t) { XposedBridge.log(t); } } // -------------------------------------------------- // https://android-review.googlesource.com/#/c/81970/ // -------------------------------------------------- public static void tweak_fix81970() { try { final Class<?> ActiveServices = XposedHelpers.findClass("com.android.server.am.ActiveServices", null); XposedHelpers.findAndHookMethod(ActiveServices, "killServicesLocked", "com.android.server.am.ProcessRecord", "boolean", new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { // XposedBridge.log("killServicesLocked happen"); Boolean DEBUG_SERVICE = (Boolean) XposedHelpers.getStaticBooleanField(ActiveServices, "DEBUG_SERVICE"); String TAG = (String) XposedHelpers.getStaticObjectField(ActiveServices, "TAG"); Object app = param.args[0]; boolean allowRestart = (Boolean) param.args[1]; Object services = XposedHelpers.getObjectField(app, "services"); int size = (Integer) XposedHelpers.callMethod(services, "size"); // First clear app state from services. for (int i = size - 1; i >= 0; i--) { Object sr = XposedHelpers.callMethod(services, "valueAt", i); Object stats = XposedHelpers.getObjectField(sr, "stats"); synchronized (XposedHelpers.callMethod(stats, "getBatteryStats")) { XposedHelpers.callMethod(stats, "stopLaunchedLocked"); } Object sr_app = XposedHelpers.getObjectField(sr, "app"); Boolean persistent = XposedHelpers.getBooleanField(sr_app, "persistent"); Boolean stopIfKilled = XposedHelpers.getBooleanField(sr, "stopIfKilled"); if (sr_app != null && !persistent && stopIfKilled) { Object sr_app_services = XposedHelpers.getObjectField(sr_app, "services"); XposedHelpers.callMethod(sr_app_services, "remove", sr); } XposedHelpers.setObjectField(sr, "app", null); XposedHelpers.setObjectField(sr, "isolatedProc", null); XposedHelpers.setObjectField(sr, "executeNesting", 0); XposedHelpers.callMethod(sr, "forceClearTracker"); Object mDestroyingServices = XposedHelpers.getObjectField(param.thisObject, "mDestroyingServices"); Boolean check = (Boolean) XposedHelpers.callMethod(mDestroyingServices, "remove", sr); if (check) { if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr); } Object bindings = XposedHelpers.getObjectField(sr, "bindings"); final int numClients = (Integer) XposedHelpers.callMethod(bindings, "size"); for (int bindingi = numClients - 1; bindingi >= 0; bindingi--) { Object IntentBindRecord = XposedHelpers.callMethod(bindings, "valueAt", bindingi); if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + IntentBindRecord + ": shouldUnbind=" + XposedHelpers.getObjectField(IntentBindRecord, "hasBound")); XposedHelpers.setObjectField(IntentBindRecord, "binder", null); XposedHelpers.setObjectField(IntentBindRecord, "requested", false); XposedHelpers.setObjectField(IntentBindRecord, "received", false); XposedHelpers.setObjectField(IntentBindRecord, "hasBound", false); } } // Clean up any connections this application has to // other // services. Object connections = XposedHelpers.getObjectField(app, "connections"); size = (Integer) XposedHelpers.callMethod(connections, "size"); for (int i = size - 1; i >= 0; i--) { Object ConnectionRecord = XposedHelpers.callMethod(connections, "valueAt", i); XposedHelpers.callMethod(param.thisObject, "removeConnectionLocked", ConnectionRecord, app, null); } XposedHelpers.callMethod(connections, "clear"); Object smap = XposedHelpers.callMethod(param.thisObject, "getServiceMap", XposedHelpers.getObjectField(app, "userId")); // Now do remaining service cleanup. services = XposedHelpers.getObjectField(app, "services"); size = (Integer) XposedHelpers.callMethod(services, "size"); for (int i = size - 1; i >= 0; i--) { Object sr = XposedHelpers.callMethod(services, "valueAt", i); Object mServicesByName = XposedHelpers.getObjectField(smap, "mServicesByName"); if (XposedHelpers.callMethod(mServicesByName, "get", XposedHelpers.getObjectField(sr, "name")) != sr) { Object cur = XposedHelpers.callMethod(mServicesByName, "get", XposedHelpers.getObjectField(sr, "name")); Slog.wtf(TAG, "Service " + sr + " in process " + app + " not same as in map: " + cur); Object app_services = XposedHelpers.getObjectField(app, "services"); XposedHelpers.callMethod(app_services, "removeAt", i); continue; } // Any services running in the application may // need to be // placed back in the pending list. Object serviceInfo = XposedHelpers.getObjectField(sr, "serviceInfo"); Object applicationInfo = XposedHelpers.getObjectField(serviceInfo, "applicationInfo"); if (allowRestart && XposedHelpers.getIntField(sr, "crashCount") >= 2 && (XposedHelpers.getIntField(applicationInfo, "flags") & ApplicationInfo.FLAG_PERSISTENT) == 0) { Slog.w(TAG, "Service crashed " + XposedHelpers.getIntField(sr, "crashCount") + " times, stopping: " + sr); EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, XposedHelpers.getObjectField(sr, "userId"), XposedHelpers.getObjectField(sr, "crashCount"), XposedHelpers.getObjectField(sr, "shortName"), XposedHelpers.getObjectField(app, "pid")); XposedHelpers.callMethod(param.thisObject, "bringDownServiceLocked", sr); } else if (!allowRestart) { XposedHelpers.callMethod(param.thisObject, "bringDownServiceLocked", sr); } else { boolean canceled = (Boolean) XposedHelpers.callMethod(param.thisObject, "scheduleServiceRestartLocked", sr, true); // Should the service remain running? Note // that in the // extreme case of so many attempts to // deliver a command // that it failed we also will stop it here. if (XposedHelpers.getBooleanField(sr, "startRequested") && (XposedHelpers.getBooleanField(sr, "stopIfKilled") || canceled)) { Object pendingStarts = XposedHelpers.getObjectField(sr, "pendingStarts"); if ((Integer) XposedHelpers.callMethod(pendingStarts, "size") == 0) { XposedHelpers.setBooleanField(sr, "startRequested", false); if (XposedHelpers.getObjectField(sr, "tracker") != null) { Object tracker = XposedHelpers.getObjectField(sr, "tracker"); Object mAm = XposedHelpers.getObjectField(param.thisObject, "mAm"); Object mProcessStats = XposedHelpers.getObjectField(mAm, "mProcessStats"); XposedHelpers.callMethod(tracker, "setStarted", false, XposedHelpers.callMethod(mProcessStats, "getMemFactorLocked"), SystemClock.uptimeMillis()); } if (!XposedHelpers.getBooleanField(sr, "hasAutoCreateConnections")) { // Whoops, no reason to restart! XposedHelpers.callMethod(param.thisObject, "bringDownServiceLocked", sr); } } } } } if (!allowRestart) { Object app_services = XposedHelpers.getObjectField(app, "services"); XposedHelpers.callMethod(app_services, "clear"); // Make sure there are no more restarting // services for this // process. Object mRestartingServices = XposedHelpers.getObjectField(param.thisObject, "mRestartingServices"); for (int i = (Integer) XposedHelpers.callMethod(mRestartingServices, "size") - 1; i >= 0; i--) { Object r = XposedHelpers.callMethod(mRestartingServices, "get", i); String processName = (String) XposedHelpers.getObjectField(r, "processName"); Object serviceInfo = XposedHelpers.getObjectField(r, "serviceInfo"); Object applicationInfo = XposedHelpers.getObjectField(serviceInfo, "applicationInfo"); Object info = XposedHelpers.getObjectField(app, "info"); if (processName.equals((String) XposedHelpers.getObjectField(app, "processName")) && XposedHelpers.getIntField(applicationInfo, "uid") == XposedHelpers.getIntField(info, "uid")) { XposedHelpers.callMethod(mRestartingServices, "remove", i); XposedHelpers.callMethod(param.thisObject, "clearRestartingIfNeededLocked", r); } } Object mPendingServices = XposedHelpers.getObjectField(param.thisObject, "mPendingServices"); for (int i = (Integer) XposedHelpers.callMethod(mPendingServices, "size") - 1; i >= 0; i--) { Object r = XposedHelpers.callMethod(mPendingServices, "get", i); String processName = (String) XposedHelpers.getObjectField(r, "processName"); Object serviceInfo = XposedHelpers.getObjectField(r, "serviceInfo"); Object applicationInfo = XposedHelpers.getObjectField(serviceInfo, "applicationInfo"); Object info = XposedHelpers.getObjectField(app, "info"); if (processName.equals((String) XposedHelpers.getObjectField(app, "processName")) && XposedHelpers.getIntField(applicationInfo, "uid") == XposedHelpers.getIntField(info, "uid")) { XposedHelpers.callMethod(mPendingServices, "remove", i); } } } // Make sure we have no more records on the stopping // list. Object mDestroyingServices = XposedHelpers.getObjectField(param.thisObject, "mDestroyingServices"); int i = (Integer) XposedHelpers.callMethod(mDestroyingServices, "size"); while (i > 0) { i--; Object sr = XposedHelpers.callMethod(mDestroyingServices, "get", i); if (XposedHelpers.getObjectField(sr, "app") == app) { XposedHelpers.callMethod(sr, "forceClearTracker"); XposedHelpers.callMethod(mDestroyingServices, "remove", i); if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr); } } Object executingServices = XposedHelpers.getObjectField(app, "executingServices"); XposedHelpers.callMethod(executingServices, "clear"); return null; } }); } catch (Throwable t) { XposedBridge.log(t); } }
try { XposedHelpers.findAndHookMethod("com.android.server.SystemConfig", paramLoadPackageParam.classLoader, "readPermission", "org.xmlpull.v1.XmlPullParser", "java.lang.String", new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { String permission = (String) param.args[1]; if (permission.equals("android.permission.WRITE_EXTERNAL_STORAGE")) { Class<?> process = XposedHelpers.findClass("android.os.Process", null); int gid = (Integer) XposedHelpers.callStaticMethod(process, "getGidForName", "media_rw"); Object mPermissions = XposedHelpers.getObjectField(param.thisObject, "mPermissions"); Object localPermissionEntry = XposedHelpers.callMethod(mPermissions, "get", permission.intern()); int[] gids = (int[]) XposedHelpers.getObjectField(localPermissionEntry, "gids"); XposedHelpers.setObjectField(localPermissionEntry, "gids", ArrayUtils.appendInt(gids, gid)); } } }); } catch (Throwable t) { XposedBridge.log(t); }
Object mActivity = XposedHelpers.getObjectField(param.thisObject, "mActivity");
(Activity) mActivity = (Activity) XposedHelpers.getObjectField(param.thisObject, "mActivity");
public void handleLoadPackage( LoadPackageParam paramLoadPackageParam) throws Throwable { final LoadPackageParam llpm = paramLoadPackageParam; String packageName = paramLoadPackageParam.packageName; if (packageName.contains("ubercab.driver")) { // DEX try{ XposedHelpers.findAndHookMethod("com.ubercab.driver.feature.main.MainActivity", llpm.classLoader, "onNewIntent", "android.content.Intent", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // } }); } catch (Throwable t) { XposedBridge.log(t); } // DEX . XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // , DEX . try { XposedHelpers.findAndHookMethod( "com.ubercab.driver.feature.online.DispatchedFragment", llpm.classLoader, "onCreateView", "android.view.LayoutInflater", "android.view.ViewGroup", "android.os.Bundle", new XC_MethodHook() { // } ); } catch (Throwable t) { XposedBridge.log(t); } } }); } }
Source: https://habr.com/ru/post/318202/
All Articles