Commit 5021195a authored by swift_gan's avatar swift_gan Committed by swift_gan

[XposedCompat]new impl

parent 5a5f9c34
...@@ -28,5 +28,6 @@ dependencies { ...@@ -28,5 +28,6 @@ dependencies {
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':hooklib') implementation project(':hooklib')
implementation project(':nativehook') implementation project(':nativehook')
implementation project(':xposedcompat') //implementation project(':xposedcompat')
implementation project(':xposedcompat_new')
} }
...@@ -15,7 +15,7 @@ import com.swift.sandhook.testHookers.LogHooker; ...@@ -15,7 +15,7 @@ import com.swift.sandhook.testHookers.LogHooker;
import com.swift.sandhook.testHookers.NewAnnotationApiHooker; import com.swift.sandhook.testHookers.NewAnnotationApiHooker;
import com.swift.sandhook.testHookers.ObjectHooker; import com.swift.sandhook.testHookers.ObjectHooker;
import com.swift.sandhook.wrapper.HookErrorException; import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.xposedcompat.XposedCompat; import com.swift.sandhook.xposedcompat_new.XposedCompat;
import dalvik.system.DexClassLoader; import dalvik.system.DexClassLoader;
import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodHook;
...@@ -58,25 +58,24 @@ public class MyApp extends Application { ...@@ -58,25 +58,24 @@ public class MyApp extends Application {
e.printStackTrace(); e.printStackTrace();
} }
//setup for xposed //setup for xposed\
XposedCompat.cacheDir = getCacheDir();
XposedCompat.context = this; XposedCompat.context = this;
XposedCompat.classLoader = getClassLoader(); XposedCompat.classLoader = getClassLoader();
XposedCompat.isFirstApplication= true; XposedCompat.isFirstApplication= true;
XposedHelpers.findAndHookMethod(Activity.class, "onResume", new XC_MethodHook() { // XposedHelpers.findAndHookMethod(Activity.class, "onResume", new XC_MethodHook() {
@Override // @Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable { // protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param); // super.beforeHookedMethod(param);
Log.e("XposedCompat", "beforeHookedMethod: " + param.method.getName()); // Log.e("XposedCompat", "beforeHookedMethod: " + param.method.getName());
} // }
//
@Override // @Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable { // protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param); // super.afterHookedMethod(param);
Log.e("XposedCompat", "afterHookedMethod: " + param.method.getName()); // Log.e("XposedCompat", "afterHookedMethod: " + param.method.getName());
} // }
}); // });
XposedHelpers.findAndHookMethod(MainActivity.class, "testStub", TestClass.class, int.class, String.class, boolean.class, char.class, String.class, new XC_MethodHook() { XposedHelpers.findAndHookMethod(MainActivity.class, "testStub", TestClass.class, int.class, String.class, boolean.class, char.class, String.class, new XC_MethodHook() {
......
...@@ -106,7 +106,7 @@ void* ArtMethod::getQuickCodeEntry() { ...@@ -106,7 +106,7 @@ void* ArtMethod::getQuickCodeEntry() {
} }
void* ArtMethod::getInterpreterCodeEntry() { void* ArtMethod::getInterpreterCodeEntry() {
return CastArtMethod::entryPointFormInterpreter->get(this); return CastArtMethod::entryPointFromInterpreter->get(this);
} }
GCRoot ArtMethod::getDeclaringClass() { GCRoot ArtMethod::getDeclaringClass() {
...@@ -122,10 +122,11 @@ void ArtMethod::setQuickCodeEntry(void *entry) { ...@@ -122,10 +122,11 @@ void ArtMethod::setQuickCodeEntry(void *entry) {
} }
void ArtMethod::setJniCodeEntry(void *entry) { void ArtMethod::setJniCodeEntry(void *entry) {
CastArtMethod::entryPointFromJNI->set(this, entry);
} }
void ArtMethod::setInterpreterCodeEntry(void *entry) { void ArtMethod::setInterpreterCodeEntry(void *entry) {
CastArtMethod::entryPointFormInterpreter->set(this, entry); CastArtMethod::entryPointFromInterpreter->set(this, entry);
} }
void ArtMethod::setDexCacheResolveList(void *list) { void ArtMethod::setDexCacheResolveList(void *list) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "../includes/cast_art_method.h" #include "../includes/cast_art_method.h"
#include "../includes/utils.h" #include "../includes/utils.h"
#include "../includes/never_call.h"
extern int SDK_INT; extern int SDK_INT;
...@@ -90,6 +91,11 @@ namespace SandHook { ...@@ -90,6 +91,11 @@ namespace SandHook {
class CastEntryPointFromJni : public IMember<art::mirror::ArtMethod, void *> { class CastEntryPointFromJni : public IMember<art::mirror::ArtMethod, void *> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod *p) override { Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod *p) override {
Size jniAddr = reinterpret_cast<Size>(Java_com_swift_sandhook_ClassNeverCall_neverCallNative);
int offset = findOffset(p, getParentSize(), 2, jniAddr);
if (offset >= 0) {
return static_cast<Size>(offset);
}
if (SDK_INT >= ANDROID_L2 && SDK_INT <= ANDROID_N) { if (SDK_INT >= ANDROID_L2 && SDK_INT <= ANDROID_N) {
return getParentSize() - 2 * BYTE_POINT; return getParentSize() - 2 * BYTE_POINT;
} else { } else {
...@@ -189,8 +195,8 @@ namespace SandHook { ...@@ -189,8 +195,8 @@ namespace SandHook {
accessFlag = new CastAccessFlag(); accessFlag = new CastAccessFlag();
accessFlag->init(env, m1, size); accessFlag->init(env, m1, size);
entryPointFormInterpreter = new CastEntryPointFormInterpreter(); entryPointFromInterpreter = new CastEntryPointFormInterpreter();
entryPointFormInterpreter->init(env, m1, size); entryPointFromInterpreter->init(env, m1, size);
dexCacheResolvedMethods = new CastDexCacheResolvedMethods(); dexCacheResolvedMethods = new CastDexCacheResolvedMethods();
dexCacheResolvedMethods->init(env, m1, size); dexCacheResolvedMethods->init(env, m1, size);
...@@ -240,6 +246,9 @@ namespace SandHook { ...@@ -240,6 +246,9 @@ namespace SandHook {
genericJniStub = entryPointQuickCompiled->get(neverCallNative); genericJniStub = entryPointQuickCompiled->get(neverCallNative);
} }
entryPointFromJNI = new CastEntryPointFromJni();
entryPointFromJNI->init(env, neverCallNative, size);
art::mirror::ArtMethod *neverCallStatic = reinterpret_cast<art::mirror::ArtMethod *>(env->GetStaticMethodID( art::mirror::ArtMethod *neverCallStatic = reinterpret_cast<art::mirror::ArtMethod *>(env->GetStaticMethodID(
neverCallTestClass, "neverCallStatic", "()V")); neverCallTestClass, "neverCallStatic", "()V"));
staticResolveStub = entryPointQuickCompiled->get(neverCallStatic); staticResolveStub = entryPointQuickCompiled->get(neverCallStatic);
...@@ -252,7 +261,8 @@ namespace SandHook { ...@@ -252,7 +261,8 @@ namespace SandHook {
Size CastArtMethod::size = 0; Size CastArtMethod::size = 0;
IMember<art::mirror::ArtMethod, void *> *CastArtMethod::entryPointQuickCompiled = nullptr; IMember<art::mirror::ArtMethod, void *> *CastArtMethod::entryPointQuickCompiled = nullptr;
IMember<art::mirror::ArtMethod, void *> *CastArtMethod::entryPointFormInterpreter = nullptr; IMember<art::mirror::ArtMethod, void *> *CastArtMethod::entryPointFromInterpreter = nullptr;
IMember<art::mirror::ArtMethod, void *> *CastArtMethod::entryPointFromJNI = nullptr;
ArrayMember<art::mirror::ArtMethod, void *> *CastArtMethod::dexCacheResolvedMethods = nullptr; ArrayMember<art::mirror::ArtMethod, void *> *CastArtMethod::dexCacheResolvedMethods = nullptr;
IMember<art::mirror::ArtMethod, uint32_t> *CastArtMethod::dexMethodIndex = nullptr; IMember<art::mirror::ArtMethod, uint32_t> *CastArtMethod::dexMethodIndex = nullptr;
IMember<art::mirror::ArtMethod, uint32_t> *CastArtMethod::accessFlag = nullptr; IMember<art::mirror::ArtMethod, uint32_t> *CastArtMethod::accessFlag = nullptr;
......
...@@ -14,7 +14,8 @@ namespace SandHook { ...@@ -14,7 +14,8 @@ namespace SandHook {
public: public:
static Size size; static Size size;
static IMember<art::mirror::ArtMethod, void*>* entryPointQuickCompiled; static IMember<art::mirror::ArtMethod, void*>* entryPointQuickCompiled;
static IMember<art::mirror::ArtMethod, void*>* entryPointFormInterpreter; static IMember<art::mirror::ArtMethod, void*>* entryPointFromInterpreter;
static IMember<art::mirror::ArtMethod, void*>* entryPointFromJNI;
static ArrayMember<art::mirror::ArtMethod,void*>* dexCacheResolvedMethods; static ArrayMember<art::mirror::ArtMethod,void*>* dexCacheResolvedMethods;
static IMember<art::mirror::ArtMethod, uint32_t>* dexMethodIndex; static IMember<art::mirror::ArtMethod, uint32_t>* dexMethodIndex;
static IMember<art::mirror::ArtMethod, uint32_t>* accessFlag; static IMember<art::mirror::ArtMethod, uint32_t>* accessFlag;
......
//
// Created by swift on 2019/6/3.
//
#ifndef SANDHOOK_NEVER_CALL_H
#define SANDHOOK_NEVER_CALL_H
#include <jni.h>
extern "C"
JNIEXPORT void JNICALL
Java_com_swift_sandhook_ClassNeverCall_neverCallNative(JNIEnv *env, jobject instance);
#endif //SANDHOOK_NEVER_CALL_H
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include "includes/log.h" #include "includes/log.h"
#include "includes/native_hook.h" #include "includes/native_hook.h"
#include "includes/elf_util.h" #include "includes/elf_util.h"
#include "includes/never_call.h"
#include <jni.h> #include <jni.h>
SandHook::TrampolineManager trampolineManager; SandHook::TrampolineManager trampolineManager;
...@@ -345,6 +345,22 @@ Java_com_swift_sandhook_SandHook_disableDex2oatInline(JNIEnv *env, jclass type, ...@@ -345,6 +345,22 @@ Java_com_swift_sandhook_SandHook_disableDex2oatInline(JNIEnv *env, jclass type,
return static_cast<jboolean>(SandHook::NativeHook::hookDex2oat(disableDex2oat)); return static_cast<jboolean>(SandHook::NativeHook::hookDex2oat(disableDex2oat));
} }
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_swift_sandhook_SandHook_setNativeEntry(JNIEnv *env, jclass type, jobject origin, jobject hook, jlong jniTrampoline) {
if (origin == nullptr || hook == NULL)
return JNI_FALSE;
art::mirror::ArtMethod* hookMethod = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(hook));
art::mirror::ArtMethod* originMethod = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(origin));
originMethod->backup(hookMethod);
hookMethod->setNative();
hookMethod->setQuickCodeEntry(SandHook::CastArtMethod::genericJniStub);
hookMethod->setJniCodeEntry(reinterpret_cast<void *>(jniTrampoline));
hookMethod->disableCompilable();
hookMethod->flushCache();
return JNI_TRUE;
}
extern "C" extern "C"
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_swift_sandhook_ClassNeverCall_neverCallNative(JNIEnv *env, jobject instance) { Java_com_swift_sandhook_ClassNeverCall_neverCallNative(JNIEnv *env, jobject instance) {
...@@ -456,6 +472,11 @@ static JNINativeMethod jniSandHook[] = { ...@@ -456,6 +472,11 @@ static JNINativeMethod jniSandHook[] = {
"disableDex2oatInline", "disableDex2oatInline",
"(Z)Z", "(Z)Z",
(void *) Java_com_swift_sandhook_SandHook_disableDex2oatInline (void *) Java_com_swift_sandhook_SandHook_disableDex2oatInline
},
{
"setNativeEntry",
"(Ljava/lang/reflect/Member;Ljava/lang/reflect/Member;J)Z",
(void *) Java_com_swift_sandhook_SandHook_setNativeEntry
} }
}; };
......
...@@ -365,6 +365,8 @@ public class SandHook { ...@@ -365,6 +365,8 @@ public class SandHook {
public static native boolean disableDex2oatInline(boolean disableDex2oat); public static native boolean disableDex2oatInline(boolean disableDex2oat);
public static native boolean setNativeEntry(Member origin, Member hook, long nativeEntry);
@FunctionalInterface @FunctionalInterface
public interface HookModeCallBack { public interface HookModeCallBack {
int hookMode(Member originMethod); int hookMode(Member originMethod);
......
...@@ -68,7 +68,7 @@ public class HookWrapper { ...@@ -68,7 +68,7 @@ public class HookWrapper {
if (TextUtils.equals(hookEntity.isCtor() ? "<init>" : hookEntity.target.getName(), hookMethodBackup.value()) && samePars(classLoader, field, hookEntity.pars)) { if (TextUtils.equals(hookEntity.isCtor() ? "<init>" : hookEntity.target.getName(), hookMethodBackup.value()) && samePars(classLoader, field, hookEntity.pars)) {
field.setAccessible(true); field.setAccessible(true);
if (hookEntity.backup == null) { if (hookEntity.backup == null) {
hookEntity.backup = BackupMethodStubs.getStubMethod(); hookEntity.backup = StubMethodsFactory.getStubMethod();
hookEntity.hookIsStub = true; hookEntity.hookIsStub = true;
hookEntity.resolveDexCache = false; hookEntity.resolveDexCache = false;
} }
......
package com.swift.sandhook.wrapper; package com.swift.sandhook.wrapper;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class BackupMethodStubs { public class StubMethodsFactory {
final static int maxStub = 300; final static int maxStub = 300;
private static volatile int curStub = 0; private static volatile int curStub = 0;
private static Method proxyGenClass;
static {
try {
proxyGenClass = Proxy.class.getDeclaredMethod("generateProxy",String.class,Class[].class,ClassLoader.class,Method[].class,Class[][].class);
proxyGenClass.setAccessible(true);
} catch (Throwable e) {
e.printStackTrace();
}
}
public static synchronized Method getStubMethod() { public static synchronized Method getStubMethod() {
while (curStub <= maxStub) { while (curStub <= maxStub) {
try { try {
return BackupMethodStubs.class.getDeclaredMethod("stub" + curStub++); return StubMethodsFactory.class.getDeclaredMethod("stub" + curStub++);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
} }
} }
return null; try {
curStub++;
Class proxyClass = (Class)proxyGenClass.invoke(null,"SandHookerStubClass_" + curStub, null, StubMethodsFactory.class.getClassLoader(), new Method[]{proxyGenClass}, null);
return proxyClass.getDeclaredMethods()[0];
} catch (Throwable e) {
e.printStackTrace();
return null;
}
} }
public void stub0() {} public void stub0() {}
......
...@@ -39,9 +39,4 @@ android { ...@@ -39,9 +39,4 @@ android {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
} }
package com.swift.sandhook.nativehook;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.swift.sandhook.nativehook.test", appContext.getPackageName());
}
}
package com.swift.sandhook.nativehook;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
include ':app', ':hooklib', ':hookers', ':annotation', ':xposedcompat', ':nativehook' include ':app', ':hooklib', ':hookers', ':annotation', ':xposedcompat', ':nativehook', ':xposedcompat_new'
...@@ -5,7 +5,7 @@ import android.util.Log; ...@@ -5,7 +5,7 @@ import android.util.Log;
import com.swift.sandhook.SandHook; import com.swift.sandhook.SandHook;
import com.swift.sandhook.SandHookMethodResolver; import com.swift.sandhook.SandHookMethodResolver;
import com.swift.sandhook.utils.ParamWrapper; import com.swift.sandhook.utils.ParamWrapper;
import com.swift.sandhook.wrapper.BackupMethodStubs; import com.swift.sandhook.wrapper.StubMethodsFactory;
import com.swift.sandhook.xposedcompat.XposedCompat; import com.swift.sandhook.xposedcompat.XposedCompat;
import com.swift.sandhook.xposedcompat.utils.DexLog; import com.swift.sandhook.xposedcompat.utils.DexLog;
...@@ -167,13 +167,13 @@ public class HookStubManager { ...@@ -167,13 +167,13 @@ public class HookStubManager {
try { try {
if (is64Bit) { if (is64Bit) {
Method hook = MethodHookerStubs64.class.getDeclaredMethod(getHookMethodName(curUseStubIndex), pars); Method hook = MethodHookerStubs64.class.getDeclaredMethod(getHookMethodName(curUseStubIndex), pars);
Method backup = hasStubBackup ? MethodHookerStubs64.class.getDeclaredMethod(getBackupMethodName(curUseStubIndex), pars) : BackupMethodStubs.getStubMethod(); Method backup = hasStubBackup ? MethodHookerStubs64.class.getDeclaredMethod(getBackupMethodName(curUseStubIndex), pars) : StubMethodsFactory.getStubMethod();
if (hook == null || backup == null) if (hook == null || backup == null)
return null; return null;
return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup); return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup);
} else { } else {
Method hook = MethodHookerStubs32.class.getDeclaredMethod(getHookMethodName(curUseStubIndex), pars); Method hook = MethodHookerStubs32.class.getDeclaredMethod(getHookMethodName(curUseStubIndex), pars);
Method backup = hasStubBackup ? MethodHookerStubs32.class.getDeclaredMethod(getBackupMethodName(curUseStubIndex), pars) : BackupMethodStubs.getStubMethod(); Method backup = hasStubBackup ? MethodHookerStubs32.class.getDeclaredMethod(getBackupMethodName(curUseStubIndex), pars) : StubMethodsFactory.getStubMethod();
if (hook == null || backup == null) if (hook == null || backup == null)
return null; return null;
return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup); return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment