Skip to content

Commit 8e6f1ff

Browse files
author
RLib
committed
Improve compatibility with Xposed
1 parent d246a2a commit 8e6f1ff

39 files changed

+5512
-0
lines changed

app/build.gradle

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
apply plugin: 'com.android.application'
2+
3+
android {
4+
compileSdkVersion 27
5+
buildToolsVersion "27.0.0"
6+
7+
defaultConfig {
8+
applicationId "andhook.ui"
9+
minSdkVersion 19
10+
targetSdkVersion 27
11+
compileOptions {
12+
sourceCompatibility JavaVersion.VERSION_1_8
13+
targetCompatibility JavaVersion.VERSION_1_8
14+
}
15+
}
16+
17+
buildTypes {
18+
release {
19+
minifyEnabled false
20+
}
21+
}
22+
compileOptions {
23+
sourceCompatibility JavaVersion.VERSION_1_8
24+
targetCompatibility JavaVersion.VERSION_1_8
25+
}
26+
}
27+
28+
dependencies {
29+
implementation project(':lib')
30+
}

app/src/main/AndroidManifest.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="andhook.ui"
4+
android:versionCode="1"
5+
android:versionName="1.0">
6+
7+
<uses-sdk
8+
android:minSdkVersion="19"
9+
android:targetSdkVersion="27" />
10+
<uses-permission android:name="android.permission.INTERNET" />
11+
12+
<application
13+
android:name="andhook.ui.MainApplication"
14+
android:allowBackup="true"
15+
android:icon="@drawable/ic_launcher"
16+
android:label="@string/app_name"
17+
android:theme="@style/AppTheme">
18+
<activity
19+
android:name="andhook.ui.MainActivity"
20+
android:label="@string/app_name">
21+
<intent-filter>
22+
<action android:name="android.intent.action.MAIN" />
23+
24+
<category android:name="android.intent.category.LAUNCHER" />
25+
</intent-filter>
26+
</activity>
27+
</application>
28+
29+
</manifest>

