Commit adf97741 authored by swift_gan's avatar swift_gan

add entry code size check

parent 9586a356
...@@ -35,6 +35,16 @@ static void clearCacheArm32(char* begin, char *end) ...@@ -35,6 +35,16 @@ static void clearCacheArm32(char* begin, char *end)
} }
#endif #endif
#define ANDROID_K 19
#define ANDROID_L 21
#define ANDROID_L2 22
#define ANDROID_M 23
#define ANDROID_N 24
#define ANDROID_N2 25
#define ANDROID_O 26
#define ANDROID_O2 27
#define ANDROID_P 28
} }
......
...@@ -12,19 +12,10 @@ ...@@ -12,19 +12,10 @@
#include "arch.h" #include "arch.h"
#include "utils.h" #include "utils.h"
#define ANDROID_K 19
#define ANDROID_L 21
#define ANDROID_L2 22
#define ANDROID_M 23
#define ANDROID_N 24
#define ANDROID_N2 25
#define ANDROID_O 26
#define ANDROID_O2 27
#define ANDROID_P 28
namespace SandHook { namespace SandHook {
static int SDK_INT = 0; int SDK_INT = 0;
template <typename T> template <typename T>
class cast { class cast {
......
...@@ -14,7 +14,7 @@ Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk) ...@@ -14,7 +14,7 @@ Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk)
// TODO // TODO
SDK_INT = sdk; SDK_INT = sdk;
SandHook::CastArtMethod::init(env, sdk); SandHook::CastArtMethod::init(env, sdk);
trampolineManager.init(SandHook::CastArtMethod::entryPointQuickCompiled->getOffset()); trampolineManager.init(sdk, SandHook::CastArtMethod::entryPointQuickCompiled->getOffset());
initHideApi(env, sdk); initHideApi(env, sdk);
return JNI_TRUE; return JNI_TRUE;
...@@ -48,6 +48,11 @@ bool isAbsMethod(art::mirror::ArtMethod* method) { ...@@ -48,6 +48,11 @@ bool isAbsMethod(art::mirror::ArtMethod* method) {
return ((accessFlags & 0x0400) != 0); return ((accessFlags & 0x0400) != 0);
} }
bool isNative(art::mirror::ArtMethod* method) {
uint32_t accessFlags = SandHook::CastArtMethod::accessFlag->get(method);
return ((accessFlags & 0x0100) != 0);
}
void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *backupMethod) { void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *backupMethod) {
if (SDK_INT >= ANDROID_P) if (SDK_INT >= ANDROID_P)
return; return;
...@@ -117,7 +122,7 @@ bool doHookWithInline(JNIEnv* env, ...@@ -117,7 +122,7 @@ bool doHookWithInline(JNIEnv* env,
SandHook::Trampoline::flushCache(reinterpret_cast<Size>(originMethod), SandHook::CastArtMethod::size); SandHook::Trampoline::flushCache(reinterpret_cast<Size>(originMethod), SandHook::CastArtMethod::size);
} }
SandHook::HookTrampoline* hookTrampoline = trampolineManager.installInlineTrampoline(originMethod, hookMethod, backupMethod); SandHook::HookTrampoline* hookTrampoline = trampolineManager.installInlineTrampoline(originMethod, hookMethod, backupMethod, isNative(originMethod));
if (hookTrampoline == nullptr) if (hookTrampoline == nullptr)
return false; return false;
// void* entryPointFormInterpreter = SandHook::CastArtMethod::entryPointFormInterpreter->get(hookMethod); // void* entryPointFormInterpreter = SandHook::CastArtMethod::entryPointFormInterpreter->get(hookMethod);
...@@ -165,9 +170,7 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or ...@@ -165,9 +170,7 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or
// doHookWithReplacement(origin, hook, backup); // doHookWithReplacement(origin, hook, backup);
// return JNI_TRUE; // return JNI_TRUE;
// #endif // #endif
if (BYTE_POINT == 4 && SDK_INT >= ANDROID_P) { if (isAbsMethod(origin)) {
return static_cast<jboolean>(doHookWithReplacement(origin, hook, backup));
} else if (isAbsMethod(origin)) {
return static_cast<jboolean>(doHookWithReplacement(origin, hook, backup)); return static_cast<jboolean>(doHookWithReplacement(origin, hook, backup));
} else if (isInterpreter) { } else if (isInterpreter) {
if (SDK_INT >= ANDROID_N) { if (SDK_INT >= ANDROID_N) {
......
...@@ -6,15 +6,27 @@ ...@@ -6,15 +6,27 @@
namespace SandHook { namespace SandHook {
uint32_t TrampolineManager::sizeOfEntryCode(mirror::ArtMethod *method) {
Code codeEntry = getEntryCode(method);
#if defined(__arm__)
if (isThumbCode(reinterpret_cast<Size>(codeEntry))) {
codeEntry = getThumbCodeAddress(codeEntry);
}
#endif
uint32_t size = *reinterpret_cast<uint32_t *>((Size)codeEntry - 4);
return size;
}
Code TrampolineManager::allocExecuteSpace(Size size) { Code TrampolineManager::allocExecuteSpace(Size size) {
if (size > MMAP_PAGE_SIZE) if (size > EXE_BLOCK_SIZE)
return 0; return 0;
AutoLock autoLock(allocSpaceLock); AutoLock autoLock(allocSpaceLock);
void* mmapRes; void* mmapRes;
Code exeSpace = 0; Code exeSpace = 0;
if (executeSpaceList.size() == 0) { if (executeSpaceList.size() == 0) {
goto label_alloc_new_space; goto label_alloc_new_space;
} else if (executePageOffset + size > MMAP_PAGE_SIZE) { } else if (executePageOffset + size > EXE_BLOCK_SIZE) {
goto label_alloc_new_space; goto label_alloc_new_space;
} else { } else {
exeSpace = executeSpaceList.back(); exeSpace = executeSpaceList.back();
...@@ -23,7 +35,7 @@ namespace SandHook { ...@@ -23,7 +35,7 @@ namespace SandHook {
return retSpace; return retSpace;
} }
label_alloc_new_space: label_alloc_new_space:
mmapRes = mmap(NULL, MMAP_PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, mmapRes = mmap(NULL, EXE_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE, -1, 0); MAP_ANON | MAP_PRIVATE, -1, 0);
if (mmapRes == MAP_FAILED) { if (mmapRes == MAP_FAILED) {
return 0; return 0;
...@@ -66,7 +78,8 @@ namespace SandHook { ...@@ -66,7 +78,8 @@ namespace SandHook {
HookTrampoline* TrampolineManager::installInlineTrampoline(mirror::ArtMethod *originMethod, HookTrampoline* TrampolineManager::installInlineTrampoline(mirror::ArtMethod *originMethod,
mirror::ArtMethod *hookMethod, mirror::ArtMethod *hookMethod,
mirror::ArtMethod *backupMethod) { mirror::ArtMethod *backupMethod,
bool isNative) {
AutoLock autoLock(installLock); AutoLock autoLock(installLock);
...@@ -80,6 +93,12 @@ namespace SandHook { ...@@ -80,6 +93,12 @@ namespace SandHook {
Code callOriginTrampolineSpace; Code callOriginTrampolineSpace;
Code originEntry; Code originEntry;
if (!isNative) {
uint32_t originCodeSize = sizeOfEntryCode(originMethod);
if (originCodeSize < SIZE_DIRECT_JUMP_TRAMPOLINE)
goto label_error;
}
//生成二段跳板 //生成二段跳板
inlineHookTrampoline = new InlineHookTrampoline(); inlineHookTrampoline = new InlineHookTrampoline();
checkThumbCode(inlineHookTrampoline, getEntryCode(originMethod)); checkThumbCode(inlineHookTrampoline, getEntryCode(originMethod));
...@@ -144,7 +163,6 @@ namespace SandHook { ...@@ -144,7 +163,6 @@ namespace SandHook {
callOriginTrampoline->setOriginCode(originCode); callOriginTrampoline->setOriginCode(originCode);
hookTrampoline->callOrigin = callOriginTrampoline; hookTrampoline->callOrigin = callOriginTrampoline;
} }
trampolines[originMethod] = hookTrampoline; trampolines[originMethod] = hookTrampoline;
return hookTrampoline; return hookTrampoline;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
namespace SandHook { namespace SandHook {
#define MMAP_PAGE_SIZE sysconf(_SC_PAGESIZE) #define MMAP_PAGE_SIZE sysconf(_SC_PAGESIZE)
#define EXE_BLOCK_SIZE MMAP_PAGE_SIZE
using namespace art; using namespace art;
...@@ -29,19 +30,25 @@ namespace SandHook { ...@@ -29,19 +30,25 @@ namespace SandHook {
Trampoline* inlineJump = nullptr; Trampoline* inlineJump = nullptr;
Trampoline* inlineSecondory = nullptr; Trampoline* inlineSecondory = nullptr;
Trampoline* callOrigin = nullptr; Trampoline* callOrigin = nullptr;
Code originCode = nullptr;
}; };
class TrampolineManager { class TrampolineManager {
public: public:
TrampolineManager() = default; TrampolineManager() = default;
void init(Size quickCompileOffset) {
this->quickCompileOffset = quickCompileOffset;
void init(int sdk, Size quickCompileOffset) {
this->quickCompileOffset = quickCompileOffset;
SDK_INT = sdk;
} }
Code allocExecuteSpace(Size size); Code allocExecuteSpace(Size size);
HookTrampoline* installReplacementTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod); HookTrampoline* installReplacementTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod);
HookTrampoline* installInlineTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod); HookTrampoline* installInlineTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod,
bool isNative);
uint32_t sizeOfEntryCode(mirror::ArtMethod* method);
HookTrampoline* getHookTrampoline(mirror::ArtMethod* method) { HookTrampoline* getHookTrampoline(mirror::ArtMethod* method) {
return trampolines[method]; return trampolines[method];
...@@ -63,21 +70,26 @@ namespace SandHook { ...@@ -63,21 +70,26 @@ namespace SandHook {
return entryCode; return entryCode;
} }
bool isThumbCode(Size codeAddr) { static bool isThumbCode(Size codeAddr) {
return (codeAddr & 0x1) == 0x1; return (codeAddr & 0x1) == 0x1;
} }
void checkThumbCode(Trampoline* trampoline, Code code) { static void checkThumbCode(Trampoline* trampoline, Code code) {
#if defined(__arm__) #if defined(__arm__)
trampoline->setThumb(isThumbCode(reinterpret_cast<Size>(code))); trampoline->setThumb(isThumbCode(reinterpret_cast<Size>(code)));
#endif #endif
} }
static Code getThumbCodeAddress(Code code) {
Size addr = reinterpret_cast<Size>(code) & (~0x00000001);
return reinterpret_cast<Code>(addr);
}
private: private:
Size quickCompileOffset; Size quickCompileOffset;
int SDK_INT = 0;
std::map<mirror::ArtMethod*,HookTrampoline*> trampolines; std::map<mirror::ArtMethod*,HookTrampoline*> trampolines;
std::list<Code> executeSpaceList = std::list<Code>(); std::list<Code> executeSpaceList = std::list<Code>();
std::mutex allocSpaceLock; std::mutex allocSpaceLock;
......
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