【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 文件名 手机中的文件全路径名命令;
[plain] view plain copy
- octopus@octopus:~/csdn$adbpushbusybox-armv7l/sdcard/octopus/busybox
- 3256KB/s(1109128bytesin0.332s)
[plain] view plain copy
- octopus@octopus:~/csdn$adbpushbusybox-armv7l/data/busybox
- failedtocopy'busybox-armv7l'to'/data/busybox':Permissiondenied
[plain] view plain copy
- shell@android:/sdcard/octopus$ll
- -rw-rw-r--rootsdcard_rw11091282014-07-0819:49busybox
- shell@android:/sdcard/octopus$chmod755busybox
- Unabletochmodbusybox:Operationnotpermitted
应用程序解决方案:
--应用程序专属用户: Android 操作系统会为每个应用程序设置一个用户, 这个用户对其安装目录(/data/data/包名/)下的文件有完整的权限;
--将可执行二进制文件拷贝到安装目录中: 将交叉编译好的 busybox 放到 工程目录下的 res/assets/ 目录下;
2. 实现策略
文件初始放置: 将 交叉编译好的 busybox 文件放在 工程目录的 /res/assets/ 目录下;
文件拷贝: 将该 二进制文件 拷贝到 app 的安装目录的 files 目录下, 即 /data/data/包名/files/下;
修改文件权限: 使用命令可以直接修改该目录下的权限, 注意这个操作是可以执行的;
执行busybox: 在代码中执行 ./data/data/包名/files/busybox ;
获取执行结果 :
3. 使用到的api解析
(1) 获取 assets 目录文件的输入流
[java] view plain copy
- InputStreamis=context.getAssets().open(source);
--获取输入流: 调用 AssetsManager 的 open(String fileName) 即可获取对应文件名的输入流;
(2) 文件流相关操作
根据输入流获取文件大小: 调用输入流的 inputStream.available() 方法;
[java] view plain copy
- intsize=is.available();
将文件读取到缓冲区中 : 创建一个与文件大小相同的字节数组缓冲区, 输入流将数据存放到缓冲区中;
[java] view plain copy
- byte[]buffer=newbyte[size];
- is.read(buffer);
- is.close();
将文件写到内存中: 调用上下文对象的 openFileOutput(绝对路径名, 权限), 即可创建一个文件的输出流;
[java] view plain copy
- FileOutputStreamoutput=context.openFileOutput(destination,Context.MODE_PRIVATE);
- output.write(buffer);
- output.close();
(3) 获取文件的绝对路径
获取app绝对安装路径: 调用 上下文对象的 getFilesDir().getAbsolutePath() 方法;
[java] view plain copy
- StringfilesPath=context.getFilesDir().getAbsolutePath();
(4) 执行二进制文件
创建 Process 对象, 并使用该 process 执行shell脚本命令:
[java] view plain copy
- Runtimeruntime=Runtime.getRuntime();
- process=runtime.exec(cmd);
获取执行的命令行结果 :
[java] view plain copy
- InputStreamis=process.getInputStream();
- BufferedReaderbr=newBufferedReader(newInputStreamReader(is));
- Stringline=null;
- while((line=br.readLine())!=null){
- processList.add(line);
- }
- br.close();
4. 代码示例
MainActivity 主程序代码:
[java] view plain copy
- packagecn.org.octopus.tracerouteandbusybox;
- importjava.io.BufferedReader;
- importjava.io.FileNotFoundException;
- importjava.io.FileOutputStream;
- importjava.io.IOException;
- importjava.io.InputStream;
- importjava.io.InputStreamReader;
- importjava.util.ArrayList;
- importjava.util.List;
- importandroid.content.Context;
- importandroid.os.Bundle;
- importandroid.support.v7.app.ActionBarActivity;
- importandroid.view.View;
- importandroid.widget.EditText;
- importandroid.widget.TextView;
- /**看不懂注释我就吃半斤狗粮:-)*/
- publicclassMainActivityextendsActionBarActivity{
- privateEditTextet_cmd;
- privateStringapp_path;
- privateTextViewtv_result;
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- 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();
- }
- /**按钮点击事件*/
- publicvoidonClick(Viewview){
- intid=view.getId();
- switch(id){
- caseR.id.copy_busybox:/*拷贝busybox可执行文件*/
- varifyFile(getApplicationContext(),"busybox");
- break;
- caseR.id.copy_traceroute:/*拷贝traceroute可执行文件*/
- varifyFile(getApplicationContext(),"traceroute");
- break;
- caseR.id.exe_busybox:/*将busybox命令添加到Editext中*/
- Stringcmd="."+app_path+"/busybox";
- System.out.println(et_cmd);
- et_cmd.setText(cmd);
- break;
- caseR.id.exe_traceroute:/*将traceroute命令添加到Editext中*/
- cmd="."+app_path+"/traceroute8.8.8.8";
- et_cmd.setText(cmd);
- break;
- caseR.id.exe:/*执行Editext中的命令*/
- cmd=et_cmd.getText().toString();
- /*执行脚本命令*/
- List<String>results=exe(cmd);
- Stringresult="";
- /*将结果转换成字符串,输出到TextView中*/
- for(Stringline:results){
- result+=line+"\n";
- }
- tv_result.setText(result);
- break;
- default:
- break;
- }
- }
- /**验证文件是否存在,如果不存在就拷贝*/
- privatevoidvarifyFile(Contextcontext,StringfileName){
- try{
- /*查看文件是否存在,如果不存在就会走异常中的代码*/
- context.openFileInput(fileName);
- }catch(FileNotFoundExceptionnotfoundE){
- try{
- /*拷贝文件到app安装目录的files目录下*/
- copyFromAssets(context,fileName,fileName);
- /*修改文件权限脚本*/
- Stringscript="chmod700"+app_path+"/"+fileName;
- /*执行脚本*/
- exe(script);
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- }
- /**将文件从assets目录中拷贝到app安装目录的files目录下*/
- privatevoidcopyFromAssets(Contextcontext,Stringsource,
- Stringdestination)throwsIOException{
- /*获取assets目录下文件的输入流*/
- InputStreamis=context.getAssets().open(source);
- /*获取文件大小*/
- intsize=is.available();
- /*创建文件的缓冲区*/
- byte[]buffer=newbyte[size];
- /*将文件读取到缓冲区中*/
- is.read(buffer);
- /*关闭输入流*/
- is.close();
- /*打开app安装目录文件的输出流*/
- FileOutputStreamoutput=context.openFileOutput(destination,
- Context.MODE_PRIVATE);
- /*将文件从缓冲区中写出到内存中*/
- output.write(buffer);
- /*关闭输出流*/
- output.close();
- }
- /**执行shell脚本命令*/
- privateList<String>exe(Stringcmd){
- /*获取执行工具*/
- Processprocess=null;
- /*存放脚本执行结果*/
- List<String>list=newArrayList<String>();
- try{
- /*获取运行时环境*/
- Runtimeruntime=Runtime.getRuntime();
- /*执行脚本*/
- process=runtime.exec(cmd);
- /*获取脚本结果的输入流*/
- InputStreamis=process.getInputStream();
- BufferedReaderbr=newBufferedReader(newInputStreamReader(is));
- Stringline=null;
- /*逐行读取脚本执行结果*/
- while((line=br.readLine())!=null){
- list.add(line);
- }
- br.close();
- }catch(IOExceptione){
- e.printStackTrace();
- }
- returnlist;
- }
- }
home_activity.xml 布局文件代码:
[html] view plain copy
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns: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
更多相关文章
- XML解析
- Android可执行文件
- android 百度sdk之 百度定位
- 我的第一个python脚本
- 反编译Android部署程序
- android 3.3 butterknife-7.0.1。jar(com.jakewharton:butterkni
- 一些android错误
- android File保存数据
- adb push可执行文件制作教程