Hi,
I'm trying to hook on a method that belongs to a class that is dynamically loaded from a .dex file (via DexClassLoader). How can I hook on this. I seen comments before where people say to hook using the DexClassLoader instead of standard class loader we have available to us through Xposed. (http://stackoverflow.com/a/28635776/3899529) How can I do this? I'm finding it hard to find examples online? How do I grab an instance and use this instance for hooking? Does anyone have a small snippet example please?
Thanks.
Did you already find out how/where the class is loaded from the dex file? Can you post that snippet please? I assume the DexClassLoader will be stored somewhere. So you could then hook the method that creates the class loader and after it has been executed, you try to fetch the class loader instance from the place where it was stored and use it to hook the method you actually want to target. Details really depend on the implementation of the app...
Hi, thanks for your reply. I figured it out. Thanks.
I didn't realize we could have nested hooks. (i.e declare hooks within hooks).
As it turns out, it was actually DexFile in this particular case I needed to hook on, not DexClassLoader. But I hooked on "after" DexFile.loadDexFile, and in there placed nested hooks. As DexFile.loadDexFile() uses same class loader as the one the app originally was booted with, the class was now loaded at that stage and could be found. So I could hook using the class loader xposed provided me, after a set point in time to hook this dynamically loaded class .
I guess it would be similar approach if DexClassLoader was used. I would hook on the Constructor(?) of DexClassLoader, capture the class loader instance, and use that instance for then hooking in the dynamically loaded classes.
Related
I used dex2jar on the apk I am hooking and made it an external jar in eclipse and all my references to classes in it get resolved in eclipse and it doesn't complain. But the code in my module is failing. Specifically, I'm trying to create a class which extends an abstract class in the original apk. When I try to do new MyClass(); the logcat shows:
Unable to resolve superclass
Is there any way to make it work the way I have it, or is there some other way that I need to instantiate my own instance of an abstract class?
If you just instantiate a class, I think Java tries to resolve it using the calling class's classloader. That classloader only knows the classes in your APK, and otherwise falls back to the boot classloader.
The only chance I see is to put your subclass into a separate JAR, then during handleLoadPackage() create a new PathClassLoader and use lpparam.classLoader as parent. Then I think you should be able to find and instantiate your class via reflection.
rovo89 said:
If you just instantiate a class, I think Java tries to resolve it using the calling class's classloader. That classloader only knows the classes in your APK, and otherwise falls back to the boot classloader.
The only chance I see is to put your subclass into a separate JAR, then during handleLoadPackage() create a new PathClassLoader and use lpparam.classLoader as parent. Then I think you should be able to find and instantiate your class via reflection.
Click to expand...
Click to collapse
Thanks for the tip on using the class loader. I managed to get it working without a jar:
Code:
String dexPath = (String)XposedHelpers.getObjectField(getClass().getClassLoader(), "originalPath");
PathClassLoader combinedClassLoader = new PathClassLoader(dexPath, lpparam.classLoader);
Class<?> c = combinedClassLoader.loadClass("MY.CLASS");
EDIT: So it seems I'm able to do c.newInstance() directly in handleLoadPackage, but if I am inside of a replaceHookedMethod I still get the unable to resolve. It's good enough for what I need, because I can create the class in handleLoadPackage just fine.
EDIt2: Well nevermind, it works in both places. It seems I was trying to cast it, and that is what was causing the error. So when doing this, you have to use generic objects, which I suppose makes sense, since the class loader in that context isn't the combined one.
Thanks for posting the solution! Be careful with getClass(), as it depends on where you use it. You might want to grab your APK's path in initZygote instead.
rbox said:
It seems I was trying to cast it, and that is what was causing the error. So when doing this, you have to use generic objects, which I suppose makes sense, since the class loader in that context isn't the combined one.
Click to expand...
Click to collapse
Yes, you can't cast between objects/classes loaded from different class loaders, even when they are the same class from the same APK. Also, it would probably not work in your situation because the class can't be resolved with your class loader.
Hi,
In my Xposed module, I have two classes with different hooks on different classes.
When hook A (from class X) finishes I want to save a flag that hook B (from class Y) will be able to read and act accordingly.
I tried class with static methods and a singleton class, in both cases, hook B can't see the changes hook A has done.
What is the best way to get this done?
Thanks!
I am hooking a class that extends FrameLayout. The FrameLayout has an override method of "onInterceptTouchEvent" that I would like to hook, however, the custom class that I am hooking never overrides this method. So doing the usual, XposedHelpers.findAndHookMethod() causes "method not found exception". I feel like I have done this before, but can't recall exactly what I did to make it work.
Any help is appreciated!
@GermainZ
You have any idea how to do this?
Tip from MohammadAG: you can override the superclass' method (FrameLayout.onInterceptTouchEvent) and check for the class name of the current instance (to see if it matches the class you want to hook or not).
GermainZ said:
Tip from MohammadAG: you can override the superclass' method (FrameLayout.onInterceptTouchEvent) and check for the class name of the current instance (to see if it matches the class you want to hook or not).
Click to expand...
Click to collapse
Thanks man. I wasn't sure if that would work since the custom class doesn't call super.onInterceptTouchEvent() but I will try it. Thanks again boss!
Hello everyone!
I'm having some dificulty with AsyncTask class hook.
To be more specific, I need to hook doInBackground(Params... params), but i have no idea about how to do that since it uses generic type Params, and I need to point to findAndHookMethod the param type.
samctt said:
Hello everyone!
I'm having some dificulty with AsyncTask class hook.
To be more specific, I need to hook doInBackground(Params... params), but i have no idea about how to do that since it uses generic type Params, and I need to point to findAndHookMethod the param type.
Click to expand...
Click to collapse
Note, that you cannot hook directly to AsyncTask.doInBackground since it's an abstract method. You have to hook it within particular implementation (instance of a class derived from AsyncTask).
Then you could use XposedBridge.hookAllMethods as there is only one doInBackground method so you don't need to pay attention to parameter type.
Btw, Params... are basically treated as arrays (Params[])
I've been trying to hook a method for hours and I'm kind of desperate.
The scenario:
I have a browser app which allows to create shortcuts on your homescreen. The only problem is: They are not renamable. So I thought I write a little xposed module to make this possible.
Steps taken:
Create module base and make it loadable into xposed - check.
Make sure method hook is only called from inside the application - check.
Create a simple dialog with edit stuff - check.
Finding and hooking the correct method in correct class - fail.
The method I am trying to hook is "sendBroadcast(Intent)". The original method is abstract and not hookable.
My first try was to hook the method in "android.content.Context" -> abstract.
I read somewhere that you can hook a subclass so I tried "android.content.ContextWrapper". Turns out this just inherits the method from android.content.Context and is still abstract.
Same goes to "android.app.Activity". So I searched for the Implementation of the sendBroadcast function. I found it in "android.app.ContextImpl" but this also turned out to be just the abstract method call from "android.content.Context".
It can't be that hard to find the right class to hook, right?
I didn't want to use the "hookAllMethods" because it seemed a little overkill for such a small change.
This is my last hook try:
Code:
findAndHookMethod(XposedHelpers.findClass("android.app.ContextImpl", lpparam.classLoader), "sendBroadcast", Intent.class, new XC_MethodHook(){
//... stuff here which I think is correct
}
the browser calls sendBroadcast with only one argument, right?
do you get a NoSuchMethodException, or just can't find the broadcast you want in this method?
Sorry for the late answer.
The error I get is: "IllegalArgumentException: abstract methods cannot be hooked"
odd because it's not an abstract. are there more findAndHookMethod calls before this one? are you sure they work?
because the sendBroadcast hook might not have been called at all if an exception was thrown beforehand
you can test it by XposedBridge.log() right before it