Android runs adb advanced permission commands without root, such as modifying mobile phone settings, etc. (transfer)


Silent installation and click anywhere without Root

0 Preface

Recently, there is a demand: root-free implementation of clicking anywhere and silent installation. Those who have done this should know that it is impossible to achieve under normal circumstances. Accessibility can only implement clicks on known controls, and cannot specify coordinates. But some people did find another way to make it. For example, Feizhi, which is a game controller, used an activator, turned on the usb debugging of the mobile phone, and then plugged it into the activator and authorized it. The Feizhi game hall was "activated", and then you can Click anywhere. If you don’t know, you can go to their official website to find out, so I won’t go into details here. Coincidentally, the black domain also uses a similar method, and it can also be activated with the computer's usb debugging. We know that clicking any position coordinate xy can be realized on the PC through the shell command "input tap xy", and root privilege is not required. However, executing this shell command through "Runtime.getRuntime().exec" in the application prompts "permission denied", which means insufficient permissions. However, Feizhi or Heiyu seem to have used some kind of magic to elevate their privileges, so here comes the question: how to use usb debugging to elevate app privileges?

1 Principle revealed

The question "How to use usb debugging to elevate the app's privileges" seems to be no problem at first glance, but there is an answer in Zhihu that "Ask if it is right first, and then why." I think it is very good. I have been troubled by this question for a long time, and finally found that I asked the wrong question. Let’s start with the conclusion that “it’s not to escalate the app’s privileges, but to run a new program with shell privileges”

Putting aside the question just now, let me ask you a new question, how to let the app get root permissions? There are already many answers to this question, and a search on the Internet shows that it is actually to get "Runtime.getRuntime(). exec" stream, use su to elevate the privileges, and then execute shell commands that require root privileges, such as mounting the system for reading and writing, accessing the data partition, silently installing with shell commands, and so on. Having said that, is it a bit similar to our topic today, how to make the app obtain shell permissions? Well, in fact, it is almost the same, and the idea is similar, because root and shell are not nouns in the Android application layer at all. They are originally nouns in Linux, but the Android framework runs on the Linux layer. We can call Shell command, you can also call su in the shell to make the shell obtain root privileges, to bypass the Android layer to do some restricted things. However, when the shell command is invoked in the app, the process is still in the app, and the permissions are still limited. So you can't run the shell command in the app, so the question is, where to run it if it is not running in the app? The answer is to run on pc. Of course, it is impossible for the PC to be connected to the mobile phone all the time, but an independent java program running in the shell on the PC. Since this program is started in the shell, it has shell authority. Let's think about it, this Java program runs in the shell, establishes a local socket server, communicates with the app, and remotely executes the code issued by the app. Because even if the data cable is unplugged, this Java program will not stop, as long as it is not restarted, it will always be alive and execute our commands. Doesn’t it seem that the app has shell permissions? Now the truth is clear, the activation of Feizhi and Heiyu with usb debugging is actually to start the Java program, Feizhi is to execute the simulated button, and Heiyu is to monitor system events, you can develop whatever you want. "Note: Due to the needs of process management, Heiyu and Feizhi actually use the shell to start a so first, and then use so as a springboard to start the Java program, and so also acts as a daemon process. When Java stops unexpectedly, it can be restarted. Read If you are interested, you can do your own research, so I won’t explain much here.”

2 yes! is app_process

So how to run the Java program with the shell? It must not be "java xxx.jar". The format that Android can run is dex. That's right, it's the dex in the apk. Then we can start Java through "app_process". The parameters of app_process are as follows

app_process [vm-options] cmd-dir [options] start-class-name [main-options]

There is no -help for this weird and scary thing. We either look at the source code, or look at what others have analyzed. My level is limited, here I choose to read other people's analysis:

vm-options – VM 选项
cmd-dir –父目录 (/system/bin)
options –运行的参数 :
    –zygote
    –start-system-server
    –application (api>=14)
    –nice-name=nice_proc_name (api>=14)
start-class-name –包含main方法的主类  (com.android.commands.am.Am)
main-options –启动时候传递到main方法中的参数

3 practice

