diff --git a/app/libs/arm64-v8a/libmui.so b/app/libs/arm64-v8a/libmui.so index dfd1c93..c3da42e 100644 Binary files a/app/libs/arm64-v8a/libmui.so and b/app/libs/arm64-v8a/libmui.so differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 44547aa..64b78fc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ @@ -109,4 +110,4 @@ - \ No newline at end of file + diff --git a/app/src/main/java/thercn/wmw/GlobalApplication.java b/app/src/main/java/thercn/wmw/GlobalApplication.java index e0f268f..145862b 100644 --- a/app/src/main/java/thercn/wmw/GlobalApplication.java +++ b/app/src/main/java/thercn/wmw/GlobalApplication.java @@ -145,7 +145,6 @@ public void run() { try { Looper.loop(); } catch (final Throwable e) { - e.printStackTrace(); if (isRunning.get()) { MAIN_HANDLER.post(new Runnable(){ @@ -331,4 +330,4 @@ public void onBackPressed() { restart(); } } -} \ No newline at end of file +} diff --git a/app/src/main/java/thercn/wmw/MainActivity.java b/app/src/main/java/thercn/wmw/MainActivity.java index 157ac12..78f1091 100644 --- a/app/src/main/java/thercn/wmw/MainActivity.java +++ b/app/src/main/java/thercn/wmw/MainActivity.java @@ -26,12 +26,6 @@ public class MainActivity extends Activity { public static String appDataDir = Environment.getExternalStorageDirectory().toString() + "/WMW"; public static boolean isIPadScreen = false; - public static String loadLibrary; - - static - { - System.loadLibrary("wmw"); - } @Override protected void onCreate(Bundle savedInstanceState) { @@ -40,7 +34,6 @@ protected void onCreate(Bundle savedInstanceState) { Permission.申请(this); Log.e("WMW","安装包目录:" + getPackageResourcePath()); File obbdir = getObbDir(); - File dataDir = new File(appDataDir); File extraDataFile = new File(appDataDir + "/wmw-extra.zip"); if (!obbdir.exists() || !dataDir.exists()) { @@ -134,6 +127,4 @@ public void onClick(View view) { } }); } - private void setupLibrary(){} - } diff --git a/app/src/main/jn/Android.mk b/app/src/main/jn/Android.mk index f216ac6..de49a95 100644 --- a/app/src/main/jn/Android.mk +++ b/app/src/main/jn/Android.mk @@ -44,10 +44,8 @@ LOCAL_SRC_FILES:= Source/Imgui/imgui.cpp \ Source/EGL.cpp \ Source/MyFile.cpp \ native-lib.cpp \ - KittyMemory/KittyMemory.cpp \ - KittyMemory/MemoryPatch.cpp \ - KittyMemory/MemoryBackup.cpp \ - KittyMemory/KittyUtils.cpp + Platinmods/PlatinmodsMemoryPatch.cpp \ + Platinmods/PlatinmodsUtils.cpp LOCAL_LDLIBS := -ldl -llog -lEGL -lGLESv3 -landroid include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jn/Application.mk b/app/src/main/jn/Application.mk index 2500a8a..4d68bc3 100644 --- a/app/src/main/jn/Application.mk +++ b/app/src/main/jn/Application.mk @@ -1,2 +1,3 @@ APP_ABI := arm64-v8a -APP_STL := c++_static \ No newline at end of file +APP_STL := c++_static +APP_PLATFORM := android-24 diff --git a/app/src/main/jn/Include/EGL.h b/app/src/main/jn/Include/EGL.h index 65c4719..10cfee2 100644 --- a/app/src/main/jn/Include/EGL.h +++ b/app/src/main/jn/Include/EGL.h @@ -52,7 +52,7 @@ class EGL { ; void imguiMainWinEnd(); - + bool patch(char offset[],char hex[]); ImFont *imFont; string SaveDir; public: @@ -86,4 +86,4 @@ class EGL { ; } }; -#endif \ No newline at end of file +#endif diff --git a/app/src/main/jn/Include/patch.h b/app/src/main/jn/Include/patch.h deleted file mode 100644 index 7d31232..0000000 --- a/app/src/main/jn/Include/patch.h +++ /dev/null @@ -1,37 +0,0 @@ -#include "KittyMemory/MemoryPatch.h" -#include "log.h" - -std::vector memoryPatches; -std::vector offsetVector; - -// Patching a offset without switch. -void patchOffset(const char *fileName, uint64_t offset, std::string hexBytes, bool isOn) { - - MemoryPatch patch = MemoryPatch::createWithHex(fileName, offset, hexBytes); - - //Check if offset exists in the offsetVector - if (std::find(offsetVector.begin(), offsetVector.end(), offset) != offsetVector.end()) { - //LOGE(OBFUSCATE("Already exists")); - std::vector::iterator itr = std::find(offsetVector.begin(), offsetVector.end(), offset); - patch = memoryPatches[std::distance(offsetVector.begin(), itr)]; //Get index of memoryPatches vector - } else { - memoryPatches.push_back(patch); - offsetVector.push_back(offset); - //LOGI(OBFUSCATE("Added")); - } - - if (!patch.isValid()) { - LOGE("Failing offset: 0x%llu, please re-check the hex", offset); - return; - } - if (isOn) { - if (!patch.Modify()) { - LOGE("Something went wrong while patching this offset: 0x%llu", offset); - } - } else { - if (!patch.Restore()) { - LOGE("Something went wrong while restoring this offset: 0x%llu", offset); - } - } -} - diff --git a/app/src/main/jn/KittyMemory/KittyMemory.cpp b/app/src/main/jn/KittyMemory/KittyMemory.cpp deleted file mode 100644 index 82fdec8..0000000 --- a/app/src/main/jn/KittyMemory/KittyMemory.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// -// KittyMemory.cpp -// -// Created by MJ (Ruit) on 1/1/19. -// - -#include "KittyMemory.h" - -using KittyMemory::Memory_Status; -using KittyMemory::ProcMap; - - -struct mapsCache { - std::string identifier; - ProcMap map; -}; - -static std::vector __mapsCache; -static ProcMap findMapInCache(std::string id){ - ProcMap ret; - for(int i = 0; i < __mapsCache.size(); i++){ - if(__mapsCache[i].identifier.compare(id) == 0){ - ret = __mapsCache[i].map; - break; - } - } - return ret; -} - - -bool KittyMemory::ProtectAddr(void *addr, size_t length, int protection) { - uintptr_t pageStart = _PAGE_START_OF_(addr); - uintptr_t pageLen = _PAGE_LEN_OF_(addr, length); - return ( - mprotect(reinterpret_cast(pageStart), pageLen, protection) != -1 - ); -} - - -Memory_Status KittyMemory::memWrite(void *addr, const void *buffer, size_t len) { - if (addr == NULL) - return INV_ADDR; - - if (buffer == NULL) - return INV_BUF; - - if (len < 1 || len > INT_MAX) - return INV_LEN; - - if (!ProtectAddr(addr, len, _PROT_RWX_)) - return INV_PROT; - - if (memcpy(addr, buffer, len) != NULL && ProtectAddr(addr, len, _PROT_RX_)) - return SUCCESS; - - return FAILED; -} - - -Memory_Status KittyMemory::memRead(void *buffer, const void *addr, size_t len) { - if (addr == NULL) - return INV_ADDR; - - if (buffer == NULL) - return INV_BUF; - - if (len < 1 || len > INT_MAX) - return INV_LEN; - - if (memcpy(buffer, addr, len) != NULL) - return SUCCESS; - - return FAILED; -} - - -std::string KittyMemory::read2HexStr(const void *addr, size_t len) { - char temp[len]; - memset(temp, 0, len); - - const size_t bufferLen = len * 2 + 1; - char buffer[bufferLen]; - memset(buffer, 0, bufferLen); - - std::string ret; - - if (memRead(temp, addr, len) != SUCCESS) - return ret; - - for (int i = 0; i < len; i++) { - sprintf(&buffer[i * 2], "%02X", (unsigned char) temp[i]); - } - - ret += buffer; - return ret; -} - -ProcMap KittyMemory::getLibraryMap(const char *libraryName) { - ProcMap retMap; - char line[512] = {0}; - - FILE *fp = fopen("/proc/self/maps", "rt"); - if (fp != NULL) { - while (fgets(line, sizeof(line), fp)) { - if (strstr(line, libraryName)) { - char tmpPerms[5] = {0}, tmpDev[12] = {0}, tmpPathname[444] = {0}; - // parse a line in maps file - // (format) startAddress-endAddress perms offset dev inode pathname - sscanf(line, "%llx-%llx %s %ld %s %d %s", - (long long unsigned *) &retMap.startAddr, - (long long unsigned *) &retMap.endAddr, - tmpPerms, &retMap.offset, tmpDev, &retMap.inode, tmpPathname); - - retMap.length = (uintptr_t) retMap.endAddr - (uintptr_t) retMap.startAddr; - retMap.perms = tmpPerms; - retMap.dev = tmpDev; - retMap.pathname = tmpPathname; - - break; - } - } - fclose(fp); - } - return retMap; -} - -uintptr_t KittyMemory::getAbsoluteAddress(const char *libraryName, uintptr_t relativeAddr, bool useCache) { - ProcMap libMap; - - if(useCache){ - libMap = findMapInCache(libraryName); - if(libMap.isValid()) - return (reinterpret_cast(libMap.startAddr) + relativeAddr); - } - - libMap = getLibraryMap(libraryName); - if (!libMap.isValid()) - return 0; - - if(useCache){ - mapsCache cachedMap; - cachedMap.identifier = libraryName; - cachedMap.map = libMap; - __mapsCache.push_back(cachedMap); - } - - return (reinterpret_cast(libMap.startAddr) + relativeAddr); -} diff --git a/app/src/main/jn/KittyMemory/KittyMemory.h b/app/src/main/jn/KittyMemory/KittyMemory.h deleted file mode 100644 index 21f0160..0000000 --- a/app/src/main/jn/KittyMemory/KittyMemory.h +++ /dev/null @@ -1,169 +0,0 @@ -// -// KittyMemory.hpp -// -// Created by MJ (Ruit) on 1/1/19. -// - -#pragma once - -#include -#include -#include -#include -#include - - -#define _SYS_PAGE_SIZE_ (sysconf(_SC_PAGE_SIZE)) - -#define _PAGE_START_OF_(x) ((uintptr_t)x & ~(uintptr_t)(_SYS_PAGE_SIZE_ - 1)) -#define _PAGE_END_OF_(x, len) (_PAGE_START_OF_((uintptr_t)x + len - 1)) -#define _PAGE_LEN_OF_(x, len) (_PAGE_END_OF_(x, len) - _PAGE_START_OF_(x) + _SYS_PAGE_SIZE_) -#define _PAGE_OFFSET_OF_(x) ((uintptr_t)x - _PAGE_START_OF_(x)) - -#define _PROT_RWX_ (PROT_READ | PROT_WRITE | PROT_EXEC) -#define _PROT_RX_ (PROT_READ | PROT_EXEC) - - -#define EMPTY_VEC_OFFSET std::vector() - -namespace KittyMemory { - - typedef enum { - FAILED = 0, - SUCCESS = 1, - INV_ADDR = 2, - INV_LEN = 3, - INV_BUF = 4, - INV_PROT = 5 - } Memory_Status; - - - struct ProcMap { - void *startAddr; - void *endAddr; - size_t length; - std::string perms; - long offset; - std::string dev; - int inode; - std::string pathname; - - bool isValid() { return (startAddr != NULL && endAddr != NULL && !pathname.empty()); } - }; - - /* - * Changes protection of an address with given length - */ - bool ProtectAddr(void *addr, size_t length, int protection); - - /* - * Writes buffer content to an address - */ - Memory_Status memWrite(void *addr, const void *buffer, size_t len); - - /* - * Reads an address content into a buffer - */ - Memory_Status memRead(void *buffer, const void *addr, size_t len); - - /* - * Reads an address content and returns hex string - */ - std::string read2HexStr(const void *addr, size_t len); - - - /* - * Wrapper to dereference & get value of a multi level pointer - * Make sure to use the correct data type! - */ - template - Type readMultiPtr(void *ptr, std::vector offsets) { - Type defaultVal = {}; - if (ptr == NULL) - return defaultVal; - - uintptr_t finalPtr = reinterpret_cast(ptr); - int offsetsSize = offsets.size(); - if (offsetsSize > 0) { - for (int i = 0; finalPtr != 0 && i < offsetsSize; i++) { - if (i == (offsetsSize - 1)) - return *reinterpret_cast(finalPtr + offsets[i]); - - finalPtr = *reinterpret_cast(finalPtr + offsets[i]); - } - } - - if (finalPtr == 0) - return defaultVal; - - return *reinterpret_cast(finalPtr); - } - - - /* - * Wrapper to dereference & set value of a multi level pointer - * Make sure to use the correct data type!, const objects won't work - */ - template - bool writeMultiPtr(void *ptr, std::vector offsets, Type val) { - if (ptr == NULL) - return false; - - uintptr_t finalPtr = reinterpret_cast(ptr); - int offsetsSize = offsets.size(); - if (offsetsSize > 0) { - for (int i = 0; finalPtr != 0 && i < offsetsSize; i++) { - if (i == (offsetsSize - 1)) { - *reinterpret_cast(finalPtr + offsets[i]) = val; - return true; - } - - finalPtr = *reinterpret_cast(finalPtr + offsets[i]); - } - } - - if (finalPtr == 0) - return false; - - *reinterpret_cast(finalPtr) = val; - return true; - } - - /* - * Wrapper to dereference & get value of a pointer - * Make sure to use the correct data type! - */ - template - Type readPtr(void *ptr) { - Type defaultVal = {}; - if (ptr == NULL) - return defaultVal; - - return *reinterpret_cast(ptr); - } - - /* - * Wrapper to dereference & set value of a pointer - * Make sure to use the correct data type!, const objects won't work - */ - template - bool writePtr(void *ptr, Type val) { - if (ptr == NULL) - return false; - - *reinterpret_cast(ptr) = val; - return true; - } - - /* - * Gets info of a mapped library in self process - */ - ProcMap getLibraryMap(const char *libraryName); - - /* - * Expects a relative address in a library - * Returns final absolute address - */ - uintptr_t - getAbsoluteAddress(const char *libraryName, uintptr_t relativeAddr, bool useCache = false); -}; diff --git a/app/src/main/jn/KittyMemory/KittyUtils.cpp b/app/src/main/jn/KittyMemory/KittyUtils.cpp deleted file mode 100644 index b459287..0000000 --- a/app/src/main/jn/KittyMemory/KittyUtils.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "KittyUtils.h" - -static void xtrim(std::string &hex){ - if(hex.compare(0, 2, "0x") == 0){ - hex.erase(0, 2); - } - - // https://www.techiedelight.com/remove-whitespaces-string-cpp/ - hex.erase(std::remove_if(hex.begin(), hex.end(), [](char c){ - return (c == ' ' || c == '\n' || c == '\r' || - c == '\t' || c == '\v' || c == '\f'); - }), - hex.end()); -} - - -bool KittyUtils::validateHexString(std::string &xstr){ - if(xstr.length() < 2) return false; - xtrim(xstr); // first remove spaces - if(xstr.length() % 2 != 0) return false; - for(size_t i = 0; i < xstr.length(); i++){ - if(!std::isxdigit((unsigned char)xstr[i])){ - return false; - } - } - return true; -} - - -// https://tweex.net/post/c-anything-tofrom-a-hex-string/ -#include -#include - - -// ------------------------------------------------------------------ -/*! - Convert a block of data to a hex string -*/ -void KittyUtils::toHex( - void *const data, //!< Data to convert - const size_t dataLength, //!< Length of the data to convert - std::string &dest //!< Destination string - ) -{ - unsigned char *byteData = reinterpret_cast(data); - std::stringstream hexStringStream; - - hexStringStream << std::hex << std::setfill('0'); - for(size_t index = 0; index < dataLength; ++index) - hexStringStream << std::setw(2) << static_cast(byteData[index]); - dest = hexStringStream.str(); -} - - -// ------------------------------------------------------------------ -/*! - Convert a hex string to a block of data -*/ -void KittyUtils::fromHex( - const std::string &in, //!< Input hex string - void *const data //!< Data store - ) -{ - size_t length = in.length(); - unsigned char *byteData = reinterpret_cast(data); - - std::stringstream hexStringStream; hexStringStream >> std::hex; - for(size_t strIndex = 0, dataIndex = 0; strIndex < length; ++dataIndex) - { - // Read out and convert the string two characters at a time - const char tmpStr[3] = { in[strIndex++], in[strIndex++], 0 }; - - // Reset and fill the string stream - hexStringStream.clear(); - hexStringStream.str(tmpStr); - - // Do the conversion - int tmpValue = 0; - hexStringStream >> tmpValue; - byteData[dataIndex] = static_cast(tmpValue); - } -} \ No newline at end of file diff --git a/app/src/main/jn/KittyMemory/KittyUtils.h b/app/src/main/jn/KittyMemory/KittyUtils.h deleted file mode 100644 index ffd81c6..0000000 --- a/app/src/main/jn/KittyMemory/KittyUtils.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include -#include - -namespace KittyUtils { - - bool validateHexString(std::string &xstr); - void toHex(void *const data, const size_t dataLength, std::string &dest); - void fromHex(const std::string &in, void *const data); - -} \ No newline at end of file diff --git a/app/src/main/jn/KittyMemory/MemoryBackup.cpp b/app/src/main/jn/KittyMemory/MemoryBackup.cpp deleted file mode 100644 index 7e94222..0000000 --- a/app/src/main/jn/KittyMemory/MemoryBackup.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// -// MemoryBackup.cpp -// -// Created by MJ (Ruit) on 4/19/20. -// - -#include "MemoryBackup.h" - - -MemoryBackup::MemoryBackup() { - _address = 0; - _size = 0; - _orig_code.clear(); -} - -MemoryBackup::MemoryBackup(const char *libraryName, uintptr_t address, size_t backup_size, bool useMapCache) { - MemoryBackup(); - - if (libraryName == NULL || address == 0 || backup_size < 1) - return; - - _address = KittyMemory::getAbsoluteAddress(libraryName, address, useMapCache); - if(_address == 0) return; - - _size = backup_size; - - _orig_code.resize(backup_size); - - // backup current content - KittyMemory::memRead(&_orig_code[0], reinterpret_cast(_address), backup_size); -} - - -MemoryBackup::MemoryBackup(uintptr_t absolute_address, size_t backup_size) { - MemoryBackup(); - - if (absolute_address == 0 || backup_size < 1) - return; - - _address = absolute_address; - - _size = backup_size; - - _orig_code.resize(backup_size); - - // backup current content - KittyMemory::memRead(&_orig_code[0], reinterpret_cast(_address), backup_size); -} - - MemoryBackup::~MemoryBackup() { - // clean up - _orig_code.clear(); - } - - - bool MemoryBackup::isValid() const { - return (_address != 0 && _size > 0 - && _orig_code.size() == _size); - } - - size_t MemoryBackup::get_BackupSize() const{ - return _size; - } - - uintptr_t MemoryBackup::get_TargetAddress() const{ - return _address; - } - - bool MemoryBackup::Restore() { - if (!isValid()) return false; - return KittyMemory::memWrite(reinterpret_cast(_address), &_orig_code[0], _size) == Memory_Status::SUCCESS; - } - - std::string MemoryBackup::get_CurrBytes() { - if (!isValid()) - _hexString = std::string("0xInvalid"); - else - _hexString = KittyMemory::read2HexStr(reinterpret_cast(_address), _size); - - return _hexString; - } diff --git a/app/src/main/jn/KittyMemory/MemoryBackup.h b/app/src/main/jn/KittyMemory/MemoryBackup.h deleted file mode 100644 index fde1ea4..0000000 --- a/app/src/main/jn/KittyMemory/MemoryBackup.h +++ /dev/null @@ -1,66 +0,0 @@ -// -// MemoryBackup.h -// -// Created by MJ (Ruit) on 4/19/20. -// - -#pragma once - -#include - -#include "KittyMemory.h" -using KittyMemory::Memory_Status; -using KittyMemory::ProcMap; - - -class MemoryBackup { -private: - uintptr_t _address; - size_t _size; - - std::vector _orig_code; - - std::string _hexString; - -public: - MemoryBackup(); - - /* - * expects library name and relative address - */ - MemoryBackup(const char *libraryName, uintptr_t address, size_t backup_size, bool useMapCache=true); - - /* - * expects absolute address - */ - MemoryBackup(uintptr_t absolute_address, size_t backup_size); - - - ~MemoryBackup(); - - - /* - * Validate patch - */ - bool isValid() const; - - - size_t get_BackupSize() const; - - /* - * Returns pointer to the target address - */ - uintptr_t get_TargetAddress() const; - - - /* - * Restores backup code - */ - bool Restore(); - - - /* - * Returns current target address bytes as hex string - */ - std::string get_CurrBytes(); -}; diff --git a/app/src/main/jn/KittyMemory/MemoryPatch.cpp b/app/src/main/jn/KittyMemory/MemoryPatch.cpp deleted file mode 100644 index 3b13ba9..0000000 --- a/app/src/main/jn/KittyMemory/MemoryPatch.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// -// MemoryPatch.cpp -// -// Created by MJ (Ruit) on 1/1/19. -// - -#include "MemoryPatch.h" -#include "../log.h" - -MemoryPatch::MemoryPatch() { - _address = 0; - _size = 0; - _orig_code.clear(); - _patch_code.clear(); -} - -MemoryPatch::MemoryPatch(const char *libraryName, uintptr_t address, - const void *patch_code, size_t patch_size, bool useMapCache) { - MemoryPatch(); - - if (libraryName == NULL || address == 0 || patch_code == NULL || patch_size < 1) - return; - - _address = KittyMemory::getAbsoluteAddress(libraryName, address, useMapCache); - if (_address == 0) return; - - _size = patch_size; - - _orig_code.resize(patch_size); - _patch_code.resize(patch_size); - - // initialize patch & backup current content - KittyMemory::memRead(&_patch_code[0], patch_code, patch_size); - KittyMemory::memRead(&_orig_code[0], reinterpret_cast(_address), patch_size); -} - -MemoryPatch::MemoryPatch(uintptr_t absolute_address, - const void *patch_code, size_t patch_size) { - MemoryPatch(); - - if (absolute_address == 0 || patch_code == NULL || patch_size < 1) - return; - - _address = absolute_address; - _size = patch_size; - - _orig_code.resize(patch_size); - _patch_code.resize(patch_size); - - // initialize patch & backup current content - KittyMemory::memRead(&_patch_code[0], patch_code, patch_size); - KittyMemory::memRead(&_orig_code[0], reinterpret_cast(_address), patch_size); -} - -MemoryPatch::~MemoryPatch() { - // clean up - _orig_code.clear(); - _patch_code.clear(); -} - -MemoryPatch MemoryPatch::createWithHex(const char *libraryName, uintptr_t address, - std::string hex, bool useMapCache) { - MemoryPatch patch; - - if (libraryName == NULL || address == 0 || !KittyUtils::validateHexString(hex)) - return patch; - - patch._address = KittyMemory::getAbsoluteAddress(libraryName, address, useMapCache); - if (patch._address == 0) return patch; - - patch._size = hex.length() / 2; - - patch._orig_code.resize(patch._size); - patch._patch_code.resize(patch._size); - - // initialize patch - KittyUtils::fromHex(hex, &patch._patch_code[0]); - - // backup current content - KittyMemory::memRead(&patch._orig_code[0], reinterpret_cast(patch._address), - patch._size); - return patch; -} - -MemoryPatch MemoryPatch::createWithHex(uintptr_t absolute_address, std::string hex) { - MemoryPatch patch; - - if (absolute_address == 0 || !KittyUtils::validateHexString(hex)) - return patch; - - patch._address = absolute_address; - patch._size = hex.length() / 2; - - patch._orig_code.resize(patch._size); - patch._patch_code.resize(patch._size); - - // initialize patch - KittyUtils::fromHex(hex, &patch._patch_code[0]); - - // backup current content - KittyMemory::memRead(&patch._orig_code[0], reinterpret_cast(patch._address), - patch._size); - return patch; -} - -bool MemoryPatch::isValid() const { - return (_address != 0 && _size > 0 - && _orig_code.size() == _size && _patch_code.size() == _size); -} - -size_t MemoryPatch::get_PatchSize() const { - return _size; -} - -uintptr_t MemoryPatch::get_TargetAddress() const { - return _address; -} - -bool MemoryPatch::Restore() { - if (!isValid()) return false; - //LOGI("Restore %i", isLeeched); - return KittyMemory::memWrite(reinterpret_cast(_address), &_orig_code[0], _size) == - Memory_Status::SUCCESS; -} - -bool MemoryPatch::Modify() { - if (!isValid()) return false; - //LOGI("Modify"); - return (KittyMemory::memWrite(reinterpret_cast(_address), &_patch_code[0], _size) == - Memory_Status::SUCCESS); -} - -std::string MemoryPatch::get_CurrBytes() { - if (!isValid()) - _hexString = std::string("0xInvalid"); - else - _hexString = KittyMemory::read2HexStr(reinterpret_cast(_address), _size); - - return _hexString; -} diff --git a/app/src/main/jn/KittyMemory/MemoryPatch.h b/app/src/main/jn/KittyMemory/MemoryPatch.h deleted file mode 100644 index f63d91c..0000000 --- a/app/src/main/jn/KittyMemory/MemoryPatch.h +++ /dev/null @@ -1,80 +0,0 @@ -// -// MemoryPatch.h -// -// Created by MJ (Ruit) on 1/1/19. -// - -#pragma once - -#include -#include "KittyUtils.h" -#include "KittyMemory.h" -using KittyMemory::Memory_Status; -using KittyMemory::ProcMap; - -class MemoryPatch { -private: - uintptr_t _address; - size_t _size; - - std::vector _orig_code; - std::vector _patch_code; - - std::string _hexString; - -public: - MemoryPatch(); - - /* - * expects library name and relative address - */ - MemoryPatch(const char *libraryName, uintptr_t address, - const void *patch_code, size_t patch_size, bool useMapCache=true); - - - /* - * expects absolute address - */ - MemoryPatch(uintptr_t absolute_address, - const void *patch_code, size_t patch_size); - - - ~MemoryPatch(); - - /* - * compatible hex format (0xffff & ffff & ff ff) - */ - static MemoryPatch createWithHex(const char *libraryName, uintptr_t address, std::string hex, bool useMapCache=true); - static MemoryPatch createWithHex(uintptr_t absolute_address, std::string hex); - - /* - * Validate patch - */ - bool isValid() const; - - - size_t get_PatchSize() const; - - /* - * Returns pointer to the target address - */ - uintptr_t get_TargetAddress() const; - - - /* - * Restores patch to original value - */ - bool Restore(); - - - /* - * Applies patch modifications to target address - */ - bool Modify(); - - - /* - * Returns current patch target address bytes as hex string - */ - std::string get_CurrBytes(); -}; diff --git a/app/src/main/jn/Platinmods/PlatinmodsMemoryPatch.cpp b/app/src/main/jn/Platinmods/PlatinmodsMemoryPatch.cpp new file mode 100644 index 0000000..eeb4003 --- /dev/null +++ b/app/src/main/jn/Platinmods/PlatinmodsMemoryPatch.cpp @@ -0,0 +1,322 @@ +// +// Created by Mika Cybertron on 5/19/2023. +// + + +#include "PlatinmodsMemoryPatch.h" +#include +#define LOGGER_ENABLED +#include "../Include/log.h" + + +namespace Platinmods { + + MemoryPatch::MemoryPatch() { + this->packageName = ""; + this->libraryName = ""; + this->pid = 0; + this->size = 0; + this->absoluteAddress = 0; + } + + MemoryPatch::MemoryPatch(std::string packageName) { + this->pid = ::Platinmods::getPid(packageName); + if(!IsValidPID()) + { + return; + } + } + + MemoryPatch::MemoryPatch(pid_t pid) { + this->pid = pid; + if(!IsValidPID()) + { + return; + } + } + + MemoryPatch::MemoryPatch(std::string packageName, std::string libraryName, std::string address, std::string hexCode) { + + + this->packageName = packageName; + this->libraryName = libraryName; + this->pid = ::Platinmods::getPid(packageName); + + if(!IsValidPID()) + { + return; + } + + bool isValid = PlatinmodsUtils::validateHexString(hexCode); + if(!isValid) + { + LOGE("Error: Invalid hex codes: %s", hexCode.c_str()); + return; + } + + this->size = hexCode.length() / 2; + + this->baseAddress = getLibraryBase(pid, libraryName); + + if(baseAddress < 1) + { + LOGE("Error: Invalid base address."); + return; + } + this->absoluteAddress = baseAddress + std::stoll(address, nullptr, 16); + + std::string origHex = ""; + bool result = MemoryPatch::ReadHex(absoluteAddress, size, origHex); + if(!result) + { + origHex = hexCode; + } + + // Create Buffer of Hex Codes + PlatinmodsUtils::fromHex(hexCode, patchedHex); + + PlatinmodsUtils::fromHex(origHex, originalHex); + } + + MemoryPatch::MemoryPatch(pid_t pid, std::string libraryName, std::string address, std::string hexCode) { + + this->libraryName = libraryName; + this->pid = pid; + + if(!IsValidPID()) + { + return; + } + + bool isValid = PlatinmodsUtils::validateHexString(hexCode); + if(!isValid) + { + LOGE("Error: Invalid hex codes: %s", hexCode.c_str()); + return; + } + + this->size = hexCode.length() / 2; + + this->baseAddress = getLibraryBase(pid, libraryName); + + if(baseAddress < 1) + { + LOGE("Error: Invalid base address."); + return; + } + this->absoluteAddress = baseAddress + std::stoll(address, nullptr, 16); + + std::string origHex = ""; + bool result = MemoryPatch::ReadHex(absoluteAddress, size, origHex); + if(!result) + { + origHex = hexCode; + } + + // Create Buffer of Hex Codes + PlatinmodsUtils::fromHex(hexCode, patchedHex); + + PlatinmodsUtils::fromHex(origHex, originalHex); + } + + + bool MemoryPatch::CustomPatchHex(std::string libraryName, std::string address, std::string hexCode) { + + DWORD baseAddress = getLibraryBase(pid, libraryName); + + if(baseAddress < 1) + { + LOGE("Error: Invalid base address."); + return false; + } + + DWORD absoluteAddress = baseAddress + std::stoll(address, nullptr, 16); + + char hexData[128]; + + bool isValid = PlatinmodsUtils::validateHexString(hexCode); + if(!isValid) + { + LOGE("Error: Invalid hex codes: %s", hexCode.c_str()); + return false; + } + + size_t size = hexCode.length() / 2; + + // Create Buffer of Hex Codes + PlatinmodsUtils::fromHex(hexCode, hexData); + + return memWrite(pid, absoluteAddress, hexData, size); + } + + bool MemoryPatch::ReadHex(DWORD address, size_t size, std::string& outputHexString) { + char buffer[size]; + + bool result = memRead(pid, address, buffer, size); + + if(result) + { + char hexBuffer[3]; // Buffer to hold two hex characters and a null terminator + + for (int i = 0; i < size; i++) { + snprintf(hexBuffer, sizeof(hexBuffer), "%02X", (unsigned char) buffer[i]); + outputHexString += hexBuffer; + outputHexString += " "; + } + + // Validate Hex String + PlatinmodsUtils::validateHexString(outputHexString); + } + else + { + LOGE("Error: Failed to read hex in memory."); + } + return result; + } + + bool MemoryPatch::Modify() { + + if(!IsValid()) + { + return false; + } + return memWrite(pid, absoluteAddress, patchedHex, size); + } + + bool MemoryPatch::Restore() { + + if(!IsValid()) + { + return false; + } + return memWrite(pid, absoluteAddress, originalHex, size); + } + + bool MemoryPatch::memRead(pid_t pid, DWORD address, char *buff, size_t size) { + char path[64]; + sprintf(path, "/proc/%d/mem", pid); + FILE *fp = fopen(path, "rb"); // Open the file in binary mode + if (fp == NULL) { + printf("memRead() failed to read process %d memory", pid); + return false; + } + fseeko64(fp, address, SEEK_SET); // Use SEEK_SET as the reference position + bool ok = fread(buff, 1, size, fp) == size; // Read the specified number of bytes + fclose(fp); + return ok; + } + + bool MemoryPatch::memWrite(pid_t pid, DWORD address, char *buff, size_t size) { + char path[64]; + sprintf(path, "/proc/%d/mem", pid); + FILE *fp = fopen(path, "w"); + if (fp == NULL) { + printf("memWrite() failed to write process %d memory", pid); + return false; + } + fseeko64(fp, address, 0); + bool ok = fwrite(buff, 1, size, fp) == size; + fclose(fp); + return ok; + } + + bool MemoryPatch::IsValid() { + + if(pid == 0 || baseAddress == 0 || absoluteAddress == 0) + { + LOGE("Error: Invalid patch"); + return false; + } + return true; + } + + bool MemoryPatch::IsValidPID() { + + if(pid == 0) + { + LOGE("Error: Failed to get PID Process."); + return false; + } + return true; + } + + DWORD MemoryPatch::getBaseAddress() const { + + return baseAddress; + } + + DWORD MemoryPatch::getRealOffsets() const { + + return absoluteAddress - baseAddress; + } + + DWORD MemoryPatch::getAbsoluteAddress() const { + + return absoluteAddress; + } + + std::string MemoryPatch::get_OrigBytes() const { + + return PlatinmodsUtils::Hex2String(originalHex, size); + } + + std::string MemoryPatch::get_PatchBytes() const { + return PlatinmodsUtils::Hex2String(patchedHex, size); + } + + pid_t MemoryPatch::getPid() const { + return pid; + } + + pid_t getPid(std::string packageName) { + auto proc_dir = opendir("/proc"); + if (proc_dir == nullptr) { + return 0; + } + FILE* fp; + dirent* pid_file; + char cmd_line[128]; + + while ((pid_file = readdir(proc_dir))) { + if (pid_file->d_type != DT_DIR || + strcmp(pid_file->d_name, ".") == 0 || + strcmp(pid_file->d_name, "..") == 0) + continue; + + std::string file_path = "/proc/"; + file_path += pid_file->d_name; + file_path += "/cmdline"; + fp = fopen(file_path.c_str(), "r"); + if (fp != nullptr) { + std::fgets(cmd_line, sizeof(cmd_line), fp); + std::fclose(fp); + if (cmd_line == packageName) { + closedir(proc_dir); + return (int) std::strtol(pid_file->d_name, nullptr, 0); + } + } + } + closedir(proc_dir); + return 0; + } + + DWORD getLibraryBase(pid_t pid, std::string libraryName) { + DWORD start_address = 0; + char om[64], line[1024]; + strcpy(om, libraryName.c_str()); + std::string path = "/proc/" + std::to_string(pid) + "/maps"; + FILE *p = fopen(path.c_str(), "r"); + if (p) { + while (fgets(line, sizeof(line), p)) { + + if (strstr(line, libraryName.c_str())) + { + sscanf(line, "%lx-%*lx", &start_address); // NOLINT(cert-err34-c) + break; + } + } + fclose(p); + } + return start_address; + } +} diff --git a/app/src/main/jn/Platinmods/PlatinmodsMemoryPatch.h b/app/src/main/jn/Platinmods/PlatinmodsMemoryPatch.h new file mode 100644 index 0000000..900165f --- /dev/null +++ b/app/src/main/jn/Platinmods/PlatinmodsMemoryPatch.h @@ -0,0 +1,163 @@ +// +// Created by Mika Cybertron on 5/19/2023. +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include // PROT_READ | PROT_WRITE | PROT_EXEC + +#include "PlatinmodsUtils.h" + +namespace Platinmods { + + typedef long long DWORD; + + class MemoryPatch { + private: + std::string packageName = ""; + std::string libraryName = ""; + pid_t pid = 0; + size_t size = 0; + DWORD baseAddress = 0; + DWORD absoluteAddress = 0; + char patchedHex[128]; + char originalHex[128]; + + /*! + * Reads an address content into a buffer + */ + bool memRead(pid_t pid, DWORD address, char *buff, size_t size); + + /*! + * Writes buffer content to an address + */ + bool memWrite(pid_t pid, DWORD address, char *buff, size_t size); + + /*! + * Validate patch + */ + bool IsValid(); + + /*! + * Validate PID Process + */ + bool IsValidPID(); + + public: + + MemoryPatch& operator=(const MemoryPatch& other) { + if (this == &other) { + return *this; + } + + packageName = other.packageName; + libraryName = other.libraryName; + pid = other.pid; + size = other.size; + baseAddress = other.baseAddress; + absoluteAddress = other.absoluteAddress; + strncpy(patchedHex, other.patchedHex, sizeof(other.patchedHex)); + strncpy(originalHex, other.originalHex, sizeof(other.originalHex)); + + return *this; + } + + /*! + * Return nothing + */ + MemoryPatch(); + + /*! + * expects package name + */ + MemoryPatch(std::string packageName); + + /*! + * expects pid + */ + MemoryPatch(pid_t pid); + + /*! + * expects package name, library name and relative address + * compatible hex format (0xffff & ffff & ff ff) + */ + MemoryPatch(std::string packageName, std::string libraryName, std::string address, std::string hexCode); + + /*! + * Recommended to use this one. + * + * expects pid, library name and relative address + * compatible hex format (0xffff & ffff & ff ff) + */ + MemoryPatch(pid_t pid, std::string libraryName, std::string address, std::string hexCode); + + /*! + * Applies custom modification patches to target addresses without calling functions from `Modify()` or `Restore()` + * compatible hex format (0xffff & ffff & ff ff) + */ + bool CustomPatchHex(std::string libraryName, std::string address, std::string hexCode); + + /*! + * Read Hex Codes + */ + bool ReadHex(DWORD address, size_t size, std::string& outputHexString); + + /*! + * Applies patch modifications to target address + */ + bool Modify(); + + /*! + * Restores patch to original value + */ + bool Restore(); + + /*! + * Returns Base Address of library + */ + DWORD getBaseAddress() const; + + /*! + * Returns Real Offsets or Relative Address (Absolute Address - Base Address) + */ + DWORD getRealOffsets() const; + + /*! + * Returns Absolute Address (Base Address + Relative Address) + */ + DWORD getAbsoluteAddress() const; + + /*! + * Returns original bytes as hex string + */ + std::string get_OrigBytes() const; + + /*! + * Returns patch bytes as hex string + */ + std::string get_PatchBytes() const; + + /*! + * Returns current pid process + */ + pid_t getPid() const; + }; + + + /*! + * Get pid process by package name + */ + pid_t getPid(std::string packageName); + + /*! + * Get base address of library + */ + DWORD getLibraryBase(pid_t pid, std::string libraryName); +} diff --git a/app/src/main/jn/Platinmods/PlatinmodsUtils.cpp b/app/src/main/jn/Platinmods/PlatinmodsUtils.cpp new file mode 100644 index 0000000..a174956 --- /dev/null +++ b/app/src/main/jn/Platinmods/PlatinmodsUtils.cpp @@ -0,0 +1,122 @@ +// +// Created by Mika Cybertron on 5/20/2023. +// +#include "PlatinmodsUtils.h" + +namespace PlatinmodsUtils { + + /*! + * Hex Buffer to Hex String + */ + std::string Hex2String(const char* buffer, size_t size) { + + std::string result; + std::ostringstream oss; + oss << std::hex << std::uppercase << std::setfill('0'); + for (size_t i = 0; i < size; ++i) { + oss << std::setw(2) << static_cast(static_cast(buffer[i])); + } + result = oss.str(); + setFormatHex(result); + return result; + } + + /*! + * Set Format Hex with Whitespaces + */ + void setFormatHex(std::string &hexCode) { + std::string result; + + trim_string(hexCode); // first remove all white spaces + + for (size_t i = 0; i < hexCode.length(); i += 2) { + result += hexCode.substr(i, 2); + if (i < hexCode.length() - 2) { + result += " "; + } + } + hexCode = result; + } + + // ------------------------------------------------------------------ + // https://github.com/MJx0/KittyMemory/blob/master/Android/KittyMemory/KittyUtils.cpp + + /*! + * Trim All Whitespaces + */ + void trim_string(std::string &str) + { + // https://www.techiedelight.com/remove-whitespaces-string-cpp/ + str.erase(std::remove_if(str.begin(), str.end(), [](char c) + { return (c == ' ' || c == '\n' || c == '\r' || + c == '\t' || c == '\v' || c == '\f'); }), + str.end()); + } + + bool validateHexString(std::string &hex) + { + if (hex.empty()) return false; + + if (hex.compare(0, 2, "0x") == 0) + hex.erase(0, 2); + + trim_string(hex); // first remove spaces + + if (hex.length() < 2 || hex.length() % 2 != 0) return false; + + for (size_t i = 0; i < hex.length(); i++) { + if (!std::isxdigit((unsigned char) hex[i])) + return false; + } + + return true; + } + + // https://tweex.net/post/c-anything-tofrom-a-hex-string/ + + // ------------------------------------------------------------------ + /*! + * Convert a block of data to a hex string + */ + void toHex( + void *const data, //!< Data to convert + const size_t dataLength, //!< Length of the data to convert + std::string &dest //!< Destination string + ) { + unsigned char *byteData = reinterpret_cast(data); + std::stringstream hexStringStream; + + hexStringStream << std::hex << std::setfill('0'); + for (size_t index = 0; index < dataLength; ++index) + hexStringStream << std::setw(2) << static_cast(byteData[index]); + dest = hexStringStream.str(); + } + + // ------------------------------------------------------------------ + /*! + * Convert a hex string to a block of data + */ + void fromHex( + const std::string &in, //!< Input hex string + void *const data //!< Data store + ) { + size_t length = in.length(); + unsigned char *byteData = reinterpret_cast(data); + + std::stringstream hexStringStream; + hexStringStream >> std::hex; + for (size_t strIndex = 0, dataIndex = 0; strIndex < length; ++dataIndex) { + // Read out and convert the string two characters at a time + const char tmpStr[3] = {in[strIndex++], in[strIndex++], 0}; + + // Reset and fill the string stream + hexStringStream.clear(); + hexStringStream.str(tmpStr); + + // Do the conversion + int tmpValue = 0; + hexStringStream >> tmpValue; + byteData[dataIndex] = static_cast(tmpValue); + } + } +} diff --git a/app/src/main/jn/Platinmods/PlatinmodsUtils.h b/app/src/main/jn/Platinmods/PlatinmodsUtils.h new file mode 100644 index 0000000..62cff04 --- /dev/null +++ b/app/src/main/jn/Platinmods/PlatinmodsUtils.h @@ -0,0 +1,19 @@ +// +// Created by Mika Cybertron on 5/20/2023. +// +#pragma once + +#include +#include +#include +#include + +namespace PlatinmodsUtils { + + std::string Hex2String(const char* buffer, size_t size); + void setFormatHex(std::string &hexCode); + void trim_string(std::string &str); + bool validateHexString(std::string &xstr); + void toHex(void *const data, const size_t dataLength, std::string &dest); + void fromHex(const std::string &in, void *const data); +} diff --git a/app/src/main/jn/Source/EGL.cpp b/app/src/main/jn/Source/EGL.cpp index ffe956d..7e5f04e 100644 --- a/app/src/main/jn/Source/EGL.cpp +++ b/app/src/main/jn/Source/EGL.cpp @@ -3,8 +3,7 @@ // #include "EGL.h" -#include "patch.h" -#include "Utils.h" +#include "../Platinmods/PlatinmodsMemoryPatch.h" #define PATCH_LIB(lib, offset, hex) patchOffset(lib, string2Offset(offset), hex, true) EGL::EGL() { @@ -241,9 +240,10 @@ void EGL::EglThread() { ImGuiInputTextFlags_CallbackAlways, ImguiAndroidInput::inputCallback); if (ImGui::Button("修改")){ - PATCH_LIB("libwmw.so",offset,str); + patch(offset,str); LOGE("成功为%d打上%s",offset,str); } + ImGui::End(); imguiMainWinEnd(); @@ -251,6 +251,27 @@ void EGL::EglThread() { input->fps = this->FPS; } } + +bool EGL::patch(char offset[],char hex[]) { +pid_t pid = Platinmods::getPid("thercn.wmw"); + + std::string offset_str(offset); + std::string hex_str(hex); + + Platinmods::MemoryPatch patch1 = Platinmods::MemoryPatch(pid, "libwmw.so", offset_str, hex_str); + + // Write Modified Hex + bool result = patch1.Modify(); + if (result) { + LOGE("Offset patches successfully!\n"); + } else { + LOGE("Patch failed\n"); + } + return result; +} + + + int EGL::swapBuffers() { //opengl当前buff传递至屏幕 if (eglSwapBuffers(mEglDisplay, mEglSurface)) { diff --git a/app/src/main/jn/Source/EGL.cpp.bak b/app/src/main/jn/Source/EGL.cpp.bak deleted file mode 100644 index 0e3f164..0000000 --- a/app/src/main/jn/Source/EGL.cpp.bak +++ /dev/null @@ -1,303 +0,0 @@ -// -// Created by admin on 2022/6/10. -// - -#include "EGL.h" -#include "patch.h" - -#define PATCH_LIB(lib, offset, hex) patchOffset(lib, string2Offset(offset), hex, true) -EGL::EGL() { - mEglDisplay = EGL_NO_DISPLAY; - mEglSurface = EGL_NO_SURFACE; - mEglConfig = nullptr; - mEglContext = EGL_NO_CONTEXT; - // FPS = 90; -} - -static bool RunInitImgui;//检测imgui是否初始化过 - - -int EGL::initEgl() { - //1、 - mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (mEglDisplay == EGL_NO_DISPLAY) { - LOGE("eglGetDisplay error=%u", glGetError()); - return -1; - } - LOGE("生成mEglDisplay"); - //2、 - EGLint *version = new EGLint[2]; - if (!eglInitialize(mEglDisplay, &version[0], &version[1])) { - LOGE("eglInitialize error=%u", glGetError()); - return -1; - } - LOGE("eglInitialize成功"); - //3、 - const EGLint attribs[] = {EGL_BUFFER_SIZE, 32, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE}; - - EGLint num_config; - if (!eglGetConfigs(mEglDisplay, NULL, 1, &num_config)) { - LOGE("eglGetConfigs error =%u", glGetError()); - return -1; - } - LOGE("num_config=%d", num_config); - // 4、 - if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, 1, &num_config)) { - LOGE("eglChooseConfig error=%u", glGetError()); - return -1; - } - LOGE("eglChooseConfig成功"); - //5、 - int attrib_list[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list); - if (mEglContext == EGL_NO_CONTEXT) { - LOGE("eglCreateContext error = %u", glGetError()); - return -1; - } - // 6、 - mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, SurfaceWin, NULL); - if (mEglSurface == EGL_NO_SURFACE) { - LOGE("eglCreateWindowSurface error = %u", glGetError()); - return -1; - } - LOGE("eglCreateWindowSurface成功"); - //7、 - if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { - LOGE("eglMakeCurrent error = %u", glGetError()); - return -1; - } - LOGE("eglMakeCurrent成功"); - return 1; -} - - - -int EGL::initImgui() { - - if (RunInitImgui){ - //如果初始化过,就只执行这段 - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGui_ImplAndroid_Init(this->SurfaceWin); - ImGui_ImplOpenGL3_Init("#version 300 es"); - return 1; - } - RunInitImgui= true; - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - LOGE("CreateContext成功"); - io = &ImGui::GetIO(); - io->IniSavingRate = 10.0f; - string SaveFile = this->SaveDir; - SaveFile += "/save.ini"; - // LOGE("保存配置文件的位置:%s",SaveFile.c_str()); - io->IniFilename = SaveFile.c_str(); - - - - - // io->ConfigWindowsMoveFromTitleBarOnly = true; - //ImGui::LoadIniSettingsFromDisk(SaveFile.c_str()); - ImGui_ImplAndroid_Init(this->SurfaceWin); - LOGE(" ImGui_ImplAndroid_Init成功"); - // ImGui_ImplOpenGL3_Init("#version 100"); - ImGui_ImplOpenGL3_Init("#version 300 es"); - LOGE(" ImGui_ImplOpenGL3_Init成功"); - ImFontConfig font_cfg; - font_cfg.FontDataOwnedByAtlas = false; - imFont = io->Fonts->AddFontFromMemoryTTF((void *) OPPOSans_H, OPPOSans_H_size, 32.0f, &font_cfg, io->Fonts->GetGlyphRangesChineseFull()); - io->MouseDoubleClickTime = 0.0001f; - LOGE(" Font成功"); - //UI窗体风格 - g = ImGui::GetCurrentContext(); - - style =&ImGui::GetStyle(); - style->ScaleAllSizes(1.0f);//缩放尺寸 - style->FramePadding=ImVec2(10.0f,20.0f); - - //自动读取主题 - string LoadFile = this->SaveDir; - LoadFile += "/Style.dat"; - ImGuiStyle s; - if (MyFile::ReadFile(&s,LoadFile.c_str())==1){ - *style=s; - LOGE("读取主题成功"); - } - - - return 1; -} - - -void EGL::onSurfaceCreate(JNIEnv *env, jobject surface, int SurfaceWidth, int SurfaceHigh) { - LOGE("onSurfaceCreate"); - this->SurfaceWin = ANativeWindow_fromSurface(env, surface); - this->surfaceWidth = SurfaceWidth; - this->surfaceHigh = SurfaceHigh; - this->surfaceWidthHalf = this->surfaceWidth / 2; - this->surfaceHighHalf = this->surfaceHigh / 2; - SurfaceThread = new std::thread([this] { EglThread(); }); - SurfaceThread->detach(); - LOGE("onSurfaceCreate_end"); -} - -void EGL::onSurfaceChange(int SurfaceWidth, int SurfaceHigh) { - this->surfaceWidth = SurfaceWidth; - this->surfaceHigh = SurfaceHigh; - this->surfaceWidthHalf = this->surfaceWidth / 2; - this->surfaceHighHalf = this->surfaceHigh / 2; - this->isChage = true; - LOGE("onSurfaceChange"); -} - -void EGL::onSurfaceDestroy() { - - LOGE("onSurfaceDestroy"); - this->isDestroy = true; - - std::unique_lock ulo(Threadlk); - //LOGE("onSurfaceDestroy2"); - cond.wait(ulo, [this] { return !this->ThreadIo; }); - delete SurfaceThread; - SurfaceThread = nullptr; - -} -void EGL::EglThread() { - LOGE("imguidgsbdf成"); - - //LOGE("EglThreadstrat"); - this->initEgl(); - // LOGE("Egl初始化完成"); - this->initImgui(); -// LOGE("imgui初始化完成"); - ThreadIo = true; - // AutoFPS.setAffinity(); -// getRandomColor(HealthColor, 200, 0.7); - input->initImguiIo(io); - input->setImguiContext(g); - input->setwin(this->g_window); - // LOGE("surfaceWidth=%d,surfaceHigh=%d", this->surfaceWidth, this->surfaceHigh); - - while (true) { - - - - if (this->isChage) { - glViewport(0, 0, this->surfaceWidth, this->surfaceHigh); - this->isChage = false; - } - if (this->isDestroy) { - // LOGE("isDes1"); - this->isDestroy = false; - // LOGE("isDes2"); - ThreadIo = false; - //LOGE("isDes3"); - cond.notify_all(); - // LOGE("isDes1"); - return; - } - - - this->clearBuffers(); - - //如果Activity不处于活动状态就停止绘制 - if (!ActivityState)continue;//感觉没屌用 - imguiMainWinStart(); - - //菜单 - // MainView(); - ImGui::SetNextWindowBgAlpha(0.7); - //input->ItemActive = ImGui::IsAnyItemActive(); - //input->ItemHovered = ImGui::IsAnyItemHovered(); - //input->ItemFocused = ImGui::IsAnyItemFocused(); - style->WindowTitleAlign = ImVec2(0.5, 0.5);//标题居中 - //style->WindowMinSize = ImVec2(900, 800); - // FrameHeight = ImGui::GetFrameHeight(); - if (input->Scrollio && !input->Activeio) { - input->funScroll(g->WheelingWindow ? g->WheelingWindow : g->HoveredWindow); - } - - - ImGui::Begin("menuTest"); - input->g_window = g_window = ImGui::GetCurrentWindow(); - ImGui::SetWindowSize({500, 500}, ImGuiCond_FirstUseEver); - ImGui::SetWindowPos({0, 200}, ImGuiCond_FirstUseEver); - ImGui::Text("libwmw.so修改工具"); - char offset[18]; - ImGui::InputTextWithHint("##偏移", "请输入偏移", offset, IM_ARRAYSIZE(offset), - ImGuiInputTextFlags_CallbackAlways, - ImguiAndroidInput::inputCallback); - char str[24]; - ImGui::InputTextWithHint("##字节", "请输入修改的16进制字节,例如00 1A 2B 3C 4D 5E 6A 7B", str, IM_ARRAYSIZE(str), - ImGuiInputTextFlags_CallbackAlways, - ImguiAndroidInput::inputCallback); - if (ImGui::Button("修改")) PATCH_LIB("libwmw.so",offset,str); - - - - - - - - - - - - - - - - - - - - - ImGui::End(); - - imguiMainWinEnd(); - this->swapBuffers(); - input->fps = this->FPS; - } -} -int EGL::swapBuffers() { - //opengl当前buff传递至屏幕 - if (eglSwapBuffers(mEglDisplay, mEglSurface)) { - return 1; - } - LOGE("eglSwapBuffers error = %u", glGetError()); - return 0; -} -void EGL::clearBuffers() { - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - - -void EGL::imguiMainWinStart() { - // Start the Dear ImGui frame - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplAndroid_NewFrame(); - ImGui::NewFrame(); - -} - -void EGL::imguiMainWinEnd() { - // Render the Dear ImGui frame - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); -} - -void EGL::setSaveSettingsdir(string &dir) { - this->SaveDir = dir; - LOGE("保存路径=%s", SaveDir.c_str()); -} - -void EGL::setinput(ImguiAndroidInput *input_) { - this->input = input_; -} - - - diff --git a/app/src/main/jn/libdobby.a b/app/src/main/jn/libdobby.a deleted file mode 100644 index f3e1356..0000000 Binary files a/app/src/main/jn/libdobby.a and /dev/null differ diff --git a/app/src/main/jniLibs/arm64-v8a/libmui.so b/app/src/main/jniLibs/arm64-v8a/libmui.so index dfd1c93..c3da42e 100644 Binary files a/app/src/main/jniLibs/arm64-v8a/libmui.so and b/app/src/main/jniLibs/arm64-v8a/libmui.so differ