博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 上实现非root的 Traceroute -- 非Root权限下移植可执行二进制文件 脚本文件...
阅读量:7185 次
发布时间:2019-06-29

本文共 6888 字,大约阅读时间需要 22 分钟。

作者 : 万境绝尘

转载请著名出处http://blog.csdn.net/shulianghan/article/details/36438365

示例代码下载 :

-- CSDN : http://download.csdn.net/detail/han1202012/7639253;

-- GitHub : https://github.com/han1202012/TracerouteAndBusybox ;

1. 原理思路

文件权限修改无法实现 : 如果 没有 root 权限, 就不能改变二进制文件的文件权限;

-- 将busybox推送到Android系统中 : 使用 adb push 命令, 将 busybox 传入到 sd 卡中, 注意, 上传到内存中无法实现;

-- 上传到sd卡成功 : 使用 adb push 文件名 手机中的文件全路径名 命令;

octopus@octopus:~/csdn$ adb push busybox-armv7l /sdcard/octopus/busybox3256 KB/s (1109128 bytes in 0.332s)
--
上传到内存失败 : 使用 adb push 上传到内存中失败, 因为 adb 使用的是 system 用户, 只有 root 用户才有权限向内存中写入数据;

octopus@octopus:~/csdn$ adb push busybox-armv7l /data/busyboxfailed to copy 'busybox-armv7l' to '/data/busybox': Permission denied
--
查看并修改busybox权限失败 : system 用户没有修改 sd 卡文件模式的权限;

shell@android:/sdcard/octopus $ ll -rw-rw-r-- root     sdcard_rw  1109128 2014-07-08 19:49 busyboxshell@android:/sdcard/octopus $ chmod 755 busybox                              Unable to chmod busybox: Operation not permitted

应用程序解决方案

-- 应用程序专属用户 : Android 操作系统会为每个应用程序设置一个用户, 这个用户对其安装目录(/data/data/包名/)下的文件有完整的权限;

-- 将可执行二进制文件拷贝到安装目录中 : 将交叉编译好的 busybox 放到 工程目录下的 res/assets/ 目录下;

2. 实现策略

文件初始放置 : 将 交叉编译好的 busybox 文件放在 工程目录的 /res/assets/ 目录下;

文件拷贝 : 将该 二进制文件 拷贝到 app 的安装目录的 files 目录下, 即 /data/data/包名/files/下;

修改文件权限 : 使用命令可以直接修改该目录下的权限, 注意这个操作是可以执行的;

执行busybox : 在代码中执行 ./data/data/包名/files/busybox ;

获取执行结果 : 

3. 使用到的api解析

(1) 获取 assets 目录文件的输入流

InputStream is = context.getAssets().open(source);
--
获取AssetsManager : 调用 Context 上下文对象的 context.getAssets() 即可获取 AssetsManager对象;

-- 获取输入流 : 调用 AssetsManager 的 open(String fileName) 即可获取对应文件名的输入流;

(2) 文件流相关操作

根据输入流获取文件大小 : 调用输入流的 inputStream.available() 方法;

int size = is.available();
将文件读取到缓冲区中 : 创建一个与文件大小相同的字节数组缓冲区, 输入流将数据存放到缓冲区中;

byte[] buffer = new byte[size];is.read(buffer);is.close();

将文件写到内存中 : 调用上下文对象的 openFileOutput(绝对路径名, 权限), 即可创建一个文件的输出流;

FileOutputStream output = context.openFileOutput(destination, Context.MODE_PRIVATE);output.write(buffer);output.close();

(3) 获取文件的绝对路径

获取app绝对安装路径 : 调用 上下文对象的 getFilesDir().getAbsolutePath() 方法;

String filesPath = context.getFilesDir().getAbsolutePath();

(4) 执行二进制文件

创建 Process 对象, 并使用该 process 执行shell脚本命令

Runtime runtime = Runtime.getRuntime();process = runtime.exec(cmd);
获取执行的命令行结果

InputStream is = process.getInputStream();            BufferedReader br = new BufferedReader(new InputStreamReader(is));            String line = null;              while ((line = br.readLine()) != null) {                  processList.add(line);             }            br.close();

4. 代码示例

MainActivity 主程序代码

