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

[XposedCompat]new impl

parent 5a5f9c34
......@@ -28,5 +28,6 @@ dependencies {
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':hooklib')
implementation project(':nativehook')
implementation project(':xposedcompat')
//implementation project(':xposedcompat')
implementation project(':xposedcompat_new')
}
......@@ -15,7 +15,7 @@ import com.swift.sandhook.testHookers.LogHooker;
import com.swift.sandhook.testHookers.NewAnnotationApiHooker;
import com.swift.sandhook.testHookers.ObjectHooker;
import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.xposedcompat.XposedCompat;
import com.swift.sandhook.xposedcompat_new.XposedCompat;
import dalvik.system.DexClassLoader;
import de.robv.android.xposed.XC_MethodHook;
......@@ -58,25 +58,24 @@ public class MyApp extends Application {
e.printStackTrace();
}
//setup for xposed
XposedCompat.cacheDir = getCacheDir();
//setup for xposed\
XposedCompat.context = this;
XposedCompat.classLoader = getClassLoader();
XposedCompat.isFirstApplication= true;
XposedHelpers.findAndHookMethod(Activity.class, "onResume", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.e("XposedCompat", "beforeHookedMethod: " + param.method.getName());
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.e("XposedCompat", "afterHookedMethod: " + param.method.getName());
}
});
// XposedHelpers.findAndHookMethod(Activity.class, "onResume", new XC_MethodHook() {
// @Override
// protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// super.beforeHookedMethod(param);
// Log.e("XposedCompat", "beforeHookedMethod: " + param.method.getName());
// }
//
// @Override
// protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// super.afterHookedMethod(param);
// 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() {
......
......@@ -106,7 +106,7 @@ void* ArtMethod::getQuickCodeEntry() {
}
void* ArtMethod::getInterpreterCodeEntry() {
return CastArtMethod::entryPointFormInterpreter->get(this);
return CastArtMethod::entryPointFromInterpreter->get(this);
}
GCRoot ArtMethod::getDeclaringClass() {
......@@ -122,10 +122,11 @@ void ArtMethod::setQuickCodeEntry(void *entry) {
}
void ArtMethod::setJniCodeEntry(void *entry) {
CastArtMethod::entryPointFromJNI->set(this, entry);
}
void ArtMethod::setInterpreterCodeEntry(void *entry) {
CastArtMethod::entryPointFormInterpreter->set(this, entry);
CastArtMethod::entryPointFromInterpreter->set(this, entry);
}
void ArtMethod::setDexCacheResolveList(void *list) {
......
......@@ -4,6 +4,7 @@
#include "../includes/cast_art_method.h"
#include "../includes/utils.h"
#include "../includes/never_call.h"
extern int SDK_INT;
......@@ -90,6 +91,11 @@ namespace SandHook {
class CastEntryPointFromJni : public IMember<art::mirror::ArtMethod, void *> {
protected:
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) {
return getParentSize() - 2 * BYTE_POINT;
} else {
......@@ -189,8 +195,8 @@ namespace SandHook {
accessFlag = new CastAccessFlag();
accessFlag->init(env, m1, size);
entryPointFormInterpreter = new CastEntryPointFormInterpreter();
entryPointFormInterpreter->init(env, m1, size);
entryPointFromInterpreter = new CastEntryPointFormInterpreter();
entryPointFromInterpreter->init(env, m1, size);
dexCacheResolvedMethods = new CastDexCacheResolvedMethods();
dexCacheResolvedMethods->init(env, m1, size);
......@@ -240,6 +246,9 @@ namespace SandHook {
genericJniStub = entryPointQuickCompiled->get(neverCallNative);
}
entryPointFromJNI = new CastEntryPointFromJni();
entryPointFromJNI->init(env, neverCallNative, size);
art::mirror::ArtMethod *neverCallStatic = reinterpret_cast<art::mirror::ArtMethod *>(env->GetStaticMethodID(
neverCallTestClass, "neverCallStatic", "()V"));
staticResolveStub = entryPointQuickCompiled->get(neverCallStatic);
......@@ -252,7 +261,8 @@ namespace SandHook {
Size CastArtMethod::size = 0;
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;
IMember<art::mirror::ArtMethod, uint32_t> *CastArtMethod::dexMethodIndex = nullptr;
IMember<art::mirror::ArtMethod, uint32_t> *CastArtMethod::accessFlag = nullptr;
......
......@@ -14,7 +14,8 @@ namespace SandHook {
public:
static Size size;
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 IMember<art::mirror::ArtMethod, uint32_t>* dexMethodIndex;
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 @@
#include "includes/log.h"
#include "includes/native_hook.h"
#include "includes/elf_util.h"
#include "includes/never_call.h"
#include <jni.h>
SandHook::TrampolineManager trampolineManager;
......@@ -345,6 +345,22 @@ Java_com_swift_sandhook_SandHook_disableDex2oatInline(JNIEnv *env, jclass type,
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"
JNIEXPORT void JNICALL
Java_com_swift_sandhook_ClassNeverCall_neverCallNative(JNIEnv *env, jobject instance) {
......@@ -456,6 +472,11 @@ static JNINativeMethod jniSandHook[] = {
"disableDex2oatInline",
"(Z)Z",
(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 {
public static native boolean disableDex2oatInline(boolean disableDex2oat);
public static native boolean setNativeEntry(Member origin, Member hook, long nativeEntry);
@FunctionalInterface
public interface HookModeCallBack {
int hookMode(Member originMethod);
......
......@@ -68,7 +68,7 @@ public class HookWrapper {
if (TextUtils.equals(hookEntity.isCtor() ? "<init>" : hookEntity.target.getName(), hookMethodBackup.value()) && samePars(classLoader, field, hookEntity.pars)) {
field.setAccessible(true);
if (hookEntity.backup == null) {
hookEntity.backup = BackupMethodStubs.getStubMethod();
hookEntity.backup = StubMethodsFactory.getStubMethod();
hookEntity.hookIsStub = true;
hookEntity.resolveDexCache = false;
}
......
package com.swift.sandhook.wrapper;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class BackupMethodStubs {
public class StubMethodsFactory {
final static int maxStub = 300;
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() {
while (curStub <= maxStub) {
try {
return BackupMethodStubs.class.getDeclaredMethod("stub" + curStub++);
return StubMethodsFactory.class.getDeclaredMethod("stub" + curStub++);
} 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() {}
......
......@@ -39,9 +39,4 @@ android {
dependencies {
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;
import com.swift.sandhook.SandHook;
import com.swift.sandhook.SandHookMethodResolver;
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.utils.DexLog;
......@@ -167,13 +167,13 @@ public class HookStubManager {
try {
if (is64Bit) {
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)
return null;
return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup);
} else {
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)
return null;
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