diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 639c779..ffc5fc8 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -11,6 +11,7 @@
+
diff --git a/mpcore/build.gradle.kts b/mpcore/build.gradle.kts
index 8b21afd..50206e4 100644
--- a/mpcore/build.gradle.kts
+++ b/mpcore/build.gradle.kts
@@ -10,6 +10,10 @@ android {
defaultConfig {
minSdk = 27
+ ndk {
+ abiFilters += listOf("armeabi-v7a", "x86")
+ }
+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
externalNativeBuild {
diff --git a/mpcore/src/main/cpp/main.cpp b/mpcore/src/main/cpp/main.cpp
new file mode 100644
index 0000000..b84ec35
--- /dev/null
+++ b/mpcore/src/main/cpp/main.cpp
@@ -0,0 +1,33 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include "main.h"
+#include "util/util.h"
+#include
+#include
+
+// Callback для dl_iterate_phdr
+static int find_libapp_callback(struct dl_phdr_info *info, size_t size, void *data) {
+ if (strstr(info->dlpi_name, "libapp.so")) {
+ libapp = (void *) info->dlpi_addr;
+ return 1; // Останавливаем перебор
+ }
+ return 0;
+}
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
+ // Ищем libapp.so
+ dl_iterate_phdr(find_libapp_callback, NULL);
+
+ if (libapp) {
+ __android_log_print(ANDROID_LOG_INFO, "MyLib", "libapp.so base: %p", libapp);
+ } else {
+ __android_log_print(ANDROID_LOG_ERROR, "MyLib", "libapp.so not found!");
+ return JNI_ERR;
+ }
+
+ return JNI_VERSION_1_6;
+}
\ No newline at end of file
diff --git a/mpcore/src/main/cpp/main.h b/mpcore/src/main/cpp/main.h
new file mode 100644
index 0000000..7684fd5
--- /dev/null
+++ b/mpcore/src/main/cpp/main.h
@@ -0,0 +1,6 @@
+
+//Основная ссылка на начало основного процесса - libapp.so
+static void* libapp = nullptr;
+
+//Макрос для ссылок внутри памяти процесса
+#define APP_ADDR(addr) ((uintptr_t)libapp + (addr))
diff --git a/mpcore/src/main/cpp/util/armhook.cpp b/mpcore/src/main/cpp/util/armhook.cpp
new file mode 100644
index 0000000..23df63b
--- /dev/null
+++ b/mpcore/src/main/cpp/util/armhook.cpp
@@ -0,0 +1,198 @@
+#include // system api
+#include // assert()
+#include // dlopen
+#include
+#include
+#include
+#include "armhook.h"
+#include "util.h"
+#include "../main.h"
+
+uintptr_t mmap_start = 0;
+uintptr_t mmap_end = 0;
+uintptr_t memlib_start = 0;
+uintptr_t memlib_end = 0;
+
+//#define PAGE_SIZE 0x8124
+
+#define HOOK_PROC "\x01\xB4\x01\xB4\x01\x48\x01\x90\x01\xBD\x00\xBF\x00\x00\x00\x00"
+
+
+void unProtect(uintptr_t ptr, size_t dwSize)
+{
+ if(mprotect(reinterpret_cast(ptr & 0xFFFFF000), PAGE_SIZE, PROT_WRITE | PROT_READ | PROT_EXEC) == -1)
+ {
+ const auto err = errno;
+
+ if(err == EACCES)
+ {
+ mprotect(reinterpret_cast(ptr & 0xFFFFF000), PAGE_SIZE, PROT_WRITE | PROT_READ);
+ return;
+ }
+ }
+}
+
+
+void makeNOP(uintptr_t addr, unsigned int count)
+{
+ Log("Hello from makeNOP!");
+ unProtect(addr);
+
+ for(uintptr_t ptr = addr; ptr != (addr+(count * 2)); ptr += 2)
+ {
+ Log("Hello from loop makeNOP!");
+ *(char*)ptr = 0x00;
+ *(char*)(ptr+1) = 0x46;
+ }
+
+ //cacheflush(addr, (uintptr_t)(addr + count * 2), 0);
+}
+
+void WriteMemory(uintptr_t dest, uintptr_t src, size_t size)
+{
+ unProtect(dest);
+ memcpy((void*)dest, (void*)src, size);
+ //cacheflush(dest, dest+size, 0);
+}
+void WriteMemory(uintptr_t dest, void* src, size_t size)
+{
+ unProtect(dest);
+ memcpy((void*)dest, src, size);
+ //cacheflush(dest, dest+size, 0);
+}
+void SetPointer(uintptr_t addr, void* value)
+{
+ WriteMemory(addr, &value, sizeof(value));
+}
+void ReadMemory(uintptr_t dest, uintptr_t src, size_t size)
+{
+ unProtect(src);
+ memcpy((void*)dest, (void*)src, size);
+}
+
+
+void InitHookStuff()
+{
+ memlib_start = APP_ADDR(0x000A1B44);
+ memlib_end = memlib_start + 0x1A36;
+
+ mmap_start = (uintptr_t)mmap(0, PAGE_SIZE, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ int code = mprotect((void*)(mmap_start & 0xFFFFF000), PAGE_SIZE, PROT_READ | PROT_EXEC | PROT_WRITE);
+ mmap_end = (mmap_start + PAGE_SIZE);
+
+ /*const auto err = errno;
+
+ Log("Status is %d && %d", err, code);
+
+ Log("mmap_stat = 0x%08x", mmap_start);
+ Log("mmap_end = 0x%08x", mmap_end);
+
+ Log("memlib_start = 0x%08x", memlib_start);
+ Log("memlib_end = 0x%08x", memlib_end);*/
+
+ //unProtect(APP_ADDR(0x1800AC));
+
+}
+
+void makeJMP(uintptr_t func, uintptr_t addr)
+{
+ uint32_t code = ((addr - func - 4) >> 12) & 0x7FF | 0xF000 | ((((addr - func - 4) >> 1) & 0x7FF | 0xB800) << 16);
+ WriteMemory(func, (uintptr_t)&code, 4);
+}
+
+void makeBLX(uintptr_t func, uintptr_t addr)
+{
+ uint32_t code = ((addr - func - 4) >> 12) & 0x7FF | ((addr - func - 4) << 15) | 0xF800F000;
+ WriteMemory(func, (uintptr_t)&code, 4);
+}
+
+void WriteHookProc(uintptr_t addr, uintptr_t func)
+{
+ char code[16];
+
+ memcpy(code, HOOK_PROC, 16);
+ *(uint32_t*)&code[12] = (func | 1);
+
+ WriteMemory(addr, (uintptr_t)code, 16);
+}
+
+void InstallBLXHook(uintptr_t addr, uintptr_t func)
+{
+ // memlib_start = 0
+ // memlib_end = 10
+
+ if(memlib_end < (memlib_start + 0x10) || mmap_end < (mmap_start + 0x20))
+ {
+ std::terminate();
+ }
+
+ makeBLX(addr, func);
+ WriteHookProc(addr, func);
+
+ memlib_start += 16;
+}
+
+void InstallJMPHook(uintptr_t addr, uintptr_t func)
+{
+
+ if(memlib_end < (memlib_start + 0x10) || mmap_end < (mmap_start + 0x20))
+ {
+ std::terminate();
+ }
+
+ makeJMP(addr, func);
+ WriteHookProc(addr, func);
+
+ memlib_start += 16;
+}
+
+void InstallHook(uintptr_t addr, uintptr_t func, uintptr_t *orig)
+{
+
+ if(memlib_end < (memlib_start + 0x10) || mmap_end < (mmap_start + 0x20))
+ {
+ Log("FAILED!");
+ std::terminate();
+ }
+
+ ReadMemory(mmap_start, addr, 4);
+ WriteHookProc(mmap_start+4, addr+4);
+ *orig = mmap_start+1;
+ mmap_start += 32;
+
+ makeJMP(addr, memlib_start);
+ WriteHookProc(memlib_start, func);
+ memlib_start += 16;
+}
+
+void RedirectCall(uintptr_t addr, uintptr_t func)
+{
+ makeJMP(addr, memlib_start);
+ WriteHookProc(memlib_start, func);
+ memlib_start += 16;
+}
+
+void InstallMethodHook(uintptr_t addr, uintptr_t func)
+{
+ unProtect(addr);
+ *(uintptr_t*)addr = func;
+}
+
+void CodeInject(uintptr_t addr, uintptr_t func, int reg)
+{
+
+ char injectCode[12];
+
+ injectCode[0] = 0x01;
+ injectCode[1] = 0xA0 + reg;
+ injectCode[2] = (0x08 * reg) + reg;
+ injectCode[3] = 0x68;
+ injectCode[4] = 0x87 + (0x08 * reg);
+ injectCode[5] = 0x46;
+ injectCode[6] = injectCode[4];
+ injectCode[7] = injectCode[5];
+
+ *(uintptr_t*)&injectCode[8] = func;
+
+ WriteMemory(addr, (uintptr_t)injectCode, 12);
+}
\ No newline at end of file
diff --git a/mpcore/src/main/cpp/util/armhook.h b/mpcore/src/main/cpp/util/armhook.h
new file mode 100644
index 0000000..f32db9c
--- /dev/null
+++ b/mpcore/src/main/cpp/util/armhook.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include
+
+extern uintptr_t mmap_start;
+extern uintptr_t mmap_end;
+extern uintptr_t memlib_start;
+extern uintptr_t memlib_end;
+
+void unProtect(uintptr_t ptr, size_t dwSize = 100);
+
+void WriteMemory(uintptr_t dest, uintptr_t src, size_t size);
+void ReadMemory(uintptr_t dest, uintptr_t src, size_t size);
+
+void makeNOP(uintptr_t addr, unsigned int count);
+void makeJMP(uintptr_t func, uintptr_t addr);
+void makeBLX(uintptr_t func, uintptr_t addr);
+
+void InitHookStuff();
+
+void InstallHook(uintptr_t addr, uintptr_t func, uintptr_t *orig);
+void InstallMethodHook(uintptr_t addr, uintptr_t func);
+void InstallJMPHook(uintptr_t addr, uintptr_t func);
+void InstallBLXHook(uintptr_t addr, uintptr_t func);
+
+void CodeInject(uintptr_t addr, uintptr_t func, int reg);
+
+void WriteMemory(uintptr_t dest, void* src, size_t size);
+void SetPointer(uintptr_t addr, void* value);
+
+template
+static Ret CallFunction(unsigned int address, Args... args)
+{
+ return reinterpret_cast(address)(args...);
+}
\ No newline at end of file
diff --git a/mpcore/src/main/cpp/util/util.cpp b/mpcore/src/main/cpp/util/util.cpp
new file mode 100644
index 0000000..b805cc9
--- /dev/null
+++ b/mpcore/src/main/cpp/util/util.cpp
@@ -0,0 +1,52 @@
+#include
+#include
+#include
+#include
+#include "util.h"
+
+uintptr_t FindLibrary(const char *lib_name) {
+ char filename[0xFF] = {0},
+ buffer[2048] = {0};
+ FILE *fp = 0;
+ uintptr_t address = 0;
+
+ sprintf(filename, "/proc/%d/maps", getpid());
+
+ fp = fopen(filename, "rt");
+ if (fp == nullptr) {
+ Log("ERROR: can't open file %s", filename);
+ goto done;
+ }
+
+
+ while (fgets(buffer, sizeof(buffer), fp)) {
+ if (strstr(buffer, lib_name)) {
+ address = (uintptr_t) strtoul(buffer, 0, 16);
+ break;
+ }
+ }
+ done:
+
+ if (fp)
+ fclose(fp);
+
+ return address;
+}
+
+void Log(const char *fmt, ...) {
+ char buffer[0xFF];
+ static FILE *flLog = nullptr;
+
+ memset(buffer, 0, sizeof(buffer));
+
+ va_list arg;
+ va_start(arg, fmt);
+ vsnprintf(buffer, sizeof(buffer), fmt, arg);
+ va_end(arg);
+
+ __android_log_write(ANDROID_LOG_INFO, "mpcore_log", buffer);
+
+ if (flLog == nullptr) return;
+ fprintf(flLog, "%s\n", buffer);
+ fflush(flLog);
+}
\ No newline at end of file
diff --git a/mpcore/src/main/cpp/util/util.h b/mpcore/src/main/cpp/util/util.h
new file mode 100644
index 0000000..899b21c
--- /dev/null
+++ b/mpcore/src/main/cpp/util/util.h
@@ -0,0 +1,5 @@
+#pragma once
+
+uintptr_t FindLibrary(const char* lib_name);
+
+void Log(const char *fmt, ...);
\ No newline at end of file