Commit c9260188 authored by swift_gan's avatar swift_gan

done demo

parent 8c3f0c1d
...@@ -69,7 +69,11 @@ namespace SandHook { ...@@ -69,7 +69,11 @@ namespace SandHook {
class CastAccessFlag : public IMember<art::mirror::ArtMethod, uint32_t> { class CastAccessFlag : public IMember<art::mirror::ArtMethod, uint32_t> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override { Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override {
int offset = findOffset(&p, getParentSize(), 2, (uint32_t)524313); uint32_t accessFlag = getIntFromJava(jniEnv, "com/swift/sandhook/SandHook", "testAccessFlag");
if (accessFlag == 0) {
accessFlag = 524313;
}
int offset = findOffset(&p, getParentSize(), 2, accessFlag);
if (offset < 0) if (offset < 0)
return getParentSize() + 1; return getParentSize() + 1;
else else
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
#define SANDHOOK_UTILS_H #define SANDHOOK_UTILS_H
#include <stdlib.h> #include <stdlib.h>
#include <sys/mman.h>
#include "jni.h" #include "jni.h"
#include <unistd.h>
template<typename T> template<typename T>
int findOffset(void *start, size_t len,size_t step,T value) { int findOffset(void *start, size_t len,size_t step,T value) {
...@@ -87,6 +89,17 @@ jint getIntFromJava(JNIEnv* env, char* className, char* fieldName) { ...@@ -87,6 +89,17 @@ jint getIntFromJava(JNIEnv* env, char* className, char* fieldName) {
return env -> GetStaticIntField(clazz, id); return env -> GetStaticIntField(clazz, id);
} }
bool munprotect(size_t addr, size_t len) {
long pagesize = sysconf(_SC_PAGESIZE);
unsigned alignment = (unsigned)((unsigned long long)addr % pagesize);
int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len),
PROT_READ | PROT_WRITE | PROT_EXEC);
if (i == -1) {
return false;
}
return true;
}
#endif //SANDHOOK_UTILS_H #endif //SANDHOOK_UTILS_H
...@@ -2,12 +2,30 @@ ...@@ -2,12 +2,30 @@
#include "casts/cast_art_method.h" #include "casts/cast_art_method.h"
#include "./trampoline/trampoline_manager.h" #include "./trampoline/trampoline_manager.h"
SandHook::TrampolineManager trampolineManager;
extern "C" extern "C"
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk) { Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk) {
// TODO // TODO
SandHook::CastArtMethod::init(env, sdk); SandHook::CastArtMethod::init(env, sdk);
trampolineManager.init(SandHook::CastArtMethod::entryPointQuickCompiled->getOffset());
return JNI_TRUE;
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject originMethod,
jobject hookMethod, jobject backupMethod) {
// TODO
art::mirror::ArtMethod* origin = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(originMethod));
art::mirror::ArtMethod* hook = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(hookMethod));
art::mirror::ArtMethod* backup = backupMethod == NULL ? nullptr : reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(backupMethod));
trampolineManager.installInlineTrampoline(origin, hook, backup);
return JNI_TRUE; return JNI_TRUE;
......
...@@ -88,7 +88,7 @@ namespace SandHook { ...@@ -88,7 +88,7 @@ namespace SandHook {
memcpy(code, tempCode, codeLen); memcpy(code, tempCode, codeLen);
} }
void codeCopy(Code src, Size targetOffset, Size len) { void codeCopy(Code src, Size targetOffset, Size len) {
memcpy(code + targetOffset, src, len); memcpy(reinterpret_cast<void*>((Size)code + targetOffset), src, len);
} }
void clone(Code dest) { void clone(Code dest) {
memcpy(dest, code, codeLen); memcpy(dest, code, codeLen);
......
...@@ -77,6 +77,7 @@ namespace SandHook { ...@@ -77,6 +77,7 @@ namespace SandHook {
ReplacementHookTrampoline* callOriginTrampoline = nullptr; ReplacementHookTrampoline* callOriginTrampoline = nullptr;
Code inlineHookTrampolineSpace; Code inlineHookTrampolineSpace;
Code callOriginTrampolineSpace; Code callOriginTrampolineSpace;
Code originEntry;
//生成二段跳板 //生成二段跳板
inlineHookTrampoline = new InlineHookTrampoline; inlineHookTrampoline = new InlineHookTrampoline;
...@@ -94,12 +95,16 @@ namespace SandHook { ...@@ -94,12 +95,16 @@ namespace SandHook {
//注入 EntryCode //注入 EntryCode
directJumpTrampoline = new DirectJumpTrampoline(); directJumpTrampoline = new DirectJumpTrampoline();
directJumpTrampoline->init(); directJumpTrampoline->init();
directJumpTrampoline->setExecuteSpace(getEntryCode(originMethod)); originEntry = getEntryCode(originMethod);
if (!memUnprotect(reinterpret_cast<Size>(originEntry), directJumpTrampoline->getCodeLen())) {
goto label_error;
}
directJumpTrampoline->setExecuteSpace(originEntry);
directJumpTrampoline->setJumpTarget(inlineHookTrampoline->getCode()); directJumpTrampoline->setJumpTarget(inlineHookTrampoline->getCode());
hookTrampoline->inlineJump = directJumpTrampoline; hookTrampoline->inlineJump = directJumpTrampoline;
//备份原始方法 //备份原始方法
if (backupMethod) { if (backupMethod != nullptr) {
callOriginTrampoline = new ReplacementHookTrampoline(); callOriginTrampoline = new ReplacementHookTrampoline();
callOriginTrampoline->init(); callOriginTrampoline->init();
callOriginTrampolineSpace = allocExecuteSpace(callOriginTrampoline->getCodeLen()); callOriginTrampolineSpace = allocExecuteSpace(callOriginTrampoline->getCodeLen());
......
...@@ -11,10 +11,11 @@ ...@@ -11,10 +11,11 @@
#include "../utils/lock.h" #include "../utils/lock.h"
#include <sys/mman.h> #include <sys/mman.h>
#include "../casts/art/art.h" #include "../casts/art/art.h"
#include <unistd.h>
namespace SandHook { namespace SandHook {
#define MMAP_PAGE_SIZE 4 * 1024 #define MMAP_PAGE_SIZE sysconf(_SC_PAGESIZE)
using namespace art; using namespace art;
...@@ -46,9 +47,20 @@ namespace SandHook { ...@@ -46,9 +47,20 @@ namespace SandHook {
return trampolines[method]; return trampolines[method];
} }
Code getEntryCode(mirror::ArtMethod* method) { bool memUnprotect(Size addr, Size len) {
Size* pEntryAddress = reinterpret_cast<Size*>(method + quickCompileOffset); long pagesize = sysconf(_SC_PAGESIZE);
Code entryCode = reinterpret_cast<Code>(*pEntryAddress); unsigned alignment = (unsigned)((unsigned long long)addr % pagesize);
int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len),
PROT_READ | PROT_WRITE | PROT_EXEC);
if (i == -1) {
return false;
}
return true;
}
Code getEntryCode(void* method) {
Code entryCode = *reinterpret_cast<Code*>((Size)method + quickCompileOffset);
return entryCode;
} }
...@@ -56,7 +68,7 @@ namespace SandHook { ...@@ -56,7 +68,7 @@ namespace SandHook {
Size quickCompileOffset; Size quickCompileOffset;
std::map<mirror::ArtMethod*,HookTrampoline*> trampolines = {}; std::map<mirror::ArtMethod*,HookTrampoline*> trampolines;
std::list<Code> executeSpaceList = std::list<Code>(); std::list<Code> executeSpaceList = std::list<Code>();
std::mutex allocSpaceLock; std::mutex allocSpaceLock;
std::mutex installLock; std::mutex installLock;
......
package com.swift.sandhook; package com.swift.sandhook;
import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import com.swift.sandhook.wrapper.HookClass; import com.swift.sandhook.wrapper.HookClass;
import com.swift.sandhook.wrapper.HookMethod; import com.swift.sandhook.wrapper.HookMethod;
import com.swift.sandhook.wrapper.HookMethodBackup; import com.swift.sandhook.wrapper.HookMethodBackup;
import com.swift.sandhook.wrapper.MethodParams; import com.swift.sandhook.wrapper.MethodParams;
@HookClass(Activity.class) @HookClass(MainActivity.class)
public class ActivityHooker { public class ActivityHooker {
@HookMethod("onCreate") @HookMethod("methodBeHooked")
@MethodParams(Bundle.class) @MethodParams(Bundle.class)
public static void onCreate(Activity thiz, Bundle bundle) { public static void onCreate(MainActivity thiz, Bundle bundle) {
Log.e("ActivityHooker", "hooked success " + thiz);
onCreateBackup(thiz, bundle); onCreateBackup(thiz, bundle);
} }
@HookMethodBackup("onCreate") @HookMethodBackup("methodBeHooked")
@MethodParams(Bundle.class) @MethodParams(Bundle.class)
public static void onCreateBackup(Activity thiz, Bundle bundle) { public static void onCreateBackup(MainActivity thiz, Bundle bundle) {
} }
......
...@@ -38,7 +38,7 @@ public class MainActivity extends AppCompatActivity { ...@@ -38,7 +38,7 @@ public class MainActivity extends AppCompatActivity {
} }
}); });
SandHook.init(); methodBeHooked(savedInstanceState);
try { try {
HookWrapper.addHookClass(ActivityHooker.class); HookWrapper.addHookClass(ActivityHooker.class);
...@@ -46,6 +46,8 @@ public class MainActivity extends AppCompatActivity { ...@@ -46,6 +46,8 @@ public class MainActivity extends AppCompatActivity {
e.printStackTrace(); e.printStackTrace();
} }
methodBeHooked(savedInstanceState);
// Example of a call to a native method // Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text); TextView tv = (TextView) findViewById(R.id.sample_text);
...@@ -69,6 +71,12 @@ public class MainActivity extends AppCompatActivity { ...@@ -69,6 +71,12 @@ public class MainActivity extends AppCompatActivity {
return true; return true;
} }
public void methodBeHooked(Bundle bundle) {
int a = 1 + 2;
int b = a + 3;
Log.e("gy", "not hooked" + b + bundle);
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will // Handle action bar item clicks here. The action bar will
......
...@@ -4,7 +4,11 @@ import android.os.Build; ...@@ -4,7 +4,11 @@ import android.os.Build;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.wrapper.HookWrapper;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
public class SandHook { public class SandHook {
...@@ -20,17 +24,21 @@ public class SandHook { ...@@ -20,17 +24,21 @@ public class SandHook {
static { static {
System.loadLibrary("native-lib"); System.loadLibrary("native-lib");
init();
} }
private static boolean init() {
public static boolean init() {
initTestOffset(); initTestOffset();
SandHookMethodResolver.init(); SandHookMethodResolver.init();
return initNative(Build.VERSION.SDK_INT); return initNative(Build.VERSION.SDK_INT);
} }
public static void hook(@NonNull Method target, @NonNull Method hook, @Nullable Method backup) { public static void addHookClass(Class... hookWrapperClass) throws HookErrorException {
HookWrapper.addHookClass(hookWrapperClass);
}
public static void hook(@NonNull Member target, @NonNull Method hook, @Nullable Method backup) {
hookMethod(target, hook, backup);
} }
...@@ -104,4 +112,6 @@ public class SandHook { ...@@ -104,4 +112,6 @@ public class SandHook {
private static native boolean initNative(int sdk); private static native boolean initNative(int sdk);
private static native boolean hookMethod(Member originMethod, Method hookMethod, Method backupMethod);
} }
...@@ -24,7 +24,7 @@ public class HookWrapper { ...@@ -24,7 +24,7 @@ public class HookWrapper {
Map<Member,HookEntity> hookEntityMap = getHookMethods(targetHookClass, clazz); Map<Member,HookEntity> hookEntityMap = getHookMethods(targetHookClass, clazz);
for (HookEntity entity:hookEntityMap.values()) { for (HookEntity entity:hookEntityMap.values()) {
if (entity.target != null && entity.hook != null) { if (entity.target != null && entity.hook != null) {
SandHook.hook(entity.target, entity.hook, entity.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