static void *exec_addr = nullptr;
jstring mmap_exec(JNIEnv *env, jobject thiz, jbyteArray insnBytes, jint num) {
size_t page_size = sysconf(_SC_PAGE_SIZE);
if (page_size == -1) {
std::cerr << "Failed to get page size!" << std::endl;
return nullptr;
}
void *start_addr = exec_addr;
int flags = MAP_ANON | MAP_PRIVATE;
if (start_addr != nullptr) {
flags |= MAP_FIXED;
}
void *mem = mmap(
start_addr, page_size, PROT_READ | PROT_WRITE | PROT_EXEC,
flags, -1, 0);
if (mem == MAP_FAILED) {
std::cerr << "mmap failed!" << std::endl;
exec_addr = nullptr;
return nullptr;
}
if (exec_addr == nullptr) {
exec_addr = mem;
}
jsize length = env->GetArrayLength((insnBytes));
jbyte *code = env->GetByteArrayElements(insnBytes, nullptr);
std::memcpy(mem, code, length);
aarch64_sync_cache_range(mem, page_size);
func_t func = reinterpret_cast<func_t>(mem);
uint64_t sum = func(num);
munmap(mem, page_size);
env->ReleaseByteArrayElements(insnBytes, code, 0);
char buff[128];
std::sprintf(buff, "[%p] sum[%lu]", mem, sum);
return env->NewStringUTF(buff);
}
__attribute__((visibility("default")))
JNIEXPORT jobjectArray JNICALL
Java_com_example_frida_1stalker_1recompile_1fix_MainActivity_mmapExec(
JNIEnv *env, jobject thiz, jbyteArray inst1, jbyteArray inst2, jint base_num) {
jclass stringCls = env->FindClass("java/lang/String");
const jsize test_num = 20;
jobjectArray resultArray = env->NewObjectArray(test_num, stringCls, nullptr);
for(jsize i = 0; i < test_num; i++) {
jbyteArray inst = i % 2 == 0 ? inst1 : inst2;
jstring result1 = mmap_exec(env, thiz, inst, base_num);
env->SetObjectArrayElement(resultArray, i, result1);
}
return resultArray;
}