Как я могу программно остановить системную службу на рутированном телефоне Android?

Я разрабатываю сервер telnet (?) Bluetooth для Android, который получает команды через Bluetooth OPP. Мой план состоит в том, чтобы отслеживать входящие сообщения Opp, проверять, исходят ли они от определенного пользователя, а затем запускать рабочую службу, которая фактически выполняет заданную работу.

Итак, я исследовал информацию о получении входящего OPP через Bluetooth и обнаружил, что убийство BluetoothOppService является ключевым моментом в этом SO thread. Поэтому я написал приведенные ниже коды, чтобы принимать входящие сообщения OPP.

private void KillOriginalService()
    {
        java.lang.Process suProcess=null;
        int pid;
        try
    {
                String[] command = {
                    "/system/bin/sh",
                    "-c",
                    "ps|grep com.android.bl"
                };
                suProcess = Runtime.getRuntime().exec(command);
                DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
                DataInputStream osRes = new DataInputStream(suProcess.getInputStream());
                if (null != os && null != osRes)
            {
                    String line;
                    while (osRes.available() > 0)
                    {
                        line = osRes.readLine();
                        if (line.contains("1002"))
                        {
                            String[] words=line.split(" ");
                            //pid=Integer.parseInt(words[0]);
                        final String p=words[0];
                        new ExecuteAsRootBase(){
                            @Override
                            protected ArrayList<String> getCommandsToExecute()
                            {
                                // TODO: Implement this method
                                ArrayList<String> list=new ArrayList<String>();
                                list.add("system/bin/kill -9 " + p);
                                return list;
                            }
                        }.execute();
                        Log.v(TAG,"Success kill");
                        return;
                    }
                }
            }   
        }
        catch (IOException e)
        {
            Log.e(TAG, "error occured trying to kill opp service ",e);
        }
    }

И следующий код для получения ServerSocket.

private void getServerSocket()
    {
        boolean fail = true;
        while (fail)
        {
            try
            {
                serversocket = null; 
                Log.v(TAG, "trying to get serverSocket");
                serversocket = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("OPP Listener", UUID.fromString("00001105-0000-1000-8000-00805f9b34fb"));   
                if(serversocket!=null)
                    fail = false;
            }
            catch (IOException e)
            {
                fail = true;
                Log.e(TAG, "Failed to get serversocket " , e);
            }

            if (fail)
            {
                KillOriginalService();
            }           
        }
        //return serversocket;
    }

И этот код работает, но иногда постоянно игнорирует входящее соединение, пока я не перезапущу свою службу вручную, в результате чего исходная служба принимает соединение, отклоняя его (поскольку тип mime входящего файла нулевой). Также оригинальный сервис приобретает полный wakelock, значительно потребляя батарею моего устройства. Кроме того, даже когда мой принимает соединение, мне приходится терпеть неудачу примерно 2 раза, прежде чем мой принимает соединение вместо исходной службы. Я прочитал выходные данные logcat и обнаружил, что исходный BtOppService перезапускается после того, как я убиваю его, печатая OnStartCommand logcat.

Я решил проблему с энергопотреблением через Администрирование screenoff api. Но первая проблема не решена. Как сделать так, чтобы моя служба, а не исходная служба, получала каждое входящее подключение?

(В настоящее время я решаю эту проблему, используя сторожевой поток, который автоматически перезапускает мою службу.)

P.S. У меня есть рутированное устройство, и su работает правильно.


person KYHSGeekCode    schedule 23.02.2018    source источник
comment
Попробуйте использовать зиготу.   -  person KYHSGeekCode    schedule 14.03.2018


Ответы (1)


Наконец-то я нашел способ программно остановить системные службы: Hook системную службу!

Поскольку у меня было рутированное устройство, я мог установить XPosed Framework и модули. Я могу создать модуль, который прикрепляется к целевой службе, а затем возврат not START_STICKY может предотвратить его перезапуск.

Однако это оказалось проблемой XY. В конце концов я изменил свою имплементацию на Убить системную службу, а Жить с ней.

Я создал файловый наблюдатель, чтобы проверить, получила ли система файл. Когда файл получен, он запускает соответствующую службу.

Он создает синергетический эффект с Auto-Accept, который заставляет телефон принимать каждую передачу файлов OPP через Bluetooth. запросы без запроса пользователя (без подсказок!).

person KYHSGeekCode    schedule 05.09.2018
comment
Вы когда-нибудь находили способ остановить системную службу с root-доступом? Ищете, как остановить системную службу USB. - person dazza5000; 15.11.2019
comment
@ dazza5000, может быть, вы могли бы подключить службу OnStartService? затем вернитесь, кроме START_STICKY. - person KYHSGeekCode; 16.11.2019