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