Commit faa13b1a authored by swift_gan's avatar swift_gan

done trampoline manager

parent 6ab163a8
...@@ -11,7 +11,7 @@ android { ...@@ -11,7 +11,7 @@ android {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {
cmake { cmake {
arguments '-DBUILD_TESTING=OFF','-DANDROID_TOOLCHAIN=gcc' arguments '-DBUILD_TESTING=OFF'
cppFlags "-frtti -fexceptions" cppFlags "-frtti -fexceptions"
abiFilters 'armeabi-v7a', 'arm64-v8a' abiFilters 'armeabi-v7a', 'arm64-v8a'
} }
......
/*
*
* Copyright (c) 2011 The Android Open Source Project
* Copyright (c) 2015, alipay.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* art_6_0.h
*
* @author : sanping.li@alipay.com
*
*/
#ifndef ART_H
#define ART_H
namespace art {
namespace mirror {
class Object {
public:
};
class Class: public Object {
public:
};
class ArtField {
public:
};
class ArtMethod {
public:
};
}
}
#endif //ART_H
/*
*
* Copyright (c) 2011 The Android Open Source Project
* Copyright (c) 2015, alipay.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* art_6_0.h
*
* @author : sanping.li@alipay.com
*
*/
#include <string.h>
#include <jni.h>
#include <stdio.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <stdint.h> /* C99 */
namespace art {
namespace mirror {
class Object {
public:
// The number of vtable entries in java.lang.Object.
static constexpr size_t kVTableLength = 11;
static uint32_t hash_code_seed;
uint32_t klass_;
uint32_t monitor_;
};
class Class: public Object {
public:
// A magic value for reference_instance_offsets_. Ignore the bits and walk the super chain when
// this is the value.
// [This is an unlikely "natural" value, since it would be 30 non-ref instance fields followed by
// 2 ref instance fields.]
static constexpr uint32_t kClassWalkSuper = 0xC0000000;
// Interface method table size. Increasing this value reduces the chance of two interface methods
// colliding in the interface method table but increases the size of classes that implement
// (non-marker) interfaces.
static constexpr size_t kImtSize = 0; //IMT_SIZE;
// Defining class loader, or null for the "bootstrap" system loader.
uint32_t class_loader_;
// For array classes, the component class object for instanceof/checkcast
// (for String[][][], this will be String[][]). null for non-array classes.
uint32_t component_type_;
// DexCache of resolved constant pool entries (will be null for classes generated by the
// runtime such as arrays and primitive classes).
uint32_t dex_cache_;
// Short cuts to dex_cache_ member for fast compiled code access.
uint32_t dex_cache_strings_;
// The interface table (iftable_) contains pairs of a interface class and an array of the
// interface methods. There is one pair per interface supported by this class. That means one
// pair for each interface we support directly, indirectly via superclass, or indirectly via a
// superinterface. This will be null if neither we nor our superclass implement any interfaces.
//
// Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
// Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a
// single vtable.
//
// For every interface a concrete class implements, we create an array of the concrete vtable_
// methods for the methods in the interface.
uint32_t iftable_;
// Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName
uint32_t name_;
// The superclass, or null if this is java.lang.Object or a primitive type.
//
// Note that interfaces have java.lang.Object as their
// superclass. This doesn't match the expectations in JNI
// GetSuperClass or java.lang.Class.getSuperClass() which need to
// check for interfaces and return null.
uint32_t super_class_;
// If class verify fails, we must return same error on subsequent tries.
uint32_t verify_error_class_;
// Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is
// copied in, and virtual methods from our class either replace those from the super or are
// appended. For abstract classes, methods may be created in the vtable that aren't in
// virtual_ methods_ for miranda methods.
uint32_t vtable_;
// Access flags; low 16 bits are defined by VM spec.
// Note: Shuffled back.
uint32_t access_flags_;
// static, private, and <init> methods. Pointer to an ArtMethod length-prefixed array.
uint64_t direct_methods_;
// instance fields
//
// These describe the layout of the contents of an Object.
// Note that only the fields directly declared by this class are
// listed in ifields; fields declared by a superclass are listed in
// the superclass's Class.ifields.
//
// ArtFields are allocated as a length prefixed ArtField array, and not an array of pointers to
// ArtFields.
uint64_t ifields_;
// Static fields length-prefixed array.
uint64_t sfields_;
// Virtual methods defined in this class; invoked through vtable. Pointer to an ArtMethod
// length-prefixed array.
uint64_t virtual_methods_;
// Total size of the Class instance; used when allocating storage on gc heap.
// See also object_size_.
uint32_t class_size_;
// Tid used to check for recursive <clinit> invocation.
pid_t clinit_thread_id_;
// ClassDef index in dex file, -1 if no class definition such as an array.
// TODO: really 16bits
int32_t dex_class_def_idx_;
// Type index in dex file.
// TODO: really 16bits
int32_t dex_type_idx_;
// Number of direct fields.
uint32_t num_direct_methods_;
// Number of instance fields.
uint32_t num_instance_fields_;
// Number of instance fields that are object refs.
uint32_t num_reference_instance_fields_;
// Number of static fields that are object refs,
uint32_t num_reference_static_fields_;
// Number of static fields.
uint32_t num_static_fields_;
// Number of virtual methods.
uint32_t num_virtual_methods_;
// Total object size; used when allocating storage on gc heap.
// (For interfaces and abstract classes this will be zero.)
// See also class_size_.
uint32_t object_size_;
// The lower 16 bits contains a Primitive::Type value. The upper 16
// bits contains the size shift of the primitive type.
uint32_t primitive_type_;
// Bitmap of offsets of ifields.
uint32_t reference_instance_offsets_;
// State of class initialization.
uint32_t status_;
// TODO: ?
// initiating class loader list
// NOTE: for classes with low serialNumber, these are unused, and the
// values are kept in a table in gDvm.
// InitiatingLoaderList initiating_loader_list_;
// The following data exist in real class objects.
// Embedded Imtable, for class object that's not an interface, fixed size.
// ImTableEntry embedded_imtable_[0];
// Embedded Vtable, for class object that's not an interface, variable size.
// VTableEntry embedded_vtable_[0];
// Static fields, variable size.
// uint32_t fields_[0];
// java.lang.Class
static uint32_t java_lang_Class_;
};
class ArtField {
public:
uint32_t declaring_class_;
uint32_t access_flags_;
uint32_t field_dex_idx_;
uint32_t offset_;
};
class ArtMethod {
public:
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
// The class we are a part of.
uint32_t declaring_class_;
// Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
uint32_t dex_cache_resolved_methods_;
// Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
uint32_t dex_cache_resolved_types_;
// Access flags; low 16 bits are defined by spec.
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.
uint32_t method_index_;
// Fake padding field gets inserted here.
// Must be the last fields in the method.
// PACKED(4) is necessary for the correctness of
// RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size).
struct PtrSizedFields {
// Method dispatch from the interpreter invokes this pointer which may cause a bridge into
// compiled code.
void* entry_point_from_interpreter_;
// Pointer to JNI function registered to this method, or a function to resolve the JNI function.
void* entry_point_from_jni_;
// 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_;
};
}
}
// //
// Created by 甘尧 on 2019/1/12. // Created by 甘尧 on 2019/1/12.
// //
#ifndef SANDHOOK_CAST_ART_METHOD_H
#define SANDHOOK_CAST_ART_METHOD_H
#include "../includes/cast.h" #include "../includes/cast.h"
#include "art/art_6_0.h"
namespace SandHook { namespace SandHook {
...@@ -94,7 +97,7 @@ namespace SandHook { ...@@ -94,7 +97,7 @@ namespace SandHook {
class cast_art_method { class CastArtMethod {
public: public:
static Size size; static Size size;
static IMember<art::mirror::ArtMethod, void*>* entryPointQuickCompiled; static IMember<art::mirror::ArtMethod, void*>* entryPointQuickCompiled;
...@@ -143,15 +146,15 @@ namespace SandHook { ...@@ -143,15 +146,15 @@ namespace SandHook {
}; };
Size cast_art_method::size = 0; Size CastArtMethod::size = 0;
IMember<art::mirror::ArtMethod, void*>* cast_art_method::entryPointQuickCompiled = nullptr; IMember<art::mirror::ArtMethod, void*>* CastArtMethod::entryPointQuickCompiled = nullptr;
IMember<art::mirror::ArtMethod, void*>* cast_art_method::entryPointFormInterpreter = nullptr; IMember<art::mirror::ArtMethod, void*>* CastArtMethod::entryPointFormInterpreter = nullptr;
ArrayMember<art::mirror::ArtMethod>* cast_art_method::dexCacheResolvedMethods = nullptr; ArrayMember<art::mirror::ArtMethod>* CastArtMethod::dexCacheResolvedMethods = nullptr;
IMember<art::mirror::ArtMethod, uint32_t>* cast_art_method::dexMethodIndex = nullptr; IMember<art::mirror::ArtMethod, uint32_t>* CastArtMethod::dexMethodIndex = nullptr;
IMember<art::mirror::ArtMethod, uint32_t>* cast_art_method::accessFlag = nullptr; IMember<art::mirror::ArtMethod, uint32_t>* CastArtMethod::accessFlag = nullptr;
} }
#endif //SANDHOOK_CAST_ART_METHOD_H
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
#ifndef SANDHOOK_ARCH_H #ifndef SANDHOOK_ARCH_H
#define SANDHOOK_ARCH_H #define SANDHOOK_ARCH_H
#endif //SANDHOOK_ARCH_H
namespace SandHook { namespace SandHook {
#define BYTE_POINT sizeof(void*) #define BYTE_POINT sizeof(void*)
...@@ -24,4 +22,7 @@ namespace SandHook { ...@@ -24,4 +22,7 @@ namespace SandHook {
#else #else
#endif #endif
} }
#endif //SANDHOOK_ARCH_H
\ No newline at end of file
...@@ -2,11 +2,16 @@ ...@@ -2,11 +2,16 @@
// Created by 甘尧 on 2019/1/12. // Created by 甘尧 on 2019/1/12.
// //
#ifndef SANDHOOK_ICAST_H
#define SANDHOOK_ICAST_H
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <jni.h> #include <jni.h>
#include "arch.h" #include "arch.h"
#include "utils.h" #include "utils.h"
#include "../casts/art/art.h"
#define ANDROID_L 21 #define ANDROID_L 21
#define ANDROID_L2 22 #define ANDROID_L2 22
...@@ -17,9 +22,6 @@ ...@@ -17,9 +22,6 @@
#define ANDROID_O2 27 #define ANDROID_O2 27
#define ANDROID_P 28 #define ANDROID_P 28
#ifndef SANDHOOK_ICAST_H
#define SANDHOOK_ICAST_H
namespace SandHook { namespace SandHook {
static int SDK_INT = 0; static int SDK_INT = 0;
......
...@@ -5,20 +5,8 @@ ...@@ -5,20 +5,8 @@
#ifndef SANDHOOK_UTILS_H #ifndef SANDHOOK_UTILS_H
#define SANDHOOK_UTILS_H #define SANDHOOK_UTILS_H
#if defined(__MACH__) && defined(__FreeBSD__) && defined(__NetBSD__) && defined(__OpenBSD__)\
&& defined(__DragonFly__)
#define ERROR_SIGNAL SIGBUS
#else
#define ERROR_SIGNAL SIGSEGV
#endif
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include "jni.h"
#include <setjmp.h>
#include <unistd.h>
#include <cwchar>
template<typename T> template<typename T>
int findOffset(void *start, size_t len,size_t step,T value) { int findOffset(void *start, size_t len,size_t step,T value) {
...@@ -70,57 +58,6 @@ int findOffsetWithCB2(void *start1, void *start2, size_t len,size_t step, bool f ...@@ -70,57 +58,6 @@ int findOffsetWithCB2(void *start1, void *start2, size_t len,size_t step, bool f
return -1; return -1;
} }
static sigjmp_buf badreadjmpbuf;
static void badreadfunc(int signo)
{
/*write(STDOUT_FILENO, "catch\n", 6);*/
siglongjmp(badreadjmpbuf, 1);
}
bool isBadReadPtr(void *ptr, int length)
{
struct sigaction sa, osa;
bool ret = false;
/*init new handler struct*/
sa.sa_handler = badreadfunc;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
/*retrieve old and set new handlers*/
if(sigaction(ERROR_SIGNAL, &sa, &osa)<0)
return true;
if(sigsetjmp(badreadjmpbuf, 1) == 0)
{
int i, hi=length/sizeof(int), remain=length%sizeof(int);
int* pi = static_cast<int *>(ptr);
char* pc = (char*)ptr + hi;
for(i=0;i<hi;i++)
{
int tmp = *(pi+i);
}
for(i=0;i<remain;i++)
{
char tmp = *(pc+i);
}
}
else
{
ret = true;
}
/*restore prevouis signal actions*/
if(sigaction(ERROR_SIGNAL, &osa, NULL)<0)
return true;
return ret;
}
Size getAddressFromJava(JNIEnv* env, char* className, char* fieldName) { Size getAddressFromJava(JNIEnv* env, char* className, char* fieldName) {
jclass clazz = env -> FindClass(className); jclass clazz = env -> FindClass(className);
......
#include <jni.h> #include <jni.h>
#include <string> #include <string>
#include "casts/cast_art_method.h" #include "casts/cast_art_method.h"
#include "./trampoline/arch/base.h" #include "./trampoline/trampoline_manager.h"
extern "C" JNIEXPORT jstring extern "C" JNIEXPORT jstring
...@@ -40,6 +41,6 @@ Java_com_swift_sandhook_MainActivity_initHook(JNIEnv *env, jobject instance) { ...@@ -40,6 +41,6 @@ Java_com_swift_sandhook_MainActivity_initHook(JNIEnv *env, jobject instance) {
INLINE_HOOK_TRAMPOLINE(); INLINE_HOOK_TRAMPOLINE();
SandHook::cast_art_method::init(env); SandHook::CastArtMethod::init(env);
} }
\ No newline at end of file
// //
// Created by SwiftGan on 2019/1/17. // Created by SwiftGan on 2019/1/17.
// //
#ifndef SANDHOOK_TRAMPOLINE_CPP
#define SANDHOOK_TRAMPOLINE_CPP
#include "trampoline.h" #include "trampoline.h"
namespace SandHook { namespace SandHook {
...@@ -76,3 +80,4 @@ namespace SandHook { ...@@ -76,3 +80,4 @@ namespace SandHook {
} }
#endif //SANDHOOK_TRAMPOLINE_CPP
...@@ -83,20 +83,20 @@ namespace SandHook { ...@@ -83,20 +83,20 @@ namespace SandHook {
codeLen = codeLength(); codeLen = codeLength();
tempCode = templateCode(); tempCode = templateCode();
} }
const void setExecuteSpace(Code start) { void setExecuteSpace(Code start) {
code = start; code = start;
memcpy(code, tempCode, codeLen); memcpy(code, tempCode, codeLen);
} }
const void codeCopy(Code src, Size targetOffset, Size len) { void codeCopy(Code src, Size targetOffset, Size len) {
memcpy(code + targetOffset, src, len); memcpy(code + targetOffset, src, len);
} }
const void clone(Code dest) { void clone(Code dest) {
memcpy(dest, code, codeLen); memcpy(dest, code, codeLen);
} }
const Code getCode() { Code getCode() {
return code; return code;
} }
const Size getCodeLen() { Size getCodeLen() {
return codeLen; return codeLen;
} }
protected: protected:
......
...@@ -5,10 +5,6 @@ ...@@ -5,10 +5,6 @@
namespace SandHook { namespace SandHook {
void TrampolineManager::init() {
}
Code TrampolineManager::allocExecuteSpace(Size size) { Code TrampolineManager::allocExecuteSpace(Size size) {
if (size > MMAP_PAGE_SIZE) if (size > MMAP_PAGE_SIZE)
return 0; return 0;
...@@ -37,23 +33,99 @@ namespace SandHook { ...@@ -37,23 +33,99 @@ namespace SandHook {
return exeSpace; return exeSpace;
} }
HookTrampoline* TrampolineManager::installReplacementTrampoline(void *originMethod, HookTrampoline* TrampolineManager::installReplacementTrampoline(mirror::ArtMethod *originMethod,
void *hookMethod, mirror::ArtMethod *hookMethod,
void *backupMethod) { mirror::ArtMethod *backupMethod) {
AutoLock autoLock(installLock);
if (trampolines.count(originMethod) != 0) if (trampolines.count(originMethod) != 0)
return getHookTrampoline(originMethod); return getHookTrampoline(originMethod);
HookTrampoline* hookTrampoline = new HookTrampoline(); HookTrampoline* hookTrampoline = new HookTrampoline();
ReplacementHookTrampoline* replacementHookTrampoline = nullptr;
Code replacementHookTrampolineSpace;
replacementHookTrampoline = new ReplacementHookTrampoline();
replacementHookTrampoline->init();
replacementHookTrampolineSpace = allocExecuteSpace(replacementHookTrampoline->getCodeLen());
if (replacementHookTrampolineSpace == 0)
goto label_error;
replacementHookTrampoline->setExecuteSpace(replacementHookTrampolineSpace);
replacementHookTrampoline->setEntryCodeOffset(quickCompileOffset);
replacementHookTrampoline->setHookMethod(reinterpret_cast<Code>(hookMethod));
hookTrampoline->replacement = replacementHookTrampoline;
trampolines[originMethod] = hookTrampoline;
return hookTrampoline;
label_error:
delete hookTrampoline;
delete replacementHookTrampoline;
return nullptr;
} }
HookTrampoline* TrampolineManager::installInlineTrampoline(void *originMethod, void *hookMethod, HookTrampoline* TrampolineManager::installInlineTrampoline(mirror::ArtMethod *originMethod,
void *backupMethod) { mirror::ArtMethod *hookMethod,
mirror::ArtMethod *backupMethod) {
AutoLock autoLock(installLock);
if (trampolines.count(originMethod) != 0) if (trampolines.count(originMethod) != 0)
return getHookTrampoline(originMethod); return getHookTrampoline(originMethod);
HookTrampoline* hookTrampoline = new HookTrampoline(); HookTrampoline* hookTrampoline = new HookTrampoline();
InlineHookTrampoline* inlineHookTrampoline = nullptr;
DirectJumpTrampoline* directJumpTrampoline = nullptr;
ReplacementHookTrampoline* callOriginTrampoline = nullptr;
Code inlineHookTrampolineSpace;
Code callOriginTrampolineSpace;
//生成二段跳板
inlineHookTrampoline = new InlineHookTrampoline;
inlineHookTrampoline->init();
inlineHookTrampolineSpace = allocExecuteSpace(inlineHookTrampoline->getCodeLen());
if (inlineHookTrampolineSpace == 0)
goto label_error;
inlineHookTrampoline->setExecuteSpace(inlineHookTrampolineSpace);
inlineHookTrampoline->setOriginMethod(reinterpret_cast<Code>(originMethod));
inlineHookTrampoline->setHookMethod(reinterpret_cast<Code>(hookMethod));
inlineHookTrampoline->setEntryCodeOffset(quickCompileOffset);
inlineHookTrampoline->setOriginCode(getEntryCode(originMethod));
hookTrampoline->inlineSecondory = inlineHookTrampoline;
DirectJumpTrampoline* directJumpTrampoline = new DirectJumpTrampoline(); //注入 EntryCode
directJumpTrampoline = new DirectJumpTrampoline();
directJumpTrampoline->init();
directJumpTrampoline->setExecuteSpace(getEntryCode(originMethod));
directJumpTrampoline->setJumpTarget(inlineHookTrampoline->getCode());
hookTrampoline->inlineJump = directJumpTrampoline;
//备份原始方法
if (backupMethod) {
callOriginTrampoline = new ReplacementHookTrampoline();
callOriginTrampoline->init();
callOriginTrampolineSpace = allocExecuteSpace(callOriginTrampoline->getCodeLen());
if (callOriginTrampolineSpace == 0)
goto label_error;
callOriginTrampoline->setExecuteSpace(callOriginTrampolineSpace);
callOriginTrampoline->setHookMethod(reinterpret_cast<Code>(originMethod));
callOriginTrampoline->setEntryCodeOffset(quickCompileOffset);
hookTrampoline->callOrigin = callOriginTrampoline;
}
trampolines[originMethod] = hookTrampoline;
return hookTrampoline;
label_error:
delete hookTrampoline;
if (inlineHookTrampoline != nullptr) {
delete inlineHookTrampoline;
}
if (directJumpTrampoline != nullptr) {
delete directJumpTrampoline;
}
if (callOriginTrampoline != nullptr) {
delete callOriginTrampoline;
}
return nullptr;
} }
} }
...@@ -10,39 +10,53 @@ ...@@ -10,39 +10,53 @@
#include "trampoline.cpp" #include "trampoline.cpp"
#include "../utils/lock.h" #include "../utils/lock.h"
#include <sys/mman.h> #include <sys/mman.h>
#include "../casts/art/art.h"
namespace SandHook { namespace SandHook {
#define MMAP_PAGE_SIZE 4 * 1024 #define MMAP_PAGE_SIZE 4 * 1024
using namespace art;
class HookTrampoline { class HookTrampoline {
public: public:
HookTrampoline() = default; HookTrampoline() = default;
Trampoline* replacement; Trampoline* replacement = nullptr;
Trampoline* inlineJump; Trampoline* inlineJump = nullptr;
Trampoline* inlineSecondory; Trampoline* inlineSecondory = nullptr;
Trampoline* callOrigin; Trampoline* callOrigin = nullptr;
}; };
class TrampolineManager { class TrampolineManager {
public: public:
TrampolineManager() = default; TrampolineManager() = default;
void init(); void init(Size quickCompileOffset) {
this->quickCompileOffset = quickCompileOffset;
}
Code allocExecuteSpace(Size size); Code allocExecuteSpace(Size size);
HookTrampoline* installReplacementTrampoline(void* originMethod, void* hookMethod, void* backupMethod); HookTrampoline* installReplacementTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod);
HookTrampoline* installInlineTrampoline(void* originMethod, void* hookMethod, void* backupMethod); HookTrampoline* installInlineTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod);
HookTrampoline* getHookTrampoline(void* method) { HookTrampoline* getHookTrampoline(mirror::ArtMethod* method) {
return trampolines[method]; return trampolines[method];
} }
Code getEntryCode(mirror::ArtMethod* method) {
Size* pEntryAddress = reinterpret_cast<Size*>(method + quickCompileOffset);
Code entryCode = reinterpret_cast<Code>(*pEntryAddress);
}
private: private:
std::map<void*,HookTrampoline*> trampolines = {};
Size quickCompileOffset;
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;
std::mutex installLock; std::mutex installLock;
......
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