Can't save static variable to access it later in xposed - Xposed General

seems like I placed that in a wrong section.Please ,move it to dev section
___
I'm hooking systemui to get data from updateAppMessage method. And I'm hooking method updateMessage method in package launcher. SystemUI's method invokes first (I checked).
All I need is to remember data from systemui hook to use it later in launcher hook. As it turns out it's a big problem to me. I wan't to compare package name from these two methods. But when it goes to updateMessage in launcher I see in log file that all variables from systemui hook reset to their initial values.
May be I miss just one crucial thing but I spend already the whole day so I'm begging for help.
I'm using xposed v87 for miui (android 6) by SolarWarez (also now I have flashed v86 and nothing changed)
here's the log
Code:
12-01 00:19:53.464 I/Xposed ( 5682): OMG [B]pkg= com.vkcoffee.androi[/B]d number=2
12-01 00:19:53.468 I/Xposed ( 5968): Launcher [B]pkg=com.vkcoffee.android[/B]
12-01 00:19:53.468 I/Xposed ( 5968): Launcher other= -1 [B]-string[/B]
12-01 00:20:58.544 I/Xposed ( 5682): OMG pkg= android number=0
12-01 00:20:58.555 I/Xposed ( 5968): Launcher pkg=android
12-01 00:20:58.555 I/Xposed ( 5968): Launcher other= -1 -string
12-01 00:20:58.816 I/Xposed ( 5682): OMG pkg= com.miui.securitycenter number=0
12-01 00:20:58.820 I/Xposed ( 5968): Launcher pkg=com.miui.securitycenter
12-01 00:20:58.820 I/Xposed ( 5968): Launcher other= -1 -string
12-01 00:22:24.126 I/Xposed ( 5968): Launcher pkg=de.robv.android.xposed.installer
12-01 00:22:24.126 I/Xposed ( 5968): Launcher other= -1 -string
and here's the code
PHP:
public class XposedMod implements IXposedHookInitPackageResources, IXposedHookZygoteInit, IXposedHookLoadPackage {
public static String MODULE_PATH = null;
public static int number=-1;
public static String notif_pkg="-string";
public static String pkg="-string";
public static ComponentName comp;
@Override
public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) throws Throwable {
MODULE_PATH = startupParam.modulePath;
XModuleResources modRes = XModuleResources.createInstance(MODULE_PATH, null);
}
@Override
public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable {
}
@Override
public void handleLoadPackage(LoadPackageParam lpparam)
throws Throwable {
if (lpparam.packageName.equals("com.miui.home") ) {
findAndHookMethod("com.miui.home.launcher.ApplicationsMessage",lpparam.classLoader,"updateMessage",ComponentName.class, int.class, String.class,String.class, byte[].class, new XC_MethodHook()
{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
comp = (ComponentName) param.args[0];
pkg=comp.getPackageName();
XposedBridge.log("Launcher pkg="+pkg);
XposedBridge.log("Launcher other="+ " "+number+" "+notif_pkg);
}
});
}
if (lpparam.packageName.equals("com.android.systemui")) {
findAndHookMethod("com.android.systemui.statusbar.phone.PhoneStatusBar",lpparam.classLoader,"updateAppMessage","com.android.systemui.statusbar.ExpandedNotification", new XC_MethodHook()
{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
StatusBarNotification sbn =(StatusBarNotification) param.args[0];
number=sbn.getNotification().number;
notif_pkg=sbn.getPackageName();
XposedBridge.log("OMG pkg= "+notif_pkg+" number="+number);
}
});
}
}
}
Also I tried to store data in text File but with no luck as well. My own application Activity returns null context everytime I try to get it from XposedMod class. And I tried to use SystemUI context to store file in /data/data/com.android.systemui/files/ folder (with file.setReadable(true, false); on file creation) but later when I'm trying to read the file xposed log throws exception about "FileNotFoundException.... EACCES (Permition denied)
PHP:
public static String getStringFromFile(String fileName) throws IOException {
File file = new File("/data/data/com.android.systemui/files/", fileName);
int length = (int) file.length();
byte[] bytes = new byte[length];
FileInputStream in = new FileInputStream(file);
try {
in.read(bytes);
} finally {
in.close();
}
String contents = new String(bytes);
return contents;
}
I'm just dumb. If I create file in internal storage there's no access error. but still I want to deal only with variables inside my app..

