mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
commit
d6142173c9
@ -1,11 +1,14 @@
|
||||
package moe.fuqiuluo.shamrock.xposed.loader
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import de.robv.android.xposed.XposedBridge
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.xposed.XposedEntry
|
||||
import moe.fuqiuluo.shamrock.xposed.loader.tmpnativehelper.moduleClassLoader
|
||||
import mqq.app.MobileQQ
|
||||
import oicq.wlogin_sdk.tools.MD5
|
||||
import java.io.File
|
||||
|
||||
internal object NativeLoader {
|
||||
@ -17,6 +20,33 @@ internal object NativeLoader {
|
||||
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
|
||||
if ( instructionSet.contains("x86") ) {
|
||||
XposedBridge.log("[Shamrock] 反射检测到 Android x86")
|
||||
true
|
||||
} else false
|
||||
} 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,17 +54,7 @@ internal object NativeLoader {
|
||||
fun load(name: String) {
|
||||
try {
|
||||
if (name == "shamrock" || name == "clover") {
|
||||
val context = MobileQQ.getContext()
|
||||
val packageManager = context.packageManager
|
||||
val applicationInfo = packageManager.getApplicationInfo("moe.fuqiuluo.shamrock.hided", 0)
|
||||
val file = File(applicationInfo.nativeLibraryDir)
|
||||
LogCenter.log("LoadLibrary(name = $name)")
|
||||
System.load(file.resolve("lib$name.so").also {
|
||||
if (!it.exists()) {
|
||||
LogCenter.log("LoadLibrary(name = $name) failed, file not exists.", level = Level.ERROR)
|
||||
return
|
||||
}
|
||||
}.absolutePath)
|
||||
onLoadByCopiedLibrary(name, getCtx())
|
||||
} else {
|
||||
val sourceFile = externalLibPath.resolve("lib$name.so")
|
||||
val soFile = MobileQQ.getContext().filesDir.parentFile!!.resolve("txlib").resolve("lib$name.so")
|
||||
@ -54,4 +74,55 @@ internal object NativeLoader {
|
||||
XposedBridge.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun getCtx() = MobileQQ.getContext()
|
||||
|
||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||
private fun onLoadByCopiedLibrary(name: String, context: Context) {
|
||||
val soDir = File(context.filesDir, "SM_LIBS")
|
||||
if (soDir.isFile) {
|
||||
soDir.delete()
|
||||
}
|
||||
if (!soDir.exists()) {
|
||||
soDir.mkdirs()
|
||||
}
|
||||
val soPath = getLibFilePath(name)
|
||||
val soFile = File(soDir, name)
|
||||
fun reloadSo(tmp: File? = null) {
|
||||
LogCenter.log("SO文件大小不一致或不存在,正在重新加载", Level.INFO)
|
||||
soFile.delete()
|
||||
if (tmp == null) moduleClassLoader.getResourceAsStream(soPath).use { origin ->
|
||||
soFile.outputStream().use { origin.copyTo(it) }
|
||||
} else tmp.renameTo(soFile)
|
||||
}
|
||||
try {
|
||||
if (!soFile.exists()) {
|
||||
reloadSo()
|
||||
} else {
|
||||
val tmpSoFile = soFile.resolve("$name.tmp").also { file ->
|
||||
if (file.exists()) file.delete()
|
||||
file.outputStream().use {
|
||||
moduleClassLoader.getResourceAsStream(soPath).use { origin ->
|
||||
origin.copyTo(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (soFile.length() != tmpSoFile.length() || MD5.getFileMD5(soFile).let {
|
||||
it != MD5.getFileMD5(tmpSoFile)
|
||||
}) {
|
||||
reloadSo(tmpSoFile)
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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