【Java】利用反射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、付费专栏及课程。

余额充值