第三方App与Termux命令建立IO通道

简介: 、第三方 App 与 Termux 建立 TCP/Socket 通信通过 RunCommandService 调用 Termux 执行 nc 命令反弹某个程序,然后通过 java.net.Socket 建立 Socket 连接,取得 Socket 的 IO 流,即可实现进程间通信。调用 Termux。注意,Termux 可使用两个版本的 Netcat:安卓自带的 /system/bin/nc 和 Termux 仓库的 netcat-openbsd。前者随 ToyBox 在 Android Marshmallow 被引入,支持反弹 shell,而后者不支持;后者支持抽象命名空间 UDS。所以

前言

继上一篇 Android 调用 Termux 执行命令,执行命令的问题基本解决,但是 bashawkclangd 这类命令可以从标准输入读取信息并维持运行,Termux 第三方调用缺乏有效支持。而 RunCommandService 可以允许命令后台运行,然后我们以某种方式取得该后台程序的标准输入/输出,便可以实现前后端的持续通信。


一、Android 进程间通信(IPC)

进程间通信(In-Process Communication, IPCreliefmsgustrend)主要实现多进程间的数据通信问题。比如一个 UI 程序后台调用一个 CLI 程序执行某功能,每个程序会启动一个进程,UI 进程给 CLI 进程发送输入数据,CLI 进程接收后返回处理结果给 UI 进程。

Android 实现跨进程通信有多种方式,其各有优缺点:

文件:直接在设备上创建文件实现数据通信。原理简单,操作方便,但是效率低。

Binder:结构上 Binder 是一个虚拟的设备驱动(/dev/binder),连接 Service 进程、Client 进程和 Service Manager 进程。其数据只在内核空间与用户空间复制一次,效率较高,但是限制 1M 数据。另外,基于 Binder 的方法有 AIDL、ContentProvider、Messenger 等。

SharedMemory:共享内存在 Android SDK 27 引入,允许开辟一块共享内存空间用于进程间的数据交互。SharedMemory 配合 AIDL/Binder 使用,可以破除 1M 的限制,传输大文件。但是注意直接对内存进行操作,使用完毕需要手动销毁。

Unix Domain Socket:又叫 Local Domain Socket,本地套字节是 Linux 内核提供的功能,数据经过内核,实现本地进程间通信。其效率高,但是 Android 9+ 限制用户 App 间使用 UDS 通信。

Socket:套字节本质上是网络通信,采用 TCP 或 UDP 协议,主要用于网络通信。其中 TCP 协议较复杂,用于建立稳定的通信;UDP 则速度快而不安全。

受安卓不同应用之间的权限限制,支持进程间字节数据 IO 通信的方案较少,本次采用 Socket 实现。

二、Netcat 网络瑞士军刀

Netcat 是一个小巧强大的网络工具,用于网络监听测试等。Netcat 可建立网络通信,支持 TCP/UDP/Unix 协议。在 Termux 端使用 Netcat 建立套字节通信,并将 stdin/stdout 重定向到一个子进程,如此实现通信。

通过以下方式建立 TCP 通信。服务器端:

nc -l -s 127.0.0.1 -p 1234

客户端:

nc 127.0.0.1 1234

此时在客户端输入的内容可传至服务器端,而服务器端输入的内容可传回客户端,二者间实现通信。

另外,使用 Netcat 可以方便反弹 shell 程序。下面是服务器端命令:

nc -l -s 127.0.0.1 -p 1234 bash

用客户端登录到 127.0.0.1:1234,建立连接后,服务端会启动 bash 程序,并接收来自客户端的标准输入,将标准输出发送给客户端。

三、第三方 App 与 Termux 建立 TCP/Socket 通信

通过 RunCommandService 调用 Termux 执行 nc 命令反弹某个程序,然后通过 java.net.Socket 建立 Socket 连接,取得 Socket 的 IO 流,即可实现进程间通信。

