|
@@ -0,0 +1,93 @@
|
|
|
+package com.eastpolar.hookcli.tools
|
|
|
+
|
|
|
+import android.content.Context
|
|
|
+import android.util.Log
|
|
|
+import java.io.DataOutputStream
|
|
|
+import java.io.File
|
|
|
+import java.io.IOException
|
|
|
+
|
|
|
+
|
|
|
+class AutoCopySO {
|
|
|
+ init {
|
|
|
+ System.loadLibrary("cli")
|
|
|
+ }
|
|
|
+
|
|
|
+ private external fun logHello();
|
|
|
+
|
|
|
+ //将本应用的对应版本so文件拷贝到目标目录下
|
|
|
+ fun copySoFile(context: Context, targetPackage: String,type: ArmType = ArmType.ARM64V8A) {
|
|
|
+ logHello()
|
|
|
+
|
|
|
+ // 获取应用的私有文件目录
|
|
|
+ // 获取应用的私有文件目录
|
|
|
+ val libDir: File = File(context.getApplicationInfo().nativeLibraryDir)
|
|
|
+
|
|
|
+// 列出目录下的所有文件(包括.so文件)
|
|
|
+
|
|
|
+// 列出目录下的所有文件(包括.so文件)
|
|
|
+
|
|
|
+ var soPath = ""
|
|
|
+ val soName = "libcli.so"
|
|
|
+
|
|
|
+ val files = libDir.listFiles()
|
|
|
+ if (files != null) {
|
|
|
+ for (file in files) {
|
|
|
+ if (file.path.contains(type.type)&&file.name.endsWith(soName)) {
|
|
|
+ // 这里可以获取到每个.so文件的路径
|
|
|
+ soPath = file.absolutePath
|
|
|
+ Log.d("SO_FILE", "Found .so file: " + file.absolutePath)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ val targetPath = "/data/data/$targetPackage/files" // 注意这里修正了字符串模板的错误
|
|
|
+ val targetSoFile = "$targetPath/$soName"
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 执行复制操作,需要root权限
|
|
|
+ val process = Runtime.getRuntime().exec("su")
|
|
|
+ val os = DataOutputStream(process.outputStream)
|
|
|
+
|
|
|
+ // 创建目标目录,防止目标目录不存在
|
|
|
+ os.writeBytes("mkdir -p $targetPath\n")
|
|
|
+ os.flush()
|
|
|
+ os.writeBytes("mkdir -p $targetPath/test\n")
|
|
|
+ os.flush()
|
|
|
+ // 复制文件
|
|
|
+ os.writeBytes("cp $soPath $targetSoFile\n")
|
|
|
+ os.flush()
|
|
|
+ // 修改目标文件权限,确保目标应用可以访问
|
|
|
+ os.writeBytes("chmod 777 $targetSoFile\n")
|
|
|
+ os.flush()
|
|
|
+ // 退出su
|
|
|
+ os.writeBytes("exit\n")
|
|
|
+ os.flush()
|
|
|
+ os.close()
|
|
|
+
|
|
|
+ process.waitFor()
|
|
|
+ if (process.exitValue() == 0) {
|
|
|
+ // 成功复制
|
|
|
+ println("Copy successful")
|
|
|
+ } else {
|
|
|
+ // 复制失败
|
|
|
+ println("Copy failed")
|
|
|
+ }
|
|
|
+ } catch (e: IOException) {
|
|
|
+ e.printStackTrace()
|
|
|
+ } catch (e: InterruptedException) {
|
|
|
+ e.printStackTrace()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //单例模式
|
|
|
+ companion object {
|
|
|
+ val instance: AutoCopySO by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
|
|
+ AutoCopySO()
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//Arm类型和架构,包含参数v7a,arm64-v8a
|
|
|
+enum class ArmType(val type: String) {
|
|
|
+ ARMV7A("armeabi-v7a"), ARM64V8A("arm64")
|
|
|
+}
|