从 PHP 执行 adb shell 并转义字符串

Executing adb shell from PHP and escaping strings

我正在尝试将有效的 bash 脚本转换为 PHP 代码。

#!/bin/bash
phonenumber=""
message=""

# check the args...
# double quotes inside $message must be escaped. Also prevents code injection.
message=${message//\"/\\"}

adb shell "am startservice --user 0 -n com.android.shellms/.sendSMS -e \"contact\" $phonenumber -e msg \"$message\""

上面的代码有效。 在 PHP 中,当消息包含新行时,下一个代码不起作用:

function sendsms ($m, $to, $n) {
    echo "About to sent an sms to $to [$n]\n";

    // escape some chars in $m
    $m = addslashes($m);

    adb_shell_exec ("am startservice --user 0 -n com.android.shellms/.sendSMS -e contact \"$to\" -e msg \"$m\"");

}

function adb_shell_exec ($s) {
    shell_exec("adb shell " . addslashes ($s));
}

我收到消息错误:

       $ php -r "require 'sim-android-v8.php'; sendsms('Message with one double \" quote final solution
       and new line','+32*******31','Pierre François');"
       About to sent an sms to +32*******31 [Pierre François]
       /system/bin/sh: no closing quote
       sh: 2: and: not found

我不明白为什么它在 bash 中有效,但在 PHP 中无效。

相同的bash脚本

function sendsms ($m, $to, $n) {
echo "About to sent an sms to $to [$n]\n";

$m = escapeshellarg(addslashes($m)); // use escape for shell
$to = escapeshellarg($to);
// double quotes around command for sub shell
shell_exec('adb shell "am startservice --user 0 -n com.android.shellms/.sendSMS -e contact '.$to.' -e msg '.$m.'"');
}

感谢 FAEWZX,我发现了函数 escapeshellarg() 的正确用法。他上面给出的答案在大多数情况下都有效,但不防水。 IMO,下面的代码更好,因为它涵盖了到目前为止 100% 的情况,使用 escapeshellarg() 两次并递归。

function sendsms ($m, $to, $n) {
    echo "About to sent an sms to $to [$n]\n";

    $subshell = 'am startservice --user 0' .
      ' -n com.android.shellms/.sendSMS' .
      ' -e contact ' . escapeshellarg($to) . 
      ' -e msg ' . escapeshellarg($m);

    $shell = 'adb shell ' . escapeshellarg($subshell);

    shell_exec($shell);
}