Commit 86681ef3 authored by swift_gan's avatar swift_gan

done arm32 impl

parent 35ac9abc
......@@ -41,49 +41,50 @@ public:
class ArtMethod {
public:
uint32_t declaring_class_;
// Access flags; low 16 bits are defined by spec.
// Getting and setting this flag needs to be atomic when concurrency is
// possible, e.g. after this method's class is linked. Such as when setting
// verifier flags and single-implementation flag.
uint32_t access_flags_;
/* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
// Offset to the CodeItem.
uint32_t dex_code_item_offset_;
// Index into method_ids of the dex file associated with this method.
uint32_t dex_method_index_;
/* End of dex file fields. */
// Entry within a dispatch table for this method. For static/direct methods the index is into
// the declaringClass.directMethods, for virtual methods the vtable and for interface methods the
// ifTable.
uint16_t method_index_;
// The hotness we measure for this method. Managed by the interpreter. Not atomic, as we allow
// missing increments: if the method is hot, we will see it eventually.
uint16_t hotness_count_;
// Fake padding field gets inserted here.
// Must be the last fields in the method.
struct PtrSizedFields {
// Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
void* dex_cache_resolved_methods_;
// Pointer to JNI function registered to this method, or a function to resolve the JNI function,
// or the profiling data for non-native methods, or an ImtConflictTable, or the
// single-implementation of an abstract/interface method.
void* data_;
// Method dispatch from quick compiled code invokes this pointer which may cause bridging into
// the interpreter.
void* entry_point_from_quick_compiled_code_;
} ptr_sized_fields_;
// uint32_t declaring_class_;
//
// // Access flags; low 16 bits are defined by spec.
// // Getting and setting this flag needs to be atomic when concurrency is
// // possible, e.g. after this method's class is linked. Such as when setting
// // verifier flags and single-implementation flag.
// uint32_t access_flags_;
//
// /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
//
// // Offset to the CodeItem.
// uint32_t dex_code_item_offset_;
//
// // Index into method_ids of the dex file associated with this method.
// uint32_t dex_method_index_;
//
// /* End of dex file fields. */
//
// // Entry within a dispatch table for this method. For static/direct methods the index is into
// // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the
// // ifTable.
// uint16_t method_index_;
//
// // The hotness we measure for this method. Managed by the interpreter. Not atomic, as we allow
// // missing increments: if the method is hot, we will see it eventually.
// uint16_t hotness_count_;
//
// // Fake padding field gets inserted here.
//
// // Must be the last fields in the method.
// struct PtrSizedFields {
// // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
// void* dex_cache_resolved_methods_;
//
// // Pointer to JNI function registered to this method, or a function to resolve the JNI function,
// // or the profiling data for non-native methods, or an ImtConflictTable, or the
// // single-implementation of an abstract/interface method.
// void* data_;
//
// // Method dispatch from quick compiled code invokes this pointer which may cause bridging into
// // the interpreter.
// void* entry_point_from_quick_compiled_code_;
// } ptr_sized_fields_;
uint16_t placeholder[40];
};
}
......
......@@ -23,9 +23,24 @@ namespace SandHook {
return static_cast<Size>(offset);
}
}
if (SDK_INT == ANDROID_M) {
return 4;
} else if (SDK_INT >= ANDROID_L && SDK_INT <= ANDROID_L2) {
return 4 * 3;
}
return getParentSize() + 1;
}
public:
Size arrayStart(mirror::ArtMethod *parent) override {
void* p = IMember<mirror::ArtMethod,void*>::get(parent);
if (SDK_INT <= ANDROID_M) {
return reinterpret_cast<Size>(p) + 4 * 3;
} else {
reinterpret_cast<Size>(p);
}
}
};
class CastEntryPointFormInterpreter : public IMember<art::mirror::ArtMethod, void*> {
......
......@@ -2,7 +2,7 @@
#if defined(__arm__)
#define Reg0 r12
#define Reg0 ip
//need restore
#define Reg1 r11
#define RegMethod r0
......@@ -40,10 +40,9 @@ origin_code:
.long 0
.long 0
ldr Reg0, addr_origin_art_method
ldr Reg1, offset_entry_code2
add Reg1, Reg0, Reg1
ldr Reg1, [Reg1]
add pc, Reg1, SIZE_JUMP
add Reg0, Reg0, #8
ldr Reg0, [Reg0]
add pc, Reg0, SIZE_JUMP
addr_origin_art_method:
.long 0
offset_entry_code2:
......
......@@ -62,6 +62,18 @@ namespace SandHook {
void setEntryCodeOffset(Size offSet) {
codeCopy(reinterpret_cast<Code>(&offSet), OFFSET_INLINE_OFFSET_ENTRY_CODE, BYTE_POINT);
#if defined(__arm__)
Code32Bit offset32;
Code32Bit code32Bit;
offset32.code = offSet;
unsigned char offsetOP = isBigEnd() ? offset32.op.op4 : offset32.op.op1;
code32Bit.code = *reinterpret_cast<uint32_t*>(((Size)getCode() + OFFSET_INLINE_OP_OFFSET_CODE));
if (isBigEnd()) {
code32Bit.op.op4 = offsetOP;
} else {
code32Bit.op.op1 = offsetOP;
}
#endif
}
void setOriginCode(Code originCode) {
......
......@@ -41,18 +41,19 @@
#define OFFSET_INLINE_OFFSET_ENTRY_CODE 4 * 20
#define OFFSET_INLINE_ADDR_HOOK_METHOD 4 * 22
#elif defined(__arm__)
#define SIZE_REPLACEMENT_HOOK_TRAMPOLINE 4 * 9
#define OFFSET_REPLACEMENT_ADDR_ART_METHOD 4 * 5
#define OFFSET_REPLACEMENT_OFFSET_ENTRY_CODE 4 * 7
#define SIZE_REPLACEMENT_HOOK_TRAMPOLINE 4 * 6
#define OFFSET_REPLACEMENT_ADDR_ART_METHOD 4 * 4
#define OFFSET_REPLACEMENT_OFFSET_ENTRY_CODE 4 * 5
#define SIZE_DIRECT_JUMP_TRAMPOLINE 4 * 4
#define OFFSET_JUMP_ADDR_TARGET 4 * 2
#define SIZE_DIRECT_JUMP_TRAMPOLINE 4 * 2
#define OFFSET_JUMP_ADDR_TARGET 4 * 1
#define SIZE_INLINE_HOOK_TRAMPOLINE 4 * 24
#define OFFSET_INLINE_ADDR_ORIGIN_METHOD 4 * 10
#define OFFSET_INLINE_ORIGIN_CODE 4 * 12
#define OFFSET_INLINE_OFFSET_ENTRY_CODE 4 * 20
#define OFFSET_INLINE_ADDR_HOOK_METHOD 4 * 22
#define SIZE_INLINE_HOOK_TRAMPOLINE 4 * 16
#define OFFSET_INLINE_ADDR_ORIGIN_METHOD 4 * 13
#define OFFSET_INLINE_ORIGIN_CODE 4 * 7
#define OFFSET_INLINE_OFFSET_ENTRY_CODE 4 * 14
#define OFFSET_INLINE_ADDR_HOOK_METHOD 4 * 15
#define OFFSET_INLINE_OP_OFFSET_CODE 4 * 10
#define SIZE_CALL_ORIGIN_TRAMPOLINE 4 * 7
#define OFFSET_CALL_ORIGIN_ART_METHOD 4 * 3
......@@ -71,9 +72,9 @@
#define OFFSET_INLINE_OFFSET_ENTRY_CODE 4 * 20
#define OFFSET_INLINE_ADDR_HOOK_METHOD 4 * 22
#define SIZE_CALL_ORIGIN_TRAMPOLINE 4 * 7
#define OFFSET_CALL_ORIGIN_ART_METHOD 4 * 3
#define OFFSET_CALL_ORIGIN_JUMP_ADDR 4 * 5
#define SIZE_CALL_ORIGIN_TRAMPOLINE 4 * 4
#define OFFSET_CALL_ORIGIN_ART_METHOD 4 * 2
#define OFFSET_CALL_ORIGIN_JUMP_ADDR 4 * 3
#else
#endif
......@@ -127,6 +128,14 @@ namespace SandHook {
Size getCodeLen() {
return codeLen;
}
bool isBigEnd(void) {
int i = 1;
unsigned char *pointer;
pointer = (unsigned char *) &i;
return *pointer == 0;
}
protected:
virtual Size codeLength() = 0;
virtual Code templateCode() = 0;
......@@ -136,6 +145,17 @@ namespace SandHook {
Size codeLen;
};
union Code32Bit {
uint32_t code;
struct {
unsigned char op1;
unsigned char op2;
unsigned char op3;
unsigned char op4;
} op;
};
}
......
......@@ -72,7 +72,11 @@ public class SandHookMethodResolver {
canResolvedInJava = false;
resolvedMethodsAddress = (long) resolvedMethods;
} else if (resolvedMethods instanceof long[]) {
//64bit
canResolvedInJava = true;
} else if (resolvedMethods instanceof int[]) {
//32bit
canResolvedInJava = false;
}
}
......@@ -101,8 +105,15 @@ public class SandHookMethodResolver {
} else {
int dexMethodIndex = (int) dexMethodIndexField.get(backup);
Object resolvedMethods = resolvedMethodsField.get(dexCache);
long artMethod = (long) artMethodField.get(backup);
((long[])resolvedMethods)[dexMethodIndex] = artMethod;
if (resolvedMethods instanceof long[]) {
long artMethod = (long) artMethodField.get(backup);
((long[])resolvedMethods)[dexMethodIndex] = artMethod;
} else if (resolvedMethods instanceof int[]) {
int artMethod = Long.valueOf((long)artMethodField.get(backup)).intValue();
((int[])resolvedMethods)[dexMethodIndex] = artMethod;
} else {
throw new UnsupportedOperationException("un support");
}
}
}
......
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