mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
NativeLoader
现在,可以在HMA做了隐藏的情况下正确加载库文件 借鉴过来的,貌似会导致亿点问题 感觉isEmu也会翻车呢 ┭┮﹏┭┮
This commit is contained in:
parent
60fdfd9071
commit
1f620bcc06
@ -69,6 +69,8 @@ dependencies {
|
|||||||
|
|
||||||
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
|
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
|
||||||
|
|
||||||
|
implementation("cn.hutool:hutool-core:5.8.0.M1")
|
||||||
|
|
||||||
DEPENDENCY_ANDROIDX.forEach {
|
DEPENDENCY_ANDROIDX.forEach {
|
||||||
implementation(it)
|
implementation(it)
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
package moe.fuqiuluo.shamrock.xposed.loader
|
package moe.fuqiuluo.shamrock.xposed.loader
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import cn.hutool.core.io.FileUtil
|
||||||
|
import cn.hutool.core.io.IoUtil
|
||||||
|
import com.tencent.mmkv.MMKV
|
||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
import moe.fuqiuluo.shamrock.helper.Level
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.xposed.XposedEntry
|
import moe.fuqiuluo.shamrock.xposed.XposedEntry
|
||||||
|
import moe.fuqiuluo.shamrock.xposed.loader.tmpnativehelper.moduleClassLoader
|
||||||
import mqq.app.MobileQQ
|
import mqq.app.MobileQQ
|
||||||
|
import java.io.BufferedInputStream
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal object NativeLoader {
|
internal object NativeLoader {
|
||||||
@ -17,6 +25,31 @@ internal object NativeLoader {
|
|||||||
return externalLibPath.resolve("libffmpegkit.so").exists()
|
return externalLibPath.resolve("libffmpegkit.so").exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val isEmu: Boolean
|
||||||
|
get() {
|
||||||
|
if (Build.SUPPORTED_ABIS.any { it.contains("x86") }) {
|
||||||
|
XposedBridge.log("[Shamrock] 通过SUPPORTED_ABIS检测到 Android x86")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return try {
|
||||||
|
val clazz = Class.forName("dalvik.system.VMRuntime")
|
||||||
|
val method = clazz.getDeclaredMethod("getRuntime")
|
||||||
|
val runtime = method.invoke(null)
|
||||||
|
val field = clazz.getDeclaredField("vmInstructionSet")
|
||||||
|
field.isAccessible = true
|
||||||
|
val instructionSet = field.get(runtime) as String
|
||||||
|
instructionSet.contains("x86")
|
||||||
|
XposedBridge.log("[Shamrock] 反射检测到 Android x86")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
XposedBridge.log("[Shamrock] $e")
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLibFilePath(name: String): String {
|
||||||
|
return if (isEmu) "lib/x86_64/lib${name}.so" else "lib/arm64-v8a/lib$name.so"
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使目标进程可以使用来自模块的库
|
* 使目标进程可以使用来自模块的库
|
||||||
*/
|
*/
|
||||||
@ -24,7 +57,8 @@ internal object NativeLoader {
|
|||||||
fun load(name: String) {
|
fun load(name: String) {
|
||||||
try {
|
try {
|
||||||
if (name == "shamrock" || name == "clover") {
|
if (name == "shamrock" || name == "clover") {
|
||||||
val context = MobileQQ.getContext()
|
|
||||||
|
/* val context = MobileQQ.getContext()
|
||||||
val packageManager = context.packageManager
|
val packageManager = context.packageManager
|
||||||
val applicationInfo = packageManager.getApplicationInfo("moe.fuqiuluo.shamrock.hided", 0)
|
val applicationInfo = packageManager.getApplicationInfo("moe.fuqiuluo.shamrock.hided", 0)
|
||||||
val file = File(applicationInfo.nativeLibraryDir)
|
val file = File(applicationInfo.nativeLibraryDir)
|
||||||
@ -34,7 +68,10 @@ internal object NativeLoader {
|
|||||||
LogCenter.log("LoadLibrary(name = $name) failed, file not exists.", level = Level.ERROR)
|
LogCenter.log("LoadLibrary(name = $name) failed, file not exists.", level = Level.ERROR)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}.absolutePath)
|
}.absolutePath)*/
|
||||||
|
|
||||||
|
onload(name, getCtx())
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
val sourceFile = externalLibPath.resolve("lib$name.so")
|
val sourceFile = externalLibPath.resolve("lib$name.so")
|
||||||
val soFile = MobileQQ.getContext().filesDir.parentFile!!.resolve("txlib").resolve("lib$name.so")
|
val soFile = MobileQQ.getContext().filesDir.parentFile!!.resolve("txlib").resolve("lib$name.so")
|
||||||
@ -54,4 +91,52 @@ internal object NativeLoader {
|
|||||||
XposedBridge.log(e)
|
XposedBridge.log(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
fun getCtx() = MobileQQ.getContext()
|
||||||
|
|
||||||
|
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||||
|
fun onload(name: String, context: Context) {
|
||||||
|
val soDir = File(context.filesDir, "SM_LIBS")
|
||||||
|
if (soDir.isFile) {
|
||||||
|
soDir.delete()
|
||||||
|
}
|
||||||
|
if (!soDir.exists()) {
|
||||||
|
soDir.mkdirs()
|
||||||
|
}
|
||||||
|
val soPath = NativeLoader.getLibFilePath(name)
|
||||||
|
val soFile = File(soDir, name)
|
||||||
|
val libStream =
|
||||||
|
BufferedInputStream(moduleClassLoader.getResourceAsStream(soPath))
|
||||||
|
val tmpSoFile = File(soDir, "$name.tmp")
|
||||||
|
try {
|
||||||
|
FileUtil.writeFromStream(libStream, tmpSoFile)
|
||||||
|
if (!soFile.exists()) {
|
||||||
|
LogCenter.log("SO文件 ${name} 不存在,正在尝试加载", Level.INFO)
|
||||||
|
tmpSoFile.renameTo(soFile)
|
||||||
|
} else {
|
||||||
|
val oldStream = FileUtil.getInputStream(soFile)
|
||||||
|
val newStream = FileUtil.getInputStream(tmpSoFile)
|
||||||
|
if (!IoUtil.contentEquals(oldStream, newStream)) {
|
||||||
|
LogCenter.log("SO文件版本不一致,正在重新加载", Level.INFO)
|
||||||
|
soFile.delete()
|
||||||
|
tmpSoFile.renameTo(soFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
System.load(soFile.absolutePath)
|
||||||
|
LogCenter.log("加载SO文件成功 -> ${soFile.path}", Level.INFO)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
LogCenter.log(e.toString(), Level.WARN)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
LogCenter.log(e.toString(), Level.WARN)
|
||||||
|
throw e
|
||||||
|
} finally {
|
||||||
|
if (tmpSoFile.exists()) {
|
||||||
|
tmpSoFile.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
@file:JvmName("ModuleInfo")
|
||||||
|
package moe.fuqiuluo.shamrock.xposed.loader.tmpnativehelper
|
||||||
|
|
||||||
|
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader
|
||||||
|
|
||||||
|
val moduleClassLoader: ClassLoader = LuoClassloader::class.java.classLoader!!
|
Loading…
x
Reference in New Issue
Block a user