I have code like this:
XposedHelpers.findAndHookMethod(packageManagerService, null,
"anything", String.class, Integer.class, Integer.class, new XC_MethodHook() {
How can I change bolded code for specific Android Version?
For example:
if Android version is lower than JB MR2 then params = String.class, Integer.class, Integer.class, Integer.class else params = String.class, Integer.class, Integer.class
?
Either pass the array of classes to e.g. findAndHookMethod, or define the hook and use different findAndHookMethod calls with the arguments you want.
Code:
Object[] argumentClasses;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
argumentClasses = new Object[]{argumentClass1, argumentClass2};
else
argumentClasses = new Object[]{argumentClass1};
findAndHookMethod(class, method, argumentClasses, hook);
Or:
Code:
XC_MethodHook hook = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// Hook
}
};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
findAndHookMethod(class, method, argumentClass1, argumentClass2, hook);
else
findAndHookMethod(class, method, argumentClass1, hook);
Great! Thank you!
Related
Hi everyone. I ask for help. I literally beg for it..
com.android.dialer.dialpad.LatinSmartDialMap
You can see it here http://grepcode.com/file/repository...id/dialer/dialpad/LatinSmartDialMap.java?av=f
I only want to replace method . Any of them.
For example I want this method returns FALSE every time it's called.
Code:
@Override
public boolean isValidDialpadAlphabeticChar(char ch) {
return (ch >= 'a' && ch <= 'z');
}
Here is my code
Code:
public class Fm implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadpkg) throws Throwable {
if (loadpkg.packageName.equals("com.android.dialer")) {
ClassLoader classLoader = loadpkg.classLoader;
XC_MethodReplacement methodreplacer = new XC_MethodReplacement() {
protected Object replaceHookedMethod(
XC_MethodHook.MethodHookParam paramAnonymousMethodHookParam)
throws Throwable {
XposedBridge.log("ALLLLL RIGHTTTT . NOW We ARE IN. AND MADE IT FALSe");
return false;
}
};
XposedHelpers.findAndHookMethod("com.android.dialer.dialpad.LatinSmartDialMap", loadpkg.classLoader,
"[COLOR="Red"]isValidDialpadAlphabeticChar[/COLOR]", Character.class, methodreplacer);
}
}
}
But this doesn't work
Here what I see in xposed log file:
java.lang.NoSuchMethodError: com.android.dialer.dialpad.LatinSmartDialMap#isValidDialpadAlphabeticChar(java.lang.Character)#exact
at de.robv.android.xposed.XposedHelpers.findMethodExact(XposedHelpers.java:179)
at de.robv.android.xposed.XposedHelpers.findAndHookMethod(XposedHelpers.java:129)
at de.robv.android.xposed.XposedHelpers.findAndHookMethod(XposedHelpers.java:136)
at com.s0bes.fmspeaker.Fm.handleLoadPackage(Fm.java:30)
at de.robv.android.xposed.IXposedHookLoadPackage
BUUUT. If I will try to replace other method. For example
matchesCombination in com.android.dialer.dialpad.SmartDialNameMatcher (http://grepcode.com/file/repository...dialer/dialpad/SmartDialNameMatcher.java?av=f)
Here the part of code which was changed:
Code:
XposedHelpers.findAndHookMethod("com.android.dialer.dialpad.SmartDialNameMatcher", loadpkg.classLoader,
"matchesCombination", String.class, String.class, ArrayList.class, methodreplacer);
Now everything work...
So, it works with one thing and doesnt work with method I need
If you want to replace a method to return a consatnt, you can use the XC_MethodReplacement.returnConstant(…) shortcut. For example:
Java:
XposedHelpers.findAndHookMethod("com.android.dialer.dialpad.SmartDialNameMatcher", loadpkg.classLoader,
"matchesCombination", String.class, String.class, ArrayList.class, XC_MethodReplacement.returnConstant(false));
As for your problem, you're trying to hook isValidDialpadAlphabeticChar(Character.class), but you should be hooking isValidDialpadAlphabeticChar(char.class). Just replace "Character.class" by "char.class" in your findAndHookMethod call.
I have one app which can call java functions from scripts defined at runtime, but has not enough permissions to do most of the stuff, like toggling wifi.
So I tried to create a module hooking the Packagemanager to grant these permissions.
My code so far:
Code:
public class Hook implements IXposedHookLoadPackage, IXposedHookZygoteInit {
ArrayList<String> newPerms;
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(!loadPackageParam.packageName.equals("android"))return;
final Class<?> clsPMS = findClass("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader);
XC_MethodHook hookGrantPermissions = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String pkgName = (String) getObjectField(param.args[0], "packageName");
if(!(pkgName.equals(Strings.LLX)||pkgName.equals(Strings.LL)))return;
//XposedBridge.log("Package: "+pkgName);
if(newPerms == null || newPerms.isEmpty() ) return;
ArrayList<String> origRequestedPermissions = (ArrayList<String>) getObjectField(param.args[0], "requestedPermissions");
param.setObjectExtra("orig_requested_permissions", origRequestedPermissions);
//XposedBridge.log("Old Permissions "+Arrays.toString(origRequestedPermissions.toArray()));
//XposedBridge.log("New Permissions "+Arrays.toString(newPerms.toArray()));
ArrayList<String> newRequestedPermissions = new ArrayList<>(origRequestedPermissions);
newRequestedPermissions.addAll(newPerms);
//XposedBridge.log("All Permissions"+Arrays.toString(newRequestedPermissions.toArray()));
//param.args[1] = true;
[U][B]setObjectField(param.args[0], "requestedPermissions", newRequestedPermissions);[/B][/U]
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
ArrayList<String> origRequestedPermissions = (ArrayList<String>) param.getObjectExtra("orig_requested_permissions");
if (origRequestedPermissions != null)
setObjectField(param.args[0], "requestedPermissions", origRequestedPermissions);
}
};
if (Build.VERSION.SDK_INT < 21) {
findAndHookMethod(clsPMS, "grantPermissionsLPw", "android.content.pm.PackageParser$Package", boolean.class, hookGrantPermissions);
} else {
findAndHookMethod(clsPMS, "grantPermissionsLPw", "android.content.pm.PackageParser$Package", boolean.class, String.class, hookGrantPermissions);
}
}
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
XSharedPreferences pref = new XSharedPreferences(this.getClass().getPackage().getName(), Strings.PREF_NAME);
pref.makeWorldReadable();
newPerms = Strings.read(pref);
}
Sidenote: Code is partially forked from Appsettings module: https://github.com/rovo89/XposedAppSettings
The problem is: when I restart my phone after enabling the module, I just get a blackscreen after the bootanimation.
When I comment out the line marked fat underlined, it works, but does nothing (because this line is essential).
I have practically no idea why this isn't working.
I know that the input returned from Strings.read is valid.
My Question: What am I doing wrong?
LM13 said:
I have one app which can call java functions from scripts defined at runtime, but has not enough permissions to do most of the stuff, like toggling wifi.
So I tried to create a module hooking the Packagemanager to grant these permissions.
My code so far:
Code:
public class Hook implements IXposedHookLoadPackage, IXposedHookZygoteInit {
ArrayList<String> newPerms;
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(!loadPackageParam.packageName.equals("android"))return;
final Class<?> clsPMS = findClass("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader);
XC_MethodHook hookGrantPermissions = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String pkgName = (String) getObjectField(param.args[0], "packageName");
if(!(pkgName.equals(Strings.LLX)||pkgName.equals(Strings.LL)))return;
//XposedBridge.log("Package: "+pkgName);
if(newPerms == null || newPerms.isEmpty() ) return;
ArrayList<String> origRequestedPermissions = (ArrayList<String>) getObjectField(param.args[0], "requestedPermissions");
param.setObjectExtra("orig_requested_permissions", origRequestedPermissions);
//XposedBridge.log("Old Permissions "+Arrays.toString(origRequestedPermissions.toArray()));
//XposedBridge.log("New Permissions "+Arrays.toString(newPerms.toArray()));
ArrayList<String> newRequestedPermissions = new ArrayList<>(origRequestedPermissions);
newRequestedPermissions.addAll(newPerms);
//XposedBridge.log("All Permissions"+Arrays.toString(newRequestedPermissions.toArray()));
//param.args[1] = true;
[U][B]setObjectField(param.args[0], "requestedPermissions", newRequestedPermissions);[/B][/U]
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
ArrayList<String> origRequestedPermissions = (ArrayList<String>) param.getObjectExtra("orig_requested_permissions");
if (origRequestedPermissions != null)
setObjectField(param.args[0], "requestedPermissions", origRequestedPermissions);
}
};
if (Build.VERSION.SDK_INT < 21) {
findAndHookMethod(clsPMS, "grantPermissionsLPw", "android.content.pm.PackageParser$Package", boolean.class, hookGrantPermissions);
} else {
findAndHookMethod(clsPMS, "grantPermissionsLPw", "android.content.pm.PackageParser$Package", boolean.class, String.class, hookGrantPermissions);
}
}
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
XSharedPreferences pref = new XSharedPreferences(this.getClass().getPackage().getName(), Strings.PREF_NAME);
pref.makeWorldReadable();
newPerms = Strings.read(pref);
}
Sidenote: Code is partially forked from Appsettings module: https://github.com/rovo89/XposedAppSettings
The problem is: when I restart my phone after enabling the module, I just get a blackscreen after the bootanimation.
When I comment out the line marked fat underlined, it works, but does nothing (because this line is essential).
I have practically no idea why this isn't working.
I know that the input returned from Strings.read is valid.
My Question: What am I doing wrong?
Click to expand...
Click to collapse
I am doing something similar. Maybe you can get some ideas from my PermissionGranter at:
https://github.com/GravityBox/Gravi...co/lollipop/gravitybox/PermissionGranter.java
I thought it would be better to modify the query instead of lists itself, but I'll try that out. Thanks!
Now my Hook looks like this:
Code:
XC_MethodHook hookGrantPermissions = new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String pkgName = (String) getObjectField(param.args[0], "packageName");
if (!(pkgName.equals(Strings.LLX) || pkgName.equals(Strings.LL))) return;
Object extras = getObjectField(param.args[0], "mExtras");
Set<String> grantedPerms = (Set<String>) getObjectField(extras, "grantedPermissions");
Object settings = getObjectField(param.thisObject, "mSettings");
Object permissions = getObjectField(settings, "mPermissions");
for (String perm : newPerms) {
Object permission = callMethod(permissions, "get", perm);
if (permission == null) continue;
grantedPerms.add(perm);
int[] gpGids = (int[]) getObjectField(extras, "gids");
int[] bpGids = (int[]) getObjectField(permission, "gids");
gpGids = (int[]) callStaticMethod(param.thisObject.getClass(),
"appendInts", gpGids, bpGids);
if (BuildConfig.DEBUG) XposedBridge.log("Permission added: " + permission);
}
}
};
But checkCallingOrSelfPermsisson still fails for the added permissions...
I get the log (in fact two times) but I still don't seem to have the permissions inside of the app.
Solved it myself. If there is a shared user, it has to be used instead of normal object.
Code:
XC_MethodHook hookGrantPermissions = new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String pkgName = (String) getObjectField(param.args[0], "packageName");
if (!(pkgName.equals(Strings.LLX) || pkgName.equals(Strings.LL))) return;
Object extras = getObjectField(param.args[0], "mExtras");
Set<String> grantedPerms = (Set<String>) getObjectField(extras, "grantedPermissions");
Object sharedUser = getObjectField(extras, "sharedUser");
if(sharedUser != null) grantedPerms = (Set<String>) getObjectField(sharedUser, "grantedPermissions");
Object settings = getObjectField(param.thisObject, "mSettings");
Object permissions = getObjectField(settings, "mPermissions");
for (String perm : newPerms) {
Object permission = callMethod(permissions, "get", perm);
if (permission == null) continue;
grantedPerms.add(perm);
int[] gpGids = (int[]) getObjectField(sharedUser!=null?sharedUser:extras, "gids");
int[] bpGids = (int[]) getObjectField(permission, "gids");
callStaticMethod(param.thisObject.getClass(),
"appendInts", gpGids, bpGids);
if (BuildConfig.DEBUG) XposedBridge.log("Permission added: " + permission);
}
}
};
@C3C076 do you know any way how to get runtime (level dangerous) permissions on Android Marshmallow?
Getting normal permissions is actually a bit easier now, but I haven't found a way for runtime permissions.
Hello. I have this code.
Code:
public String getId() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
String id;
try {
data.writeInterfaceToken("com.google.android.gms.ads.identifier.internal.IAdvertisingIdService");
binder.transact(1, data, reply, 0);
reply.readException();
id = reply.readString();
} finally {
reply.recycle();
data.recycle();
}
return id;
}
How i can hook " id = reply.readString();" when a don't know method name like "getId()". Thanks.
PS: Sorry for my bad English.
Now i can hook "transact" method like this:
Code:
XposedHelpers.findAndHookMethod("android.os.BinderProxy", loadPackageParam.classLoader, "transact", int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() {
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
IBinder binder = (IBinder) param.thisObject;
String interfaceBinder = binder.getInterfaceDescriptor();
if (interfaceBinder.equals("com.google.android.gms.ads.identifier.internal.IAdvertisingIdService")) {
// change result for readString
}
}
});
But i cant override "readString" result for Parcel (args[2]) object. How can i do this? Thanks.
Code:
public class SuperHook implements IXposedHookLoadPackage, IXposedHookZygoteInit {
Config mConfig;
Gson mGson;
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
mConfig = new Config();
mGson = new Gson();
}
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
Log.d("SuperHook", "handleLoadPackage imei:" + mConfig.getmImei());
if (loadPackageParam.packageName.equals("cn.superscript.supertools")) {
Class<?> classSuperService = XposedHelpers.findClass(SuperService.class.getName(), loadPackageParam.classLoader);
XposedHelpers.findAndHookMethod(classSuperService, "onStartCommand", Intent.class, int.class, int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Intent intent = (Intent) param.args[0];
String json = intent.getStringExtra("json");
mConfig = mGson.fromJson(json, new TypeToken<Config>() {
}.getType());
Log.d("SuperHook", "onStartCommand: imei = " + mConfig.getmImei());
}
});
}
}
}
Log:
01-21 18:49:56.220 664-664/? D/SuperHook: handleLoadPackage imei:null
01-21 18:49:56.240 664-664/? D/SuperHook: onStartCommand: imei = 3333333
01-21 18:50:00.930 757-757/com.android.settings D/SuperHook: handleLoadPackage imei:null
why handleLoadPackage imei = null , onStartCommand: imei = 3333333 successful.
Please help me, thank you
Have you ever tried to extend your favorite app with new features using Xposed, but were shocked halfway that your hooked app doesn't declare a permission in AndroidManifest ? And then you spent infinite hours on the internet trying to solve this frustrating problem, you decided to use services and an external intent, but you found out that it was not convenient, and finally you gave up...
So you are like me, who wasted hours looking for a solution, until I figured out how to do it myself. Here's a snippet to save time for future Xposed enthusiasts. Put this code snippet in handleLoadPackage
Java:
// Hook will only patch System Framework
if (!lpparam.packageName.equals("android")) return;
String targetPkgName = "com.example.app"; // Replace this with the target app package name
String[] newPermissions = new String[] { // Put the new permissions here
"android.permission.INTERNET",
"android.permission.ACCESS_NETWORK_STATE"
};
String grantPermissionsMethod = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
grantPermissionsMethod = "restorePermissionState";
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) {
XposedBridge.log("[WARNING] THIS HOOK IS NOT GUARANTEED TO WORK ON ANDROID VERSIONS NEWER THAN ANDROID 12");
}
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
grantPermissionsMethod = "grantPermissions";
}
else {
grantPermissionsMethod = "grantPermissionsLPw";
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
XposedBridge.log("[WARNING] THIS HOOK IS NOT GUARANTEED TO WORK ON ANDROID VERSIONS PRIOR TO JELLYBEAN");
}
}
XposedBridge.hookAllMethods(XposedHelpers.findClass("com.android.server.pm.permission.PermissionManagerService", lpparam.classLoader),
grantPermissionsMethod, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// on Android R and above, param.args[0] is an instance of android.content.pm.parsing.ParsingPackageImpl
// on Android Q and older, param.args[0] is an instance of android.content.pm.PackageParser$Package
// However, they both declare the same fields we need, so no need to check for class type
String pkgName = (String) XposedHelpers.getObjectField(param.args[0], "packageName");
XposedBridge.log("Package " + pkgName + " is requesting permissions");
if (pkgName.equals(targetPkgName)) {
List<String> permissions = (List<String>) XposedHelpers.getObjectField(param.args[0], "requestedPermissions");
for (String newPermission: newPermissions) {
if (!permissions.contains(newPermission)) {
permissions.add(newPermission);
XposedBridge.log("Added " + newPermission + " permission to " + pkgName);
}
}
}
}
});
Notes:
You must check System Framework in LSposed Manager
A reboot is required after adding the target permissions
You still need to prompt the user to accept sensitive permissions (ie android.permission.READ_CONTACTS), even if you have added them using this method
Wow, thx. Great for the install permissions!
I wrote a class to grant install and runtime/sensitive permissions (without prompting users).
Android 12 and 13 implementation:
Java:
public class Grant_Package_Permissions {
private static final int sdk = android.os.Build.VERSION.SDK_INT;
public static void hook(LoadPackageParam lpparam) {
try {
Class<?> PermissionManagerService = XposedHelpers.findClass(
sdk >= 33 /* android 13+ */ ?
"com.android.server.pm.permission.PermissionManagerServiceImpl" :
"com.android.server.pm.permission.PermissionManagerService", lpparam.classLoader);
Class<?> AndroidPackage = XposedHelpers.findClass(
"com.android.server.pm.parsing.pkg.AndroidPackage", lpparam.classLoader);
Class<?> PermissionCallback = XposedHelpers.findClass(
sdk >= 33 /* android 13+ */ ?
"com.android.server.pm.permission.PermissionManagerServiceImpl$PermissionCallback" :
"com.android.server.pm.permission.PermissionManagerService$PermissionCallback", lpparam.classLoader);
// PermissionManagerService(Impl) - restorePermissionState
XposedHelpers.findAndHookMethod(PermissionManagerService, "restorePermissionState",
AndroidPackage, boolean.class, String.class, PermissionCallback, int.class, new XC_MethodHook() {
@SuppressWarnings("unchecked")
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// params
Object pkg = param.args[0];
int filterUserId = (int) param.args[4];
// obtém os campos
Object mState = XposedHelpers.getObjectField(param.thisObject, "mState");
Object mRegistry = XposedHelpers.getObjectField(param.thisObject, "mRegistry");
Object mPackageManagerInt = XposedHelpers.getObjectField(param.thisObject, "mPackageManagerInt");
// Continua ?
String packageName = (String) XposedHelpers.callMethod(pkg, "getPackageName");
Object ps = XposedHelpers.callMethod(mPackageManagerInt,
sdk >= 33 /* android 13+ */ ?
"getPackageStateInternal" :
"getPackageSetting", packageName);
if (ps == null)
return;
int[] getAllUserIds = (int[]) XposedHelpers.callMethod(param.thisObject, "getAllUserIds");
int userHandle_USER_ALL = XposedHelpers.getStaticIntField(Class.forName("android.os.UserHandle"), "USER_ALL");
final int[] userIds = filterUserId == userHandle_USER_ALL ? getAllUserIds : new int[]{filterUserId};
for (int userId : userIds) {
List<String> requestedPermissions;
Object userState = XposedHelpers.callMethod(mState, "getOrCreateUserState", userId);
int appId = (int) XposedHelpers.callMethod(ps, "getAppId");
Object uidState = XposedHelpers.callMethod(userState, "getOrCreateUidState", appId);
// package 1
if (packageName.equals("PACKAGE_1")) {
requestedPermissions = (List<String>) XposedHelpers.callMethod(pkg, "getRequestedPermissions");
grantInstallOrRuntimePermission(requestedPermissions, uidState, mRegistry,
Manifest.permission.RECORD_AUDIO);
grantInstallOrRuntimePermission(requestedPermissions, uidState, mRegistry,
Manifest.permission.MODIFY_AUDIO_SETTINGS);
}
// package 2
if (packageName.equals("PACKAGE_2")) {
requestedPermissions = (List<String>) XposedHelpers.callMethod(pkg, "getRequestedPermissions");
grantInstallOrRuntimePermission(requestedPermissions, uidState, mRegistry,
Manifest.permission.READ_CONTACTS);
}
}
}
});
} catch (Exception e) {
XposedBridge.log(e);
}
}
private static void grantInstallOrRuntimePermission(List<String> requestedPermissions, Object uidState,
Object registry, String permission) {
if (!requestedPermissions.contains(permission))
XposedHelpers.callMethod(uidState, "grantPermission",
XposedHelpers.callMethod(registry, "getPermission", permission));
}
}
Edit: Android 12 and 13 implementation!
this looks promising. how to use this in xposed ? is there a module available?