Hello,
I want to hook a method in com.android.commands.pm.PM but i fail to load this class (i get class not found exception)
I tried both using initZygote approach and handleLoadPackage approach, both with the same result..
what am i doing wrong?
Thanks!
Maybe @GermainZ can help?
Can you post the relevant Xposed code and exact error, please?
Hi,
Thanks.
Yes, here are my both tries...
Code:
public class XPm implements IXposedHookZygoteInit, IXposedHookLoadPackage {
[user=439709]@override[/user]
public void initZygote(StartupParam startupParam) throws Throwable {
String methodName = "installFailureToString";
XC_MethodHook hookMethod = new XC_MethodHook() {
[user=439709]@override[/user]
protected void beforeHookedMethod(final MethodHookParam param)
throws Throwable {
int result = (Integer) param.args[0];
switch (result) {
case 1:
param.setResult("BLA");
break;
case 2:
param.setResult("BLA BLA");
break;
}
}
};
final Class<?> clsPMS = XposedHelpers.findClass(
"com.android.commands.pm.Pm$1", XPm.class.getClassLoader());
XposedHelpers.findAndHookMethod(clsPMS, methodName, int.class,
hookMethod);
}
[user=439709]@override[/user]
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
String methodName = "installFailureToString";
if (!lpparam.packageName.equals("com.android.commands.pm"))
return;
Log.d(TAG, "com.android.commands.pm is loaded...");
XC_MethodHook hookMethod = new XC_MethodHook() {
[user=439709]@override[/user]
protected void beforeHookedMethod(final MethodHookParam param)
throws Throwable {
int result = (Integer) param.args[0];
switch (result) {
case 1:
param.setResult("BLA");
break;
case 2:
param.setResult("BLA BLA");
break;
}
}
};
final Class<?> clsPMS = XposedHelpers.findClass(
"com.android.commands.pm.Pm", XPm.class.getClassLoader());
XposedHelpers.findAndHookMethod(clsPMS, methodName, int.class,
hookMethod);
}
}
Well, there is no android.commands.pm. Not sure what you're trying to hook, but you should get the correct class name first.
PS. Please wrap your code in [CODE][/CODE] tags next time.
GermainZ said:
Well, there is no android.commands.pm. Not sure what you're trying to hook, but you should get the correct class name first.
PS. Please wrap your code in [CODE][/CODE] tags next time.
Click to expand...
Click to collapse
Hi,
sure, Sorry.
one of the things android.commands.pm.Pm is doing is to print the ADB installation message like "Failure [INVALIED_APK]"
my goal is to print my own message, so it's either by hooking the method i tried or by hooking PackageManager.class.getFields() and add my own fields.
this is the code from Pm.Java
Code:
/**
* Converts a failure code into a string by using reflection to find a matching constant
* in PackageManager.
*/
private String installFailureToString(int result) {
Field[] fields = PackageManager.class.getFields();
for (Field f: fields) {
if (f.getType() == int.class) {
int modifiers = f.getModifiers();
// only look at public final static fields.
if (((modifiers & Modifier.FINAL) != 0) &&
((modifiers & Modifier.PUBLIC) != 0) &&
((modifiers & Modifier.STATIC) != 0)) {
String fieldName = f.getName();
if (fieldName.startsWith("INSTALL_FAILED_") ||
fieldName.startsWith("INSTALL_PARSE_FAILED_")) {
// get the int value and compare it to result.
try {
if (result == f.getInt(null)) {
return fieldName;
}
} catch (IllegalAccessException e) {
// this shouldn't happen since we only look for public static fields.
}
}
}
}
}
// couldn't find a matching constant? return the value
return Integer.toString(result);
}
If it's not possible to hook this method, i understand i should add my own fields to packageManager
Thanks!
So we're talking about this? You haven't pasted the exact error but I'm guessing it's failing because you're using the wrong classloader. In initZygote, you shouldn't normally pass a classloader — just pass "null". In handleLoadPackage, use the hooked process' classloader (lpparam.classLoader).
EDIT: You can change/get a method's return value using param.setResult/param.getResult. Check the wiki for some more info.
GermainZ said:
So we're talking about this? You haven't pasted the exact error but I'm guessing it's failing because you're using the wrong classloader. In initZygote, you shouldn't normally pass a classloader — just pass "null". In handleLoadPackage, use the hooked process' classloader (lpparam.classLoader).
EDIT: You can change/get a method's return value using param.setResult/param.getResult. Check the wiki for some more info.
Click to expand...
Click to collapse
Hi,
First of all thanks a lot!
this is the exception I'm getting when trying to initZygote and pass null as classloader:
Code:
de.robv.android.xposed.XposedHelpers$ClassNotFoundError: java.lang.ClassNotFoundException: com.android.commands.pm.Pm
I/Xposed ( 8491): at de.robv.android.xposed.XposedHelpers.findClass(XposedHelpers.java:52)
I/Xposed ( 8491): at com.myapp.Hooks.XPm.initZygote(XPm.java:29)
I/Xposed ( 8491): at de.robv.android.xposed.XposedBridge.loadModule(XposedBridge.java:437)
I/Xposed ( 8491): at de.robv.android.xposed.XposedBridge.loadModules(XposedBridge.java:386)
I/Xposed ( 8491): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:120)
I/Xposed ( 8491): at dalvik.system.NativeStart.main(Native Method)
I/Xposed ( 8491): Caused by: java.lang.ClassNotFoundException: com.android.commands.pm.Pm
I/Xposed ( 8491): at java.lang.Class.classForName(Native Method)
I/Xposed ( 8491): at java.lang.Class.forName(Class.java:204)
I/Xposed ( 8491): at external.org.apache.commons.lang3.ClassUtils.getClass(ClassUtils.java:823)
I/Xposed ( 8491): at de.robv.android.xposed.XposedHelpers.findClass(XposedHelpers.java:50)
I/Xposed ( 8491): ... 5 more
I/Xposed ( 8491): Caused by: java.lang.NoClassDefFoundError: com/android/commands/pm/Pm
I/Xposed ( 8491): ... 9 more
I/Xposed ( 8491): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.android.commands.pm.Pm" on path: DexPathList[[zip file "/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar"],nativeLibraryDirectories=[/system/lib]]
BTW, i also tried this approach:
Code:
final Class<?> clsPm = XposedHelpers.findClass("android.content.pm.PackageManager", XPm.class.getClassLoader());
XposedHelpers.setAdditionalStaticField(clsPm, "MY_MESSAGE", 1000);
But it doesn't seem to work either...
As I said, you're using the wrong class loader.
Yes, i understand that, but which class loader should I use?
actually, which approach is better for this case? use initZygote or handleLoadPackage?
this how i did it this time:
Code:
final Class<?> clsPMS = XposedHelpers.findClass("com.android.commands.pm.Pm", null);
XposedHelpers.findAndHookMethod(clsPMS, methodName,int.class, hookMethod);
I'd use initZygote since it's more readable/shorter.
As for which class loader to use, please see post #7.
I tried that (please see post #10), is that what you meant? since i got the same exception as in post #8
shnapsi said:
I tried that (please see post #10), is that what you meant? since i got the same exception as in post #8
Click to expand...
Click to collapse
You didn't indicate anything was wrong in post #10, I assumed that had worked. As usual, you should post the full code (including the initZygote/handleLoadPackage part so we know which you're using) and the exact error.
This is how you'd do it in initZygote:
Java:
public void initZygote(StartupParam startupParam) throws Throwable {
findAndHookMethod("full.class.Name", null, "methodName",
SomeArgument.class, new XC_MethodHook() {
[PLAIN]@Override[/PLAIN]
protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
// Do something.
}
}
);
}
And in handleLoadPackage:
Java:
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("some.package.name"))
return;
findAndHookMethod("full.class.Name", lpparam.classLoader, "methodName",
SomeArgument.class, new XC_MethodHook() {
[PLAIN]@Override[/PLAIN]
protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
// Do something.
}
}
);
}
GermainZ said:
You didn't indicate anything was wrong in post #10, I assumed that had worked. As usual, you should post the full code (including the initZygote/handleLoadPackage part so we know which you're using) and the exact error.
This is how you'd do it in initZygote:
Java:
public void initZygote(StartupParam startupParam) throws Throwable {
findAndHookMethod("full.class.Name", null, "methodName",
SomeArgument.class, new XC_MethodHook() {
[PLAIN]@Override[/PLAIN]
protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
// Do something.
}
}
);
}
And in handleLoadPackage:
Java:
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("some.package.name"))
return;
findAndHookMethod("full.class.Name", lpparam.classLoader, "methodName",
SomeArgument.class, new XC_MethodHook() {
[PLAIN]@Override[/PLAIN]
protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
// Do something.
}
}
);
}
Click to expand...
Click to collapse
Hi,
Strange since i do see in #10 an example (not full code...) of how i tried to do it.
anyway, I don't think that this is my problem. here is my code:
Code:
public class XPm implements IXposedHookZygoteInit {
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
String methodName = "installFailureToString";
XC_MethodHook hookMethod = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(final MethodHookParam param) throws Throwable {
int result = (Integer) param.args[0];
switch(result) {
case 1:
param.setResult("BLA");
break;
case 2:
param.setResult("BLA BLA");
break;
}
}
};
final Class<?> clsPMS = XposedHelpers.findClass("com.android.commands.pm.Pm", null);
XposedHelpers.findAndHookMethod(clsPMS, methodName,int.class, hookMethod);
}
}
shnapsi said:
Hi,
Strange since i do see in #10 an example (not full code...) of how i tried to do it.
Click to expand...
Click to collapse
Not the initZygote/handleLoadPackage part, though, so I couldn't know which you're using.
shnapsi said:
anyway, I dont think that this is my problem. here is my code:
Click to expand...
Click to collapse
That looks correct to me. What's the error you're getting?
GermainZ said:
Not the initZygote/handleLoadPackage part, though, so I couldn't know which you're using.
That looks correct to me. What's the error you're getting?
Click to expand...
Click to collapse
The same exception as i posted in #8
I think this might be your problem (see post #2): http://forum.xda-developers.com/xposed/xposed-api-changelog-developer-news-t2714067
GermainZ said:
I think this might be your problem (see post #2): http://forum.xda-developers.com/xposed/xposed-api-changelog-developer-news-t2714067
Click to expand...
Click to collapse
So, I'm not sure I understand, can i hook it or not?
I didn't find IXposedHookCmdInit under XposedHelpers...
Thanks!
shnapsi said:
So, Im not sure I understand, can i hook it or not?
I didnt find IXposedHookCmdInit under XposedHelpers...
Thanks!
Click to expand...
Click to collapse
Also check post #4 in the same thread.
Basically, you could do it, but you probably don't want to since it's deprecated and disabled by default. I guess you'll want to look into hooking PackageManager instead.
GermainZ said:
Also check post #4 in the same thread.
Basically, you could do it, but you probably don't want to since it's deprecated and disabled by default. I guess you'll want to look into hooking PackageManager instead.
Click to expand...
Click to collapse
I agree, so if this the method I wanted to hook (under PM):
Code:
private String installFailureToString(int result) {
Field[] fields = PackageManager.class.getFields();
for (Field f: fields) {
if (f.getType() == int.class) {
int modifiers = f.getModifiers();
// only look at public final static fields.
if (((modifiers & Modifier.FINAL) != 0) &&
((modifiers & Modifier.PUBLIC) != 0) &&
((modifiers & Modifier.STATIC) != 0)) {
String fieldName = f.getName();
if (fieldName.startsWith("INSTALL_FAILED_") ||
fieldName.startsWith("INSTALL_PARSE_FAILED_")) {
// get the int value and compare it to result.
try {
if (result == f.getInt(null)) {
return fieldName;
}
} catch (IllegalAccessException e) {
// this shouldn't happen since we only look for public static fields.
}
}
}
}
}
// couldn't find a matching constant? return the value
return Integer.toString(result);
}
I now need to hook this part:
Code:
Field[] fields = PackageManager.class.getFields();
which as i understand means to add more fields under PackageManager. is this the right way to do it? (since it didn't work for me)
Code:
final Class<?> clsPMS = XposedHelpers.findClass("android.content.pm.PackageManager", XPm.class.getClassLoader());
XposedHelpers.setAdditionalStaticField(clsPMS, "MY_KEY", 1000);
Thanks!
I tried to hook method "java.lang.System.loadLibrary", but it caused the process crashed.
My code is simple:
@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (!loadPackageParam.packageName.equals("com.shinybox.yongchuandixiachengfortx13"))
return;
XposedHelpers.findAndHookMethod("java.lang.System", loadPackageParam.classLoader, "loadLibrary",
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String libName = (String) param.args[0];
XposedBridge.log("XPOSED:" + libName);
XposedBridge.log("XPOSED:" + loadPackageParam.classLoader.toString());
super.beforeHookedMethod(param);
}
});
}
Click to expand...
Click to collapse
And I could got some output:
I/Xposed ( 1709): XPOSED:crypto
I/Xposed ( 1709): XPOSED:dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.shinybox.yongchuandixiachengfortx13-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.shinybox.yongchuandixiachengfortx13-1, /vendor/lib, /system/lib]]]
I/Xposed ( 1709): XPOSED:ssl
I/Xposed ( 1709): XPOSED:dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.shinybox.yongchuandixiachengfortx13-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.shinybox.yongchuandixiachengfortx13-1, /vendor/lib, /system/lib]]]
I/Xposed ( 1709): XPOSEDpenal
I/Xposed ( 1709): XPOSED:dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.shinybox.yongchuandixiachengfortx13-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.shinybox.yongchuandixiachengfortx13-1, /vendor/lib, /system/lib]]]
Click to expand...
Click to collapse
But the app crashed and here is the error info:
E/AndroidRuntime( 1709): java.lang.UnsatisfiedLinkError: Couldn't load openal from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]]: findLibrary returned null
E/AndroidRuntime( 1709): at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
E/AndroidRuntime( 1709): at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
E/AndroidRuntime( 1709): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
Click to expand...
Click to collapse
The reason is that the app tried to load the library "openal" from xposed installer's class loader rather than its own's. How this happened?
Hello everybody, I'm having a problem developing an application (a launcher) with android studio.
Log:
01-31 15:26:27.744 22983-22983/joe2k01.launcher E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at joe2k01.launcher.DrawerLongClickListener.onItemLongClick(DrawerLongClickListener.java:36)
at android.widget.AbsListView.performLongPress(AbsListView.java:2878)
at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:2828)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5336)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(Native Method)
01-31 15:26:27.986 22983-22989/joe2k01.launcher D/jdwp: processIncoming
01-31 15:26:27.986 22983-22989/joe2k01.launcher D/jdwp: handlePacket : cmd=0x1, cmdSet=0xC7, len=0x14, id=0x40002CA3, flags=0x0, dataLen=0x9
01-31 15:26:27.986 22983-22989/joe2k01.launcher D/jdwp: sendBufferedRequest : len=0x34
Click to expand...
Click to collapse
Code :
package joe2k01.launcher;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SlidingDrawer;
import android.widget.TextView;
public class DrawerLongClickListener implements AdapterView.OnItemLongClickListener
{
SlidingDrawer drawerForAdapteer;
RelativeLayout homeViewForAdapter;
Context mContext;
public DrawerLongClickListener(Context ctxt, SlidingDrawer slidingDrawer, RelativeLayout homeView)
{
mContext = ctxt;
drawerForAdapteer = slidingDrawer;
homeViewForAdapter = homeView;
}
@override
public boolean onItemLongClick(AdapterView arg0, View item, int arg2, long arg3)
{
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(item.getWidth(), item.getHeight());
lp.leftMargin = (int) item.getX();
lp.topMargin = (int) item.getY();
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout ll = (LinearLayout) li.inflate(R.layout.drawer_layout, null);
((ImageView)ll.findViewById(R.id.icon_image)).setImageDrawable(((ImageView) item.findViewById(R.id.icon_image)).getDrawable());
((TextView)ll.findViewById(R.id.icon_text)).setText(((TextView) item.findViewById(R.id.icon_text)).getText());
homeViewForAdapter.addView(ll, lp);
drawerForAdapteer.animateClose();
return false;
}
}
Click to expand...
Click to collapse
I'm tryng the app on my phone that runs android 4.2.1.
Can anyone help me? :silly:
Anyone can help me?
NullPointerException indicates that one of objects that you're using has null value. You can set breakpoint at the line on which this exceptions happens and inspect values of your objects. To do that, you should run application in Debug mode (a button next to Run).
Ok man, I' ll try later
Thank you, I fixed it. :good: :highfive:
Correct. A object has not yet create but you already call some method of it, system return null pointer
I've already solved the problem
hi i am new to xposed framework and java as well. :laugh:
my objective:
1. hook a class method - DONE
2. modify its first param using beforehooked - DONE
3. log the output and call the same method again in afterhooked. NEED HELP
i am tried like this
PHP:
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("result " + param.setResult);
param.setResult(null);
XposedBridge.log("calling method ");
XposedHelpers.callMethod(param.thisObject, "BodyDataByStr",param.args[0],param.args[1],param.args[2],param.args[3]);
}
but this is throwing null pointer exception in logs.
PHP:
java.lang.NullPointerException
at de.robv.android.xposed.XposedHelpers.callMethod(XposedHelpers.java:947)
at just.trust.me.Main$1.afterHookedMethod(Main.java:70)
at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:645)
at com.nob.mypp.h.a.BodyDataByStr(Native Method)
at com.nob.myapp.h.a.getBody(Unknown Source)
at com.nob.myapp.h.a.<init>(Unknown Source)
at com.nob.myapp.k.bk.<init>(Unknown Source)
at com.nob.myapp.k.bk.a(Unknown Source)
at com.mob.mypp.n.b$1.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
please help me.
hotwap said:
hi i am new to xposed framework and java as well. :laugh:
my objective:
1. hook a class method - DONE
2. modify its first param using beforehooked - DONE
3. log the output and call the same method again in afterhooked. NEED HELP
i am tried like this
PHP:
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("result " + param.setResult);
param.setResult(null);
XposedBridge.log("calling method ");
XposedHelpers.callMethod(param.thisObject, "BodyDataByStr",param.args[0],param.args[1],param.args[2],param.args[3]);
}
but this is throwing null pointer exception in logs.
PHP:
java.lang.NullPointerException
at de.robv.android.xposed.XposedHelpers.callMethod(XposedHelpers.java:947)
at just.trust.me.Main$1.afterHookedMethod(Main.java:70)
at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:645)
at com.nob.mypp.h.a.BodyDataByStr(Native Method)
at com.nob.myapp.h.a.getBody(Unknown Source)
at com.nob.myapp.h.a.<init>(Unknown Source)
at com.nob.myapp.k.bk.<init>(Unknown Source)
at com.nob.myapp.k.bk.a(Unknown Source)
at com.mob.mypp.n.b$1.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
please help me.
Click to expand...
Click to collapse
Code:
XposedBridge.log("result " + param.[COLOR="Red"]setResult[/COLOR]);
It should be getResult() right?
Also, you can use XC_MethodReplacement() instead of XC_MethodHook(), something like this:
PHP:
XposedHelpers.findAndHookMethod(........ new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
if (mBlaBlaBla == true) {
mBlaBlaBla = false;
XposedBridge.log("log this");
} else {
mBlaBlaBla = true;
// invoke original method
XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args);
}
return null;
}
});
serajr said:
Code:
XposedBridge.log("result " + param.[COLOR="Red"]setResult[/COLOR]);
It should be getResult() right?
yes you are right. in the source its already getResult(), i made mistake while creating the thread.
Click to expand...
Click to collapse
Also note, calling the same method using callMethod inside its hook will basically run your hook recursively until stack overflows.
If you need to call the original method you should use XposedBridge.invokeOriginalMethod()
This will bypass any hooks attached to this method.
I've been able to hook static methods using Xposed but can not figure out how to hook android classes such as android.bluetooth.BluetoothGatt. My goal is to log bluetooth payloads and then trace the static method within the given app responsible for said payload. I can access the desired payload using the JDB debugger as follows:
Code:
> stop in android.bluetooth.BluetoothGatt.writeCharacteristic
Set breakpoint android.bluetooth.BluetoothGatt.writeCharacteristic
>
Breakpoint hit: "thread=main",
android.bluetooth.BluetoothGatt.writeCharacteristic(), line=926 bci=0
main[1] dump characteristic.mValue
characteristic.mValue = {
116, 101, 115, 116, 49, 51, 51
}
This is my code for attempting to hook the android.bluetooth.BluetoothGatt.writeCharacteristic method:
Code:
package com.example.test.xposed3;
import java.lang.reflect.Method;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import static de.robv.android.xposed.XposedHelpers.findClass;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class Xposed3 implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("com.macdom.ble.blescanner"))
return;
XposedBridge.log("Loaded app: " + lpparam.packageName);
findAndHookMethod("com.macdom.ble.blescanner.a", lpparam.classLoader, "onStart", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Calling com.macdom.ble.blescanner.a onStart()");
}
});
Class<?> BluetoothGatt = findClass("android.bluetooth.BluetoothGatt", lpparam.classLoader);
Method writeCharacteristic = XposedHelpers.findMethodBestMatch(BluetoothGatt, "writeCharacteristic");
XposedBridge.hookMethod(writeCharacteristic, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Calling android.bluetooth.BluetoothGatt writeCharacteristic()");
}
});
The logs show I'm successfully hooking the static method com.macdom.ble.blescanner.a onStart() but outputs a java.lang.NoSuchMethodError when attempting to hook android.bluetooth.BluetoothGatt writeCharacteristic()
Code:
I/Xposed (11661): Loaded app: com.macdom.ble.blescanner
E/Xposed (11661): java.lang.NoSuchMethodError: android.bluetooth.BluetoothGatt#writeCharacteristic()#bestmatch
E/Xposed (11661): at de.robv.android.xposed.XposedHelpers.findMethodBestMatch(XposedHelpers.java:440)
E/Xposed (11661): at com.example.test.xposed3.Xposed3.handleLoadPackage(Xposed3.java:34)
E/Xposed (11661): at de.robv.android.xposed.IXposedHookLoadPackage$Wrapper.handleLoadPackage(IXposedHookLoadPackage.java:34)
E/Xposed (11661): at de.robv.android.xposed.callbacks.XC_LoadPackage.call(XC_LoadPackage.java:61)
E/Xposed (11661): at de.robv.android.xposed.callbacks.XCallback.callAll(XCallback.java:106)
E/Xposed (11661): at de.robv.android.xposed.XposedInit$2.beforeHookedMethod(XposedInit.java:116)
E/Xposed (11661): at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:314)
E/Xposed (11661): at android.app.ActivityThread.handleBindApplication(<Xposed>)
E/Xposed (11661): at android.app.ActivityThread.access$1500(ActivityThread.java:151)
E/Xposed (11661): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
E/Xposed (11661): at android.os.Handler.dispatchMessage(Handler.java:102)
E/Xposed (11661): at android.os.Looper.loop(Looper.java:135)
E/Xposed (11661): at android.app.ActivityThread.main(ActivityThread.java:5254)
E/Xposed (11661): at java.lang.reflect.Method.invoke(Native Method)
E/Xposed (11661): at java.lang.reflect.Method.invoke(Method.java:372)
E/Xposed (11661): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
E/Xposed (11661): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
E/Xposed (11661): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)
I/Xposed (11661): Calling com.macdom.ble.blescanner.a onStart()
The module should be usable for any given app that uses bluetooth BLE. I'm not sure if this is the best approach or if there is a way to dynamically discover the the app's instance of BluetoothGatt and hook it.
jostomp said:
I've been able to hook static methods using Xposed but can not figure out how to hook android classes such as android.bluetooth.BluetoothGatt. My goal is to log bluetooth payloads and then trace the static method within the given app responsible for said payload. I can access the desired payload using the JDB debugger as follows:
Code:
> stop in android.bluetooth.BluetoothGatt.writeCharacteristic
Set breakpoint android.bluetooth.BluetoothGatt.writeCharacteristic
>
Breakpoint hit: "thread=main",
android.bluetooth.BluetoothGatt.writeCharacteristic(), line=926 bci=0
main[1] dump characteristic.mValue
characteristic.mValue = {
116, 101, 115, 116, 49, 51, 51
}
This is my code for attempting to hook the android.bluetooth.BluetoothGatt.writeCharacteristic method:
Code:
package com.example.test.xposed3;
import java.lang.reflect.Method;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import static de.robv.android.xposed.XposedHelpers.findClass;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class Xposed3 implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("com.macdom.ble.blescanner"))
return;
XposedBridge.log("Loaded app: " + lpparam.packageName);
findAndHookMethod("com.macdom.ble.blescanner.a", lpparam.classLoader, "onStart", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Calling com.macdom.ble.blescanner.a onStart()");
}
});
Class<?> BluetoothGatt = findClass("android.bluetooth.BluetoothGatt", lpparam.classLoader);
Method writeCharacteristic = XposedHelpers.findMethodBestMatch(BluetoothGatt, "writeCharacteristic");
XposedBridge.hookMethod(writeCharacteristic, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Calling android.bluetooth.BluetoothGatt writeCharacteristic()");
}
});
The logs show I'm successfully hooking the static method com.macdom.ble.blescanner.a onStart() but outputs a java.lang.NoSuchMethodError when attempting to hook android.bluetooth.BluetoothGatt writeCharacteristic()
Code:
I/Xposed (11661): Loaded app: com.macdom.ble.blescanner
E/Xposed (11661): java.lang.NoSuchMethodError: android.bluetooth.BluetoothGatt#writeCharacteristic()#bestmatch
E/Xposed (11661): at de.robv.android.xposed.XposedHelpers.findMethodBestMatch(XposedHelpers.java:440)
E/Xposed (11661): at com.example.test.xposed3.Xposed3.handleLoadPackage(Xposed3.java:34)
E/Xposed (11661): at de.robv.android.xposed.IXposedHookLoadPackage$Wrapper.handleLoadPackage(IXposedHookLoadPackage.java:34)
E/Xposed (11661): at de.robv.android.xposed.callbacks.XC_LoadPackage.call(XC_LoadPackage.java:61)
E/Xposed (11661): at de.robv.android.xposed.callbacks.XCallback.callAll(XCallback.java:106)
E/Xposed (11661): at de.robv.android.xposed.XposedInit$2.beforeHookedMethod(XposedInit.java:116)
E/Xposed (11661): at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:314)
E/Xposed (11661): at android.app.ActivityThread.handleBindApplication(<Xposed>)
E/Xposed (11661): at android.app.ActivityThread.access$1500(ActivityThread.java:151)
E/Xposed (11661): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
E/Xposed (11661): at android.os.Handler.dispatchMessage(Handler.java:102)
E/Xposed (11661): at android.os.Looper.loop(Looper.java:135)
E/Xposed (11661): at android.app.ActivityThread.main(ActivityThread.java:5254)
E/Xposed (11661): at java.lang.reflect.Method.invoke(Native Method)
E/Xposed (11661): at java.lang.reflect.Method.invoke(Method.java:372)
E/Xposed (11661): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
E/Xposed (11661): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
E/Xposed (11661): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)
I/Xposed (11661): Calling com.macdom.ble.blescanner.a onStart()
The module should be usable for any given app that uses bluetooth BLE. I'm not sure if this is the best approach or if there is a way to dynamically discover the the app's instance of BluetoothGatt and hook it.
Click to expand...
Click to collapse
If the method have some args, Xposed won't find it. Can you share the source? And why you didn't use findandhookmethod?
Massi-X said:
If the method have some args, Xposed won't find it. Can you share the source? And why you didn't use findandhookmethod?
Click to expand...
Click to collapse
Thanks for the reply. This method does not take any arguments - https:[//]developer.android.com/reference/android/bluetooth/BluetoothGatt.html#writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic)
Using the findandhookmethod returns a similar error:
Code:
java.lang.NoSuchMethodError: android.bluetooth.BluetoothGatt#writeCharacteristic()#exact
The application I'm testing on is called BLE Scanner - I do not have the source for this.
jostomp said:
Thanks for the reply. This method does not take any arguments - https:[//]developer.android.com/reference/android/bluetooth/BluetoothGatt.html#writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic)
Using the findandhookmethod returns a similar error:
Code:
java.lang.NoSuchMethodError: android.bluetooth.BluetoothGatt#writeCharacteristic()#exact
The application I'm testing on is called BLE Scanner - I do not have the source for this.
Click to expand...
Click to collapse
Uhm from the page you share it says the method wants an argument of BluetoothGattCharacteristic type .
So, this is the problem!
Massi-X said:
Uhm from the page you share it says the method wants an argument of BluetoothGattCharacteristic type .
So, this is the problem!
Click to expand...
Click to collapse
Ahh yes you are completely right! Thanks
Here's the working code:
Code:
package com.example.djason.xposed3;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
import android.bluetooth.BluetoothGattCharacteristic;
public class Xposed3 implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("com.macdom.ble.blescanner"))
return;
XposedBridge.log("Loaded app: " + lpparam.packageName);
findAndHookMethod("android.bluetooth.BluetoothGatt", lpparam.classLoader, "writeCharacteristic", BluetoothGattCharacteristic.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Calling android.bluetooth.BluetoothGatt writeCharacteristic()");
}
});
}
}
Glad to help!