Commit c9260188 authored by swift_gan's avatar swift_gan

done demo

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