├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── vcs.xml
├── modules.xml
├── runConfigurations.xml
├── gradle.xml
├── compiler.xml
└── misc.xml
├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── jniLibs
│ │ │ ├── x86
│ │ │ │ ├── libsubstrate.so
│ │ │ │ └── libsubstrate-dvm.so
│ │ │ └── armeabi
│ │ │ │ ├── libsubstrate.so
│ │ │ │ └── libsubstrate-dvm.so
│ │ ├── res
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ └── styles.xml
│ │ │ ├── values-v21
│ │ │ │ └── styles.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ ├── menu
│ │ │ │ └── menu_main.xml
│ │ │ └── layout
│ │ │ │ ├── content_main.xml
│ │ │ │ └── activity_main.xml
│ │ ├── jni
│ │ │ ├── hello.h
│ │ │ ├── hello.cpp
│ │ │ ├── substrate.cpp
│ │ │ └── substrate.h
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── f8
│ │ │ └── hellonative
│ │ │ └── MainActivity.java
│ ├── test
│ │ └── java
│ │ │ └── f8
│ │ │ └── hellonative
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── f8
│ │ └── hellonative
│ │ └── ApplicationTest.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── README.md
├── .gitignore
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew.bat
└── gradlew
/.idea/.name:
--------------------------------------------------------------------------------
1 | HelloNative
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/README.md
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/jniLibs/x86/libsubstrate.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/jniLibs/x86/libsubstrate.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi/libsubstrate.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/jniLibs/armeabi/libsubstrate.so
--------------------------------------------------------------------------------
/app/src/main/jniLibs/x86/libsubstrate-dvm.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/jniLibs/x86/libsubstrate-dvm.so
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/jniLibs/armeabi/libsubstrate-dvm.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/jniLibs/armeabi/libsubstrate-dvm.so
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/F8LEFT/Cydia-Substrate-Android-NativeFuncHook/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | HelloNative
3 | Settings
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/jni/hello.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by F8LEFT on 2016/2/29.
3 | //
4 |
5 | #ifndef HELLONATIVE_HELLO_H
6 | #define HELLONATIVE_HELLO_H
7 |
8 | #endif //HELLONATIVE_HELLO_H
9 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 21 11:34:03 PDT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 | >
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/test/java/f8/hellonative/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package f8.hellonative;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/f8/hellonative/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package f8.hellonative;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\environment\AndroidSDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.model.application'
2 |
3 | model {
4 | android {
5 | compileSdkVersion 23
6 | buildToolsVersion "23.0.2"
7 |
8 | defaultConfig {
9 | applicationId "f8.hellonative"
10 | minSdkVersion.apiLevel 15
11 | targetSdkVersion.apiLevel 23
12 | versionCode 1
13 | versionName "1.0"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles.add(file("proguard-rules.pro"))
19 | }
20 | }
21 |
22 | ndk {
23 | moduleName "hello"
24 | ldLibs.add("log");
25 | ldLibs.add("dl");
26 | }
27 |
28 | }
29 |
30 | }
31 |
32 |
33 | dependencies {
34 | compile fileTree(dir: 'libs', include: ['*.jar'])
35 | //testCompile 'junit:junit:4.12'
36 | compile 'com.android.support:appcompat-v7:23.2.0'
37 | compile 'com.android.support:design:23.2.0'
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/f8/hellonative/MainActivity.java:
--------------------------------------------------------------------------------
1 | package f8.hellonative;
2 |
3 | import android.app.Application;
4 | import android.os.Bundle;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.design.widget.Snackbar;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.support.v7.widget.Toolbar;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.view.Menu;
12 | import android.view.MenuItem;
13 |
14 | public class MainActivity extends AppCompatActivity {
15 | static {
16 | System.loadLibrary("hello");
17 | }
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_main);
23 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
24 | setSupportActionBar(toolbar);
25 |
26 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
27 | fab.setOnClickListener(new View.OnClickListener() {
28 | @Override
29 | public void onClick(View view) {
30 | Log.d("F8LEFT", "SUm is " + Hello3(100));
31 | }
32 | });
33 | }
34 |
35 | @Override
36 | public boolean onCreateOptionsMenu(Menu menu) {
37 | // Inflate the menu; this adds items to the action bar if it is present.
38 | getMenuInflater().inflate(R.menu.menu_main, menu);
39 | return true;
40 | }
41 |
42 | @Override
43 | public boolean onOptionsItemSelected(MenuItem item) {
44 | // Handle action bar item clicks here. The action bar will
45 | // automatically handle clicks on the Home/Up button, so long
46 | // as you specify a parent activity in AndroidManifest.xml.
47 | int id = item.getItemId();
48 |
49 | //noinspection SimplifiableIfStatement
50 | if (id == R.id.action_settings) {
51 | return true;
52 | }
53 | return super.onOptionsItemSelected(item);
54 | }
55 |
56 | public native int Hello3(int base);
57 | }
58 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.8
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/jni/hello.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by F8LEFT on 2016/2/29.
3 | //
4 |
5 | #include "hello.h"
6 | #include "substrate.h"
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #define LOGOPEN
13 |
14 | #ifdef LOG_TAG
15 | #undef LOG_TAG
16 | #endif
17 |
18 |
19 | #ifdef LOGOPEN
20 | #define LOG_TAG "F8LEFT"
21 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
22 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
23 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
24 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
25 | #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
26 | #else
27 | #define LOGE(...)
28 | #define LOGD(...)
29 | #define LOGW(...)
30 | #define LOGI(...)
31 | #endif
32 |
33 | #define NULL 0
34 |
35 | int loadbase = 0;
36 |
37 | __attribute__((constructor))
38 | void fixBase() {
39 | loadbase = 50;
40 | }
41 |
42 | __attribute__ ((destructor))
43 | void unfixBase() {
44 | loadbase = 1000;
45 | }
46 |
47 | int enc1(int a) {
48 | return a / 2;
49 | }
50 |
51 | int enc2(int a) {
52 | return enc1(a) * 23333;
53 | }
54 |
55 | //public native String Hello3(MainActivity ma);
56 | jint Hello3(JNIEnv *env, jobject obj, jint base) {
57 | int sum = 0;
58 | for (int i = loadbase; i < base; i++) {
59 | sum = sum + i;
60 | }
61 | return enc2(sum);
62 | }
63 |
64 |
65 | jint HelloHook(JNIEnv *env, jobject obj, jint base) {
66 | int sum = 0;
67 | for (int i = 0; i < base; i++) {
68 | sum = sum + i;
69 | }
70 | return sum;
71 | }
72 |
73 |
74 | MSInitialize{
75 | MSHookFunction((void*)Hello3, (void*)HelloHook, NULL);
76 | }
77 |
78 | static int registerNativeMethods(JNIEnv *env, const char *className,
79 | JNINativeMethod *gMethods, int numMethods) {
80 | jclass clazz;
81 | clazz = env->FindClass(className);
82 | if (clazz == NULL) {
83 | return JNI_FALSE;
84 | }
85 | if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
86 | return JNI_FALSE;
87 | }
88 | return JNI_TRUE;
89 | }
90 |
91 | static const char *gClassName = "f8/hellonative/MainActivity";
92 | static JNINativeMethod gMethods[] = {
93 | {"Hello3", "(I)I", (void *) Hello3},
94 | };
95 |
96 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
97 | JNIEnv *env = NULL;
98 | jint result = -1;
99 |
100 | if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
101 | return -1;
102 | }
103 | if (registerNativeMethods(env, gClassName, gMethods,
104 | sizeof(gMethods) / sizeof(gMethods[0])) == JNI_FALSE) {
105 | return -1;
106 | }
107 |
108 | return JNI_VERSION_1_6;
109 | }
110 |
111 | JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
112 | return;
113 | }
--------------------------------------------------------------------------------
/app/src/main/jni/substrate.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by F8LEFT on 2016/3/3.
3 | //
4 |
5 | #include "substrate.h"
6 | #include
7 |
8 | typedef bool (FMSHookProcess)(pid_t pid, const char *library);
9 | typedef MSImageRef (FMSGetImageByName)(const char *file);
10 | typedef void *(FMSFindSymbol)(MSImageRef image, const char *name);
11 | typedef void (FMSHookFunction)(void *symbol, void *replace, void **result);
12 |
13 | MSImageRef imageBase = NULL;
14 | FMSHookProcess *fmsHookProcess = NULL;
15 | FMSGetImageByName *fmsGetImageByName = NULL;
16 | FMSFindSymbol *fmsFindSymbol = NULL;
17 | FMSHookFunction *fmsHookFunction = NULL;
18 |
19 | #ifdef __ANDROID__
20 | typedef void (FMSJavaHookClassLoad)(JNIEnv *jni, const char *name, void (*callback)(JNIEnv *, jclass, void *), void *data);
21 | typedef void (FMSJavaHookMethod)(JNIEnv *jni, jclass _class, jmethodID methodID, void *function, void **result);
22 | typedef void (FMSJavaBlessClassLoader)(JNIEnv *jni, jobject loader);
23 |
24 | typedef MSJavaObjectKey (FMSJavaCreateObjectKey)();
25 | typedef void (FMSJavaReleaseObjectKey)(MSJavaObjectKey key);
26 | typedef void *(FMSJavaGetObjectKey)(JNIEnv *jni, jobject object, MSJavaObjectKey key);
27 | typedef void (FMSJavaSetObjectKey)(JNIEnv *jni, jobject object, MSJavaObjectKey key, void *value, void (*clean)(void *, JNIEnv *, void *), void *data);
28 |
29 | FMSJavaHookClassLoad *fmsJavaHookClassLoad = NULL;
30 | FMSJavaHookMethod *fmsJavaHookMethod = NULL;
31 | FMSJavaBlessClassLoader *fmsJavaBlessClassLoader = NULL;
32 | FMSJavaCreateObjectKey *fmsJavaCreateObjectKey = NULL;
33 | FMSJavaReleaseObjectKey *fmsJavaReleaseObjectKey = NULL;
34 | FMSJavaGetObjectKey *fmsJavaGetObjectKey = NULL;
35 | FMSJavaSetObjectKey *fmsJavaSetObjectKey = NULL;
36 | #endif
37 | //Initialise function
38 | MSInitialize {
39 | bool isDalvik = dlopen("libdvm.so", RTLD_NOLOAD) != NULL;
40 | if (isDalvik)
41 | imageBase = dlopen("libsubstrate.so-dvm", RTLD_NOW);
42 | else
43 | imageBase = dlopen("libsubstrate.so", RTLD_NOW);
44 | fmsHookProcess = (FMSHookProcess*)dlsym((void*)imageBase, "MSHookProcess");
45 | fmsGetImageByName = (FMSGetImageByName*)dlsym((void*)imageBase, "MSGetImageByName");
46 | fmsFindSymbol = (FMSFindSymbol*)dlsym((void*)imageBase, "MSFindSymbol");
47 | fmsHookFunction = (FMSHookFunction*)dlsym((void*)imageBase, "MSHookFunction");
48 |
49 | #ifdef __ANDROID__
50 | if (isDalvik) {
51 | fmsJavaHookClassLoad = (FMSJavaHookClassLoad*)dlsym((void*)imageBase, "MSJavaHookClassLoad");
52 | fmsJavaHookMethod = (FMSJavaHookMethod*)dlsym((void*)imageBase, "MSJavaHookMethod");
53 | fmsJavaBlessClassLoader = (FMSJavaBlessClassLoader *)dlsym((void*)imageBase, "MSJavaBlessClassLoader");
54 | fmsJavaCreateObjectKey = (FMSJavaCreateObjectKey *)dlsym((void*)imageBase, "MSJavaCreateObjectKey");
55 | fmsJavaReleaseObjectKey = (FMSJavaReleaseObjectKey *)dlsym((void*)imageBase, "MSJavaReleaseObjectKey");
56 | fmsJavaGetObjectKey = (FMSJavaGetObjectKey *)dlsym((void*)imageBase, "MSJavaGetObjectKey");
57 | fmsJavaSetObjectKey = (FMSJavaSetObjectKey *)dlsym((void*)imageBase, "MSJavaSetObjectKey");
58 | }
59 | #endif
60 | };
61 |
62 | bool MSHookProcess(pid_t pid, const char *library) {
63 | if (fmsHookFunction != NULL)
64 | return fmsHookProcess(pid, library);
65 | return false;
66 | }
67 |
68 | MSImageRef MSGetImageByName(const char *file) {
69 | if (fmsGetImageByName != NULL)
70 | return fmsGetImageByName(file);
71 | return NULL;
72 | }
73 |
74 | void *MSFindSymbol(MSImageRef image, const char *name) {
75 | if (fmsFindSymbol != NULL)
76 | return fmsFindSymbol(image, name);
77 | return NULL;
78 | }
79 |
80 | void MSHookFunction(void *symbol, void *replace, void **result) {
81 | if (fmsHookFunction != NULL)
82 | return fmsHookFunction(symbol, replace, result);
83 | return;
84 | }
85 |
86 | #ifdef __ANDROID__
87 | void MSJavaHookClassLoad(JNIEnv *jni, const char *name, void (*callback)(JNIEnv *, jclass, void *), void *data)
88 | {
89 | if (fmsJavaHookClassLoad != NULL)
90 | return fmsJavaHookClassLoad(jni, name, callback, data);
91 | return;
92 | }
93 |
94 | void MSJavaHookMethod(JNIEnv *jni, jclass _class, jmethodID methodID, void *function, void **result)
95 | {
96 | if (fmsJavaHookMethod != NULL)
97 | return fmsJavaHookMethod(jni, _class, methodID, function, result);
98 | return;
99 | }
100 |
101 | void MSJavaBlessClassLoader(JNIEnv *jni, jobject loader) {
102 | if (fmsJavaBlessClassLoader != NULL)
103 | return fmsJavaBlessClassLoader(jni, loader);
104 | return;
105 | }
106 |
107 | MSJavaObjectKey MSJavaCreateObjectKey() {
108 | if (fmsJavaCreateObjectKey != NULL)
109 | return fmsJavaCreateObjectKey();
110 | return NULL;
111 | }
112 |
113 | void MSJavaReleaseObjectKey(MSJavaObjectKey key) {
114 | if (fmsJavaReleaseObjectKey != NULL)
115 | return fmsJavaReleaseObjectKey(key);
116 | return;
117 | }
118 | void *MSJavaGetObjectKey(JNIEnv *jni, jobject object, MSJavaObjectKey key)
119 | {
120 | if (fmsJavaGetObjectKey != NULL)
121 | return fmsJavaGetObjectKey(jni, object, key);
122 | return NULL;
123 | }
124 |
125 | void MSJavaSetObjectKey(JNIEnv *jni, jobject object, MSJavaObjectKey key, void *value, void (*clean)(void *, JNIEnv *, void *), void *data)
126 | {
127 | if (fmsJavaSetObjectKey != NULL)
128 | return fmsJavaSetObjectKey(jni, object, key, value, clean, data);
129 | return;
130 | }
131 | #endif
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/jni/substrate.h:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2013 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_H_
23 | #define SUBSTRATE_H_
24 |
25 | #ifdef __APPLE__
26 | #ifdef __cplusplus
27 | extern "C" {
28 | #endif
29 | #include
30 | #ifdef __cplusplus
31 | }
32 | #endif
33 |
34 | #include
35 | #include
36 | #endif
37 |
38 | #include
39 | #include
40 |
41 | #define _finline \
42 | inline __attribute__((__always_inline__))
43 | #define _disused \
44 | __attribute__((__unused__))
45 |
46 | #ifdef __cplusplus
47 | #define _default(value) = value
48 | #else
49 | #define _default(value)
50 | #endif
51 |
52 | #ifdef __cplusplus
53 | extern "C" {
54 | #endif
55 |
56 | bool MSHookProcess(pid_t pid, const char *library);
57 |
58 | typedef const void *MSImageRef;
59 |
60 | MSImageRef MSGetImageByName(const char *file);
61 | void *MSFindSymbol(MSImageRef image, const char *name);
62 |
63 | void MSHookFunction(void *symbol, void *replace, void **result);
64 |
65 | #ifdef __APPLE__
66 | #ifdef __arm__
67 | __attribute__((__deprecated__))
68 | IMP MSHookMessage(Class _class, SEL sel, IMP imp, const char *prefix _default(NULL));
69 | #endif
70 | void MSHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result);
71 | #endif
72 |
73 | #ifdef __ANDROID__
74 | #include
75 | void MSJavaHookClassLoad(JNIEnv *jni, const char *name, void (*callback)(JNIEnv *, jclass, void *), void *data _default(NULL));
76 | void MSJavaHookMethod(JNIEnv *jni, jclass _class, jmethodID methodID, void *function, void **result);
77 | void MSJavaBlessClassLoader(JNIEnv *jni, jobject loader);
78 |
79 | typedef struct MSJavaObjectKey_ *MSJavaObjectKey;
80 | MSJavaObjectKey MSJavaCreateObjectKey();
81 | void MSJavaReleaseObjectKey(MSJavaObjectKey key);
82 | void *MSJavaGetObjectKey(JNIEnv *jni, jobject object, MSJavaObjectKey key);
83 | void MSJavaSetObjectKey(JNIEnv *jni, jobject object, MSJavaObjectKey key, void *value, void (*clean)(void *, JNIEnv *, void *) _default(NULL), void *data _default(NULL));
84 | #endif
85 |
86 | #ifdef __cplusplus
87 | }
88 | #endif
89 |
90 | #ifdef __cplusplus
91 |
92 | #ifdef __APPLE__
93 |
94 | namespace etl {
95 |
96 | template
97 | struct Case {
98 | static char value[Case_ + 1];
99 | };
100 |
101 | typedef Case Yes;
102 | typedef Case No;
103 |
104 | namespace be {
105 | template
106 | static Yes CheckClass_(void (Checked_::*)());
107 |
108 | template
109 | static No CheckClass_(...);
110 | }
111 |
112 | template
113 | struct IsClass {
114 | void gcc32();
115 |
116 | static const bool value = (sizeof(be::CheckClass_(0).value) == sizeof(Yes::value));
117 | };
118 |
119 | }
120 |
121 | #ifdef __arm__
122 | template
123 | __attribute__((__deprecated__))
124 | static inline Type_ *MSHookMessage(Class _class, SEL sel, Type_ *imp, const char *prefix = NULL) {
125 | return reinterpret_cast(MSHookMessage(_class, sel, reinterpret_cast(imp), prefix));
126 | }
127 | #endif
128 |
129 | template
130 | static inline void MSHookMessage(Class _class, SEL sel, Type_ *imp, Type_ **result) {
131 | return MSHookMessageEx(_class, sel, reinterpret_cast(imp), reinterpret_cast(result));
132 | }
133 |
134 | template
135 | static inline Type_ &MSHookIvar(id self, const char *name) {
136 | Ivar ivar(class_getInstanceVariable(object_getClass(self), name));
137 | void *pointer(ivar == NULL ? NULL : reinterpret_cast(self) + ivar_getOffset(ivar));
138 | return *reinterpret_cast(pointer);
139 | }
140 |
141 | #define MSAddMessage0(_class, type, arg0) \
142 | class_addMethod($ ## _class, @selector(arg0), (IMP) &$ ## _class ## $ ## arg0, type);
143 | #define MSAddMessage1(_class, type, arg0) \
144 | class_addMethod($ ## _class, @selector(arg0:), (IMP) &$ ## _class ## $ ## arg0 ## $, type);
145 | #define MSAddMessage2(_class, type, arg0, arg1) \
146 | class_addMethod($ ## _class, @selector(arg0:arg1:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $, type);
147 | #define MSAddMessage3(_class, type, arg0, arg1, arg2) \
148 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $, type);
149 | #define MSAddMessage4(_class, type, arg0, arg1, arg2, arg3) \
150 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $, type);
151 | #define MSAddMessage5(_class, type, arg0, arg1, arg2, arg3, arg4) \
152 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $, type);
153 | #define MSAddMessage6(_class, type, arg0, arg1, arg2, arg3, arg4, arg5) \
154 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $, type);
155 | #define MSAddMessage7(_class, type, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
156 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ $$ arg6 ## $, type);
157 | #define MSAddMessage8(_class, type, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
158 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:arg7:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ $$ arg6 ## $ ## arg7 ## $, type);
159 |
160 | #define MSHookMessage0(_class, arg0) \
161 | MSHookMessage($ ## _class, @selector(arg0), MSHake(_class ## $ ## arg0))
162 | #define MSHookMessage1(_class, arg0) \
163 | MSHookMessage($ ## _class, @selector(arg0:), MSHake(_class ## $ ## arg0 ## $))
164 | #define MSHookMessage2(_class, arg0, arg1) \
165 | MSHookMessage($ ## _class, @selector(arg0:arg1:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $))
166 | #define MSHookMessage3(_class, arg0, arg1, arg2) \
167 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $))
168 | #define MSHookMessage4(_class, arg0, arg1, arg2, arg3) \
169 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $))
170 | #define MSHookMessage5(_class, arg0, arg1, arg2, arg3, arg4) \
171 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $))
172 | #define MSHookMessage6(_class, arg0, arg1, arg2, arg3, arg4, arg5) \
173 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $))
174 | #define MSHookMessage7(_class, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
175 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ ## arg6 ## $))
176 | #define MSHookMessage8(_class, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
177 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:arg7:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ ## arg6 ## $ ## arg7 ## $))
178 |
179 | #define MSRegister_(name, dollar, colon) \
180 | namespace { static class C_$ ## name ## $ ## dollar { public: _finline C_$ ## name ## $ ##dollar() { \
181 | MSHookMessage($ ## name, @selector(colon), MSHake(name ## $ ## dollar)); \
182 | } } V_$ ## name ## $ ## dollar; } \
183 |
184 | #define MSIgnore_(name, dollar, colon)
185 |
186 | #define MSMessage_(extra, type, _class, name, dollar, colon, call, args...) \
187 | static type _$ ## name ## $ ## dollar(Class _cls, type (*_old)(_class, SEL, ## args, ...), type (*_spr)(struct objc_super *, SEL, ## args, ...), _class self, SEL _cmd, ## args); \
188 | MSHook(type, name ## $ ## dollar, _class self, SEL _cmd, ## args) { \
189 | Class const _cls($ ## name); \
190 | type (* const _old)(_class, SEL, ## args, ...) = reinterpret_cast(_ ## name ## $ ## dollar); \
191 | typedef type (*msgSendSuper_t)(struct objc_super *, SEL, ## args, ...); \
192 | msgSendSuper_t const _spr(::etl::IsClass::value ? reinterpret_cast(&objc_msgSendSuper_stret) : reinterpret_cast(&objc_msgSendSuper)); \
193 | return _$ ## name ## $ ## dollar call; \
194 | } \
195 | extra(name, dollar, colon) \
196 | static _finline type _$ ## name ## $ ## dollar(Class _cls, type (*_old)(_class, SEL, ## args, ...), type (*_spr)(struct objc_super *, SEL, ## args, ...), _class self, SEL _cmd, ## args)
197 |
198 | /* for((x=1;x!=7;++x)){ echo -n "#define MSMessage${x}_(extra, type, _class, name";for((y=0;y!=x;++y));do echo -n ", sel$y";done;for((y=0;y!=x;++y));do echo -n ", type$y, arg$y";done;echo ") \\";echo -n " MSMessage_(extra, type, _class, name,";for((y=0;y!=x;++y));do if [[ $y -ne 0 ]];then echo -n " ##";fi;echo -n " sel$y ## $";done;echo -n ", ";for((y=0;y!=x;++y));do echo -n "sel$y:";done;echo -n ", (_cls, _old, _spr, self, _cmd";for((y=0;y!=x;++y));do echo -n ", arg$y";done;echo -n ")";for((y=0;y!=x;++y));do echo -n ", type$y arg$y";done;echo ")";} */
199 |
200 | #define MSMessage0_(extra, type, _class, name, sel0) \
201 | MSMessage_(extra, type, _class, name, sel0, sel0, (_cls, _old, _spr, self, _cmd))
202 | #define MSMessage1_(extra, type, _class, name, sel0, type0, arg0) \
203 | MSMessage_(extra, type, _class, name, sel0 ## $, sel0:, (_cls, _old, _spr, self, _cmd, arg0), type0 arg0)
204 | #define MSMessage2_(extra, type, _class, name, sel0, sel1, type0, arg0, type1, arg1) \
205 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $, sel0:sel1:, (_cls, _old, _spr, self, _cmd, arg0, arg1), type0 arg0, type1 arg1)
206 | #define MSMessage3_(extra, type, _class, name, sel0, sel1, sel2, type0, arg0, type1, arg1, type2, arg2) \
207 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $, sel0:sel1:sel2:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2), type0 arg0, type1 arg1, type2 arg2)
208 | #define MSMessage4_(extra, type, _class, name, sel0, sel1, sel2, sel3, type0, arg0, type1, arg1, type2, arg2, type3, arg3) \
209 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $, sel0:sel1:sel2:sel3:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3), type0 arg0, type1 arg1, type2 arg2, type3 arg3)
210 | #define MSMessage5_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \
211 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $, sel0:sel1:sel2:sel3:sel4:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4)
212 | #define MSMessage6_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5) \
213 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $, sel0:sel1:sel2:sel3:sel4:sel5:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)
214 | #define MSMessage7_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, sel6, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6) \
215 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $ ## sel6 ## $, sel0:sel1:sel2:sel3:sel4:sel5:sel6:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5, arg6), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6)
216 | #define MSMessage8_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, sel6, sel7, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6, type7, arg7) \
217 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $ ## sel6 ## $ ## sel7 ## $, sel0:sel1:sel2:sel3:sel4:sel5:sel6:sel7:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7)
218 |
219 | #define MSInstanceMessage0(type, _class, args...) MSMessage0_(MSIgnore_, type, _class *, _class, ## args)
220 | #define MSInstanceMessage1(type, _class, args...) MSMessage1_(MSIgnore_, type, _class *, _class, ## args)
221 | #define MSInstanceMessage2(type, _class, args...) MSMessage2_(MSIgnore_, type, _class *, _class, ## args)
222 | #define MSInstanceMessage3(type, _class, args...) MSMessage3_(MSIgnore_, type, _class *, _class, ## args)
223 | #define MSInstanceMessage4(type, _class, args...) MSMessage4_(MSIgnore_, type, _class *, _class, ## args)
224 | #define MSInstanceMessage5(type, _class, args...) MSMessage5_(MSIgnore_, type, _class *, _class, ## args)
225 | #define MSInstanceMessage6(type, _class, args...) MSMessage6_(MSIgnore_, type, _class *, _class, ## args)
226 | #define MSInstanceMessage7(type, _class, args...) MSMessage7_(MSIgnore_, type, _class *, _class, ## args)
227 | #define MSInstanceMessage8(type, _class, args...) MSMessage8_(MSIgnore_, type, _class *, _class, ## args)
228 |
229 | #define MSClassMessage0(type, _class, args...) MSMessage0_(MSIgnore_, type, Class, $ ## _class, ## args)
230 | #define MSClassMessage1(type, _class, args...) MSMessage1_(MSIgnore_, type, Class, $ ## _class, ## args)
231 | #define MSClassMessage2(type, _class, args...) MSMessage2_(MSIgnore_, type, Class, $ ## _class, ## args)
232 | #define MSClassMessage3(type, _class, args...) MSMessage3_(MSIgnore_, type, Class, $ ## _class, ## args)
233 | #define MSClassMessage4(type, _class, args...) MSMessage4_(MSIgnore_, type, Class, $ ## _class, ## args)
234 | #define MSClassMessage5(type, _class, args...) MSMessage5_(MSIgnore_, type, Class, $ ## _class, ## args)
235 | #define MSClassMessage6(type, _class, args...) MSMessage6_(MSIgnore_, type, Class, $ ## _class, ## args)
236 | #define MSClassMessage7(type, _class, args...) MSMessage7_(MSIgnore_, type, Class, $ ## _class, ## args)
237 | #define MSClassMessage8(type, _class, args...) MSMessage8_(MSIgnore_, type, Class, $ ## _class, ## args)
238 |
239 | #define MSInstanceMessageHook0(type, _class, args...) MSMessage0_(MSRegister_, type, _class *, _class, ## args)
240 | #define MSInstanceMessageHook1(type, _class, args...) MSMessage1_(MSRegister_, type, _class *, _class, ## args)
241 | #define MSInstanceMessageHook2(type, _class, args...) MSMessage2_(MSRegister_, type, _class *, _class, ## args)
242 | #define MSInstanceMessageHook3(type, _class, args...) MSMessage3_(MSRegister_, type, _class *, _class, ## args)
243 | #define MSInstanceMessageHook4(type, _class, args...) MSMessage4_(MSRegister_, type, _class *, _class, ## args)
244 | #define MSInstanceMessageHook5(type, _class, args...) MSMessage5_(MSRegister_, type, _class *, _class, ## args)
245 | #define MSInstanceMessageHook6(type, _class, args...) MSMessage6_(MSRegister_, type, _class *, _class, ## args)
246 | #define MSInstanceMessageHook7(type, _class, args...) MSMessage7_(MSRegister_, type, _class *, _class, ## args)
247 | #define MSInstanceMessageHook8(type, _class, args...) MSMessage8_(MSRegister_, type, _class *, _class, ## args)
248 |
249 | #define MSClassMessageHook0(type, _class, args...) MSMessage0_(MSRegister_, type, Class, $ ## _class, ## args)
250 | #define MSClassMessageHook1(type, _class, args...) MSMessage1_(MSRegister_, type, Class, $ ## _class, ## args)
251 | #define MSClassMessageHook2(type, _class, args...) MSMessage2_(MSRegister_, type, Class, $ ## _class, ## args)
252 | #define MSClassMessageHook3(type, _class, args...) MSMessage3_(MSRegister_, type, Class, $ ## _class, ## args)
253 | #define MSClassMessageHook4(type, _class, args...) MSMessage4_(MSRegister_, type, Class, $ ## _class, ## args)
254 | #define MSClassMessageHook5(type, _class, args...) MSMessage5_(MSRegister_, type, Class, $ ## _class, ## args)
255 | #define MSClassMessageHook6(type, _class, args...) MSMessage6_(MSRegister_, type, Class, $ ## _class, ## args)
256 | #define MSClassMessageHook7(type, _class, args...) MSMessage7_(MSRegister_, type, Class, $ ## _class, ## args)
257 | #define MSClassMessageHook8(type, _class, args...) MSMessage8_(MSRegister_, type, Class, $ ## _class, ## args)
258 |
259 | #define MSOldCall(args...) \
260 | _old(self, _cmd, ## args)
261 | #define MSSuperCall(args...) \
262 | _spr(& (struct objc_super) {self, class_getSuperclass(_cls)}, _cmd, ## args)
263 |
264 | #define MSIvarHook(type, name) \
265 | type &name(MSHookIvar(self, #name))
266 |
267 | #define MSClassHook(name) \
268 | @class name; \
269 | static Class $ ## name = objc_getClass(#name);
270 | #define MSMetaClassHook(name) \
271 | @class name; \
272 | static Class $$ ## name = object_getClass($ ## name);
273 |
274 | #endif/*__APPLE__*/
275 |
276 | template
277 | static inline void MSHookFunction(Type_ *symbol, Type_ *replace, Type_ **result) {
278 | return MSHookFunction(
279 | reinterpret_cast(symbol),
280 | reinterpret_cast(replace),
281 | reinterpret_cast(result)
282 | );
283 | }
284 |
285 | template
286 | static inline void MSHookFunction(Type_ *symbol, Type_ *replace) {
287 | return MSHookFunction(symbol, replace, reinterpret_cast(NULL));
288 | }
289 |
290 | template
291 | static inline void MSHookSymbol(Type_ *&value, const char *name, MSImageRef image = NULL) {
292 | value = reinterpret_cast(MSFindSymbol(image, name));
293 | }
294 |
295 | template
296 | static inline void MSHookFunction(const char *name, Type_ *replace, Type_ **result = NULL) {
297 | Type_ *symbol;
298 | MSHookSymbol(symbol, name);
299 | return MSHookFunction(symbol, replace, result);
300 | }
301 |
302 | template
303 | static inline void MSHookFunction(MSImageRef image, const char *name, Type_ *replace, Type_ **result = NULL) {
304 | Type_ *symbol;
305 | MSHookSymbol(symbol, name, image);
306 | return MSHookFunction(symbol, replace, result);
307 | }
308 |
309 | #endif
310 |
311 | #ifdef __ANDROID__
312 |
313 | #ifdef __cplusplus
314 |
315 | template
316 | static inline void MSJavaHookMethod(JNIEnv *jni, jclass _class, jmethodID method, Type_ (*replace)(JNIEnv *, Kind_, Args_...), Type_ (**result)(JNIEnv *, Kind_, ...)) {
317 | return MSJavaHookMethod(
318 | jni, _class, method,
319 | reinterpret_cast(replace),
320 | reinterpret_cast(result)
321 | );
322 | }
323 |
324 | #endif
325 |
326 | static inline void MSAndroidGetPackage(JNIEnv *jni, jobject global, const char *name, jobject &local, jobject &loader) {
327 | jclass Context(jni->FindClass("android/content/Context"));
328 | jmethodID Context$createPackageContext(jni->GetMethodID(Context, "createPackageContext", "(Ljava/lang/String;I)Landroid/content/Context;"));
329 | jmethodID Context$getClassLoader(jni->GetMethodID(Context, "getClassLoader", "()Ljava/lang/ClassLoader;"));
330 |
331 | jstring string(jni->NewStringUTF(name));
332 | local = jni->CallObjectMethod(global, Context$createPackageContext, string, 3);
333 | loader = jni->CallObjectMethod(local, Context$getClassLoader);
334 | }
335 |
336 | static inline jclass MSJavaFindClass(JNIEnv *jni, jobject loader, const char *name) {
337 | jclass Class(jni->FindClass("java/lang/Class"));
338 | jmethodID Class$forName(jni->GetStaticMethodID(Class, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"));
339 |
340 | jstring string(jni->NewStringUTF(name));
341 | jobject _class(jni->CallStaticObjectMethod(Class, Class$forName, string, JNI_TRUE, loader));
342 | if (jni->ExceptionCheck())
343 | return NULL;
344 |
345 | return reinterpret_cast(_class);
346 | }
347 |
348 | _disused static void MSJavaCleanWeak(void *data, JNIEnv *jni, void *value) {
349 | jni->DeleteWeakGlobalRef(reinterpret_cast(value));
350 | }
351 |
352 | #endif
353 |
354 | #define MSHook(type, name, args...) \
355 | _disused static type (*_ ## name)(args); \
356 | static type $ ## name(args)
357 |
358 | #define MSJavaHook(type, name, arg0, args...) \
359 | _disused static type (*_ ## name)(JNIEnv *jni, arg0, ...); \
360 | static type $ ## name(JNIEnv *jni, arg0, ## args)
361 |
362 | #ifdef __cplusplus
363 | #define MSHake(name) \
364 | &$ ## name, &_ ## name
365 | #else
366 | #define MSHake(name) \
367 | &$ ## name, (void **) &_ ## name
368 | #endif
369 |
370 | #define SubstrateConcat_(lhs, rhs) \
371 | lhs ## rhs
372 | #define SubstrateConcat(lhs, rhs) \
373 | SubstrateConcat_(lhs, rhs)
374 |
375 | #ifdef __APPLE__
376 | #define SubstrateSection \
377 | __attribute__((__section__("__TEXT, __substrate")))
378 | #else
379 | #define SubstrateSection \
380 | __attribute__((__section__(".substrate")))
381 | #endif
382 |
383 | #ifdef __APPLE__
384 | #define MSFilterCFBundleID "Filter:CFBundleID"
385 | #define MSFilterObjC_Class "Filter:ObjC.Class"
386 | #endif
387 |
388 | #define MSFilterLibrary "Filter:Library"
389 | #define MSFilterExecutable "Filter:Executable"
390 |
391 | #define MSConfig(name, value) \
392 | extern const char SubstrateConcat(_substrate_, __LINE__)[] SubstrateSection = name "=" value;
393 |
394 | #ifdef __cplusplus
395 | #define MSInitialize \
396 | static void _MSInitialize(void); \
397 | namespace { static class $MSInitialize { public: _finline $MSInitialize() { \
398 | _MSInitialize(); \
399 | } } $MSInitialize; } \
400 | static void _MSInitialize()
401 | #else
402 | #define MSInitialize \
403 | __attribute__((__constructor__)) static void _MSInitialize(void)
404 | #endif
405 |
406 | #define Foundation_f "/System/Library/Frameworks/Foundation.framework/Foundation"
407 | #define UIKit_f "/System/Library/Frameworks/UIKit.framework/UIKit"
408 | #define JavaScriptCore_f "/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore"
409 | #define IOKit_f "/System/Library/Frameworks/IOKit.framework/IOKit"
410 |
411 | #endif//SUBSTRATE_H_
412 |
--------------------------------------------------------------------------------