Commit 90da813a authored by swift_gan's avatar swift_gan

fix get jni trampoline

parent 83470325
...@@ -148,10 +148,16 @@ bool ArtMethod::compile(JNIEnv* env) { ...@@ -148,10 +148,16 @@ bool ArtMethod::compile(JNIEnv* env) {
bool ArtMethod::deCompile() { bool ArtMethod::deCompile() {
if (!isCompiled()) if (!isCompiled())
return true; return true;
if (CastArtMethod::beAot) if ((isNative() && CastArtMethod::canGetJniBridge) || (!isNative() && CastArtMethod::canGetInterpreterBridge)) {
setQuickCodeEntry(isNative() ? CastArtMethod::genericJniStub : CastArtMethod::quickToInterpreterBridge);
if (SDK_INT < ANDROID_N) {
//TODO SetEntryPointFromInterpreterCode
}
flushCache();
return true;
} else {
return false; return false;
setQuickCodeEntry(isNative() ? CastArtMethod::genericJniStub : CastArtMethod::quickToInterpreterBridge); }
flushCache();
} }
void ArtMethod::flushCache() { void ArtMethod::flushCache() {
......
...@@ -180,23 +180,45 @@ namespace SandHook { ...@@ -180,23 +180,45 @@ namespace SandHook {
declaringClass->init(env, m1, size); declaringClass->init(env, m1, size);
jclass neverCallTestClass = env->FindClass("com/swift/sandhook/ClassNeverCall"); jclass neverCallTestClass = env->FindClass("com/swift/sandhook/ClassNeverCall");
art::mirror::ArtMethod *neverCall = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID( art::mirror::ArtMethod *neverCall = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID(
neverCallTestClass, "neverCall", "()V")); neverCallTestClass, "neverCall", "()V"));
art::mirror::ArtMethod *neverCall2 = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID( art::mirror::ArtMethod *neverCall2 = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID(
neverCallTestClass, "neverCall2", "()V")); neverCallTestClass, "neverCall2", "()V"));
beAot = entryPointQuickCompiled->get(neverCall) != entryPointQuickCompiled->get(neverCall2); bool beAot = entryPointQuickCompiled->get(neverCall) != entryPointQuickCompiled->get(neverCall2);
if (beAot) {
quickToInterpreterBridge = getInterpreterBridge(false);
if (quickToInterpreterBridge == nullptr || quickToInterpreterBridge <= 0) {
quickToInterpreterBridge = entryPointQuickCompiled->get(neverCall);
canGetInterpreterBridge = false;
}
} else {
quickToInterpreterBridge = entryPointQuickCompiled->get(neverCall);
}
quickToInterpreterBridge = entryPointQuickCompiled->get(neverCall); art::mirror::ArtMethod *neverCallNative = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID(
neverCallTestClass, "neverCallNative", "()V"));
art::mirror::ArtMethod *neverCallNative2 = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID(
neverCallTestClass, "neverCallNative2", "()V"));
beAot = entryPointQuickCompiled->get(neverCallNative) != entryPointQuickCompiled->get(neverCallNative2);
if (beAot) {
genericJniStub = getInterpreterBridge(true);
if (genericJniStub == nullptr || genericJniStub <= 0) {
genericJniStub = entryPointQuickCompiled->get(neverCallNative);
canGetJniBridge = false;
}
} else {
genericJniStub = entryPointQuickCompiled->get(neverCallNative);
}
art::mirror::ArtMethod *neverCallStatic = reinterpret_cast<art::mirror::ArtMethod *>(env->GetStaticMethodID( art::mirror::ArtMethod *neverCallStatic = reinterpret_cast<art::mirror::ArtMethod *>(env->GetStaticMethodID(
neverCallTestClass, "neverCallStatic", "()V")); neverCallTestClass, "neverCallStatic", "()V"));
staticResolveStub = entryPointQuickCompiled->get(neverCallStatic); staticResolveStub = entryPointQuickCompiled->get(neverCallStatic);
art::mirror::ArtMethod *neverCallNative = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID(
neverCallTestClass, "neverCallNative", "()V"));
genericJniStub = entryPointQuickCompiled->get(neverCallNative);
} }
void CastArtMethod::copy(art::mirror::ArtMethod *from, art::mirror::ArtMethod *to) { void CastArtMethod::copy(art::mirror::ArtMethod *from, art::mirror::ArtMethod *to) {
...@@ -213,6 +235,7 @@ namespace SandHook { ...@@ -213,6 +235,7 @@ namespace SandHook {
void *CastArtMethod::quickToInterpreterBridge = nullptr; void *CastArtMethod::quickToInterpreterBridge = nullptr;
void *CastArtMethod::genericJniStub = nullptr; void *CastArtMethod::genericJniStub = nullptr;
void *CastArtMethod::staticResolveStub = nullptr; void *CastArtMethod::staticResolveStub = nullptr;
bool CastArtMethod::beAot = false; bool CastArtMethod::canGetInterpreterBridge = true;
bool CastArtMethod::canGetJniBridge = true;
} }
\ No newline at end of file
...@@ -22,7 +22,8 @@ namespace SandHook { ...@@ -22,7 +22,8 @@ namespace SandHook {
static void* quickToInterpreterBridge; static void* quickToInterpreterBridge;
static void* genericJniStub; static void* genericJniStub;
static void* staticResolveStub; static void* staticResolveStub;
static bool beAot; static bool canGetJniBridge;
static bool canGetInterpreterBridge;
static void init(JNIEnv *env); static void init(JNIEnv *env);
static void copy(art::mirror::ArtMethod* from, art::mirror::ArtMethod* to); static void copy(art::mirror::ArtMethod* from, art::mirror::ArtMethod* to);
......
//
// Created by Swift Gan on 2019/3/14.
//
#ifndef SANDHOOK_ELF_UTIL_H #ifndef SANDHOOK_ELF_UTIL_H
#define SANDHOOK_ELF_UTIL_H #define SANDHOOK_ELF_UTIL_H
...@@ -45,7 +48,7 @@ namespace SandHook { ...@@ -45,7 +48,7 @@ namespace SandHook {
void* base = nullptr; void* base = nullptr;
char* buffer = nullptr; char* buffer = nullptr;
off_t size = 0; off_t size = 0;
off_t bias = 0; off_t bias = -4396;
Elf_Ehdr* header = nullptr; Elf_Ehdr* header = nullptr;
Elf_Shdr* section_header = nullptr; Elf_Shdr* section_header = nullptr;
Elf_Shdr* symtab = nullptr; Elf_Shdr* symtab = nullptr;
......
...@@ -24,10 +24,10 @@ Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk, ...@@ -24,10 +24,10 @@ Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk,
// TODO // TODO
SDK_INT = sdk; SDK_INT = sdk;
DEBUG = debug; DEBUG = debug;
initHideApi(env);
SandHook::CastArtMethod::init(env); SandHook::CastArtMethod::init(env);
SandHook::CastCompilerOptions::init(env); SandHook::CastCompilerOptions::init(env);
trampolineManager.init(SandHook::CastArtMethod::entryPointQuickCompiled->getOffset()); trampolineManager.init(SandHook::CastArtMethod::entryPointQuickCompiled->getOffset());
initHideApi(env);
return JNI_TRUE; return JNI_TRUE;
} }
...@@ -327,4 +327,11 @@ Java_com_swift_sandhook_ClassNeverCall_neverCallNative(JNIEnv *env, jobject inst ...@@ -327,4 +327,11 @@ Java_com_swift_sandhook_ClassNeverCall_neverCallNative(JNIEnv *env, jobject inst
int a = 1 + 1; int a = 1 + 1;
int b = a + 1; int b = a + 1;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_swift_sandhook_ClassNeverCall_neverCallNative2(JNIEnv *env, jobject instance) {
int a = 4 + 3;
int b = 9 + 6;
} }
\ No newline at end of file
//
// Created by Swift Gan on 2019/3/14.
//
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include <sys/mman.h> #include <sys/mman.h>
...@@ -12,10 +15,15 @@ ElfImg::ElfImg(const char *elf) { ...@@ -12,10 +15,15 @@ ElfImg::ElfImg(const char *elf) {
this->elf = elf; this->elf = elf;
//load elf //load elf
int fd = open(elf, O_RDONLY); int fd = open(elf, O_RDONLY);
if (fd < 0) LOGE("failed to open %s", elf); if (fd < 0) {
LOGE("failed to open %s", elf);
return;
}
size = lseek(fd, 0, SEEK_END); size = lseek(fd, 0, SEEK_END);
if (size <= 0) LOGE("lseek() failed for %s", elf); if (size <= 0) {
LOGE("lseek() failed for %s", elf);
}
header = reinterpret_cast<Elf_Ehdr *>(mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)); header = reinterpret_cast<Elf_Ehdr *>(mmap(0, size, PROT_READ, MAP_SHARED, fd, 0));
...@@ -56,7 +64,7 @@ ElfImg::ElfImg(const char *elf) { ...@@ -56,7 +64,7 @@ ElfImg::ElfImg(const char *elf) {
} }
break; break;
case SHT_PROGBITS: case SHT_PROGBITS:
if (has_dynsym && has_strtab && bias == 0) { if (has_dynsym && has_strtab && bias == -4396) {
bias = (off_t) section_h->sh_addr - (off_t) section_h->sh_offset; bias = (off_t) section_h->sh_addr - (off_t) section_h->sh_offset;
} }
break; break;
...@@ -74,10 +82,12 @@ ElfImg::ElfImg(const char *elf) { ...@@ -74,10 +82,12 @@ ElfImg::ElfImg(const char *elf) {
} }
ElfImg::~ElfImg() { ElfImg::~ElfImg() {
//open elf file local
if (buffer) { if (buffer) {
free(buffer); free(buffer);
buffer = nullptr; buffer = nullptr;
} }
//use mmap
if (header) { if (header) {
munmap(header, size); munmap(header, size);
} }
......
...@@ -23,15 +23,13 @@ extern "C" { ...@@ -23,15 +23,13 @@ extern "C" {
void* (*get)(bool*) = nullptr; void* (*get)(bool*) = nullptr;
void* (*getQuickToInterpreterBridge)(void*) = nullptr; const char* art_lib_path;
void* (*getQuickGenericJniStub)(void*) = nullptr; const char* jit_lib_path;
void initHideApi(JNIEnv* env) { void initHideApi(JNIEnv* env) {
const char* art_lib_path;
const char* jit_lib_path;
if (BYTE_POINT == 8) { if (BYTE_POINT == 8) {
art_lib_path = "/system/lib64/libart.so"; art_lib_path = "/system/lib64/libart.so";
jit_lib_path = "/system/lib64/libart-compiler.so"; jit_lib_path = "/system/lib64/libart-compiler.so";
...@@ -81,9 +79,6 @@ extern "C" { ...@@ -81,9 +79,6 @@ extern "C" {
if (SDK_INT >= ANDROID_N) { if (SDK_INT >= ANDROID_N) {
globalJitCompileHandlerAddr = reinterpret_cast<art::jit::JitCompiler **>(getSymCompat(art_lib_path, "_ZN3art3jit3Jit20jit_compiler_handle_E")); globalJitCompileHandlerAddr = reinterpret_cast<art::jit::JitCompiler **>(getSymCompat(art_lib_path, "_ZN3art3jit3Jit20jit_compiler_handle_E"));
getQuickGenericJniStub = reinterpret_cast<void *(*)(void *)>(getSymCompat(art_lib_path, "_ZNK3art11ClassLinker29GetRuntimeQuickGenericJniStubEv"));
getQuickToInterpreterBridge = reinterpret_cast<void *(*)(void *)>(getSymCompat(art_lib_path, "_ZNK3art9OatHeader27GetQuickToInterpreterBridgeEv"));
SandHook::ElfImg elfImg(art_lib_path); SandHook::ElfImg elfImg(art_lib_path);
void* sym = reinterpret_cast<void *>(elfImg.getSymbAddress("art_quick_to_interpreter_bridge")); void* sym = reinterpret_cast<void *>(elfImg.getSymbAddress("art_quick_to_interpreter_bridge"));
...@@ -166,13 +161,11 @@ extern "C" { ...@@ -166,13 +161,11 @@ extern "C" {
} }
void* getInterpreterBridge(bool isNative) { void* getInterpreterBridge(bool isNative) {
SandHook::ElfImg libart(art_lib_path);
if (isNative) { if (isNative) {
if (getQuickGenericJniStub == nullptr || getQuickGenericJniStub <= 0) return reinterpret_cast<void *>(libart.getSymbAddress("art_quick_generic_jni_trampoline"));
return nullptr;
return getQuickGenericJniStub(nullptr);
} else { } else {
//no implement return reinterpret_cast<void *>(libart.getSymbAddress("art_quick_to_interpreter_bridge"));
return nullptr;
} }
} }
......
...@@ -9,4 +9,5 @@ public class ClassNeverCall { ...@@ -9,4 +9,5 @@ public class ClassNeverCall {
} }
private static void neverCallStatic() {} private static void neverCallStatic() {}
private native void neverCallNative(); private native void neverCallNative();
private native void neverCallNative2();
} }
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