Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1107403
  • 博文数量: 276
  • 博客积分: 8317
  • 博客等级: 少将
  • 技术积分: 2329
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-12 08:17
个人简介

http://ads.buzzcity.net/adpage.php?partnerid=40096

文章分类

全部博文(276)

文章存档

2013年(1)

2012年(38)

2011年(102)

2010年(85)

2009年(45)

2008年(5)

分类: LINUX

2010-03-13 10:44:26

一般而言,执行本地代码是需要用ndk写jni lib的。在ndk发布之前的sdk 1.1时代,人们是这么越狱的:

用arm-gcc()交叉编译出本地程序,然后在java中创建进程:

try {
// android.os.Exec is not included in android.jar so we need to use reflection.
Class execClass = Class.forName("android.os.Exec");
Method createSubprocess = execClass.getMethod("createSubprocess",
String.class, String.class, String.class, int[].class);
Method waitFor = execClass.getMethod("waitFor", int.class);

// Executes the command.
// NOTE: createSubprocess() is asynchronous.
int[] pid = new int[1];
FileDescriptor fd = (FileDescriptor)createSubprocess.invoke(
null, "/system/bin/ls", "/sdcard", null, pid);

// Reads stdout.
// NOTE: You can write to stdin of the command using new FileOutputStream(fd).
FileInputStream in = new FileInputStream(fd);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String output = "";
try {
String line;
while ((line = reader.readLine()) != null) {
output += line + "\n";
}
} catch (IOException e) {
// It seems IOException is thrown when it reaches EOF.
}

// Waits for the command to finish.
waitFor.invoke(null, pid[0]);

return output;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e.getMessage());
} catch (SecurityException e) {
throw new RuntimeException(e.getMessage());
} catch (NoSuchMethodException e) {
throw new RuntimeException(e.getMessage());
} catch (IllegalArgumentException e) {
throw new RuntimeException(e.getMessage());
} catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage());
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getMessage());
}

就这样,ls /sdcard可以成功的执行。这个方法调用了JNI函数createSubprocess,效率比较高。旧版的android版Doom就是这么越狱的。不过,android.os.Exec毕竟是未公开接口,很快就行不通了,后来的ROM甚至根本没把android.os.Exec编译进android.jar。当然,后来我们可以用ndk写lib了,不过总是有人喜欢直接执行进程的。这时网上流传出另一个更简洁的办法,继续可用:

Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
DataInputStream osRes = new DataInputStream(process.getInputStream());
for (String single : commands) {
os.writeBytes(single + "\n");
os.flush();
res.add(osRes.readLine());
}
os.writeBytes("exit\n");
os.flush();
process.waitFor();

这个方法在1.1时还是可用的,但从1.5开始,用户权限代码陆续实现了,普通程序不能再执行su命令,只能这么干了:

public String exec(String command) {
StringBuffer output = new StringBuffer();
Log.d("exec", command);
try {
Process process = Runtime.getRuntime().exec(command);
DataInputStream stdout = new DataInputStream(process.getInputStream());
String line;
while ((line = stdout.readLine()) != null) {
output.append(line).append('\n');
}
process.waitFor();
} catch (Exception e) {
output.append('\n').append(e.toString());
}
return output.toString();
}

经过验证,此方法在1.6、2.0、2.1下都是有效的。
阅读(832) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~