diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..a2d7c21 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bdd9278 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..2120d43 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'com.teamuxh.uxh_toolkit' + compileSdk 32 + + defaultConfig { + applicationId "com.teamuxh.uxh_toolkit" + minSdk 23 + targetSdk 32 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + externalNativeBuild { + cmake { + cppFlags '' + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + externalNativeBuild { + cmake { + path file('src/main/cpp/CMakeLists.txt') + version '3.18.1' + } + } +} + +dependencies { + def libsuVersion = '5.0.3' + + // The core module that provides APIs to a shell + implementation "com.github.topjohnwu.libsu:core:${libsuVersion}" + + // Optional: APIs for creating root services. Depends on ":core" + implementation "com.github.topjohnwu.libsu:service:${libsuVersion}" + + // Optional: Provides remote file system support + implementation "com.github.topjohnwu.libsu:nio:${libsuVersion}" + + implementation 'androidx.core:core-ktx:1.7.0' + implementation 'androidx.appcompat:appcompat:1.5.1' + implementation 'com.google.android.material:material:1.7.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b52f576 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/aidl/com/teamuxh/uxh_toolkit/ITestRoot.aidl b/app/src/main/aidl/com/teamuxh/uxh_toolkit/ITestRoot.aidl new file mode 100644 index 0000000..32e2f51 --- /dev/null +++ b/app/src/main/aidl/com/teamuxh/uxh_toolkit/ITestRoot.aidl @@ -0,0 +1,14 @@ +// ITestRoot.aidl +package com.teamuxh.uxh_toolkit; + +// Declare any non-default types here with import statements + +interface ITestRoot { + /** * Demonstrates some basic types that you can use as parameters + * and return values in AIDL. + */ + int getUid(); + int getAppPid(String packageName); + int getLibAddress(int pid,String libName); + String[] getLoadedLibrary(int pid); +} \ No newline at end of file diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..3329711 --- /dev/null +++ b/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.18.1) + + +project("uxh_toolkit") + +add_library(uxh_toolkit + SHARED + main.cpp) + +find_library(log-lib + log) + +target_link_libraries( + uxh_toolkit + ${log-lib}) + +add_library( + root + SHARED + rootMain.cpp +) +find_library(log-lib + log) +target_link_libraries( + root + ${log-lib}) \ No newline at end of file diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp new file mode 100644 index 0000000..1de9ec0 --- /dev/null +++ b/app/src/main/cpp/main.cpp @@ -0,0 +1,3 @@ +#include +#include +#include diff --git a/app/src/main/cpp/rootMain.cpp b/app/src/main/cpp/rootMain.cpp new file mode 100644 index 0000000..a45cb52 --- /dev/null +++ b/app/src/main/cpp/rootMain.cpp @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Created by hurri on 23-11-2022. +// + + +extern "C" +JNIEXPORT jint JNICALL +Java_com_teamuxh_uxh_1toolkit_constant_NativeRoot_00024Companion_nativeGetUid(JNIEnv *env, + jobject thiz) { + return (int) getuid(); +} +extern "C" +JNIEXPORT jint JNICALL +Java_com_teamuxh_uxh_1toolkit_constant_NativeRoot_00024Companion_nativeGetPid(JNIEnv *env, + jobject thiz, + jstring package_name) { + const char *packagename = env->GetStringUTFChars(package_name, nullptr); + int id = -1; + DIR *dir; + FILE *fp; + char filename[512]; + char cmdline[256]; + struct dirent *entry; + dir = opendir("/proc"); + while ((entry = readdir(dir)) != NULL) { + id = atoi(entry->d_name); + if (id != 0) { + sprintf(filename, "/proc/%d/cmdline", id); + fp = fopen(filename, "r"); + if (fp) { + fgets(cmdline, sizeof(cmdline), fp); + fclose(fp); + + if (strcmp(packagename, cmdline) == 0) { + return id; + } + } + } + } + closedir(dir); + return -1; +} + + + + +extern "C" +JNIEXPORT jint JNICALL +Java_com_teamuxh_uxh_1toolkit_constant_NativeRoot_00024Companion_getModuleAddress(JNIEnv *env, + jobject thiz, + jint pid, + jstring lib_name) { + const char *module_name = env->GetStringUTFChars(lib_name, 0); + FILE *fp; + long addr = 0; + char *pch; + char filename[32]; + char line[1024]; + snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); + fp = fopen(filename, "r"); + if (fp != NULL) { + while (fgets(line, sizeof(line), fp)) { + if (strstr(line, module_name)) { + pch = strtok(line, "-"); + addr = strtoul(pch, NULL, 16); + if (addr == 0x8000) + addr = 0; + break; + } + } + fclose(fp); + + } + return addr; +} + +void test() { + +} + +extern "C" +JNIEXPORT jobjectArray JNICALL +Java_com_teamuxh_uxh_1toolkit_constant_NativeRoot_00024Companion_getLoadedLibraries(JNIEnv *env, + jobject thiz, + jint pid) { + jobjectArray pArray = nullptr; + char filename[32]; + snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); + std::ifstream file(filename); + std::unordered_set values; + std::string line; + while (std::getline(file, line)) { + std::istringstream iss(line); + std::string word; + for (int i = 0; i < 6; ++i) { + iss >> word; + if (i == 5 && word.find(".so") != std::string::npos) + values.insert(word); + } + } + file.close(); + std::vector vecValues(values.begin(), values.end()); + std::sort(vecValues.begin(), vecValues.end()); + pArray = env->NewObjectArray(vecValues.size(), env->FindClass("java/lang/String"), + nullptr); + for (int i = 0; i < vecValues.size(); i++) { + env->SetObjectArrayElement(pArray, i, env->NewStringUTF(vecValues[i].c_str())); + } + + return pArray; +} \ No newline at end of file diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/MainActivity.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/MainActivity.kt new file mode 100644 index 0000000..279c02e --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/MainActivity.kt @@ -0,0 +1,30 @@ +package com.teamuxh.uxh_toolkit + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import com.teamuxh.uxh_toolkit.ui.main.MainFragment +import com.topjohnwu.superuser.Shell + +class MainActivity : AppCompatActivity() { + + companion object{ + init { + Shell.enableVerboseLogging = true + Shell.setDefaultBuilder( + Shell.Builder.create() + .setFlags(Shell.FLAG_REDIRECT_STDERR) + .setTimeout(10) + ) + } + } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + if (savedInstanceState == null) { + supportFragmentManager.beginTransaction() + .replace(R.id.container, MainFragment()) + .commitNow() + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/constant/Native.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/constant/Native.kt new file mode 100644 index 0000000..6e664df --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/constant/Native.kt @@ -0,0 +1,9 @@ +package com.teamuxh.uxh_toolkit.constant + +class Native { + companion object{ + init { + System.loadLibrary("uxh_toolkit") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/constant/NativeRoot.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/constant/NativeRoot.kt new file mode 100644 index 0000000..faaaee6 --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/constant/NativeRoot.kt @@ -0,0 +1,16 @@ +package com.teamuxh.uxh_toolkit.constant + +import android.os.Process + +class NativeRoot { + companion object{ + external fun nativeGetUid() : Int + external fun nativeGetPid(packageName : String) : Int + external fun getModuleAddress(pid : Int,libName : String) : Int + external fun getLoadedLibraries(pid : Int) : Array + init { + if (Process.myUid() == 0) + System.loadLibrary("root") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/services/RootService.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/services/RootService.kt new file mode 100644 index 0000000..b4ca0ad --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/services/RootService.kt @@ -0,0 +1,35 @@ +package com.teamuxh.uxh_toolkit.services + +import android.content.Intent +import com.teamuxh.uxh_toolkit.ITestRoot +import com.teamuxh.uxh_toolkit.constant.NativeRoot +import com.teamuxh.uxh_toolkit.utils.Logger.Companion.logD + + +class RootService : com.topjohnwu.superuser.ipc.RootService(){ + + class IRootClass : ITestRoot.Stub() { + override fun getUid(): Int { + return NativeRoot.nativeGetUid() + } + + override fun getAppPid(packageName: String?): Int { + return NativeRoot.nativeGetPid(packageName.toString()) + } + + override fun getLibAddress(pid: Int, libName: String?): Int { + return NativeRoot.getModuleAddress(pid,libName.toString()) + } + override fun getLoadedLibrary(pid : Int): Array { + return NativeRoot.getLoadedLibraries(pid) + } + + + } + override fun onBind(intent: Intent): IRootClass { + logD("onBind: Called") + return IRootClass() + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/LibSheetDialog.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/LibSheetDialog.kt new file mode 100644 index 0000000..afe81f6 --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/LibSheetDialog.kt @@ -0,0 +1,116 @@ +package com.teamuxh.uxh_toolkit.ui.main + +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.widget.SearchView +import android.widget.TextView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.teamuxh.uxh_toolkit.R +import com.teamuxh.uxh_toolkit.utils.Logger.Companion.logD +import java.util.* +import kotlin.collections.ArrayList + +class LibSheetDialog( + private var array: Array, + private var resultPid: Int, + private val terminal: (string: String) -> Unit +) : BottomSheetDialogFragment() { + private lateinit var arrayBack: Array + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE and WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) + arrayBack = array + val view = inflater.inflate(R.layout.lib_dialog_sheet, container, false) + val showResult = view.findViewById(R.id.show_result) + + val recyclerView = view.findViewById(R.id.libRecycleView) + val searchView = view.findViewById(R.id.search_lib) + val dialogAdapter = DialogAdapter() + + searchView.setOnCloseListener { + dialogAdapter.filterList(array) + return@setOnCloseListener false + } + searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + override fun onQueryTextSubmit(p0: String?): Boolean { + return false + } + + override fun onQueryTextChange(newText: String): Boolean { + val filteredList: ArrayList = ArrayList() + for (i in arrayBack.indices) { + if (arrayBack[i].lowercase().contains(newText.lowercase())) { + filteredList.add(arrayBack[i]) + } + } + dialogAdapter.filterList(filteredList.toTypedArray()) + + return false + } + }) + showResult.text = getString(R.string.showing_results_302, array.size) + val layoutManager = LinearLayoutManager(requireActivity()) + layoutManager.orientation = LinearLayoutManager.VERTICAL + recyclerView.layoutManager = layoutManager + recyclerView.adapter = dialogAdapter + dialogAdapter.notifyDataSetChanged() + return view + } + + inner class DialogAdapter : + RecyclerView.Adapter() { + + inner class Adapter(itemView: View) : RecyclerView.ViewHolder(itemView) { + val textView: TextView + + init { + textView = itemView.findViewById(R.id.libName) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Adapter { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.text_row, parent, false) + return Adapter(view) + } + + @SuppressLint("NotifyDataSetChanged") + fun filterList(filterList: Array) { + array = filterList + notifyDataSetChanged() + } + + override fun onBindViewHolder(holder: Adapter, position: Int) { + holder.textView.text = array[position] + holder.textView.setOnClickListener { + val libAddress = + MainFragment.iTestRoot.getLibAddress(resultPid, holder.textView.text.toString()) + terminal( + "($resultPid)[${holder.textView.text}] Address is 0x${ + java.lang.String.format( + "%02X", + libAddress + ) + }" + ) + dismiss() + + + } + } + + override fun getItemCount(): Int = array.size + } +} + + diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/MainFragment.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/MainFragment.kt new file mode 100644 index 0000000..b3cdbc5 --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/MainFragment.kt @@ -0,0 +1,182 @@ +package com.teamuxh.uxh_toolkit.ui.main + +import android.content.ComponentName +import android.content.Intent +import android.content.ServiceConnection +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.os.Bundle +import android.os.IBinder +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.AutoCompleteTextView +import android.widget.TextView +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import com.google.android.material.button.MaterialButton +import com.google.android.material.textfield.TextInputEditText +import com.teamuxh.uxh_toolkit.ITestRoot +import com.teamuxh.uxh_toolkit.R +import com.teamuxh.uxh_toolkit.services.RootService +import com.teamuxh.uxh_toolkit.utils.Logger.Companion.logD +import com.teamuxh.uxh_toolkit.utils.Toast +import com.topjohnwu.superuser.Shell + + +class MainFragment : Fragment() { + + private var rootAccess: Boolean = false + private lateinit var autoCompleteTextView: AutoCompleteTextView + private lateinit var libNameText: TextInputEditText + private lateinit var processIdCLink: MaterialButton + private lateinit var getLibAdrName: MaterialButton + private lateinit var getLoadedLibs: MaterialButton + private lateinit var clearOutput: MaterialButton + private lateinit var textInput: TextView + + private lateinit var arrayAdapter: ArrayAdapter + private lateinit var viewModel: MainViewModel + + companion object { + lateinit var iTestRoot: ITestRoot + } + + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + autoCompleteTextView = view.findViewById(R.id.package_name) + processIdCLink = view.findViewById(R.id.get_processID) + getLibAdrName = view.findViewById(R.id.get_libAddress) + clearOutput = view.findViewById(R.id.clearOutput) + getLoadedLibs = view.findViewById(R.id.getLoadedLibs) + + libNameText = view.findViewById(R.id.lib_text) + textInput = view.findViewById(R.id.inputTerminal) + viewModel = ViewModelProvider(this)[MainViewModel::class.java] + arrayAdapter = ArrayAdapter(requireActivity(), R.layout.list_item, getInstalledApps()) + autoCompleteTextView.setAdapter(arrayAdapter) + + + getLoadedLibs.setOnClickListener { + if (autoCompleteTextView.text.isEmpty()) + Toast.toastLong(requireActivity(), "package id can't be empty") + else if (!rootAccess) + Toast.toastLong(requireActivity(), "Root access not found") + else { + val resultPid = iTestRoot.getAppPid(autoCompleteTextView.text.toString()) + if (resultPid == -1) + Toast.toastLong(requireActivity(), "App is not running") + else { + /* Thread { + val libAddress = iTestRoot.getLoadedLibrary(resultPid) + for (i in libAddress.indices){ + requireActivity().runOnUiThread { + updateTerminalOutput(libAddress[i]) + } + } + }.start()*/ + val libSheetDialog = LibSheetDialog( + iTestRoot.getLoadedLibrary(resultPid), + resultPid, ::updateTerminalOutput + ) + libSheetDialog.show(requireActivity().supportFragmentManager, tag) + } + } + } + + clearOutput.setOnClickListener { textInput.text = "" } + + getLibAdrName.setOnClickListener { + if (autoCompleteTextView.text.isEmpty()) + Toast.toastLong(requireActivity(), "package id can't be empty") + else if (libNameText.text!!.isEmpty()) + Toast.toastLong(requireActivity(), "lib name can't be empty") + else if (!rootAccess) + Toast.toastLong(requireActivity(), "Root access not found") + else { + val resultPid = iTestRoot.getAppPid(autoCompleteTextView.text.toString()) + if (resultPid == -1) + Toast.toastLong(requireActivity(), "App is not running") + else { + val libAddress = iTestRoot.getLibAddress(resultPid, libNameText.text.toString()) + updateTerminalOutput( + "($resultPid)[${libNameText.text}] Address is 0x${ + java.lang.String.format( + "%02X", + libAddress + ) + }" + ) + } + } + } + processIdCLink.setOnClickListener { + if (autoCompleteTextView.text.isEmpty()) + Toast.toastLong(requireActivity(), "package id can't be empty") + else if (!rootAccess) + Toast.toastLong(requireActivity(), "Root access not found") + else { + val resultPid = iTestRoot.getAppPid(autoCompleteTextView.text.toString()) + if (resultPid == -1) + Toast.toastLong(requireActivity(), "App is not running") + else + updateTerminalOutput("App is running at pid $resultPid") + } + } + + Shell.getShell { + rootAccess = true + com.topjohnwu.superuser.ipc.RootService.bind( + Intent( + requireActivity(), + RootService::class.java + ), AidlConnection(true) + ) + } + } + + class AidlConnection(daemon: Boolean) : ServiceConnection { + private var isDaemon: Boolean? = null + + init { + isDaemon = daemon + } + + override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) { + iTestRoot = ITestRoot.Stub.asInterface(p1) + logD("onServiceConnected: Connected") + } + + override fun onServiceDisconnected(p0: ComponentName?) { + logD("onServiceDisconnected: Disconnected") + } + } + + private fun updateTerminalOutput(newMessage: String) { + if (textInput.text.isEmpty()) { + textInput.text = newMessage + } else { + textInput.text = getString(R.string.terminal, textInput.text.toString(), newMessage) + } + } + + private fun getInstalledApps(): List { + val packages: List = + requireActivity().packageManager.getInstalledApplications(PackageManager.GET_META_DATA) + val ret: MutableList = ArrayList() + for (s in packages) { + ret.add(s.packageName) + } + return ret + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater.inflate(R.layout.fragment_main, container, false) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/MainViewModel.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/MainViewModel.kt new file mode 100644 index 0000000..2bc1370 --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/ui/main/MainViewModel.kt @@ -0,0 +1,7 @@ +package com.teamuxh.uxh_toolkit.ui.main + +import androidx.lifecycle.ViewModel + +class MainViewModel : ViewModel() { + // TODO: Implement the ViewModel +} \ No newline at end of file diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/utils/Logger.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/utils/Logger.kt new file mode 100644 index 0000000..28216a5 --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/utils/Logger.kt @@ -0,0 +1,17 @@ +package com.teamuxh.uxh_toolkit.utils + +import android.util.Log + +class Logger { + companion object{ + /** + * Simple Logger to debug your applications + */ + private const val tag = "TeamUxHLog" + private const val debug = true + fun logD(message : String){if (debug) Log.d(tag,message)} + fun logV(message: String){if (debug) Log.v(tag,message)} + fun logI(message: String){if (debug) Log.i(tag,message)} + fun logE(message: String){if (debug) Log.e(tag,message)} + } +} \ No newline at end of file diff --git a/app/src/main/java/com/teamuxh/uxh_toolkit/utils/Toast.kt b/app/src/main/java/com/teamuxh/uxh_toolkit/utils/Toast.kt new file mode 100644 index 0000000..49446e2 --- /dev/null +++ b/app/src/main/java/com/teamuxh/uxh_toolkit/utils/Toast.kt @@ -0,0 +1,13 @@ +package com.teamuxh.uxh_toolkit.utils + +import android.content.Context + +class Toast { + companion object{ + /** + * Toast for ease + */ + fun toastLong(context: Context,message : String){android.widget.Toast.makeText(context,message,android.widget.Toast.LENGTH_SHORT).show()} + fun toastShort(context: Context,message : String){android.widget.Toast.makeText(context,message,android.widget.Toast.LENGTH_SHORT).show()} + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/box_output.xml b/app/src/main/res/drawable/box_output.xml new file mode 100644 index 0000000..622c634 --- /dev/null +++ b/app/src/main/res/drawable/box_output.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..1dfb73b --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml new file mode 100644 index 0000000..5b5ee31 --- /dev/null +++ b/app/src/main/res/layout/fragment_main.xml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/lib_dialog_sheet.xml b/app/src/main/res/layout/lib_dialog_sheet.xml new file mode 100644 index 0000000..718ee8c --- /dev/null +++ b/app/src/main/res/layout/lib_dialog_sheet.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/list_item.xml b/app/src/main/res/layout/list_item.xml new file mode 100644 index 0000000..ff03d23 --- /dev/null +++ b/app/src/main/res/layout/list_item.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/text_row.xml b/app/src/main/res/layout/text_row.xml new file mode 100644 index 0000000..8564664 --- /dev/null +++ b/app/src/main/res/layout/text_row.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..0f9f3ee --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..f0cb738 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,9 @@ + + UxH_ToolKit + Root ToolKit + Lib Name + %1$s\n%2$s + Loaded Libs + search loaded libs + Showing results : %1$d + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..b4f952c --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000..fa0f996 --- /dev/null +++ b/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000..9ee9997 --- /dev/null +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..2536974 --- /dev/null +++ b/build.gradle @@ -0,0 +1,6 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id 'com.android.application' version '7.3.1' apply false + id 'com.android.library' version '7.3.1' apply false + id 'org.jetbrains.kotlin.android' version '1.7.20' apply false +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..3c5031e --- /dev/null +++ b/gradle.properties @@ -0,0 +1,23 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..864369e --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat Oct 22 10:36:13 IST 2022 +distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..b658d13 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,20 @@ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + maven { url 'https://jitpack.io' } + + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven { url 'https://jitpack.io' } + + } +} +rootProject.name = "UxH_ToolKit" +include ':app'