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.
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.
Okey,
Code from GP: http://pastebin.com/raw.php?i=rEH9nq78
I need to hook onTransact method
Code:
XposedHelpers.findAndHookMethod("com.android.vending.details.IDetailsService$Stub",lpparam.classLoader,"onTransact",int.class,Parcel.class,Parcel.class,int.class,testHook);
testHook = just log me if i am in...
But this doesnt work and I think com.android.vending.details.IDetailsService$Stub is probably wrong part.
pyler said:
Okey,
Code from GP: http://pastebin.com/raw.php?i=rEH9nq78
I need to hook onTransact method
Code:
XposedHelpers.findAndHookMethod("com.android.vending.details.IDetailsService$Stub",lpparam.classLoader,"onTransact",int.class,Parcel.class,Parcel.class,int.class,testHook);
testHook = just log me if i am in...
But this doesnt work and I think com.android.vending.details.IDetailsService$Stub is probably wrong part.
Click to expand...
Click to collapse
Mostly the stub is inherited from, so this won't work, because you need to hook into the sub class.
You can hook into android.os.BinderProxy.transact (client) or android.os.Binder.execTransact (service) and check for the interface name, but you'll have still to solve which transaction to catch (transaction = method).
Check this source for more details:
https://github.com/M66B/XPrivacy/blob/master/src/biz/bokhorst/xprivacy/XBinder.java
Note that this is performance wise not the best solution, although the impact is not too big.
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!
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
Hello.
I have a tasker profile that's not quite working as I want it to, trying to get a screenshot method working because the buttons on my phone aren't reliable
(Task) 1: Run shell ~ Command screencap -p /sdcard/screenshots/screengrab-%DATE-%TIME.png
Use root (ticked)
2: Flash "Saved!"
It works, but I have to wait awhile before screenshotting again. If I want to take two screenshots in a row, the first one will save, the other won't. Seems like it's affected by what minute it is.... if it's 5:16 on the first screenshot, and 5:16 on the second, the second won't save. But if it's 5:16 on the first screenshot, and 5:17 on the second, it works. Is there something I need to add after %TIME so I'm not limited, or is this not a fixable issue?
This may not seem like a big deal for many people but sometimes I take screenshots of important emails, payment receipts, etc, sometimes they're too big to fit all on one screen and need 2 or 3 screenshots.
May or may not be relevant, but my phone is on 6.0 and stock ROM.
Bump
Found someone else with the problem I was having, adding %TIMES seems to have solved it.
Cinderbunny said:
Found someone else with the problem I was having, adding %TIMES seems to have solved it.
Click to expand...
Click to collapse
Hi,
Glad that you solved it. Just a friendly tip: to be able to save multiple (999, to be exact) screenshots per second, you could add %TIMEMS instead of %TIMES.
Additionally, if you want the actual, human-readable time in the filename, you could use the following task:
Code --> Java Function
Class Or Object: Date
Function: new {Date} (long)
Param (long): %TIMEMS
Return {Date}: date
Code --> Java Function
Class Or Object: SimpleDateFormat
Function: new {SimpleDateFormat} (String)
Param (String): yyyyMMdd-HHmmssSSS
Return {SimpleDateFormat}: formatter
Code --> Java Function
Class Or Object: formatter
Function: format {String} (Date)
Param (Date): date
Return {String}: %datetime
Code --> Run Shell
Command: screencap -p /sdcard/screenshots/screengrab-%datetime.png
Use Root: ticked
I hope this is of use to you, or anyone!