Commit a482565f authored by swift_gan's avatar swift_gan

reconstitution

parent 0d3eb16a
......@@ -21,6 +21,10 @@ add_library( # Sets the name of the library.
src/main/cpp/trampoline/trampoline.cpp
src/main/cpp/trampoline/trampoline_manager.cpp
src/main/cpp/utils/fake_dlfcn.cpp
src/main/cpp/utils/utils.cpp
src/main/cpp/utils/offset.cpp
src/main/cpp/casts/cast_art_method.cpp
src/main/cpp/art/art_method.cpp
src/main/cpp/trampoline/arch/arm32.S
src/main/cpp/trampoline/arch/arm64.S
)
......
......@@ -13,7 +13,7 @@ android {
externalNativeBuild {
cmake {
arguments '-DBUILD_TESTING=OFF', '-DANDROID_TOOLCHAIN=gcc'
arguments '-DBUILD_TESTING=OFF'
cppFlags "-frtti -fexceptions"
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
......
//
// Created by swift on 2019/2/3.
//
#include <cstdint>
#include "../includes/art_method.h"
#include "../includes/cast_art_method.h"
using namespace art::mirror;
void ArtMethod::setStatic() {
};
void ArtMethod::tryDisableInline() {
}
void ArtMethod::disableInterpreterForO() {
}
void ArtMethod::disableCompilable() {
}
bool ArtMethod::isAbstract() {
}
bool ArtMethod::isNative() {
}
void ArtMethod::setAccessFlags(uint32_t flags) {
}
void ArtMethod::setPrivate() {
}
//
// Created by swift on 2019/2/3.
//
#include <cstdint>
#include "art.h"
#include <../cast_art_method.h>
namespace art::mirror {
void ArtMethod::setStatic() {
};
void ArtMethod::tryDisableInline() {
}
void ArtMethod::disableInterpreterForO() {
}
void ArtMethod::disableCompilable() {
}
bool ArtMethod::isAbstract() {
}
bool ArtMethod::isNative() {
}
void ArtMethod::setAccessFlags(uint32_t flags) {
}
void ArtMethod::setPrivate() {
}
}
\ No newline at end of file
......@@ -5,8 +5,6 @@
#ifndef SANDHOOK_ARCH_H
#define SANDHOOK_ARCH_H
namespace SandHook {
#define BYTE_POINT sizeof(void*)
//32bit
......@@ -45,7 +43,4 @@ static void clearCacheArm32(char* begin, char *end)
#define ANDROID_O2 27
#define ANDROID_P 28
}
#endif //SANDHOOK_ARCH_H
\ No newline at end of file
......@@ -15,7 +15,7 @@
namespace SandHook {
int SDK_INT = 0;
static int SDK_INT = 0;
template <typename T>
class cast {
......@@ -59,6 +59,22 @@ namespace SandHook {
memcpy(reinterpret_cast<void *>((Size)p + getOffset()), &t, sizeof(MType));
};
template<typename T>
int findOffset(void *start, size_t len, size_t step, T value) {
if (NULL == start) {
return -1;
}
for (int i = 0; i <= len; i += step) {
T current_value = *reinterpret_cast<T *>((size_t) start + i);
if (value == current_value) {
return i;
}
}
return -1;
}
private:
Size offset = 0;
protected:
......
//
// Created by 甘尧 on 2019/1/12.
//
#ifndef SANDHOOK_CAST_ART_METHOD_H
#define SANDHOOK_CAST_ART_METHOD_H
#include "cast.h"
#include "trampoline_manager.h"
namespace SandHook {
class CastArtMethod {
public:
static Size size;
static IMember<art::mirror::ArtMethod, void*>* entryPointQuickCompiled;
static IMember<art::mirror::ArtMethod, void*>* entryPointFormInterpreter;
static ArrayMember<art::mirror::ArtMethod,void*>* dexCacheResolvedMethods;
static IMember<art::mirror::ArtMethod, uint32_t>* dexMethodIndex;
static IMember<art::mirror::ArtMethod, uint32_t>* accessFlag;
static void* quickToInterpreterBridge;
static void* genericJniStub;
static void* staticResolveStub;
static void init(JNIEnv *env, int sdk);
static void copy(art::mirror::ArtMethod* from, art::mirror::ArtMethod* to);
};
}
#endif //SANDHOOK_CAST_ART_METHOD_H
//
// Created by swift on 2019/2/3.
//
#ifndef SANDHOOK_OFFSET_H
#define SANDHOOK_OFFSET_H
#include <unistd.h>
namespace SandHook {
class Offset {
public:
template<typename T>
static int findOffset(void *start, size_t len, size_t step, T value);
template<typename T>
static int findOffsetWithCB1(void *start, size_t len, size_t step, bool func(int, T));
template<typename T>
static int findOffsetWithCB2(void *start1, void *start2, size_t len, size_t step, bool func(T, T));
};
}
#endif //SANDHOOK_OFFSET_H
......@@ -7,8 +7,8 @@
#include <cstdint>
#include <string.h>
#include "../includes/arch.h"
#include "./arch/base.h"
#include "arch.h"
#include "arch_base.h"
#include "stdlib.h"
#include <sys/mman.h>
......
......@@ -7,10 +7,10 @@
#include "map"
#include "list"
#include "trampoline.cpp"
#include "../trampoline/trampoline.cpp"
#include "../utils/lock.h"
#include <sys/mman.h>
#include "../casts/art/art.h"
#include "art_method.h"
#include <unistd.h>
namespace SandHook {
......@@ -45,8 +45,7 @@ namespace SandHook {
Code allocExecuteSpace(Size size);
HookTrampoline* installReplacementTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod);
HookTrampoline* installInlineTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod,
bool isNative);
HookTrampoline* installInlineTrampoline(mirror::ArtMethod* originMethod, mirror::ArtMethod* hookMethod, mirror::ArtMethod* backupMethod);
bool canSafeInline(mirror::ArtMethod* method, char* msg);
......
......@@ -8,112 +8,20 @@
#include <stdlib.h>
#include <sys/mman.h>
#include "jni.h"
#include "../includes/arch.h"
#include <unistd.h>
template<typename T>
int findOffset(void *start, size_t len,size_t step,T value) {
extern "C" {
if (NULL == start) {
return -1;
}
Size getAddressFromJava(JNIEnv *env, char *className, char *fieldName);
for (int i = 0; i <= len; i += step) {
T current_value = *reinterpret_cast<T*>((size_t)start + i);
if (value == current_value) {
return i;
}
}
return -1;
}
template<typename T>
int findOffsetWithCB1(void *start, size_t len,size_t step, bool func(int, T)) {
if (NULL == start) {
return -1;
}
for (int i = 0; i <= len; i += step) {
T current_value = *reinterpret_cast<T*>((size_t)start + i);
if (func(i, current_value)) {
return i;
}
}
return -1;
}
template<typename T>
int findOffsetWithCB2(void *start1, void *start2, size_t len,size_t step, bool func(T,T)) {
if (NULL == start1 || NULL == start2) {
return -1;
}
for (int i = 0; i <= len; i += step) {
T v1 = *reinterpret_cast<T*>((size_t)start1 + i);
T v2 = *reinterpret_cast<T*>((size_t)start2 + i);
if (func(v1, v2)) {
return i;
}
}
Size getAddressFromJavaByCallMethod(JNIEnv *env, char *className, char *methodName);
return -1;
}
Size getAddressFromJava(JNIEnv* env, char* className, char* fieldName) {
jclass clazz = env -> FindClass(className);
if (clazz == NULL){
printf("find class error !");
return 0;
}
jfieldID id = env -> GetStaticFieldID(clazz, fieldName, "J");
if (id == NULL){
printf("find field error !");
return 0;
}
return env -> GetStaticLongField(clazz, id);
}
jint getIntFromJava(JNIEnv *env, char *className, char *fieldName);
Size getAddressFromJavaByCallMethod(JNIEnv* env, char* className, char* methodName) {
jclass clazz = env -> FindClass(className);
if (clazz == NULL){
printf("find class error !");
return 0;
}
jmethodID id = env -> GetStaticMethodID(clazz, methodName, "()J");
if (id == NULL){
printf("find field error !");
return 0;
}
return env -> CallStaticLongMethodA(clazz, id, nullptr);
}
jint getIntFromJava(JNIEnv* env, char* className, char* fieldName) {
jclass clazz = env -> FindClass(className);
if (clazz == NULL){
printf("find class error !");
return 0;
}
jfieldID id = env -> GetStaticFieldID(clazz, fieldName, "I");
if (id == NULL){
printf("find field error !");
return 0;
}
return env -> GetStaticIntField(clazz, id);
}
bool munprotect(size_t addr, size_t len);
bool munprotect(size_t addr, size_t len) {
long pagesize = sysconf(_SC_PAGESIZE);
unsigned alignment = (unsigned)((unsigned long long)addr % pagesize);
int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len),
PROT_READ | PROT_WRITE | PROT_EXEC);
if (i == -1) {
return false;
}
return true;
}
#endif //SANDHOOK_UTILS_H
#include <jni.h>
#include "casts/cast_art_method.h"
#include "./trampoline/trampoline_manager.h"
#include "includes/cast_art_method.h"
#include "includes/trampoline_manager.h"
#include "./utils/hide_api.h"
SandHook::TrampolineManager trampolineManager;
......@@ -85,14 +85,14 @@ void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMeth
} else {
int cacheSize = 1024;
Size slotIndex = index % cacheSize;
void *newCachedMethodsArray = calloc(cacheSize, BYTE_POINT * 2);
Size newCachedMethodsArray = reinterpret_cast<Size>(calloc(cacheSize, BYTE_POINT * 2));
unsigned int one = 1;
memcpy(newCachedMethodsArray + BYTE_POINT, &one, 4);
memcpy(newCachedMethodsArray + BYTE_POINT * 2 * slotIndex,
memcpy(reinterpret_cast<void *>(newCachedMethodsArray + BYTE_POINT), &one, 4);
memcpy(reinterpret_cast<void *>(newCachedMethodsArray + BYTE_POINT * 2 * slotIndex),
(&backupMethod),
BYTE_POINT
);
memcpy(newCachedMethodsArray + BYTE_POINT * 2 * slotIndex + BYTE_POINT,
memcpy(reinterpret_cast<void *>(newCachedMethodsArray + BYTE_POINT * 2 * slotIndex + BYTE_POINT),
&index,
4
);
......@@ -157,7 +157,7 @@ bool doHookWithInline(JNIEnv* env,
tryDisableInline(originMethod);
SandHook::HookTrampoline* hookTrampoline = trampolineManager.installInlineTrampoline(originMethod, hookMethod, backupMethod, isNative(originMethod));
SandHook::HookTrampoline* hookTrampoline = trampolineManager.installInlineTrampoline(originMethod, hookMethod, backupMethod);
if (hookTrampoline == nullptr)
return false;
......
#include "base.h"
#include "../../includes/arch_base.h"
#if defined(__arm__)
......
#include "base.h"
#include "../../includes/arch_base.h"
/**
*
......
......@@ -5,7 +5,7 @@
#ifndef SANDHOOK_TRAMPOLINE_CPP
#define SANDHOOK_TRAMPOLINE_CPP
#include "trampoline.h"
#include "../includes/trampoline.h"
namespace SandHook {
......
//
// Created by swift on 2019/1/20.
//
#include "trampoline_manager.h"
#include "trampoline.h"
#include "../includes/trampoline_manager.h"
#include "../includes/trampoline.h"
namespace SandHook {
......@@ -20,11 +20,16 @@ namespace SandHook {
bool TrampolineManager::canSafeInline(mirror::ArtMethod *method, char *msg) {
//check size
if (!isNative) {
uint32_t originCodeSize = sizeOfEntryCode(originMethod);
if (originCodeSize < SIZE_DIRECT_JUMP_TRAMPOLINE)
goto label_error;
if (!method->isNative()) {
uint32_t originCodeSize = sizeOfEntryCode(method);
if (originCodeSize < SIZE_DIRECT_JUMP_TRAMPOLINE) {
msg = "code entry size < inject code size";
return false;
}
}
//TODO
//check pc relate inst
return true;
}
Code TrampolineManager::allocExecuteSpace(Size size) {
......
......@@ -113,9 +113,9 @@ void *fake_dlopen(const char *libpath, int flags) {
if (!ctx) fatal("no memory for %s", libpath);
ctx->load_addr = (void *) load_addr;
shoff = ((void *) elf) + elf->e_shoff;
shoff = reinterpret_cast<void *>(((size_t) elf) + elf->e_shoff);
for (k = 0; k < elf->e_shnum; k++, shoff += elf->e_shentsize) {
for (k = 0; k < elf->e_shnum; k++, shoff = reinterpret_cast<void *>((size_t)shoff + elf->e_shentsize)) {
Elf_Shdr *sh = (Elf_Shdr *) shoff;
log_dbg("%s: k=%d shdr=%p type=%x", __func__, k, sh, sh->sh_type);
......@@ -126,7 +126,7 @@ void *fake_dlopen(const char *libpath, int flags) {
if (ctx->dynsym) fatal("%s: duplicate DYNSYM sections", libpath); /* .dynsym */
ctx->dynsym = malloc(sh->sh_size);
if (!ctx->dynsym) fatal("%s: no memory for .dynsym", libpath);
memcpy(ctx->dynsym, ((void *) elf) + sh->sh_offset, sh->sh_size);
memcpy(ctx->dynsym, reinterpret_cast<const void *>(((size_t) elf) + sh->sh_offset), sh->sh_size);
ctx->nsyms = (sh->sh_size / sizeof(Elf_Sym));
break;
......@@ -134,7 +134,7 @@ void *fake_dlopen(const char *libpath, int flags) {
if (ctx->dynstr) break; /* .dynstr is guaranteed to be the first STRTAB */
ctx->dynstr = malloc(sh->sh_size);
if (!ctx->dynstr) fatal("%s: no memory for .dynstr", libpath);
memcpy(ctx->dynstr, ((void *) elf) + sh->sh_offset, sh->sh_size);
memcpy(ctx->dynstr, reinterpret_cast<const void *>(((size_t) elf) + sh->sh_offset), sh->sh_size);
break;
case SHT_PROGBITS:
......@@ -174,7 +174,7 @@ void *fake_dlsym(void *handle, const char *name) {
if (strcmp(strings + sym->st_name, name) == 0) {
/* NB: sym->st_value is an offset into the section for relocatables,
but a VMA for shared libs or exe files, so we have to subtract the bias */
void *ret = ctx->load_addr + sym->st_value - ctx->bias;
void *ret = reinterpret_cast<void *>((size_t)ctx->load_addr + sym->st_value - ctx->bias);
log_info("%s found at %p", name, ret);
return ret;
}
......
......@@ -16,13 +16,10 @@ bool (*jitCompileMethod)(void*, void*, void*, bool) = nullptr;
void initHideApi(JNIEnv* env, int SDK_VERSION) {
if (SDK_VERSION >= 24) {
void *handle;
void *jit_lib;
if (sizeof(void*) == 8) {
handle = fake_dlopen("/system/lib64/libart.so", RTLD_NOW);
jit_lib = fake_dlopen("/system/lib64/libart-compiler.so", RTLD_NOW);
} else {
handle = fake_dlopen("/system/lib/libart.so", RTLD_NOW);
jit_lib = fake_dlopen("/system/lib/libart-compiler.so", RTLD_NOW);
}
jitCompileMethod = (bool (*)(void *, void *, void *, bool)) fake_dlsym(jit_lib, "jit_compile_method");
......
//
// Created by swift on 2019/2/3.
//
#include "../includes/offset.h"
namespace SandHook {
template<typename T>
int Offset::findOffset(void *start, size_t len, size_t step, T value) {
if (NULL == start) {
return -1;
}
for (int i = 0; i <= len; i += step) {
T current_value = *reinterpret_cast<T *>((size_t) start + i);
if (value == current_value) {
return i;
}
}
return -1;
}
template<typename T>
int Offset::findOffsetWithCB1(void *start, size_t len, size_t step, bool func(int, T)) {
if (NULL == start) {
return -1;
}
for (int i = 0; i <= len; i += step) {
T current_value = *reinterpret_cast<T *>((size_t) start + i);
if (func(i, current_value)) {
return i;
}
}
return -1;
}
template<typename T>
int Offset::findOffsetWithCB2(void *start1, void *start2, size_t len, size_t step, bool func(T, T)) {
if (NULL == start1 || NULL == start2) {
return -1;
}
for (int i = 0; i <= len; i += step) {
T v1 = *reinterpret_cast<T *>((size_t) start1 + i);
T v2 = *reinterpret_cast<T *>((size_t) start2 + i);
if (func(v1, v2)) {
return i;
}
}
return -1;
}
}
//
// Created by swift on 2019/2/3.
//
#include "../includes/utils.h"
Size getAddressFromJava(JNIEnv *env, char *className, char *fieldName) {
jclass clazz = env->FindClass(className);
if (clazz == NULL) {
printf("find class error !");
return 0;
}
jfieldID id = env->GetStaticFieldID(clazz, fieldName, "J");
if (id == NULL) {
printf("find field error !");
return 0;
}
return env->GetStaticLongField(clazz, id);
}
Size getAddressFromJavaByCallMethod(JNIEnv *env, char *className, char *methodName) {
jclass clazz = env->FindClass(className);
if (clazz == NULL) {
printf("find class error !");
return 0;
}
jmethodID id = env->GetStaticMethodID(clazz, methodName, "()J");
if (id == NULL) {
printf("find field error !");
return 0;
}
return env->CallStaticLongMethodA(clazz, id, nullptr);
}
jint getIntFromJava(JNIEnv *env, char *className, char *fieldName) {
jclass clazz = env->FindClass(className);
if (clazz == NULL) {
printf("find class error !");
return 0;
}
jfieldID id = env->GetStaticFieldID(clazz, fieldName, "I");
if (id == NULL) {
printf("find field error !");
return 0;
}
return env->GetStaticIntField(clazz, id);
}
bool munprotect(size_t addr, size_t len) {
long pagesize = sysconf(_SC_PAGESIZE);
unsigned alignment = (unsigned) ((unsigned long long) addr % pagesize);
int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len),
PROT_READ | PROT_WRITE | PROT_EXEC);
if (i == -1) {
return false;
}
return true;
}
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