调用 Termux。注意,Termux 可使用两个版本的 Netcat:安卓自带的 /system/bin/nc 和 Termux 仓库的 netcat-openbsd。前者随 ToyBox 在 Android Marshmallow 被引入,支持反弹 shell,而后者不支持;后者支持抽象命名空间 UDS。所以我们使用 /system/bin/nc

intent.setClassName("com.termux", "com.termux.app.RunCommandService");
intent.setAction("com.termux.RUN_COMMAND");
intent.putExtra("com.termux.RUN_COMMAND_PATH", "/system/bin/nc");
intent.putExtra("com.termux.RUN_COMMAND_ARGUMENTS", new String[]{"-l", "-s", "127.0.0.1", "-p", "1234", "bash"});
intent.putExtra("com.termux.RUN_COMMAND_WORKDIR", "/data/data/com.termux/files/home");
intent.putExtra("com.termux.RUN_COMMAND_BACKGROUND", true);
intent.putExtra("com.termux.RUN_COMMAND_SESSION_ACTION", "0");
startService(intent);

建立 Socket 连接:

Socket mSocket;
InputStream mInput;
OutputStream mOutput;
public void connect() {
  mSocket = new Socket();
new Thread(){
public run() {
try {
        sk.connect(new InetSocketAddress("127.0.0.1", 1234));
        mInput = sk.getInputStream();
// 写入命令/发出数据
        mOutput = sk.getOutputStream();
        mOutput.write("ls\n");
        mOutput.flush();
// 读取结果
        Thread.sleep(200L);
int l = mInput.avaliable();
byte[] bs = new byte[l];
        mInput.read(bs);
        System.out.println(new String(bs));
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }.start();
}

四、应用:调用 LSP 语言服务器

语言服务器协议(Language Server Protocol, LSP)是微软推出的一个基于 JSONRPC 的数据协议,用于

Termux 的软件仓库里正好有 clangdccls 两个 C/C++ 的 LSP 服务器端。笔者测试 ccls 时遇到 BUG,故选用 clangd 测试。

安装 clangd

apt install clangd

nc 反弹 clangd

/system/bin/nc -l -s 127.0.0.1 -p 48455 clangd

Android 客户端建立 Socket IO 通信:

Socket sk = new Socket(new InetAddress("127.0.0.1", 48455));

注意,安卓中 Socket 的 IO 流不允许在 UI 主线程进行操作,需要另起线程,以免阻塞主线程引起卡顿。

读取线程:

new Thread() {
public void run() {
InputStream mIn = sk.getInputStream();
final int L = 1024;
byte[] buf = new byte[L];
while (mIn.read(buf, 0, 16)!=-1) {
if (new String(buf, 0, 16).equals("Content-Length: ")) {
// read int c
// skip \r\n\r\n
// read c bytes
      }
    }
  }
}.start();

写入线程:

Thread td = new Thread() {
public void run() {
try {
OutputStream mOut = sk.getOutputStream();
byte[] s="{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":\"initialize\",\"params\":{}}".getBytes(StandardCharsets.UTF_8);
      mOut.write(("Content-Length: "+s.length+"\r\n\r\n").getBytes());
      mOut.write(s);
      mOut.flush();
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }
};
td.start();
td.join(); // 阻塞写入线程,避免同时写入

笔者的开源项目:TermuC - github.com/RainbowC0

相关文章
|
1月前
ModelScope中swft app-ui 命令怎么开启推理日志?
ModelScope中swft app-ui 命令怎么开启推理日志?【1月更文挑战第4天】【1月更文挑战第19篇】
31 1
|
1月前
|
机器学习/深度学习 缓存 监控
linux查看CPU、内存、网络、磁盘IO命令
`Linux`系统中,使用`top`命令查看CPU状态,要查看CPU详细信息,可利用`cat /proc/cpuinfo`相关命令。`free`命令用于查看内存使用情况。网络相关命令包括`ifconfig`(查看网卡状态)、`ifdown/ifup`(禁用/启用网卡)、`netstat`(列出网络连接,如`-tuln`组合)以及`nslookup`、`ping`、`telnet`、`traceroute`等。磁盘IO方面,`iostat`(如`-k -p ALL`)显示磁盘IO统计,`iotop`(如`-o -d 1`)则用于查看磁盘IO瓶颈。
148 10
|
12天前
|
安全 网络安全 Windows
【Azure App Service】遇见az命令访问HTTPS App Service 时遇见SSL证书问题,暂时跳过证书检查的办法
在访问App Service的KUDU工具或使用`az webapp deploy`时遇到SSL错误:`SSL: CERTIFICATE_VERIFY_FAILED`。解决方法是临时禁用Azure CLI的SSL验证。在PowerShell中,设置`$env:ADAL_PYTHON_SSL_NO_VERIFY`和`$env:AZURE_CLI_DISABLE_CONNECTION_VERIFICATION`为1;在Windows命令提示符中,使用`set AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1`。注意,这可能引入安全风险,应仅在必要时使用。
|
1月前
|
运维 Linux
Linux系统调优详解(五)——磁盘IO状态查看命令
Linux系统调优详解(五)——磁盘IO状态查看命令
68 5
|
1月前
|
监控 数据库 数据安全/隐私保护
第三方授权的应用苹果审核被驳回解决方案和app版本更新
第三方授权的应用苹果审核被驳回解决方案和app版本更新
30 0
|
1月前
|
Android开发
Android修改默认system/bin/下可执行程序拥有者和权限,使用实例,只有root和系统app权限才能执行某个命令。
Android修改默认system/bin/下可执行程序拥有者和权限,使用实例,只有root和系统app权限才能执行某个命令。 【5月更文挑战第2天】
38 0
|
1月前
|
前端开发 Android开发 iOS开发
应用研发平台EMAS使用 aliyun-react-native-push 库接入推送和辅助通道,推送都可以收到,但是在App切到后台或者杀掉进程之后就收不到推送了,是需要配置什么吗?
【2月更文挑战第31天】应用研发平台EMAS使用 aliyun-react-native-push 库接入推送和辅助通道,推送都可以收到,但是在App切到后台或者杀掉进程之后就收不到推送了,是需要配置什么吗?
49 2
|
1月前
|
物联网 Java 数据安全/隐私保护
App Inventor 2 低功耗蓝牙(BLE) 硬件接入、数据通信及IO控制
低功耗蓝牙(BLE)以低功耗、低成本、开发简便逐渐被广泛应用,本文主要介绍一款较为通用、价格低廉的BLE设备从零开始如何利用App Inventor 2开发一款自己专属的手机蓝牙App应用。 本文主要通过一款常见的BLE硬件接入控制,介绍硬件接入App Inventor 2 的通用方法,类似的硬件接入都是大同小异的。
230 1
|
1月前
|
安全 Java Android开发
Android App开发之安全加固中反编译、代码混淆、第三方加固以及重签名的讲解及实战(图文解释 简单易懂)
Android App开发之安全加固中反编译、代码混淆、第三方加固以及重签名的讲解及实战(图文解释 简单易懂)
95 0
|
6天前
|
编解码 Java Android开发
FFmpeg开发笔记(三十一)使用RTMP Streamer开启APP直播推流
RTMP Streamer是一款开源的安卓直播推流框架,支持RTMP、RTSP和SRT协议,适用于各种直播场景。它支持H264、H265、AV1视频编码和AAC、G711、OPUS音频编码。本文档介绍了如何使用Java版的RTMP Streamer,建议使用小海豚版本的Android Studio (Dolphin)。加载项目时,可添加国内仓库加速依赖下载。RTMP Streamer包含五个模块:app、encoder、rtmp、rtplibrary和rtsp。完成加载后,可以在手机上安装并运行APP,提供多种直播方式。开发者可以从《FFmpeg开发实战:从零基础到短视频上线》获取更多信息。
33 7
FFmpeg开发笔记(三十一)使用RTMP Streamer开启APP直播推流