Search code examples
phpadb

Executing adb shell from PHP and escaping strings


I am trying to convert a working bash script into PHP code.

#!/bin/bash
phonenumber="$1"
message="$2"

# 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\""

The code above works. In PHP, next code doesn't work when the messages includes a new line:

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

I get the message error:

       $ 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

I don't understand why it works in bash but not in PHP.


Solution

  • Thanks to FAEWZX, I discovered the proper use of the function escapeshellarg(). The answer he gave above is working in most of the cases, but is not waterproof. IMO, the code below is better because it covers 100% of the cases so far, using escapeshellarg() twice and recursively.

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