利用反射hacking java程序

一般来说,client程序不能直接调用private方法,但是通过反射,可以实现。

package chentao;

public class A
{
private static String getPassword() {
return "call the method!";
}
}

package chentao;

import java.lang.reflect.InvocationTargetException;

public class Test
{

/**
* @param args
* @throws ClassNotFoundException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
// ERROR
/*String password = A.getPassword();
System.out.println("I got it:" + password);*/

Class cl = Class.forName("chentao.A");
java.lang.reflect.Method[] m = cl.getDeclaredMethods();
m[0].setAccessible(true);
String password = (String) m[0].invoke(null, null);
System.out.println("I got it:" + password);

}
}

/*output:
I got it:call the method!*/


OK,singleton模式可以保证获取的实例唯一性,下面通过反射可以改变这一限制。

package chentao;

public class B
{
public static final B singleton = new B("I'm the only instance of class B");
private String name;
private B(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
}
package chentao;

package chentao;

import java.lang.reflect.InvocationTargetException;

public class TestB
{

/**
* @param args
* @throws ClassNotFoundException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InstantiationException
*/
public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException
{
Class cl = Class.forName("chentao.B");
java.lang.reflect.Constructor[] c = cl.getDeclaredConstructors();
c[0].setAccessible(true);
B anotherB = (B) c[0].newInstance(new Object[]{"Not anymore!!"});
System.out.println(B.singleton);
System.out.println(anotherB);
}
}

/*output:
I'm the only instance of class B
Not anymore!!
*/


最后一个例子,Runtime类有一个private static field用来表示当前的runtime实例。我们首先获得当前的runtime实例并打印。然后,因为currentRuntime在class初始化时会被初始化,所以我们设置Runtime.currentRuntime静态域为null,为了验证这次修改,我们再次获取runtime实例并打印。最后,我们通过当前runtime实例调用dos命令dir试试看...

package chentao;

import java.lang.reflect.InvocationTargetException;

public class TestRuntime
{

/**
* @param args
* @throws ClassNotFoundException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InstantiationException
*/
public static void main(String[] args) throws Exception
{
Runtime r = Runtime.getRuntime();
System.out.println("Before: Runtime.getRuntime() yields " + r);

Class cl = Class.forName("java.lang.Runtime");
java.lang.reflect.Field f = cl.getDeclaredField("currentRuntime");
f.setAccessible(true);
f.set(null, null);

r = Runtime.getRuntime();
System.out.println("After: Runtime.getRuntime() yields " + r);

r.exec("dir"); //raises NullPointerException!!

}
}

/*Output:

Before: Runtime.getRuntime() yields java.lang.Runtime@cac268
After: Runtime.getRuntime() yields null
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:59)
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值