Android上app_process启动java进程

  Java程序是跨平台的,由JVM虚拟机执行字节码。Android应用程序开发也是Java,但是都是运行在Context环境下的。独立的Java程序能够在Android上独立运行?

  这里不介绍Android启动过程中,app_process从哪个进程fork处理,也不介绍app_process启动App的过程。仅介绍app_process启动纯Java程序的相关知识。

一、HelloWorld示例

1. 源程序

  编写一个hellworld 的Java程序,并且编译成.class文件,简单得没啥可说的。

public class Helloworld {
    public static void main(String[]args){
        System.out.println("Hello, I am started by app_process!");
    }
}

  Android对Java虚拟机做了修改,即使用自己的dalvik虚拟机(后来的ART)。因此,.class的字节码在Dalvik虚拟机上是不能运行的。Android Platform tool为我们提供了生成Android上可执行jar(Dex)工具:dx。编译命令如下:

//编译,这里主要是Platform tool上用的是Java 7,所以显式指定1.7
javac -source 1.7 -target 1.7 C:\Users\Venscor\Desktop\app_process\dump.java
//生成dex,当然生成jar在Android上也是可执行的
dx --dex --output=C:\Users\Venscor\Desktop\app_process\Hellworld.dex Helloworld.class

2. 运行

  app_process参数格式如下:

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

  app_process运行参数居然没有help,万恶的开发者。这块要么查资料,要么看源码。从网上找的对参数解释如下:

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方法中的参数

  将我们前面编译得到的dex(jar)文件push到/data/local/tmp文件夹下,构建app_process运行参数:

app_process -Djava.class.path=Helloworld.dex  /data/local/tmp Helloworld

  切换/data/local/tmp目录下运行,HelloWorld就成功运行啦!

二、被启动的Java的Pid, Uid与权限

  上面展示了使用app_process在Android启动独立的Java进程的Demo。那么,被启动的Java程序作为一个独立的进程,其从何处fork而来,Uid为多少,对应什么级别权限就是下面要解决的问题。

  为了能够查看app_process启动的Java程序的进程信息,希望demo程序不立马执行结束,以便能够通过ps查看进程信息。修改上面的demo程序,变成死循环让程序持久存活,并先后启动两个这样的Java程序。

  通过上面进程信息可以看到,每次Java程序运行时,系统都会给其分配一个pid,并且进程名都是app_process。(至于为什么要这么命名,不清楚。。。)

  通过追踪ppid,还能发现启动的java进程源自何处,即怎么fork出来的,即:/init–>/sbin/adbd–>/system/bin/sh–>app_process(Java进程),也就是说,启动的Java进程是从/system/bin/sh(shell)fork出来的。

Android上app_process启动java进程_第1张图片

  知道了相应的pid,就可以通过pid查看进程信息,对应的shell命令为:cat /proc/[pid]/status.

Android上app_process启动java进程_第2张图片

  通过上面信息可以看到,app_process启动的Java程序运行的uid是和pid是2000,也就是shell 的Uid,所以app_process启动的Java程序拥有shell级别的权限,下面就此来做个验证。

三、启动的Java程序拥有的权限及Uid

  adb shell中,dumpsys activity命令是查看Activity栈信息的,只有shell权限(可能有shell权限也不行,必须Uid为shell,没有去看)才能调用。所以可以通过这个来验证启动的Java程序是否真的运行于shell的Uid下,测试源代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class dump {
    public static void main(String[]args){
        String cmd="dumpsys activity";
        System.out.println("Hello, I am started by app_process!");
        try {
            Process p=Runtime.getRuntime().exec(cmd);
            BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));
            String readLine=br.readLine();
            while(readLine!=null){
                System.out.println(readLine);
                readLine=br.readLine();
            }
            if(br!=null){
                br.close();
            }
            p.destroy();
            p=null;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

  和前面demo一样编译到Android下运行,查看结果,发现可以正常输出,说明app_process启动的Java程序的确具有shell级别的权限(其实其Uid就是shell)。

Android上app_process启动java进程_第3张图片

  总结: 上面说明了app_process启动Java的相关知识,至于有啥重要用途,后续会陆续给出。

你可能感兴趣的:(android,appprocess,独立Java,Android安全)