Skip to content

Commit

Permalink
update YAHFA
Browse files Browse the repository at this point in the history
  • Loading branch information
rk700 committed Jul 17, 2017
1 parent 9ac0b6e commit ad36757
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 12 deletions.
20 changes: 18 additions & 2 deletions VirtualApp/YAHFA/src/main/java/lab/galaxy/yahfa/HookMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;

import dalvik.system.DexClassLoader;

Expand All @@ -14,6 +16,7 @@

public class HookMain {
private static final String TAG = "YAHFA";
private static List<Class<?>> hookInfoClasses = new LinkedList<>();

static {
System.loadLibrary("yahfa");
Expand All @@ -27,20 +30,27 @@ public void doHookDefault(ClassLoader patchClassLoader, ClassLoader originClassL
for(String hookItemName : hookItemNames) {
doHookItemDefault(patchClassLoader, hookItemName, originClassLoader);
}
hookInfoClasses.add(hookInfoClass);
}
catch (Exception e) {
e.printStackTrace();
}
}

public void doHookItemDefault(ClassLoader patchClassLoader, String hookItemName, ClassLoader originClassLoader) {
private void doHookItemDefault(ClassLoader patchClassLoader, String hookItemName, ClassLoader originClassLoader) {
try {
Log.i(TAG, "Start hooking with item "+hookItemName);
Class<?> hookItem = Class.forName(hookItemName, true, patchClassLoader);

String className = (String)hookItem.getField("className").get(null);
String methodName = (String)hookItem.getField("methodName").get(null);
String methodSig = (String)hookItem.getField("methodSig").get(null);
int isStatic = 0;
try {
isStatic = (int) hookItem.getField("isStatic").get(null);
}
catch (NoSuchFieldException e) {
}

if(className == null || className.equals("")) {
Log.w(TAG, "No target class. Skipping...");
Expand Down Expand Up @@ -72,8 +82,14 @@ public void doHookItemDefault(ClassLoader patchClassLoader, String hookItemName,
}


public void findAndBackupAndHook(Class targetClass, String methodName, String methodSig,
Method hook, Method backup) {
findAndBackupAndHook(targetClass, methodName, methodSig, 0, hook, backup);
}

public native void findAndBackupAndHook(Class targetClass, String methodName, String methodSig,
Method hook, Method backup);
int isStatic, // 1: static, -1: virtual, 0: unset(try both)
Method hook, Method backup);

private static native void init(int SDK_version);
}
30 changes: 20 additions & 10 deletions VirtualApp/YAHFA/src/main/jni/HookMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ static int OFFSET_entry_point_from_interpreter_in_ArtMethod;
static int OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod;
static int OFFSET_hotness_count_in_ArtMethod;
static int OFFSET_ArtMehod_in_Object;
static size_t ArtMethodSize;
static int ArtMethodSize;

static inline uint32_t read32(void *addr) {
return *((uint32_t *)addr);
Expand Down Expand Up @@ -71,7 +71,7 @@ void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVers
memset(trampoline2+5, '\x90', 6);
}
#elif defined(__arm__)
trampoline1[4] = OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod;
trampoline1[4] = (unsigned char)OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod;
if(SDKVersion < ANDROID_N) { // do not set hotness_count before N
for(i=4; i<=16; i+=4) {
memcpy(trampoline2+i, "\x00\x00\xa0\xe1", 4); // mov r0, r0
Expand Down Expand Up @@ -107,7 +107,7 @@ static int doBackupAndHook(void *originMethod, void *hookMethod, void *backupMet
LOGW("backup method is null");
}
else { //do method backup
void *realEntryPoint = readAddr((char *) originMethod +
void *realEntryPoint = (void *)readAddr((char *) originMethod +
OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod);
void *newEntryPoint = genTrampoline2(originMethod, realEntryPoint);
if(newEntryPoint) {
Expand Down Expand Up @@ -148,7 +148,7 @@ static int doBackupAndHook(void *originMethod, void *hookMethod, void *backupMet
}

void Java_lab_galaxy_yahfa_HookMain_findAndBackupAndHook(JNIEnv *env, jclass clazz,
jclass targetClass, jstring methodName, jstring methodSig, jobject hook, jobject backup) {
jclass targetClass, jstring methodName, jstring methodSig, jint isStatic, jobject hook, jobject backup) {
if(!methodName || !methodSig) {
LOGE("empty method name or signature");
return;
Expand All @@ -165,16 +165,26 @@ void Java_lab_galaxy_yahfa_HookMain_findAndBackupAndHook(JNIEnv *env, jclass cla
LOGE("Not initialized");
goto end;
}
targetMethod = (void *)(*env)->GetMethodID(env, targetClass, c_methodName, c_methodSig);
if((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env); //cannot find non-static method
if(isStatic == -1) { // non-static
targetMethod = (void *) (*env)->GetMethodID(env, targetClass, c_methodName, c_methodSig);
}
else if(isStatic == 1) { // static
targetMethod = (void *)(*env)->GetStaticMethodID(env, targetClass, c_methodName, c_methodSig);
}
else {
targetMethod = (void *) (*env)->GetMethodID(env, targetClass, c_methodName, c_methodSig);
if((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env); //cannot find static method
LOGE("Cannot find target method %s%s", c_methodName, c_methodSig);
goto end;
(*env)->ExceptionClear(env); //cannot find non-static method, try finding static method
targetMethod = (void *)(*env)->GetStaticMethodID(env, targetClass, c_methodName, c_methodSig);
}
}

if((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env);
LOGE("Cannot find target method %s%s", c_methodName, c_methodSig);
goto end;
}

if(!doBackupAndHook(targetMethod, (void *)(*env)->FromReflectedMethod(env, hook),
backup==NULL ? NULL : (void *)(*env)->FromReflectedMethod(env, backup))) {
(*env)->NewGlobalRef(env, hook); // keep a global ref so that the hook method would not be GCed
Expand Down

0 comments on commit ad36757

Please sign in to comment.