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
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.
I'm trying to override onCreate and I'm having problems because I need to call super.onCreate(). The best I could come up with is:
XposedHelpers.findMethodBestMatch(param.thisObject.getClass().getSuperclass(), "onCreate", Bundle.class).invoke(param.thisObject, param.args[0]);
Is there some better way to do it?
EDIT: And it doesn't seem to work...
See these posts:
http://forum.xda-developers.com/showpost.php?p=42947833&postcount=1846
http://forum.xda-developers.com/showpost.php?p=51645044&postcount=10271
Basically, there's no easy way to just call "super.method()" - you'll need to find the class (or instance of the class if the method isn't static) and then call the method normally.
I'm not entirely sure why what you've tried doesn't work, but checking the log may help.
It's quite a simple one I hope. Also, apologies for adding noise to the forum, but I couldn't find any detailed documentation or many tutorials.
I'm making use of findAndHookMethod for a little test project of mine. The problem is, the method which I am hooking has custom classes in its parameters.
Obviously I don't have access to these classes in terms of having the source code imported, so my first thought was just to list the paramaters as Object.class, but this didn't work.
What (if any) are the solutions? Thanks!
P.S.
In case I worded it badly. Say I have method to be hooked...
public void methodThatDoesSomething(ThisCustomClass nameOfParameter)
How do I use findAndHookMethod when listing parameters, as ThisCustomClass.class is not within the scope of my project
Use a string with the class' full name, e.g. "com.hooked.package.ThisCustomClass".
I'm in a situation such that I need to change a method so that it always returns true. This should be too hard, I'm fairly certain I know the class, the packages containing the class but the contents of only the class itself are obfuscated.
I know there is a method "findMethodBestMatch" that Xposed provides, but the method I'm looking for could really be called any number of things.
Is there anything that when given the correct LoadPackageParam, or when I know the exact class (correct package names containing it too) that I could see the real package structure with non-obfuscated names, or I could see all the real method names?
Or am I over thinking this? In other words, is obfuscation purely just to try to make things harder to understand but I could still hook something like "a.b.c.e.z.blah"?
I don't have a great understand of Xposed, so if anything needs to be explained more clearly I'd be happy to reword
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.