app/src/main/java/andhook/test/A.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package andhook.test;
2+
3+
import android.util.Log;
4+
5+
@SuppressWarnings("all")
6+
public final class A {
7+
public A() {
8+
Log.i(AndTest.LOG_TAG, "constructor A::A hit, this is " + this);
9+
}
10+
11+
private String a(String a, byte[] b, Object c, Object d, int e, Object f,
12+
int g) {
13+
if (b != null) {
14+
if (a != null) {
15+
c = null;
16+
d = null;
17+
f = null;
18+
}
19+
e = 0;
20+
g = 0;
21+
}
22+
Log.i(AndTest.LOG_TAG, "private method A::a hit, this is " + this);
23+
return "A::a";
24+
}
25+
26+
public static String AA(final String s) {
27+
Log.i(AndTest.LOG_TAG, "public static method A::AA hit!");
28+
final A a = new A();
29+
a.a("AA", new byte[1], null, null, 0, null, 0);
30+
return "return from A::AA with param " + s;
31+
}
32+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package andhook.test;
2+
3+
import android.content.ContentResolver;
4+
import android.content.ContextWrapper;
5+
import android.util.Log;
6+
7+
import andhook.lib.AndHook;
8+
9+
@SuppressWarnings({"all"})
10+
public class AndTest {
11+
public final static String LOG_TAG = "AndHook_Test";
12+
13+
public static void RunTest(final ContextWrapper context,
14+
final ContentResolver resolver) {
15+
Log.i(AndTest.LOG_TAG, "\nhook test started.\n--------------------------------");
16+
// libAndHook.so must be loaded before libmyjnihook.so
17+
AndHook.ensureNativeLibraryLoaded();
18+
19+
Log.i(AndTest.LOG_TAG, "\nhook in C/C++...\n--------------------------------");
20+
try {
21+
System.loadLibrary("myjnihook");
22+
} catch (final UnsatisfiedLinkError e) {
23+
Log.w(AndTest.LOG_TAG, "failed to load myjnihook!");
24+
}
25+
26+
Log.i(AndTest.LOG_TAG, "\n--------------------------------");
27+
Xposed.doHook();
28+
29+
Log.i(AndTest.LOG_TAG, "\n--------------------------------");
30+
WideningConversion.doHook();
31+
32+
Log.i(AndTest.LOG_TAG, "\n--------------------------------");
33+
Static.doHook();
34+
35+
Log.i(AndTest.LOG_TAG, "\n--------------------------------");
36+
Constructor.doHook();
37+
38+
Log.i(AndTest.LOG_TAG, "\n--------------------------------");
39+
Virtual.doHook();
40+
41+
Log.i(AndTest.LOG_TAG, "\n--------------------------------");
42+
SystemClass.doHook(resolver);
43+
44+
Log.i(AndTest.LOG_TAG, "\n--------------------------------\nhook test done.\n");
45+
}
46+
}

app/src/main/java/andhook/test/B.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package andhook.test;
2+
3+
import andhook.lib.AndHook.HookHelper;
4+
5+
import android.util.Log;
6+
7+
@SuppressWarnings("all")
8+
public final class B {
9+
public B() {
10+
Log.i(AndTest.LOG_TAG, "constructor B::B hit, this is " + this);
11+
}
12+
13+
private String b(String a, byte[] b, Object c, Object d, int e, Object f,
14+
int g) {
15+
if (b != null) {
16+
if (a != null) {
17+
c = null;
18+
d = null;
19+
f = null;
20+
}
21+
e = 0;
22+
g = 0;
23+
}
24+
Log.i(AndTest.LOG_TAG, "private method B::b hit, this is " + this);
25+
return "B::b";
26+
}
27+
28+
public static String BB(final Class<?> classA, final String s) {
29+
Log.i(AndTest.LOG_TAG, "public static method B::BB hit, class = " + classA);
30+
31+
// shuffles bytecode
32+
double da = 0.01;
33+
double db = da + 0.01;
34+
da = db + 0.01;
35+
36+
final B b = new B();
37+
b.b("BB", new byte[1], null, null, 0, null, 0);
38+
Log.i(AndTest.LOG_TAG, "invoking original public static method A::AA!");
39+
HookHelper.invokeObjectOrigin(null, s);
40+
return "return from B::BB with param " + s;
41+
}
42+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package andhook.test;
2+
3+
import andhook.lib.AndHook.HookHelper;
4+
import andhook.lib.AndHook.HookHelper.Hook;
5+
6+
import android.util.Log;
7+
8+
@SuppressWarnings("all")
9+
public final class Constructor {
10+
public Constructor() {
11+
Log.i(AndTest.LOG_TAG, "Original constructor hit, this is " + this);
12+
}
13+
14+
@Hook(clazz = Constructor.class, name = "<init>")
15+
private static void FakeConstructor(final Object objConstructor) {
16+
Log.i(AndTest.LOG_TAG, "Fake constructor hit, this is " + objConstructor);
17+
HookHelper.invokeVoidOrigin(objConstructor);
18+
}
19+
20+
public static void doHook() {
21+
// test call constructor
22+
new Constructor();
23+
24+
// hook using HookHelper
25+
HookHelper.applyHooks(Constructor.class);
26+
27+
// test call constructor
28+
new Constructor();
29+
}
30+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package andhook.test;
2+
3+
import java.lang.reflect.Method;
4+
5+
import andhook.lib.AndHook;
6+
import andhook.lib.AndHook.HookHelper;
7+
8+
import android.util.Log;
9+
10+
@SuppressWarnings("all")
11+
public final class Static {
12+
public static String a1(final String s) {
13+
Log.i(AndTest.LOG_TAG, "public static method Static::a1 hit!");
14+
return "return from Static::a1 with param " + s;
15+
}
16+
17+
private static String a2(final Class<?> classStatic, final String s) {
18+
Log.i(AndTest.LOG_TAG, "public static method Static::a2 hit, class = " + classStatic);
19+
try {
20+
final Object obj = HookHelper.invokeObjectOrigin(null, s + "+a2");
21+
Log.i(AndTest.LOG_TAG, "invokeObjectOrigin[static] return " + obj);
22+
} catch (final Exception e) {
23+
e.printStackTrace();
24+
}
25+
return "return from Static::a2 with param " + s;
26+
}
27+
28+
private static void hookUsingApi() {
29+
try {
30+
final Method m1 = Static.class.getDeclaredMethod("a1",
31+
String.class);
32+
final Method m2 = Static.class.getDeclaredMethod("a2", Class.class,
33+
String.class);
34+
Log.i(AndTest.LOG_TAG, "begin hook public static method Static::a1...");
35+
HookHelper.hook(m1, m2);
36+
Log.i(AndTest.LOG_TAG, "end hook public static method Static::a1");
37+
38+
Log.i(AndTest.LOG_TAG, "calling public static method Static::a1...");
39+
Log.i(AndTest.LOG_TAG, "public static method Static::a1 returns [" + a1("test")
40+
+ "]");
41+
} catch (final Exception e) {
42+
e.printStackTrace();
43+
}
44+
}
45+
46+
private static void hookMethodFromDifferentClassUsingApi() {
47+
try {
48+
// The following code should be called once and only once
49+
// as A.class and B.class may not have been initialized
50+
// if you use AndHook api directly.
51+
AndHook.ensureClassInitialized(A.class);
52+
AndHook.ensureClassInitialized(B.class);
53+
54+
final Method m1 = A.class.getDeclaredMethod("AA", String.class);
55+
final Method m2 = B.class.getDeclaredMethod("BB", Class.class, String.class);
56+
Log.i(AndTest.LOG_TAG, "begin hook public static method A::AA...");
57+
HookHelper.hook(m1, m2);
58+
Log.i(AndTest.LOG_TAG, "end hook public static method A::AA");
59+
60+
Log.i(AndTest.LOG_TAG, "calling public static method A::AA...");
61+
Log.i(AndTest.LOG_TAG,
62+
"public static method A::AA returns [" + A.AA("test") + "]");
63+
} catch (final Exception e) {
64+
e.printStackTrace();
65+
}
66+
}
67+
68+
public static void doHook() {
69+
// hook using base AndHook api
70+
hookUsingApi();
71+
hookMethodFromDifferentClassUsingApi();
72+
}
73+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package andhook.test;
2+
3+
import andhook.lib.AndHook.HookHelper;
4+
import andhook.lib.AndHook.HookHelper.Hook;
5+
6+
import android.content.ContentResolver;
7+
import android.os.Bundle;
8+
import android.provider.Settings.Secure;
9+
import android.util.Log;
10+
11+
@SuppressWarnings("all")
12+
public final class SystemClass {
13+
@Hook(clazz = android.app.Activity.class)
14+
private static void onCreate(final Object objActivity, final Bundle savedInstanceState) {
15+
Log.i(AndTest.LOG_TAG, "Activity::onCreate start, this is " + objActivity);
16+
HookHelper.invokeVoidOrigin(objActivity, savedInstanceState);
17+
Log.i(AndTest.LOG_TAG, "Activity::onCreate end");
18+
}
19+
20+
@Hook(clazz = Secure.class)
21+
private static String getString(final Class<?> classSecure, final ContentResolver resolver,
22+
final String name) {
23+
Log.i(AndTest.LOG_TAG, "hit name = " + name + ", class = " + classSecure);
24+
if (name.equals(Secure.ANDROID_ID))
25+
return "8888888888888888";
26+
return HookHelper.invokeObjectOrigin(null, resolver, name);
27+
}
28+
29+
public static void doHook(final ContentResolver resolver) {
30+
Log.i(AndTest.LOG_TAG, Secure.getString(resolver, Secure.ANDROID_ID));
31+
HookHelper.applyHooks(SystemClass.class);
32+
Log.i(AndTest.LOG_TAG, Secure.getString(resolver, Secure.ANDROID_ID));
33+
}
34+
}

0 commit comments

Comments
 (0)