Upload source files to complete submission of history changes

Co-authored-by:Shirkneko <Shirkneko@2773800761@qq.com>
This commit is contained in:
ShirkNeko
2025-03-22 14:37:14 +08:00
parent 3121eb0f9a
commit 7b7fff91a6
14 changed files with 1 additions and 631 deletions

View File

@@ -1,62 +0,0 @@
name: Build ksud_magic
on:
workflow_call:
inputs:
target:
required: true
type: string
os:
required: false
type: string
default: ubuntu-latest
pack_lkm:
required: false
type: boolean
default: true
use_cache:
required: false
type: boolean
default: true
jobs:
build:
runs-on: ${{ inputs.os }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Prepare LKM fies
if: ${{ inputs.pack_lkm }}
run: |
cp android*-lkm/*_kernelsu.ko ./userspace/ksud_magic/bin/aarch64/
- name: Import susfsd lib
run: |
cp susfsd-aarch64-linux-android/arm64-v8a/susfsd ./userspace/ksud_magic/bin/aarch64/
- name: Setup rustup
run: |
rustup update stable
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
- uses: Swatinem/rust-cache@v2
with:
workspaces: userspace/ksud_magic
cache-targets: false
- name: Install cross
run: |
cargo install cross --git https://github.com/cross-rs/cross --rev 66845c1 --force
- name: Build ksud_magic
run: CROSS_NO_WARNINGS=0 cross build --target ${{ inputs.target }} --release --manifest-path ./userspace/ksud_magic/Cargo.toml
- name: Upload ksud_magic artifact
uses: actions/upload-artifact@v4
with:
name: ksud_magic-${{ inputs.target }}
path: userspace/ksud_magic/target/**/release/ksud*

View File

@@ -1,62 +0,0 @@
name: Build ksud_overlayfs
on:
workflow_call:
inputs:
target:
required: true
type: string
os:
required: false
type: string
default: ubuntu-latest
pack_lkm:
required: false
type: boolean
default: true
use_cache:
required: false
type: boolean
default: true
jobs:
build:
runs-on: ${{ inputs.os }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Prepare LKM fies
if: ${{ inputs.pack_lkm }}
run: |
cp android*-lkm/*_kernelsu.ko ./userspace/ksud_overlayfs/bin/aarch64/
- name: Import susfsd lib
run: |
cp susfsd-aarch64-linux-android/arm64-v8a/susfsd ./userspace/ksud_overlayfs/bin/aarch64/
- name: Setup rustup
run: |
rustup update stable
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
- uses: Swatinem/rust-cache@v2
with:
workspaces: userspace/ksud_overlayfs
cache-targets: false
- name: Install cross
run: |
cargo install cross --git https://github.com/cross-rs/cross --rev 66845c1 --force
- name: Build ksud_overlayfs
run: CROSS_NO_WARNINGS=0 cross build --target ${{ inputs.target }} --release --manifest-path ./userspace/ksud_overlayfs/Cargo.toml
- name: Upload ksud_overlayfs artifact
uses: actions/upload-artifact@v4
with:
name: ksud_overlayfs-${{ inputs.target }}
path: userspace/ksud_overlayfs/target/**/release/ksud*

View File

@@ -1,34 +0,0 @@
name: Build susfsd
on:
push:
branches: [ "next" ]
paths:
- '.github/workflows/susfsd.yml'
- 'userspace/susfsd/**'
workflow_dispatch:
workflow_call:
inputs:
target:
required: true
type: string
os:
required: false
type: string
default: ubuntu-latest
jobs:
build-susfs:
name: Build userspace susfsd
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build susfsd
working-directory: ./userspace/susfsd
run: $ANDROID_NDK/ndk-build
- name: Upload a Build Artifact
uses: actions/upload-artifact@v4
with:
name: susfsd-aarch64-linux-android
path: ./userspace/susfsd/libs

View File

@@ -3,19 +3,15 @@ package shirkneko.zako.sukisu.ui.screen
import android.app.Activity import android.app.Activity
import android.app.AlertDialog import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.app.AlertDialog
import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.widget.Toast import android.widget.Toast
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.LocalIndication import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.selection.toggleable
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@@ -24,19 +20,15 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.FileUpload import androidx.compose.material.icons.filled.FileUpload
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.documentfile.provider.DocumentFile
import com.maxkeppeker.sheets.core.models.base.Header import com.maxkeppeker.sheets.core.models.base.Header
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.list.ListDialog import com.maxkeppeler.sheets.list.ListDialog
@@ -57,12 +49,6 @@ import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.IOException import java.io.IOException
import shirkneko.zako.sukisu.ui.util.*
import shirkneko.zako.sukisu.utils.AssetsUtil
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
/** /**
* @author weishu * @author weishu
@@ -82,33 +68,6 @@ fun InstallScreen(navigator: DestinationsNavigator) {
showRebootDialog = true showRebootDialog = true
} }
if (showRebootDialog) {
RebootDialog(
show = true,
onDismiss = { showRebootDialog = false },
onConfirm = {
showRebootDialog = false
try {
val process = Runtime.getRuntime().exec("su")
process.outputStream.bufferedWriter().use { writer ->
writer.write("svc power reboot\n")
writer.write("exit\n")
}
} catch (e: Exception) {
Toast.makeText(context, R.string.failed_reboot, Toast.LENGTH_SHORT).show()
}
}
)
var installMethod by remember { mutableStateOf<InstallMethod?>(null) }
var lkmSelection by remember { mutableStateOf<LkmSelection>(LkmSelection.KmiNone) }
val context = LocalContext.current
var showRebootDialog by remember { mutableStateOf(false) }
val onFlashComplete = {
showRebootDialog = true
}
if (showRebootDialog) { if (showRebootDialog) {
RebootDialog( RebootDialog(
show = true, show = true,
@@ -149,32 +108,9 @@ fun InstallScreen(navigator: DestinationsNavigator) {
} }
} }
} }
Unit
when (method) {
is InstallMethod.HorizonKernel -> {
method.uri?.let { uri ->
val worker = HorizonKernelWorker(context)
worker.uri = uri
worker.setOnFlashCompleteListener(onFlashComplete)
worker.start()
}
}
else -> {
val flashIt = FlashIt.FlashBoot(
boot = if (method is InstallMethod.SelectFile) method.uri else null,
lkm = lkmSelection,
ota = method is InstallMethod.DirectInstallToInactiveSlot
)
navigator.navigate(FlashScreenDestination(flashIt))
}
}
}
Unit Unit
} }
val currentKmi by produceState(initialValue = "") {
value = getCurrentKmi()
}
val currentKmi by produceState(initialValue = "") { val currentKmi by produceState(initialValue = "") {
value = getCurrentKmi() value = getCurrentKmi()
} }
@@ -193,18 +129,8 @@ fun InstallScreen(navigator: DestinationsNavigator) {
onInstall() onInstall()
} }
Unit Unit
Unit
} }
val selectLkmLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode == Activity.RESULT_OK) {
it.data?.data?.let { uri ->
lkmSelection = LkmSelection.LkmUri(uri)
}
}
}
val selectLkmLauncher = rememberLauncherForActivityResult( val selectLkmLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult() contract = ActivityResultContracts.StartActivityForResult()
) { ) {
@@ -226,7 +152,6 @@ fun InstallScreen(navigator: DestinationsNavigator) {
Scaffold( Scaffold(
topBar = { topBar = {
TopBar( TopBar(
onBack = { navigator.popBackStack() },
onBack = { navigator.popBackStack() }, onBack = { navigator.popBackStack() },
onLkmUpload = onLkmUpload, onLkmUpload = onLkmUpload,
scrollBehavior = scrollBehavior scrollBehavior = scrollBehavior
@@ -235,9 +160,6 @@ fun InstallScreen(navigator: DestinationsNavigator) {
contentWindowInsets = WindowInsets.safeDrawing.only( contentWindowInsets = WindowInsets.safeDrawing.only(
WindowInsetsSides.Top + WindowInsetsSides.Horizontal WindowInsetsSides.Top + WindowInsetsSides.Horizontal
) )
contentWindowInsets = WindowInsets.safeDrawing.only(
WindowInsetsSides.Top + WindowInsetsSides.Horizontal
)
) { innerPadding -> ) { innerPadding ->
Column( Column(
modifier = Modifier modifier = Modifier
@@ -262,14 +184,10 @@ fun InstallScreen(navigator: DestinationsNavigator) {
) )
) )
} }
Button(
modifier = Modifier.fillMaxWidth(),
Button( Button(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
enabled = installMethod != null, enabled = installMethod != null,
onClick = onClickNext onClick = onClickNext
) {
onClick = onClickNext
) { ) {
Text( Text(
stringResource(id = R.string.install_next), stringResource(id = R.string.install_next),
@@ -464,12 +382,6 @@ sealed class InstallMethod {
override val summary: String? = null override val summary: String? = null
) : InstallMethod() ) : InstallMethod()
data class HorizonKernel(
val uri: Uri? = null,
@StringRes override val label: Int = R.string.horizon_kernel,
override val summary: String? = null
) : InstallMethod()
abstract val label: Int abstract val label: Int
open val summary: String? = null open val summary: String? = null
} }
@@ -481,15 +393,8 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {
val selectFileTip = stringResource( val selectFileTip = stringResource(
id = R.string.select_file_tip, id = R.string.select_file_tip,
if (isInitBoot()) "init_boot" else "boot" if (isInitBoot()) "init_boot" else "boot"
id = R.string.select_file_tip,
if (isInitBoot()) "init_boot" else "boot"
) )
val radioOptions = mutableListOf<InstallMethod>(
InstallMethod.SelectFile(summary = selectFileTip)
)
val radioOptions = mutableListOf<InstallMethod>( val radioOptions = mutableListOf<InstallMethod>(
InstallMethod.SelectFile(summary = selectFileTip) InstallMethod.SelectFile(summary = selectFileTip)
) )
@@ -500,14 +405,11 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {
radioOptions.add(InstallMethod.DirectInstallToInactiveSlot) radioOptions.add(InstallMethod.DirectInstallToInactiveSlot)
} }
radioOptions.add(InstallMethod.HorizonKernel(summary = "Flashing the Anykernel3 Kernel")) radioOptions.add(InstallMethod.HorizonKernel(summary = "Flashing the Anykernel3 Kernel"))
radioOptions.add(InstallMethod.HorizonKernel(summary = "Flashing the Anykernel3 Kernel"))
} }
var selectedOption by remember { mutableStateOf<InstallMethod?>(null) } var selectedOption by remember { mutableStateOf<InstallMethod?>(null) }
var currentSelectingMethod by remember { mutableStateOf<InstallMethod?>(null) } var currentSelectingMethod by remember { mutableStateOf<InstallMethod?>(null) }
var currentSelectingMethod by remember { mutableStateOf<InstallMethod?>(null) }
val selectImageLauncher = rememberLauncherForActivityResult( val selectImageLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult() contract = ActivityResultContracts.StartActivityForResult()
) { ) {
@@ -524,26 +426,7 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {
} }
} }
} }
val option = when (currentSelectingMethod) {
is InstallMethod.SelectFile -> InstallMethod.SelectFile(uri, summary = selectFileTip)
is InstallMethod.HorizonKernel -> InstallMethod.HorizonKernel(uri, summary = " Flashing the Anykernel3 Kernel")
else -> null
} }
option?.let {
selectedOption = it
onSelected(it)
}
}
}
}
val confirmDialog = rememberConfirmDialog(
onConfirm = {
selectedOption = InstallMethod.DirectInstallToInactiveSlot
onSelected(InstallMethod.DirectInstallToInactiveSlot)
},
onDismiss = null
)
val confirmDialog = rememberConfirmDialog( val confirmDialog = rememberConfirmDialog(
onConfirm = { onConfirm = {
@@ -557,10 +440,8 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {
val dialogContent = stringResource(id = R.string.install_inactive_slot_warning) val dialogContent = stringResource(id = R.string.install_inactive_slot_warning)
val onClick = { option: InstallMethod -> val onClick = { option: InstallMethod ->
currentSelectingMethod = option
currentSelectingMethod = option currentSelectingMethod = option
when (option) { when (option) {
is InstallMethod.SelectFile, is InstallMethod.HorizonKernel -> {
is InstallMethod.SelectFile, is InstallMethod.HorizonKernel -> { is InstallMethod.SelectFile, is InstallMethod.HorizonKernel -> {
selectImageLauncher.launch(Intent(Intent.ACTION_GET_CONTENT).apply { selectImageLauncher.launch(Intent(Intent.ACTION_GET_CONTENT).apply {
type = "application/*" type = "application/*"
@@ -587,7 +468,6 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {
.toggleable( .toggleable(
value = option.javaClass == selectedOption?.javaClass, value = option.javaClass == selectedOption?.javaClass,
onValueChange = { onClick(option) }, onValueChange = { onClick(option) },
onValueChange = { onClick(option) },
role = Role.RadioButton, role = Role.RadioButton,
indication = LocalIndication.current, indication = LocalIndication.current,
interactionSource = interactionSource interactionSource = interactionSource
@@ -596,7 +476,6 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {
RadioButton( RadioButton(
selected = option.javaClass == selectedOption?.javaClass, selected = option.javaClass == selectedOption?.javaClass,
onClick = { onClick(option) }, onClick = { onClick(option) },
onClick = { onClick(option) },
interactionSource = interactionSource interactionSource = interactionSource
) )
Column( Column(
@@ -630,10 +509,8 @@ fun rememberSelectKmiDialog(onSelected: (String?) -> Unit): DialogHandle {
value = getSupportedKmis() value = getSupportedKmis()
} }
val options = supportedKmi.map { value -> val options = supportedKmi.map { value ->
ListOption(titleText = value) ListOption(titleText = value)
ListOption(titleText = value)
} }
var selection by remember { mutableStateOf<String?>(null) } var selection by remember { mutableStateOf<String?>(null) }
@@ -658,27 +535,6 @@ fun rememberSelectKmiDialog(onSelected: (String?) -> Unit): DialogHandle {
selection = option.titleText selection = option.titleText
} }
) )
ListDialog(
state = rememberUseCaseState(
visible = true,
onFinishedRequest = {
onSelected(selection)
},
onCloseRequest = {
dismiss()
}
),
header = Header.Default(
title = stringResource(R.string.select_kmi),
),
selection = ListSelection.Single(
showRadioButtons = true,
options = options,
) { _, option ->
selection = option.titleText
}
)
} }
} }
@@ -690,13 +546,6 @@ private fun TopBar(
scrollBehavior: TopAppBarScrollBehavior? = null scrollBehavior: TopAppBarScrollBehavior? = null
) { ) {
TopAppBar( TopAppBar(
title = { Text(stringResource(R.string.install)) },
navigationIcon = {
IconButton(onClick = onBack) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null)
}
},
actions = {
title = { Text(stringResource(R.string.install)) }, title = { Text(stringResource(R.string.install)) },
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
@@ -711,14 +560,10 @@ private fun TopBar(
windowInsets = WindowInsets.safeDrawing.only( windowInsets = WindowInsets.safeDrawing.only(
WindowInsetsSides.Top + WindowInsetsSides.Horizontal WindowInsetsSides.Top + WindowInsetsSides.Horizontal
), ),
windowInsets = WindowInsets.safeDrawing.only(
WindowInsetsSides.Top + WindowInsetsSides.Horizontal
),
scrollBehavior = scrollBehavior scrollBehavior = scrollBehavior
) )
} }
@Preview
@Preview @Preview
@Composable @Composable
fun SelectInstallPreview() { fun SelectInstallPreview() {

File diff suppressed because one or more lines are too long

View File

@@ -66,8 +66,6 @@
<string name="failed_to_update_app_profile">Gagal membarui Profil pada %s</string> <string name="failed_to_update_app_profile">Gagal membarui Profil pada %s</string>
<string name="settings_umount_modules_default">Melepas Modul secara bawaan</string> <string name="settings_umount_modules_default">Melepas Modul secara bawaan</string>
<string name="settings_umount_modules_default_summary">Menggunakan \"Umount Modul\" secara universal pada Profil Aplikasi. Jika diaktifkan, akan menghapus semua modifikasi sistem untuk aplikasi yang tidak memiliki set profil.</string> <string name="settings_umount_modules_default_summary">Menggunakan \"Umount Modul\" secara universal pada Profil Aplikasi. Jika diaktifkan, akan menghapus semua modifikasi sistem untuk aplikasi yang tidak memiliki set profil.</string>
<string name="settings_susfs_toggle">Sembunyikan hook kprobe</string>
<string name="settings_susfs_toggle_summary">Ini menonaktifkan hook kprobe yang dibuat oleh ksu, dan sebagai gantinya, hook inline non-kprobe akan diaktifkan, sama seperti implementasi untuk kernel non-gki yang tidak mendukung kprobe.</string>
<string name="profile_umount_modules_summary">Aktifkan opsi ini agar KernelSU dapat memulihkan kembali berkas termodifikasi oleh modul pada aplikasi ini.</string> <string name="profile_umount_modules_summary">Aktifkan opsi ini agar KernelSU dapat memulihkan kembali berkas termodifikasi oleh modul pada aplikasi ini.</string>
<string name="profile_selinux_domain">Domain</string> <string name="profile_selinux_domain">Domain</string>
<string name="profile_selinux_rules">Aturan</string> <string name="profile_selinux_rules">Aturan</string>

View File

@@ -1,2 +1 @@
**/*.ko **/*.ko
susfsd

View File

@@ -8,7 +8,6 @@ use crate::{defs::BINARY_DIR, utils};
pub const RESETPROP_PATH: &str = concatcp!(BINARY_DIR, "resetprop"); pub const RESETPROP_PATH: &str = concatcp!(BINARY_DIR, "resetprop");
pub const BUSYBOX_PATH: &str = concatcp!(BINARY_DIR, "busybox"); pub const BUSYBOX_PATH: &str = concatcp!(BINARY_DIR, "busybox");
pub const BOOTCTL_PATH: &str = concatcp!(BINARY_DIR, "bootctl"); pub const BOOTCTL_PATH: &str = concatcp!(BINARY_DIR, "bootctl");
pub const SUSFSD_PATH: &str = concatcp!(BINARY_DIR, "susfsd");
#[cfg(all(target_arch = "x86_64", target_os = "android"))] #[cfg(all(target_arch = "x86_64", target_os = "android"))]
#[derive(RustEmbed)] #[derive(RustEmbed)]

View File

@@ -1,2 +0,0 @@
**/*.ko
susfsd

View File

@@ -1,52 +0,0 @@
use anyhow::Result;
use const_format::concatcp;
use rust_embed::RustEmbed;
use std::path::Path;
use crate::{defs::BINARY_DIR, utils};
pub const RESETPROP_PATH: &str = concatcp!(BINARY_DIR, "resetprop");
pub const BUSYBOX_PATH: &str = concatcp!(BINARY_DIR, "busybox");
pub const BOOTCTL_PATH: &str = concatcp!(BINARY_DIR, "bootctl");
pub const SUSFSD_PATH: &str = concatcp!(BINARY_DIR, "susfsd");
#[cfg(all(target_arch = "x86_64", target_os = "android"))]
#[derive(RustEmbed)]
#[folder = "bin/x86_64"]
struct Asset;
// IF NOT x86_64 ANDROID, ie. macos, linux, windows, always use aarch64
#[cfg(not(all(target_arch = "x86_64", target_os = "android")))]
#[derive(RustEmbed)]
#[folder = "bin/aarch64"]
struct Asset;
pub fn ensure_binaries(ignore_if_exist: bool) -> Result<()> {
for file in Asset::iter() {
if file == "ksuinit" || file.ends_with(".ko") {
// don't extract ksuinit and kernel modules
continue;
}
let asset = Asset::get(&file).ok_or(anyhow::anyhow!("asset not found: {}", file))?;
utils::ensure_binary(format!("{BINARY_DIR}{file}"), &asset.data, ignore_if_exist)?
}
Ok(())
}
pub fn copy_assets_to_file(name: &str, dst: impl AsRef<Path>) -> Result<()> {
let asset = Asset::get(name).ok_or(anyhow::anyhow!("asset not found: {}", name))?;
std::fs::write(dst, asset.data)?;
Ok(())
}
pub fn list_supported_kmi() -> Result<Vec<String>> {
let mut list = Vec::new();
for file in Asset::iter() {
// kmi_name = "xxx_kernelsu.ko"
if let Some(kmi) = file.strip_suffix("_kernelsu.ko") {
list.push(kmi.to_string());
}
}
Ok(list)
}

View File

@@ -1,2 +0,0 @@
/obj
/libs

View File

@@ -1,6 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := susfsd
LOCAL_SRC_FILES := susfsd.c
include $(BUILD_EXECUTABLE)

View File

@@ -1,3 +0,0 @@
APP_ABI := arm64-v8a
APP_PLATFORM := android-24
APP_STL := none

View File

@@ -1,239 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#define KERNEL_SU_OPTION 0xDEADBEEF
#define CMD_SUSFS_SHOW_VERSION 0x555e1
#define CMD_SUSFS_SHOW_ENABLED_FEATURES 0x555e2
#define CMD_SUSFS_SHOW_VARIANT 0x555e3
#define CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE 0x555e4
#define CMD_SUSFS_IS_SUS_SU_READY 0x555f0
#define CMD_SUSFS_SUS_SU 0x60000
#define SUS_SU_DISABLED 0
#define SUS_SU_WITH_HOOKS 2
struct st_sus_su {
int mode;
};
int enable_sus_su(int last_working_mode, int target_working_mode) {
struct st_sus_su info;
int error = -1;
if (target_working_mode == SUS_SU_WITH_HOOKS) {
info.mode = SUS_SU_WITH_HOOKS;
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SUS_SU, &info, NULL, &error);
if (error) {
if (error == 1) {
} else if (error == 2) {
}
return error;
}
printf("[+] sus_su mode 2 is enabled\n");
} else if (target_working_mode == SUS_SU_DISABLED) {
info.mode = SUS_SU_DISABLED;
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SUS_SU, &info, NULL, &error);
if (error) {
if (error == 1) {
}
return error;
}
printf("[+] sus_su mode 0 is enabled\n");
} else {
return 1;
}
return 0;
}
int main(int argc, char *argv[]) {
int error = -1;
char support[16];
char version[16];
char variant[16];
// Check for arguments
if (argc < 2) {
fprintf(stderr, "Usage: %s <support|version|variant|features|sus_su <0|2|mode>|>\n", argv[0]);
return 1;
}
if (strcmp(argv[1], "version") == 0) {
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_VERSION, version, NULL, &error);
if (!error) {
printf("%s\n", version);
} else {
printf("Invalid\n");
}
} else if (strcmp(argv[1], "variant") == 0) {
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_VARIANT, variant, NULL, &error);
if (!error) {
printf("%s\n", variant);
} else {
printf("Invalid\n");
}
} else if (strcmp(argv[1], "features") == 0) {
char *enabled_features_buf = malloc(getpagesize() * 2);
char *ptr_buf;
unsigned long enabled_features;
int str_len;
if (!enabled_features_buf) {
perror("malloc");
return -ENOMEM;
}
ptr_buf = enabled_features_buf;
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_ENABLED_FEATURES, &enabled_features, NULL, &error);
if (!error) {
if (enabled_features & (1 << 0)) {
str_len = strlen("CONFIG_KSU_SUSFS_SUS_PATH\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_SUS_PATH\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 1)) {
str_len = strlen("CONFIG_KSU_SUSFS_SUS_MOUNT\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_SUS_MOUNT\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 2)) {
str_len = strlen("CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 3)) {
str_len = strlen("CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 4)) {
str_len = strlen("CONFIG_KSU_SUSFS_SUS_KSTAT\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_SUS_KSTAT\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 5)) {
str_len = strlen("CONFIG_KSU_SUSFS_SUS_OVERLAYFS\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_SUS_OVERLAYFS\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 6)) {
str_len = strlen("CONFIG_KSU_SUSFS_TRY_UMOUNT\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_TRY_UMOUNT\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 7)) {
str_len = strlen("CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 8)) {
str_len = strlen("CONFIG_KSU_SUSFS_SPOOF_UNAME\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_SPOOF_UNAME\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 9)) {
str_len = strlen("CONFIG_KSU_SUSFS_ENABLE_LOG\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_ENABLE_LOG\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 10)) {
str_len = strlen("CONFIG_KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 11)) {
str_len = strlen("CONFIG_KSU_SUSFS_SPOOF_BOOTCONFIG\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_SPOOF_BOOTCONFIG\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 12)) {
str_len = strlen("CONFIG_KSU_SUSFS_OPEN_REDIRECT\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_OPEN_REDIRECT\n", str_len);
ptr_buf += str_len;
}
if (enabled_features & (1 << 13)) {
str_len = strlen("CONFIG_KSU_SUSFS_SUS_SU\n");
strncpy(ptr_buf, "CONFIG_KSU_SUSFS_SUS_SU\n", str_len);
ptr_buf += str_len;
}
printf("%s", enabled_features_buf);
free(enabled_features_buf);
} else {
printf("Invalid\n");
}
} else if (strcmp(argv[1], "support") == 0) {
unsigned long enabled_features;
int any_feature_enabled = 0;
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_ENABLED_FEATURES, &enabled_features, NULL, &error);
if (!error) {
if (enabled_features & ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) |
(1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) |
(1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) |
(1 << 12) | (1 << 13))) {
any_feature_enabled = 1;
}
if (any_feature_enabled) {
printf("Supported\n");
} else {
printf("Unsupported\n");
}
} else {
printf("Unsupported\n");
}
} else if (argc == 3 && !strcmp(argv[1], "sus_su")) {
int last_working_mode = 0;
int target_working_mode;
char* endptr;
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE, &last_working_mode, NULL, &error);
if (error)
return error;
if (!strcmp(argv[2], "mode")) {
printf("%d\n", last_working_mode);
return 0;
}
target_working_mode = strtol(argv[2], &endptr, 10);
if (*endptr != '\0') {
return 1;
}
if (target_working_mode == SUS_SU_WITH_HOOKS) {
bool is_sus_su_ready;
prctl(KERNEL_SU_OPTION, CMD_SUSFS_IS_SUS_SU_READY, &is_sus_su_ready, NULL, &error);
if (error)
return error;
if (!is_sus_su_ready) {
printf("[-] sus_su mode %d has to be run during or after service stage\n", SUS_SU_WITH_HOOKS);
return 1;
}
if (last_working_mode == SUS_SU_DISABLED) {
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
} else if (last_working_mode == SUS_SU_WITH_HOOKS) {
printf("[-] sus_su is already in mode %d\n", last_working_mode);
return 1;
} else {
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
if (!error)
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
}
} else if (target_working_mode == SUS_SU_DISABLED) {
if (last_working_mode == SUS_SU_DISABLED) {
printf("[-] sus_su is already in mode %d\n", last_working_mode);
return 1;
}
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
}
} else {
fprintf(stderr, "Invalid argument: %s\n", argv[1]);
return 1;
}
return 0;
}