`

Android 上实现非root的 Traceroute -- 非Root权限下移植可执行二进制文件 脚本文件

 
阅读更多

作者 : 万境绝尘

转载请著名出处 :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/busybox
3256 KB/s (1109128 bytes in 0.332s)
-- 上传到内存失败 : 使用 adb push 上传到内存中失败, 因为 adb 使用的是 system 用户, 只有 root 用户才有权限向内存中写入数据;

octopus@octopus:~/csdn$ adb push busybox-armv7l /data/busybox
failed 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 busybox
shell@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<String> 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<String> exe(String cmd) {
		/* 获取执行工具 */
		Process process = null; 
		/* 存放脚本执行结果 */
        List<String> list = new ArrayList<String>();  
        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 布局文件代码 :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/copy_busybox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="拷贝busybox"
            android:textSize="7dp"
            android:textStyle="bold" />

        <Button
            android:id="@+id/copy_traceroute"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="拷贝traceroute"
            android:textSize="7dp"
            android:textStyle="bold" />

        <Button
            android:id="@+id/exe_busybox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="执行busybox"
            android:textSize="7dp"
            android:textStyle="bold" />

        <Button
            android:id="@+id/exe_traceroute"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="执行traceroute"
            android:textSize="7dp"
            android:textStyle="bold" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <EditText
            android:id="@+id/et_cmd"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="4"
            android:hint="输入要执行的命令"
            android:textStyle="bold" />

        <Button
            android:id="@+id/exe"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClick"
            android:text="执行"
            android:textSize="10dp"
            android:textStyle="bold" />
    </LinearLayout>

    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        android:textColor="#FFF"
        android:textSize="10dp"
        android:textStyle="bold" />

</LinearLayout>


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



分享到:
评论

相关推荐

    traceroute-2.1.0

    3. **编译**:运行`make`命令编译源码,这将生成可执行文件。 4. **安装**:如果一切顺利,可以使用`sudo make install`将编译好的traceroute安装到系统路径。 四、应用实例 1. **排查网络问题**:当用户遇到访问...

    非root权限移植busybox 和 traceroute 示例程序

    总之,非root权限移植Busybox和Traceroute是一项技术挑战,但通过合理配置和源码修改,可以在不破坏系统安全性的前提下满足日常的使用需求。这种方法尤其适用于那些无法获取root权限的环境,如企业内部网络或公共...

    traceroute-2.1.0源码

    7. **配置和编译**:源码可能附带`Makefile`,用户可以通过运行`make`命令来编译源码,生成可执行文件。编译过程可能需要特定的库支持,如`libpcap`用于网络数据包捕获。 8. **调试和测试**:源码中可能包含测试...

    traceroute-2.1.0.rar

    3. 若是从源码编译安装,如标题所示的"traceroute-2.1.0.rar"文件,首先解压,然后编译安装: ``` unrar x traceroute-2.1.0.rar cd traceroute-2.1.0 ./configure make sudo make install ``` 四、实例...

    traceroute-for-android:适用于Android的traceroute

    在Android上使用traceroute的简单方法。 描述 Traceroute跟踪从IP网络获取的路由数据包到达给定主机的过程。 它利用IP协议的生存时间(TTL)字段,并尝试从每个网关到主机的路径引发ICMP TIME_EXCEEDED响应。 渲染...

    traceroute-2.1.0-6.el8.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    traceroute.rar

    traceroute-2.0.22-2.el7.x86_64.rpm traceroute-2.1.0-10.fc32.x86_64.rpm rpm -ivh traceroute-2.0.22-2.el7.x86_64.rpm

    traceroute-2.1.0-6.el8.aarch64.rpm

    官方离线安装包,亲测可用

    traceroute 安装包

    对于traceroute-2.1.1这样的压缩包,通常意味着我们需要进行手动编译和安装。 首先,确保系统中已经安装了必要的编译工具,如gcc、make等。在终端中运行以下命令: ```bash sudo apt-get install build-essential ...

    traceroute-2.0.22-2.el7.x86-64.rpm

    标题中的"traceroute-2.0.22-2.el7.x86_64.rpm"是一个Linux系统下的网络诊断工具traceroute的软件包。traceroute是用于追踪数据包在网络中传输路径的一个实用程序,它可以帮助网络管理员或普通用户了解数据包在到达...

    traceroute android工程编译的32位和64位bin程序 支持域名和IP

    文件列表中的“test.txt”可能是编译过程中的日志文件或测试脚本,而“traceroute-2.0.18”则可能是优化后的traceroute工具的二进制文件,对应版本号为2.0.18,这通常意味着它包含了最新的修复和改进。 在实际应用...

    Python库 | traceroute-19.2.0-py2.py3-none-any.whl

    python库,解压后可用。 资源全名:traceroute-19.2.0-py2.py3-none-any.whl

    traceroute适配CentOS7、el7

    本文将详细讲解如何在CentOS 7或EL 7系统上安装和使用`traceroute`,以及它在排查网络问题时的作用。 `traceroute`是一款用于跟踪IP数据包在网络中传输路径的工具,它可以帮助我们了解数据包从源主机到目标主机过程...

    traceroute-2.1.0-9.fc31.x86_64.rpm

    网络测试工具

    网络路由追踪,traceroute,centos系统拷贝安装的可执行文件,常用命令

    我上传的是 traceroute 的可执行文件,拷贝到系统上就能跑。对系统库的依赖非常少。 拷贝到系统上后,可用ldd命令查看依赖文件是否缺失: ldd /usr/bin/traceroute linux-vdso.so.1 =&gt; (0x00007ffc8e3f7000) ...

    traceroute rpm 离线安装包(x86-64 和 arrch64)

    traceroute 官方离线安装包,亲测可用哦!!

    PyPI 官网下载 | traceroute-19.2.0-py2.py3-none-any.whl

    资源来自pypi官网。 资源全名:traceroute-19.2.0-py2.py3-none-any.whl

    TraceRoute_pack

    SourceCode(include VCL IP-edit , Finger ,Info_from_IP)

    android ping traceroute url 拨测小工具 附源码和apk

    net tool box小工具,是前段时间写的一个测试demo,主Activity有3个按钮(ping、...其次,手机必须获取root权限(即root过的手机),否则无法实现traceroute功能。 本zip包中,包含已经打包的apk安装程序 和 源码。

Global site tag (gtag.js) - Google Analytics