Flush CPU cache in YAHFA
This commit is contained in:
parent
87f9ab1f61
commit
6dd10b1fb7
|
|
@ -115,17 +115,6 @@ void *getEntryPoint(void* method) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) {
|
static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) {
|
||||||
if (hookCount >= hookCap) {
|
|
||||||
LOGI("not enough capacity. Allocating...");
|
|
||||||
if (doInitHookCap(DEFAULT_CAP)) {
|
|
||||||
LOGE("cannot hook method");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
LOGI("Allocating done");
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGI("replace method from %p to %p", fromMethod, toMethod);
|
|
||||||
|
|
||||||
// replace entry point
|
// replace entry point
|
||||||
void *newEntrypoint = NULL;
|
void *newEntrypoint = NULL;
|
||||||
if(isBackup) {
|
if(isBackup) {
|
||||||
|
|
@ -157,7 +146,6 @@ static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) {
|
||||||
pointer_size);
|
pointer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
hookCount += 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,6 @@
|
||||||
|
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
static unsigned char *trampolineCode; // place where trampolines are saved
|
|
||||||
static unsigned int trampolineSize; // trampoline size required for each hook
|
|
||||||
|
|
||||||
unsigned int hookCap = 0;
|
|
||||||
unsigned int hookCount = 0;
|
|
||||||
|
|
||||||
// trampoline:
|
// trampoline:
|
||||||
// 1. set eax/rdi/r0/x0 to the hook ArtMethod addr
|
// 1. set eax/rdi/r0/x0 to the hook ArtMethod addr
|
||||||
|
|
@ -127,17 +122,23 @@ unsigned char trampolineForBackup[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
static unsigned int trampolineSize = roundUpToPtrSize(MAX(sizeof(trampoline), sizeof(trampolineForBackup)));
|
|
||||||
|
static inline void FlushCache(void *addr, size_t size) {
|
||||||
|
__builtin___clear_cache((char *) addr, (char *) ((uintptr_t) addr + size));
|
||||||
|
}
|
||||||
|
|
||||||
void *genTrampoline(void *toMethod, void *entrypoint) {
|
void *genTrampoline(void *toMethod, void *entrypoint) {
|
||||||
unsigned char *targetAddr = trampolineCode + trampolineSize * hookCount;
|
size_t size = entrypoint == NULL ? sizeof(trampoline) : sizeof(trampolineForBackup);
|
||||||
|
|
||||||
if(entrypoint != NULL) {
|
// TODO: make use of thread_local to avoid frequent memory allocate
|
||||||
memcpy(targetAddr, trampolineForBackup, sizeof(trampolineForBackup));
|
void *targetAddr = doInitHookCap(size);
|
||||||
}
|
|
||||||
else {
|
if (targetAddr == NULL) return NULL;
|
||||||
memcpy(targetAddr, trampoline,
|
|
||||||
sizeof(trampoline)); // do not use trampolineSize since it's a rounded size
|
if (entrypoint != NULL) {
|
||||||
|
memcpy(targetAddr, trampolineForBackup, size);
|
||||||
|
} else {
|
||||||
|
memcpy(targetAddr, trampoline, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace with the actual ArtMethod addr
|
// replace with the actual ArtMethod addr
|
||||||
|
|
@ -169,17 +170,17 @@ void *genTrampoline(void *toMethod, void *entrypoint) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
if(entrypoint) {
|
if (entrypoint) {
|
||||||
memcpy(targetAddr + 20, &entrypoint, pointer_size);
|
memcpy(targetAddr + 20, &entrypoint, pointer_size);
|
||||||
memcpy(targetAddr + 12, &toMethod, pointer_size);
|
memcpy(targetAddr + 12, &toMethod, pointer_size);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
memcpy(targetAddr + 12, &toMethod, pointer_size);
|
memcpy(targetAddr + 12, &toMethod, pointer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture
|
#error Unsupported architecture
|
||||||
#endif
|
#endif
|
||||||
|
FlushCache(targetAddr, size);
|
||||||
|
|
||||||
return targetAddr;
|
return targetAddr;
|
||||||
}
|
}
|
||||||
|
|
@ -199,23 +200,17 @@ void setupTrampoline(uint8_t offset) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int doInitHookCap(unsigned int cap) {
|
void *doInitHookCap(size_t size) {
|
||||||
if (cap == 0) {
|
if (size == 0) {
|
||||||
LOGE("invalid capacity: %d", cap);
|
LOGE("invalid capacity: %zx", size);
|
||||||
return 1;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (hookCap) {
|
unsigned char *buf = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||||
LOGI("allocating new space for trampoline code");
|
|
||||||
}
|
|
||||||
unsigned int allSize = trampolineSize * cap;
|
|
||||||
unsigned char *buf = mmap(NULL, allSize, PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
||||||
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
if (buf == MAP_FAILED) {
|
if (buf == MAP_FAILED) {
|
||||||
LOGE("mmap failed, errno = %s", strerror(errno));
|
LOGE("mmap failed, errno = %s", strerror(errno));
|
||||||
return 1;
|
return NULL;
|
||||||
}
|
}
|
||||||
hookCap = cap;
|
return buf;
|
||||||
hookCount = 0;
|
|
||||||
trampolineCode = buf;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,10 @@
|
||||||
|
|
||||||
extern int SDKVersion;
|
extern int SDKVersion;
|
||||||
|
|
||||||
extern unsigned int hookCap; // capacity for trampolines
|
|
||||||
extern unsigned int hookCount; // current count of used trampolines
|
|
||||||
|
|
||||||
extern unsigned char trampoline[];
|
extern unsigned char trampoline[];
|
||||||
|
|
||||||
int doInitHookCap(unsigned int cap);
|
void* doInitHookCap(size_t cap);
|
||||||
void setupTrampoline(uint8_t offset);
|
void setupTrampoline(uint8_t offset);
|
||||||
void *genTrampoline(void *toMethod, void *entrypoint);
|
void *genTrampoline(void *toMethod, void *entrypoint);
|
||||||
|
|
||||||
#define DEFAULT_CAP 1 //size of each trampoline area would be no more than 4k Bytes(one page)
|
|
||||||
|
|
||||||
#endif //YAHFA_TAMPOLINE_H
|
#endif //YAHFA_TAMPOLINE_H
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue