package com.example.modifier import android.util.Log import androidx.core.content.ContextCompat import com.example.modifier.utils.createFakeSms import com.example.modifier.utils.getContext import com.example.modifier.utils.shellRun import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.apache.commons.io.FileUtils import org.apache.commons.io.IOUtils import java.io.File import java.util.Base64 class Frida { companion object { var p: Process? = null var script: File? = null suspend fun start() { if (p != null) { p!!.destroy() p = null } if (script != null) { script!!.delete() script = null } val context = getContext() val dataDir = ContextCompat.getDataDir(context) Utils.copyAssetFolder(context.assets, "bin", File(dataDir, "bin").path) val binPath = File(dataDir, "bin/frida-inject-16.3.3-android-arm64").path val (pid, _) = shellRun("pidof com.android.phone") if (!Regex("[0-9]+").matches(pid)) { return } val scriptContent = IOUtils.toString(context.assets.open("scripts/phone.js"), "UTF-8") withContext(Dispatchers.IO) { script = File.createTempFile("script", ".js") FileUtils.writeStringToFile(script, scriptContent, "UTF-8") Log.i(com.example.modifier.baseTag, "start: $binPath -p $pid -s $script") p = Runtime.getRuntime().exec("su -M") p!!.outputStream.bufferedWriter().use { it.write("chmod +x $binPath") it.newLine() it.flush() it.write("$binPath -p $pid -s $script") it.newLine() it.flush() } coroutineScope { launch { try { p!!.inputStream .bufferedReader() .useLines { lines -> lines.forEach { Log.i(com.example.modifier.baseTag, it) } } } catch (e: Exception) { e.printStackTrace() } } launch { try { p!!.errorStream .bufferedReader() .useLines { lines -> lines.forEach { Log.e(com.example.modifier.baseTag, it) } } } catch (e: Exception) { e.printStackTrace() } } } } } fun stop() { if (p != null) { p!!.inputStream.close() p!!.errorStream.close() p!!.destroy() p = null } if (script != null) { script!!.delete() script = null } } } } suspend fun sendSmsFrida(sender: String, msg: String) { val context = getContext() try { val dataDir = ContextCompat.getDataDir(context) Utils.copyAssetFolder(context.assets, "bin", File(dataDir, "bin").path) val binPath = File(dataDir, "bin/frida-inject-16.3.3-android-arm64").path val pduBase64 = String(Base64.getEncoder().encode(createFakeSms(sender, msg))) Log.i("Modifier", "pduBase64: $pduBase64") val script = IOUtils.toString(context.assets.open("scripts/sms.js"), "UTF-8") .replace("{pduBase64}", pduBase64) val tmpFile: File withContext(Dispatchers.IO) { tmpFile = File.createTempFile("script", ".js") FileUtils.writeStringToFile(tmpFile, script, "UTF-8") } val pid = shellRun("pidof com.android.phone").first.trim() if (!Regex("[0-9]+").matches(pid)) { return } Log.i("Modifier", "sendSms: $binPath -p $pid -s $tmpFile") val p = withContext(Dispatchers.IO) { Runtime.getRuntime().exec("su -M") } p.outputStream.bufferedWriter().use { it.write("chmod +x $binPath") it.newLine() it.flush() it.write("$binPath -p $pid -s $tmpFile") it.newLine() it.flush() } coroutineScope { launch { p.errorStream.bufferedReader().useLines { lines -> lines.forEach { Log.e("Modifier", it) } } } launch { p.inputStream .bufferedReader() .useLines { lines -> lines.forEach { Log.i("Modifier", it) if (it == "OK") { p.inputStream.close() p.errorStream.close() p.destroy() } } } } } withContext(Dispatchers.IO) { p.waitFor() } } catch (e: Exception) { e.printStackTrace() } }