Hello guys,
Here is the script to get RAM capacity of a device. It's really different to other device specs that I read.
I have no idea how to hook to change it (memInfo.totalMem) .
PHP:
ActivityManager actManager = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
long totalMemory = memInfo.totalMem;
The system file "/proc/meminfo" also holds RAM memory info, I tried to modify this file but didn't affect.
Is there anyway to solve this problem??
Have a nice day.
kidsphy said:
Hello guys,
Here is the script to get RAM capacity of a device. It's really different to other device specs that I read.
I have no idea how to hook to change it (memInfo.totalMem) .
PHP:
ActivityManager actManager = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
long totalMemory = memInfo.totalMem;
The system file "/proc/meminfo" also holds RAM memory info, I tried to modify this file but didn't affect.
Is there anyway to solve this problem??
Have a nice day.
Click to expand...
Click to collapse
You can try:
Code:
ActivityManager.MemoryInfo memInfo = (ActivityManager.MemoryInfo) XposedHelpers.newInstance(ActivityManager.MemoryInfo.class);
XposedHelpers.setObjectField(memInfo, "totalMem", 141211211L);
OR:
Code:
Constructor<?> constructLayoutParams = XposedHelpers.findConstructorExact(android.app.ActivityManager.MemoryInfo.class, Parcel.class);
constructLayoutParams.setAccessible(true);
XposedBridge.hookMethod(constructLayoutParams, new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if (param.args[0] != null) {
param.args[0] = new CustomMemoryInfo();
}
}});
CustomMemoryInfo extends MemoryInfo class, you can override super method to change "totalMem" attribute
hahalulu said:
You can try:
Code:
ActivityManager.MemoryInfo memInfo = (ActivityManager.MemoryInfo) XposedHelpers.newInstance(ActivityManager.MemoryInfo.class);
XposedHelpers.setObjectField(memInfo, "totalMem", 141211211L);
OR:
Code:
Constructor<?> constructLayoutParams = XposedHelpers.findConstructorExact(android.app.ActivityManager.MemoryInfo.class, Parcel.class);
constructLayoutParams.setAccessible(true);
XposedBridge.hookMethod(constructLayoutParams, new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if (param.args[0] != null) {
param.args[0] = new CustomMemoryInfo();
}
}});
CustomMemoryInfo extends MemoryInfo class, you can override super method to change "totalMem" attribute
Click to expand...
Click to collapse
Thank for your reply, but it doesn't work. Have you ever tried running this piece or it's just your thinking?
Here's a commented example of doing this (at least for the method that you posted):
Java:
// Hook the method getMemoryInfo from the ActivityManager class
XposedHelpers.findAndHookMethod(ActivityManager.class, "getMemoryInfo", ActivityManager.MemoryInfo.class, new XC_MethodHook() {
// We use afterHooked here because you have to modify the values *after* the method already setup the object,
// as this method take the object passed as argument and parcel the data (it's always good to check the source)
// https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityManager.java#2358 > which calls
// https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityManagerNative.java#4918
[user=439709]@override[/user]
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// Method contructor -> public void getMemoryInfo(MemoryInfo outInfo)
// As you can see, the getMemoryInfo take a MemoryInfo object as argument
// you just have to get the object from the arguments array, and then cast
// to MemoryInfo to set the desired field
((ActivityManager.MemoryInfo) param.args[0]).totalMem = 12345678L;
((ActivityManager.MemoryInfo) param.args[0]).availMem = 87654321L;
}
});
mauricio_C said:
Here's a commented example of doing this (at least for the method that you posted):
Click to expand...
Click to collapse
Thank you so much :good:
Related
Hello,
I am trying to get a *.9.png from sd card in my xposed module.
The Image loads and is set where I need it to be but it gets stretched.
I tried this:
Code:
resparam.res.setReplacement("com.whatsapp", "drawable", "input", new XResources.DrawableLoader() {
@Override
public Drawable newDrawable(XResources mRes, int id) throws Throwable {
XSharedPreferences prefs = new XSharedPreferences("in.proficientapps.uwte.trial", "saveImage");
String imagePath = prefs.getString("mImage", null);
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
byte[] chunk = bitmap.getNinePatchChunk();
//boolean result = NinePatch.isNinePatchChunk(chunk);
if (chunk == null) {
XposedBridge.log("Chunk is empty");
return Drawable.createFromPath(imagePath);
} else
return new NinePatchDrawable(bitmap, chunk, new Rect(), null);
}
});
and this:
Code:
resparam.res.setReplacement("com.whatsapp", "drawable", "input", new XResources.DrawableLoader() {
@Override
public Drawable newDrawable(XResources mRes, int id) throws Throwable {
XSharedPreferences prefs = new XSharedPreferences("in.proficientapps.uwte.trial", "saveImage");
String imagePath = prefs.getString("mImage", null);
return new NinePatchDrawable.createFromPath(imagePath);
}
});
Both results in same thing.
I have added a screenshot of how it looks on using the above codes.
Fixed the issue by compiling the *.9.png image by following the guide here : http://modmymobile.com/forums/404-motorola-cliq-themes/555408-guide-editing-compiling-draw9-9-png-images.html
I hope this will help other users too in future.
I have hooked a function from a class (w.class) and I want to call another function from another class (x.class). However, this x.class does not have any context or instance.
I tried searching XDA, Google and Github, but couldn't solve my problem. The closest thing I found was https://forum.xda-developers.com/xposed/findclass-returning-java-lang-class-t2853108 but as I stated, I do not have a context or instance.
My w.class is:
PHP:
final class w
extends Thread
{
private Handler b = new Handler();
w(SplashActivity paramSplashActivity) {}
public final void run()
{
this.b.postDelayed(new x(this), 2000L);
super.run();
}
}
and the x.class is
PHP:
final class x
implements Runnable
{
x(w paramw) {}
public final void run()
{
w.a(this.a).startActivity(new Intent(w.a(this.a).getApplicationContext(), pack.class));
}
}
I have hooked the run() function from w.class, but I don't know how to call the run() method from x.class.
My Xposed module looks like this:
PHP:
XposedHelpers.findAndHookMethod("com.pack.w", lpparam.classLoader, "run", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) {
XposedBridge.log(TAG + " we are replacing... " );
Class<?> classstart = XposedHelpers.findClass("com.pack.x", lpparam.classLoader);
Context context = (Context) XposedHelpers.getObjectField(param.thisObject, "context");
Object class2Instance = XposedHelpers.newInstance(classstart, context);
XposedHelpers.callMethod(class2Instance, "run");
XposedBridge.log(TAG + " replacing should be done " );
return null;
}
});
but since there is no "context" in x.class, it does not get the object and I cannot use callMethod()
any ideas, please? I am bit stucked
P.S.: Btw, the main goal is to remove the 2000ms wait from "postDelayed()". I did it through .smali already, but wanted to learn how to do it in Xposed.
still nothing?
I feel like this is more complicated than necessary. If Xposed weren't in the picture, and you were writing code that would end up in w.class, what statement would you put there to do what you want?
josephcsible said:
I feel like this is more complicated than necessary. If Xposed weren't in the picture, and you were writing code that would end up in w.class, what statement would you put there to do what you want?
Click to expand...
Click to collapse
Hi and thanks for answering!
I would just write a call to the e.class.
rauleeros said:
Hi and thanks for answering!
I would just write a call to the e.class.
Click to expand...
Click to collapse
I meant can you post the exact line of Java that you'd add, and which method you'd put it in?
josephcsible said:
I meant can you post the exact line of Java that you'd add, and which method you'd put it in?
Click to expand...
Click to collapse
Well, I would simply replace it with this:
PHP:
public final void run()
{
this.b.postDelayed(new x(this), 10L); // run for 10ms instead of 2 seconds
super.run();
}
rauleeros said:
Well, I would simply replace it with this:
PHP:
public final void run()
{
this.b.postDelayed(new x(this), 10L); // run for 10ms instead of 2 seconds
super.run();
}
Click to expand...
Click to collapse
Why are you involving a Context at all? Try this:
Code:
// Replace this:
Context context = (Context) XposedHelpers.getObjectField(param.thisObject, "context");
Object class2Instance = XposedHelpers.newInstance(classstart, context);
// With this:
Object class2Instance = XposedHelpers.newInstance(classstart, param.thisObject);
josephcsible said:
Why are you involving a Context at all? Try this:
Code:
// Replace this:
Context context = (Context) XposedHelpers.getObjectField(param.thisObject, "context");
Object class2Instance = XposedHelpers.newInstance(classstart, context);
// With this:
Object class2Instance = XposedHelpers.newInstance(classstart, param.thisObject);
Click to expand...
Click to collapse
Didn't even realize I could do it as simple as that! Thanks a lot for the help, I really appreciate it man
i have a class like this
PHP:
package com.insight.sdk;
public class ISBuildConfig {
public static int ASSETS_JAR_VERSION_CODE = 100043;
public static String ASSETS_JAR_VERSION_NAME = "v100.1.2.0_release";
public static boolean DEBUG = false;
public static int LOADER_VERSION_CODE = 100043;
public static String LOADER_VERSION_NAME = "v2.1.3_release";
public static final int NOUGAT = 24;
}
i want to change DEBUG to true
how to use xposed to change this value?
hotwap said:
...
how to use xposed to change this value?
Click to expand...
Click to collapse
Try kooking it as early as possible (Application's onCreate() is a good place to do that):
PHP:
XposedHelpers.findAndHookMethod(>>> APPLICATION.class <<<, "onCreate", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedHelpers.setStaticBooleanField(ISBuildConfig.class, "DEBUG", true);
}
}
SU Version 2.82 and using BlueStacks 3
I've made a post on StackExchange but w/o any responses - inside are links I'll reference below but unfortunately can't directly post here due to being a new user of these forums. Googling the following should turn up the result: SU Command to start java class for input automation not working
Since then I've learned a bit more about what I'm trying to do (which is surprising considering I've been attempting this since the 30th of January) and implemented a singleton so that I can toast from within the class I'm attempting to start. Regardless of whether this allows me to inject inputs to other apps, my current problem is simply that I'm unable to use a SU command to open up my Main.Java class as described in the following links:
The code describing what I'm trying to do: OmerJerk Execute Java Class as Root User
The code w/ a full implementation: Remotedroid on GitHub
^ ServerService runs MainStarter which runs Main.Java as SU so that Main.Java can run EventInput to inject motion events
The super basic implementation I've got is below, but I've tried a bunch of things. I can't seem to figure out what's going wrong.
A snippet from ActivityMain wherein I'm running the Main.Java (attempting at least):
Code:
new Main().main(COMMAND3); //COMMAND3 is just a String[] because if it's not provided this won't execute. This isn't what I'm trying to do, though. Just a test to see if my Main.Java was broke.
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids){
try {
//BlueStacks is 32 bit so it only has app_process - it doesn't have app_process32 and I believe if you try to target it it simply fails (the symbolic link is inconsistent iirc) vv
String[] COMMAND4 = {"su", "-c", "\"CLASSPATH=" + MainActivity.this.getPackageCodePath(), "/system/bin/app_process", "/system/bin", MainActivity.this.getPackageName() + ".Main"};
java.lang.Process console = Runtime.getRuntime().exec(COMMAND4);
BufferedWriter stdin = new BufferedWriter(new OutputStreamWriter(console.getOutputStream()));
String outputStr = new String();
BufferedReader reader = new BufferedReader(new InputStreamReader(console.getInputStream()));
while (reader.ready()) {
outputStr += reader.readLine();
}
PropertyReader.getInstance().setText(outputStr);
} catch (IOException e) {
e.printStackTrace();
PropertyReader.getInstance().showToast("IOException" + e.getMessage());
}
// final List<String> SUOutput = Shell.SU.run(String.format(COMMAND,
// new String[] {
// getApplicationContext()
// }));
// final String joined = TextUtils.join(", ", SUOutput);
//
// runOnUiThread(new Runnable() {
// @Override
// public void run() {
// if (SUOutput != null) {
// Toast.makeText(MainActivity.this, "Output isn't null" + joined, Toast.LENGTH_LONG).show();
// Toast.makeText(MainActivity.this, joined, Toast.LENGTH_LONG).show();
// Toast.makeText(MainActivity.this, SUOutput.toString(), Toast.LENGTH_LONG).show();
//
// } else {
// Toast.makeText(MainActivity.this, "Output is null o-o", Toast.LENGTH_LONG).show();
// }
// }
// });
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "It finished.. ?", Toast.LENGTH_LONG).show();
PropertyReader.getInstance().ToastString();
}
});
return null;
}
}.execute();
}
And my Main.Java is reaaaally simple and very stripped down at this point:
Code:
package intsumniac.overbitegames.com.intsumniac;
import android.os.Process;
public class Main {
public static void main(String[] args) {
PropertyReader.getInstance().showToast("Main Is working!!! SUCCESS" + "current process id = " + Process.myPid() + "current process uid = " + Process.myUid()); //Should be 0, preferably
}
}
It is certainly possible to run Java stuff as root, however you are lacking many contexts/instances/etc. There is some trickery to be able to get around some of that. Some of my apps' root parts are mostly Java, in fact.
Rule of thumb is that most Android API calls are not available, just standard Java things. Toasting for example is most certainly not available.
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?