执行 exec 命令后 Android 应用程序崩溃
Posted
技术标签:
【中文标题】执行 exec 命令后 Android 应用程序崩溃【英文标题】:Android app crashing after executing exec commands 【发布时间】:2021-02-18 07:22:14 【问题描述】:我有以下代码,用于自动更新应用程序,它像系统应用程序一样安装在有根设备上。它从已下载新 apk 文件的 copyToPrivateApps 开始。它从协程范围附加到 IO 线程
fun copyToPrivateApps(context: Context, apkPath: String?)
sudoForCommandAndResult("mount -o rw,remount /system")
sudoForCommandAndResult("mkdir $systemFolder")
sudoForCommandAndResult("cat $apkPath > $systemApkPath")
sudoForCommandAndResult("cp -R $sudoForResult("find ./data/app -name $context.packageName*").drop(1) + "/lib" $systemFolder")
sudoForCommandAndResult("chmod -R 755 $systemFolder")
sudoForCommandAndResult("chmod 644 $systemFngFolder")
sudoForCommandAndResult("chmod 644 $systemSilFolder")
sudoForCommandAndResult("chmod 644 $systemApkPath")
sudoForCommandAndResult("mount -o ro,remount /system")
fun sudoForCommandAndResult(string: String): String
var res = ""
var outputStream: DataOutputStream? = null
var response : InputStream? = null
var error : InputStream? = null
try
val su = Runtime.getRuntime().exec("su")
outputStream = DataOutputStream(su.outputStream)
response = su.inputStream
error = su.errorStream
outputStream.writeBytes(string + "\n")
outputStream.flush()
outputStream.writeBytes("exit\n")
outputStream.flush()
try
su.waitFor()
catch (e: Throwable)
e.printStackTrace()
val responseString = readFully(response!!).replace("su:main", "").trim()
val errorString = readFully(error!!).replace("su:main", "").trim()
res = logTimeFormat.format(Date()) + string + if(responseString.isNotBlank()) "\n" + logTimeFormat.format(Date()) + responseString else ""
res += if(errorString.isNotBlank()) "\n" + logTimeFormat.format(Date()) + errorString else ""
catch (e: Throwable)
res += logTimeFormat.format(Date()) + e.message?.trim()
e.printStackTrace()
finally
Closer.closeSilently(outputStream, response)
return res
fun sudoForResult(string: String): String
var res = ""
var outputStream: DataOutputStream? = null
var response : InputStream? = null
var error : InputStream? = null
try
val su = Runtime.getRuntime().exec("su")
outputStream = DataOutputStream(su.outputStream)
response = su.inputStream
error = su.errorStream
outputStream.writeBytes(string + "\n")
outputStream.flush()
outputStream.writeBytes("exit\n")
outputStream.flush()
try
su.waitFor()
catch (e: Throwable)
e.printStackTrace()
val responseString = readFully(response!!).replace("su:main", "").trim()
val errorString = readFully(error!!).replace("su:main", "").trim()
res = listOf(responseString, errorString).joinToString(separator = " ")
catch (e: Throwable)
res += e.message?.trim()
e.printStackTrace()
finally
Closer.closeSilently(outputStream, response)
return res.trim()
尝试执行“cp”命令时,在 val su = Runtime.getRuntime().exec("su") 内 sudoForResult() 失败 出现以下错误: A/libc:致命信号 4 (SIGILL),代码 1,tid 6974 中的故障地址 0x7f6190fa24 (DefaultDispatch)
还有一些奇怪的警告
W/art: 失败的 execv(/system/bin/dex2oat --runtime-arg -classpath --runtime-arg --instruction-set=arm64 --instruction-set-features=smp,a53 --runtime- arg -Xrelocate --boot-image=/system/framework/boot.art --runtime-arg -Xms64m --runtime-arg -Xmx512m -j3 --instruction-set-variant=generic --instruction-set-features=默认 --dex-file=/system/priv-app/appName/appName.apk --oat-file=/data/dalvik-cache/arm64/system@priv-app@appName@appName.apk@classes.dex)因为非0退出状态
有时它甚至更早在“cat”命令上崩溃并出现类似错误
编辑:这在以前使用较小的更新 apk 文件时有效,现在它几乎大了 3 倍。
【问题讨论】:
【参考方案1】:试试这个:
sudoForCommandAndResult("chmod +x $systemFolder")
sudoForCommandAndResult("chmod +x $systemApkPath")
//change cat command with dd if
sudoForCommandAndResult("dd if=$apkPath of=$systemApkPath")
【讨论】:
是的,它应该拥有所有需要的权限,因为它以前可以工作 @Tomerikoo 是的,我想发表评论,但我应该有 50 个代表。为什么你放弃投票以上是关于执行 exec 命令后 Android 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
system函数与exec函数区别(system需先启动一个shell才能运行指定命令,调用system函数执行指定命令,原进程等待,之后继续运行;调用exec函数开启新进程后,原进程将被直接关闭)