package cn.org.octopus.tracerouteandbusybox;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.View;import android.widget.EditText;import android.widget.TextView;/** 看不懂注释我就吃半斤狗粮 :-) */public class MainActivity extends ActionBarActivity {	private EditText et_cmd;	private String app_path;	private TextView tv_result;		@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.home_activity);				/*初始化控件*/		et_cmd = (EditText) findViewById(R.id.et_cmd);		tv_result = (TextView) findViewById(R.id.tv_result);		/* 获取app安装路径 */		app_path = getApplicationContext().getFilesDir().getAbsolutePath();			}	/** 按钮点击事件 */	public void onClick(View view) {		int id = view.getId();		switch (id) {		case R.id.copy_busybox: /* 拷贝busybox可执行文件 */			varifyFile(getApplicationContext(), "busybox");			break;		case R.id.copy_traceroute:/* 拷贝traceroute可执行文件 */			varifyFile(getApplicationContext(), "traceroute");			break;		case R.id.exe_busybox:/* 将busybox命令添加到Editext中 */			String cmd = "." + app_path + "/busybox";			System.out.println(et_cmd);			et_cmd.setText(cmd);			break;		case R.id.exe_traceroute:/* 将traceroute命令添加到Editext中 */			cmd = "." + app_path + "/traceroute 8.8.8.8";			et_cmd.setText(cmd);			break;		case R.id.exe: /* 执行Editext中的命令 */			cmd = et_cmd.getText().toString();			/* 执行脚本命令 */			List
results = exe(cmd); String result = ""; /* 将结果转换成字符串, 输出到 TextView中 */ for(String line : results){ result += line + "\n"; } tv_result.setText(result); break; default: break; } } /** 验证文件是否存在, 如果不存在就拷贝 */ private void varifyFile(Context context, String fileName) { try { /* 查看文件是否存在, 如果不存在就会走异常中的代码 */ context.openFileInput(fileName); } catch (FileNotFoundException notfoundE) { try { /* 拷贝文件到app安装目录的files目录下 */ copyFromAssets(context, fileName, fileName); /* 修改文件权限脚本 */ String script = "chmod 700 " + app_path + "/" + fileName; /* 执行脚本 */ exe(script); } catch (Exception e) { e.printStackTrace(); } } } /** 将文件从assets目录中拷贝到app安装目录的files目录下 */ private void copyFromAssets(Context context, String source, String destination) throws IOException { /* 获取assets目录下文件的输入流 */ InputStream is = context.getAssets().open(source); /* 获取文件大小 */ int size = is.available(); /* 创建文件的缓冲区 */ byte[] buffer = new byte[size]; /* 将文件读取到缓冲区中 */ is.read(buffer); /* 关闭输入流 */ is.close(); /* 打开app安装目录文件的输出流 */ FileOutputStream output = context.openFileOutput(destination, Context.MODE_PRIVATE); /* 将文件从缓冲区中写出到内存中 */ output.write(buffer); /* 关闭输出流 */ output.close(); } /** 执行 shell 脚本命令 */ private List
exe(String cmd) { /* 获取执行工具 */ Process process = null; /* 存放脚本执行结果 */ List
list = new ArrayList
(); try { /* 获取运行时环境 */ Runtime runtime = Runtime.getRuntime(); /* 执行脚本 */ process = runtime.exec(cmd); /* 获取脚本结果的输入流 */ InputStream is = process.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line = null; /* 逐行读取脚本执行结果 */ while ((line = br.readLine()) != null) { list.add(line); } br.close(); } catch (IOException e) { e.printStackTrace(); } return list; } }

home_activity.xml 布局文件代码

5. 执行结果

执行 busybox 程序

执行 traceroute 程序

示例代码下载 :

-- CSDN : http://download.csdn.net/detail/han1202012/7639253;

-- GitHub : https://github.com/han1202012/TracerouteAndBusybox ;

作者 : 万境绝尘

转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/36438365

转载于:https://www.cnblogs.com/hanshuliang/p/4215411.html

你可能感兴趣的文章
用户线程和内核线程
查看>>
打开页面自动强制QQ对话
查看>>
php 代码设置跳转
查看>>
图的邻接表存储
查看>>
XSS绕过WAF的姿势
查看>>
[python] 类常用的内置方法
查看>>
01-kubernetes集群的基本概念
查看>>
vs2010 msvcr100.DLL 丢失!!! 用release 就可以了
查看>>
Spring RMI Example
查看>>
BZOJ1042: [HAOI2008]硬币购物
查看>>
sql面试题
查看>>
Linuxの安装SQL Developer工具
查看>>
Vue中axios的使用
查看>>
2048 控制台版(C#)
查看>>
[论文笔记] A Survey of Software Refactoring(TOSE, 2004)第一部分
查看>>
关于EOF和循环体的搭配使用。
查看>>
电梯调度--初
查看>>
C#与.NET
查看>>
2.7 Go channel
查看>>
jQuery代码实现表格内容可编辑修改
查看>>