image
我们新建个包,存放我们要在 shell 下运行的 Java 代码:
image
这里我们补全 Main 方法,因为我们这个不是个 Android 程序,只是编译成 dex 的纯 Java 程序,所以我们这个的入口是 Main :
package shellService;
public class Main {
public static void main(String[] args){
System.out.println("我是在 shell 里运行的!!!");
}
}
我们在代码里只是打印一行「我是在 shell 里运行的!!!」,因为这里是纯 Java 所以也用的 println。现在编译 apk:
image
因为 apk 就是 zip 所以我们直接解压出 apk 文件里的classes.dex,然后执行 :
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
这时就能看到已经成功运行啦:
image
这里因为 utf8 在 Windows shell 里有问题,所以乱码了,但是还是说明我们成功了。
4 具有实用性
只能输出肯定是不行的,不具有实用性。我们之前说过,我们应该建立个本地 socket 服务器来接受命令并执行,这里的「Service」类实现了这个功能,因为如何建立 socket 不是文章的重点,所以大家只要知道这个类内部实现了一个「ServiceGetText」接口,在收到命令之后会把命令内容作为参数回掉 getText 方法,然后我们执行 shell 命令之后,吧结果作为字符串返回即可,具体实现可以看查看源码Service。
我们新建一个「ServiceThread」来运行「Service」服务和执行设立了命令:
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);
}
}
其中 ServiceShellUtils 用到了开源项目 ShellUtils 在此感谢。这个类用来执行 shell 命令。
然后在 Main 中调用这个线程:
public class Main {
public static void main(String[] args){
new ServiceThread().start();
while (true);
}
}
这样,我们服务端就准备好了,我们来写控制服务端的 app 。我们新建类「SocketClient」用来和服务端进行通信,并在活动里调用他(完整代码请参看SocketClient和MainActivity):
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();
}
然后重复 3 小节的操作,运行这个服务端:
image
然后安装 apk ,运行:
input text HelloWord

image
可以看到,在不 root 的情况下,成功的执行了需要 shell 权限的命令
5 最可爱的人
最后,我真的是要由衷的感谢各种技术分析文章和开源项目,真的太感谢了,没有无条件的奉献就没有互联网这么快的进步。
我对 app_process 利用方法的研究离不开以下项目和前辈的汗水:
Brevent 最早利用app_process进程实现无 root 权限使用的开源应用(虽然已经闭源,仍然尊重并感谢 liudongmiao)
Android system log viewer on Android phone without root. 利用app_process进程实现无 root 权限使用的优秀开源应用
Android上app_process启动java进程 通俗易懂的教程
使用 app_process 来调用高权限 API 分析的很深刻的教程
本文的项目可以在GitHub上获取:https://github.com/gtf35/app_process-shell-use
作者:gtf
链接:https://www.jianshu.com/p/86253b2c49f3
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论
hengbaby
11楼
拔掉数据线就停止运行的可以试试在 app-process 前加 nohup 试试,我加了这个拔掉数据线就正常了
文章均来自互联网如有不妥请联系作者删除QQ:314111741 地址:http://www.mqs.net/post/15664.html
添加新评论