Stellar Documentation

repository·main·Indexed 22 days ago

https://github.com/roro2239/stellar

Stellar is a customized fork of Shizuku that provides a privileged API framework for Android developers to access system-level APIs via ADB or Root. It features a granular, multi-dimensional permission system, a built-in Shizuku compatibility layer, and enhanced service lifecycle management. Key capabilities include executing privileged processes via newProcess() and newPtyProcess(), accessing system properties through StellarSystemProperties, and running custom Binder services via StellarUserService.

Tokens
11.8K
Snippets
36
Records
43
Agent score
77%

What's inside Stellar

  1. Overview of Stellar

    main

    Stellar is a deeply customized fork of Shizuku designed to provide developers with a more flexible and powerful privileged API framework. By starting the service via ADB wireless debugging or Root permissions, applications can call system-level APIs without requiring the application itself to have Root access.

    Key Improvements over Shizuku:

    • Enhanced Permission System: Moves from a single permission model to a fine-grained, multi-dimensional management system.
    • Startup & Service Optimization: Supports boot startup (via broadcast, accessibility, or Root), service-companion startup, and dual-process watchdogging.
    • Architecture Refactoring: Rebuilt with 100% Kotlin, optimized service layers, and improved module communication.
    • UI/UX Improvements: Modern Material Design 3 interface for permission management and onboarding.
  2. Use the Shizuku compatibility layer

    main

    Stellar includes a built-in compatibility layer that allows applications written for Shizuku to work with Stellar without any code modifications.

    How it works:

    1. Client Compatibility: ShizukuProvider receives the Binder sent by Stellar and uses ShizukuCompat to manage connection states.
    2. Server Interception: ShizukuServiceIntercept implements the IShizukuService interface and forwards Shizuku API calls to the Stellar service.
    3. Permission Mapping: Automatically maps Shizuku permission requests to the Stellar shizuku permission.

    Supported APIs:

    • pingBinder(), getVersion(), getUid()
    • checkSelfPermission(), requestPermission()
    • newProcess()
    • addUserService(), removeUserService()
    • transactRemote()

    Configuration:

    • The compatibility layer is enabled by default.
    • To disable it, toggle the "Shizuku 兼容层" (Shizuku Compatibility Layer) switch in the Stellar Manager settings.
    • Requirement: Applications using Shizuku APIs must configure ShizukuProvider in their AndroidManifest.xml.
  3. Create and bind a User Service

    main

    Stellar allows you to run your own AIDL-defined services within the Stellar environment.

    1. Define an AIDL interface (e.g., IMyUserService.aidl).
    2. Implement the service by extending the .Stub() class.
    3. Bind the service using StellarUserService.bindUserService() with UserServiceArgs.

    UserServiceArgs can be configured with a processNameSuffix, serviceMode (ONE_TIME or DAEMON), and other metadata via a builder pattern.

    // Binding a ONE_TIME service
    val args = UserServiceArgs.Builder(MyUserService::class.java)
        .processNameSuffix("myservice")
        .serviceMode(ServiceMode.ONE_TIME)
        .build()
    
    StellarUserService.bindUserService(args, object : StellarUserService.ServiceCallback {
        override fun onServiceConnected(service: IBinder) {
            val myService = IMyUserService.Stub.asInterface(service)
            // Use myService
        }
        // ... other callbacks
    })
  4. Enable Privilege Downgrade (降权激活)

    main

    If Stellar is started with Root permissions, you can enable "Privilege Downgrade" (降权激活) in the Stellar Manager settings. This improves security by automatically switching the service to run as a Shell user (uid=2000) after startup.

    Workflow:

    su (root) → libchid.so 2000 → libstellar.so --apk=...

    1. libchid.so is executed with Root permissions.
    2. libchid.so switches the process identity to uid=2000 (Shell user).
    3. libstellar.so is then executed as the Shell user to start the service.

    Important Notes:

    • Downgrade only works in Root startup mode.
    • ADB startup mode is already uid=2000, so no downgrade is needed there.
    • Once downgraded, the service loses Root-specific capabilities (e.g., writing to system properties or accessing protected directories).
  5. How Stellar's permission system works

    main

    Stellar replaces the single-permission model with a granular hierarchy to allow more precise control over what an application can do.

    Permission Levels:

    • stellar: Core API access permission, granting basic service invocation capabilities.
    • follow_stellar_startup: Allows an application to be registered as a companion to the Stellar service, enabling the application to wake up automatically when the service starts.

    Enhanced Features:

    • Smart Callbacks: Clients can precisely detect the authorization type (e.g., permanent vs. one-time authorization).
    • Full Management API: Provides interfaces for querying, requesting, and revoking permissions to support complex business logic.
  6. Quickstart: Integrate Stellar API into your Android app

    main

    Stellar is a privileged API framework (a fork of Shizuku) that allows apps to perform privileged operations via ADB or Root.

    Prerequisites

    • Minimum Android Version: API 26 (Android 8.0)
    • Stellar Manager: Must be installed on the device.
    • Stellar Service: Must be running (started via ADB or Root).
  7. Add Stellar API dependency via JitPack

    main

    To use Stellar, first add the JitPack repository to your settings.gradle file, then add the Stellar API dependency to your build.gradle file.

    Replace <版本号> with the latest version available on JitPack.

    // settings.gradle
    dependencyResolutionManagement {
        repositories {
            google()
            mavenCentral()
            maven { url 'https://jitpack.io' }
        }
    }
    
    // build.gradle
    dependencies {
        implementation 'com.github.roro2239.Stellar-API:<版本号>'
    }
  8. Configure AndroidManifest for StellarProvider

    main

    You must register the StellarProvider in your AndroidManifest.xml to allow the Stellar service to communicate with your application.

    Required Configuration

    • android:exported="true": Must be true for the service to access the provider.
    • android:multiprocess="false": Must be false because the service retrieves the UID only when the app starts.
    • android:permission="android.permission.INTERACT_ACROSS_USERS_FULL": Restricts access to Shell and the app itself.
    • android:authorities: Must follow the pattern ${applicationId}.stellar.

    Metadata Permissions

    Use <meta-data> with the name roro.stellar.permissions to define access levels:

    • stellar: Required for basic Stellar API access.
    • stellar,follow_stellar_startup: Includes basic access and allows your app to automatically start when the Stellar service starts.
    <application>
        <provider
            android:name="roro.stellar.StellarProvider"
            android:authorities="${applicationId}.stellar"
            android:exported="true"
            android:multiprocess="false"
            android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
    
        <meta-data
            android:name="roro.stellar.permissions"
            android:value="stellar,follow_stellar_startup" />
    </application>
  9. Quick Start: Integrate Stellar into your application

    main

    To integrate Stellar into an Android application, follow these high-level steps:

    1. Add JitPack dependency: Add the following to your build configuration:
      implementation 'com.github.roro2239:Stellar-API:latest.release'
    2. Configure Provider: Add StellarProvider to your AndroidManifest.xml.
    3. Initialize and Request: Initialize the Stellar SDK and request the necessary permissions.
    4. Execute Operations: Use the Stellar API to perform privileged operations.

    For detailed implementation steps and API comparisons, refer to the Integration Guide.

    implementation 'com.github.roro2239:Stellar-API:latest.release'
  10. Enable multi-process support for Stellar

    main

    If your application uses multiple processes, you must configure StellarProvider in your Application class to ensure the Binder is correctly handled across processes.

    1. Determine if the current process is the Provider process.
    2. Call StellarProvider.enableMultiProcessSupport(isProviderProcess).
    3. For non-provider processes, call StellarProvider.requestBinderForNonProviderProcess(context).
    class MyApplication : Application() {
        override fun onCreate() {
            super.onCreate()
    
            // Replace with your actual logic to detect the provider process
            val isProviderProcess = // ... 
            
            StellarProvider.enableMultiProcessSupport(isProviderProcess)
    
            if (!isProviderProcess) {
                StellarProvider.requestBinderForNonProviderProcess(this)
            }
        }
    }
  11. Follow Stellar startup via BroadcastReceiver

    main

    If your app declares the roro.stellar.action.STELLAR_STARTED intent filter in AndroidManifest.xml, you can listen for the Stellar service startup event. This is useful for performing initialization tasks immediately after the service is ready.

    <!-- AndroidManifest.xml -->
    <receiver
        android:name=".FollowStellarStartup"
        android:exported="false">
        <intent-filter>
            <action android:name="roro.stellar.action.STELLAR_STARTED" />
        </intent-filter>
    </receiver>
    // FollowStellarStartup.kt
    class FollowStellarStartup : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Log.i("MyApp", "Stellar 已启动: ${intent?.action}")
            // Perform actions here
        }
    }
  12. Initialize Stellar and manage service lifecycle

    main

    To use Stellar, you must register listeners to handle service connection, disconnection, and permission results.

    Lifecycle Management

    1. Register Listeners: Use Stellar.addBinderReceivedListenerSticky(...) to ensure you receive a callback even if the service is already connected. Use Stellar.addBinderDeadListener(...) and Stellar.addRequestPermissionResultListener(...) for connection loss and permission changes.
    2. Check Status: Use Stellar.pingBinder() to verify the service is running and Stellar.checkSelfPermission() to verify permissions.
    3. Request Permissions: Use Stellar.requestPermission(requestCode) to prompt the user for access.
    4. Cleanup: Always call remove...Listener methods in onDestroy() to prevent memory leaks.
    import roro.stellar.Stellar
    
    class MainActivity : ComponentActivity() {
    
        private val binderReceivedListener = Stellar.OnBinderReceivedListener {
            Log.i("MyApp", "Stellar 服务已连接")
            checkServiceStatus()
        }
    
        private val binderDeadListener = Stellar.OnBinderDeadListener {
            Log.w("MyApp", "Stellar 服务已断开")
        }
    
        private val permissionResultListener =
            Stellar.OnRequestPermissionResultListener {
                requestCode, allowed, onetime ->
                if (allowed) {
                    Log.i("MyApp", "权限已授予")
                } else {
                    Log.w("MyApp", "权限被拒绝")
                }
            }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            // Use Sticky version to trigger immediately if already connected
            Stellar.addBinderReceivedListenerSticky(binderReceivedListener)
            Stellar.addBinderDeadListener(binderDeadListener)
            Stellar.addRequestPermissionResultListener(permissionResultListener)
        }
    
        override fun onDestroy() {
            super.onDestroy()
            Stellar.removeBinderReceivedListener(binderReceivedListener)
            Stellar.removeBinderDeadListener(binderDeadListener)
            Stellar.removeRequestPermissionResultListener(permissionResultListener)
        }
    
        private fun checkServiceStatus() {
            if (!Stellar.pingBinder()) {
                Log.e("MyApp", "服务未运行")
                return
            }
    
            if (!Stellar.checkSelfPermission()) {
                Stellar.requestPermission(requestCode = 1)
                return
            }
    
            Log.i("MyApp", "服务版本: ${Stellar.version}")
            Log.i("MyApp", "服务 UID: ${Stellar.uid}")
        }
    }