From 4296b5d20b0e2f8bba5bc5e4879fb4c88673805d Mon Sep 17 00:00:00 2001 From: megboyzz Date: Sun, 26 Jan 2025 10:55:07 +0300 Subject: [PATCH] try to cut nimble --- .../easp/VirtualKeyboardAndroidDelegate.java | 4 +- .../java/com/ea/ironmonkey/GameActivity.kt | 2 +- .../{libnimble.so => libnimble.so1} | Bin gradle/libs.versions.toml | 2 +- mpcore/src/main/cpp/CMakeLists.txt | 4 +- mpcore/src/main/cpp/main.cpp | 73 +++++++ mpcore/src/main/cpp/main.h | 6 + mpcore/src/main/cpp/mpcore.cpp | 10 - mpcore/src/main/cpp/util/armhook.cpp | 198 ++++++++++++++++++ mpcore/src/main/cpp/util/armhook.h | 35 ++++ mpcore/src/main/cpp/util/util.cpp | 52 +++++ mpcore/src/main/cpp/util/util.h | 5 + 12 files changed, 376 insertions(+), 15 deletions(-) rename app/src/main/jniLibs/armeabi-v7a/{libnimble.so => libnimble.so1} (100%) create mode 100644 mpcore/src/main/cpp/main.cpp create mode 100644 mpcore/src/main/cpp/main.h delete mode 100644 mpcore/src/main/cpp/mpcore.cpp create mode 100644 mpcore/src/main/cpp/util/armhook.cpp create mode 100644 mpcore/src/main/cpp/util/armhook.h create mode 100644 mpcore/src/main/cpp/util/util.cpp create mode 100644 mpcore/src/main/cpp/util/util.h diff --git a/app/src/main/java/com/ea/easp/VirtualKeyboardAndroidDelegate.java b/app/src/main/java/com/ea/easp/VirtualKeyboardAndroidDelegate.java index 971bc92..ac42b11 100644 --- a/app/src/main/java/com/ea/easp/VirtualKeyboardAndroidDelegate.java +++ b/app/src/main/java/com/ea/easp/VirtualKeyboardAndroidDelegate.java @@ -9,7 +9,7 @@ import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.RelativeLayout; -import com.ea.nimble.Log; +//import com.ea.nimble.Log; public class VirtualKeyboardAndroidDelegate extends KeyboardAndroid { private static final boolean DEBUG_LOG_ENABLED = true; @@ -36,7 +36,7 @@ public class VirtualKeyboardAndroidDelegate extends KeyboardAndroid { private volatile int mKeyboardLayout = 1; private Activity mMainActivity; public ViewGroup mMainViewGroup; - public int mMaxTextLength = Log.LEVEL_INFO; + public int mMaxTextLength = 1;//Log.LEVEL_INFO; public String mNewText; private boolean mPhysicalKeyboardVisible = false; public RelativeLayout mRelativeLayout; diff --git a/app/src/main/java/com/ea/ironmonkey/GameActivity.kt b/app/src/main/java/com/ea/ironmonkey/GameActivity.kt index 28c4185..4254532 100644 --- a/app/src/main/java/com/ea/ironmonkey/GameActivity.kt +++ b/app/src/main/java/com/ea/ironmonkey/GameActivity.kt @@ -40,7 +40,7 @@ import kotlin.system.exitProcess class GameActivity : ComponentActivity(), DrawFrameListener { init { - System.loadLibrary("nimble") + //System.loadLibrary("nimble") System.loadLibrary("app") } diff --git a/app/src/main/jniLibs/armeabi-v7a/libnimble.so b/app/src/main/jniLibs/armeabi-v7a/libnimble.so1 similarity index 100% rename from app/src/main/jniLibs/armeabi-v7a/libnimble.so rename to app/src/main/jniLibs/armeabi-v7a/libnimble.so1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 18af5c6..ec23657 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.1.2" +agp = "8.3.2" compose-settings-ui-m3 = "1.0.3" junit-junit = "4.13.2" kotlin = "1.9.21" diff --git a/mpcore/src/main/cpp/CMakeLists.txt b/mpcore/src/main/cpp/CMakeLists.txt index f125423..a710fa2 100644 --- a/mpcore/src/main/cpp/CMakeLists.txt +++ b/mpcore/src/main/cpp/CMakeLists.txt @@ -3,7 +3,9 @@ cmake_minimum_required(VERSION 3.22.1) project("mpcore") add_library(${CMAKE_PROJECT_NAME} SHARED - mpcore.cpp) + main.cpp + util/util.cpp + util/armhook.cpp) target_link_libraries(${CMAKE_PROJECT_NAME} android diff --git a/mpcore/src/main/cpp/main.cpp b/mpcore/src/main/cpp/main.cpp new file mode 100644 index 0000000..d581ada --- /dev/null +++ b/mpcore/src/main/cpp/main.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include "main.h" +#include "util/util.h" + +#include "util/armhook.h" + +uintptr_t libapp = 0; + +int (*print_internal_log)(int a1, const char *a2, ...); + +void pending_thread(){ + + Log("Hello from thread!"); + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + + + int unk = APP_ADDR(0x00E4B8EC); + print_internal_log(unk, "Hello!"); + + unProtect(APP_ADDR(0x00E4A738)); + + +} + + +jint JNI_OnLoad(JavaVM *vm, void *reserved){ + + libapp = FindLibrary("libapp.so"); + Log("Hello! my base addr is 0x%08x", libapp); + + //InitHookStuff(); + + //unProtect(APP_ADDR(0x00A522C4)); + //*(int *)APP_ADDR(0x00A522C4) = 0xE320F000; + + //WriteMemory(APP_ADDR(0x00E4BA94), (uintptr_t)"my_tag", 6); + raise(SIGSTOP); + + return JNI_VERSION_1_6; +} + +/* + +Log("Hello! my base addr is 0x%08x", libapp); + Log("Address i wanna to get 0x%08x", APP_ADDR(0xC8C9D8)); + + const char* str = (char *)APP_ADDR(0xC8C9D8); + + Log("i found it! %s", str); + + unProtect(APP_ADDR(0xC8C9D8)); + + WriteMemory(APP_ADDR(0xC8C9D8), (uintptr_t)"APPLICATION_NO", 14); + + str = (char *)APP_ADDR(0xC8C9D8); + + Log("i change it! %s", str); + + //makeNOP(APP_ADDR(0x00652EB4), 2); + //makeNOP(APP_ADDR(0x00652E3C), 2); + + unProtect(APP_ADDR(0x00652EB4)); + *(char *)APP_ADDR(0x00652EB4) = 0xE320F000; + + unProtect(APP_ADDR(0x00652E3C)); + *(char *)APP_ADDR(0x00652E3C) = 0xE320F000; + + */ diff --git a/mpcore/src/main/cpp/main.h b/mpcore/src/main/cpp/main.h new file mode 100644 index 0000000..f5ac598 --- /dev/null +++ b/mpcore/src/main/cpp/main.h @@ -0,0 +1,6 @@ + +//Основная ссылка на начало основного процесса - libapp.so +extern uintptr_t libapp; + +//Макрос для ссылок внутри памяти процесса +#define APP_ADDR(addr) (libapp + (addr)) diff --git a/mpcore/src/main/cpp/mpcore.cpp b/mpcore/src/main/cpp/mpcore.cpp deleted file mode 100644 index be67627..0000000 --- a/mpcore/src/main/cpp/mpcore.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -extern "C" JNIEXPORT jstring JNICALL -Java_ru_megboyzz_mpcore_NativeLib_stringFromJNI( - JNIEnv* env, - jobject /* this */) { - std::string hello = "Hello from C++"; - return env->NewStringUTF(hello.c_str()); -} \ No newline at end of file diff --git a/mpcore/src/main/cpp/util/armhook.cpp b/mpcore/src/main/cpp/util/armhook.cpp new file mode 100644 index 0000000..9477908 --- /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