diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3a5b8f4..9c31989 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -51,10 +51,12 @@ @@ -124,6 +126,10 @@ android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" /> + \ No newline at end of file diff --git a/app/src/main/java/com/android/grape/MainActivity.kt b/app/src/main/java/com/android/grape/MainActivity.kt index db6d8d5..0a24992 100644 --- a/app/src/main/java/com/android/grape/MainActivity.kt +++ b/app/src/main/java/com/android/grape/MainActivity.kt @@ -3,7 +3,6 @@ package com.android.grape import android.content.Intent import android.os.Build import android.os.Bundle -import android.util.Log import android.widget.Toast import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels @@ -13,29 +12,26 @@ import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import com.android.grape.databinding.ActivityMainBinding import com.android.grape.job.MonitorService -import com.android.grape.provider.DeviceDataAccessor -import com.android.grape.provider.DeviceInfoHelper +import com.android.grape.service.SocketServer import com.android.grape.util.ClashUtil import com.android.grape.util.MockTools import com.android.grape.util.NotificationPermissionHandler import com.android.grape.util.ScriptUtil -import com.android.grape.util.ShellUtils import com.android.grape.util.StoragePermissionHelper -import com.android.grape.util.Util -import com.android.grape.util.Util.AUTO_JSPACKAGENAME import com.android.grape.util.Util.killRecordProcess -import com.google.gson.Gson class MainActivity : AppCompatActivity() { private val viewModel by viewModels() private lateinit var viewBinding: ActivityMainBinding private lateinit var permissionHandler: NotificationPermissionHandler + private lateinit var socketServer: SocketServer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() init() viewBinding = ActivityMainBinding.inflate(layoutInflater) setContentView(viewBinding.root) + socketServer = SocketServer(8888) ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) @@ -45,13 +41,22 @@ class MainActivity : AppCompatActivity() { ScriptUtil.registerScriptResultReceiver() viewBinding.start.setOnClickListener { MonitorService.onEvent(MainApplication.instance) -// DeviceDataAccessor.saveDeviceInfo(this, DeviceInfoHelper.getDeviceId(this)) } viewBinding.stop.setOnClickListener { killRecordProcess(this, packageName) -// DeviceDataAccessor.deleteDeviceInfo(this, DeviceInfoHelper.getDeviceId(this)) -// val deviceInfo = DeviceDataAccessor.getDeviceInfo(this, DeviceInfoHelper.getDeviceId(this)) -// Log.d("TAG", "onCreate: ${Gson().toJson(deviceInfo?:"")}") +// val deviceInfo = DeviceDataAccessor.getDeviceInfo(this, DeviceInfoHelper.getDeviceId()) +// FileUtils.writeDevice("com.headway.books", deviceInfo?:"") +// socketServer.start { client, message -> +// Log.d("Server", "收到消息: $message") +// +// // 处理消息并回复 +// val response = "服务器已收到: $message" +// runOnUiThread { +// findViewById(R.id.text).append("$message\n") +// } +// socketServer.sendToClient(client, deviceInfo?:"没有设备信息") +// } +// FileUtils.runPlugin("com.headway.books") } } @@ -63,6 +68,7 @@ class MainActivity : AppCompatActivity() { override fun onDestroy() { super.onDestroy() +// socketServer.stop() ClashUtil.unregisterReceiver(this) ScriptUtil.unregisterScriptResultReceiver() } diff --git a/app/src/main/java/com/android/grape/data/Device.kt b/app/src/main/java/com/android/grape/data/Device.kt index 70c9c56..ef19955 100644 --- a/app/src/main/java/com/android/grape/data/Device.kt +++ b/app/src/main/java/com/android/grape/data/Device.kt @@ -95,7 +95,8 @@ data class Device( var scO: String = "", var sdk: String = "", var sdkVer: String = "", - var sensor: List = listOf(), + @Transient + var sensor: JSONArray = JSONArray(), var sensorReset: Int = 0, @SerializedName("sensor_size") var sensorSize: Int = 0, @@ -115,7 +116,7 @@ data class Device( ){ fun toJson(): String { return JSONObject().apply { - put("sensors", JSONArray(sensor)) + put("sensors", sensor) put("arch", arch) put("cpu_abi", cpuAbi) put("cpu_abi2", cpuAbi2) diff --git a/app/src/main/java/com/android/grape/job/AutoJobService.kt b/app/src/main/java/com/android/grape/job/AutoJobService.kt index f649ab5..2aeee28 100644 --- a/app/src/main/java/com/android/grape/job/AutoJobService.kt +++ b/app/src/main/java/com/android/grape/job/AutoJobService.kt @@ -6,6 +6,7 @@ import android.os.Handler import android.os.Looper import androidx.core.app.JobIntentService import com.android.grape.util.ScriptUtil +import com.android.grape.util.Util class AutoJobService : JobIntentService() { override fun onHandleWork(intent: Intent) { @@ -15,7 +16,7 @@ class AutoJobService : JobIntentService() { Handler(Looper.getMainLooper()).postDelayed({ ScriptUtil.execScript( this@AutoJobService, - "/sdcard/script/main.js" + "/sdcard/script/${Util.recordPackageName}/main.js" ) }, 2000L) } else { diff --git a/app/src/main/java/com/android/grape/job/MonitorService.kt b/app/src/main/java/com/android/grape/job/MonitorService.kt index fe73cb5..638b9c5 100644 --- a/app/src/main/java/com/android/grape/job/MonitorService.kt +++ b/app/src/main/java/com/android/grape/job/MonitorService.kt @@ -24,12 +24,9 @@ class MonitorService : JobIntentService() { try { val apkRoot = "chmod 777 $packageCodePath" MockTools.exec(apkRoot) - Log.i(TAG, "set to top") - Util.setTopApp(this) - Log.i(TAG, "auto stop vpn") - ClashUtil.stopProxy(this) + ClashUtil.switchProxyGroup("PROXY", "DIRECT", "http://127.0.0.1:6170") Thread.sleep(3000) if (Util.clickTime > 0L) { diff --git a/app/src/main/java/com/android/grape/job/OpenAppService.kt b/app/src/main/java/com/android/grape/job/OpenAppService.kt index fd451ec..5027ace 100644 --- a/app/src/main/java/com/android/grape/job/OpenAppService.kt +++ b/app/src/main/java/com/android/grape/job/OpenAppService.kt @@ -2,10 +2,14 @@ package com.android.grape.job import android.content.Context import android.content.Intent +import android.text.TextUtils import android.util.Log import androidx.core.app.JobIntentService import com.android.grape.net.ChangeCallBack +import com.android.grape.provider.DeviceDataAccessor +import com.android.grape.provider.DeviceInfoHelper import com.android.grape.util.ChangeDeviceInfoUtil +import com.android.grape.util.FileUtils import com.android.grape.util.MockTools import com.android.grape.util.ServiceUtils import com.android.grape.util.Util @@ -23,25 +27,26 @@ class OpenAppService : JobIntentService() { ServiceUtils.setEnableApp("com.google.android.webview", true) ServiceUtils.setEnableApp("com.android.chrome", true) ServiceUtils.setEnableApp("com.UCMobile", true) - if (Util.isCanAuto && Util.canAutoLc.isNotEmpty()) { - MockTools.exec("pm grant ${Util.AUTO_JSPACKAGENAME} android.permission.READ_EXTERNAL_STORAGE") //sdcard权限 - MockTools.exec("pm grant ${Util.AUTO_JSPACKAGENAME} android.permission.SYSTEM_ALERT_WINDOW") //悬浮窗权限 - MockTools.exec("settings put secure enabled_accessibility_services ${Util.AUTO_JSPACKAGENAME}/${Util.AUTO_JSPACKAGENAME}.core.accessibility.AccessibilityService") - Util.doScript(this, Util.AUTO_JSPACKAGENAME) //autojs - } try { - //todo fix 改机流程 -// if (Util.isNeedRestored) { -// Log.d("IOSTQ:", "执行留存任务") -// Util.setRrInfo(this) -// } else { -// Log.d("IOSTQ:", "执行新装任务") -// Util.setInfo(this) -// } -// ChangeDeviceInfoUtil.changeDeviceInfo() ChangeDeviceInfoUtil.changeDevice(callBack = object : ChangeCallBack { override fun changeSuccess() { - Util.openRecordApp(this@OpenAppService) + runCatching { + if (Util.isCanAuto && Util.canAutoLc.isNotEmpty()) { + val deviceInfo = DeviceDataAccessor.getDeviceInfo(applicationContext, DeviceInfoHelper.getDeviceId()) + FileUtils.writePackageName(Util.recordPackageName?:"") + FileUtils.writeDevice(Util.recordPackageName?:"", deviceInfo?: "") + FileUtils.runPlugin(Util.recordPackageName?:"") + MockTools.exec("pm grant ${Util.AUTO_JSPACKAGENAME} android.permission.READ_EXTERNAL_STORAGE") //sdcard权限 + MockTools.exec("pm grant ${Util.AUTO_JSPACKAGENAME} android.permission.SYSTEM_ALERT_WINDOW") //悬浮窗权限 + MockTools.exec("settings put secure enabled_accessibility_services ${Util.AUTO_JSPACKAGENAME}/${Util.AUTO_JSPACKAGENAME}.core.accessibility.AccessibilityService") + Util.doScript(this@OpenAppService, Util.AUTO_JSPACKAGENAME) //autojs + }else { + Util.setFinish(this@OpenAppService) + } + }.onFailure { + it.printStackTrace() + Util.setFinish(this@OpenAppService) + } } override fun changeFailed() { @@ -51,6 +56,7 @@ class OpenAppService : JobIntentService() { }) } catch (e: IOException) { e.printStackTrace() + Util.setFinish(this@OpenAppService) } // Util.hookOpenApp(this); } diff --git a/app/src/main/java/com/android/grape/job/SendCallbackJobService.kt b/app/src/main/java/com/android/grape/job/SendCallbackJobService.kt index ce1b4b5..9606d87 100644 --- a/app/src/main/java/com/android/grape/job/SendCallbackJobService.kt +++ b/app/src/main/java/com/android/grape/job/SendCallbackJobService.kt @@ -199,11 +199,11 @@ class SendCallbackJobService : JobIntentService() { file1 = File(fileName1) } - Util.chownSh(this, fileName, Util.getMainUserAndGroup(this)) - var url = "http://192.168.1.111/tt/ddj/backup.do" - if (Util.backUpServerIp != "") { - url = "http://" + Util.backUpServerIp + "/tt/ddj/backup.do" - } + Util.chownSh(fileName, Util.getMainUserAndGroup(this)) + var url = "http://39.103.73.250/tt/ddj/backup.do" +// if (Util.backUpServerIp != "") { +// url = "http://" + Util.backUpServerIp + "/tt/ddj/backup.do" +// } LogUtils.i(TAG, "sendBackupEvent-> file length = " + file.length()) try { diff --git a/app/src/main/java/com/android/grape/job/UnInstallService.kt b/app/src/main/java/com/android/grape/job/UnInstallService.kt index 350de54..b642e22 100644 --- a/app/src/main/java/com/android/grape/job/UnInstallService.kt +++ b/app/src/main/java/com/android/grape/job/UnInstallService.kt @@ -1,20 +1,20 @@ package com.android.grape.job +import android.app.ActivityManager import android.content.Context import android.content.Intent import androidx.core.app.JobIntentService import com.android.grape.util.MockTools import com.android.grape.util.Util +import com.blankj.utilcode.util.LogUtils class UnInstallService : JobIntentService() { override fun onHandleWork(intent: Intent) { - Util.backUp(this) Util.setInstallRet(true) MockTools.exec("pm clear " + Util.recordPackageName) Util.delFiles(this@UnInstallService) - Util.setFinish(this@UnInstallService) } diff --git a/app/src/main/java/com/android/grape/provider/DeviceDataAccessor.kt b/app/src/main/java/com/android/grape/provider/DeviceDataAccessor.kt index 697c943..80ccbc8 100644 --- a/app/src/main/java/com/android/grape/provider/DeviceDataAccessor.kt +++ b/app/src/main/java/com/android/grape/provider/DeviceDataAccessor.kt @@ -3,13 +3,16 @@ package com.android.grape.provider import android.content.ContentValues import android.content.Context import android.net.Uri +import android.util.Log import com.android.grape.data.Device +import com.blankj.utilcode.util.LogUtils // DeviceDataAccessor.kt object DeviceDataAccessor { // 保存设备信息到提供方 fun saveDeviceInfo(context: Context, device: Device): Uri? { + LogUtils.d("TAG", "saveDeviceInfo: ${device.toJson()}") val resolver = context.contentResolver val actualDeviceId = DeviceInfoHelper.getDeviceId() diff --git a/app/src/main/java/com/android/grape/service/SocketServer.kt b/app/src/main/java/com/android/grape/service/SocketServer.kt new file mode 100644 index 0000000..db7a6ce --- /dev/null +++ b/app/src/main/java/com/android/grape/service/SocketServer.kt @@ -0,0 +1,79 @@ +package com.android.grape.service + +import android.util.Log +import java.io.BufferedReader +import java.io.InputStreamReader +import java.io.PrintWriter +import java.net.ServerSocket +import java.net.Socket + +class SocketServer(private val port: Int = 8888) { + private var serverSocket: ServerSocket? = null + private var running = false + private val clients = mutableListOf() + private var messageListener: ((Socket, String) -> Unit)? = null + + fun start(listener: (Socket, String) -> Unit) { + messageListener = listener + running = true + + Thread { + try { + serverSocket = ServerSocket(port) + Log.d("SocketServer", "服务器已启动,监听端口: $port") + + while (running) { + val clientSocket = serverSocket?.accept() + clientSocket?.let { + Log.d("SocketServer", "客户端已连接: ${it.inetAddress.hostAddress}") + clients.add(it) + handleClient(it) + } + } + } catch (e: Exception) { + Log.e("SocketServer", "服务器错误", e) + } + }.start() + } + + private fun handleClient(clientSocket: Socket) { + Thread { + try { + val reader = BufferedReader(InputStreamReader(clientSocket.getInputStream())) + + while (running) { + val message = reader.readLine() ?: break + messageListener?.invoke(clientSocket, message) + } + } catch (e: Exception) { + Log.e("SocketServer", "客户端处理错误", e) + } finally { + clients.remove(clientSocket) + clientSocket.close() + } + }.start() + } + + fun sendToClient(clientSocket: Socket, message: String) { + try { + PrintWriter(clientSocket.getOutputStream(), true).println(message) + } catch (e: Exception) { + Log.e("SocketServer", "发送消息失败", e) + } + } + + fun broadcast(message: String) { + clients.forEach { sendToClient(it, message) } + } + + fun stop() { + running = false + clients.forEach { it.close() } + clients.clear() + try { + serverSocket?.close() + } catch (e: Exception) { + Log.e("SocketServer", "关闭服务器错误", e) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/grape/util/ChangeDeviceInfoUtil.kt b/app/src/main/java/com/android/grape/util/ChangeDeviceInfoUtil.kt index c96fc44..2eeb851 100644 --- a/app/src/main/java/com/android/grape/util/ChangeDeviceInfoUtil.kt +++ b/app/src/main/java/com/android/grape/util/ChangeDeviceInfoUtil.kt @@ -8,7 +8,7 @@ import com.android.grape.data.Device import com.android.grape.net.Api import com.android.grape.net.ChangeCallBack import com.android.grape.provider.DeviceDataAccessor -import com.android.grape.util.Util.paramsJson +import com.android.grape.util.Util.taskJson import com.blankj.utilcode.util.LogUtils import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -23,12 +23,14 @@ object ChangeDeviceInfoUtil { val scope = CoroutineScope(Dispatchers.IO) fun changeDevice(callBack: ChangeCallBack){ try { - val deviceObject = paramsJson?.getJSONObject("device") + val deviceObject = taskJson?.getJSONObject("device") if (deviceObject == null) { LogUtils.d("ERROR", "ChangeDeviceInfoUtil", "device is null") return } val device = GsonUtils.fromJsonObject(deviceObject.toString(), Device::class.java) + device.sensor = deviceObject.optJSONArray("sensor")?:JSONArray() + LogUtils.d("DeviceSensor---->${device.sensor}") DeviceDataAccessor.saveDeviceInfo(MainApplication.instance, device) val padCode = ShellUtils.execRootCmdAndGetResult("getprop ro.boot.pad_code") Log.d("TAG", "changeDevice: $padCode") @@ -162,6 +164,8 @@ object ChangeDeviceInfoUtil { } } } + }else{ + callBack.changeFailed() } } catch (e: JSONException) { e.printStackTrace() @@ -174,7 +178,7 @@ object ChangeDeviceInfoUtil { MockTools.exec("pm grant com.android.grape android.permission.INTERACT_ACROSS_USERS") MockTools.exec("pm grant com.android.grape android.permission.WRITE_SECURE_SETTINGS") MockTools.exec("pm setenforce 0") - val deviceObject = paramsJson?.getJSONObject("device") + val deviceObject = taskJson?.getJSONObject("device") if (deviceObject == null) { LogUtils.d("ERROR", "ChangeDeviceInfoUtil", "device is null") return diff --git a/app/src/main/java/com/android/grape/util/FileUtils.kt b/app/src/main/java/com/android/grape/util/FileUtils.kt index 81ad933..b983225 100644 --- a/app/src/main/java/com/android/grape/util/FileUtils.kt +++ b/app/src/main/java/com/android/grape/util/FileUtils.kt @@ -1,6 +1,7 @@ package com.android.grape.util import android.os.Environment +import android.util.Base64 import android.util.Log import com.blankj.utilcode.util.LogUtils import java.io.BufferedInputStream @@ -417,4 +418,28 @@ object FileUtils { // 6. 可以考虑添加重试机制或通知用户 } } + + fun writeDevice(packageName: String, device: String) { + LogUtils.d("TAG", "writeDevice: $device") + val base64Content: String = + Base64.encodeToString(device.toByteArray(StandardCharsets.UTF_8), Base64.NO_WRAP) + // 构造安全命令 + val filePath = "/data/data/$packageName/device.txt" + val cmd = "sh -c 'printf %s '\''" + base64Content + "'\'' > " + filePath + "'" + val result = ShellUtils.execRootCmdAndGetResult(cmd) + ShellUtils.execRootCmdAndGetResult("chmod 777 $filePath") + LogUtils.d("TAG", "writeDevice: $result") + } + + fun runPlugin(packageName: String){ + val cmd = "apmt patch add -n ArmCloudAF -p $packageName -f /sdcard/Download/ArmCloudAF_lo.apk" + val result = ShellUtils.execRootCmdAndGetResult(cmd) + LogUtils.d("TAG", "runPlugin: $result") + } + + fun deletePlugin(){ + val cmd = "apmt patch del -n ArmCloudAF" + val result = ShellUtils.execRootCmdAndGetResult(cmd) + LogUtils.d("TAG", "deletePlugin: $result") + } } \ No newline at end of file diff --git a/app/src/main/java/com/android/grape/util/ScriptUtil.kt b/app/src/main/java/com/android/grape/util/ScriptUtil.kt index 8c3b9b9..af2ad97 100644 --- a/app/src/main/java/com/android/grape/util/ScriptUtil.kt +++ b/app/src/main/java/com/android/grape/util/ScriptUtil.kt @@ -19,6 +19,7 @@ object ScriptUtil { var scriptResultReceiver: BroadcastReceiver? = null fun execScript(context: Context, src: String) { if (!isAppInstalled("org.autojs.autojs6")) { + LogUtils.e("AutoJsUtil", "Auto.js app not installed") runOnUiThread { Toast.makeText(context, "Auto.js app not installed", Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/com/android/grape/util/Util.kt b/app/src/main/java/com/android/grape/util/Util.kt index fe2fa9e..f9a55a2 100644 --- a/app/src/main/java/com/android/grape/util/Util.kt +++ b/app/src/main/java/com/android/grape/util/Util.kt @@ -392,7 +392,7 @@ object Util { * @param groupanduser组和用户以“组:用户”的形式 * @return true如果操作成功,则否则为否则 */ - fun chownSh(context: Context?, dir: String?, groupAndUser: String?): Boolean { + fun chownSh(dir: String?, groupAndUser: String?): Boolean { try { val cmd = "chown -R $groupAndUser $dir" Log.i(TAG, "chownSh cmd:$cmd") @@ -469,9 +469,9 @@ object Util { MockTools.exec(cmd) val uid = getPackageUserID( context, - recordPackageName!! + recordPackageName?:"" ) - chownSh(context, getMonitorDir(context), uid) + chownSh(getMonitorDir(context), uid) return true } catch (e: Exception) { e.printStackTrace() @@ -733,16 +733,10 @@ object Util { */ fun execInstallTask(context: Context) { init() - // adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context); val url = "http://39.103.73.250/tt/ddj/preRequest!requestInstall.do" - - // String params = "platform=Android&tag="+getTag(context)+"&uuid="+PrefUtil.getUUID(context); - val ANDROID_ID = - Settings.System.getString(context.contentResolver, Settings.System.ANDROID_ID) + val ANDROID_ID = Settings.System.getString(context.contentResolver, Settings.System.ANDROID_ID) val params = "platform=Android&tag=119&uuid=$ANDROID_ID" - //+ "&id=515382023"; -// boolean valid = false; printStr("IOSTQ:request result : $url?$params") try { val result: String? = MyPost.postData(" ".toByteArray(charset = Charsets.UTF_8), @@ -754,8 +748,7 @@ object Util { if (result != null && result.isNotEmpty()) { taskJson = JSONObject(result) - val code = taskJson!!.getInt("code") - + val code = taskJson?.getInt("code") if (code == 1) { MockTools.exec("chmod 777 /data/data/com.android.grape/files/monitor") MockTools.exec("chmod 777 /data/data/com.android.grape/files/monitor/apks") @@ -783,7 +776,7 @@ object Util { */ fun execTask(context: Context) { nRandom++ - + FileUtils.deletePlugin() if (nRandom % 3 == 0) { execReloginTask(context) } else { @@ -919,13 +912,11 @@ object Util { } if (it.has("recordId") && !it.isNull("recordId")) { - recordId = - it.getLong("recordId") + recordId = it.getLong("recordId") } if (it.has("preClickRecordId") && !it.isNull("preClickRecordId")) { - preClickRecordId = - it.getLong("preClickRecordId") + preClickRecordId = it.getLong("preClickRecordId") } if (it.has("device") && !it.isNull("device")) { @@ -995,17 +986,14 @@ object Util { } if (it.has("needReg") && !it.isNull("needReg")) { - isNeedReg = - it.getBoolean("needReg") + isNeedReg = it.getBoolean("needReg") } if (it.has("isExecScript") && !it.isNull("isExecScript")) { - isCanAuto = - it.getInt("isExecScript") > 0 + isCanAuto = it.getInt("isExecScript") > 0 if (it.has("ExecScriptZipURL") && !it.isNull("ExecScriptZipURL")) { - canAutoLc = - it.getString("ExecScriptZipURL") + canAutoLc = it.getString("ExecScriptZipURL") } } @@ -1069,6 +1057,8 @@ object Util { try { taskJson?.let { val deviceJo = it.getJSONObject("device") + LogUtils.e("deviceJo:$deviceJo") + LogUtils.e("deviceJo sensor:${deviceJo.optJSONArray("sensor")}") val deviceParamJo: JSONObject = DeviceConvertUtil.MGConvert(deviceJo) if (it.has("isCollectURL")) { deviceJo.put("isCollectURL", true) @@ -1133,13 +1123,9 @@ object Util { val script_url = "http://39.103.73.250/tt/" + canAutoLc isDownload = downloadFile(script_url, script_path) if (!isDownload) { - Log.i( - TAG, - "execDownScript isDownload : $isDownload" - ) + Log.i(TAG, "execDownScript isDownload : $isDownload") return false } - unzipAPkSh(script_path, "/sdcard/script/") delFileSh(script_path) } @@ -1153,52 +1139,37 @@ object Util { fun execDownloadApp(context: Context): Boolean { try { - var url = "" - - url = if (videoProxy.startsWith("http://39.103.73.250")) { - videoProxy + "/ddj/" + recordFileName - } else { - // url = videoProxy + "/ddj/" + Util.getRecordPackageName() + ".apk"; - videoProxy + "/ddj/" + recordFileName - } - url = "http://39.103.73.250/tt/upload/ddj/" + recordFileName - // if(getRecordPackageName().equals("com.zhiliaoapp.musically")) { -// url = "http://192.168.30.201:5000/static/com.zhiliaoapp.musically_24.7.5.xapk"; -// } + var url = "http://39.103.73.250/tt/upload/ddj/$recordFileName" var ret = false - ret = if (checkAppInstalled( - context, - recordPackageName - ) || !CheckAppNeedUpgrade(context) - ) { + ret = if (checkAppInstalled(context, recordPackageName) || !CheckAppNeedUpgrade(context)) { true } else { - // ret = downloadFile(url, Util.getRecordApkVerFileName(context)); - downloadFile(url, "/sdcard/apks/" + recordFileName) + downloadFile(url, "/sdcard/apks/$recordFileName") } if (ret) { Log.i(TAG, "download apk succ") - Log.i(TAG, "recordExtraFileName:" + recordExtraFileName) - if (recordExtraFileName != null && recordExtraFileName!!.length > 0) { - val extraUrl = videoProxy + "/ddj/" + recordExtraFileName - + Log.i(TAG, "recordExtraFileName:$recordExtraFileName") + if (recordExtraFileName?.isNotEmpty() == true) { + val extraUrl = "$videoProxy/ddj/$recordExtraFileName" ret = downloadFile(extraUrl, getRecordExtraFileName(context)) } if (isNeedRestored) { println("IOSTQ:开始下载留存文件") - if (taskJson!!.has("BackupFileUrl1") && taskJson!!.getString("BackupFileUrl1").length > 0) { - var restored_zip = - "http://192.168.1.111/tt/" + taskJson!!.getString("BackupFileUrl1") - if (backUpServerIp != "") { - restored_zip = - "http://" + backUpServerIp + "/tt/" + taskJson!!.getString("BackupFileUrl1") + taskJson?.let { + if (it.has("BackupFileUrl1") && it.getString("BackupFileUrl1").isNotEmpty()) { + var restored_zip = "http://192.168.1.111/tt/" + it.getString("BackupFileUrl1") + if (backUpServerIp.isNotEmpty()) { + restored_zip = "http://" + backUpServerIp + "/tt/" + it.getString("BackupFileUrl1") + } + ret = downloadFile(restored_zip, getRecordDataFileName(context)) } - ret = downloadFile(restored_zip, getRecordDataFileName(context)) + } + if (taskJson == null){ + ret = false } } } - return ret } catch (e: Exception) { e.printStackTrace() @@ -1287,18 +1258,6 @@ object Util { writer.write(message) writer.close() - - // FileOutputStream fos = new FileOutputStream(file); -// long sum = 0; -// int lenght = 0; -// fos.write(message.getBytes(StandardCharsets.UTF_8), 0, message.length()); -// fos.flush(); -// fos.close(); - // String dstPath = "/data/data/"+ Util.getRecordPackageName() + "/" + Util.getRecordPackageName()+ "_device.txt"; - // Util.copyFileSh(AppPath +"device.txt",dstPath); - - //give777(dstPath); - // CmdUtils.chmodFilePermission(dstPath); Log.d("文件写入", "成功") } @@ -1492,12 +1451,6 @@ object Util { } fun getBaseFilesDir(context: Context): String { -// File dir = context.getExternalFilesDir(null); -// if(dir == null) { -// return "/sdcard/Android/data/" + context.getPackageName() + "/files"; -// }else{ -// return dir.getAbsolutePath(); -// } return context.filesDir.absolutePath } @@ -1539,13 +1492,11 @@ object Util { } private fun execHookApp(context: Context) { - val intent = Intent(Intent.ACTION_MAIN) - - if (intent != null) { + val intent = Intent(Intent.ACTION_MAIN).apply { val cname = ComponentName(hookPackageName, hookAppMainClass) - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - intent.setComponent(cname) - context.startActivity(intent) + setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + setComponent(cname) + context.startActivity(this) } } @@ -1587,12 +1538,12 @@ object Util { fun doScript(context: Context, targetPackageName: String): Boolean { - execTargetApp(context, targetPackageName) - try { - Thread.sleep(3000L) - } catch (e: InterruptedException) { - e.printStackTrace() - } +// execTargetApp(context, targetPackageName) +// try { +// Thread.sleep(3000L) +// } catch (e: InterruptedException) { +// e.printStackTrace() +// } Handler(Looper.getMainLooper()).postDelayed(Runnable { //开始执行脚本 AutoJobService.onEvent(context) }, 1) @@ -1848,7 +1799,7 @@ object Util { try { val file = File(getRecordSdcardApkVerFileName(context)) var extraFile: File? = null - if (recordExtraFileName != null && recordExtraFileName!!.length > 0) { + if (recordExtraFileName?.isNotEmpty() == true) { extraFile = File(getRecordExtraFileName(context)) } @@ -1870,7 +1821,7 @@ object Util { Log.i(TAG, "installRet:$installRet") } else { installRet = true - MockTools.exec("pm clear " + recordPackageName) + MockTools.exec("pm clear $recordPackageName") } @@ -1925,34 +1876,34 @@ object Util { val zipFile = getRecordDataFileName(context) val reloginDataDir = getApkDataDir( context, - recordPackageName!! + recordPackageName?:return false ) Log.i( TAG, "recoverRecordData: dir=$reloginDataDir" ) + if (reloginDataDir == null){ + return false + } - // ZipUtils1.upZipFile(new File(zipFile), dataDir+"/"); unZipFileSh(zipFile, dataDir) val userAnGroup = getUserAndGroupSh(context) - Log.i( - TAG, - "recoverRecordData->userAndGroup:$userAnGroup" - ) - - copyFolderSh( - dataDir + "/" + recordPackageName, - File(reloginDataDir).parentFile.absolutePath - ) + Log.i(TAG, "recoverRecordData->userAndGroup:$userAnGroup") + File(reloginDataDir).parentFile?.absolutePath?.let { + copyFolderSh( + "$dataDir/$recordPackageName", + it + ) + } delFilesSh( dataDir, recordPackageName ) - chownSh(context, reloginDataDir, userAnGroup) + chownSh(reloginDataDir, userAnGroup) return true } catch (e: Exception) { @@ -1999,10 +1950,7 @@ object Util { } fun copyFolderSh(oldPath: String, newPath: String): Boolean { - Log.i( - TAG, - "start copyFolderSh : $oldPath ; $newPath" - ) + Log.i(TAG, "start copyFolderSh : $oldPath ; $newPath") try { val cmd = "cp -r -f $oldPath $newPath" @@ -2016,10 +1964,7 @@ object Util { } fun copyFileSh(oldPath: String, newPath: String): Boolean { - Log.i( - TAG, - "start copyFileSh : $oldPath ; $newPath" - ) + Log.i(TAG, "start copyFileSh : $oldPath ; $newPath") try { val cmd = "cp -r -f $oldPath $newPath" MockTools.exec(cmd) @@ -2214,7 +2159,7 @@ object Util { fileOutputStream.write(buffer, 0, byteRead) } - chownSh(context, "/sdcard/Android/obb/" + recordPackageName + "/", userAndGroup) + chownSh("/sdcard/Android/obb/" + recordPackageName + "/", userAndGroup) } catch (e: Exception) { if (fileInputStream != null) { try { @@ -2297,24 +2242,6 @@ object Util { return false } - private fun hasRootPerssion(): Boolean { - var PrintWriter: PrintWriter? = null - var process: Process? = null - try { - process = Runtime.getRuntime().exec("su") - PrintWriter = PrintWriter(process.outputStream) - PrintWriter.flush() - PrintWriter.close() - val value = process.waitFor() - return returnResult(value) - } catch (e: Exception) { - e.printStackTrace() - } finally { - process?.destroy() - } - return false - } - private fun returnResult(value: Int): Boolean { // 代表成功 return if (value == 0) { @@ -2357,7 +2284,6 @@ object Util { "start to clientUninstall : $packageName" ) try { -// String cmd = "LD_LIBRARY_PATH=/vendor/lib:/system/lib" + "|"; val cmd = "pm uninstall $packageName" MockTools.exec(cmd) return true @@ -2397,10 +2323,8 @@ object Util { } fun setFinish(context: Context) { - // Log.i(TAG, "setFinish"); - + Log.i(TAG, "setFinish") MonitorService.setRunning(false) -// killRecordProcess(context, "com.tunnelworkshop.postern") killRecordProcess(context, AUTO_JSPACKAGENAME) Handler(Looper.getMainLooper()).postDelayed(Runnable { MonitorService.onEvent( @@ -2587,7 +2511,7 @@ object Util { if (taskInfo.baseActivity?.packageName == context.packageName) { // Log.i(TAG, "setTopApp exec"); activityManager.moveTaskToFront(taskInfo.id, 0) - checkFloatPermission(context) +// checkFloatPermission(context) break } } @@ -2740,62 +2664,46 @@ object Util { * @param packageName 将备份数据的软件包的名称。 * @return 如果备份成功,则创建的zip文件的绝对路径,如果该过程失败,则为null。 */ - fun backupDataFile(context: Context, packageName: String): String? { + fun backupDataFile(context: Context, packageName: String?): String? { Log.i(TAG, "start backUpDataFile : $packageName") + if (packageName == null){ + return null + } try { val zipDirName = getBaseFilesDir(context) + "/" + monitorDir + "/" + packageName - val zipFileName = - getBaseFilesDir(context) + "/" + monitorDir + "/" + packageName + ".zip" - Log.i( - TAG, - "backupDataFile-> zipDirName:$zipDirName ; zipFileName:$zipFileName" - ) + val zipFileName = getBaseFilesDir(context) + "/" + monitorDir + "/" + packageName + ".zip" + Log.i(TAG, "backupDataFile-> zipDirName:$zipDirName ; zipFileName:$zipFileName") val zipFile = File(zipFileName) forceMakeDir(File(getRecordDataDirName(context))) if (!zipFile.exists()) { val zipDir = File(zipDirName) forceMakeDir(zipDir) - //TODO:获取apk包所在的文件夹 val apkDataPath = context.packageManager.getApplicationInfo(packageName, 0).dataDir - Log.i( - TAG, - "backupDataFile->apkDataPath=$apkDataPath" - ) - + Log.i(TAG, "backupDataFile->apkDataPath=$apkDataPath") listSh(context, apkDataPath) val file = File(getRecordListTxtFileName(context)) if (file.exists()) { val ss = getStringFromFile(context, file.absolutePath) - - if (ss != null && ss.length > 0) { - val arr = - ss.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - + if (ss.isNotEmpty()) { + val arr = ss.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() for (line in arr) { Log.i(TAG, "line:$line") - val blankPos = line.lastIndexOf(" ") val fn = line.substring(blankPos + 1) - copyFileSh( - "$apkDataPath/$fn", - "$zipDirName/" - ) + copyFileSh("$apkDataPath/$fn", "$zipDirName/") } } } val uid = getUserAndGroupSh(context.applicationContext) - chownSh(context, getMonitorDir(context), uid) + chownSh(getMonitorDir(context), uid) val copySucc = File(zipDirName).exists() - Log.i( - TAG, - "copyFolder($apkDataPath,$zipDirName) = $copySucc" - ) + Log.i(TAG, "copyFolder($apkDataPath,$zipDirName) = $copySucc") //TODO:将apk包所在的文件夹备份到DownLoad文件夹下 //TODO:将新生成的文件夹进行压缩 if (copySucc) { - chownSh(context, zipDirName, getMainUserAndGroup(context)) + chownSh(zipDirName, getMainUserAndGroup(context)) val afFile = File("$zipDirName/AFPOST.txt") zipSh(zipDirName, zipFileName) @@ -2972,7 +2880,7 @@ object Util { */ fun backUp(context: Context) { killRecordProcess(context) - backUp(context, recordPackageName!!) + backUp(context, recordPackageName) } /** @@ -3012,7 +2920,7 @@ object Util { * @param上下文执行备份操作的上下文 * @param packageName备份数据的软件包的名称 */ - fun backUp(context: Context, packageName: String) { + fun backUp(context: Context, packageName: String?) { backFileName = backupDataFile(context, packageName) if (isNeedBackup) { // Util.backFileName1 = Util.backupDataFile1(context, packageName); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 72cec8a..e2efdf2 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,7 +6,14 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> - +