Skip to content

Commit

Permalink
Updated 2.9
Browse files Browse the repository at this point in the history
- Updated OBFUSCATE again. Now it will generate key
- Updated gradle to 7.0.0
- Added macros for hook and patches. Strings are in macros are automatically obfuscated. There is no need to obfuscate!
- Adjustments to spinner. However, I'm still unable to fix spinner for Android 11. If you know the fix, please let me know or make a pull request
  • Loading branch information
LGLTeam committed Aug 4, 2021
1 parent 2a9572d commit 961c350
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 127 deletions.
4 changes: 2 additions & 2 deletions README-MOBILE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- [Prerequisites](https://github.com/LGLTeam/Android-Mod-Menu/blob/master/README.md#prerequisites)
- [What you need](#what-you-need)
- [Video Tutorial](#video-tutorial)
- [Download/clone](#downloadclone)
- [Installation](#installation)
- [Setting up AIDE](#setting-up-aide)
- [Files to work with and making changes](#files-to-work-with-and-making-changes)
- [Implementing the menu to the target game](#implementing-the-menu-to-the-target-game)
Expand Down Expand Up @@ -36,7 +36,7 @@ NSRAÎNA HACKER: https://www.youtube.com/watch?v=MkkZ_loEDTU

BROKE MODS OFC (Customized menu): https://www.youtube.com/watch?v=IYREVGc-quM

# Download/Clone
# Installation

Go to releases page https://github.com/LGLTeam/Android-Mod-Menu/releases/ and download **Source code (zip)**

Expand Down
50 changes: 31 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

**For Android mobile users who don't have a PC, please read [README-MOBILE.md](https://github.com/LGLTeam/Android-Mod-Menu/blob/master/README-MOBILE.md)**

# Quick links
# KNOWN BUG
- Spinner does not show on Android 11

# Table of contents
- [Prerequisites](https://github.com/LGLTeam/Android-Mod-Menu/blob/master/README.md#prerequisites)
- [What you need](#what-you-need)
- [Download/clone](#downloadclone)
- [Video Tutorial](#video-tutorial)
- [Setting up](#setting-up)
- [Installation](#installation)
- [Files to work with and making changes](#files-to-work-with-and-making-changes)
- [Implementing the menu to the target game](#implementing-the-menu-to-the-target-game)
- [Loading lib without mod menu](#loading-lib-without-mod-menu)
Expand Down Expand Up @@ -50,31 +52,22 @@ Before we can jump head first into working a template, we need to go over a few
* Any base64 encoding to encode your file: We use https://www.base64encode.org/
* ARM converter, to convert ARM instruction to hex: https://armconverter.com/

# Download/Clone
Download this repo as ZIP, or clone using any git tools

Or download Releases here https://github.com/LGLTeam/Android-Mod-Menu/releases

Extract the source to your desired location. The location must **NOT** contain any spaces or symbols

# Video Tutorial

Big thanks to modders who created a video tutorial for me. Be warned, those videos might be outdated

PMT DVA: https://www.youtube.com/watch?v=ieMclBtL6Ig

Pasha Production: https://www.youtube.com/watch?v=RvrZKIe-QGc

# Setting up
# Installation
Download this repo as ZIP, or clone using any git tools

Make sure you have everything you need to prepare to work.
Or download Releases here https://github.com/LGLTeam/Android-Mod-Menu/releases

Extract the project to the location **WITHOUT** spaces and weird symbols. Spaces and symbols can cause problems
Extract the source to your desired location. The location must **NOT** contain any spaces or symbols

Open the project

![](https://i.imgur.com/3etm4qX.png)

Please wait for a while, it will index and sync the project for the first time, takes around a minute depending your computer performance

After it's done, you can start working!
Expand Down Expand Up @@ -244,7 +237,7 @@ CollapseAdd_Toggle_The toggle
CollapseAdd_Button_The button
```

#### KittyMemory usage:
#### KittyMemory patching usage:
```cpp
MemoryPatch::createWithHex([Lib Name], [offset], "[hex. With or without spaces]");
[Struct].get_CurrBytes().Modify();
Expand All @@ -253,13 +246,32 @@ MemoryPatch::createWithHex([Lib Name], [offset], "[hex. With or without spaces]"
[Struct].get_TargetAddress();
[Struct].get_PatchSize();
[Struct].get_CurrBytes().c_str();

PATCHOFFSET("0x20D3A8", "00 00 A0 E3 1E FF 2F E1");
PATCHOFFSET_LIB("libFileB.so", "0x20D3A8", "00 00 A0 E3 1E FF 2F E1");
```
Example: https://github.com/MJx0/KittyMemory/blob/master/Android/test/src/main.cpp
Use ARM Converter to convert ARM to HEX: https://armconverter.com/
Use an online ARM assembly converter like ARMConverter to convert ARM to HEX: https://armconverter.com/
#### Hook usage:
This macro works for both ARMv7 and ARM64. Make sure to use predefined macro `defined(__aarch64__)` and `defined(__arm__)` if you are targeting both archs
Strings for macros are automatically obfuscated. No need to obfuscate!
```cpp
HOOK("0x123456", FunctionExample, old_FunctionExample);
HOOK_LIB("libFileB.so", "0x123456", FunctionExample, old_FunctionExample);
HOOK_NO_ORIG("0x123456", FunctionExample);
HOOK_LIB_NO_ORIG("libFileC.so", "0x123456", FunctionExample);
HOOKSYM("__SymbolNameExample", FunctionExample, old_FunctionExample);
HOOKSYM_LIB("libFileB.so", "__SymbolNameExample", FunctionExample, old_FunctionExample);
HOOKSYM_NO_ORIG("__SymbolNameExample", FunctionExample);
HOOKSYM_LIB_NO_ORIG("libFileB.so", "__SymbolNameExample", FunctionExample);
```

Or

ARM64:
```cpp
A64HookFunction((void *) getAbsoluteAddress([Lib Name], [offset]), (void *)[function], (void **)&[old function]);
Expand Down Expand Up @@ -539,4 +551,4 @@ Thanks to the following individuals whose code helped me develop this mod menu
* MrIkso - First mod menu template https://github.com/MrIkso/FloatingModMenu
* MJx0 A.K.A Ruit - https://github.com/MJx0/KittyMemory
* Rprop - https://github.com/Rprop/And64InlineHook
* And everyone else who provided input and contributions to this project!
* And everyone else who provided input and contributions to this project!
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ android {
minSdkVersion 19
targetSdkVersion 30
versionCode 1
versionName "2.8"
versionName "2.9"
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86'
}
Expand Down
7 changes: 3 additions & 4 deletions app/src/main/java/uk/lgl/modmenu/FloatingModMenuService.java
Original file line number Diff line number Diff line change
Expand Up @@ -686,18 +686,17 @@ private View Spinner(final int featNum, final String featName, final String list
// Create another LinearLayout as a workaround to use it as a background
// to keep the down arrow symbol. No arrow symbol if setBackgroundColor set
LinearLayout linearLayout2 = new LinearLayout(this);
LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
layoutParams2.setMargins(10, 2, 10, 5);
LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
layoutParams2.setMargins(7, 2, 7, 5);
linearLayout2.setOrientation(LinearLayout.VERTICAL);
linearLayout2.setBackgroundColor(BTN_COLOR);
linearLayout2.setLayoutParams(layoutParams2);

final Spinner spinner = new Spinner(this, Spinner.MODE_DROPDOWN);
spinner.setPadding(5, 10, 5, 8);
spinner.setLayoutParams(layoutParams2);
spinner.getBackground().setColorFilter(1, PorterDuff.Mode.SRC_ATOP); //trick to show white down arrow color
//Creating the ArrayAdapter instance having the list
ArrayAdapter aa = new ArrayAdapter(this, android.R.layout.simple_spinner_item, lists);
ArrayAdapter aa = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, lists);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Setting the ArrayAdapter data on the Spinner'
spinner.setAdapter(aa);
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/jni/And64InlineHook/And64InlineHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,12 +603,12 @@ A64_JNIEXPORT void A64HookFunction(void *const symbol, void *const replace, void

//fix Android 10 .text segment is read-only by default
__make_rwx(symbol, 5 * sizeof(size_t));

trampoline = A64HookFunctionV(symbol, replace, trampoline, A64_MAX_INSTRUCTIONS * 10u);
if (trampoline == NULL && result != NULL) {
*result = NULL;
} //if
}
}

#endif // defined(__aarch64__)
#endif // defined(__aarch64__)
71 changes: 71 additions & 0 deletions app/src/main/jni/Includes/Macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef ANDROID_MOD_MENU_MACROS_H
#define ANDROID_MOD_MENU_MACROS_H

// thanks to shmoo and joeyjurjens for the usefull stuff under this comment.

#if defined(__aarch64__) //Compile for arm64 lib only
#include <And64InlineHook/And64InlineHook.hpp>

#define HOOK(offset, ptr, orig) A64HookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig)
#define HOOK_LIB(lib, offset, ptr, orig) A64HookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig)

#define HOOK_NO_ORIG(offset, ptr) A64HookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL)
#define HOOK_LIB_NO_ORIG(lib, offset, ptr) A64HookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL)

#define HOOKSYM(sym, ptr, org) A64HookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org)
#define HOOKSYM_LIB(lib, sym, ptr, org) A64HookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org)

#define HOOKSYM_NO_ORIG(sym, ptr) A64HookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, NULL)
#define HOOKSYM_LIB_NO_ORIG(lib, sym, ptr) A64HookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, NULL)

#else //Compile for armv7 lib only. Do not worry about greyed out highlighting code, it still works

#include <Substrate/SubstrateHook.h>
#include <Substrate/CydiaSubstrate.h>

#define HOOK(offset, ptr, orig) MSHookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig)
#define HOOK_LIB(lib, offset, ptr, orig) MSHookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig)

#define HOOK_NO_ORIG(offset, ptr) MSHookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL)
#define HOOK_LIB_NO_ORIG(lib, offset, ptr) MSHookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL)

#define HOOKSYM(sym, ptr, org) MSHookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org)
#define HOOKSYM_LIB(lib, sym, ptr, org) MSHookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org)

#define HOOKSYM_NO_ORIG(sym, ptr) MSHookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, NULL)
#define HOOKSYM_LIB_NO_ORIG(lib, sym, ptr) MSHookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, NULL)

#endif

// Obfuscate offset
#define OBFUSCATEOFFSET(str) string2Offset(OBFUSCATE(str)) // Encrypt offset

// Patching a offset without switch.
void patchOffset(const char *fileName, uint64_t offset, std::string hexBytes) {
MemoryPatch patch = MemoryPatch::createWithHex(fileName, offset, hexBytes);
if(!patch.isValid()){
LOGE(OBFUSCATE("Failing offset: 0x%llu, please re-check the hex you entered."), offset);
return;
}
if(!patch.Modify()) {
LOGE(OBFUSCATE("Something went wrong while patching this offset: 0x%llu"), offset);
return;
}
}

void patchOffset(uint64_t offset, std::string hexBytes) {
MemoryPatch patch = MemoryPatch::createWithHex(targetLibName, offset, hexBytes);
if(!patch.isValid()){
LOGE(OBFUSCATE("Failing offset: 0x%llu, please re-check the hex you entered."), offset);
return;
}
if(!patch.Modify()) {
LOGE(OBFUSCATE("Something went wrong while patching this offset: 0x%llu"), offset);
return;
}
}

#define PATCHOFFSET(offset, hex) patchOffset(string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex))
#define PATCHOFFSET_LIB(lib, offset, hex) patchOffset(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex))

#endif //ANDROID_MOD_MENU_MACROS_H
55 changes: 31 additions & 24 deletions app/src/main/jni/Includes/obfuscate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ Guaranteed compile-time string literal obfuscation library for C++14
Pass string literals into the AY_OBFUSCATE macro to obfuscate them at compile
time. AY_OBFUSCATE returns a reference to an ay::obfuscated_data object with the
following traits:
- Guaranteed obfuscation of string
The passed string is encrypted with a simple XOR cipher at compile-time to
prevent it being viewable in the binary image
- Global lifetime
The actual instantiation of the ay::obfuscated_data takes place inside a
lambda as a function level static
- Implicitly convertable to a char*
This means that you can pass it directly into functions that would normally
take a char* or a const char*
- Guaranteed obfuscation of string
The passed string is encrypted with a simple XOR cipher at compile-time to
prevent it being viewable in the binary image
- Global lifetime
The actual instantiation of the ay::obfuscated_data takes place inside a
lambda as a function level static
- Implicitly convertable to a char*
This means that you can pass it directly into functions that would normally
take a char* or a const char*
Example:
const char* obfuscated_string = AY_OBFUSCATE("Hello World");
std::cout << obfuscated_string << std::endl;
Expand All @@ -28,32 +28,38 @@ std::cout << obfuscated_string << std::endl;
// The default 64 bit key to obfuscate strings with.
// This can be user specified by defining AY_OBFUSCATE_DEFAULT_KEY before
// including obfuscate.h
#define AY_OBFUSCATE_DEFAULT_KEY 0x3AD51D91CCE7BFC9
#define AY_OBFUSCATE_DEFAULT_KEY ay::generate_key(__LINE__)
#endif

namespace ay
{
using size_type = unsigned long long;
using key_type = unsigned long long;

// Generate a psuedo-random key that spans all 8 bytes
constexpr key_type generate_key(key_type seed)
{
// Use the MurmurHash3 64-bit finalizer to hash our seed
key_type key = seed;
key ^= (key >> 33);
key *= 0xff51afd7ed558ccd;
key ^= (key >> 33);
key *= 0xc4ceb9fe1a85ec53;
key ^= (key >> 33);

// Make sure that a bit in each byte is set
key |= 0x0101010101010101ull;

return key;
}

// Obfuscates or deobfuscates data with key
constexpr void cipher(char* data, size_type size, key_type key)
{
// Split the key into unaligned chunks
const char chunks[8] = {
char(key >> 41),
char(key >> 31),
char(key >> 7),
char(key >> 17),
char(key >> 47),
char(key),
char(key >> 55),
char(key >> 25)
};

// Obfuscate with an XOR cipher based on key
// Obfuscate with a simple XOR cipher based on key
for (size_type i = 0; i < size; i++)
{
data[i] ^= chunks[i % 8];
data[i] ^= char(key >> ((i % 8) * 8));
}
}

Expand Down Expand Up @@ -190,6 +196,7 @@ namespace ay
#define OBFUSCATE_KEY(data, key) \
[]() -> ay::obfuscated_data<sizeof(data)/sizeof(data[0]), key>& { \
static_assert(sizeof(decltype(key)) == sizeof(ay::key_type), "key must be a 64 bit unsigned integer"); \
static_assert((key) >= (1ull << 56), "key must span all 8 bytes"); \
constexpr auto n = sizeof(data)/sizeof(data[0]); \
constexpr auto obfuscator = ay::make_obfuscator<n, key>(data); \
static auto obfuscated_data = ay::obfuscated_data<n, key>(obfuscator); \
Expand Down
Loading

0 comments on commit 961c350

Please sign in to comment.