首页 / JAVA / Java安全之命令执行
Java安全之命令执行
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java安全之命令执行,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3826字,纯文字阅读大概需要6分钟。
内容图文
![Java安全之命令执行](/upload/InfoBanner/zyjiaocheng/623/1764a6c5ee364ff18511fa960863b4e4.jpg)
前言
续着上一篇的笔记,把java安全的命令执行另外的ProcessBuilder和ProcessImpl这部分的笔记也记录一下。通过上一篇的runtime类命令执行的调试笔记,我们也知道,Runtime类下一层就是调用ProcessBuilder类和ProcessImpl类中的方法来操作的,具体的调用关系如下图所示:
ProcessBuilder
先简单了解下ProcessBuilder这个类,ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。在J2SE 1.5之前,都是由Process类处来实现进程的控制管理。
来看看是该类怎么完成命令执行的,比如执行ipconfig命令:
Process p = null;
// 执行ipconfig /all命令
p = new ProcessBuilder("cmd", "/c ipconfig /all").start();
byte[] b = new byte[1024];
int readbytes = -1;
StringBuffer sb = new StringBuffer();
// 读取进程输出值
InputStream in = p.getInputStream();
try {
while ((readbytes = in.read(b)) != -1) {
sb.append(new String(b, 0, readbytes));
}
} catch (IOException e1) {
} finally {
try {
in.close();
} catch (IOException e2) {
}
}
System.out.println( sb.toString());
}
至于 p = new ProcessBuilder("cmd", "/c ipconfig /all").start();
这里为什么要在ipconfig
前面加/c
,在上一篇的Runtime类的调试笔记中已经有解释了,这里就不再重复,这里主要是记录学习下ProcessBuilder这个类。
前面已经说过,在J2SE 1.5之前,都是由Process类处来实现进程的控制管理,那为什么还要ProcessBuilder这个类呢?区别又在哪?
其实区别在于两个类的性质就不一样了,process类是一个抽象类,要创建一个进程的话,一般是通过Runtime.exec()和ProcessBuilder.start()来间接创建其实例,而ProcessBuilder是一个final类,有两个带参数的构造方法,可以通过构造方法来直接创建ProcessBuilder的对象,并且ProcessBuilder为进程提供了更多的控制,例如,可以设置当前工作目录,还可以改变环境参数,可以说ProcessBuilder类是process类的一个扩展和包装。
还有个问题,就是Runtime.exec()和ProcessBuilder.start()有什么区别呢?
从上一篇的笔记中我们知道,Runtime.exec()有六种重载方法,如下:
在传入命令参数是,其中java.lang.Runtime.exec(String)可以接受单一字符串参数,也可以接受其他字符串数组等参数,而ProcessBuilder.start()是通过构建方法传入后才调用start()方法,但ProcessBuilder类构造函数只接受字符串的varargs数组或List
的字符串,其中数组或列表中的每个字符串都被假定为单个参数。
所以最关键的区别是,同个字符串参数对于ProcessBuilder类和Runtime类的命令执行结果来说是不同的,举个例子,比如同样是执行命令“ipconfig /all”
传入Runtime类的exec方法后,之后会先把“ipconfig /all”以空格隔开分为两部分,第一部分的“ipconfig”会作为启动模块,第二部分的”/all“作为第一部分的命令行参数,而ipconfig模块在我的系统环境是存在的,如下:
同样可以正常命令执行,没什么问题
到了ProcessBuilder类这里,同样的“ipconfig /all”传进来的话就抛出错误
这是因为ProcessBuilder类把整个“ipconfig /all”都标记化了,在后面的调用中会把这整一串都当做启动模块的名字寻找,而我本地系统中肯定是不存在,所以就会抛出“系统找不到指定文件”的错误。
看到ProcessBuilder#start方法的代码来会更好理解
知道了原因就比较好解决了,把"ipconfig /all"先分开来再以varargs数组或List
的字符串形式传入就可以了,如下:
Process p = null;
// 执行ipconfig /all命令
p = new ProcessBuilder("ipconfig","/all").start();
ProcessImpl
ProcessImpl类是Process抽象类的实现类,主要就是实现了Process类的waitFor、destory等等进程关键操作方法。
ProcessImpl类需要值得注意的就是它没有共有构造方法,只有一个private类型的方法,所以是不能直接实例化ProcessImpl类的,虽然我们不能直接new一个ProcessImpl,但是可以利用反射去调用非public类的方法,如下:
String[] cmds = {"ipconfig","/all"};
Class clazz = Class.forName("java.lang.ProcessImpl");
Method method = clazz.getDeclaredMethod("start", new String[]{}.getClass(), Map.class,String.class,ProcessBuilder.Redirect[].class,boolean.class);
method.setAccessible(true);
InputStream ins = ((Process) method.invoke(null,cmds,null,".",null,true)).getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int size;
while((size = ins.read(bytes)) > 0)
bos.write(bytes,0,size);
System.out.println(bos.toString());
内容总结
以上是互联网集市为您收集整理的Java安全之命令执行全部内容,希望文章能够帮你解决Java安全之命令执行所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。