Commit 86681ef3 authored by swift_gan's avatar swift_gan

done arm32 impl

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