[Xposed General] GermainZ:
OK, here's a general post that should show you how to use various methods, along with some common pitfalls.

I'm not going to write complete code, so use this as an example but don't copy/paste.

If you're using an app to view this post, I'd recommend you open it in a web browser so you get pretty syntax highlighting and formatting.

Let's assume we have two classes, Class1 and Class2. Class1:

class Class1 {
Object someVariable;
final static int SOME_FINAL_STATIC_INT = 30;
Context context;
Class2 class2Instance;

method void Class1(Context context) {
this.context = context;
class2Instance = Class2.getInstance(context);
}

method void someMethod(String stringArg, int intArg) {
for (int i = intArg; i < SOME_FINAL_STATIC_INT ; i++) {
class2Instance.doSomething(stringArg);
}
}
}

Class2:

class Class2 {
Context context;
Class2 instance;

method void Class2(Context context) {
this.context = context;
instance = this;
}

static method Class2 getInstance(Context context) {
if (instance == null)
instance = new Class2(context);
return instance;
}

method void doSomething(String stringArg) {
// do something
}
}

We want to change someMethod's behavior so it always goes from 0 to 10 instead of intArg to SOME_FINAL_STATIC_INT .

We know that we can modify the arguments of a method directly (using param.args[index]) and a static int field using setStaticInt, so it should be easy to do… right? Nope.

Why not? Because SOME_FINAL_STATIC_INT , being static and final, will be replaced by the compiler. In other words, this:

for (int i = intArg; i < SOME_FINAL_STATIC_INT ; i++) {
class2Instance.doSomething(stringArg);
}

Will actually become this when compiled:

for (int i = intArg; i < 30; i++) {
class2Instance.doSomething(stringArg);
}

So, how do you replace the 30 now? You don't. Depending on the situation, you'll have to use alternative ways to accomplish what you want. The most general one is to replace the method:

findAndHookMethod("my.package.Class1", lpparam.classLoader, "someMethod", String.class, int.class, new XC_MethodReplacement() {
[PLAIN]@Override[/PLAIN]
Object replaceHookedMethod(param) {
// we want to go from 0 to 10 only
for (int i = 0; i < 10; i++) {
// get class2Instance
Object class2Instance = getObjectField(param.thisObject, "class2Instance");
// call doSomething
callMethod(class2Instance, doSomething, param.args[0]);
}
}
});

And we're done. We wanted to modify the for loop, and we did. We then wanted to call a method, but since that method belongs to another class, we needed that class' instance first.

Assume we don't have an instance of the class, what do we do then? Well, you could create an instance yourself… but keep in mind this may not lead to the result you want if the application expects (and uses) only one instance.

For example, let's assume there was no class2Instance in Class1. We could create one like this:

findAndHookMethod("my.package.Class1", lpparam.classLoader, "someMethod", String.class, int.class, new XC_MethodReplacement() {
[PLAIN]@Override[/PLAIN]
Object replaceHookedMethod(param) {
// we want to go from 0 to 10 only
for (int i = 0; i < 10; i++) {
// find Class2
Class Class2 = findClass("my.package.Class2", lpparam.classLoader);
// we need to get a context to create an instance of Class2, since its constructor needs a context
Context context = (Context) getObjectField(param.thisObject, "context");
// create class2Instance
Object class2Instance = newInstance(Class2, context);
// we can also call Class2.getInstance, which would be a better choice, although such a method is not always available.
// Object class2Instance = callStaticMethod(Class2, "getInstance", context);
// call doSomething
callMethod(class2Instance, doSomething, param.args[0]);
}
}
});

To recap: we got the context using getObjectField, just as before.

We then got the Class for Class2 and used it to create a new instance. (We also could've called the static method, which would have given us the existing instance, if any; such a method isn't always available, though).

The rest was similar to the previous example.

I hope this explains how to use some of the methods Xposed offers clearly. Good luck. :)