Skip to content

Commit

Permalink
fix YAHFA issue #37
Browse files Browse the repository at this point in the history
  • Loading branch information
rk700 committed Aug 21, 2017
1 parent 425bc8a commit fca5dcb
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
30 changes: 20 additions & 10 deletions VirtualApp/YAHFA/src/main/jni/HookMain.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "jni.h"
#include <string.h>
#include <sys/mman.h>
#include <stdlib.h>

#include "common.h"
#include "env.h"
Expand All @@ -24,37 +25,33 @@ static inline uint64_t read64(void *addr) {
void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVersion) {
int i;
SDKVersion = sdkVersion;
LOGI("init to SDK %d", sdkVersion);
switch(sdkVersion) {
case ANDROID_N2:
case ANDROID_N:
LOGI("init to SDK %d", sdkVersion);
OFFSET_ArtMehod_in_Object = 0;
OFFSET_hotness_count_in_ArtMethod = 4*4+2 ; // sizeof(GcRoot<mirror::Class>) = 4

OFFSET_hotness_count_in_ArtMethod = 4*4+2; // sizeof(GcRoot<mirror::Class>) = 4
// ptr_sized_fields_ is rounded up to pointer_size in ArtMethod
OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod =
roundUpToPtrSize(4*4+2*2) + pointer_size*3;

ArtMethodSize = roundUpToPtrSize(4*4+2*2)+pointer_size*4;
break;
case ANDROID_M:
LOGI("init to SDK %d", sdkVersion);
OFFSET_ArtMehod_in_Object = 0;
OFFSET_entry_point_from_interpreter_in_ArtMethod = roundUpToPtrSize(4*7);
OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod =
OFFSET_entry_point_from_interpreter_in_ArtMethod + pointer_size*2;
ArtMethodSize = roundUpToPtrSize(4*7)+pointer_size*3;
break;
case ANDROID_L2:
LOGI("init to SDK %d", sdkVersion);
OFFSET_ArtMehod_in_Object = 4*2;
OFFSET_entry_point_from_interpreter_in_ArtMethod = roundUpToPtrSize(OFFSET_ArtMehod_in_Object+4*7);
OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod =
OFFSET_entry_point_from_interpreter_in_ArtMethod+pointer_size*2;
ArtMethodSize = OFFSET_entry_point_from_interpreter_in_ArtMethod+pointer_size*3;
break;
case ANDROID_L:
LOGI("init to SDK %d", sdkVersion);
OFFSET_ArtMehod_in_Object = 4*2;
OFFSET_entry_point_from_interpreter_in_ArtMethod = OFFSET_ArtMehod_in_Object+4*4;
OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod =
Expand All @@ -81,10 +78,10 @@ void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVers
if(SDKVersion < ANDROID_N) { // do not set hotness_count before N
memcpy(trampoline2+4, "\x1f\x20\x03\xd5", 4); // nop
if(SDKVersion == ANDROID_L2) {
memcpy(trampoline1+4, "\x10\x1c\x40\xf9", 4); //101c40f9 ; ldr x16, [x0, #56]
memcpy(trampoline1+4, "\x10\x1c\x40\xf9", 4); //101c40f9 ; ldr x16, [x0, #56] set entry point offset
}
else if(SDKVersion == ANDROID_L) {
memcpy(trampoline1+4, "\x10\x14\x40\xf9", 4); //101440f9 ; ldr x16, [x0, #40]
memcpy(trampoline1+4, "\x10\x14\x40\xf9", 4); //101440f9 ; ldr x16, [x0, #40] set entry point offset
}
}
#endif
Expand All @@ -107,9 +104,22 @@ static int doBackupAndHook(void *originMethod, void *hookMethod, void *backupMet
LOGW("backup method is null");
}
else { //do method backup
// have to copy the whole origin ArtMethod here
// if the origin method calls other methods which are to be resolved
// then ToDexPC would be invoked for the caller(origin method)
// in which case ToDexPC would use the entrypoint as a base for mapping pc to dex offset
// so any changes to the origin method's entrypoint would result in a wrong dex offset
// and artQuickResolutionTrampoline would fail for methods called by the origin method
void *originMethodCopy = malloc(ArtMethodSize);
if(!originMethodCopy) {
LOGE("malloc failed for copying origin method");
return 1;
}
memcpy(originMethodCopy, originMethod, ArtMethodSize);

void *realEntryPoint = (void *)readAddr((char *) originMethod +
OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod);
void *newEntryPoint = genTrampoline2(originMethod, realEntryPoint);
void *newEntryPoint = genTrampoline2(originMethodCopy, realEntryPoint);
if(newEntryPoint) {
memcpy((char *) backupMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod,
&newEntryPoint, pointer_size);
Expand Down Expand Up @@ -174,7 +184,7 @@ void Java_lab_galaxy_yahfa_HookMain_findAndBackupAndHook(JNIEnv *env, jclass cla

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

Expand Down
4 changes: 2 additions & 2 deletions VirtualApp/YAHFA/src/main/jni/trampoline.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ static unsigned int t1Size = roundUpToPtrSize(sizeof(trampoline1));
#endif

// trampoline2:
// 1. set eax/r0/x0 to the origin ArtMethod addr,
// 2. clear hotness_count of the origin ArtMethod(only after Android N)
// 1.1 set eax/r0/x0 to the copy of origin ArtMethod addr,
// 2. clear hotness_count of the copy origin ArtMethod(only after Android N)
// 3. jump into origin's real entry point
#if defined(__i386__)
// b8 21 43 65 87 ; mov eax, 0x87654321
Expand Down

0 comments on commit fca5dcb

Please sign in to comment.