Skip to content

Commit

Permalink
Fix #5
Browse files Browse the repository at this point in the history
  • Loading branch information
canyie committed Feb 5, 2021
1 parent 169b2a1 commit 2d97346
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 14 deletions.
23 changes: 12 additions & 11 deletions core/src/main/cpp/pine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,17 +231,12 @@ jlong Pine_getAddress0(JNIEnv*, jclass, jlong thread, jobject o) {

#ifdef __aarch64__

void Pine_getArgsArm64(JNIEnv* env, jclass, jlong javaExtras, jlongArray javaArray, jlong sp) {
void Pine_getArgsArm64(JNIEnv* env, jclass, jlong javaExtras, jlongArray javaArray, jlong sp, jbooleanArray typeWides) {
auto extras = reinterpret_cast<Extras*>(javaExtras);
jint length = env->GetArrayLength(javaArray);
if (LIKELY(length > 0)) {
jlong* array = static_cast<jlong*>(env->GetPrimitiveArrayCritical(javaArray, nullptr));
if (UNLIKELY(!array)) {
constexpr const char* error_msg = "GetPrimitiveArrayCritical returned nullptr! javaArray is invalid?";
LOGF(error_msg);
env->FatalError(error_msg);
abort(); // Unreachable
}
jboolean* wides = static_cast<jboolean*>(env->GetPrimitiveArrayCritical(typeWides, nullptr));

do {
array[0] = reinterpret_cast<jlong>(extras->r1);
Expand All @@ -252,11 +247,17 @@ void Pine_getArgsArm64(JNIEnv* env, jclass, jlong javaExtras, jlongArray javaArr
if (length < 8) break; // x4-x7 will be restored in java

// get args from stack
uintptr_t current_on_stack = static_cast<uintptr_t>(sp + 8/*callee*/);
for (int i = 0;i < 7;i++) {
current_on_stack += wides[i] == JNI_TRUE ? 8 : 4;
}

for (int i = 7; i < length; i++) {
array[i] = *reinterpret_cast<jlong*>(sp + 8 /*callee*/ + 8 * i);
array[i] = *reinterpret_cast<jlong*>(current_on_stack);
current_on_stack += wides[i] == JNI_TRUE ? 8 : 4;
}
} while (false);

env->ReleasePrimitiveArrayCritical(typeWides, wides, 0);
env->ReleasePrimitiveArrayCritical(javaArray, array, JNI_ABORT);
}
extras->ReleaseLock();
Expand Down Expand Up @@ -381,7 +382,7 @@ static const struct {
{"disableHiddenApiPolicy0", "(ZZ)V"},
{"currentArtThread0", "()J"},
#ifdef __aarch64__
{"getArgsArm64", "(J[JJ)V"}
{"getArgsArm64", "(J[JJ[Z)V"}
#elif defined(__arm__)
{"getArgsArm32", "(I[IIZ)V"}
#elif defined(__i386__)
Expand Down Expand Up @@ -416,7 +417,7 @@ static const JNINativeMethod gMethods[] = {
{"currentArtThread0", "()J", (void*) Pine_currentArtThread0},

#ifdef __aarch64__
{"getArgsArm64", "(J[JJ)V", (void*) Pine_getArgsArm64}
{"getArgsArm64", "(J[JJ[Z)V", (void*) Pine_getArgsArm64}
#elif defined(__arm__)
{"getArgsArm32", "(I[IIZ)V", (void*) Pine_getArgsArm32}
#elif defined(__i386__)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/top/canyie/pine/Pine.java
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ private static native Method hook0(long thread, Class<?> declaring, Member targe

public static native void getArgsArm32(int extras, int[] out, int sp, boolean skipR1);

public static native void getArgsArm64(long extras, long[] out, long sp);
public static native void getArgsArm64(long extras, long[] out, long sp, boolean[] typeWides);

public static native void getArgsX86(int extras, int[] out, int ebx);

Expand Down
25 changes: 23 additions & 2 deletions core/src/main/java/top/canyie/pine/entry/Arm64Entry.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* @author canyie
*/
public final class Arm64Entry {
private static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
private static final long[] EMPTY_LONG_ARRAY = new long[0];
private Arm64Entry() {
}
Expand Down Expand Up @@ -116,7 +117,8 @@ private static Object handleBridge(long artMethod, long extras, long sp,
throw new AssertionError("Unknown primitive type: " + paramType);
}
} else {
value = Pine.getObject(thread, argsAsLongs[index]);
// In art, object address is actually 32 bits
value = Pine.getObject(thread, argsAsLongs[index] & 0xffffffffL);
}
args[i] = value;
index++;
Expand All @@ -131,8 +133,27 @@ private static Object handleBridge(long artMethod, long extras, long sp,
private static long[] getArgsAsLongs(Pine.HookRecord hookRecord, long extras, long sp,
long x4, long x5, long x6, long x7) {
int length = (hookRecord.isStatic ? 0 : 1 /*this*/) + hookRecord.paramNumber;
boolean[] typeWides;
if (length != 0) {
typeWides = new boolean[length];
if (hookRecord.isStatic) {
for (int i = 0; i < length;i++) {
Class<?> type = hookRecord.paramTypes[i];
typeWides[i] = type == long.class || type == double.class;
}
} else {
typeWides[0] = false; // this object is a reference, always 32-bit
for (int i = 1; i < length;i++) {
Class<?> type = hookRecord.paramTypes[i - 1];
typeWides[i] = type == long.class || type == double.class;
}
}
} else {
typeWides = EMPTY_BOOLEAN_ARRAY;
}

long[] array = length != 0 ? new long[length] : EMPTY_LONG_ARRAY;
Pine.getArgsArm64(extras, array, sp);
Pine.getArgsArm64(extras, array, sp, typeWides);

do {
// x1-x3 are restored in Pine.getArgs64
Expand Down

0 comments on commit 2d97346

Please sign in to comment.