Note, that you have hooks in 2 different processes. Those are "isolated" so when you set value of variable in one process (systemui) you won't be able to see that value in another process (launcher). Those variables are completely different and independent.
You will have to use some kind of shared storage or some kind of IPC communication method.
The easiest that comes to my mind is e.g. to use Settings.Global storage to save variable in one process and then read that variable in another process.
All you need to access Setting.Global is a valid context which gives you content resolver you need for Setting.Global.putString/getString methods.

C3C076 said:
Note, that you have hooks in 2 different processes. Those are "isolated" so when you set value of variable in one process (systemui) you won't be able to see that value in another process (launcher). Those variables are completely different and independent.
Click to expand...
Click to collapse
thanks for clarifying these things to me

Related

Replace method. Need help. PLease

Hi everyone. I ask for help. I literally beg for it..
com.android.dialer.dialpad.LatinSmartDialMap
You can see it here http://grepcode.com/file/repository...id/dialer/dialpad/LatinSmartDialMap.java?av=f
I only want to replace method . Any of them.
For example I want this method returns FALSE every time it's called.
Code:
@Override
public boolean isValidDialpadAlphabeticChar(char ch) {
return (ch >= 'a' && ch <= 'z');
}
Here is my code
Code:
public class Fm implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam loadpkg) throws Throwable {
if (loadpkg.packageName.equals("com.android.dialer")) {
ClassLoader classLoader = loadpkg.classLoader;
XC_MethodReplacement methodreplacer = new XC_MethodReplacement() {
protected Object replaceHookedMethod(
XC_MethodHook.MethodHookParam paramAnonymousMethodHookParam)
throws Throwable {
XposedBridge.log("ALLLLL RIGHTTTT . NOW We ARE IN. AND MADE IT FALSe");
return false;
}
};
XposedHelpers.findAndHookMethod("com.android.dialer.dialpad.LatinSmartDialMap", loadpkg.classLoader,
"[COLOR="Red"]isValidDialpadAlphabeticChar[/COLOR]", Character.class, methodreplacer);
}
}
}
But this doesn't work
Here what I see in xposed log file:
java.lang.NoSuchMethodError: com.android.dialer.dialpad.LatinSmartDialMap#isValidDialpadAlphabeticChar(java.lang.Character)#exact
at de.robv.android.xposed.XposedHelpers.findMethodExact(XposedHelpers.java:179)
at de.robv.android.xposed.XposedHelpers.findAndHookMethod(XposedHelpers.java:129)
at de.robv.android.xposed.XposedHelpers.findAndHookMethod(XposedHelpers.java:136)
at com.s0bes.fmspeaker.Fm.handleLoadPackage(Fm.java:30)
at de.robv.android.xposed.IXposedHookLoadPackage
BUUUT. If I will try to replace other method. For example
matchesCombination in com.android.dialer.dialpad.SmartDialNameMatcher (http://grepcode.com/file/repository...dialer/dialpad/SmartDialNameMatcher.java?av=f)
Here the part of code which was changed:
Code:
XposedHelpers.findAndHookMethod("com.android.dialer.dialpad.SmartDialNameMatcher", loadpkg.classLoader,
"matchesCombination", String.class, String.class, ArrayList.class, methodreplacer);
Now everything work...
So, it works with one thing and doesnt work with method I need
If you want to replace a method to return a consatnt, you can use the XC_MethodReplacement.returnConstant(…) shortcut. For example:
Java:
XposedHelpers.findAndHookMethod("com.android.dialer.dialpad.SmartDialNameMatcher", loadpkg.classLoader,
"matchesCombination", String.class, String.class, ArrayList.class, XC_MethodReplacement.returnConstant(false));
As for your problem, you're trying to hook isValidDialpadAlphabeticChar(Character.class), but you should be hooking isValidDialpadAlphabeticChar(char.class). Just replace "Character.class" by "char.class" in your findAndHookMethod call.

[Q] Can't hook com.android.commands.pm.PM

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!

[Q] Please help, my Xposed module doesn't work in CM12

I wrote an Xposed module to modify the visibility of the navigation bar.
Code snippet:
Code:
public class disableHideNavigationBar implements IXposedHookZygoteInit {
public void initZygote(StartupParam startupParam) throws Throwable {
findAndHookMethod("com.android.server.wm.WindowState", null, "getSystemUiVisibility",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
The full code can be found here: https://github.com/aidfarh/DontHideNavbar/blob/master/app/src/main/java/com/aidfarh/DisableHideNavigationBar/disableHideNavigationBar.java
The module works perfectly in Android 4.4. However, it fails in CM12 (Android 5.0). The error log contains this:
Code:
03-21 06:48:46.710 I/Xposed (11748): Loading modules from /data/app/com.aidfarh.DisableHideNavigationBar-1/base.apk
03-21 06:48:46.864 I/Xposed (11748): Loading class com.aidfarh.DisableHideNavigationBar.disableHideNavigationBar
03-21 06:48:46.871 E/Xposed (11748): de.robv.android.xposed.XposedHelpers$ClassNotFoundError: java.lang.ClassNotFoundException: com.android.server.wm.WindowState
The full error log is attached.
The thing is, the class "com.android.server.wm.WindowState" does exists in CM12, as seen here: https://github.com/CyanogenMod/android_frameworks_base/blob/cm-12.0/services/core/java/com/android/server/wm/WindowState.java, but Xposed is reporting ClassNotFound. Can somebody please help?
BTW, my module contains another part that uses handleLoadPackage to hook into "com.android.systemui" and that part works perfectly. Only the part under initZygote doesn't work.
Never mind, I figured out how to make it work. Turns out that instead of initZygote, I had to use handleLoadPackage with package name "android". Good thing is, it works with both android 5.0 and 4.4 .

Internet permission denied within com.android.systemui context

Hello,
I'm fairly new to using Xposed. I've used it a couple of times to solve some Android CTF challenges, where its ability to hook into an app is a real benefit.
But now I'm trying to understand it a little bit better. As a simple toy project, I'm considering using Xposed to implement a sort of periodic update for Xposed modules. It's not exactly the most useful mod, but it helps me get a better understanding of the framework.
Based on the development tutorial, I thought I could just implement a naive cron.d over the updateClock() method and fire off an AsyncTask to handle
communication to an external server (a package repo if you will). So far, my code goes like this:
Code:
package com.example.red;
import android.app.AndroidAppHelper;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;
class UpdateModulesTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... voids) {
XposedBridge.log("Updating modules");
try {
Application app = AndroidAppHelper.currentApplication();
Context ctx = app.getApplicationContext();
int res = ctx.checkCallingOrSelfPermission(android.Manifest.permission.INTERNET);
if (res == PackageManager.PERMISSION_DENIED)
XposedBridge.log("No internet");
else
XposedBridge.log("Internet granted");
URL url = new URL("<MY URL>");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes("key=value");
out.flush();
out.close();
int rcode = conn.getResponseCode();
XposedBridge.log("Return code " + String.valueOf(rcode));
if (rcode == 200) {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
StringBuilder response = new StringBuilder();
while ((line = in.readLine()) != null) {
response.append(line);
}
in.close();
XposedBridge.log(response.toString());
}
} catch (Exception e) {
XposedBridge.log(e.getMessage());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
XposedBridge.log(sw.toString());
}
return null;
}
}
public class Main implements IXposedHookLoadPackage {
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
XposedBridge.log(lpparam.packageName);
if (lpparam.packageName.equals("com.android.systemui")) {
findAndHookMethod("com.android.systemui.statusbar.policy.Clock", lpparam.classLoader, "updateClock", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Calendar now = Calendar.getInstance();
int hour = now.get(Calendar.HOUR_OF_DAY);
XposedBridge.log("Hour is: " + String.valueOf(hour));
if (hour == 11) {
int minute = now.get(Calendar.MINUTE);
XposedBridge.log("Minute is: " + String.valueOf(minute));
if (minute % 2 == 0) { // update modules
new UpdateModulesTask().execute();
}
}
}
});
}
}
}
What Xposed logs, instead, goes like this:
Code:
I/Xposed ( 3574): Hour is: 11
I/Xposed ( 3574): Minute is: 50
I/Xposed ( 3574): Updating modules
I/Xposed ( 3574): Internet granted
I/Xposed ( 3574): Permission denied (missing INTERNET permission?)
I/Xposed ( 3574): java.lang.SecurityException: Permission denied (missing INTERNET permission?)
I/Xposed ( 3574): at java.net.InetAddress.lookupHostByName(InetAddress.java:451)
I/Xposed ( 3574): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
I/Xposed ( 3574): at java.net.InetAddress.getAllByName(InetAddress.java:215)
I/Xposed ( 3574): at com.android.okhttp.HostResolver$1.getAllByName(HostResolver.java:29)
I/Xposed ( 3574): at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:232)
I/Xposed ( 3574): at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:124)
I/Xposed ( 3574): at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:272)
I/Xposed ( 3574): at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
I/Xposed ( 3574): at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:373)
I/Xposed ( 3574): at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:106)
I/Xposed ( 3574): at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:208)
I/Xposed ( 3574): at com.example.red.UpdateModulesTask.doInBackground(Main.java:41)
I/Xposed ( 3574): at com.example.red.UpdateModulesTask.doInBackground(Main.java:26)
I/Xposed ( 3574): at android.os.AsyncTask$2.call(AsyncTask.java:288)
I/Xposed ( 3574): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
I/Xposed ( 3574): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
I/Xposed ( 3574): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
I/Xposed ( 3574): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
I/Xposed ( 3574): at java.lang.Thread.run(Thread.java:818)
I/Xposed ( 3574): Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
I/Xposed ( 3574): at libcore.io.Posix.android_getaddrinfo(Native Method)
I/Xposed ( 3574): at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
I/Xposed ( 3574): at java.net.InetAddress.lookupHostByName(InetAddress.java:438)
I/Xposed ( 3574): ... 18 more
I/Xposed ( 3574): Caused by: android.system.ErrnoException: android_getaddrinfo failed: EACCES (Permission denied)
I/Xposed ( 3574): ... 21 more
So, from what I understand, com.android.systemui should have the "android.permission.INTERNET" permission, which is also what the "Internet granted" message in the logcat output indicates. I also checked for SELinux violations and it doesn't seem to be the case.
What I'd like to understand is why my hook, called from the context of com.android.systemui (which hold the Internet permission), checks to see if it has the Internet permission (and it does) and then receives a permission denied error when actually attempting make the connection, despite the fact that there is no intervention from SELinux. Am I missing something obvious with regards to the way Xposed works?
Don't know on which Android version you test this but by simply looking at SystemUI manifest of Android 6.0.1
you can clearly see there is no INTERNET permission.
Your "if" statement is confusing you. You should rather use:
Code:
if (res == PackageManager.PERMISSION_GRANTED)
XposedBridge.log("Internet granted");
else
XposedBridge.log("No internet");
Thanks for the reply, C3C076!
Sorry for not mentioning the Android version. I'm running Android 5.0.0 build LRX21T on a Nexus 4, if that is of any use.
I've looked through the manifest for 5.0.0 and indeed, there seems to be no reference to the Internet permission. So I've looked around for some means to grant that permission, and came up with:
Code:
if (lpparam.packageName.equals("android")) {
final Class<?> pmServiceClass = XposedHelpers.findClass("com.android.server.pm.PackageManagerService", lpparam.classLoader);
findAndHookMethod(pmServiceClass, "grantPermissionsLPw", "android.content.pm.PackageParser.Package", boolean.class, String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
final String pkgname = (String) XposedHelpers.getObjectField(param.args[0], "packageName");
XposedBridge.log("Called for package: " + pkgname);
if (pkgname.equals("com.android.systemui")) {
Object extras = XposedHelpers.getObjectField(param.args[0], "mExtras");
Object sharedUser = XposedHelpers.getObjectField(extras, "sharedUser");
Set<String> grantedPerms = (Set<String>) XposedHelpers.getObjectField(sharedUser != null ? sharedUser :extras, "grantedPermissions");
Object settings = XposedHelpers.getObjectField(param.thisObject, "mSettings");
Object permissions = XposedHelpers.getObjectField(settings, "mPermissions");
XposedBridge.log(grantedPerms.toString());
if (!grantedPerms.contains("android.permission.INTERNET")) {
final Object pInet = XposedHelpers.callMethod(permissions, "get", "android.permission.INTERNET");
grantedPerms.add("android.permission.INTERNET");
int[] gpGids = (int[]) XposedHelpers.getObjectField(sharedUser != null ? sharedUser : extras, "gids");
int[] bpGids = (int[]) XposedHelpers.getObjectField(pInet, "gids");
XposedBridge.log("Extended GIDs with: " + bpGids.toString());
XposedHelpers.callStaticMethod(param.thisObject.getClass(), "appendInts", gpGids, bpGids);
}
}
}
});
XposedBridge.log("Granted extra permission.");
}
The funny thing is that android.permission.INTERNET did not have to be added. It was already in the list of granted permissions.
Code:
I/Xposed ( 6218): Called for package: com.android.systemui
I/Xposed ( 6218): [android.permission.SYSTEM_ALERT_WINDOW,
android.permission.GET_APP_OPS_STATS,
android.permission.REMOVE_TASKS,
android.permission.STATUS_BAR_SERVICE,
android.permission.CHANGE_WIFI_STATE,
android.permission.GET_ACCOUNTS,
android.permission.CAMERA,
android.permission.ACCESS_ALL_EXTERNAL_STORAGE,
android.permission.MEDIA_CONTENT_CONTROL,
android.permission.WRITE_DREAM_STATE,
android.permission.REMOTE_AUDIO_PLAYBACK,
android.permission.STOP_APP_SWITCHES,
android.permission.MANAGE_ACCOUNTS,
android.permission.BLUETOOTH_ADMIN,
android.permission.ACCESS_NETWORK_STATE,
com.android.alarm.permission.SET_ALARM,
android.permission.MANAGE_MEDIA_PROJECTION,
android.permission.DEVICE_POWER,
android.permission.START_TASKS_FROM_RECENTS,
android.permission.START_ANY_ACTIVITY,
android.permission.READ_PROFILE,
android.permission.WRITE_SECURE_SETTINGS,
android.permission.CHANGE_NETWORK_STATE,
android.permission.BIND_APPWIDGET,
android.permission.GET_DETAILED_TASKS,
android.permission.DUMP,
android.permission.MANAGE_APP_TOKENS,
android.permission.READ_EXTERNAL_STORAGE,
android.permission.SET_SCREEN_COMPATIBILITY,
android.permission.CONTROL_KEYGUARD,
android.permission.EXPAND_STATUS_BAR,
android.permission.DISABLE_KEYGUARD,
android.permission.READ_PHONE_STATE,
android.permission.MANAGE_USB,
android.permission.INTERACT_ACROSS_USERS,
android.permission.INTERNAL_SYSTEM_WINDOW,
android.permission.MODIFY_PHONE_STATE,
android.permission.READ_CONTACTS,
android.permission.ACCESS_KEYGUARD_SECURE_STORAGE,
android.permission.WAKE_LOCK,
android.permission.INTERACT_ACROSS_USERS_FULL,
android.permission.MASTER_CLEAR,
android.permission.READ_FRAME_BUFFER,
android.permission.REAL_GET_TASKS,
android.permission.GET_TOP_ACTIVITY_INFO,
android.permission.SET_ORIENTATION,
android.permission.INJECT_EVENTS,
android.permission.CONFIGURE_WIFI_DISPLAY,
android.permission.READ_DREAM_STATE,
android.permission.VIBRATE,
android.permission.CHANGE_COMPONENT_ENABLED_STATE,
android.permission.INTERNET,
android.permission.REORDER_TASKS,
android.permission.WRITE_SETTINGS,
android.permission.STATUS_BAR,
android.permission.MOUNT_UNMOUNT_FILESYSTEMS,
android.permission.WRITE_EXTERNAL_STORAGE,
android.permission.READ_NETWORK_USAGE_HISTORY,
android.permission.MANAGE_ACTIVITY_STACKS,
android.permission.MANAGE_USERS,
android.permission.CONNECTIVITY_INTERNAL,
android.permission.MANAGE_NETWORK_POLICY,
android.permission.TRUST_LISTENER,
android.permission.BLUETOOTH,
android.permission.RECEIVE_BOOT_COMPLETED,
android.permission.BIND_DEVICE_ADMIN,
android.permission.ACCESS_WIFI_STATE]
I'm not sure what to make of this difference between AOSP and my device. The only modifications I've made are installing TWRP, SuperSU, and Xposed. To my knowledge, none modify permissions by default. But then again, I could be wrong.
I'm curious whether you have any idea about this, C3C076.
Or anyone else for that matter ...
Did you take a look at the permission list before you were testing code for adding permission or after?
Because if you previously added permission during code testing then it will be there cached in the system.

