Skip to content

Commit

Permalink
Ensure stub APK is expected
Browse files Browse the repository at this point in the history
Fix #7884
  • Loading branch information
topjohnwu committed Mar 9, 2024
1 parent d56f4fb commit dbf6e40
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 44 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ dependencies {
implementation("androidx.room:room-ktx:${vRoom}")
kapt("androidx.room:room-compiler:${vRoom}")

val vNav = "2.7.6"
val vNav = "2.7.7"
implementation("androidx.navigation:navigation-fragment-ktx:${vNav}")
implementation("androidx.navigation:navigation-ui-ktx:${vNav}")

Expand Down
23 changes: 0 additions & 23 deletions app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.view.forEach
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavDirections
import com.topjohnwu.magisk.MainDirections
import com.topjohnwu.magisk.R
Expand All @@ -24,13 +23,10 @@ import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
import com.topjohnwu.magisk.ui.home.HomeFragmentDirections
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Shortcuts
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File

class MainViewModel : BaseViewModel()
Expand Down Expand Up @@ -62,7 +58,6 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
setContentView()
showUnsupportedMessage()
askForHomeShortcut()
checkStubComponent()

// Ask permission to post notifications for background update check
if (Config.checkUpdate) {
Expand Down Expand Up @@ -231,22 +226,4 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
}.show()
}
}

@SuppressLint("InlinedApi")
private fun checkStubComponent() {
if (intent.component?.className?.contains(HideAPK.PLACEHOLDER) == true) {
// The stub APK was not properly patched, re-apply our changes
withPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES) { granted ->
if (granted) {
lifecycleScope.launch(Dispatchers.IO) {
val apk = File(applicationInfo.sourceDir)
HideAPK.upgrade(this@MainActivity, apk)?.let {
startActivity(it)
}
}
}
}
}
}

}
67 changes: 49 additions & 18 deletions app/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,30 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.arch.NavigationActivity
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.JobService
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.ui.theme.Theme
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Shortcuts
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import timber.log.Timber
import java.io.File
import java.io.IOException

@SuppressLint("CustomSplashScreen")
abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Binding>() {
Expand Down Expand Up @@ -58,7 +65,7 @@ abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Bi
showInvalidStateMessage()
return@getShell
}
preLoad(savedInstanceState)
initialize(savedInstanceState)
}
}
}
Expand Down Expand Up @@ -102,7 +109,7 @@ abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Bi
}
}

private fun preLoad(savedState: Bundle?) {
private fun initialize(savedState: Bundle?) {
val prevPkg = intent.getStringExtra(Const.Key.PREV_PKG)?.let {
// Make sure the calling package matches (prevent DoS)
if (it == realCallingPackage)
Expand All @@ -112,7 +119,21 @@ abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Bi
}

Config.load(prevPkg)
handleRepackage(prevPkg)

if (packageName != APPLICATION_ID) {
runCatching {
// Hidden, remove com.topjohnwu.magisk if exist as it could be malware
packageManager.getApplicationInfo(APPLICATION_ID, 0)
Shell.cmd("(pm uninstall $APPLICATION_ID)& >/dev/null 2>&1").exec()
}
} else {
if (Config.suManager.isNotEmpty())
Config.suManager = ""
if (prevPkg != null) {
Shell.cmd("(pm uninstall $prevPkg)& >/dev/null 2>&1").exec()
}
}

if (prevPkg != null) {
runOnUiThread {
// Relaunch the process after package migration
Expand All @@ -121,6 +142,31 @@ abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Bi
return
}

// Validate stub APK
if (isRunningAsStub && (
// Version mismatch
Info.stub!!.version != BuildConfig.STUB_VERSION ||
// Not properly patched
intent.component!!.className.contains(HideAPK.PLACEHOLDER)
)) {
withPermission(REQUEST_INSTALL_PACKAGES) { granted ->
if (granted) {
lifecycleScope.launch(Dispatchers.IO) {
val apk = File(cacheDir, "stub.apk")
try {
assets.open("stub.apk").writeTo(apk)
HideAPK.upgrade(this@SplashActivity, apk)?.let {
startActivity(it)
}
} catch (e: IOException) {
Timber.e(e)
}
}
}
}
return
}

JobService.schedule(this)
Shortcuts.setupDynamic(this)

Expand All @@ -144,19 +190,4 @@ abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Bi
}
}
}

private fun handleRepackage(pkg: String?) {
if (packageName != APPLICATION_ID) {
runCatching {
// Hidden, remove com.topjohnwu.magisk if exist as it could be malware
packageManager.getApplicationInfo(APPLICATION_ID, 0)
Shell.cmd("(pm uninstall $APPLICATION_ID)& >/dev/null 2>&1").exec()
}
} else {
if (Config.suManager.isNotEmpty())
Config.suManager = ""
pkg ?: return
Shell.cmd("(pm uninstall $pkg)& >/dev/null 2>&1").exec()
}
}
}
2 changes: 1 addition & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ gradlePlugin {
dependencies {
implementation(embeddedKotlin("gradle-plugin"))
implementation("com.android.tools.build:gradle:8.2.2")
implementation("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.6")
implementation("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7")
implementation("org.lsposed.lsparanoid:gradle-plugin:0.5.2")
implementation("org.eclipse.jgit:org.eclipse.jgit:6.7.0.202309050840-r")
}
4 changes: 4 additions & 0 deletions buildSrc/src/main/java/Setup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ private fun Project.setupAppCommon() {
}
}

defaultConfig {
buildConfigField("int", "STUB_VERSION", Config.stubVersion)
}

buildTypes {
signingConfigs["config"].also {
debug {
Expand Down
1 change: 0 additions & 1 deletion stub/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ android {
applicationId = "com.topjohnwu.magisk"
versionCode = 1
versionName = "1.0"
buildConfigField("int", "STUB_VERSION", Config.stubVersion)
buildConfigField("String", "APK_URL", url?.let { "\"$it\"" } ?: "null" )
}

Expand Down

0 comments on commit dbf6e40

Please sign in to comment.