how to inflate a layout which is in the res directory of my own module? - Xposed General

Hi everyone:
how could I use View.inflate() to inflate a layout which is in the res directory of my own module? I want to add this layout into the target app’s view container.
I had tried to generate a fakeId for this layout xml resource file by this way:
Code:
fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam?) {
MODULE_PATH = startupParam?.modulePath
}
fun handleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam?) {
val modRes = XModuleResources.createInstance(MODULE_PATH, resparam.res)
ID_MENU = resparam.res.addResource(modRes, R.layout.menu_littlespider)
}
then I use this ID_MENU to to inflate it:
Code:
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?){
findAndHookMethod(C.View, "inflate", C.Context, C.Int, C.ViewGroup, object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam?) {
if (param == null) return
val context = param.args[0] as Context
var targetViewId = param.args[1] as Int
if (targetViewId == 2130904238) {
var targetView = param.result as LinearLayout
val layoutParser = context.resources.getLayout(InitResourceHooker.ID_MENU)
val menu = LayoutInflater.from(context).inflate(layoutParser, null)
//val menu = View.inflate(context, InitResourceHooker.ID_MENU, null) as LinearLayout
targetView.addView(menu, 0)
}
}
})
}
sadly,it gives me an error,#0x7eb8f41b is my FakeId :
Code:
android.content.res.Resources$NotFoundException: Resource ID #0x7eb8f41b
can anyone show me is it possible to inflate this layout?
thanks a lot!

吃泡面的猫儿 said:
Hi everyone:
how could I use View.inflate() to inflate a layout which is in the res directory of my own module? I want to add this layout into the target app’s view container.
I had tried to generate a fakeId for this layout xml resource file by this way:
then I use this ID_MENU to to inflate it:
sadly,it gives me an error,#0x7eb8f41b is my FakeId :
can anyone show me is it possible to inflate this layout?
thanks a lot!
Click to expand...
Click to collapse
Hint: use getResourcesForApplication
Background: Xposed hooks run in the context of the hooked app.

Also, you can inflate layout without adding it to hooked app resources provided you create instance of LayoutInflater using your xposed app context.
Code:
Context ctx = context.createPackageContext("your_xposed_app_pkg_name", Context.CONTEXT_IGNORE_SECURITY);
LayoutInflater inflater = LayoutInflater.from(ctx);
inflater.inflate(R.layout.your_layout, parent);
The thing is, layout can contain only such elements that are known to hooked app classloader.
E.g. you won't be able to inflate layout that contains some custom views that were defined within your app, as inflater created within hooked app won't be able to resolve them.

C3C076 said:
Also, you can inflate layout without adding it to hooked app resources provided you create instance of LayoutInflater using your xposed app context.
Code:
Context ctx = context.createPackageContext("your_xposed_app_pkg_name", Context.CONTEXT_IGNORE_SECURITY);
LayoutInflater inflater = LayoutInflater.from(ctx);
inflater.inflate(R.layout.your_layout, parent);
The thing is, layout can contain only such elements that are known to hooked app classloader.
E.g. you won't be able to inflate layout that contains some custom views that were defined within your app, as inflater created within hooked app won't be able to resolve them.
Click to expand...
Click to collapse
Hi, i wonder if i can inflate layout which is in res directory of my app target?

Related

[add custom action intent to My custon ROM]

Hi friends,
I try to make my own ROM by adding my own intent actions, this actions will brodcasted by the system when i click on the camera button ,
where i can add this two lines :
Code:
Intent myintent =new Intent("ACTION_MY_OWN_INTENT");
context.sendBroadcast(myintent);
Thanks for any help.
01tarik007 said:
Hi friends,
I try to make my own ROM by adding my own intent actions, this actions will brodcasted by the system when i click on the camera button ,
where i can add this two lines :
Code:
Intent myintent =new Intent("ACTION_MY_OWN_INTENT");
context.sendBroadcast(myintent);
Thanks for any help.
Click to expand...
Click to collapse
Now my action is broadcasted by the system , only when i click on Volume up or down physique button by doing this:
open the AudioService.java path/to/android_root/frameworks/base/media/java/android/media/AudioService.java.
search for sendVolumeUpdate function
Code:
// UI update and Broadcast Intent
private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
if (!isPlatformVoice() && (streamType == AudioSystem.STREAM_RING)) {
streamType = AudioSystem.STREAM_NOTIFICATION;
}
if (streamType == AudioSystem.STREAM_MUSIC) {
flags = updateFlagsForSystemAudio(flags);
}
mVolumeController.postVolumeChanged(streamType, flags);
if ((flags & AudioManager.FLAG_FIXED_VOLUME) == 0) {
oldIndex = (oldIndex + 5) / 10;
index = (index + 5) / 10;
Intent intent = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
intent.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
sendBroadcastToAll(intent);
}
}
and add your own action in the end of this function
Code:
Intent myintent =new Intent("ACTION_MY_OWN_INTENT") }
use
Code:
sendBroadcastToAll
function to broadcast the intent, so you can be sure that the context had been well initiated.
now I try to make my own module for sending my own action intent, any helps are welcome.
:laugh:
offfff
finally the secret is here
Code:
android_root/frameworks/base/policy/src/com/android/internal/policy/impl/ PhoneFallbackEventHandler.java
Thanks t me

