Skip to content

Commit

Permalink
Avoid systemMain for jni
Browse files Browse the repository at this point in the history
  • Loading branch information
Mygod committed Jul 24, 2024
1 parent 45e6cd3 commit f815f36
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 21 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded
* `Lcom/android/internal/R$string;->config_ethernet_iface_regex:I,lo-prio,max-target-o`
* (since API 29) `Lcom/android/server/wifi/p2p/WifiP2pServiceImpl;->ANONYMIZED_DEVICE_ADDRESS:Ljava/lang/String;`
* (since API 30) `Lcom/android/server/SystemServer;->TETHERING_CONNECTOR_CLASS:Ljava/lang/String;`
* (since API 33) `Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;,unsupported`
* (since API 33) `Ldalvik/system/DexPathList;->nativeLibraryDirectories:Ljava/util/List;,unsupported`
* `Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V,unsupported`
* `Ljava/lang/invoke/MethodHandles$Lookup;->ALL_MODES:I,lo-prio,max-target-o`
* (prior to API 29) `Ljava/net/InetAddress;->parseNumericAddress(Ljava/lang/String;)Ljava/net/InetAddress;,core-platform-api,max-target-p`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package be.mygod.vpnhotspot.net

import android.content.Context
import android.os.Build
import android.os.IBinder
import androidx.annotation.RequiresApi
import be.mygod.librootkotlinx.ParcelableBoolean
import be.mygod.librootkotlinx.RootCommand
import be.mygod.librootkotlinx.systemContext
import be.mygod.vpnhotspot.BuildConfig
import be.mygod.vpnhotspot.root.Jni
import be.mygod.vpnhotspot.util.Services
import dalvik.system.PathClassLoader
import kotlinx.parcelize.Parcelize
Expand Down Expand Up @@ -85,14 +83,7 @@ data class RemoveUidInterfaceRuleCommand(private val uid: Int) : RootCommand<Par
}
}

operator fun invoke(uid: Int): Boolean {
val clazz = systemContext.createPackageContext(BuildConfig.APPLICATION_ID,
Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY)
.classLoader.loadClass("be.mygod.vpnhotspot.root.Jni")
val jni = clazz.getDeclaredConstructor().newInstance()
return clazz.getDeclaredMethod("removeUidInterfaceRules", String::class.java, Int::class.java,
Long::class.java)(jni, mapPath, uid, matches) as Boolean
}
operator fun invoke(uid: Int) = Jni.removeUidInterfaceRules(mapPath, uid, matches)
}

override suspend fun execute() = ParcelableBoolean(if (Build.VERSION.SDK_INT < 33) {
Expand Down
14 changes: 10 additions & 4 deletions mobile/src/main/java/be/mygod/vpnhotspot/net/VpnFirewallManager.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package be.mygod.vpnhotspot.net

import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Process
import android.system.Os
import androidx.annotation.RequiresApi
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.root.Jni
import be.mygod.vpnhotspot.root.RootManager
import be.mygod.vpnhotspot.util.RootSession
import be.mygod.vpnhotspot.widget.SmartSnackbar
Expand Down Expand Up @@ -68,16 +68,22 @@ object VpnFirewallManager {
*/
private val firewallMatcher by lazy { "^\\s*${Process.myUid()}\\D* IIF_MATCH ".toRegex(RegexOption.MULTILINE) }

@RequiresApi(29)
private suspend fun removeUidInterfaceRules(uid: Int) = RootManager.use {
if (Build.VERSION.SDK_INT >= 33) it.execute(Jni.Init())
it.execute(RemoveUidInterfaceRuleCommand(uid))
}.value

@RequiresApi(29)
private fun excludeFromFirewall(uid: Int) {
if (!runBlocking { RootManager.use { it.execute(RemoveUidInterfaceRuleCommand(uid)) } }.value) {
if (!runBlocking { removeUidInterfaceRules(uid) }) {
throw Exception("RemoveUidInterfaceRuleCommand failed to update")
}
}
fun excludeIfNeeded(scope: CoroutineScope) {
if (mayBeAffected) scope.launch {
try {
RootManager.use { it.execute(RemoveUidInterfaceRuleCommand(Process.myUid())) }
removeUidInterfaceRules(Process.myUid())
} catch (e: Exception) {
Timber.w(e)
}
Expand All @@ -101,7 +107,7 @@ object VpnFirewallManager {
transaction.exec("settings put global $UIDS_ALLOWED_ON_RESTRICTED_NETWORKS '${allowed.joinToString(";")}'")
}
if (Build.VERSION.SDK_INT >= 33) try {
runBlocking { RootManager.use { it.execute(RemoveUidInterfaceRuleCommand(uid)) } }
runBlocking { removeUidInterfaceRules(uid) }
} catch (e: Exception) {
SmartSnackbar.make(R.string.error_vpn_firewall_reboot).show()
Timber.w(e)
Expand Down
36 changes: 30 additions & 6 deletions mobile/src/main/java/be/mygod/vpnhotspot/root/Jni.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
package be.mygod.vpnhotspot.root

import androidx.annotation.Keep
import android.os.Parcelable
import be.mygod.librootkotlinx.RootCommandNoResult
import dalvik.system.BaseDexClassLoader
import kotlinx.parcelize.Parcelize
import java.io.File

class Jni {
init {
System.loadLibrary("vpnhotspot")
object Jni {
private var initialized = 0
private val nativeLibraryDirs by lazy {
val pathList = BaseDexClassLoader::class.java.getDeclaredField("pathList").apply {
isAccessible = true
}.get(javaClass.classLoader)
pathList.javaClass.getDeclaredField("nativeLibraryDirectories").apply {
isAccessible = true
}.get(pathList) as ArrayList<File>
}

@Keep
external fun removeUidInterfaceRules(path: String, uid: Int, rules: Long): Boolean
@Parcelize
data class Init(private val nativeDirs: List<File> = nativeLibraryDirs) : RootCommandNoResult {
override suspend fun execute(): Parcelable? {
if (initialized <= 0) {
nativeLibraryDirs.addAll(nativeDirs)
initialized = 1
}
if (initialized == 1) {
System.loadLibrary("vpnhotspot")
initialized = 2
}
return null
}
}

external fun removeUidInterfaceRules(path: String?, uid: Int, rules: Long): Boolean
}

0 comments on commit f815f36

Please sign in to comment.