Skip to content

Commit f815f36

Browse files
committed
Avoid systemMain for jni
1 parent 45e6cd3 commit f815f36

File tree

4 files changed

+44
-21
lines changed

4 files changed

+44
-21
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded
197197
* `Lcom/android/internal/R$string;->config_ethernet_iface_regex:I,lo-prio,max-target-o`
198198
* (since API 29) `Lcom/android/server/wifi/p2p/WifiP2pServiceImpl;->ANONYMIZED_DEVICE_ADDRESS:Ljava/lang/String;`
199199
* (since API 30) `Lcom/android/server/SystemServer;->TETHERING_CONNECTOR_CLASS:Ljava/lang/String;`
200+
* (since API 33) `Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;,unsupported`
201+
* (since API 33) `Ldalvik/system/DexPathList;->nativeLibraryDirectories:Ljava/util/List;,unsupported`
200202
* `Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V,unsupported`
201203
* `Ljava/lang/invoke/MethodHandles$Lookup;->ALL_MODES:I,lo-prio,max-target-o`
202204
* (prior to API 29) `Ljava/net/InetAddress;->parseNumericAddress(Ljava/lang/String;)Ljava/net/InetAddress;,core-platform-api,max-target-p`

mobile/src/main/java/be/mygod/vpnhotspot/net/RemoveUidInterfaceRuleCommand.kt

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package be.mygod.vpnhotspot.net
22

3-
import android.content.Context
43
import android.os.Build
54
import android.os.IBinder
65
import androidx.annotation.RequiresApi
76
import be.mygod.librootkotlinx.ParcelableBoolean
87
import be.mygod.librootkotlinx.RootCommand
9-
import be.mygod.librootkotlinx.systemContext
10-
import be.mygod.vpnhotspot.BuildConfig
8+
import be.mygod.vpnhotspot.root.Jni
119
import be.mygod.vpnhotspot.util.Services
1210
import dalvik.system.PathClassLoader
1311
import kotlinx.parcelize.Parcelize
@@ -85,14 +83,7 @@ data class RemoveUidInterfaceRuleCommand(private val uid: Int) : RootCommand<Par
8583
}
8684
}
8785

88-
operator fun invoke(uid: Int): Boolean {
89-
val clazz = systemContext.createPackageContext(BuildConfig.APPLICATION_ID,
90-
Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY)
91-
.classLoader.loadClass("be.mygod.vpnhotspot.root.Jni")
92-
val jni = clazz.getDeclaredConstructor().newInstance()
93-
return clazz.getDeclaredMethod("removeUidInterfaceRules", String::class.java, Int::class.java,
94-
Long::class.java)(jni, mapPath, uid, matches) as Boolean
95-
}
86+
operator fun invoke(uid: Int) = Jni.removeUidInterfaceRules(mapPath, uid, matches)
9687
}
9788

9889
override suspend fun execute() = ParcelableBoolean(if (Build.VERSION.SDK_INT < 33) {

mobile/src/main/java/be/mygod/vpnhotspot/net/VpnFirewallManager.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package be.mygod.vpnhotspot.net
22

3-
import android.content.Context
43
import android.content.pm.PackageManager
54
import android.os.Build
65
import android.os.Process
76
import android.system.Os
87
import androidx.annotation.RequiresApi
98
import be.mygod.vpnhotspot.App.Companion.app
109
import be.mygod.vpnhotspot.R
10+
import be.mygod.vpnhotspot.root.Jni
1111
import be.mygod.vpnhotspot.root.RootManager
1212
import be.mygod.vpnhotspot.util.RootSession
1313
import be.mygod.vpnhotspot.widget.SmartSnackbar
@@ -68,16 +68,22 @@ object VpnFirewallManager {
6868
*/
6969
private val firewallMatcher by lazy { "^\\s*${Process.myUid()}\\D* IIF_MATCH ".toRegex(RegexOption.MULTILINE) }
7070

71+
@RequiresApi(29)
72+
private suspend fun removeUidInterfaceRules(uid: Int) = RootManager.use {
73+
if (Build.VERSION.SDK_INT >= 33) it.execute(Jni.Init())
74+
it.execute(RemoveUidInterfaceRuleCommand(uid))
75+
}.value
76+
7177
@RequiresApi(29)
7278
private fun excludeFromFirewall(uid: Int) {
73-
if (!runBlocking { RootManager.use { it.execute(RemoveUidInterfaceRuleCommand(uid)) } }.value) {
79+
if (!runBlocking { removeUidInterfaceRules(uid) }) {
7480
throw Exception("RemoveUidInterfaceRuleCommand failed to update")
7581
}
7682
}
7783
fun excludeIfNeeded(scope: CoroutineScope) {
7884
if (mayBeAffected) scope.launch {
7985
try {
80-
RootManager.use { it.execute(RemoveUidInterfaceRuleCommand(Process.myUid())) }
86+
removeUidInterfaceRules(Process.myUid())
8187
} catch (e: Exception) {
8288
Timber.w(e)
8389
}
@@ -101,7 +107,7 @@ object VpnFirewallManager {
101107
transaction.exec("settings put global $UIDS_ALLOWED_ON_RESTRICTED_NETWORKS '${allowed.joinToString(";")}'")
102108
}
103109
if (Build.VERSION.SDK_INT >= 33) try {
104-
runBlocking { RootManager.use { it.execute(RemoveUidInterfaceRuleCommand(uid)) } }
110+
runBlocking { removeUidInterfaceRules(uid) }
105111
} catch (e: Exception) {
106112
SmartSnackbar.make(R.string.error_vpn_firewall_reboot).show()
107113
Timber.w(e)
Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
11
package be.mygod.vpnhotspot.root
22

3-
import androidx.annotation.Keep
3+
import android.os.Parcelable
4+
import be.mygod.librootkotlinx.RootCommandNoResult
5+
import dalvik.system.BaseDexClassLoader
6+
import kotlinx.parcelize.Parcelize
7+
import java.io.File
48

5-
class Jni {
6-
init {
7-
System.loadLibrary("vpnhotspot")
9+
object Jni {
10+
private var initialized = 0
11+
private val nativeLibraryDirs by lazy {
12+
val pathList = BaseDexClassLoader::class.java.getDeclaredField("pathList").apply {
13+
isAccessible = true
14+
}.get(javaClass.classLoader)
15+
pathList.javaClass.getDeclaredField("nativeLibraryDirectories").apply {
16+
isAccessible = true
17+
}.get(pathList) as ArrayList<File>
818
}
919

10-
@Keep
11-
external fun removeUidInterfaceRules(path: String, uid: Int, rules: Long): Boolean
20+
@Parcelize
21+
data class Init(private val nativeDirs: List<File> = nativeLibraryDirs) : RootCommandNoResult {
22+
override suspend fun execute(): Parcelable? {
23+
if (initialized <= 0) {
24+
nativeLibraryDirs.addAll(nativeDirs)
25+
initialized = 1
26+
}
27+
if (initialized == 1) {
28+
System.loadLibrary("vpnhotspot")
29+
initialized = 2
30+
}
31+
return null
32+
}
33+
}
34+
35+
external fun removeUidInterfaceRules(path: String?, uid: Int, rules: Long): Boolean
1236
}

0 commit comments

Comments
 (0)