[Q][Help Needed]Drawable.setColorFilter(a, b) not working.

Hello,
I am working on a Xposed Module and for which I require to change the Colour of a Drawable PNG to User Selected.
I am using this code :
Code:
final int mAccentColour = pref.getInt("pref_key_theme_colour_accent", R.color.predefined_theme_blue);
resparam.res.setReplacement("com.whatsapp", "drawable", "input_circle_normal", new XResources.DrawableLoader() {
@Override
public Drawable newDrawable(XResources res, int id) throws Throwable {
Drawable myIcon = modRes.getDrawable(R.drawable.scrubber_normal);
if (myIcon != null) {
myIcon.mutate().setColorFilter(mAccentColour, PorterDuff.Mode.DST_OVER);
}
return myIcon;
}
});
But it won't work. Icon gets replaced my newIcon but Color Filter is not working.
SArnab©® said:
Hello,
I am working on a Xposed Module and for which I require to change the Colour of a Drawable PNG to User Selected.
I am using this code :
Code:
final int mAccentColour = pref.getInt("pref_key_theme_colour_accent", R.color.predefined_theme_blue);
resparam.res.setReplacement("com.whatsapp", "drawable", "input_circle_normal", new XResources.DrawableLoader() {
@Override
public Drawable newDrawable(XResources res, int id) throws Throwable {
Drawable myIcon = modRes.getDrawable(R.drawable.scrubber_normal);
if (myIcon != null) {
myIcon.mutate().setColorFilter(mAccentColour, PorterDuff.Mode.DST_OVER);
}
return myIcon;
}
});
But it won't work. Icon gets replaced my newIcon but Color Filter is not working.
Click to expand...
Click to collapse
Hello, is not it better to use
Code:
myIcon.[STRIKE]mutate().[/STRIKE]setColorFilter(mAccentColour, PorterDuff.Mode.DST_OVER);
?
Or in case he needs to use mutate() to make sure only that instance of resource drawable gets state change, he should rather:
Code:
Drawable myIcon = modRes.getDrawable(R.drawable.scrubber_normal)[COLOR="Red"].mutate();[/COLOR]
if (myIcon != null) {
myIcon.setColorFilter(mAccentColour, PorterDuff.Mode.DST_OVER);
}
deadlynounou said:
Hello, is not it better to use
Code:
myIcon.[STRIKE]mutate().[/STRIKE]setColorFilter(mAccentColour, PorterDuff.Mode.DST_OVER);
?
Click to expand...
Click to collapse
Thanks for replying. One of my friend told the same and it worked.
But the strange thing is that before I too tried the same but it didn't worked. I don't know what made it work at last but now am all set to go ahead.
C3C076 said:
Or in case he needs to use mutate() to make sure only that instance of resource drawable gets state change, he should rather:
Code:
Drawable myIcon = modRes.getDrawable(R.drawable.scrubber_normal)[COLOR="Red"].mutate();[/COLOR]
if (myIcon != null) {
myIcon.setColorFilter(mAccentColour, PorterDuff.Mode.DST_OVER);
}
Click to expand...
Click to collapse
Thanks for replying. If ever I will need to use mutate(), I will use your implementation.
Post Deleted

[Q] How to modify memory capacity?

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:

Calling another method from another class

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

Suggest method to load libraries (.aar)dynamically in java application (.apk)

