Merge pull request #6 from ShirkNeko/dev

Dev
This commit is contained in:
ShirkNeko
2025-03-31 14:53:34 +08:00
committed by GitHub
13 changed files with 101 additions and 1461 deletions

View File

@@ -15,19 +15,30 @@ Android device root solution based on [KernelSU](https://github.com/KernelSU/Ker
## How to add
Using the susfs-dev branch (integrated susfs with support for non-GKI devices)
Using the susfs-stable or susfs-dev branch (integrated susfs with support for non-GKI devices)
```
curl -LSs "https://raw.githubusercontent.com/ShirkNeko/KernelSU/main/kernel/setup.sh" | bash -s susfs-stable
```
```
curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-dev
```
Use main branching (no longer with support for non-GKI devices)
Use main branching
```
curl -LSs "https://raw.githubusercontent.com/ShirkNeko/KernelSU/main/kernel/setup.sh" | bash -s main
```
Use dev branchingWith support for non-GKI devices
```
curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
## How to use integrated susfs
Use the susfs-dev branch directly without any patching
1. Use the susfs-dev branch directly without any patching
2. Manually patch susfs using a dev branch that supports non-GKI devices.
## More links
@@ -83,6 +94,7 @@ Note: You only need to fill in the first two kernel versions, such as 5.10, 5.15
- [Ktouls](https://github.com/Ktouls) Thanks so much for bringing me support
- [zaoqi123](https://github.com/zaoqi123) It's not a bad idea to buy me a milk tea
- [wswzgdg](https://github.com/wswzgdg) Many thanks for supporting this project
- [yspbwx2010](https://github.com/yspbwx2010) Many thanks

View File

@@ -15,20 +15,30 @@
## 如何添加
在内核源码的根目录下执行以下命令:
使用 susfs-dev 分支已集成susfs带非GKI设备的支持
使用 susfs-stable 或者 susfs-dev 分支已集成susfs带非GKI设备的支持
```
curl -LSs "https://raw.githubusercontent.com/ShirkNeko/KernelSU/main/kernel/setup.sh" | bash -s susfs-stable
```
```
curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-dev
```
使用 main 分支不再带非GKI设备的支持
使用 main 分支
```
curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
使用 dev 分支带非GKI设备的支持
```
curl -LSs "https://raw.githubusercontent.com/ShirkNeko/KernelSU/main/kernel/setup.sh" | bash -s main
```
## 如何集成 susfs
1. 直接使用 susfs-dev 分支,不需要再集成 susfs
1. 直接使用 susfs-stable 或者 susfs-dev 分支,不需要再集成 susfs
2. 使用支持非GKI设备的 dev 分支,手动补丁 susfs
## 钩子方法
- 此部分引用自 [rsuntk 的钩子方法](https://github.com/rsuntk/KernelSU)
@@ -72,7 +82,7 @@ curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/
1. 基于内核的 `su` 和 root 访问管理
2. 基于 5ec1cff 的 [Magic Mount](https://github.com/5ec1cff/KernelSU) 的模块系统
3. [App Profile](https://kernelsu.org/guide/app-profile.html):将 root 权限锁在笼子里
4. 恢复对非 GKI 2.0 内核的支持仅限susfs-dev和未进行susfs补丁的dev分支
4. 恢复对非 GKI 2.0 内核的支持
5. 更多自定义功能
@@ -85,6 +95,7 @@ curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/
- [Ktouls](https://github.com/Ktouls) 非常感谢你给我带来的支持
- [zaoqi123](https://github.com/zaoqi123) 请我喝奶茶也不错
- [wswzgdg](https://github.com/wswzgdg) 非常感谢对此项目的支持
- [yspbwx2010](https://github.com/yspbwx2010) 非常感谢

View File

@@ -686,12 +686,6 @@ __maybe_unused int ksu_kprobe_init(void)
rc = register_kprobe(&renameat_kp);
pr_info("renameat kp: %d\n", rc);
#ifdef CONFIG_KPM
// KPM初始化状态
kpm_cfi_bypass_init();
// kpm_stack_init();
#endif
return rc;
}
@@ -699,11 +693,6 @@ __maybe_unused int ksu_kprobe_exit(void)
{
unregister_kprobe(&prctl_kp);
unregister_kprobe(&renameat_kp);
#ifdef CONFIG_KPM
// KPM取消状态
kpm_cfi_bypass_exit();
// kpm_stack_exit();
#endif
return 0;
}

View File

@@ -1,3 +1,2 @@
obj-y += kpm.o
obj-y += compact.o
obj-y += bypasscfi.o

View File

@@ -1,73 +0,0 @@
#include <linux/kprobes.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kallsyms.h>
/* CFI 检查函数符号 */
#define CFI_CHECK_FUNC "__cfi_check"
/* Kprobe 实例 */
static struct kprobe cfi_kp;
bool kpm_is_allow_address(unsigned long addr);
/*--------------------- kprobe 处理逻辑 ---------------------*/
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
unsigned long target_addr;
/* 从寄存器获取目标地址(架构相关) */
#if defined(__aarch64__)
target_addr = regs->regs[1]; // ARM64: 第二个参数在 X1
#elif defined(__x86_64__)
target_addr = regs->si; // x86_64: 第二个参数在 RSI
#else
#error "Unsupported architecture"
#endif
/* 根据自定义规则放行 */
if (kpm_is_allow_address(target_addr)) {
printk(KERN_INFO "CFI bypass at 0x%lx\n", target_addr);
#if defined(__aarch64__)
regs->regs[0] = 0; // 修改返回值0 表示校验通过
#elif defined(__x86_64__)
regs->ax = 0; // x86 返回值在 RAX
#endif
return 0; // 跳过原始 CFI 检查
}
return 0; // 继续执行原始检查
}
/*--------------------- 模块初始化/卸载 ---------------------*/
int kpm_cfi_bypass_init(void)
{
unsigned long cfi_check_addr;
/* 动态查找 CFI 检查函数 */
cfi_check_addr = kallsyms_lookup_name(CFI_CHECK_FUNC);
if (!cfi_check_addr) {
printk(KERN_ERR "CFI check function not found\n");
return -ENOENT;
}
/* 初始化 kprobe */
memset(&cfi_kp, 0, sizeof(cfi_kp));
cfi_kp.addr = (kprobe_opcode_t *)cfi_check_addr;
cfi_kp.pre_handler = handler_pre;
/* 注册 kprobe */
if (register_kprobe(&cfi_kp) < 0) {
printk(KERN_ERR "Register kprobe failed\n");
return -EINVAL;
}
printk(KERN_INFO "CFI bypass module loaded\n");
return 0;
}
void kpm_cfi_bypass_exit(void)
{
unregister_kprobe(&cfi_kp);
printk(KERN_INFO "CFI bypass module unloaded\n");
}

View File

@@ -31,66 +31,20 @@ unsigned long sukisu_compact_find_symbol(const char* name);
// ======================================================================
const char* kpver = "0.10";
struct CompactAddressSymbol {
const char* symbol_name;
void* addr;
};
struct CompactAliasSymbol {
const char* symbol_name;
const char* compact_symbol_name;
};
struct CompactProxySymbol {
const char* symbol_name;
const char* compact_symbol_name;
void* cached_address;
};
static struct CompactAddressSymbol address_symbol [] = {
{ "kallsyms_lookup_name", &kallsyms_lookup_name },
{ "compact_find_symbol", &sukisu_compact_find_symbol },
{ "compat_copy_to_user", &copy_to_user },
{ "compat_strncpy_from_user", &strncpy_from_user },
{ "kpver", &kpver },
{ "is_run_in_sukisu_ultra", (void*)1 }
};
static struct CompactAliasSymbol alias_symbol[] = {
{"compat_copy_to_user", "__arch_copy_to_user"}
};
static struct CompactProxySymbol proxy_symbol[] = {
{"kf_strncat", "strncat", NULL },
{"kf_strlen", "strlen", NULL },
{"kf_strcpy", "strcpy", NULL },
};
static unsigned long sukisu_find_proxy_symbol(const char* name) {
// 查找proxy符号
int i;
for(i = 0; i < (sizeof(proxy_symbol) / sizeof(struct CompactProxySymbol)); i++) {
struct CompactProxySymbol* symbol = &proxy_symbol[i];
if(strcmp(name, symbol->symbol_name) == 0) {
if(symbol->cached_address == NULL) {
symbol->cached_address = (void*) kallsyms_lookup_name(symbol->compact_symbol_name);
}
if(symbol->cached_address != NULL) {
return (unsigned long) &symbol->cached_address;
} else {
return 0;
}
}
}
return 0;
}
unsigned long sukisu_compact_find_symbol(const char* name) {
int i;
unsigned long addr;
char isFoundedProxy = 0;
// 先自己在地址表部分查出来
for(i = 0; i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); i++) {
@@ -100,34 +54,13 @@ unsigned long sukisu_compact_find_symbol(const char* name) {
}
}
/* 如果符号名以 "kf_" 开头,尝试解析去掉前缀的部分 */
if (strncmp(name, "kf_", 3) == 0) {
addr = sukisu_find_proxy_symbol(name);
isFoundedProxy = 1;
if(addr != 0) {
return addr;
}
}
// 通过内核来查
addr = kallsyms_lookup_name(name);
if(addr) {
return addr;
}
// 查不到就查查兼容的符号
for(i = 0; i < (sizeof(alias_symbol) / sizeof(struct CompactAliasSymbol)); i++) {
struct CompactAliasSymbol* symbol = &alias_symbol[i];
if(strcmp(name, symbol->symbol_name) == 0) {
addr = kallsyms_lookup_name(symbol->compact_symbol_name);
if(addr)
return addr;
}
}
if(!isFoundedProxy) {
return sukisu_find_proxy_symbol(name);
}
return 0;
}
EXPORT_SYMBOL(sukisu_compact_find_symbol);

File diff suppressed because it is too large Load Diff

View File

@@ -4,14 +4,9 @@
int sukisu_handle_kpm(unsigned long arg3, unsigned long arg4, unsigned long arg5);
int sukisu_is_kpm_control_code(unsigned long arg2);
int kpm_cfi_bypass_init(void);
void kpm_cfi_bypass_exit(void);
int kpm_stack_init(void);
void kpm_stack_exit(void);
// KPM控制代码
#define CMD_KPM_CONTROL 28
#define CMD_KPM_CONTROL_MAX 34
#define CMD_KPM_CONTROL_MAX 35
// 控制代码
@@ -46,6 +41,8 @@ void kpm_stack_exit(void);
// error will return -1
#define SUKISU_KPM_PRINT 34
#define SUKISU_KPM_VERSION 35
/* A64 instructions are always 32 bits. */
#define AARCH64_INSN_SIZE 4

View File

@@ -335,16 +335,18 @@ private fun StatusCard(
Spacer(modifier = Modifier.height(4.dp))
val suSFS = getSuSFS()
val translatedStatus = when (suSFS) {
"Supported" -> stringResource(R.string.status_supported)
"Not Supported" -> stringResource(R.string.status_not_supported)
else -> stringResource(R.string.status_unknown)
}
if (lkmMode != true) {
val translatedStatus = when (suSFS) {
"Supported" -> stringResource(R.string.status_supported)
"Not Supported" -> stringResource(R.string.status_not_supported)
else -> stringResource(R.string.status_unknown)
}
Text(
text = stringResource(R.string.home_susfs, translatedStatus),
style = MaterialTheme.typography.bodyMedium
)
Text(
text = stringResource(R.string.home_susfs, translatedStatus),
style = MaterialTheme.typography.bodyMedium
)
}
}
}

View File

@@ -346,7 +346,11 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
floatingActionButton = {
if (!hideInstallButton) {
val moduleInstall = stringResource(id = R.string.module_install)
val cardColor = MaterialTheme.colorScheme.secondaryContainer
val cardColor = if (!ThemeConfig.useDynamicColor) {
ThemeConfig.currentTheme.ButtonContrast
} else {
MaterialTheme.colorScheme.secondaryContainer
}
ExtendedFloatingActionButton(
onClick = {
selectZipLauncher.launch(

View File

@@ -140,7 +140,6 @@ fun SettingScreen(navigator: DestinationsNavigator) {
loadingDialog.hide()
snackBarHost.showSnackbar(context.getString(R.string.log_saved))
}
// endregion
}
// region 配置项列表
// 配置文件模板入口
@@ -218,12 +217,12 @@ fun SettingScreen(navigator: DestinationsNavigator) {
prefs.edit { putBoolean("enable_web_debugging", it) }
enableWebDebugging = it
}
// endregion
// 更多设置
val newButtonTitle = stringResource(id = R.string.more_settings)
ListItem(
leadingContent = {
Icon(
Icons.Filled.ExpandMore,
Icons.Filled.Settings,
contentDescription = newButtonTitle
)
},

View File

@@ -60,6 +60,7 @@ import com.ramcosta.composedestinations.result.getOr
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import shirkneko.zako.sukisu.R
import shirkneko.zako.sukisu.ui.theme.ThemeConfig
import shirkneko.zako.sukisu.ui.viewmodel.TemplateViewModel
/**
@@ -77,7 +78,11 @@ fun AppProfileTemplateScreen(
val viewModel = viewModel<TemplateViewModel>()
val scope = rememberCoroutineScope()
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val cardColor = MaterialTheme.colorScheme.secondaryContainer
val cardColor = if (!ThemeConfig.useDynamicColor) {
ThemeConfig.currentTheme.ButtonContrast
} else {
MaterialTheme.colorScheme.secondaryContainer
}
LaunchedEffect(Unit) {
if (viewModel.templateList.isEmpty()) {

View File

@@ -43,23 +43,23 @@ object ThemeConfig {
@Composable
private fun getDarkColorScheme() = darkColorScheme(
primary = ThemeConfig.currentTheme.Primary.copy(alpha = 0.8f),
onPrimary = Color.White,
onPrimary = mixColors(ThemeConfig.currentTheme.Primary, Color.White, 0.2f),
primaryContainer = ThemeConfig.currentTheme.PrimaryContainer.copy(alpha = 0.15f),
onPrimaryContainer = Color.White,
onPrimaryContainer = mixColors(ThemeConfig.currentTheme.Primary, Color.White, 0.2f),
secondary = ThemeConfig.currentTheme.Secondary.copy(alpha = 0.8f),
onSecondary = Color.White,
onSecondary = mixColors(ThemeConfig.currentTheme.Secondary, Color.White, 0.2f),
secondaryContainer = ThemeConfig.currentTheme.SecondaryContainer.copy(alpha = 0.15f),
onSecondaryContainer = Color.White,
onSecondaryContainer = mixColors(ThemeConfig.currentTheme.Secondary, Color.White, 0.2f),
tertiary = ThemeConfig.currentTheme.Tertiary.copy(alpha = 0.8f),
onTertiary = Color.White,
onTertiary = mixColors(ThemeConfig.currentTheme.Tertiary, Color.White, 0.2f),
tertiaryContainer = ThemeConfig.currentTheme.TertiaryContainer.copy(alpha = 0.15f),
onTertiaryContainer = Color.White,
onTertiaryContainer = mixColors(ThemeConfig.currentTheme.Tertiary, Color.White, 0.2f),
background = Color.Transparent,
surface = Color.Transparent,
onBackground = Color.White.copy(alpha = 0.87f),
onSurface = Color.White.copy(alpha = 0.87f),
onBackground = mixColors(ThemeConfig.currentTheme.Primary, Color.White, 0.1f),
onSurface = mixColors(ThemeConfig.currentTheme.Primary, Color.White, 0.1f),
surfaceVariant = Color(0xFF2F2F2F),
onSurfaceVariant = Color.White.copy(alpha = 0.78f),
onSurfaceVariant = mixColors(ThemeConfig.currentTheme.Primary, Color.White, 0.2f),
outline = Color.White.copy(alpha = 0.12f),
outlineVariant = Color.White.copy(alpha = 0.12f)
)
@@ -340,3 +340,11 @@ private fun adjustColor(color: Color): Color {
}
return color.copy(luminance)
}
private fun mixColors(color1: Color, color2: Color, ratio: Float): Color {
val r = (color1.red * ratio + color2.red * (1 - ratio))
val g = (color1.green * ratio + color2.green * (1 - ratio))
val b = (color1.blue * ratio + color2.blue * (1 - ratio))
val a = (color1.alpha * ratio + color2.alpha * (1 - ratio))
return Color(r, g, b, a)
}