mirror of
https://github.com/LSPosed/LSPlant.git
synced 2025-05-04 20:42:02 +08:00
More unit tests
This commit is contained in:
parent
bdb668751b
commit
db91f83f3e
@ -3,15 +3,45 @@ package org.lsposed.lsplant;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class UnitTest {
|
||||
|
||||
private final List<Hooker> hookers = new ArrayList<>();
|
||||
|
||||
@Test
|
||||
public void initTest() {
|
||||
public void t00_initTest() {
|
||||
boolean result = LSPTest.initHooker();
|
||||
Assert.assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void t01_hookTest() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
var staticMethod = LSPTest.class.getDeclaredMethod("staticMethod");
|
||||
var staticMethodReplacement = Replacement.class.getDeclaredMethod("staticMethodReplacement");
|
||||
Assert.assertFalse(LSPTest.staticMethod());
|
||||
Hooker hooker1 = Hooker.hook(staticMethod, staticMethodReplacement);
|
||||
hookers.add(hooker1);
|
||||
Assert.assertNotNull(hooker1);
|
||||
Assert.assertTrue(LSPTest.staticMethod());
|
||||
Assert.assertFalse((Boolean) ((Method) hooker1.backup).invoke(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void t02_unhookTest() {
|
||||
for (Hooker hooker : hookers) {
|
||||
Assert.assertTrue(hooker.unhook());
|
||||
}
|
||||
Assert.assertFalse(LSPTest.staticMethod());
|
||||
}
|
||||
}
|
||||
|
55
test/src/main/java/org/lsposed/lsplant/Hooker.java
Normal file
55
test/src/main/java/org/lsposed/lsplant/Hooker.java
Normal file
@ -0,0 +1,55 @@
|
||||
package org.lsposed.lsplant;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Hooker {
|
||||
|
||||
public Executable backup;
|
||||
|
||||
private boolean isStatic;
|
||||
private Executable replacement;
|
||||
|
||||
private Hooker() {
|
||||
}
|
||||
|
||||
private native Executable doHook(Executable original, Executable callback);
|
||||
|
||||
private native boolean doUnhook(Executable replacement);
|
||||
|
||||
public Object callback(Object[] args) throws InvocationTargetException, IllegalAccessException, InstantiationException {
|
||||
if (replacement instanceof Method) {
|
||||
if (isStatic) {
|
||||
return ((Method) replacement).invoke(null, args);
|
||||
} else {
|
||||
return ((Method) replacement).invoke(args[0], Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
} else if (replacement instanceof Constructor) {
|
||||
return ((Constructor<?>) replacement).newInstance(args);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported executable type");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean unhook() {
|
||||
return doUnhook(replacement);
|
||||
}
|
||||
|
||||
public static Hooker hook(Executable original, Executable replacement) {
|
||||
Hooker hooker = new Hooker();
|
||||
try {
|
||||
var callbackMethod = Hooker.class.getDeclaredMethod("callback", Object[].class);
|
||||
var result = hooker.doHook(original, callbackMethod);
|
||||
if (result == null) return null;
|
||||
hooker.isStatic = (replacement.getModifiers() & Modifier.STATIC) != 0;
|
||||
hooker.backup = result;
|
||||
hooker.replacement = replacement;
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
return hooker;
|
||||
}
|
||||
}
|
@ -7,4 +7,8 @@ public class LSPTest {
|
||||
}
|
||||
|
||||
native static boolean initHooker();
|
||||
|
||||
static boolean staticMethod() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
8
test/src/main/java/org/lsposed/lsplant/Replacement.java
Normal file
8
test/src/main/java/org/lsposed/lsplant/Replacement.java
Normal file
@ -0,0 +1,8 @@
|
||||
package org.lsposed.lsplant;
|
||||
|
||||
public class Replacement {
|
||||
|
||||
static boolean staticMethodReplacement() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -37,6 +37,18 @@ Java_org_lsposed_lsplant_LSPTest_initHooker(JNIEnv*, jclass) {
|
||||
return init_result;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_org_lsposed_lsplant_Hooker_doHook(JNIEnv* env, jobject thiz, jobject original, jobject callback) {
|
||||
return lsplant::Hook(env, original, thiz, callback);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_lsposed_lsplant_Hooker_doUnhook(JNIEnv* env, jobject, jobject replacement) {
|
||||
return lsplant::UnHook(env, replacement);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
JNIEnv* env;
|
||||
@ -48,7 +60,7 @@ JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
.inline_hooker = InlineHooker,
|
||||
.inline_unhooker = InlineUnhooker,
|
||||
.art_symbol_resolver = [&art](std::string_view symbol) -> void* {
|
||||
auto *out = reinterpret_cast<void*>(art.getSymbAddress(symbol));
|
||||
auto* out = reinterpret_cast<void*>(art.getSymbAddress(symbol));
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user