Pls Suggest method to load libraries (.aar) dynamically in android java application.
I have Tried below:
File file = Environment.getExternalStorageDirectory();
File jarFile = new File(file.getAbsolutePath()+File.separator + "myjarlib.jar");
dalvik.system.PathClassLoader myClassLoader = new dalvik.system.PathClassLoader("/storage/emulated/0/myjarlib.jar", ModuleLoader.class.getClassLoader());
myClassLoader.findLibrary("myjarliib.jar");
Enumeration<URL> en = myClassLoader.getResources("META-INF");
//Enumeration<URL> en = getClass().getClassLoader().getResources("META-INF");
List<String> profiles = new ArrayList<>();
while (en.hasMoreElements()) {
URL url = en.nextElement();
JarURLConnection urlcon = (JarURLConnection) (url.openConnection());
try (JarFile jar = urlcon.getJarFile() {
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
String entry = entries.nextElement().getName();
System.out.println(entry);
Log.d("tag" ,entry );
}
}
}
Class classToLoad = Class.forName("MyClass.class", true, myClassLoader); -----> I am getting ClassNotFound exception here. Pls suggest .
ModuleLoader.java
***************************************************************************************************************************************
package com.tel.myapplication;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import com.tel.myapplication.IPeripheral;
public class ModuleLoader {
private static List<URL> urls = new ArrayList<URL>();
// to retrieve the unknown list of jar files contained in the directory folder
// in my case it was in the SDCard folder
// link to create a SDCard directory on the Eclipse emulator
// http://blog.lecacheur.com/2010/01/14/android-avoir-acces-a-une-carte-memoire-dans-lemulateur/
// retrieve the classes of all this jar files and their URL (location)
private static List<String> getModuleClasses(String folder)
{
List<String> classes = new ArrayList<String>();
//we are listing the jar files
File[] files = new File(folder).listFiles(new ModuleFilter());
for(File f : files)
{
JarFile jarFile = null;
try
{
//we open the jar file
jarFile = new JarFile(f);
//we recover the manifest
Manifest manifest = jarFile.getManifest();
//we recover the class name of our peripherals thanks to ours manifest
String moduleClassName = manifest.getMainAttributes().getValue("Module-Class");
classes.add(moduleClassName);
urls.add(f.toURI().toURL());
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if(jarFile != null)
{
try
{
jarFile.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
return classes;
}
private static class ModuleFilter implements FileFilter {
@override
public boolean accept(File file) {
return file.isFile() && file.getName().toLowerCase().endsWith(".jar");
}
}
//This function loads the jar file into the dalvik system
// retrieves the associated classes using its name
// and try to know if the loaded classes are implementing our interface
public static List<IPeripheral> loadModules(String folder, Context CurrentContext) {
List<IPeripheral> modules = new ArrayList<IPeripheral>();
List<String> classes = getModuleClasses(folder);
int index = 0;
for(String c : classes)
{
try
{
dalvik.system.PathClassLoader myClassLoader = new dalvik.system.PathClassLoader(urls.get(index).toString(), ModuleLoader.class.getClassLoader());
Class<?> moduleClass = Class.forName(c, true, myClassLoader);
//check and cast to an interface, then use it
if(IPeripheral.class.isAssignableFrom(moduleClass))
{
@SuppressWarnings("unused")
Class<IPeripheral> castedClass = (Class<IPeripheral>)moduleClass;
IPeripheral module = (IPeripheral)moduleClass.newInstance();
modules.add(module);
}
index++;
}
catch (ClassNotFoundException e1)
{
e1.printStackTrace();
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
return modules;
}
}
IPeripheral
package com.tel.myapplication;
public interface IPeripheral {
public boolean Initialize();
public boolean configure();
public boolean execute();
public String GetName();
}
To dynamically load libraries (.aar) in a Java application (.apk), you can use the following steps:
1# Download the library file (.aar) and save it in the "libs" folder of your Android project.
2# In your Java code, use the "DexClassLoader" class to load the library dynamically. You can use the following code snippet as an example:
String libraryPath = context.getFilesDir() + "/libs/your-library.aar";
DexClassLoader classLoader = new DexClassLoader(libraryPath, context.getCacheDir().getPath(), null, context.getClassLoader());
Class<?> libraryClass = classLoader.loadClass("com.your.library.ClassName");
In this example, "context" refers to the Android application context, "your-library.aar" is the name of the library file, and "com.your.library.ClassName" is the fully qualified name of the class you want to load from the library.
3# Once the library is loaded, you can use it in your Java code as you would with any other library. For example, you can call methods on objects from the library or create new objects from classes in the library.
Note that dynamically loading libraries can be more complex than using static libraries, and requires careful handling of class loading and versioning. You should ensure that the library you are loading is compatible with your application and has been thoroughly tested before using it in production.

Categories

Resources