Running a shell command early during Zygote initialization

Hello, I'm using a Nexus 4, running Android 5.0.0 build LRX21T, with Xposed (xposed-v87-sdk21-arm.zip). I'm trying to run a command early during Android startup. My code so far looks like this:
Code:
package com.example.test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.XposedBridge;
class RunCmdTask extends Thread {
private String cmd;
RunCmdTask(String c) {
cmd = c;
}
public void run() {
XposedBridge.log("task start");
Process proc = null;
try {
Runtime rt = Runtime.getRuntime();
proc = rt.exec(cmd);
proc.waitFor();
BufferedReader stdin = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String s;
while ((s = stdin.readLine()) != null)
XposedBridge.log(s);
stdin.close();
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
XposedBridge.log(sw.toString());
} finally {
if (proc != null)
proc.destroy();
}
XposedBridge.log("task end");
}
}
public class Main implements IXposedHookZygoteInit {
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
XposedBridge.log("main start");
try {
RunCmdTask id = new RunCmdTask("id");
id.start();
id.join();
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
XposedBridge.log(sw.toString());
}
XposedBridge.log("main end");
}
}
The "id" gets invoked, since my logcat looks like:
Code:
I/Xposed (25305): main start
I/Xposed (25305): task start
I/Xposed (25305): uid=0(root) gid=0(root) context=u:r:zygote:s0
I/Xposed (25305): task end
I/Xposed (25305): main end
The problem is that the startup process hangs after this point. I just get the bootup animation looping over and over again. I've tried terminating the VM by calling the Runtime.halt() method, but that kills the whole Zygote, thus being equivalent to a soft reboot. I'm curious to see what I'm mistaking/overlooking. From what I understand, since both the thread and the main hook method finish, normal startup should resume.

Categories

Resources