Coldnight
Coldnight

Reputation: 137

Android app crashing after executing exec commands

I have following code, which is used for auto update of app, which is installed like system app on rooted device. It starts from copyToPrivateApps with already downloaded new apk file. It is attached to IO thread from corutine scope

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()}

It fails inside sudoForResult(), on val su = Runtime.getRuntime().exec("su") when trying to execute "cp" command with following error: A/libc: Fatal signal 4 (SIGILL), code 1, fault addr 0x7f6190fa24 in tid 6974 (DefaultDispatch)

and some strange warning

W/art: Failed 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=default --dex-file=/system/priv-app/appName/appName.apk --oat-file=/data/dalvik-cache/arm64/system@priv-app@[email protected]@classes.dex) because non-0 exit status

Sometimes it crash even earlier on "cat" command with similar error

EDIT: This was working before with smaller update apk file, now it is almost 3x bigger.

Upvotes: 0

Views: 196

Answers (1)

Zeta
Zeta

Reputation: 46

try this:

sudoForCommandAndResult("chmod +x $systemFolder")
sudoForCommandAndResult("chmod +x $systemApkPath")
//change cat command with dd if
sudoForCommandAndResult("dd if=$apkPath of=$systemApkPath")

Upvotes: 0

Related Questions