Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion library/src/main/cpp/epic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,25 @@ jlong epic_malloc(JNIEnv *env, jclass, jint size) {
return (jlong) ptr;
}

//add by gzh
jlong malloc_internal(int size) {
size_t length = sizeof(void *) * size;
void *ptr = malloc(length);
LOGV("malloc :%d of memory at: %p", (int) length, ptr);
return (jlong) ptr;
}

jlong epic_malloc_address(JNIEnv *env, jclass) {
LOGV("epic_malloc_address %p",malloc_internal);
return jlong(malloc_internal);
}

void epic_free(JNIEnv *env, jclass, jlong addr) {
LOGV("epic_free :%p",(void *)addr);
free((void*)addr);
}

//add by gzh end

jobject epic_getobject(JNIEnv *env, jclass clazz, jlong self, jlong address) {
JavaVM *vm;
Expand Down Expand Up @@ -382,7 +401,9 @@ static JNINativeMethod dexposedMethods[] = {
{"startJit", "(J)V", (void *) epic_startJit},
{"disableMovingGc", "(I)V", (void *) epic_disableMovingGc},
{"activateNative", "(JJJJ[B)Z", (void *) epic_activate},
{"isGetObjectAvailable", "()Z", (void *) epic_isGetObjectAvaliable}
{"isGetObjectAvailable", "()Z", (void *) epic_isGetObjectAvaliable},
{"mallocAdress", "()J", (void*) epic_malloc_address},//add by gzh
{"free", "(J)V", (void*) epic_free}//add by gzh
};

static int registerNativeMethods(JNIEnv *env, const char *className,
Expand Down
6 changes: 6 additions & 0 deletions library/src/main/java/me/weishu/epic/art/EpicNative.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ public final class EpicNative {

public static native long malloc(int sizeOfPtr);

//add by gzh
public static native long mallocAdress();

public static native void free(long address);
//add by gzh end

public static native Object getObjectNative(long self, long address);

private static native boolean isGetObjectAvailable();
Expand Down
6 changes: 4 additions & 2 deletions library/src/main/java/me/weishu/epic/art/Trampoline.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,10 @@ private byte[] createTrampoline(ArtMethod source){
long targetAddress = target.getAddress();
long targetEntry = target.getEntryPointFromQuickCompiledCode();
long sourceAddress = source.getAddress();
long structAddress = EpicNative.malloc(4);

//add by gzh
// long structAddress = EpicNative.malloc(4);//这里有个bug,由于这个地址是固定的,因此当多个线程并发的调用某一个被hook的方法时,就会造成方法参数被覆盖的问题
long structAddress = EpicNative.mallocAdress();//这里传入一个函数指针,而不是结构体地址
//add by gzh end
Logger.d(TAG, "targetAddress:"+ Debug.longHex(targetAddress));
Logger.d(TAG, "sourceAddress:"+ Debug.longHex(sourceAddress));
Logger.d(TAG, "targetEntry:"+ Debug.longHex(targetEntry));
Expand Down
146 changes: 118 additions & 28 deletions library/src/main/java/me/weishu/epic/art/arch/Arm64.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,36 +39,125 @@ public byte[] createDirectJump(long targetAddress) {

@Override
public byte[] createBridgeJump(long targetAddress, long targetEntry, long srcAddress, long structAddress) {

/* delete by gzh begin
// byte[] instructions = new byte[]{
// 0x1f, 0x20, 0x03, (byte) 0xd5, // nop
// 0x69, 0x02, 0x00, 0x58, // ldr x9, source_method
// 0x1f, 0x00, 0x09, (byte) 0xeb, // cmp x0, x9
// (byte) 0xa1, 0x02, 0x00, 0x54, // bne 5f
// (byte) 0x80, 0x01, 0x00, 0x58, // ldr x0, target_method
//
// 0x29, 0x02, 0x00, 0x58, // ldr x9, struct
// (byte) 0xea, 0x03, 0x00, (byte) 0x91, // mov x10, sp
//
// 0x2a, 0x01, 0x00, (byte) 0xf9, // str x10, [x9, #0]
// 0x22, 0x05, 0x00, (byte) 0xf9, // str x2, [x9, #8]
//
// 0x23, 0x09, 0x00, (byte) 0xf9, // str x3, [x9, #16]
// (byte) 0xe3, 0x03, 0x09, (byte) 0xaa, // mov x3, x9
// 0x22, 0x01, 0x00, 0x58, // ldr x2, source_method
// 0x22, 0x0d, 0x00, (byte) 0xf9, // str x2, [x9, #24]
// (byte) 0xe2, 0x03, 0x13, (byte) 0xaa, // mov x2, x19
// (byte) 0x89, 0x00, 0x00, 0x58, // ldr x9, target_method_entry
// 0x20, 0x01, 0x1f, (byte) 0xd6, // br x9
//
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // target_method_address
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // target_method_entry
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // source_method
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // struct
//
// };
// delete by gzh end
*/
/*
ldr x9, source_method
cmp x0, x9
bne 5f
//add by gzh begin
sub sp, sp, #80 //open stack space
stp x0, x1, [sp] //save x0-x1
stp x2, x3, [sp,#16] //save x2-x3
stp x4, x5, [sp,#32] //save x4-x5
stp x6, x7, [sp,#48] //save x6-x7
stp x29, x30, [sp,#64] //save lr
mov x0, #4
ldr x4, struct //call malloc
blr x4
mov x9, x0
ldp x0, x1, [sp] //restore x0-x1
ldp x2, x3, [sp,#16] //restore x2-x3
ldp x4, x5, [sp,#32] //restore x4-x5
ldp x6, x7, [sp,#48] //restore x6-x7
ldp x29, x30, [sp,#64] //restore lr
add sp, sp, #80 //free stack space
//add by gzh end
ldr x0, target_method_address
//ldr x9, struct //modify by gzh
mov x10, sp
str x10, [x9, #0]
str x2, [x9, #8]
str x3, [x9, #16]
mov x3, x9
ldr x2, source_method
str x2, [x9, #24]
mov x2, x19
ldr x9, target_method_entry
br x9
target_method_address:
.long 0
.long 0
target_method_entry:
.long 0
.long 0
source_method:
.long 0
.long 0
struct:
.long 0
.long 0
5:
* */
byte[] instructions = new byte[]{
0x1f, 0x20, 0x03, (byte) 0xd5, // nop
0x69, 0x02, 0x00, 0x58, // ldr x9, source_method
0x1f, 0x00, 0x09, (byte) 0xeb, // cmp x0, x9
(byte) 0xa1, 0x02, 0x00, 0x54, // bne 5f
(byte) 0x80, 0x01, 0x00, 0x58, // ldr x0, target_method

0x29, 0x02, 0x00, 0x58, // ldr x9, struct
(byte) 0xea, 0x03, 0x00, (byte) 0x91, // mov x10, sp

0x2a, 0x01, 0x00, (byte) 0xf9, // str x10, [x9, #0]
0x22, 0x05, 0x00, (byte) 0xf9, // str x2, [x9, #8]

0x23, 0x09, 0x00, (byte) 0xf9, // str x3, [x9, #16]
(byte) 0xe3, 0x03, 0x09, (byte) 0xaa, // mov x3, x9
0x22, 0x01, 0x00, 0x58, // ldr x2, source_method
0x22, 0x0d, 0x00, (byte) 0xf9, // str x2, [x9, #24]
(byte) 0xe2, 0x03, 0x13, (byte) 0xaa, // mov x2, x19
(byte) 0x89, 0x00, 0x00, 0x58, // ldr x9, target_method_entry
0x20, 0x01, 0x1f, (byte) 0xd6, // br x9

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // target_method_address
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // target_method_entry
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // source_method
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // struct

0x49, 0x04, 0x00, 0x58,
0x1f, 0x00, 0x09, (byte)0xeb,
(byte)0x81, 0x04, 0x00, 0x54,
(byte)0xff, 0x43, 0x01, (byte)0xd1,
(byte)0xe0, 0x07, 0x00, (byte)0xa9,
(byte)0xe2, 0x0f, 0x01, (byte)0xa9,
(byte)0xe4, 0x17, 0x02, (byte)0xa9,
(byte)0xe6, 0x1f, 0x03, (byte)0xa9,
(byte)0xfd, 0x7b, 0x04, (byte)0xa9,
(byte)0x80, 0x00, (byte)0x80, (byte)0xd2,
0x44, 0x03, 0x00, 0x58,
(byte)0x80, 0x00, 0x3f, (byte)0xd6,
(byte)0xe9, 0x03, 0x00, (byte)0xaa,
(byte)0xe0, 0x07, 0x40, (byte)0xa9,
(byte)0xe2, 0x0f, 0x41, (byte)0xa9,
(byte)0xe4, 0x17, 0x42, (byte)0xa9,
(byte)0xe6, 0x1f, 0x43, (byte)0xa9,
(byte)0xfd, 0x7b, 0x44, (byte)0xa9,
(byte)0xff, 0x43, 0x01, (byte)0x91,
0x60, 0x01, 0x00, 0x58,
(byte)0xea, 0x03, 0x00, (byte)0x91,
0x2a, 0x01, 0x00, (byte)0xf9,
0x22, 0x05, 0x00, (byte)0xf9,
0x23, 0x09, 0x00, (byte)0xf9,
(byte)0xe3, 0x03, 0x09, (byte)0xaa,
0x22, 0x01, 0x00, 0x58,
0x22, 0x0d, 0x00, (byte)0xf9,
(byte)0xe2, 0x03, 0x13, (byte)0xaa,
(byte)0x89, 0x00, 0x00, 0x58,
0x20, 0x01, 0x1f, (byte)0xd6,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};


writeLong(targetAddress, ByteOrder.LITTLE_ENDIAN, instructions,
instructions.length - 32);
writeLong(targetEntry, ByteOrder.LITTLE_ENDIAN, instructions,
Expand All @@ -83,7 +172,8 @@ public byte[] createBridgeJump(long targetAddress, long targetEntry, long srcAdd

@Override
public int sizeOfBridgeJump() {
return 24 * 4;
// return 24 * 4;
return 38 * 4;//add by gzh
}


Expand Down
61 changes: 58 additions & 3 deletions library/src/main/java/me/weishu/epic/art/arch/Thumb2.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public byte[] createBridgeJump(long targetAddress, long targetEntry, long srcAdd
// ByteOrder.LITTLE_ENDIAN, instructions, instructions.length - 8);
// writeInt((int) srcAddress, ByteOrder.LITTLE_ENDIAN, instructions,
// instructions.length - 4);

//add by gzh
/*
byte[] instructions = new byte[]{

(byte) 0xdf, (byte) 0xf8, (byte) 0x30, (byte) 0xc0, // ldr ip, [pc, #48] ip = source method address
Expand All @@ -91,7 +92,60 @@ public byte[] createBridgeJump(long targetAddress, long targetEntry, long srcAdd
0x0, 0x0, 0x0, 0x0, // struct address (sp, r1, r2)
// 1:
};

*/
//add by gzh
/*
ldr ip, src_method_address //ip = source method address
cmp r0, ip //if r0 != ip
bne.w 1f //jump label 1:
//ldr r0, target_method_pos_x //r0 = target_method_address
push {r0-r4,lr} //save r0-r4,lr
mov r0, #4
ldr r4, struct_address //call malloc
blx r4
mov ip, r0
pop {r0-r4,lr} //restore r0-r4,lr
ldr r0, target_method_pos_x
//ldr ip, struct_address //ip = struct address
str sp, [ip, #0]
str r2, [ip, #4]
str r3, [ip, #8]
mov r3, ip
ldr r2, src_method_address //r2 = source_method_address
str r2, [ip, #12]
mov r2, r9
mov r2, r9
ldr pc, [pc, #4]
target_method_pos_x:
.long 0
target_method_address:
.long 0
src_method_address:
.long 0
struct_address:
.long 0
1:
* */
byte[] instructions = new byte[]{
(byte)0xdf, (byte)0xf8, 0x3c, (byte)0xc0,
0x60, 0x45, 0x40, (byte)0xf0,
0x1f, (byte)0x80, 0x1f, (byte)0xb5,
0x4f, (byte)0xf0, 0x04, 0x00,
0x0c, 0x4c, (byte)0xa0, 0x47,
(byte)0x84, 0x46, (byte)0xbd, (byte)0xe8,
0x1f, 0x40, 0x07, 0x48,
(byte)0xcc, (byte)0xf8, 0x00, (byte)0xd0,
(byte)0xcc, (byte)0xf8, 0x04, 0x20,
(byte)0xcc, (byte)0xf8, 0x08, 0x30,
0x63, 0x46, 0x05, 0x4a,
(byte)0xcc, (byte)0xf8, 0x0c, 0x20,
0x4a, 0x46, 0x4a, 0x46,
(byte)0xdf, (byte)0xf8, 0x04, (byte)0xf0,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
writeInt((int) targetAddress, ByteOrder.LITTLE_ENDIAN, instructions,
instructions.length - 16);
writeInt((int) targetEntry, ByteOrder.LITTLE_ENDIAN, instructions,
Expand All @@ -106,7 +160,8 @@ public byte[] createBridgeJump(long targetAddress, long targetEntry, long srcAdd

@Override
public int sizeOfBridgeJump() {
return 15 * 4;
// return 15 * 4;
return 18 * 4;//add by gzh
}

@Override
Expand Down
4 changes: 4 additions & 0 deletions library/src/main/java/me/weishu/epic/art/entry/Entry.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ private static Object referenceBridge(int r1, int self, int struct) {

final byte[] sourceAddr = EpicNative.get(struct + 12, 4);

//add by gzh
EpicNative.free(struct);//在汇编中申请的,使用完释放
//add by gzh end

ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[8]);
byteBuffer.put(sourceAddr);
byteBuffer.put(new byte[] {0, 0, 0, 0});
Expand Down
2 changes: 2 additions & 0 deletions library/src/main/java/me/weishu/epic/art/entry/Entry64.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ private static Object referenceBridge(long x1, long self, long struct, long x4,
final long sourceMethod = ByteBuffer.wrap(EpicNative.get(struct + 24, 8)).order(ByteOrder.LITTLE_ENDIAN).getLong();
Logger.d(TAG, "sourceMethod:" + Long.toHexString(sourceMethod));

EpicNative.free(struct);//add by gzh

Epic.MethodInfo originMethodInfo = Epic.getMethodInfo(sourceMethod);
Logger.d(TAG, "originMethodInfo :" + originMethodInfo);

Expand Down