Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

This implementation focuses on stealth and efficiency by embedding the `FloatingModMenu.dex` as a HEX-encoded string within the native binary. At runtime, the JNI layer performs a dynamic bootstrap to initialize the menu without leaving any traces in the application's assets or data folders.

## Termux code
``
pkg install xxd
``
``
begin; printf '#define hexdex "'; xxd -p -c0 classes.dex | tr 'a-f' 'A-F' | tr -d '\n'; printf '"\n'; end > Dex.h
``
### Key Architectural Differences

* **Zero Disk Footprint:** No external dex file is shipped; the menu exists only in memory.
Expand Down
1 change: 0 additions & 1 deletion app/.gitignore

This file was deleted.

125 changes: 34 additions & 91 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,91 +1,34 @@
import com.android.build.gradle.tasks.ExternalNativeBuildTask
import java.io.FileInputStream

plugins {
alias(libs.plugins.android.application)
}

class JavaDex {
public static String xxd_p(String filePath) {
StringBuilder hexString = new StringBuilder()
File file = new File(filePath)
try (FileInputStream fis = new FileInputStream(file)) {
byte[] data = fis.readAllBytes()
for (byte b : data) {
hexString.append(String.format("%02X", b))
}
}
return hexString.toString()
}
}

android {
namespace 'com.android.support'
compileSdk 36

defaultConfig {
applicationId "com.android.support"
minSdk 28
targetSdk 36
versionCode 1
versionName "1.0"

ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
}

multiDexEnabled false
}

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

externalNativeBuild {
ndkBuild {
path file('src/main/jni/Android.mk')
}
ndkVersion = '28.2.13676358'
}

android.applicationVariants.all { variant ->
def variantName = variant.name.capitalize()
def taskName = "Dex2CppAnd8Up${variantName}"

def customTask = tasks.register(taskName) {
outputs.upToDateWhen { false }

def mergeDexTask = tasks.findByName("mergeDex${variantName}")
if (mergeDexTask) {
dependsOn mergeDexTask
}

doLast {
def dexDir = file("${project.buildDir}/intermediates/dex/${variant.name}/mergeDex${variantName}")
def dexFiles = fileTree(dir: dexDir, include: "**/classes.dex")

if (dexFiles.isEmpty()) {
throw new GradleException("classes.dex not found for ${variant.name} in ${dexDir}")
}

def dexFile = dexFiles.first()
String hexString = JavaDex.xxd_p(dexFile.absolutePath)
def headerFile = file("${project.projectDir}/src/main/jni/Includes/Dex.h")

headerFile.parentFile.mkdirs()
headerFile.write("#define hexdex \"${hexString}\"\n")
println ">>> Success: Generated header for ${variantName}"
}
}

tasks.configureEach { task ->
if (task.name.startsWith("buildNdkBuild${variantName}") ||
task.name.startsWith("externalNativeBuild${variantName}")) {
task.dependsOn customTask
}
}
}
}
plugins {
id 'com.android.application'
}

android {
namespace 'com.android.support'
compileSdkVersion 36

defaultConfig {
applicationId "com.android.support"
minSdkVersion 28
targetSdkVersion 36
versionCode 1
versionName "1.0"

ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
}
}

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

externalNativeBuild {
ndkBuild {
path file('src/main/jni/Android.mk')
}
}
}

4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.android.support">

<application
Expand All @@ -10,7 +9,8 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<activity android:name="com.android.support.MainActivity"
<activity
android:name="com.android.support.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
1 change: 1 addition & 0 deletions app/src/main/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ LOCAL_CFLAGS := -w -s -Wno-error=format-security -fvisibility=hidden -fpermissiv
LOCAL_CPPFLAGS := -w -s -Wno-error=format-security -fvisibility=hidden -Werror -std=c++17
LOCAL_CPPFLAGS += -Wno-error=c++11-narrowing -fpermissive -Wall -fexceptions
LOCAL_LDFLAGS += -Wl,--gc-sections,--strip-all,-llog
LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2
LOCAL_ARM_MODE := arm

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/jni/Application.mk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# To AIDE Users: If you are using 32-bit/ARMv7 phone, please remove arm64-v8a
APP_ABI := armeabi-v7a arm64-v8a x86
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
# APP_PLATFORM := android-18 #APP_PLATFORM does not need to be set. It will automatically defaulting
APP_STL := c++_static
APP_OPTIM := release
Expand Down
17 changes: 8 additions & 9 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#202020"
tools:context="com.android.support.MainActivity">
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#202020"
tools:context="com.android.support.MainActivity">
</FrameLayout>
27 changes: 23 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:8.13.2"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
mavenCentral()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
22 changes: 0 additions & 22 deletions gradle/libs.versions.toml

This file was deleted.

25 changes: 2 additions & 23 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1,23 +1,2 @@
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}

rootProject.name = "Native-LGL"
include ':app'
rootProject.name = "Native-LGL"
include ':app'