Because it is dex, let's write it directly in as, and it is also convenient to extract dex. Create a new blank project, the initial structure is as follows:

We create a new package to store the Java code we want to run under the shell:

Here we complete the Main method, because this is not an Android program, but a pure Java program compiled into dex, so our entry is Main:

package shellService;

public class Main {
    
    
    public static void main(String[] args){
    
    
        System.out.println("我是在 shell 里运行的!!!");
    }
}

We just print a line in the code "I am running in the shell!!!", because it is pure Java here, so println is also used. Now compile the apk:

Because the apk is zip, we directly decompress the classes.dex in the apk file, and then execute:

adb push classes.dex /data/local/tmp
cd /data/local/tmp
app_process -Djava.class.path=/data/local/tmp/classes.dex /system/bin shellService.Main

At this time, you can see that it has successfully run:

Here, because utf8 has problems in the Windows shell, the characters are garbled, but it still means that we have succeeded.

##4 Be practical

It is definitely not enough to only output, and it is not practical. As we said before, we should create a local socket server to accept commands and execute them. The "Service" class here realizes this function, because how to establish a socket is not the focus of the article, so you only need to know that this class internally implements a "ServiceGetText "Interface, after receiving the command, it will return the command content as a parameter to the getText method, and then after we execute the shell command, just return the result as a string. For the specific implementation, see the source code Service .

We create a new " ServiceThread " to run the "Service" service and execute the set up command:

public class ServiceThread extends Thread {
    
    
    private static int ShellPORT = 4521;

    @Override
    public void run() {
    
    
        System.out.println(">>>>>>Shell服务端程序被调用<<<<<<");
        new Service(new Service.ServiceGetText() {
    
    
            @Override
            public String getText(String text) {
    
    
                if (text.startsWith("###AreYouOK")){
    
    
                    return "###IamOK#";
                }
                try{
    
    
                    ServiceShellUtils.ServiceShellCommandResult sr =  ServiceShellUtils.execCommand(text, false);
                    if (sr.result == 0){
    
    
                        return "###ShellOK#" + sr.successMsg;
                    } else {
    
    
                        return "###ShellError#" + sr.errorMsg;
                    }
                }catch (Exception e){
    
    
                    return "###CodeError#" + e.toString();
                }
            }
        }, ShellPORT);
    }
}

Among them, ServiceShellUtils uses the open source project ShellUtils, thank you here. This class is used to execute shell commands.

Then call this thread in Main:

public class Main {
    
    

    public static void main(String[] args){
    
    
        new ServiceThread().start();
        while (true);
    }

}

In this way, our server is ready, let's write the app that controls the server. We create a new class "SocketClient" to communicate with the server and call it in the activity (see SocketClient and MainActivity for the complete code ):

private void runShell(final String cmd){
    
    
        if (TextUtils.isEmpty(cmd)) return;
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
              new SocketClient(cmd, new SocketClient.onServiceSend() {
    
    
                  @Override
                  public void getSend(String result) {
    
    
                      showTextOnTextView(result);
                  }
              });
            }
        }).start();
    }

Then repeat the operation of the 3 subsections to run the server:

Then to install the apk, run:

input text HelloWord

It can be seen that without root, the commands that require shell permissions are successfully executed

5 cutest people

Finally, I really want to thank all kinds of technical analysis articles and open source projects from the bottom of my heart. I am really grateful. Without unconditional dedication, there would be no such rapid progress of the Internet.

My research on app_process utilization methods is inseparable from the following projects and the sweat of predecessors:

Brevent was the first to use the app_process process to implement open source applications without root privileges (although the source has been closed, I still respect and thank liudongmiao )

Android system log viewer on Android phone without root. Use the app_process process to realize the excellent open source application without root permission

App_process on Android starts java process easy-to-understand tutorial

A very in-depth tutorial on using app_process to call high-privilege API analysis

The project for this article is available on GitHub : https://github.com/gtf35/app_process-shell-use

This article is forwarded from: https://github.com/gtf35/app_process-shell-use
If the forwarding address fails or access 404, you can visit
https://github.com/miqt/app_process-shell-use of my fork

Guess you like

Origin blog.csdn.net/qq_27512671/article/details/107637318